[swift-evolution] [Review] SE-0081: Move where clause to end of declaration

Karl Wagner razielim at gmail.com
Sat May 14 19:26:08 CDT 2016


> IMHO proposals like this should never be discussed in the context of trivial examples as the full scope of their value gets lost. I have written enough generics code in other languages to appreciate the idea of a 'headline-form-followed-by-the-details-idea' for any complex declaration. My understanding is that the proposal offers to make us write explicitely what anyone reading the code will try to extract out of the declaration. Instead of 100's or 1000's doing the work in their heads, the code author does it once for all subsequent readers. What's not to like about this idea?

There is a lot not to like about the idea; even if it was optional. Personally, I feel the problem is solved in a much, much more elegant manner by other proposals.

Firstly, the stuff after the ‘where’ clause is getting shorter once typealiases come to protocols. C.Iterator.Element become C.Element. In this one example, that’s 18 characters down to 9 - a 50% reduction in length. We tend to use quite expressive names for associated types, so I expect we’ll see similar gains elsewhere from this very simple proposal.

Not only that, but there’s a very good proposal to add ‘where’ clauses to associated types in the protocols themselves, which will likely further reduce the verbosity of the constraints you need to specify at each declaration site. https://github.com/hartbit/swift-evolution/blob/9acd75abfbe626bbb3f9458cc3f6edb1d1f88c95/proposals/XXXX-associated-types-constraints.md <https://github.com/hartbit/swift-evolution/blob/9acd75abfbe626bbb3f9458cc3f6edb1d1f88c95/proposals/XXXX-associated-types-constraints.md>

And then we have generic typealiases and generalised existentials, which would allow us to wrap those ‘where’ clauses in to something much more intelligible to a human being at first glance. ‘StringCollection’ or ‘CollectionOfStrings’ is much clearer than <C:Collection where C.Element==String>, no matter how you chop it up.

If I look at the other proposals, and where we are headed with much more expressive typealiases and associated types, I just feel that that’s the future: that’s the “swift’ way. It’s like type inference - all of the strict constraints are still there under-the-hood, but you’re able to work at a much clearer and more obvious abstraction level. This proposal pulls us further away from things like ‘obviousness’, and like I said, simply feels like an inelegant solution.

At the very least, I think we should shelve the discussion until the larger expansion of typealiases, etc is complete. We should re-evaluate at that time, with a bigger set of more general-purpose tools to produce readable code.


> On 14 May 2016, at 22:28, L. Mihalkovic via swift-evolution <swift-evolution at swift.org> wrote:
> 
> 
> 
> On May 14, 2016, at 9:43 PM, Pyry Jahkola via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> 
>> Tony & Haravikk,
>> 
>> (Reformatting your quoted examples just a bit…)
>> 
>>>> It enables things like:
>>>>     func someMethod<S : SequenceType, T>(value: S) -> AnySequence<T>
>>>>         where S.Generator.Element == T { ... }
>>> 
>>> I'm not assuming that. Under the current syntax, I would format your example as:
>>> 
>>>     func someMethod<
>>>         S : SequenceType, T
>>>         where S.Generator.Element == T
>>>     >(value: S) -> AnySequence<T> {
>>>         ...
>>>     }
>> 
>> You are both right here, but please note that the proposal still also allows moving all constraints to the `where` clause:
>> 
>>     func someMethod<S, T>(value: S) -> AnySequence<T>
>>         where S : SequenceType,
>>               S.Generator.Element == T
>>     {
>>         ...
>>     }
>> 
>> just like Swift 2 allows doing so within the `<...>` brackets:
>> 
>>     func someMethod<S, T
>>         where S : SequenceType, S.Generator.Element == T
>>     >(value: S) -> AnySequence<T> {
>>         ...
>>     }
>> 
>> The reason I'd recommend that style for anything but simple constraints is because:
>> 
>> 1) It makes the call site `let items = someMethod(value: things)` lightest to visually match to the declaration, because the only thing between the function name and its argument list is the `<...>` bracketed list of introduced generic types which you'll expect to see in the function signature and constraints.
>> 
>> 2) In general, the `where` constraints really apply to the whole function/type declaration, not just a single generic parameter.
>> 
>> 3) It was claimed that all constraints should go right next to the introduction of the generic parameters. But that isn't the whole case because Swift also applies implicit constraints onto any generic parameters that are used in constrained positions. If that wasn't clearly said, take the following example in Swift 2.x:
>> 
>>     func aMethod<S : SequenceType, T where S.Generator.Element == T>(value: S) -> Set<T> {
>>         return Set(value)
>>     }
>> 
>> That declaration actually makes you wait all the way until the return type `Set<T>` until you learn that `T` must also necessarily be `Hashable`. So I don't see how it's that different if the `where` clause isn't right next to the generic type arguments' introduction:
>> 
>>     func aMethod<S, T>(value: S) -> Set<T> // FWIW, this line contains what I usually have in mind when browsing code.
>>         where // T : Hashable, // (implicit)
>>               S : SequenceType,
>>               S.Generator.Element == T
>>     {
>>         return Set(value)
>>     }
>> 
>> — Pyry
>> 
> 
> 
> 
>> PS. Besides, neither the original example nor mine was really fair; you don't need `where` for these. Instead, you'd just write:
>> 
>>     func someMethod<S : SequenceType>(value: S) -> AnySequence<S.Generator.Element> {
>>         ...
>>     }
>> 
>> which SE-0081 has nothing to argue for or against.
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160515/832c849a/attachment.html>


More information about the swift-evolution mailing list