Hey José!

My thoughts aren't to make guarantees of constant-time access, just 
linear-time access, which seems reasonable as the main index-accessible 
data structure in Elixir, lists, makes the same promise. As such I am 
inclined to agree with you--implementing Sequential for tuples and binaries 
could distract from the superior pattern-matching method of negotiating 
them. Just because we could doesn't mean we should.

I propose a new protocol mostly because I feel as if Enum is doing its job 
really well––allowing you to yield values from collections. The only 
awkwardness I find in its API are the cases where it has functions that 
make assumptions about countability and termination, at the risk of falling 
into an infinite loop. If we moved these to a dedicated protocol we could 
be more assertive about the type incompatibility and failure cases of these 
functions.

Taken to its logical conclusion, this module would eat Enum.at/2, and 
perhaps even Enumerable.count/1. This would be a major API change, but 
allow us be explicit about when we're handling countable collections, and 
countable infinities.

Things like Sequence.product/{1,2} could be added to Enum instead, but a 
large part of the appeal of this proposal is, to me, slimming down the Enum 
module by moving these index-oriented assumptions into a devoted protocol. 
The question is if this is desirable enough to make the breaking change in 
Enum.

As such, consider my proposal to hinge on the merits of:

1. Guarantees of linear-time index access
2. Enforcing explicit handling of countable collections
3. Consistent failure modes around negative index access of interminable 
sequences
4. Slimming down Enum and Enumerable a little
5. Adding a possible avenue to introducing an Access-style formalism for 
non-atom (ie integer index) values

Some cases where these distinctions seem useful to me:

- Most streams are logically Enumerable and Sequential, but not necessarily 
terminable
- Database tables and key-value stores are logically Enumerable, but not 
necessarily Sequential
- Monotonically increasing random number generators might be meaningfully 
Enumerable but more usefully Sequential
- Ranges are meaningfully Sequential; MapSets less so
- Providing a non-destructive Stream.sequence/1 that converts a stream an 
index-accessible struct that caches produced values for access later 
(useful in the implementation of Sequence.product/{1, 2}, being the example 
that prompted me to start thinking about such a protocol)

The functions in Sequence would handle explicitly addressing individual 
elements by index, so I'm not sure if worrying about keeping the same shape 
is a concern. If we opt to include things like Sequence.slice/2 in there 
they could make the same list-oriented guarantees as Enum and require you 
to reach into Collectable if you need a particular resulting type––that is 
what that module is for after all.

With these clarifications and motivations, do you think the API change 
would be worth the effort? I'd rather see this not go anywhere than further 
widen the Enum module's API, so I think the addition of a new protocol and 
probably deprecation of other functions is a key part of the proposal.

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/04d0e315-168a-4832-9d4b-ca15bb3bb6e2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to