> On Nov 14, 2017, at 9:06 PM, Brent Royal-Gordon via swift-dev
> <[email protected]> wrote:
>
>> On Nov 14, 2017, at 5:21 PM, Xiaodi Wu <[email protected]
>> <mailto:[email protected]>> wrote:
>>
>> 1. It must be possible to easily access the count of values, and to access
>> any particular value using contiguous `Int` indices. This could be achieved
>> either by directly accessing elements in the list of values through an Int
>> subscript, or by constructing an Array from the list of values.
>>
>> 2. It must be possible to control the order of values in the list of values,
>> either by using source order or through some other simple, straightforward
>> mechanism.
>>
>> OK, first of all, nowhere in the proposal text are these requirements stated
>> as part of the use case. You're free to put forward new use cases, but here
>> I am trying to design the most elegant way to fulfill a stated need and
>> you're telling me that it's something other than what's written.
>
> Honestly, re-reading the proposal, it never cites a fully-formed use case.
> Instead, it cites several blog posts, Stack Overflow questions, and small
> code samples without digging in to the underlying reasons why developers are
> doing what they're doing. Most of the people discussing it so far seem to
> have had a tacit understanding that we wanted roughly Array-like access, but
> we haven't explicitly dug into which properties of an Array are important.
>
> (If anyone involved feels like they had a different understanding of the use
> case, please speak up.)
>
> I think this is a place where the proposal can be improved, and I'm willing
> to do some writing to improve it.
This is a feature I have been requesting since Swift 1. If the resulting
ordering is not SOURCE ordering, this feature loses most of it’s usefulness for
me. I would say around 80% of my uses for this require a predictable ordering
(and I don’t consider something based on compiler internals predictable) which
I can control. As Brent said, most of those cases involve something that shows
to the user in some way. The weekday example was a good one (I actually have
that in my code).
The most painful case of this being missing was where I needed an enum of all
country codes (it is a beast to maintain). In that case, I am displaying them
to the user in a tableView (along with icons named by the country codes), but I
am also filtering them based on the user’s input in a search field. To do
both, you need to be able to iterate/filter an array of cases. Awful to build.
Just awful.
Also, I would greatly prefer an allValues/allCases method to having the type be
a collection. It just reads clearer in code what is going on. I think what I
basically want to see is:
protocol ValueEnumerable {
var allValues:Collection<Self>
}
…where both the conformance and implementation are automatically inferred for
enums when possible.
I would probably also end up using this protocol on Structs that I use as
extensible enums. That is, I have a private/internal initializer and use
static vars in place of the cases. This isn’t perfect, since part of the
reason I use these structs is that they can be built in a distributed way… but
I could find a way to build that array in a mostly distributed way as well (and
if we ever get the Multi-function capability I have suggested elsewhere, then
it could be truly distributed).
Semantically, the protocol should infer not only a finite number of cases, but
a number that can be iterated over in a reasonable period of time. I would be
fine with Bool conforming, but not with Int. With those semantics, I could
easily see a follow-on proposal which says that associated cases where all of
the values are ValueEnumerable are ValueEnumerable themselves. This would be
super useful for cascading enums. I have a game that I am working on in my
spare time right now, where effects of actions are represented as enums, with a
single enum for all effects that references more specific enums for each type
of thing that can be affected.
One other common need which I feel I should bring up even though it is a bit
tangential, is that when I have enums with associated values, 90% of the time,
I end up wanting a way to refer to the base of that without the value. For
example, if the player has a case called ‘damage’ which has an associated Int,
I end up wanting to ask (and sometimes store) if the case is a ‘damage’ case.
Often, I am trying to match against patterns: Were there two damages followed
by a block? What I end up doing is creating a second enum with the same cases
(sans values) and then creating a mapping between the two. Busywork in the same
way writing these allValues arrays are busywork. If we end up creating a way
to reference just the base, maybe the allValues array should just contain those
bases for non-enumerable associated values. Food for thought.
Thanks,
Jon
_______________________________________________
swift-dev mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-dev