And to further explicate "bewildering" -- I mean that I only figured out
what was happening because I was explicitly testing a library against
1.7.0-RC1 and even then had to `git bisect` *Clojure* to find the offending
commit.  Otherwise the resulting behavior is just that values generated via
the deep guts of a complex Java API suddenly became nonsensical.

On Tue, May 26, 2015 at 9:45 PM Marshall Bockrath-Vandegrift <
llas...@gmail.com> wrote:

> Ugh -- looks like the iterator value re-use behavior for EnumMap entrySet
> was "fixed" post Java 1.6 (my example was under Java 1.6, which I believe
> is still a Clojure-supported version of Java?).  I can throw together a
> synthetic example, but I think the people following this thread get what's
> happening.  The point isn't whether this pattern is a "good idea" or not
> (it certainly isn't) but whether existing Java APIs people want to interop
> with use it (they certainly do).
>
> I presently depend on no less than 3 separate Java library APIs I
> currently know for a fact depend on this behavior:
> - Hadoop ReduceContextImpl$ValueIterator
> - Mahout DenseVector$AllIterator/NonDefaultIterator
> - LensKit FastIterators
>
> It is an option to explicitly construct `IteratorSeq` instances (I
> actually had verified that approach this afternoon for the Hadoop API in
> Parkour), but I'm not happy about it. That approach places a definite
> burden on integration library maintainers to implement the change, and on
> end-users to realize they need to upgrade for Clojure 1.7 compatibility.
> The `Iterator` interface just fundamentally in no way guarantees that the
> `next()` yielded values are functional-safe in the sense necessary to
> support chunking. I understand the desire to increase performance, but I
> don't think it's worth the potential silent and bewildering breakage in
> interop.
>
>
> On Tue, May 26, 2015 at 9:18 PM Alex Miller <a...@puredanger.com> wrote:
>
>> That's not what I see with 1.7.0-RC1 (or any of the betas). I tried with
>> both Java 1.7.0_25 and 1.8.0-b132.
>>
>> user=> *clojure-version*
>> {:major 1, :minor 7, :incremental 0, :qualifier "RC1"}
>> user=> (->> (map vector (java.util.EnumSet/allOf
>> java.util.concurrent.TimeUnit) (range)) (into {}) (java.util.EnumMap.)
>> (.entrySet) (map str) (into []))
>> ["NANOSECONDS=0" "MICROSECONDS=1" "MILLISECONDS=2" "SECONDS=3"
>> "MINUTES=4" "HOURS=5" "DAYS=6"]
>>
>> Re "implementing the not-uncommon Java pattern of mutating and
>> re-yielding the same object on each `next()` invocation". I'm assuming that
>> you're somehow expecting to traverse one seq node, then having an
>> opportunity to mutate something (the source, the iterator, the return
>> object) in between each new advancement of the seq node? That seems a) not
>> common at all, b) a bad idea even in Java and c) dangerous even before this
>> change. In either case you end up with a seq that points to a succession of
>> the same repeated (mutable and mutating) object - this violates most
>> expectations we as Clojure users have of sequences. Any sort of chunking
>> (map, filter, etc) over the top of that seq would force realization up to
>> 32 elements beyond the head causing the same issue.
>>
>> The original one-at-a-time IteratorSeq is still there (for now) and you
>> can still make one if you want via (clojure.lang.IteratorSeq/create iter)
>> but I would consider it deprecated. I think a custom lazy-seq or a
>> loop-recur would be a better way to handle this case, which in my opinion
>> is highly unusual. That said, my ears are open if this is an issue for a
>> large number of people.
>>
>>
>> On Tuesday, May 26, 2015 at 6:24:54 PM UTC-5, Marshall
>> Bockrath-Vandegrift wrote:
>>>
>>> The difference is that the original behavior allowed room to transform
>>> the mutated object into an object which *could* be safely cached in a
>>> "downstream" seq, while the new behavior pumps the iterator through 32
>>> mutations before user-level code has a chance to see it.  Contrived example
>>> using the Java standard libary:
>>>
>>> Clojure 1.6.0:
>>> (->> (map vector (java.util.EnumSet/allOf java.util.concurrent.TimeUnit)
>>> (range)) (into {}) (java.util.EnumMap.) (.entrySet) (map str) (into []))
>>> #=> ["NANOSECONDS=0" "MICROSECONDS=1" "MILLISECONDS=2" "SECONDS=3"
>>> "MINUTES=4" "HOURS=5" "DAYS=6"]
>>>
>>> Clojure 1.7.0-RC1:
>>> (->> (map vector (java.util.EnumSet/allOf java.util.concurrent.TimeUnit)
>>> (range)) (into {}) (java.util.EnumMap.) (.entrySet) (map str) (into []))
>>> #=> ["DAYS=6" "DAYS=6" "DAYS=6" "DAYS=6" "DAYS=6" "DAYS=6" "DAYS=6"]
>>>
>>> IMHO the latter behavior demonstrates a mismatch where chunked seqs and
>>> iterators are simple incompatible.
>>>
>>> On Tue, May 26, 2015 at 5:33 PM Alex Miller <a...@puredanger.com> wrote:
>>>
>>>> In what way is it broken? Both before and after wrapped a mutable
>>>> iterator into a caching seq. The new one is different in that it chunks so
>>>> reads 32 at a time instead of 1. However combining either with other
>>>> chunking sequence operations would have the same effect which is to say
>>>> that using that mutable iterator with anything else, or having expectations
>>>> about its rate of consumption was as dubious before as it is now.
>>>>
>>>> Unless of course I misunderstand your intent, which possible because I
>>>> am on a phone without easy access to look further at the commit and am
>>>> going by memory.
>>>>
>>>>
>>>>
>>>> On May 26, 2015, at 2:17 PM, Marshall Bockrath-Vandegrift <
>>>> llas...@gmail.com> wrote:
>>>>
>>>> Some of my code is broken by
>>>> commit c47e1bbcfa227723df28d1c9e0a6df2bcb0fecc1, which landed in
>>>> 1.7.0-alpha6 (I lasted tested with -alpha5 and have been unfortunately busy
>>>> since).  The culprit is the switch to producing seqs over iterators as
>>>> chunked iterators.  This would appear to break seq-based traversal of any
>>>> iterator implementing the not-uncommon Java pattern of mutating and
>>>> re-yielding the same object on each `next()` invocation.
>>>>
>>>> I'm unable to find an existing ticket for this apparent-regression.
>>>> Should I create one, or did I miss the existing ticket, or is there some
>>>> mitigating issue which makes this a non-problem?
>>>>
>>>> Thanks.
>>>>
>>>> -Marshall
>>>>
>>>> On Thu, May 21, 2015 at 12:31 PM Alex Miller <a...@puredanger.com>
>>>> wrote:
>>>>
>>>>> Clojure 1.7.0-RC1 is now available.
>>>>>
>>>>> Try it via
>>>>> - Download:
>>>>> https://repo1.maven.org/maven2/org/clojure/clojure/1.7.0-RC1/
>>>>> - Leiningen: [org.clojure/clojure "1.7.0-RC1"]
>>>>>
>>>>> The only change since 1.7.0-beta3 is CLJ-1706, which makes reader
>>>>> conditional splicing an error at the top level (previously it would
>>>>> silently drop all but the first spliced element).
>>>>>
>>>>> For a full list of changes since 1.6.0, see:
>>>>> https://github.com/clojure/clojure/blob/master/changes.md
>>>>>
>>>>> Please give it a try and let us know if things are working (or not).
>>>>> The more and quicker feedback we get, the sooner we can release 1.7.0 
>>>>> final!
>>>>>
>>>>> - Alex
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "Clojure Dev" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to clojure-dev+unsubscr...@googlegroups.com.
>>>>> To post to this group, send email to clojure-...@googlegroups.com.
>>>>> Visit this group at http://groups.google.com/group/clojure-dev.
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>  --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure Dev" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to clojure-dev+unsubscr...@googlegroups.com.
>>>> To post to this group, send email to clojure-...@googlegroups.com.
>>>> Visit this group at http://groups.google.com/group/clojure-dev.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>>  --
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure Dev" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to clojure-dev+unsubscr...@googlegroups.com.
>>>> To post to this group, send email to clojure-...@googlegroups.com.
>>>> Visit this group at http://groups.google.com/group/clojure-dev.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>  --
>> You received this message because you are subscribed to the Google Groups
>> "Clojure Dev" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure-dev+unsubscr...@googlegroups.com.
>> To post to this group, send email to clojure-...@googlegroups.com.
>> Visit this group at http://groups.google.com/group/clojure-dev.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
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/d/optout.

Reply via email to