Re: Implementing destructuring without setting your hair on fire
Daniel Werner daniel.d.wer...@googlemail.com writes: After a few tries I've come up with the following algorithm to transform :keys syntax into normal destructuring syntax, but am still appalled by its complexity: (let [vmap {'y :y, 'z :z :keys ['a 'b]}] (- vmap ((juxt :keys :strs :syms)) (apply concat) (mapcat #(vector % (keyword %))) (apply hash-map))) == {a :a, b :b} Pretty's such a subjective thing, but my first impulse was: (let [vmap {'y :y, 'z :z :keys ['a 'b]}] (reduce #(assoc %1 %2 (keyword %2)) {} (mapcat vmap [:keys :strs :syms]))) -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: filtering with multiple predicates
I cheated and used 'every?' :) (defn andf [ preds] (fn [ args] (every? #(apply % args) preds))) .Bill Smith william.m.sm...@gmail.com writes: I want to filter a list based on the logical AND of a set of predicates. For example, let's say I have single-argument functions f, g, and h (without side-effects), and I want those items x in the list such that (f x), (g x) and (h x) are all true. I know I can do this: (filter #(and (f %) (g %) (h %)) my-list) Is there a more terse way to express the same thing? I suspect there is a mechanism similar to (or perhaps a generalization of) composition for that, but I couldn't find it in the API docs. Bill Smith Austin, TX -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: filtering with multiple predicates
j-g-faustus johannes.fries...@gmail.com writes: I was apparently too late. Oh well :) My apologies for pre-emptively stealing your idea :) -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Another `line-seq' issue
Hi all, At the risk of being labelled the guy who always whines about line-seq, I'm whining about line-seq again. I hit some surprising behaviour stemming from the fact that line-seq isn't fully lazy: (defn line-seq Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader. [#^java.io.BufferedReader rdr] (when-let [line (.readLine rdr)] (cons line (lazy-seq (line-seq rdr) This implementation is fully lazy: (defn line-seq [rdr] (lazy-seq (when-let [line (.readLine rdr)] (cons line (line-seq rdr) but doesn't return nil on an empty sequence, which I think is why line-seq was changed in the first place (commit efc54c000445f8b3d8d2e75d560fa02397951598). It seems that there's an inherent trade-off between wanting to return nil for an empty sequence and wanting to be fully lazy, so I'm not sure of the best way of achieving both objectives. I just thought I'd raise the issue in case someone brighter than me has any good ideas :) Cheers, Mark -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Small line-seq regression?
Drew Raines aarai...@gmail.com writes: Rich Hickey wrote: On Mon, Dec 14, 2009 at 8:48 AM, Chouser chou...@gmail.com wrote: [...] Your analysis and solution seem right to me. Rich, would you accept a ticket for this? Yes, and could someone please check the other functions that were patched similarly? I'll do it since I created the original patch. https://www.assembla.com/spaces/clojure/tickets/222 Many thanks everyone. Cheers, Mark -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Small line-seq regression?
Hi all, I recently pulled down the latest Clojure master branch and have noticed a small change in line-seq's behaviour which breaks some of my code. The code in question uses line-seq like this: (use 'clojure.contrib.duck-streams) (with-open [ss (java.net.ServerSocket. 4141)] (println (first (line-seq (reader (.accept ss)) If I run this then telnet to the listen port and send a single line: Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. hi The above code prints nothing until the *second* line arrives from the socket, even though that line isn't required to fulfil my (first ...) request. It appears this behaviour changed in patch 284ee8aa in an effort to make line-seq return nil (instead of ()) for an empty lazy seq. The line-seq definition currently reads: (defn line-seq Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader. [#^java.io.BufferedReader rdr] (let [line (. rdr (readLine))] (when line (lazy-seq (cons line (line-seq rdr)) and when my code above is blocked, it's because my call to 'first' has caused the first recursive call to be made, which immediately blocks on the now-eagerly-performed readLine for the second line of input. Taking the line to be returned out of the lazy-seq seems to fix things for me: (defn line-seq Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader. [#^java.io.BufferedReader rdr] (let [line (. rdr (readLine))] (when line (cons line (lazy-seq (line-seq-new rdr)) and, I think, still preserves the intention of the original change. Does that seem reasonable? Thanks, Mark -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Specified behavior of every?
I've always relied on this being true without losing sleep at night (or during the day), and it has a good grounding in predicate logic: http://en.wikipedia.org/wiki/Universal_quantification#The_empty_set Cheers, Mark Sean Devlin francoisdev...@gmail.com writes: The following return true: user=(every? even? nil) true user=(every? even? []) true Is this behavior the specified behavior? Can I ASSUME it is true in my code? -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Krishnamurthi's Automata in Clojure (OutOfMemoryError)
Hi Charles, I notice I can stop your version from running out of memory with a very small change. Changing from: ;; the [f args] form of trampoline (trampoline init start-stream) to: ;; the [f] form of trampoline (trampoline #(init start-stream)) seems to work as expected. I would hazard a guess that this might be the same issue as described in this thread: http://groups.google.com/group/clojure/msg/dfb1c1d68ac7e742 Cheers, Mark Charles Gordon charles.gor...@gmail.com writes: The implementation listed there doesn't work, and is before Rich introduced letfn, so I decided to try my own implementation using letfn and trampoline: (defn machine [start-stream] (letfn [(init [stream] #(cond (empty? stream) true (= \c (first stream)) (more (rest stream)) :else false)) (more [stream] #(cond (empty? stream) true (= \a (first stream)) (more (rest stream)) (= \d (first stream)) (more (rest stream)) (= \r (first stream)) (end (rest stream)) :else false)) (end [stream] #(cond (empty? stream) true :else false))] (trampoline init start-stream))) This works, but if I try to run it on an infinite sequence, it eventually runs out of memory: (machine (iterate (fn [c] (if (= c \c) \a \d)) \c)) Java heap space [Thrown class java.lang.OutOfMemoryError] -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Proposal: Extend behavior of hash-map
How about?: (java.util.HashMap. {:a 1 :b 2 :c 3}) = #HashMap {:c=3, :b=2, :a=1} Mark Sean Devlin francoisdev...@gmail.com writes: Okay golfers. Is there a better way to do this? (defn put-all! [java-map clj-map] (do (doseq [entry clj-map] (.put java-map (key entry) (val entry))) java-map)) user=(put-all (java.util.HashMap. ) {:a 1 :b 2 :c 3}) #HashMap {:c=3, :b=2, :a=1} I already tried into :) -- Mark Triggs mark.h.tri...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Starting swank separately and connecting to it works almost but no REPL
Hi Mathias, This wouldn't just be because SLIME no longer includes the REPL by default, would it? Does adding: (require 'slime-fancy) to your emacs setup help at all? Cheers, Mark Mathias Dahl mathias.d...@gmail.com writes: Hi! I am trying to start swank separately so that I can connect to it from a separate emacs instance. It works almost all the way but I never get a REPL. Here are the details: [...] In emacs -Q: (add-to-list 'load-path ~/clj/slime) (require 'slime) (slime-setup) M-x slime-connect RET RET In the *Messages* buffer I can see this: Connecting to Swank on port 4005.. [2 times] Connected. Hack and be merry! I can then enter slime-mode and for example eval (+ 1 2) in a buffer and I get as reply 3 in the echo area. So, all seems to be setup properly and working. But, I get no REPL. Why? -- Mark Triggs mark.h.tri...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Idiom for array slicing
Yep, this was my thinking too. Maybe it doesn't matter, but I'm always a little reluctant to make those sort of compromises when writing general-purpose utility functions. Mark Andrew Baine andrew.ba...@gmail.com writes: If coll has O(n) access and we impose the restriction that indices is increasing (or sort it up front), we can do better than this by only doing one pass through coll. On Aug 18, 10:46 am, CuppoJava patrickli_2...@hotmail.com wrote: The most straight-forward answer I would have given is also: (defn slice [indices coll] (map #(nth coll %) indices)) Is there some disadvantage with this approach that I'm not seeing? -- Mark Triggs mark.h.tri...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Idiom for array slicing
That works nicely, even for infinite sequences, but appears to hang on to the head: user= (split [2000 2001] (repeatedly #(int-array 102400))) java.lang.OutOfMemoryError: Java heap space The map/nth variant has this same problem, unfortunately. My original version works around these issues at the expense of being longer and uglier ;o) Mark CuppoJava patrickli_2...@hotmail.com writes: I see. Thanks for explaining. If speed is an issue, and if you can assume that indices are properly sorted in ascending order, I believe this looks like a lazy-reduce problem. Clojure has no lazy-reduce (or does it?) so I've written my own: (defn lazy_reduce [f val coll] (lazy-seq (if (seq coll) (let [val (f val (first coll))] (cons val (lazy_reduce f val (rest coll))) (defn split [indices coll] (map first (lazy_reduce nthnext coll (map - indices (cons 0 indices) -- Mark Triggs mark.h.tri...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Idiom for array slicing
Hi all, Is there an idiom for what I'm doing below, or does a function already exist? (let [vowels (slice abcdefghijklmnopqrstuvwxyz 0 4 8 14 20)] vowels) = (\a \e \i \o \u) A possible implementation: (defn slice Return the items in coll at index positions keys. (slice \abcdefg\ 0 4 6) = (\\a \\e \\g) [coll keys] (let [keyset (set keys)] (for [[idx elt] (indexed coll) :when (keyset idx)] elt))) I often want something like this when picking apart lines from log files (calling .split on a string, then grabbing certain segments) Thanks, Mark -- Mark Triggs mark.h.tri...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Idiom for array slicing
Thanks all. So combining a few suggested ideas: (defn slice Return the items in coll at index positions keys. (slice [0 4 6] \abcdefg\) = (\\a \\e \\g) [keys coll] (let [max-idx (apply max keys) keyset (set keys)] (map second (filter (fn [[idx _]] (keyset idx)) (take-while (fn [[idx _]] (= idx max-idx)) (indexed coll)) This version has the advantage of working on infinite sequences and not hanging onto the head. This works as expected: (slice [200 201] (repeatedly #(int-array 102400))) without blowing up the stack or throwing OutOfMemory (on my JVM). Thanks again, Mark Mark Triggs mark.h.tri...@gmail.com writes: Hi all, Is there an idiom for what I'm doing below, or does a function already exist? (let [vowels (slice abcdefghijklmnopqrstuvwxyz 0 4 8 14 20)] vowels) = (\a \e \i \o \u) -- Mark Triggs mark.h.tri...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Uncle Bob: bowling meets Clojure
Hi Stu, Stuart Halloway stuart.hallo...@gmail.com writes: Uncle Bob Martin, a very well-respected OO and agile guy, is learning Clojure. He has posted an example [1] and asked for feedback from the Clojure community. I have made my suggestions in code [2] and will be writing them up shortly. Would love to see what other folks on this list have to say. My first version came out rather similar to yours, and then I started thinking about turning the problem on its head and making the concept of types of rolls more explicit. I'm still not sure how I feel about this, but the line of thinking led me to code like this: (ns bowling-game (:use clojure.contrib.seq-utils)) (def *roll-types* [{:name strike :satisfies #(= (first %) 10) :consumes 3 :advances 1} {:name spare :satisfies #(= (apply + (take 2 %)) 10) :consumes 3 :advances 2} {:name regular (underachieving?) :satisfies (constantly true) :consumes 2 :advances 2}]) (defn roll-type [rolls] (find-first #((:satisfies %) rolls) *roll-types*)) (defn frames [rolls] (when (seq rolls) (let [{:keys [consumes advances]} (roll-type rolls)] (cons (take consumes rolls) (frames (drop advances rolls)) (defn score-game [rolls] (reduce + (map #(reduce + %) (take 10 (group-frames rolls) Cheers, Mark -- Mark Triggs mark.h.tri...@gmail.com --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Algorithm help
Heheh, three times slower but gives the wrong answer--maybe not a great trade-off :o) I'd misread the way the last if statements work in the Python version. I modified mine to read: (defn backtrack-all [c x y i j] (cond (or (zero? i) (zero? j)) #{} (= (get x (dec i)) (get y (dec j))) (set (map #(str % (get x (dec i))) (backtrack-all c x y (dec i) (dec j :else (set (concat (when (= (get-in c [i (dec j)]) (get-in c [(dec i) j])) (backtrack-all c x y i (dec j))) (when (= (get-in c [(dec i) j]) (get-in c [i (dec j)])) (backtrack-all c x y (dec i) j)) I'd mistakenly assumed that those last two conditionals were mutually exclusive, but they're not. Cheers, Mark On Jul 17, 7:07 pm, martin_clausen martin.clau...@gmail.com wrote: Thanks. Your code is definitely much more idiomatic Clojure - and 3X faster. The lcs function does exactly what it is suppose to, but the backtrack-all function only returns the first LCS found(for the strings AATCC ACACG = (ACC), whereas the Python version returns all the LCSes found (for the same strings = set(['ACC', 'AAC'])). I have tried to find out why this is, but cannot identify the cause. On Jul 17, 12:16 am, Mark Triggs mark.h.tri...@gmail.com wrote: Hi there, I had a bit of a go at converting the Python version into Clojure and removed the need to mutate an array. Because the 'lcs' function was basically just mapping over a list of i/j pairs and accumulating the resulting matrix, it seemed like a good candidate for reduce: (defn lcs [x y] (let [m (count x) n (count y)] (reduce (fn [c [i j]] (if (= (get x (dec i)) (get y (dec j))) (assoc-in c [i j] (inc (get-in c [(dec i) (dec j)]))) (assoc-in c [i j] (max (get-in c [i (dec j)]) (get-in c [(dec i) j]) (vec (replicate (inc n) (vec (replicate (inc m) 0 (for [i (range 1 (inc m)) j (range 1 (inc n))] [i j] Then, 'backtrack-all' is pretty much a straight translation of the Python one, but with tail recursion where possible: (defn backtrack-all [c x y i j] (cond (or (zero? i) (zero? j)) #{} (= (get x (dec i)) (get y (dec j))) (set (map #(str % (get x (dec i))) (backtrack-all c x y (dec i) (dec j (= (get-in c [i (dec j)]) (get-in c [(dec i) j])) (recur c x y i (dec j)) (= (get-in c [(dec i) j]) (get-in c [i (dec j)])) (recur c x y (dec i) j))) Mostly untested ;o) Cheers, Mark On Jul 17, 6:57 am, martin_clausen martin.clau...@gmail.com wrote: Can anybody give me some hints on how to translate this:http://bit.ly/lcs_py (the backTrackAll function) from Python into Clojure? I have a pasted my attempt here:http://paste.lisp.org/+1SL7, but it doesn't work. For completeness I have included the functions required to test the traceback-all-lcs function and my traceback-lcs function (that works :-)). I cannot figure out if it is the list comprehension that is wrong or my use of cons or some immutability thing that is tricking me. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Algorithm help
Hi there, I had a bit of a go at converting the Python version into Clojure and removed the need to mutate an array. Because the 'lcs' function was basically just mapping over a list of i/j pairs and accumulating the resulting matrix, it seemed like a good candidate for reduce: (defn lcs [x y] (let [m (count x) n (count y)] (reduce (fn [c [i j]] (if (= (get x (dec i)) (get y (dec j))) (assoc-in c [i j] (inc (get-in c [(dec i) (dec j)]))) (assoc-in c [i j] (max (get-in c [i (dec j)]) (get-in c [(dec i) j]) (vec (replicate (inc n) (vec (replicate (inc m) 0 (for [i (range 1 (inc m)) j (range 1 (inc n))] [i j] Then, 'backtrack-all' is pretty much a straight translation of the Python one, but with tail recursion where possible: (defn backtrack-all [c x y i j] (cond (or (zero? i) (zero? j)) #{} (= (get x (dec i)) (get y (dec j))) (set (map #(str % (get x (dec i))) (backtrack-all c x y (dec i) (dec j (= (get-in c [i (dec j)]) (get-in c [(dec i) j])) (recur c x y i (dec j)) (= (get-in c [(dec i) j]) (get-in c [i (dec j)])) (recur c x y (dec i) j))) Mostly untested ;o) Cheers, Mark On Jul 17, 6:57 am, martin_clausen martin.clau...@gmail.com wrote: Can anybody give me some hints on how to translate this:http://bit.ly/lcs_py (the backTrackAll function) from Python into Clojure? I have a pasted my attempt here:http://paste.lisp.org/+1SL7, but it doesn't work. For completeness I have included the functions required to test the traceback-all-lcs function and my traceback-lcs function (that works :-)). I cannot figure out if it is the list comprehension that is wrong or my use of cons or some immutability thing that is tricking me. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Adding type hint causes compiler error
Hi Phil, Part of me hopes there's a nicer way of doing this, but I was able to get it working using: (defn bi-get-pixels [#^BufferedImage bi] (let [raster (.getData bi) pixels (.getPixels raster 0 0 (.getWidth bi) (.getHeight bi) (cast (Class/forName [I) nil))] (vec pixels))) Cheers, Mark On Jul 5, 10:18 pm, philip.hazel...@gmail.com philip.hazel...@gmail.com wrote: Hi, The following code works as expected: (import 'javax.imageio.ImageIO 'java.io.File 'java.awt.image.BufferedImage) (defn bi-get-pixels [bi] (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi) nil (bi-get-pixels (. ImageIO read (File. /home/phil/prog/small- test.png))) But if *warn-on-reflection* is true, it generates four warnings. If we try to shut it up with a type hint: (defn bi-get-pixels [#^BufferedImage bi] (vec (.. bi (getData) (getPixels 0 0 (.getWidth bi) (.getHeight bi) nil Exception in thread main java.lang.IllegalArgumentException: More than one matching method found: getPixels (imagio-test.clj:7) at clojure.lang.Compiler.analyzeSeq(Compiler.java:4558) ... Caused by: java.lang.IllegalArgumentException: More than one matching method found: getPixels at clojure.lang.Compiler.getMatchingParams(Compiler.java:2122) at clojure.lang.Compiler$InstanceMethodExpr.init (Compiler.java:1159) at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java: 810) at clojure.lang.Compiler.analyzeSeq(Compiler.java:4551) ... 34 more The problem here is that getPixels has three forms: (http://java.sun.com/j2se/1.4.2/docs/api/java/awt/image/Raster.html) double[] getPixels(int x, int y, int w, int h, double[] dArray) Returns a double array containing all samples for a rectangle of pixels, one sample per array element. float[] getPixels(int x, int y, int w, int h, float[] fArray) Returns a float array containing all samples for a rectangle of pixels, one sample per array element. int[] getPixels(int x, int y, int w, int h, int[] iArray) Returns an int array containing all samples for a rectangle of pixels, one sample per array element. In each case, if the final argument is NULL it is ignored, and if not the array is populated with the return data from the call (generating an error if it's not large enough). Is it possible to specify which invocation of getPixels I intend without passing an array? I've tried putting #^ints in some likely- looking places, but nil can't be type-hinted and the others seem to have no effect. I've also tried splitting the .. up: (defn bi-get-pixels [#^BufferedImage bi] (let [rast (.getData bi) #^ints pi (.getPixels rast 0 0 (.getWidth bi) (.getHeight bi) nil)] pi)) But this doesn't work either. I could do manual reflection on Raster to get the correct method and .invoke it, but that seems far more complicated than necessary. Any other ideas? -Phil --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
SLIME/elisp hack to generate import lines
Hi all, I just thought I'd write to share a terrible (but maybe useful!) hack for SLIME. I've written some code that sniffs around the classpath to find libraries matching some regexp, then inserts the appropriate `import' sexps into the current buffer. For example: M-x clj-import [RET] IndexWriter [RET] inserts (for my classpath): (import '(org.apache.lucene.index IndexWriter IndexWriter $MaxFieldLength)) Yep, I'm *that* lazy. I've put the code here: http://dishevelled.net/Generating-Clojure-import-lines-using-SLIME.html Cheers, Mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Nested loops
Hi David, Quite a few times when I've felt the need for this sort of thing I've found that laziness comes to the rescue. Would something like this sort of approach work for you? (defn possibilities [word pos] All variations of `word' with letters from 'a' to 'z' inserted at `pos' (let [[beg end] (split-at pos word) letters (map char (range (int \a) (inc (int \z] (map #(apply str (concat beg [%] end)) letters))) (defn all-possibilities [word] (for [n (range (inc (count word))) pos (possibilities word n)] pos)) ;; Since all-possibilities produces a lazy seq we don't need short circuiting anyway... (some #(binary-search word) (all-possibilities hello)) Cheers, Mark On Apr 5, 1:26 pm, David Sletten da...@bosatsu.net wrote: I'm working on a spell checker that attempts to suggest corrections from a given dictionary. One of the heuristics is to see if inserting a character at each point in the given string results in a recognized word. So I have an outer loop that moves across each position in the string and an inner loop that tests a-z at that point. In Common Lisp I use this: (defun word-insertion (s) (let ((s1 (make-string (1+ (length s) ; Copy the input and make room for an extra char (setf (subseq s1 1 (length s1)) s) (dotimes (i (length s1) nil) ; Outer loop (unless (zerop i) (setf (char s1 (1- i)) (char s (1- i (dotimes (j (1+ (- (char-code #\z) (char-code #\a ; Inner loop (setf (char s1 i) (code-char (+ j (char-code #\a (let ((index (binary-search s1))) ; Check in the dictionary for a match (when index (return-from word-insertion index ))) ; Done if match found The main point is that I can use two DOTIMES forms, one nested inside the other, and I can exit either at any point. I actually exit the entire function as soon as I find a match via RETURN-FROM. Clojure has 'dotimes', but from what I understand there is no way to exit prematurely? The obvious alternative is to nest a couple of 'loop' forms: (defn g [p q] (loop [i 0] (if (= i p) nil (do (loop [j 0] (if (= j q) nil (do (prn (list i j)) (recur (inc j ) (recur (inc i )) The loop/recur pairs seem to establish outer and inner recursion points (I can't really tell from the macro expansion), and this function behaves as expected. This approach appears to be equivalent to something like this: (defn f [p q] (letfn [(outer [i] (if (= i p) nil (do (inner i 0) (outer (inc i ) (inner [i j] (if (= j q) nil (do (prn (list i j)) (inner i (inc j )] (outer 0))) Again the important thing is that I can terminate the inner loop based on my own condition. However, it seems that in the outer loop I have to capture the value of the inner loop directly. I can't simply leave both loops: (defn word-insertion [s] (let [s1 (make-array Character/TYPE (inc (count s)))] (System/arraycopy (.toCharArray s) 0 s1 1 (count s)) (loop [i 0] (if (= i (count s1)) nil (do (when-not (zero? i) (aset s1 (dec i) (nth s (dec i (let [match (loop [j 0] (if (= j (inc (- (int \z) (int \a nil (do (aset s1 i (char (+ j (int \a (let [match (binary-search (String. s1))] (if match match (recur (inc j )))] (if match match (recur (inc i ) One other version I considered makes due with a single 'loop', but this is pretty convoluted: (defn word-insertion [s] (let [s1 (make-array Character/TYPE (inc (count s)))] (System/arraycopy (.toCharArray s) 0 s1 1 (count s)) (loop [i 0 j 0] (when (and (not (zero? i)) (zero? j)) (aset s1 (dec i) (nth s (dec i (cond (= i (count s1)) nil (= j (inc (- (int \z) (int \a (recur (inc i) 0) :else (do (aset s1 i (char (+ j (int \a (let [match (binary-search (String. s1))] (if match match (recur i (inc j ) The one nice thing about this is I can terminate the entire loop and return a value in one step. Otherwise the logic is a mess. Any suggestions out there? Aloha, David Sletten
Re: Quick slime/emacs questions
Something like this in your ~/.emacs might do the job: (define-key global-map (kbd C-x C-b) (lambda () (interactive) (select-window (call-interactively 'list-buffers Cheers, Mark On Mar 30, 7:41 am, Mark Engelberg mark.engelb...@gmail.com wrote: When I have two windows open, and hit C-x-C-b, it pops up a list of buffers in the OTHER window from where the current focus is. Any idea why it's doing that, and how I can alter the behavior so it pops up the list of buffers in the current window? Also, where can I look up the names of various commands to rebind to different keys? For example, I want to remap C-s to do what C-x-C-s currently does, and I wan to remap C-f to do what C-s currently does, to make behavior more consistent with other programs I use. (After using emacs for a while, I inevitably find myself hitting C-x-C-s to save in other programs :) ) Thanks! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Calling `str' on a LazySeq
Hi David, On Mar 22, 5:01 pm, David Sletten da...@bosatsu.net wrote: On Mar 21, 2009, at 1:44 PM, Mark Triggs wrote: user= (str (filter even? (range 1 10))) clojure.lang.lazy...@f1005 Previously this would readably print the contents of the seq and some of my code was relying on this. Obviously it's not difficult to call `prn-str' myself, but I just wondered if this change was made consciously. According to the documentation for 'str': With one arg x, returns x.toString(). So it looks like toString() on a sequence used to return its contents and now doesn't. However, rather than relying on this behavior what you probably should be doing is using 'apply': (apply str (filter even? (range 1 10))) = 2468 If you want commas between those elements, use 'interpose': (apply str (interpose , (filter even? (range 1 10 = 2, 4, 6, 8 Yep, that's fine. In my case I was actually relying on the fact that `str' was effectively doing a `prn-str' because I would later read it back using `read-string' elsewhere. Calling `prn-str' explicitly isn't a problem--I just thought I'd mention that the semantics have now changed a little. Thanks, Mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: doall vs. dorun
In addition to what others have said, I also tend to use doall when working with agent actions that return sequences (i.e. to force any computation to happen in the agent's thread and not in the caller's) Cheers, Mark On Wed, Jan 21, 2009 at 7:32 AM, Mark Volkmann r.mark.volkm...@gmail.com wrote: Can someone describe a situation where it is preferable to use doall instead of dorun? I see in the documentation that it retains the head and returns it, thus causing the entire seq to reside in memory at one time, but I'm not sure why I'd want that. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: java.lang.IncompatibleClassChangeError: [class] and [inner class] disagree on InnerClasses attribute
Aha! I notice that this problem goes away if I run the JVM the way I'm supposed to (with -cp lucene-core.xxx.jar) instead of using (add- classpath ...) to load the jar in the first place. This probably isn't a big deal, then :o) Thanks, Mark On Jan 13, 11:06 am, Mark Triggs mark.h.tri...@gmail.com wrote: Hi all, I've just been fiddling with Lucene indexing from Clojure, and wanted to access a static field of this inner class: http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/index/Index... I'm importing IndexWriter$MaxFieldLength with no problems, but attempts to eval: IndexWriter$MaxFieldLength/UNLIMITED or (. IndexWriter$MaxFieldLength UNLIMITED) both yield the following exception: java.lang.IncompatibleClassChangeError: org.apache.lucene.index.IndexWriter and org.apache.lucene.index.IndexWriter$MaxFieldLength disagree on InnerClasses attribute (NO_SOURCE_FILE:0) [Thrown class clojure.lang.Compiler$CompilerException] I'm running SVN r1205. Am I doing something wrong here? Thanks, Mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
java.lang.IncompatibleClassChangeError: [class] and [inner class] disagree on InnerClasses attribute
Hi all, I've just been fiddling with Lucene indexing from Clojure, and wanted to access a static field of this inner class: http://lucene.apache.org/java/2_4_0/api/org/apache/lucene/index/IndexWriter.MaxFieldLength.html I'm importing IndexWriter$MaxFieldLength with no problems, but attempts to eval: IndexWriter$MaxFieldLength/UNLIMITED or (. IndexWriter$MaxFieldLength UNLIMITED) both yield the following exception: java.lang.IncompatibleClassChangeError: org.apache.lucene.index.IndexWriter and org.apache.lucene.index.IndexWriter$MaxFieldLength disagree on InnerClasses attribute (NO_SOURCE_FILE:0) [Thrown class clojure.lang.Compiler$CompilerException] I'm running SVN r1205. Am I doing something wrong here? Thanks, Mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: what does - mean?
I've also found this useful for accessing members in nested maps. For example: (let [me {:person {:name {:first Mark :last Triggs} :email mark.h.tri...@gmail.com}}] (- me :person :name :first)) = Mark On Jan 12, 1:04 pm, kkw kevin.k@gmail.com wrote: One use I've found for - (though there are others I haven't come to appreciate yet) is when I have something like: (f1 (f2 (f3 (f4 x which can be re-written as (- x f4 f3 f2 f1) I find the latter expression easier to read. Kev On Dec 30 2008, 2:49 pm, wubbie sunj...@gmail.com wrote: Very criptic for newbie. What does Threads the expr through the forms. mean? Does it create a thread to execute? thanks sun On Dec 29, 10:07 pm, Paul Barry pauljbar...@gmail.com wrote: You can look up the documentation for a function/macro interactively from the repl: user= (doc -) - clojure.core/- ([x form] [x form more]) Macro Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc. nil On Dec 29, 8:27 pm, wubbie sunj...@gmail.com wrote: Hi all, Looking intoants.clj, I came across (defn place [[x y]] (- world (nth x) (nth y))) What - mean here? thanks sun --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Memory usage when iterating over lazy sequences
Hi all, I'm just getting started with Clojure, and I've got a bit of a beginner's question regarding memory usage of lazy sequences. I have an array of data that is too big to fit in memory, so I thought I would be clever and process it in manageable-sized chunks. My instinct was to do this using loop/recur using 'take' to bite off the next chunk, and 'drop' to give me the remainder for the next recursive call. Here's a contrived example: ;; Process the list one chunk at a time (defn do-something [biglist] (loop [rest (drop 1000 biglist)] (when rest (doall (take 1000 rest)) (recur (drop 1000 rest) ;; Lazily calculate our big data set and pass it along for processing (do (do-something (map (fn [n] (make-array java.lang.Character 10240)) (range 0 10))) nil) When I ran my code it very quickly ran out of memory and fell over. After thinking about it for a while I've realised it must be because my 'do-something' function call is hanging on to the head of the list, so as its elements are realised and cached it gradually eats up all my memory. Assuming my diagnosis is right, is there some sort of idiomatic way of dealing with this sort of issue? I suppose that if the JVM allowed for true tail recursion then this problem wouldn't arise? Many thanks, Mark -- Mark Triggs [EMAIL PROTECTED] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Memory usage when iterating over lazy sequences
On Oct 31, 1:57 pm, Mark Triggs [EMAIL PROTECTED] wrote: When I ran my code it very quickly ran out of memory and fell over. After thinking about it for a while I've realised it must be because my 'do-something' function call is hanging on to the head of the list, so as its elements are realised and cached it gradually eats up all my memory. Answering my own question, using the function itself as the recur target does exactly what I want: ;; Process the list one chunk at a time (defn do-something [biglist] (when biglist (doall (take 1000 biglist)) (recur (drop 1000 biglist I guess I should have tried it instead of assuming it wouldn't work. Please excuse my talking to myself :o) Cheers, Mark --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---