Re: question about clojure.lang.LazySeq.toString()

2013-03-22 Thread Nelson Morris
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()

2013-03-22 Thread Nelson Morris
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()

2013-03-22 Thread Cedric Greevey
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()

2013-03-22 Thread Cedric Greevey
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()

2013-03-21 Thread Razvan Rotaru
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()

2013-03-21 Thread Brian Marick

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()

2013-03-21 Thread Brian Marick

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()

2013-03-21 Thread Brian Marick

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()

2013-03-21 Thread Mark Engelberg
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()

2013-03-21 Thread Marko Topolnik
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.