Re: question about clojure.lang.LazySeq.toString()
If I'm reading everything correctly: 1. Object 's .toString uses .hashCode() 2. LazySeq 's .hashCode() uses seq() which realizes a seq. 3. LazySeq 's .hashCode() calls .hashCode() on the realized seq 3. (map ..) creates a LazySeq with a fn to create (cons val (lazy-seq (map f rest))) 4. (cons ... ...) creates a Cons 5. Cons uses Aseq's .hashcode() which traverses each object in the seq and merges the hashcodes together. A similar thing happens with a (range) as it builds a ChunkedCons which also uses Aseq's hashcode. On Fri, Mar 22, 2013 at 12:53 AM, Marko Topolnik marko.topol...@gmail.com wrote: I am deeply puzzled abouth the behavior of .toString invocation on a lazy sequence. == (.getClass (map println (range 100))) clojure.lang.LazySeq == (.toString (map println (range 100))) ;; integers 0..100 printed clojure.lang.LazySeq@590b4b81 It should be obvious from the output, but for the record: LazySeq doesn't override toString, so just the basic Java method is called. How can this possibly cause the sequence to be realized? Beyond my curiosity, however, what possible purpose could such behavior serve? -marko On Thursday, March 21, 2013 7:54:39 PM UTC+1, Razvan Rotaru wrote: Hi, I'm curious, why doesn't toString of clojure.lang.LazySeq return the entire sequence as a String, and returns the Java pointer instead? I find it annoying when I do this: user (str (map + [1 2 3])) clojure.lang.LazySeq@7861 What's the reason behind this decision? Shouldn't toString trigger the evaluation of the sequence? Doesn't it do that for other values, like numbers and vectors? Is there an alternative to the code above (preferably simple and elegant), which will return the etire sequence? Thanks, Răzvan -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: question about clojure.lang.LazySeq.toString()
Found a post on clojure-dev about this https://groups.google.com/forum/?fromgroups=#!topic/clojure-dev/F68GRPrbfWo On Fri, Mar 22, 2013 at 1:29 AM, Nelson Morris nmor...@nelsonmorris.net wrote: If I'm reading everything correctly: 1. Object 's .toString uses .hashCode() 2. LazySeq 's .hashCode() uses seq() which realizes a seq. 3. LazySeq 's .hashCode() calls .hashCode() on the realized seq 3. (map ..) creates a LazySeq with a fn to create (cons val (lazy-seq (map f rest))) 4. (cons ... ...) creates a Cons 5. Cons uses Aseq's .hashcode() which traverses each object in the seq and merges the hashcodes together. A similar thing happens with a (range) as it builds a ChunkedCons which also uses Aseq's hashcode. On Fri, Mar 22, 2013 at 12:53 AM, Marko Topolnik marko.topol...@gmail.com wrote: I am deeply puzzled abouth the behavior of .toString invocation on a lazy sequence. == (.getClass (map println (range 100))) clojure.lang.LazySeq == (.toString (map println (range 100))) ;; integers 0..100 printed clojure.lang.LazySeq@590b4b81 It should be obvious from the output, but for the record: LazySeq doesn't override toString, so just the basic Java method is called. How can this possibly cause the sequence to be realized? Beyond my curiosity, however, what possible purpose could such behavior serve? -marko On Thursday, March 21, 2013 7:54:39 PM UTC+1, Razvan Rotaru wrote: Hi, I'm curious, why doesn't toString of clojure.lang.LazySeq return the entire sequence as a String, and returns the Java pointer instead? I find it annoying when I do this: user (str (map + [1 2 3])) clojure.lang.LazySeq@7861 What's the reason behind this decision? Shouldn't toString trigger the evaluation of the sequence? Doesn't it do that for other values, like numbers and vectors? Is there an alternative to the code above (preferably simple and elegant), which will return the etire sequence? Thanks, Răzvan -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: question about clojure.lang.LazySeq.toString()
Hrm. Sounds like getting the hash of an infinite sequence will hang or cause OOME. On the one hand, *most* uses of the hash are followed by .equals if the hashes match, and .equals on an infinite seq can't work, since if it gives up and says equal after some large number N of elements, the seqs might still differ at position N + 1, and there's no *general* way to determine in an analytic manner whether two seqs will produce identical output, or even whether they're infinite (even given the generating code, those're equivalent to the halting problem). On the other hand, the above use of the hash does *not* require equals to work. Hash could be changed to use only the first N elements of the seq, at most, for some N, and would then work for such uses as in the generic .toString. On the gripping hand, a) doing this would make infinite seqs *mostly* work in associative data structures, but with intermittent failures (when there were collisions), instead of failing promptly every time, and b) .toString for LazySeq might more productively just produce (the seq), if it's going to fail on infinite seqs anyway. On Fri, Mar 22, 2013 at 2:29 AM, Nelson Morris nmor...@nelsonmorris.netwrote: If I'm reading everything correctly: 1. Object 's .toString uses .hashCode() 2. LazySeq 's .hashCode() uses seq() which realizes a seq. 3. LazySeq 's .hashCode() calls .hashCode() on the realized seq 3. (map ..) creates a LazySeq with a fn to create (cons val (lazy-seq (map f rest))) 4. (cons ... ...) creates a Cons 5. Cons uses Aseq's .hashcode() which traverses each object in the seq and merges the hashcodes together. A similar thing happens with a (range) as it builds a ChunkedCons which also uses Aseq's hashcode. On Fri, Mar 22, 2013 at 12:53 AM, Marko Topolnik marko.topol...@gmail.com wrote: I am deeply puzzled abouth the behavior of .toString invocation on a lazy sequence. == (.getClass (map println (range 100))) clojure.lang.LazySeq == (.toString (map println (range 100))) ;; integers 0..100 printed clojure.lang.LazySeq@590b4b81 It should be obvious from the output, but for the record: LazySeq doesn't override toString, so just the basic Java method is called. How can this possibly cause the sequence to be realized? Beyond my curiosity, however, what possible purpose could such behavior serve? -marko On Thursday, March 21, 2013 7:54:39 PM UTC+1, Razvan Rotaru wrote: Hi, I'm curious, why doesn't toString of clojure.lang.LazySeq return the entire sequence as a String, and returns the Java pointer instead? I find it annoying when I do this: user (str (map + [1 2 3])) clojure.lang.LazySeq@7861 What's the reason behind this decision? Shouldn't toString trigger the evaluation of the sequence? Doesn't it do that for other values, like numbers and vectors? Is there an alternative to the code above (preferably simple and elegant), which will return the etire sequence? Thanks, Răzvan -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from
Re: question about clojure.lang.LazySeq.toString()
Eh. Not just any collisions, but only ones where the succession of tails are equal-as-seqs but not identical as objects (.equals, but not ==) for sufficiently long. So seqs that differ after only a trillion items would blow up. So would equal ones sharing no tail structure. Putting (iterate inc 0) and (range) into a hashset together would fail, and (concat (range 10) [3]) and (concat (range 10) [4]) dropped in together would either fail or make things really, really sloow, depending on whether anything held onto the head of either seq. On Fri, Mar 22, 2013 at 2:37 AM, Cedric Greevey cgree...@gmail.com wrote: Hrm. Sounds like getting the hash of an infinite sequence will hang or cause OOME. On the one hand, *most* uses of the hash are followed by .equals if the hashes match, and .equals on an infinite seq can't work, since if it gives up and says equal after some large number N of elements, the seqs might still differ at position N + 1, and there's no *general* way to determine in an analytic manner whether two seqs will produce identical output, or even whether they're infinite (even given the generating code, those're equivalent to the halting problem). On the other hand, the above use of the hash does *not* require equals to work. Hash could be changed to use only the first N elements of the seq, at most, for some N, and would then work for such uses as in the generic .toString. On the gripping hand, a) doing this would make infinite seqs *mostly* work in associative data structures, but with intermittent failures (when there were collisions), instead of failing promptly every time, and b) .toString for LazySeq might more productively just produce (the seq), if it's going to fail on infinite seqs anyway. On Fri, Mar 22, 2013 at 2:29 AM, Nelson Morris nmor...@nelsonmorris.netwrote: If I'm reading everything correctly: 1. Object 's .toString uses .hashCode() 2. LazySeq 's .hashCode() uses seq() which realizes a seq. 3. LazySeq 's .hashCode() calls .hashCode() on the realized seq 3. (map ..) creates a LazySeq with a fn to create (cons val (lazy-seq (map f rest))) 4. (cons ... ...) creates a Cons 5. Cons uses Aseq's .hashcode() which traverses each object in the seq and merges the hashcodes together. A similar thing happens with a (range) as it builds a ChunkedCons which also uses Aseq's hashcode. On Fri, Mar 22, 2013 at 12:53 AM, Marko Topolnik marko.topol...@gmail.com wrote: I am deeply puzzled abouth the behavior of .toString invocation on a lazy sequence. == (.getClass (map println (range 100))) clojure.lang.LazySeq == (.toString (map println (range 100))) ;; integers 0..100 printed clojure.lang.LazySeq@590b4b81 It should be obvious from the output, but for the record: LazySeq doesn't override toString, so just the basic Java method is called. How can this possibly cause the sequence to be realized? Beyond my curiosity, however, what possible purpose could such behavior serve? -marko On Thursday, March 21, 2013 7:54:39 PM UTC+1, Razvan Rotaru wrote: Hi, I'm curious, why doesn't toString of clojure.lang.LazySeq return the entire sequence as a String, and returns the Java pointer instead? I find it annoying when I do this: user (str (map + [1 2 3])) clojure.lang.LazySeq@7861 What's the reason behind this decision? Shouldn't toString trigger the evaluation of the sequence? Doesn't it do that for other values, like numbers and vectors? Is there an alternative to the code above (preferably simple and elegant), which will return the etire sequence? Thanks, Răzvan -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from
question about clojure.lang.LazySeq.toString()
Hi, I'm curious, why doesn't toString of clojure.lang.LazySeq return the entire sequence as a String, and returns the Java pointer instead? I find it annoying when I do this: user (str (map + [1 2 3])) clojure.lang.LazySeq@7861 What's the reason behind this decision? Shouldn't toString trigger the evaluation of the sequence? Doesn't it do that for other values, like numbers and vectors? Is there an alternative to the code above (preferably simple and elegant), which will return the etire sequence? Thanks, Răzvan -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: question about clojure.lang.LazySeq.toString()
On Mar 21, 2013, at 1:54 PM, Razvan Rotaru razvan.rot...@gmail.com wrote: I'm curious, why doesn't toString of clojure.lang.LazySeq return the entire sequence as a String, and returns the Java pointer instead? I don't know, but perhaps it's to avoid problems with infinite sequences? (Although it's interesting that `(range)` produces a lazy sequence and `(str (range))` runs out of heap.) Is there an alternative to the code above (preferably simple and elegant), which will return the etire sequence? I don't know if it's elegant, but: user= (str (list* (map + [1 2 3]))) (1 2 3) Looking for employment as a Clojure programmer Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: question about clojure.lang.LazySeq.toString()
On Mar 21, 2013, at 2:20 PM, Brian Marick mar...@exampler.com wrote: I don't know if it's elegant, but: user= (str (list* (map + [1 2 3]))) (1 2 3) I wrote too soon. `list*` returns a lazy sequence, not a list, so I guess you shouldn't rely on it. If you don't mind brackets even though lazy sequences usually print as lists, you could do: user= (str (vec (map inc [1 2 3]))) [2 3 4] Looking for employment as a Clojure programmer Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: question about clojure.lang.LazySeq.toString()
On Mar 21, 2013, at 2:30 PM, Brian Marick mar...@exampler.com wrote: If you don't mind brackets Or, if you do mind brackets: user= (str (apply list (map inc [1 2 3]))) (2 3 4) I'll stop now. Looking for employment as a Clojure programmer Latest book: /Functional Programming for the Object-Oriented Programmer/ https://leanpub.com/fp-oo -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: question about clojure.lang.LazySeq.toString()
On Thu, Mar 21, 2013 at 11:54 AM, Razvan Rotaru razvan.rot...@gmail.comwrote: Is there an alternative to the code above (preferably simple and elegant), which will return the etire sequence? (pr-str (map + [1 2 3])) or (print-str (map + [1 2 3])) There are subtle differences between pr-str and print-str, (which I can never remember) but either one works for this scenario. They build a string for how it prints (using either pr or print respectively). -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: question about clojure.lang.LazySeq.toString()
I am deeply puzzled abouth the behavior of *.toString* invocation on a lazy sequence. == (.getClass (map println (range 100))) clojure.lang.LazySeq == (.toString (map println (range 100))) *;;* *integers 0..100 printed* clojure.lang.LazySeq@590b4b81 It should be obvious from the output, but for the record: *LazySeq* doesn't override *toString*, so just the basic Java method is called. How can this possibly cause the sequence to be realized? Beyond my curiosity, however, what possible purpose could such behavior serve? -marko On Thursday, March 21, 2013 7:54:39 PM UTC+1, Razvan Rotaru wrote: Hi, I'm curious, why doesn't toString of clojure.lang.LazySeq return the entire sequence as a String, and returns the Java pointer instead? I find it annoying when I do this: user (str (map + [1 2 3])) clojure.lang.LazySeq@7861 What's the reason behind this decision? Shouldn't toString trigger the evaluation of the sequence? Doesn't it do that for other values, like numbers and vectors? Is there an alternative to the code above (preferably simple and elegant), which will return the etire sequence? Thanks, Răzvan -- -- 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.