[swift-evolution] [Pitch] Non-class type requirements on protocols (eg : struct, : enum)

Mike Kasianowicz mike at ap14.com
Fri Oct 21 12:29:35 CDT 2016


Hooray, I'm not the only one.

I agree copying is a much more nuanced issue- but sometimes struct is close
enough.

What I would really like is "this is a data-only type" rather than
"struct".  But short-term, I'd take the struct restriction if it's a simple
change. If we ever had a more specific constraint like that, my
hypothetical API will break many more clients if people have implemented my
protocol as a class.  I'm considering runtime enforcement, but this is
clearly something that the compiler can do, and the question is whether it
should.  I would argue yes - one of the great things about Swift is getting
your head out of the technical weeds and thinking at a higher level.

Protocol-oriented programming could be much more concise and allow for some
really awesome high-level things to be done and enforced - ex: MVC, MVVM,
MVP, VIPER whatever your UI approach is today - you could codify the
infrastructural paradigm and then require data-only types for the models,
or enum-only types for the events, to prevent dependency violations.  Great
for making frameworks safer, enforcing coding standards, etc.

Maybe long-term there could be user-defined constraints similar to the
proposed property decorator/annotation notation?

On Fri, Oct 21, 2016 at 11:38 AM, T.J. Usiyan <griotspeak at gmail.com> wrote:

> I would like the ability to specify that something is an enum so that I
> could model a generic `Result` type.
>
> ```
> protocol Result : enum {
>     associatedtype Payload
>     case success(Payload)
>     case failure(Error)
> }
> ```
>
> the basic idea being that I could then, while conforming, state which
> cases in the concrete type serve as the protocol's case.  I don't have a
> great vision for the syntax of spelling this conformance so I will make
> this painfully verbose to be clear
>
> ```
> enum UserParseResult {
>     case success(User)
>     case failure(Error)
> }
>
> extension UserParseResult : Result {
>     protocol(Result) case success = UserParseResult.success
>     protocol(Result) case failure = UserParseResult.failure
> }
> ```
>
>
> The benefit of this, in my opinion, is that we could have code commonly
> used on results everywhere written once on the protocol without sacrificing
> the ability to switch with guarantees. I can see that this suggestion has
> some rough points so all I will finish by restating the problem that I want
> to solve.
>
> There is code that is fairly common to enum types that have shared
> characteristics and/or purpose. I would find it useful to have a way to
> implement shared algorithms in a generic way while retaining core features
> of enums.
>
> On Fri, Oct 21, 2016 at 11:11 AM, Mike Kasianowicz via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> Just from an outside perspective, the class restriction seems to be there
>> as a kludge for technical reasons... but that's neither here nor there.
>>
>> It is not so much to enforce a lack of identity - in the struct case, it
>> would be to enforce copy-by-value semantics.  I think the strongest
>> argument I've got is, say, a serialization or caching framework where you
>> want to enforce that something is entirely writeable via memory pointer or
>> copyable.  A value-type restriction would get us mostly there, albeit there
>> would still be ways to break the contract.  However, as noted in my
>> previous email, I see a lot of possibilities for enums too - in that case
>> the protocol somewhat acts as 'base type' without adding the complexity of
>> a base type.
>>
>> I listed some of my examples in my previous email - I could elaborate if
>> it helps.
>>
>> On Fri, Oct 21, 2016 at 9:51 AM, Karl Wagner <razielim at gmail.com> wrote:
>>
>>> IIRC, the reason we have "class" there is for the optimiser, so it can
>>> optimise for the protocol being satisfied by a reference-counted type.
>>> Classes are semantically unique from values because they have identity,
>>> which is also something a protocol might want to codify.
>>>
>>> There may be some optimisation gains by requiring all conformers to be
>>> values, but I struggle to think of why you might want to codify that a
>>> conformer should not have identity.
>>>
>>> Personally I don't really like this asymmetry in the language either,
>>> and would support changes to make these two elements more explicit. For
>>> example, a magic "hasIdentity" protocol which is automatically satisfied
>>> only by classes, and moving the optimisation guides to usage site (e.g.
>>> when declaring a variable of type MyProto, I could declare it of type
>>> AnyClass<MyProto> or AnyValue<MyProto> instead, to annotate this specific
>>> instance as being refcountable or not, without making such optimisation
>>> hints part of the MyProto definition)
>>>
>>> - Karl
>>>
>>>
>>> On Oct 21, 2016 at 8:39 am, <Mike Kasianowicz via swift-evolution
>>> <swift-evolution at swift.org>> wrote:
>>>
>>> Currently protocols can have the class constraint:
>>> protocol MyProtocol : class {}
>>>
>>> It would be (a) intuitive and (b) useful to allow such things as:
>>> protocol Model : struct {} or protocol Event : enum {}
>>>
>>> These types of restrictions can help prevent accidental anti-patterns or
>>> misuse of APIs.
>>>
>>> Seems simple and non-controversial... right?
>>>
>>> [Note: I'd like to see even more heavy-handed protocol restrictions in
>>> the future.  For example, a protocol describing an enum with a common case,
>>> or a struct with no reference members. Great stuff for defensively coding
>>> APIs.]
>>> _______________________________________________ swift-evolution mailing
>>> list swift-evolution at swift.org https://lists.swift.org/mailma
>>> n/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/20161021/7e6fb624/attachment.html>


More information about the swift-evolution mailing list