Specify type of a delegate which conforms to a protocol

I think this proposal should stick to the intersection type: a type which
inherits from at most one class (multiple inheritance should definitely be
a separate proposal) if it conforms to all of one or more specified
protocols.

The immediate problem I see with a union type is using it. If I'm
understanding it right, this would let me define a union type of
any<UITextView, UITextField>, to a variable 'textControl'. I might then be
able to set 'textControl.text' to a value, regardless of whether it's
actually a UITextView or UITextField. But the correct way to do this would
be to create a protocol (say) 'HasTextProperty', extend UITextView and
UITextField to conform to HasTextProperty, and use that. The intersection
type would even let us extend the type safety of 'textControl' to
'all<UIView, HasTextProperty>'.

The next issue I'd see with the union type is that it's the already
proposed Either type.

-- Ross

···

On Thu, Feb 11, 2016 at 1:10 PM, Maximilian Hünenberger < m.huenenberger@me.com> wrote:

I don't see union and intersection types either in the "goals list" or in
the "non-goals list". Either way it should be a separate proposal.

- Maximilian

Am 11.02.2016 um 09:29 schrieb Thorsten Seitz <tseitz42@icloud.com>:

Ceylon uses & for intersection types (and | for union types) which I find
quite intuitive, meaning a type which conforms to this AND that
protocol/type (OR in the case of unions).

It works like expected, i.e.
A & B & A == A & B

or
typealias A = B & C
A & C == B & C
A & D == B & C & D

class A<T> {
        var x: T & B
}

var a: A<C>
a.x has type C & B

var b: A<B>
b.x has type B

etc.

-Thorsten

Am 10.02.2016 um 14:59 schrieb Ross O'Brien via swift-evolution < > swift-evolution@swift.org>:

I agree with everything Brent just said.
My question would then be: how does this extend?

Continuing the example:
'typealias ViewControllerTableViewDataSource = all<UIViewController,
>'

It should then be possible to have a subtype of this which also conforms
to UITableViewDelegate.
So, given the above, this would work:
'typealias ViewControllerTableViewPackage = all<UIViewController,
UITableViewDataSource, UITableViewDelegate>'.
Would this also work?
'typealias ViewControllerTableViewPackage =
all<ViewControllerTableViewDataSource, UITableViewDelegate>'
Assuming someone defined this typealias: 'typealias TableViewPackage =
protocol<UITableViewDataSource, UITableViewDelegate>', would the above also
be equivalent to this?:
'typealias ViewControllerTableViewPackage = all<UIViewController,
>'

The TableViewPackage protocol, defined above, is considered by Swift to be
a 'non-nominal type'. Thus this is illegal:
'extension TableViewPackage'
(I don't know why. Perhaps a type conforming to the separate protocols has
to opt-in to the combination?)

However, we can have the following:
'extension UITableViewDelegate where Self : UITableViewDataSource'
'extension UITableViewDelegate where Self : UIViewController'
'extension UITableViewDelegate where Self : UIViewController, Self :
UITableViewDataSource'

Similarly we can't currently have this:
'extension UIViewController where Self : UITableViewDataSource,
UITableViewDelegate'
because UIViewController is not a generic type (and this is part of the
original complaint).

It would be nice to be able to write this out as: 'extension
all<UIViewController, UITableViewDataSource, UITableViewDelegate>', even if
it's just syntactic sugar for 'extension UITableViewDelegate where Self :
UIViewController, Self : UITableViewDataSource'.

-- Ross

On Wed, Feb 10, 2016 at 1:44 PM, Maximilian Hünenberger < > swift-evolution@swift.org> wrote:

In the thread "Partially constrained protocols" we have discussed a
similar approach using where clauses:

        protocol<MyProtocol where Self: UIViewController>

- Maximilian

Am 10.02.2016 um 14:00 schrieb Brent Royal-Gordon via swift-evolution < >> swift-evolution@swift.org>:

>> So, I definitely think there is room for improvement here… how about
recycling the inheritance syntax?
>>
>> let controller: (UIViewController, UITableViewDatasource)
>
> This declares a tuple containing a UIViewController and a
UITableViewDataSource.
>
>> I added the braces because it would be really when you add the
question mark for an optional value; an alternative for this case would be
>>
>> let controller: Optional<UIViewController, UITableViewDatasource>
>
> This attempts to declare an optional with two generic types, which
doesn't work because Optional only has one type parameter. (But other
types, like Dictionary, *do* take two type parameters.)
>
> Swift does already have a syntax for declaring that a type must conform
to two (or more!) protocols:
>
> let controller: protocol<UITableViewDataSource, UITableViewDelegate>
>
> I think this could probably be extended to support one class type as
well, perhaps with a new name:
>
> let controller: all<UIViewController, UITableViewDataSource>
>
> --
> Brent Royal-Gordon
> Architechies
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Actually, no the union type has not been proposed. It has been slightly talked about in the Either type discussion. Either was a simple implementation that could do 80% of the use cases of type unions would allow (with 1% of the work :p).

Whereas, union and intersection types are basically making changes to the type system itself — is it not?

···

On 2016-02-11, at 20:38:21, Ross O'Brien via swift-evolution <swift-evolution@swift.org> wrote:

I think this proposal should stick to the intersection type: a type which inherits from at most one class (multiple inheritance should definitely be a separate proposal) if it conforms to all of one or more specified protocols.

The next issue I'd see with the union type is that it's the already proposed Either type.

— Ross

Apologies.
For the sake of clarity: I had understood the term 'intersection type' to
be referring to the concept in the original post of this thread - a type
which conforms to one type and all of a given collection of protocols (i.e.
to be a valid value of this type an instance must conform to the
intersection of all of these things), and a 'union type' to conform to one
option in each series of options in a type.
e.g. if a type is a subclass of UIViewController and conforms to
UITableViewDataSource then - according to my misunderstanding - it would be
an eligible value for a variable of "intersection type"
all<UIViewController, UITableViewDataSource>, whereas if it conforms to
either UITableViewDataSource OR UITableViewDelegate then it would be
eligible for a variable of "union type" any<UIViewController,
(UITableViewDataSource | UITableViewDelegate)>. I got confused by the
terminology used in the thread (it sounded good).

So, to rephrase (hopefully) more correctly:
I think this proposal should stick with the 'all' type: a type which
inherits from at most one class and conforms to all of a specified
collection of protocols.

'any', intersection types, union types, and Either should be a different
proposal.

···

On Thu, Feb 11, 2016 at 1:45 PM, Craig Cruden <ccruden@novafore.com> wrote:

> On 2016-02-11, at 20:38:21, Ross O'Brien via swift-evolution < > swift-evolution@swift.org> wrote:
>
> I think this proposal should stick to the intersection type: a type
which inherits from at most one class (multiple inheritance should
definitely be a separate proposal) if it conforms to all of one or more
specified protocols.
>
> The next issue I'd see with the union type is that it's the already
proposed Either type.
>
> — Ross

Actually, no the union type has not been proposed. It has been slightly
talked about in the Either type discussion. Either was a simple
implementation that could do 80% of the use cases of type unions would
allow (with 1% of the work :p).

Whereas, union and intersection types are basically making changes to the
type system itself — is it not?

Apologies.
For the sake of clarity: I had understood the term 'intersection type' to be referring to the concept in the original post of this thread - a type which conforms to one type and all of a given collection of protocols (i.e. to be a valid value of this type an instance must conform to the intersection of all of these things), and a 'union type' to conform to one option in each series of options in a type.

That is correct. No misunderstanding there as far as I can see.

e.g. if a type is a subclass of UIViewController and conforms to UITableViewDataSource then - according to my misunderstanding - it would be an eligible value for a variable of "intersection type" all<UIViewController, UITableViewDataSource>, whereas if it conforms to either UITableViewDataSource OR UITableViewDelegate then it would be eligible for a variable of "union type" any<UIViewController, (UITableViewDataSource | UITableViewDelegate)>.

That’s exactly my understanding, too.

See Eclipse Ceylon™ | projects.eclipse.org for details of how this works in Ceylon’s type system.

I got confused by the terminology used in the thread (it sounded good).

So, to rephrase (hopefully) more correctly:
I think this proposal should stick with the 'all' type: a type which inherits from at most one class and conforms to all of a specified collection of protocols.

This won’t work for a tuple:

let a: A
let b: B
let t: (A, B) = (a, b)

t[i] has type A | B, as I will either get something conforming to A or to B, depending on the value of i. It would be necessary to switch on the type to do something with it, similar to unwrapping an optional (actually optionals in Ceylon are not wrappers but type unions of the given type T with the Nil type: T | Nil).
if t[i] had type A & B this would mean that I can use any method of A and any method of B which will not work

I think you meant the third case for which I don’t have a technical term: a type containing the intersection of the methods (properties …) of A and B. That is not an intersection type as the term is used in Ceylon, but the term „intersection“ is certainly confusing here.

'any', intersection types, union types, and Either should be a different proposal.

Either is different from union types like Craig already explained.

-Thorsten

···

Am 11.02.2016 um 14:56 schrieb Ross O'Brien via swift-evolution <swift-evolution@swift.org>:

On Thu, Feb 11, 2016 at 1:45 PM, Craig Cruden <ccruden@novafore.com <mailto:ccruden@novafore.com>> wrote:

> On 2016-02-11, at 20:38:21, Ross O'Brien via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> I think this proposal should stick to the intersection type: a type which inherits from at most one class (multiple inheritance should definitely be a separate proposal) if it conforms to all of one or more specified protocols.
>
> The next issue I'd see with the union type is that it's the already proposed Either type.
>
> — Ross

Actually, no the union type has not been proposed. It has been slightly talked about in the Either type discussion. Either was a simple implementation that could do 80% of the use cases of type unions would allow (with 1% of the work :p).

Whereas, union and intersection types are basically making changes to the type system itself — is it not?

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution