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

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

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

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

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




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

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

2013-03-21 Thread Brian Marick

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

2013-03-21 Thread Brian Marick

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

2013-03-21 Thread Brian Marick

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.