[Pitch] merge types and protocols back together with type<Type, Protocol, ...>


(Adrian Zubarev) #1

This one have bothered me for days, since the idea came to my mind.

I don't want to be too futuristic so here are my first thoughts.

What if Swift 3 would have the ability to merge types and protocols together?

Sure we will see generic typealias in Swift 3 but it doesn't allow us merge value types which conforms to specific protocols (if there is a need).

protocol SomeProtocol {
    
  func boo()
}

// this use-case can be solved with generic typealias in Swift 3 (at least for classes), but it is not the only one usecase of type merging
func foo(mergedInstance: type<UIView, SomeProtocol>) {
    
  mergedInstance.removeFromSuperview() // just for the example
  mergedInstance.boo()
}

extension UIButton: SomeProtocol { /* implemnt boo() */ }

let button: SomeProtocol = UIButton() // decouple UIButton first

Ok now I want to use one instance as SomeProtocol and UIView.

// another possible use-case
if let mergedView = button as? type<UIView, SomeProtocol> {
    
  mergedView.removeFromSuperview() // just for the example
  mergedView.boo()
}

More detailed design:

- type<> can contain only one value or reference type and n protocols
- value or reference type should always be the first type
- type<> should always contain at least 2 types (one value or reference type and min. one protocol)
- reference types does represent one possible super/base type of the actuall type
* class A {}
* class B: A {}
* class C: B {}
* possible types for B and C: type<B, AnyProtocolType, ...> or type<A, AnyProtocolType, ...>
- the dynamicType/Self instance passed to type<> conforms to all protocols type<> contains

If there is more rules one would apply to this idea feel free to discuss them here.

···

--
Adrian Zubarev
Sent with Airmail


(Adrian Zubarev) #2

Sorry for pushing this back, but I really would like to read any feedback for this idea of mine. :wink:

···

--
Adrian Zubarev
Sent with Airmail

Am 4. Mai 2016 bei 22:38:33, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

This one have bothered me for days, since the idea came to my mind.

I don't want to be too futuristic so here are my first thoughts.

What if Swift 3 would have the ability to merge types and protocols together?

Sure we will see generic typealias in Swift 3 but it doesn't allow us merge value types which conforms to specific protocols (if there is a need).

protocol SomeProtocol {
func boo()
}

// this use-case can be solved with generic typealias in Swift 3 (at least for classes), but it is not the only one usecase of type merging
func foo(mergedInstance: type<UIView, SomeProtocol>) {
mergedInstance.removeFromSuperview() // just for the example
mergedInstance.boo()
}

extension UIButton: SomeProtocol { /* implemnt boo() */ }

let button: SomeProtocol = UIButton() // decouple UIButton first

Ok now I want to use one instance as SomeProtocol and UIView.

// another possible use-case
if let mergedView = button as? type<UIView, SomeProtocol> {
mergedView.removeFromSuperview() // just for the example
mergedView.boo()
}

More detailed design:

- type<> can contain only one value or reference type and n protocols
- value or reference type should always be the first type
- type<> should always contain at least 2 types (one value or reference type and min. one protocol)
- reference types does represent one possible super/base type of the actuall type
* class A {}
* class B: A {}
* class C: B {}
* possible types for B and C: type<B, AnyProtocolType, ...> or type<A, AnyProtocolType, ...>
- the dynamicType/Self instance passed to type<> conforms to all protocols type<> contains

If there is more rules one would apply to this idea feel free to discuss them here.

--
Adrian Zubarev
Sent with Airmail


(Vladimir) #3

I feel like this could be a useful feature. We can right now couple protocols

protocol A { func a() }
protocol B { func b() }

func z(o: protocol<A,B>) {
     o.a()
     o.b()
}

let o = some as! protocol<A, B>
o.a()
o.b()

But how to be if we need to specify some class/struct in addition to protocol?
So, if this feature could be implemented, I'm +1 on this `type<>` feature
Or probably we can allow class in protocol<>

···

On 11.05.2016 21:06, Adrian Zubarev via swift-evolution wrote:

Sorry for pushing this back, but I really would like to read any feedback
for this idea of mine. :wink:

--
Adrian Zubarev
Sent with Airmail

Am 4. Mai 2016 bei 22:38:33, Adrian Zubarev
(adrian.zubarev@devandartist.com <mailto:adrian.zubarev@devandartist.com>)
schrieb:

This one have bothered me for days, since the idea came to my mind.

I don't want to be too futuristic so here are my first thoughts.

What if Swift 3 would have the ability to merge types and protocols together?

Sure we will see generic typealias in Swift 3 but it doesn't allow us
merge value types which conforms to specific protocols (if there is a need).

protocol SomeProtocol {
func boo()
}

// this use-case can be solved with generic typealias in Swift 3 (at
least for classes), but it is not the only one usecase of type merging
func foo(mergedInstance: type<UIView, SomeProtocol>) {
mergedInstance.removeFromSuperview() // just for the example
mergedInstance.boo()
}

extension UIButton: SomeProtocol { /* implemnt boo() */ }

let button: SomeProtocol = UIButton() // decouple UIButton first

Ok now I want to use one instance as SomeProtocol and UIView.

// another possible use-case
if let mergedView = button as? type<UIView, SomeProtocol> {
mergedView.removeFromSuperview() // just for the example
mergedView.boo()
}

More detailed design:

- type<> can contain only one value or reference type and n protocols
- value or reference type should always be the first type
- type<> should always contain at least 2 types (one value or reference
type and min. one protocol)
- reference types does represent one possible super/base type of the
actuall type
     * class A {}
     * class B: A {}
     * class C: B {}
     * possible types for B and C: type<B, AnyProtocolType, ...> or
type<A, AnyProtocolType, ...>
- the dynamicType/Self instance passed to type<> conforms to all
protocols type<> contains

If there is more rules one would apply to this idea feel free to discuss
them here.

--
Adrian Zubarev
Sent with Airmail

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


(Tony Allevato) #4

I'm +1 on this. It seems like it would solve the issue of Objective-C APIs
losing their protocol conformances on properties/arguments/return values
when they're added to a class, like UIView<SomeProtocol>. That always
seemed like a major hole in the cross-language support and when writing
ObjC libraries I've had to explicitly use id<Foo> instead of a stronger
class-based type simply to ensure Swift interoperability.

The other option of course is to import those things as generic functions
with constraints, but (1) that doesn't solve it for properties, and (2) if
we already support composing protocols in this way, why not also allow it
for other types, where it can be used for properties and variables? This
approach feels like it would round out the type system nicely.

···

On Thu, May 12, 2016 at 7:09 AM Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to
build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this
feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com) schrieb:

protocol<>

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


(Adrian Zubarev) #5

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

···

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com) schrieb:

protocol<>


(Thorsten Seitz) #6

Ceylon uses „&" for intersection types, i.e.

  SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

  String | Int

That has proven to be very lightweight and readable in Ceylon where it is heavily used to good effect.

I agree with you that

  type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door open for union types, I would prefer

  all<SomeRealClass, SomeProtocol>

This would allow

  any<String, Int>

to be used for union types.

-Thorsten

···

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com <mailto:svabox@gmail.com>) schrieb:

protocol<>

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


(Adrian Zubarev) #7

I don’t get the part how `all<>` should allow `any<>`. Could you explain that a little bit in detail (I’m not familiar with Ceylon)?

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

// how would one use value here?
// what about its properties
// what will foo return and how to use the result

}

One benefit of `any<>` is the replacement of overloading, at least for the type part of the function.

I’d like to propose `type<>` as the base extension to the language in that direction, before we’ll move forward with more complex scenarios (just like Chris did with generic typealias).

This function is clear that it only will work if you provide a subclass of an UIView which conforms to SomeProtocol (nice addition for library design).

func foo(value: type<UIView, SomeProtocol>) -> type<UIView, SomeProtocol> {

// use it as a UIView and SomeProtocol at the same type
return value // return type works great

}

We can split the value just fine:

let mergedValue = foo(SomeViewThatWorks)
let view: UIView = mergedValue
let protocolValue: SomeProtocol = mergedValue

And merge it back together:

guard let newMergedValue = view as? type<UIView, SomeProtocol> else { /* do something */ }

`all<>` could be seen as an alternative name for `type<>`, but to me its not clear what `all<>` can do, whereas `type<>` is almost like `protocol<>`.

···

From my point of view `any<>` is something different that I pitched here. `any<>` could be proposed in its own thread, because it is way different than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com) schrieb:

Ceylon uses „&" for intersection types, i.e.

SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

String | Int

That has proven to be very lightweight and readable in Ceylon where it is heavily used to good effect.

I agree with you that

type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door open for union types, I would prefer

all<SomeRealClass, SomeProtocol>

This would allow

any<String, Int>

to be used for union types.

-Thorsten

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com) schrieb:

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


(Jordan Rose) #8

We've been over this a few times before on the list. I personally like naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and "AnySequence". I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

I will say that "type" is unlikely to see much traction simply because it is an incredibly common name for both properties and locals. We went through that exercise when trying to name both "static" and "dynamicType" and decided that it would be too confusing, even if we could make the parsing work.

The feature itself has definitely been shown to be useful when working with the Cocoa frameworks, if not in general. I don't see it on JIRA yet but we have it internally tracked in Radar as rdar://problem/15873071 <rdar://problem/15873071>.

Jordan

···

On May 12, 2016, at 13:08, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I don’t get the part how `all<>` should allow `any<>`. Could you explain that a little bit in detail (I’m not familiar with Ceylon)?

From my point of view `any<>` is something different that I pitched here. `any<>` could be proposed in its own thread, because it is way different than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

    // how would one use value here?
    // what about its properties
    // what will foo return and how to use the result
}

One benefit of `any<>` is the replacement of overloading, at least for the type part of the function.

I’d like to propose `type<>` as the base extension to the language in that direction, before we’ll move forward with more complex scenarios (just like Chris did with generic typealias).

This function is clear that it only will work if you provide a subclass of an UIView which conforms to SomeProtocol (nice addition for library design).

func foo(value: type<UIView, SomeProtocol>) -> type<UIView, SomeProtocol> {

    // use it as a UIView and SomeProtocol at the same type
    return value // return type works great
}

We can split the value just fine:

let mergedValue = foo(SomeViewThatWorks)
let view: UIView = mergedValue
let protocolValue: SomeProtocol = mergedValue

And merge it back together:

guard let newMergedValue = view as? type<UIView, SomeProtocol> else { /* do something */ }

`all<>` could be seen as an alternative name for `type<>`, but to me its not clear what `all<>` can do, whereas `type<>` is almost like `protocol<>`.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com <mailto:tseitz42@icloud.com>) schrieb:

Ceylon uses „&" for intersection types, i.e.

SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

String | Int

That has proven to be very lightweight and readable in Ceylon where it is heavily used to good effect.

I agree with you that

type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door open for union types, I would prefer

all<SomeRealClass, SomeProtocol>

This would allow

any<String, Int>

to be used for union types.

-Thorsten

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com <mailto:svabox@gmail.com>) schrieb:

protocol<>

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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


(Tony Allevato) #9

I think there would be a certain elegance to allowing Boolean type
expressions wherever types are currently allowed, so `A & B` being a
replacement for `protocol<A, B>` might look nice, and then extend that to
allow concrete types as well. Then, if Swift ever decided to support union
types, the `|` operator naturally fits there.

One concern though would be whether parsing would get more complicated with
deeply composed expressions. If we only supported `&`, there's no real
nesting going on. But if we wanted to be forward thinking and leave the
door open for `|`, we might need to support things like `(String | Int) &
SomeProtocol`, and I'm not enough of a parser expert to know whether that
would really complicate things (e.g., could the compiler decide easily
enough that those parentheses are part of a type expression and not a
function type?).

`all<A, B>` would be a nice compromise in that case, and leave the door
open for `any<A, B>` in the future. So I'd be supportive of either option.

···

On Thu, May 12, 2016 at 1:30 PM Jordan Rose via swift-evolution < swift-evolution@swift.org> wrote:

We've been over this a few times before on the list. I personally like
naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and
"AnySequence". I also see Thorsten (and in the past Brent's?) argument for
calling it "all" or "All", because it's enforcing multiple constraints.

I will say that "type" is unlikely to see much traction simply because it
is an *incredibly* common name for both properties and locals. We went
through that exercise when trying to name both "static" and "dynamicType"
and decided that it would be too confusing, even if we could make the
parsing work.

The feature itself has definitely been shown to be useful when working
with the Cocoa frameworks, if not in general. I don't see it on JIRA yet
but we have it internally tracked in Radar as rdar://problem/15873071.

Jordan

On May 12, 2016, at 13:08, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

I don’t get the part how `all<>` should allow `any<>`. Could you explain
that a little bit in detail (I’m not familiar with Ceylon)?

From my point of view `any<>` is something different that I pitched here.
`any<>` could be proposed in its own thread, because it is way different
than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

    // how would one use value here?
    // what about its properties
    // what will foo return and how to use the result
}

One benefit of `any<>` is the replacement of overloading, at least for the
type part of the function.

I’d like to propose `type<>` as the base extension to the language in that
direction, before we’ll move forward with more complex scenarios (just like
Chris did with generic typealias).

This function is clear that it only will work if you provide a subclass of
an UIView which conforms to SomeProtocol (nice addition for library design).

func foo(value: type<UIView, SomeProtocol>) -> type<UIView, SomeProtocol> {

    // use it as a UIView and SomeProtocol at the same type
    return value // return type works great
}

We can split the value just fine:

let mergedValue = foo(SomeViewThatWorks)
let view: UIView = mergedValue
let protocolValue: SomeProtocol = mergedValue

And merge it back together:

guard let newMergedValue = view as? type<UIView, SomeProtocol> else { /*
do something */ }

`all<>` could be seen as an alternative name for `type<>`, but to me its
not clear what `all<>` can do, whereas `type<>` is almost like
`protocol<>`.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com)
schrieb:

Ceylon uses „&" for intersection types, i.e.

SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

String | Int

That has proven to be very lightweight and readable in Ceylon where it is
heavily used to good effect.

I agree with you that

type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door
open for union types, I would prefer

all<SomeRealClass, SomeProtocol>

This would allow

any<String, Int>

to be used for union types.

-Thorsten

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution < > swift-evolution@swift.org>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to
build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this
feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com) schrieb:

protocol<>

_______________________________________________
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


(Brent Royal-Gordon) #10

We've been over this a few times before on the list. I personally like naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and "AnySequence". I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

I have suggested `all<>` in the past, but I now favor `Any`, because that allows it to be unified with the universal supertype `Any`, `Any<class>`, and things like `Any<Collection>` to forge the One Existential Syntax to rule them all.

···

--
Brent Royal-Gordon
Architechies


(Matthew Johnson) #11

I think there would be a certain elegance to allowing Boolean type expressions wherever types are currently allowed, so `A & B` being a replacement for `protocol<A, B>` might look nice, and then extend that to allow concrete types as well. Then, if Swift ever decided to support union types, the `|` operator naturally fits there.

+1

But maybe we should consider generalizing this to type operators. The '?' For optional could then be a postfix type operator. And we could define our own type operators for type composition.

One concern though would be whether parsing would get more complicated with deeply composed expressions. If we only supported `&`, there's no real nesting going on. But if we wanted to be forward thinking and leave the door open for `|`, we might need to support things like `(String | Int) & SomeProtocol`, and I'm not enough of a parser expert to know whether that would really complicate things (e.g., could the compiler decide easily enough that those parentheses are part of a type expression and not a function type?).

`all<A, B>` would be a nice compromise in that case, and leave the door open for `any<A, B>` in the future. So I'd be supportive of either option.

This makes sense as an immediate step in the right direction. I like that it is more concise than protocol<>

···

Sent from my iPad

On May 13, 2016, at 9:21 AM, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

On Thu, May 12, 2016 at 1:30 PM Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:
We've been over this a few times before on the list. I personally like naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and "AnySequence". I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

I will say that "type" is unlikely to see much traction simply because it is an incredibly common name for both properties and locals. We went through that exercise when trying to name both "static" and "dynamicType" and decided that it would be too confusing, even if we could make the parsing work.

The feature itself has definitely been shown to be useful when working with the Cocoa frameworks, if not in general. I don't see it on JIRA yet but we have it internally tracked in Radar as rdar://problem/15873071.

Jordan

On May 12, 2016, at 13:08, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I don’t get the part how `all<>` should allow `any<>`. Could you explain that a little bit in detail (I’m not familiar with Ceylon)?

From my point of view `any<>` is something different that I pitched here. `any<>` could be proposed in its own thread, because it is way different than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

    // how would one use value here?
    // what about its properties
    // what will foo return and how to use the result
}

One benefit of `any<>` is the replacement of overloading, at least for the type part of the function.

I’d like to propose `type<>` as the base extension to the language in that direction, before we’ll move forward with more complex scenarios (just like Chris did with generic typealias).

This function is clear that it only will work if you provide a subclass of an UIView which conforms to SomeProtocol (nice addition for library design).

func foo(value: type<UIView, SomeProtocol>) -> type<UIView, SomeProtocol> {

    // use it as a UIView and SomeProtocol at the same type
    return value // return type works great
}

We can split the value just fine:

let mergedValue = foo(SomeViewThatWorks)
let view: UIView = mergedValue
let protocolValue: SomeProtocol = mergedValue

And merge it back together:

guard let newMergedValue = view as? type<UIView, SomeProtocol> else { /* do something */ }

`all<>` could be seen as an alternative name for `type<>`, but to me its not clear what `all<>` can do, whereas `type<>` is almost like `protocol<>`.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com) schrieb:

Ceylon uses „&" for intersection types, i.e.

SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

String | Int

That has proven to be very lightweight and readable in Ceylon where it is heavily used to good effect.

I agree with you that

type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door open for union types, I would prefer

all<SomeRealClass, SomeProtocol>

This would allow

any<String, Int>

to be used for union types.

-Thorsten

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com) schrieb:

protocol<>

_______________________________________________
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

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


(Adrian Zubarev) #12

Lets sum things up before I try to write a draft proposal for this feature `type<>` aka `all<>`.

Is this feature out of scope for Swift 3?

Is the name `type<>` really that bad for the compiler?

Here I’m not sure, because that is out of my experience. From a readers perspective it’s more clear than `all<>`, I would say, even though this is a perfect explanation why it should be called `all<>`:

I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.
Do we miss any rules here?

`type<>` can contain only one value-type or reference-type and n protocols
the value-type or reference-type should always be the first element between angle brackets
`type<>` should always contain at least 2 types (one value-type or a reference-type and at least one protocol)
reference-types do represent a possible super/base type/class
nesting `type<>` is not allowed, however `type<>` can contain `protocol<>`
protocols conformance of `type<>` is tested with the actual type `type<>` not with the first element of `type<>` (hard to describe this one, does this makes sense to you?)
Does this proposal need more than the base `type<>`?

Maybe, but I think we should start with `type<>` before we will introduce a type operator for this.

Did I missed anything out here?

PS: Feel free to help me with my English, because it’s not so well.

···

From my point of view it’s definitely not.

--
Adrian Zubarev
Sent with Airmail

Am 13. Mai 2016 bei 16:21:41, Tony Allevato (allevato@google.com) schrieb:

I think there would be a certain elegance to allowing Boolean type expressions wherever types are currently allowed, so `A & B` being a replacement for `protocol<A, B>` might look nice, and then extend that to allow concrete types as well. Then, if Swift ever decided to support union types, the `|` operator naturally fits there.

One concern though would be whether parsing would get more complicated with deeply composed expressions. If we only supported `&`, there's no real nesting going on. But if we wanted to be forward thinking and leave the door open for `|`, we might need to support things like `(String | Int) & SomeProtocol`, and I'm not enough of a parser expert to know whether that would really complicate things (e.g., could the compiler decide easily enough that those parentheses are part of a type expression and not a function type?).

`all<A, B>` would be a nice compromise in that case, and leave the door open for `any<A, B>` in the future. So I'd be supportive of either option.

On Thu, May 12, 2016 at 1:30 PM Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:
We've been over this a few times before on the list. I personally like naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and "AnySequence". I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

I will say that "type" is unlikely to see much traction simply because it is an incredibly common name for both properties and locals. We went through that exercise when trying to name both "static" and "dynamicType" and decided that it would be too confusing, even if we could make the parsing work.

The feature itself has definitely been shown to be useful when working with the Cocoa frameworks, if not in general. I don't see it on JIRA yet but we have it internally tracked in Radar as rdar://problem/15873071.

Jordan

On May 12, 2016, at 13:08, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I don’t get the part how `all<>` should allow `any<>`. Could you explain that a little bit in detail (I’m not familiar with Ceylon)?

From my point of view `any<>` is something different that I pitched here. `any<>` could be proposed in its own thread, because it is way different than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

// how would one use value here?
// what about its properties
// what will foo return and how to use the result

}

One benefit of `any<>` is the replacement of overloading, at least for the type part of the function.

I’d like to propose `type<>` as the base extension to the language in that direction, before we’ll move forward with more complex scenarios (just like Chris did with generic typealias).

This function is clear that it only will work if you provide a subclass of an UIView which conforms to SomeProtocol (nice addition for library design).

func foo(value: type<UIView, SomeProtocol>) -> type<UIView, SomeProtocol> {

// use it as a UIView and SomeProtocol at the same type
return value // return type works great

}

We can split the value just fine:

let mergedValue = foo(SomeViewThatWorks)
let view: UIView = mergedValue
let protocolValue: SomeProtocol = mergedValue

And merge it back together:

guard let newMergedValue = view as? type<UIView, SomeProtocol> else { /* do something */ }

`all<>` could be seen as an alternative name for `type<>`, but to me its not clear what `all<>` can do, whereas `type<>` is almost like `protocol<>`.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com) schrieb:

Ceylon uses „&" for intersection types, i.e.

SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

String | Int

That has proven to be very lightweight and readable in Ceylon where it is heavily used to good effect.

I agree with you that

type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door open for union types, I would prefer

all<SomeRealClass, SomeProtocol>

This would allow

any<String, Int>

to be used for union types.

-Thorsten

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com) schrieb:

protocol<>
_______________________________________________
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


(Adrian Zubarev) #13

But maybe we should consider generalizing this to type operators. The '?' For optional could then be a postfix type operator. And we could define our own type operators for type composition.
Would you mind to provide a more detailed design from your perspective? I mean, how do you imagine `type<>` aka. `all<>` to look like with operators?

Any feedback is welcome. :slight_smile:

···

--
Adrian Zubarev
Sent with Airmail

Am 13. Mai 2016 bei 17:05:29, Matthew Johnson (matthew@anandabits.com) schrieb:

Sent from my iPad

On May 13, 2016, at 9:21 AM, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

I think there would be a certain elegance to allowing Boolean type expressions wherever types are currently allowed, so `A & B` being a replacement for `protocol<A, B>` might look nice, and then extend that to allow concrete types as well. Then, if Swift ever decided to support union types, the `|` operator naturally fits there.

+1

But maybe we should consider generalizing this to type operators. The '?' For optional could then be a postfix type operator. And we could define our own type operators for type composition.

One concern though would be whether parsing would get more complicated with deeply composed expressions. If we only supported `&`, there's no real nesting going on. But if we wanted to be forward thinking and leave the door open for `|`, we might need to support things like `(String | Int) & SomeProtocol`, and I'm not enough of a parser expert to know whether that would really complicate things (e.g., could the compiler decide easily enough that those parentheses are part of a type expression and not a function type?).

`all<A, B>` would be a nice compromise in that case, and leave the door open for `any<A, B>` in the future. So I'd be supportive of either option.

This makes sense as an immediate step in the right direction. I like that it is more concise than protocol<>

On Thu, May 12, 2016 at 1:30 PM Jordan Rose via swift-evolution <swift-evolution@swift.org> wrote:
We've been over this a few times before on the list. I personally like naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and "AnySequence". I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

I will say that "type" is unlikely to see much traction simply because it is an incredibly common name for both properties and locals. We went through that exercise when trying to name both "static" and "dynamicType" and decided that it would be too confusing, even if we could make the parsing work.

The feature itself has definitely been shown to be useful when working with the Cocoa frameworks, if not in general. I don't see it on JIRA yet but we have it internally tracked in Radar as rdar://problem/15873071.

Jordan

On May 12, 2016, at 13:08, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I don’t get the part how `all<>` should allow `any<>`. Could you explain that a little bit in detail (I’m not familiar with Ceylon)?

From my point of view `any<>` is something different that I pitched here. `any<>` could be proposed in its own thread, because it is way different than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

// how would one use value here?
// what about its properties
// what will foo return and how to use the result

}

One benefit of `any<>` is the replacement of overloading, at least for the type part of the function.

I’d like to propose `type<>` as the base extension to the language in that direction, before we’ll move forward with more complex scenarios (just like Chris did with generic typealias).

This function is clear that it only will work if you provide a subclass of an UIView which conforms to SomeProtocol (nice addition for library design).

func foo(value: type<UIView, SomeProtocol>) -> type<UIView, SomeProtocol> {

// use it as a UIView and SomeProtocol at the same type
return value // return type works great

}

We can split the value just fine:

let mergedValue = foo(SomeViewThatWorks)
let view: UIView = mergedValue
let protocolValue: SomeProtocol = mergedValue

And merge it back together:

guard let newMergedValue = view as? type<UIView, SomeProtocol> else { /* do something */ }

`all<>` could be seen as an alternative name for `type<>`, but to me its not clear what `all<>` can do, whereas `type<>` is almost like `protocol<>`.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com) schrieb:

Ceylon uses „&" for intersection types, i.e.

SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

String | Int

That has proven to be very lightweight and readable in Ceylon where it is heavily used to good effect.

I agree with you that

type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door open for union types, I would prefer

all<SomeRealClass, SomeProtocol>

This would allow

any<String, Int>

to be used for union types.

-Thorsten

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com) schrieb:

protocol<>
_______________________________________________
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
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Vladimir) #14

IMO it will be nice to have ability to write:

func f(obj: A&B&C) {..}
if obj is A&B&C {...}
obj2 = obj as! A&B&C

(but I still don't understand real use case of things like (String | Int))

Btw, as we have `protocol` keyword for this feature to couple protocols, why we can't have `class` keyword to merge class&protocols?
Like
func f(obj: class<SomeClass,SomeProtocl>) {..}
if obj is class<SomeClass,SomeProtocl> {..}
obj2 = obj as! class<SomeClass,SomeProtocol>

and yes, probably struct<SomeStruct,SomeProtocol>

···

On 13.05.2016 17:21, Tony Allevato via swift-evolution wrote:

I think there would be a certain elegance to allowing Boolean type
expressions wherever types are currently allowed, so `A & B` being a
replacement for `protocol<A, B>` might look nice, and then extend that to
allow concrete types as well. Then, if Swift ever decided to support union
types, the `|` operator naturally fits there.

One concern though would be whether parsing would get more complicated with
deeply composed expressions. If we only supported `&`, there's no real
nesting going on. But if we wanted to be forward thinking and leave the
door open for `|`, we might need to support things like `(String | Int) &
SomeProtocol`, and I'm not enough of a parser expert to know whether that
would really complicate things (e.g., could the compiler decide easily
enough that those parentheses are part of a type expression and not a
function type?).

`all<A, B>` would be a nice compromise in that case, and leave the door
open for `any<A, B>` in the future. So I'd be supportive of either option.

On Thu, May 12, 2016 at 1:30 PM Jordan Rose via swift-evolution > <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

    We've been over this a few times before on the list. I personally like
    naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass",
    and "AnySequence". I also see Thorsten (and in the past Brent's?)
    argument for calling it "all" or "All", because it's enforcing multiple
    constraints.

    I will say that "type" is unlikely to see much traction simply because
    it is an /incredibly/ common name for both properties and locals. We
    went through that exercise when trying to name both "static" and
    "dynamicType" and decided that it would be too confusing, even if we
    could make the parsing work.

    The feature itself has definitely been shown to be useful when working
    with the Cocoa frameworks, if not in general. I don't see it on JIRA
    yet but we have it internally tracked in Radar as rdar://problem/15873071.

    Jordan

    On May 12, 2016, at 13:08, Adrian Zubarev via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

    I don’t get the part how `all<>` should allow `any<>`. Could you
    explain that a little bit in detail (I’m not familiar with Ceylon)?

    From my point of view `any<>` is something different that I pitched
    here. `any<>` could be proposed in its own thread, because it is way
    different than `type<>`. Or can we refine the rules of `type<>` to
    get to `any<>`?

    Here is a little example where `any<>` gets strange:

    func foo(value: any<String, Int>) -> any<String, Int> {

        // how would one use value here?
        // what about its properties
        // what will foo return and how to use the result
    }

    One benefit of `any<>` is the replacement of overloading, at least
    for the type part of the function.

    I’d like to propose `type<>` as the base extension to the language in
    that direction, before we’ll move forward with more complex scenarios
    (just like Chris did with generic typealias).

    This function is clear that it only will work if you provide a
    subclass of an UIView which conforms to SomeProtocol (nice addition
    for library design).

    func foo(value: type<UIView, SomeProtocol>) ->
    type<UIView, SomeProtocol> {

        // use it as a UIView and SomeProtocol at the same type
        return value // return type works great
    }

    We can split the value just fine:

    let mergedValue = foo(SomeViewThatWorks)
    let view: UIView = mergedValue
    let protocolValue: SomeProtocol = mergedValue

    And merge it back together:

    guard let newMergedValue = view as? type<UIView, SomeProtocol> else {
    /* do something */ }

    `all<>` could be seen as an alternative name for `type<>`, but to me
    its not clear what `all<>` can do, whereas `type<>` is almost like
    `protocol<>`.

    --
    Adrian Zubarev
    Sent with Airmail

    Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com
    <mailto:tseitz42@icloud.com>) schrieb:

    Ceylon uses „&" for intersection types, i.e.

    SomeRealClass & SomeProtocol

    and the bar („|“) for union types, i.e.

    String | Int

    That has proven to be very lightweight and readable in Ceylon where
    it is heavily used to good effect.

    I agree with you that

    type<SomeRealClass, SomeProtocol>

    is much nicer than protocol<> for intersection types but to keep the
    door open for union types, I would prefer

    all<SomeRealClass, SomeProtocol>

    This would allow

    any<String, Int>

    to be used for union types.

    -Thorsten

    Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution
    <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

    protocol<SomeRealClass, SomeProtocol>
    protocol<SomeRealStruct, SomeProtocol>

    This feels really odd to me.

    `type<SomeRealClass, SomeProtocol>` is more clear I’d say.

    I think this would be a good addition to the type system and allow
    us to build more complex and type save code.

    But still I’d love to discuss if there might be
    any disadvantages to this feature.

    --
    Adrian Zubarev
    Sent with Airmail

    Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com
    <mailto:svabox@gmail.com>) schrieb:

    protocol<>

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

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

    _______________________________________________
    swift-evolution mailing list
    swift-evolution@swift.org <mailto: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


(Thorsten Seitz) #15

But don't you mean the union type of all possible Collection types when you write Any<Collection>?

I suggested `all<>` for the intersection type, and `any<>` for the union type, so that would be the same, wouldn't it?

-Thorsten

···

Am 17.05.2016 um 07:10 schrieb Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org>:

We've been over this a few times before on the list. I personally like naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and "AnySequence". I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

I have suggested `all<>` in the past, but I now favor `Any`, because that allows it to be unified with the universal supertype `Any`, `Any<class>`, and things like `Any<Collection>` to forge the One Existential Syntax to rule them all.

--
Brent Royal-Gordon
Architechies

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


(Matthew Johnson) #16

But maybe we should consider generalizing this to type operators. The '?' For optional could then be a postfix type operator. And we could define our own type operators for type composition.

Would you mind to provide a more detailed design from your perspective? I mean, how do you imagine `type<>` aka. `all<>` to look like with operators?

The & type operator would produce a “flattened" all<> with its operands. It could be overloaded to accept either a concrete type or a protocol on the lhs and would produce `type` for an lhs that is a type and `all` when lhs is a protocol. "Type operators” would be evaluated during compile time and would produce a type that is used where the expression was present in the code. This is a long-term idea, not something that needs to be considered right now. It would be way out of scope for Swift 3.

···

On May 13, 2016, at 10:33 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

Any feedback is welcome. :slight_smile:

--
Adrian Zubarev
Sent with Airmail

Am 13. Mai 2016 bei 17:05:29, Matthew Johnson (matthew@anandabits.com <mailto:matthew@anandabits.com>) schrieb:

Sent from my iPad

On May 13, 2016, at 9:21 AM, Tony Allevato via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I think there would be a certain elegance to allowing Boolean type expressions wherever types are currently allowed, so `A & B` being a replacement for `protocol<A, B>` might look nice, and then extend that to allow concrete types as well. Then, if Swift ever decided to support union types, the `|` operator naturally fits there.

+1

But maybe we should consider generalizing this to type operators. The '?' For optional could then be a postfix type operator. And we could define our own type operators for type composition.

One concern though would be whether parsing would get more complicated with deeply composed expressions. If we only supported `&`, there's no real nesting going on. But if we wanted to be forward thinking and leave the door open for `|`, we might need to support things like `(String | Int) & SomeProtocol`, and I'm not enough of a parser expert to know whether that would really complicate things (e.g., could the compiler decide easily enough that those parentheses are part of a type expression and not a function type?).

`all<A, B>` would be a nice compromise in that case, and leave the door open for `any<A, B>` in the future. So I'd be supportive of either option.

This makes sense as an immediate step in the right direction. I like that it is more concise than protocol<>

On Thu, May 12, 2016 at 1:30 PM Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
We've been over this a few times before on the list. I personally like naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and "AnySequence". I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

I will say that "type" is unlikely to see much traction simply because it is an incredibly common name for both properties and locals. We went through that exercise when trying to name both "static" and "dynamicType" and decided that it would be too confusing, even if we could make the parsing work.

The feature itself has definitely been shown to be useful when working with the Cocoa frameworks, if not in general. I don't see it on JIRA yet but we have it internally tracked in Radar as rdar://problem/15873071 <>.

Jordan

On May 12, 2016, at 13:08, Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I don’t get the part how `all<>` should allow `any<>`. Could you explain that a little bit in detail (I’m not familiar with Ceylon)?

From my point of view `any<>` is something different that I pitched here. `any<>` could be proposed in its own thread, because it is way different than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

    // how would one use value here?
    // what about its properties
    // what will foo return and how to use the result
}

One benefit of `any<>` is the replacement of overloading, at least for the type part of the function.

I’d like to propose `type<>` as the base extension to the language in that direction, before we’ll move forward with more complex scenarios (just like Chris did with generic typealias).

This function is clear that it only will work if you provide a subclass of an UIView which conforms to SomeProtocol (nice addition for library design).

func foo(value: type<UIView, SomeProtocol>) -> type<UIView, SomeProtocol> {

    // use it as a UIView and SomeProtocol at the same type
    return value // return type works great
}

We can split the value just fine:

let mergedValue = foo(SomeViewThatWorks)
let view: UIView = mergedValue
let protocolValue: SomeProtocol = mergedValue

And merge it back together:

guard let newMergedValue = view as? type<UIView, SomeProtocol> else { /* do something */ }

`all<>` could be seen as an alternative name for `type<>`, but to me its not clear what `all<>` can do, whereas `type<>` is almost like `protocol<>`.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com <mailto:tseitz42@icloud.com>) schrieb:

Ceylon uses „&" for intersection types, i.e.

SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

String | Int

That has proven to be very lightweight and readable in Ceylon where it is heavily used to good effect.

I agree with you that

type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door open for union types, I would prefer

all<SomeRealClass, SomeProtocol>

This would allow

any<String, Int>

to be used for union types.

-Thorsten

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com <mailto:svabox@gmail.com>) schrieb:

protocol<>

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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


(Tino) #17

func f(obj: A&B&C) {..}
if obj is A&B&C {...}
obj2 = obj as! A&B&C

(but I still don't understand real use case of things like (String | Int))

Ceylon has already been mentioned: It uses the concept for its optionals.
Swift uses enums, and those could be made obsolete by union types.


(Thorsten Seitz) #18

Lets sum things up before I try to write a draft proposal for this feature `type<>` aka `all<>`.

Is this feature out of scope for Swift 3?

From my point of view it’s definitely not.

Is the name `type<>` really that bad for the compiler?

Here I’m not sure, because that is out of my experience. From a readers perspective it’s more clear than `all<>`, I would say, even though this is a perfect explanation why it should be called `all<>`:

I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

Do we miss any rules here?

`type<>` can contain only one value-type or reference-type and n protocols
the value-type or reference-type should always be the first element between angle brackets
`type<>` should always contain at least 2 types (one value-type or a reference-type and at least one protocol)

I think type<> (or all<>) should replace protocol<>, otherwise the idea of having all<> and any<> loses its charm.
Is there a reason why type<> should exist in parallel to protocol<>?

reference-types do represent a possible super/base type/class
nesting `type<>` is not allowed, however `type<>` can contain `protocol<>`
protocols conformance of `type<>` is tested with the actual type `type<>` not with the first element of `type<>` (hard to describe this one, does this makes sense to you?)

The components of type<> are unrelated and do not have to conform to each other. They are just a union type. Did you mean that?

-Thorsten

···

Am 13.05.2016 um 17:25 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org>:

Does this proposal need more than the base `type<>`?

Maybe, but I think we should start with `type<>` before we will introduce a type operator for this.

Did I missed anything out here?

PS: Feel free to help me with my English, because it’s not so well.

--
Adrian Zubarev
Sent with Airmail

Am 13. Mai 2016 bei 16:21:41, Tony Allevato (allevato@google.com <mailto:allevato@google.com>) schrieb:

I think there would be a certain elegance to allowing Boolean type expressions wherever types are currently allowed, so `A & B` being a replacement for `protocol<A, B>` might look nice, and then extend that to allow concrete types as well. Then, if Swift ever decided to support union types, the `|` operator naturally fits there.

One concern though would be whether parsing would get more complicated with deeply composed expressions. If we only supported `&`, there's no real nesting going on. But if we wanted to be forward thinking and leave the door open for `|`, we might need to support things like `(String | Int) & SomeProtocol`, and I'm not enough of a parser expert to know whether that would really complicate things (e.g., could the compiler decide easily enough that those parentheses are part of a type expression and not a function type?).

`all<A, B>` would be a nice compromise in that case, and leave the door open for `any<A, B>` in the future. So I'd be supportive of either option.

On Thu, May 12, 2016 at 1:30 PM Jordan Rose via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
We've been over this a few times before on the list. I personally like naming this thing "Any<…>" in the same vein as "AnyObject", "AnyClass", and "AnySequence". I also see Thorsten (and in the past Brent's?) argument for calling it "all" or "All", because it's enforcing multiple constraints.

I will say that "type" is unlikely to see much traction simply because it is an incredibly common name for both properties and locals. We went through that exercise when trying to name both "static" and "dynamicType" and decided that it would be too confusing, even if we could make the parsing work.

The feature itself has definitely been shown to be useful when working with the Cocoa frameworks, if not in general. I don't see it on JIRA yet but we have it internally tracked in Radar as rdar://problem/15873071 <>.

Jordan

On May 12, 2016, at 13:08, Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I don’t get the part how `all<>` should allow `any<>`. Could you explain that a little bit in detail (I’m not familiar with Ceylon)?

From my point of view `any<>` is something different that I pitched here. `any<>` could be proposed in its own thread, because it is way different than `type<>`. Or can we refine the rules of `type<>` to get to `any<>`?

Here is a little example where `any<>` gets strange:

func foo(value: any<String, Int>) -> any<String, Int> {

    // how would one use value here?
    // what about its properties
    // what will foo return and how to use the result
}

One benefit of `any<>` is the replacement of overloading, at least for the type part of the function.

I’d like to propose `type<>` as the base extension to the language in that direction, before we’ll move forward with more complex scenarios (just like Chris did with generic typealias).

This function is clear that it only will work if you provide a subclass of an UIView which conforms to SomeProtocol (nice addition for library design).

func foo(value: type<UIView, SomeProtocol>) -> type<UIView, SomeProtocol> {

    // use it as a UIView and SomeProtocol at the same type
    return value // return type works great
}

We can split the value just fine:

let mergedValue = foo(SomeViewThatWorks)
let view: UIView = mergedValue
let protocolValue: SomeProtocol = mergedValue

And merge it back together:

guard let newMergedValue = view as? type<UIView, SomeProtocol> else { /* do something */ }

`all<>` could be seen as an alternative name for `type<>`, but to me its not clear what `all<>` can do, whereas `type<>` is almost like `protocol<>`.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 21:40:24, Thorsten Seitz (tseitz42@icloud.com <mailto:tseitz42@icloud.com>) schrieb:

Ceylon uses „&" for intersection types, i.e.

SomeRealClass & SomeProtocol

and the bar („|“) for union types, i.e.

String | Int

That has proven to be very lightweight and readable in Ceylon where it is heavily used to good effect.

I agree with you that

type<SomeRealClass, SomeProtocol>

is much nicer than protocol<> for intersection types but to keep the door open for union types, I would prefer

all<SomeRealClass, SomeProtocol>

This would allow

any<String, Int>

to be used for union types.

-Thorsten

Am 12.05.2016 um 16:09 schrieb Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:

protocol<SomeRealClass, SomeProtocol>
protocol<SomeRealStruct, SomeProtocol>

This feels really odd to me.

`type<SomeRealClass, SomeProtocol>` is more clear I’d say.

I think this would be a good addition to the type system and allow us to build more complex and type save code.

But still I’d love to discuss if there might be any disadvantages to this feature.

--
Adrian Zubarev
Sent with Airmail

Am 12. Mai 2016 bei 15:11:00, Vladimir.S (svabox@gmail.com <mailto:svabox@gmail.com>) schrieb:

protocol<>

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

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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


(Brent Royal-Gordon) #19

But don't you mean the union type of all possible Collection types when you write Any<Collection>?

No, I mean "an existential capable of holding any Collection".

If I write Any<Equatable, Collection>, I mean "an existential capable of holding any Equatable Collection".

If I write Any<UITableViewCell, CounterDisplaying>, I mean "an existential capable of holding any CounterDisplaying UITableViewCell".

If I write Any<Collection where .Element: Equatable>, I mean "an existential capable of holding any Collection with an Equatable Element".

If I write Any<class>, I mean "An existential capable of holding any class instance".

If I write Any, I mean "An existential capable of holding anything".

Union types have nothing to do with it.

···

--
Brent Royal-Gordon
Architechies


(Austin Zheng) #20

This is the proposal I'd like to see go before review, and the one I think is closest in spirit to the generics roadmap.

Things like adding union types, and rewriting Swift's type system to look like Scala's, have very little to do with better representations of existentials, and belong in a follow-up proposal.

Austin

···

On May 16, 2016, at 11:55 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

But don't you mean the union type of all possible Collection types when you write Any<Collection>?

No, I mean "an existential capable of holding any Collection".

If I write Any<Equatable, Collection>, I mean "an existential capable of holding any Equatable Collection".

If I write Any<UITableViewCell, CounterDisplaying>, I mean "an existential capable of holding any CounterDisplaying UITableViewCell".

If I write Any<Collection where .Element: Equatable>, I mean "an existential capable of holding any Collection with an Equatable Element".

If I write Any<class>, I mean "An existential capable of holding any class instance".

If I write Any, I mean "An existential capable of holding anything".

Union types have nothing to do with it.

--
Brent Royal-Gordon
Architechies

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