How to use realized? on a lazy sequence?
Here's a REPL session, wherein I try to use realized? on a lazy-seq. Clojure 1.3.0 Define the lazy-seq: user= (def naturals (iterate inc 0)) #'user/naturals Force realization of the first 1 + 123456 elements: user= (time (nth naturals 123456)) Elapsed time: 481.349 msecs 123456 Due to previous realization, the same expression now eval's quickly: user= (time (nth naturals 123456)) Elapsed time: 15.571 msecs 123456 Now I try to use realized? on 123456th element: user= (realized? (nth naturals 123456)) ClassCastException java.lang.Long cannot be cast to clojure.lang.IPending clojure.core/realized? (core.clj:6505) Ouch! I guess realized? isn't a macro. Next try: user= (realized? (drop 123456 naturals)) false Hmmm... could I be off by one? Let's leave lots of room for error: user= (realized? (drop 12345 naturals)) false user= (realized? (drop 0 naturals)) false Huh? How do I get realized? to tell me what I want to know? What I want to know, is wether the element at the nth index has been computed and cached. Maybe something like realized- length, just for lazy-seq's, which would report how far along the sequence has realization occurred. Thanks, George Kangas -- 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: How to use realized? on a lazy sequence?
On Oct 7, 5:02 pm, Alan Malloy a...@malloys.org wrote: Can't you write that function yourself? (defn realized-length [xs] (loop [n 0 xs xs] (if (realized? xs) (recur (inc n) (rest xs)) n))) Thanks, Alan! drop returns a new lazy sequence, with no realized elements, I didn't realize that! I expected that drop would call rest recursively, like your realized-length does. But apparently, it's lazier than that: user= (def c (drop 12345678 naturals)) #'user/c user= (time (first c)) Exception in thread main java.lang.OutOfMemoryError: Java heap space (more java.lang.barfing) user= (def naturals (rest (iterate inc 0))) #'user/naturals You introduce another subtlety here: realized? won't work on the result of iterate (as Tassilo Horn found), but it will work on (rest (iterate ...)). And this is because: Note that this does not work for the base case of an iterated sequence, because that is not a lazy-seq but a cons. Seems a bit weird to me, but then realized? itself is a bit weird... realized? doesn't seem so weird, when it deals with promises, delays and futures. Those objects have explicit API's for their creation and realization, and realized? has a natural and predictable role in that API. Lazy sequences are more magic, and less explicit about creation and realization (or so it seems to me). Implementors of functions such as iterate, drop, rest, range, etc., have some freedom to decide times of creation/realization. Then, when you try to use realized? on lazy sequences, those decisions (which you may not have expected) come to the surface. Maybe realized? doesn't really belong in the lazy sequence API, but it is fun to play around with it. Thanks for showing me how! regards, George -- 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
What happened to bignum support? (clojure 1.3.0)
Greetings, Clojure community. I've been playing around with clojure, and just downloaded 1.3.0. Here's a REPL session, wherein I define a power-of-two function, and apply it a couple of times. lecturer-01:clojure-1.3.0 kangas$ java -cp clojure-1.3.0.jar clojure.main Clojure 1.3.0 user= (defn pow2 [n] (loop [n n, p 1] (if (zero? n) p (recur (dec n) (+ p p)) ))) #'user/pow2 user= (pow2 62) 4611686018427387904 user= (pow2 63) ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374) user= Previous versions would silently, automagically convert to bignums and give me the answer I wanted. Is clojure-1.3.0 too serious, enterprisy, and Java-like for this sort of thing? I found no clue in the list of changes. thanks, George -- 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: aquamacs, slime and clojure on OS X
I'm quite happy using emacs's Scheme support. But then, I've never experienced the luxury of swank and slime. The Scheme modes work a bit better (for Clojure) than the Lisp modes, because: 1) it highlights matching square and curly brackets, not just parentheses; and 2) after you do C-u M-x run-scheme / java -cp... to start inferior Scheme mode, you can restart it with just M-x run- scheme (within the same emacs session). So, until you man up, and build the great edifice of leiningen + ant + maven + ..., something I'll probably never get around to, you can make do with Scheme mode. Good enough for the '90s! Some people are happy with mini-IDE called clooj that's under developement. You can find that on github. ciao, George -- 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: What happened to bignum support? (clojure 1.3.0)
Thanks, Baishampayan and Sam! Since so little effort is required to get the BigInt behavior, you'll all be relieved to hear that I Approve of This Change. Should I ever need high performance from Clojure, I'll actually be happy about it. Notwithstanding the snarking tone of my original post. George -- 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: puzzlement over lazy sequences
Hi, Stu, Loving your book! I posted a reply earlier, through a different interface, which went to moderators. Sorry for the clumsiness, but I'm not familiar with the mechanics of newsgroups. On Sep 11, 7:28 am, Stuart Halloway stuart.hallo...@gmail.com wrote: The consing version of ev-stream is self-referential, because you explicitly made it so by consing it back onto itself. So it only has two items in it, though it bounces back and forth between them forever. The cycling version is not self-referential. Since it's the self reference that gives the nice results (finite memory consumption, and apparently better speed), I came up with a little macro to provide it: (defmacro defcycle [name coll] `(def ~name (lazy-seq (concat ~coll ~name))) ) This is probably not the most useful way to do it, since the user has to provide name. Now I'll test it with 9876543210, a number which ev? was able to handle: user= (time (mod3 9876543210)) Elapsed time: 37759.615 msecs 1 user= (mod 987654321 3) 0 Whoa! The computation finished in reasonable time, but with the WRONG answer! How did that happen? Did I find a bug? No, there is simply a typo in your input arg. with the typo fixed, i.e. (mod 9876543210 3), the result is still 0. regards, George -- 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
puzzlement over lazy sequences
Greetings, Clojurers! I've been playing with clojure, particularly with lazy sequences. Some of the results have left me puzzled, so I saved a REPL session wherein I illustrate the points of puzzlement. REPL lines are indented below; added comments are unindented. Clojure 1.2.1 I define a silly version of even? which uses a lazy sequence: user= (defn ev? [n] (nth (cycle [true false]) n)) #'user/ev? It works, albeit slowly, for large arguments: user= (time (ev? 9876543210)) Elapsed time: 337225.287 msecs true This won't work, if any reference is retained to that long sequence: user= (def ev-stream (cycle [true false])) #'user/ev-stream user= (defn ev? [n] (nth ev-stream n)) #'user/ev? user= (time (ev? 9876543210)) Exception in thread main java.lang.OutOfMemoryError: Java heap space at java.lang.reflect.Method.copy(Method.java:143) at java.lang.reflect.ReflectAccess.copyMethod(ReflectAccess.java:118) at sun.reflect.ReflectionFactory.copyMethod(ReflectionFactory.java: 282) at java.lang.Class.copyMethods(Class.java:2748) at java.lang.Class.getMethods(Class.java:1410) at clojure.lang.Reflector.getMethods(Reflector.java:310) at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:27) at clojure.main$repl_caught.invoke(main.clj:116) at clojure.main$repl$fn__5637.invoke(main.clj:206) at clojure.main$repl.doInvoke(main.clj:204) at clojure.lang.RestFn.invoke(RestFn.java:421) at clojure.main$repl_opt.invoke(main.clj:262) at clojure.main$main.doInvoke(main.clj:355) at clojure.lang.RestFn.invoke(RestFn.java:397) at clojure.lang.Var.invoke(Var.java:361) at clojure.lang.AFn.applyToHelper(AFn.java:159) at clojure.lang.Var.applyTo(Var.java:482) at clojure.main.main(main.java:37) Process scheme exited abnormally with code 1 Okay, that was the expected java.lang.barf. No puzzlement so far. Now I restart the REPL. Clojure 1.2.1 Once again, I make a globally referenced, infinitely long stream. But now I use lazy-seq instead of cycle: user= (def ev-stream (lazy-seq (cons true (cons false ev- stream #'user/ev-stream user= (defn ev? [n] (nth ev-stream n)) #'user/ev? user= (time (ev? 9876543210)) Elapsed time: 47244.061 msecs true OMG! Not only did it NOT hose the heap and crash, it actually ran much faster than the version with the unreferenced (cycle [true false]). The only reason I can think of, for this to NOT exhaust memory, is that the lazy-seq macro knows when to construct a circular list. Is that what happens? If so, why DOESN'T it happen with cycle, where it's obviously the behavior one would want? Okay, now I'll play the same game again, but with mod 3: user= (def mod3-stream (lazy-seq (cons 0 (cons 1 (cons 2 mod3- stream) #'user/mod3-stream user= (defn mod3 [n] (nth mod3-stream n)) #'user/mod3 It passes a simple test: user= (map mod3 (range 20)) (0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1) It passes a test with a pretty big number: user= (time (mod3 987654321)) Elapsed time: 28998.966 msecs 0 user= (mod 987654321 3) 0 Now I'll test it with 9876543210, a number which ev? was able to handle: user= (time (mod3 9876543210)) Elapsed time: 37759.615 msecs 1 user= (mod 987654321 3) 0 Whoa! The computation finished in reasonable time, but with the WRONG answer! How did that happen? Did I find a bug? Thanks for reading this far, and best regards, George Kangas -- 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