-
Notifications
You must be signed in to change notification settings - Fork 167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Seq.lazy() #306
Add Seq.lazy() #306
Conversation
Ha! I can't believe it but I've just realized (thanks to @lukaseder's link to certain StackOverflow issue which directed me to this issue: http://stackoverflow.com/questions/29229373/why-filter-after-flatmap-is-not-completely-lazy-in-java-streams) that This means that the implementation of |
Thanks again for your suggestion. I won't rename-and-close it this time, promised. :) However, I'm still not convinced that this feature pulls its weight to be published in the public API. As we move on, improving jOOλ, we might add this feature as an internal optimisation, but perhaps, |
Well, I'm quite convinced it's useful internally (as But well, maybe you're right that it's not important enough to be placed in the public API. Relating to our discussion on
The lazy methods you added ( So my last shot - maybe the method should simply be named differently, e.g. |
Yes, I agree. That would be much better for now. See, I don't oppose putting something really useful in the public API eventually, and I do agree that your suggested improvements of
I'm still not convinced of the utility to the public API of the concept, regardless of the name. If we do add something like this to the public API, we'll also need tons of overloads and these need to be well-designed. I do agree with your improvement for now, if we can keep it internal. |
I want to say that I really appreciate your care for not adding anything to the public API without enough consideration :) To me, well-though API is one of the main strengths of jOOλ. Yet, responding to your words that "we cannot remove it anymore", I hope you mean that we cannot remove it anytime soon, and that a policy like Guava's (deprecate in one major release, remove in the following major release) can be taken into consideration here :) That said, I propose the following:
|
Sure. Infinity is aproximately 2-3 years. :) But why deprecate/remove if we can simply not add.
Yes.
If you insist :) |
Sure, deprecation and removal are the last resort - it's much better not to add if in doubt :)
Well, maybe I miss something but this non-laziness during constructing a So I'll exploit your courtesy in this matter ;) |
I don't see this as being serious. Array allocation is relatively cheap (I'd even bet on escape analysis to kick in, perhaps), compared to the bad algorithmic complexity we still have in many other method implementations. Besides, laziness has its "caveats". Consider this: Seq<Integer> mymethod(int a, int b, int c) {
if (someCheck)
return Seq.supply(() -> Seq.of(a, b, c));
else
return Seq.empty();
} Now, your lambda is capturing scope. This scope might be a heavy class with heavy state that is now referenced by this It's just an example. Perhaps, you can show me some really serious trouble when allocating this array... |
Well, I wouldn't like to use it to defer array initialization (which, as you mentioned, is cheap). Instead, I had two use cases in mind:
return Seq.supply(() -> Seq.seq(computeExpensiveOptional(param))); or several expensive computations: return Seq.supply(() -> Seq.seq(computeExpensive1(a), computeExpensive2(b))); However, I've just realised that in the second example you'd still unnecessarily precalculate the second element so As for the first example, I now think it'd be much better to use a method like this: static <T> Seq<T> seq(Supplier<Optional<? extends T>> s); which we obviously can't add under this name because of type erasure (and because overloading methods taking lambdas is generally a bad idea). But we could add it under a different name - maybe something like return Seq.supplyOptional(() -> computeExpensiveOptional(param)); |
(Just a short note, I haven't forgotten about the pending changes. Thanks for your patience :) ) |
The PR got closed by github due to a recent rename of the main branch. I'm sorry, I don't want to re-iterate this |
This is my second attempt to propose
Seq.lazy()
(see #302 for details).Here, I propose it together with the reimplementations of the following methods mentioned in #195 (in order to demonstrate the real usefulness of
Seq.lazy
):shuffle()
(provided simpler implementation)reverse()
removeAll()
retainAll()
window()
(this has to be adapted by @lukaseder injOOQ-tools
)I did not reimplement the following methods (although they eagerly call
iterator()
orspliterator()
, they do not try to iterate it immediately so they don't seem to be problematic in practice):zip()
,zipAll()
SeqUtils.transform()
grouped
partition
(returnsTuple
- could not useSeq.lazy
)duplicate()
(returnsTuple
- in this particular case I'd implement it usingSeqBuffer
proposed in Added SeqBuffer<T> class as a replacement for some of Seq.toList() calls #305)Reimplementation of the remaining methods mentioned in #195 (i.e. all kinds of
join
s) was proposed in #305.