--
You received this message because you are subscribed to the Google Groups "ceylon-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
To post to this group, send email to ceylon...@googlegroups.com.
Visit this group at https://groups.google.com/group/ceylon-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/20160720172722.082cd2d4%40dinu.
On Jul 20, 2016, at 9:11 AM, Dirk Lattermann <dl...@alqualonde.de> wrote:
--
You received this message because you are subscribed to the Google Groups "ceylon-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
To post to this group, send email to ceylon...@googlegroups.com.
Visit this group at https://groups.google.com/group/ceylon-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/20160720151101.23d4eb27%40dinu.
Only the JVM backend does, actually. On the JS backend, this can
still be a good idea. See
https://github.com/ceylon/ceylon/issues/6312
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/B977494A-6F5A-4392-AE06-B2665E793503%40vasileff.com.
I made the reader satisfy Iterator instead of Iterable to make it clear
that it can be iterated only once.
--
You received this message because you are subscribed to the Google Groups "ceylon-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
To post to this group, send email to ceylon...@googlegroups.com.
Visit this group at https://groups.google.com/group/ceylon-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/CAOJRyvrRh7JVDQUtaSN7FH_etX%3DP65%2B7w_PW%3DKL%2BCBE5TxgKjw%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "ceylon-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
To post to this group, send email to ceylon...@googlegroups.com.
Visit this group at https://groups.google.com/group/ceylon-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/CAP7PoCcbxb8n3guTHWFpPYCDeZLYn_pwOuY6Jyc5R2orNvmnHQ%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/B3014757-F960-4C9F-913D-63098C1CD056%40vasileff.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/CAOJRyvrEZuuxrL64kVp70f4cwm%3DJY5ZjmgGWZodaTqFBdJoMqg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/CADFF250-F5E3-411C-9460-414DF8E54CBA%40vasileff.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/CAOJRyvpkjm5MfNqC5jOMBC_TTTuTHHYz40tqEFOqeKoubbq_Kg%40mail.gmail.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/155D0234-1E04-470D-9FA0-67DFECBC6876%40vasileff.com.
On Jul 20, 2016, at 8:08 PM, Tako Schotanus <ta...@codejive.org> wrote:So you mean that the results returned from those methods will exhibit the same characteristics as the stream that was used to create it?I'm still not convinced. I look at your `functionIterable` and I look at how `Iterable.first` is implemented and AFAICT if you call it repeatedly it would basically function like a `next`.
To me this is different than having an unstable iteration order and IMO an Iterable that can only be used once should either give correct results or fail with an exception.And from a user's perspective it's not very clear which ones are "safe" to use and which ones aren't (eg. you can safely filter, map and then iterate, but you can't get the value of "first" and then iterate over "rest", at least not with the default implementation).
So it seems to me that at the very least the `functionIterable` would need some more work to make sure the Iterable doesn't behave in all kinds of strange ways when not used exactly right.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/CAOJRyvoUWwCG-Nk3ocpFWXsO0XwFzTChKBrYsRKxRyDQZZV4Aw%40mail.gmail.com.
I'm still not convinced. I look at your `functionIterable` and I look at how `Iterable.first` is implemented and AFAICT if you call it repeatedly it would basically function like a `next`.Note that the parameter for the functionIterable that I pasted is a function that returns a function - <T | Finished>()(). So it’s more tailored for re-iterables. The parameter is analogous to an Iterable, not an Iterator.
And from a user's perspective it's not very clear which ones are "safe" to use and which ones aren't (eg. you can safely filter, map and then iterate, but you can't get the value of "first" and then iterate over "rest", at least not with the default implementation).I’m not sure it’s so important to distinguish the “safe” ones. I “never” assume re-iterability in my code, and instead either memoize or call sequence() when I have to.
If I’m wrong, and we should always use iterator-like-functions for non-re-iterables, then at least the functionIterable idea would provide some relief for when we want to *immediately* call something like map, filter, or sequence.But, really, I “can’t” be wrong, because inevitably, you're going to want to pass a non-re-iterable to some really useful third party utility. And then we’ll just “abuse” functionIterable to do so and be back to square one not knowing which Iterables can only be used once!
On Thu, Jul 21, 2016 at 2:57 AM, Tako Schotanus <ta...@codejive.org> wrote:
>
> Well `Iterable.string` says you're wrong to think everybody else does so too
> ;)
Huh?!
Iterable.string *does* call sequence() to memoize the stream. It does
exactly the thing John is describing.
> Well perhaps there's a way to have a super interface of Iterable that only
> guarantees single-use and only defines those methods that support that?
> Iterable would then be an extension to that where reusability is guaranteed.
> We could then refactor things like for loops and comprehensions to use that
> super interface because they never need to restart their data streams. Is
> that doable?
I don't understand. How would this interface be different to Iterable?
As far as I can tell it would have exactly the same operations.
(Except, perhaps, for paired and partition().)
How would you represents it's singleshotedness within the type system?
I can't quite see how such a thing could be defined.
I don't see how this would be better. It's completely untypesafe,
since nothing in the type system enforces singleshotedness. So you're
introducing a completely useless type to, what, add a *comment* to it?
Definitely not worth the additional complexity.
On Jul 21, 2016, at 5:55 AM, Tako Schotanus <ta...@codejive.org> wrote:Ok true, bad example. But then something as simple as:if (!iter.empty) {for (T item : iter) { }}for example can't work.
I’ve come to believe that Iterables are a pretty low level thing (indeed they are very close to Anything), and if you want to write code in the above style, you’re better off using a a List, Sequential, or something else.
if (!iter.empty) {iter.map(stringify).each(process.write);} else {process.write("nothing to see here")}
Note that even for re-iterables, the ‘iter.empty’ may be expensive, possibly involving opening a file, creating a network connection, querying a database, or performing an expensive calculation.
Rather than trying to come up with yet another Iterable type, I think time is better spent developing utilities and techniques to deal with iterables. For example, the memoizing stream that I posted somewhere before (something that can even be used with infinite streams).
On Jul 21, 2016, at 11:56 AM, Tako Schotanus <ta...@codejive.org> wrote:Note that even for re-iterables, the ‘iter.empty’ may be expensive, possibly involving opening a file, creating a network connection, querying a database, or performing an expensive calculation.Sure, but there's a difference between expensive and impossible.
Rather than trying to come up with yet another Iterable type, I think time is better spent developing utilities and techniques to deal with iterables. For example, the memoizing stream that I posted somewhere before (something that can even be used with infinite streams).That sounds interesting too, where can I take a look at it? And if it's so good why isn't it part of the language module yet? ;)But wouldn't that stream implement Iterable? If not it doesn't seem that useful, because I'd expect it to implement the whole kaboodle of filter, map, scan, count, etc etc etc.
--
You received this message because you are subscribed to the Google Groups "ceylon-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceylon-users...@googlegroups.com.
To post to this group, send email to ceylon...@googlegroups.com.
Visit this group at https://groups.google.com/group/ceylon-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceylon-users/7FF5B811-5D36-416C-916A-B699173E291C%40vasileff.com.
> On Jul 21, 2016, at 3:38 PM, Tako Schotanus <ta...@codejive.org> wrote:
>
> Ok, but doesn't this load the entire stream into memory? As a cons-list on top of that which seems quite wasteful. Or am I missing something here?
>
WTF, of course you can’t load an entire { ++i }.cycled into memory! But yes, it does use *some* memory.
Note that if you follow the pattern 'stream = current.skip(consumed);’ in the function transform() [1], no-longer-relevant leading portions of the stream will be gc'd.
On Jul 21, 2016, at 4:39 PM, Tako Schotanus <ta...@codejive.org> wrote:(Also I'm only looking at one-shot streams, the ones this thread started with)
Note that if you follow the pattern 'stream = current.skip(consumed);’ in the function transform() [1], no-longer-relevant leading portions of the stream will be gc'd.That sounds interesting, but how does it work exactly? Can't you give a short explanation how your Stream does what it does?
(Also I'm only looking at one-shot streams, the ones this thread started with)But it’s *also* wrong to consume expensive or mutable streams more times than necessary. So saying, “don’t call ‘first' on one-shot streams” isn’t sufficient, and therefore a solution to *just* that isn’t valuable.
On Jul 21, 2016, at 6:45 PM, Tako Schotanus <ta...@codejive.org> wrote:On Thu, Jul 21, 2016 at 11:15 PM, John Vasileff <jo...@vasileff.com> wrote:(Also I'm only looking at one-shot streams, the ones this thread started with)But it’s *also* wrong to consume expensive or mutable streams more times than necessary. So saying, “don’t call ‘first' on one-shot streams” isn’t sufficient, and therefore a solution to *just* that isn’t valuable.
Well that was my whole point in suggesting a super type with only those method that make sense for a one-shot stream.
Of course I could make an Iterable that takes an Iterator and just implements those methods and throws NotImplementedExceptions for anything else. But I could never be sure that some change in the future of how Ceylin implements for loops/comprehensions wouldn't break looping over them.
A dedicated super type *could* solve that. But Gavin already explained why that wouldn't be a good idea either.Anyway, all this hasn't gotten us one inch closer to something nicer than what Dirk wrote in his first message which sucks.
If that really is the intention, I think that's very error-prone.