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 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 > 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 >> 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...@goog
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 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 > 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 ht
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 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 > 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()
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 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()
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.
Re: question about clojure.lang.LazySeq.toString()
On Thu, Mar 21, 2013 at 11:54 AM, Razvan Rotaru wrote: > 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()
On Mar 21, 2013, at 2:30 PM, Brian Marick 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 Mar 21, 2013, at 2:20 PM, Brian Marick 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 1:54 PM, Razvan Rotaru 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.
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.