Re: [swift-evolution] Union instead of Optional

2016-05-15 Thread David Hart via swift-evolution
Enums with associated types in Swift are the equivalent of unions, even if they 
don’t have the name. I don’t see what your proposal is trying to solve?

> On 15 May 2016, at 04:33, Cao Jiannan via swift-evolution 
>  wrote:
> 
> 
> It’s kind of same idea of TypeScipt 2, at 46:21 in this video.
> 
> https://channel9.msdn.com/Events/Build/2016/B881 
> 
> 
> <屏幕快照 2016-05-15 10.20.36.png>
> 
> 
>> 
>> 2016-2-16 GMT+8 14:36:28
>> Hi all,
>> 
>> I think the best way to solve the either problem is to separate it from 
>> generic. 
>> Optional and Either shouldn’t work the same way of generic type. 
>> It’s just a represent of multiple type in one location.
>> 
>> Using an old friend, Union in C.
>> union {
>>  case firstType
>>  case secondType
>> }
>> 
>> This is the final solution for the sub typing problem of optional.
>> 
>> A  == union(A,A)
>> union(A,B) == union(B,A)
>> B == union(B,B)
>> 
>> B is subtype of union(A,B)
>> A is subtype of union(A,B)
>> union(A,B,C) is subtype of union(A,B,C,D,…)
>> 
>> suppose 
>> a is subclass of A
>> b is subclass of B, then
>>  union(a,B) is subtype of union(A,B)
>>  union(A,b) is subtype of union(A,B)
>>  union(a,b) is subtype of union(a,B)
>>  union(a,b) is subtype of union(A,b)
>> 
>> union can have as many case as possible. e.g., union(A,B,C,D,…)
>> 
>> So the Optional should be union(UITableView, None)
>> and Optional should be union(MyTableView, None), which is 
>> subclass of union(UITableView, None)
>> 
>> This is a final rational solution. I think.
>> 
>> -Jiannan
>> 
> 
> 
> 
> 
> ___
> 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


Re: [swift-evolution] Union instead of Optional

2016-05-15 Thread Austin Zheng via swift-evolution
In addition, not everything in Swift can be modeled in terms of inheritance 
relationships.

I'm a little curious as to why union types keep on coming up, when enums can do 
everything they can and much more (methods, constraints on generic types, 
conformance to protocols).

Austin

> On May 15, 2016, at 12:19 AM, David Hart via swift-evolution 
>  wrote:
> 
> Enums with associated types in Swift are the equivalent of unions, even if 
> they don’t have the name. I don’t see what your proposal is trying to solve?
> 
>> On 15 May 2016, at 04:33, Cao Jiannan via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> It’s kind of same idea of TypeScipt 2, at 46:21 in this video.
>> 
>> https://channel9.msdn.com/Events/Build/2016/B881 
>> 
>> 
>> <屏幕快照 2016-05-15 10.20.36.png>
>> 
>> 
>>> 
>>> 2016-2-16 GMT+8 14:36:28
>>> Hi all,
>>> 
>>> I think the best way to solve the either problem is to separate it from 
>>> generic. 
>>> Optional and Either shouldn’t work the same way of generic type. 
>>> It’s just a represent of multiple type in one location.
>>> 
>>> Using an old friend, Union in C.
>>> union {
>>> case firstType
>>> case secondType
>>> }
>>> 
>>> This is the final solution for the sub typing problem of optional.
>>> 
>>> A  == union(A,A)
>>> union(A,B) == union(B,A)
>>> B == union(B,B)
>>> 
>>> B is subtype of union(A,B)
>>> A is subtype of union(A,B)
>>> union(A,B,C) is subtype of union(A,B,C,D,…)
>>> 
>>> suppose 
>>> a is subclass of A
>>> b is subclass of B, then
>>> union(a,B) is subtype of union(A,B)
>>> union(A,b) is subtype of union(A,B)
>>> union(a,b) is subtype of union(a,B)
>>> union(a,b) is subtype of union(A,b)
>>> 
>>> union can have as many case as possible. e.g., union(A,B,C,D,…)
>>> 
>>> So the Optional should be union(UITableView, None)
>>> and Optional should be union(MyTableView, None), which is 
>>> subclass of union(UITableView, None)
>>> 
>>> This is a final rational solution. I think.
>>> 
>>> -Jiannan
>>> 
>> 
>> 
>> 
>> 
>> ___
>> 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


Re: [swift-evolution] Union instead of Optional

2016-05-15 Thread Cao, Jiannan via swift-evolution
Optional should be implement by union concept s instead of using generic.

Enum cannot be easily used to represent many types until you name all of them. 

Both generic and enum solution cannot build a strong relation between optional 
type and its original type, for example, an Integer type has no reparation with 
Optional, until the compiler make a special case for Optional to 
automatically unwrap or wrap for this.

> 在 2016年5月15日,15:19,David Hart  写道:
> 
> Enums with associated types in Swift are the equivalent of unions, even if 
> they don’t have the name. I don’t see what your proposal is trying to solve?
> 
>> On 15 May 2016, at 04:33, Cao Jiannan via swift-evolution 
>>  wrote:
>> 
>> 
>> It’s kind of same idea of TypeScipt 2, at 46:21 in this video.
>> 
>> https://channel9.msdn.com/Events/Build/2016/B881
>> 
>> <屏幕快照 2016-05-15 10.20.36.png>
>> 
>> 
>>> 
>>> 2016-2-16 GMT+8 14:36:28
>>> Hi all,
>>> 
>>> I think the best way to solve the either problem is to separate it from 
>>> generic. 
>>> Optional and Either shouldn’t work the same way of generic type. 
>>> It’s just a represent of multiple type in one location.
>>> 
>>> Using an old friend, Union in C.
>>> union {
>>> case firstType
>>> case secondType
>>> }
>>> 
>>> This is the final solution for the sub typing problem of optional.
>>> 
>>> A  == union(A,A)
>>> union(A,B) == union(B,A)
>>> B == union(B,B)
>>> 
>>> B is subtype of union(A,B)
>>> A is subtype of union(A,B)
>>> union(A,B,C) is subtype of union(A,B,C,D,…)
>>> 
>>> suppose 
>>> a is subclass of A
>>> b is subclass of B, then
>>> union(a,B) is subtype of union(A,B)
>>> union(A,b) is subtype of union(A,B)
>>> union(a,b) is subtype of union(a,B)
>>> union(a,b) is subtype of union(A,b)
>>> 
>>> union can have as many case as possible. e.g., union(A,B,C,D,…)
>>> 
>>> So the Optional should be union(UITableView, None)
>>> and Optional should be union(MyTableView, None), which is 
>>> subclass of union(UITableView, None)
>>> 
>>> This is a final rational solution. I think.
>>> 
>>> -Jiannan
>> 
>> 
>> 
>> 
>> ___
>> 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


Re: [swift-evolution] Union instead of Optional

2016-05-15 Thread Tino Heth via swift-evolution
I don't know if there has been any internal discussion about using union-types 
instead of enums, but afaics, there are no obvious downsides for that approach.

> I'm a little curious as to why union types keep on coming up, when enums can 
> do everything they can and much more (methods, constraints on generic types, 
> conformance to protocols).
Are there any strong reasons why those features would not be possible with 
union types?

There has been a discussion started because it is a little bit cumbersome to 
create enum-properties (and methods).
With unions, there would be no need for all those switch-statements, and would 
be possible to configure cases in a central location.
There has also been a proposal for "anonymous enums", which could be modeled 
with unions in a very elegant way.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Thorsten Seitz via swift-evolution
Yes, enums are like explicit named type unions whereas ad hoc type unions can 
be useful exactly because they are ad hoc.
It is kind of like named functions vs. anonymous functions. Both have their 
place.

Ceylon makes tremendous use of union and intersection types. While they don’t 
have enums in the Swift sense they have something very similar, so they 
certainly make use of both approaches, too. Like I said both have their place 
and introducing type unions shouldn’t replace enums (unless we should discover 
that type unions can do all that enums do, e.g. with extensions it might even 
be possible to add methods to type unions in Swift).

-Thorsten


> Am 15.05.2016 um 13:07 schrieb Tino Heth via swift-evolution 
> :
> 
> I don't know if there has been any internal discussion about using 
> union-types instead of enums, but afaics, there are no obvious downsides for 
> that approach.
> 
>> I'm a little curious as to why union types keep on coming up, when enums can 
>> do everything they can and much more (methods, constraints on generic types, 
>> conformance to protocols).
> Are there any strong reasons why those features would not be possible with 
> union types?
> 
> There has been a discussion started because it is a little bit cumbersome to 
> create enum-properties (and methods).
> With unions, there would be no need for all those switch-statements, and 
> would be possible to configure cases in a central location.
> There has also been a proposal for "anonymous enums", which could be modeled 
> with unions in a very elegant way.
> ___
> 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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Austin Zheng via swift-evolution
Precisely. To me unions are to enums with associated type the same way tuples 
are to structs. One is named, has well-defined semantics, can conform to 
protocols, can have complex internal structure, can have methods, etc. The 
other is ad-hoc and lightweight, easy to define at the site of use, best suited 
for simple purposes, has special syntax to support it. 

Even if we can extend tuples in the future, though, I wouldn't want structs to 
go away. When exceeding some level of complexity structs are just more explicit 
than tuples, and therefore easier to understand.

Finally, please note that Ceylon is a pervasively object-oriented language with 
a single root superclass. Neither of those is true for Swift, which chooses to 
solve a lot of problems in a different (and I would argue, superior) way. So 
solutions that might work well in Ceylon might not be suited for Swift, at 
least not without modification, and vice versa. The core team could certainly 
have chosen to model Swift's type system after that of e.g. Scala, but they 
chose not to, and I think they did so for good reason.

Austin


> On May 16, 2016, at 2:58 AM, Thorsten Seitz  wrote:
> 
> Yes, enums are like explicit named type unions whereas ad hoc type unions can 
> be useful exactly because they are ad hoc.
> It is kind of like named functions vs. anonymous functions. Both have their 
> place.
> 
> Ceylon makes tremendous use of union and intersection types. While they don’t 
> have enums in the Swift sense they have something very similar, so they 
> certainly make use of both approaches, too. Like I said both have their place 
> and introducing type unions shouldn’t replace enums (unless we should 
> discover that type unions can do all that enums do, e.g. with extensions it 
> might even be possible to add methods to type unions in Swift).
> 
> -Thorsten
> 
> 
>> Am 15.05.2016 um 13:07 schrieb Tino Heth via swift-evolution 
>> mailto:swift-evolution@swift.org>>:
>> 
>> I don't know if there has been any internal discussion about using 
>> union-types instead of enums, but afaics, there are no obvious downsides for 
>> that approach.
>> 
>>> I'm a little curious as to why union types keep on coming up, when enums 
>>> can do everything they can and much more (methods, constraints on generic 
>>> types, conformance to protocols).
>> Are there any strong reasons why those features would not be possible with 
>> union types?
>> 
>> There has been a discussion started because it is a little bit cumbersome to 
>> create enum-properties (and methods).
>> With unions, there would be no need for all those switch-statements, and 
>> would be possible to configure cases in a central location.
>> There has also been a proposal for "anonymous enums", which could be modeled 
>> with unions in a very elegant way.
>> ___
>> 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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Austin Zheng via swift-evolution
This doesn't explain how I can use 'value' once an A() is passed into the
function:

func input(value: (A | B | C)) {


}

If A, B, and C are not related via protocol or class inheritance, then
there is almost nothing you can do with value. Otherwise you still need to
test against the concrete type using a case statement or a if-else ladder.

The other 'gain' is being able to call 'input(A())', rather than
'input(.caseA(A()))'. I agree that the first form is prettier than the
second one. I also think you could make the language pervasively prettier
and more expressive by allowing for all sorts of implicit conversions. At
some point clarity at the point of use beats conciseness, especially when
code within a complex codebase needs to be maintained.

I understand that this is largely a matter of style - different people
value different things, and that's wonderful. I welcome a formal proposal
submitted to the swift-evolution process, and if one appears I'm happy to
consider it in more detail and argue for or against it based on that.

Austin



On Sun, May 15, 2016 at 3:34 AM, Cao Jiannan  wrote:

> for example, there is a method input union of 3 types: A, B, C,
>
> This is the three class.
>
> class A {}
>
> class B {}
>
> class C {}
>
> This is how it implemented under Swift 2:
>
> enum UnionABC {
> case classA(A)
> case classB(B)
> case classC(C)
> }
>
> func input(value: UnionABC) {
>
>
> }
>
> let a = A()
> let b = B()
> let c = C()
> input(UnionABC.classA(a))
>
>
> It needs announce all the cases and name each cases and cannot use class
> names as their case names.
>
> what about using union? It is more easy and rational.
>
>
> func input(value: (A | B | C)) {
>
>
> }
>
> let a= A()
> input(a)
>
> Or you can implement it with protocol and extension, but compiler will not
> know how many cases it should have.
>
>
> protocol UnionABC {
>
>
> }
>
> extension A: UnionABC {}
> extension B: UnionABC {}
> extension C: UnionABC {}
>
>
> func input(value: UnionABC) {
> if value is A {
>
>
> } else if value is B {
>
>
> } else if value is C {
>
>
> } else {
> // There are other cases? Compiler doesn't know
> }
> }
>
> let a = A()
> input(a)
>
>
>
> 下面是被转发的邮件:
>
> *发件人: *frog...@163.com
> *主题: **回复: [swift-evolution] Union instead of Optional*
> *日期: *2016年5月15日 GMT+8 18:00:55
> *收件人: *Austin Zheng 
>
>
> Enum and Union are two things.
>
> If you use Enum to implement Union, you should announce it with case name.
>
> Another issue using enum instead of union is that,  union can combine
> types as many as possible, you just write ( A | B | C ... | Z), but for
> enum, you should carefully announce it for each case.
>
> 在 2016年5月15日,15:22,Austin Zheng  写道:
>
> In addition, not everything in Swift can be modeled in terms of
> inheritance relationships.
>
> I'm a little curious as to why union types keep on coming up, when enums
> can do everything they can and much more (methods, constraints on generic
> types, conformance to protocols).
>
> Austin
>
> 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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Cao Jiannan via swift-evolution


Consider this case:

class A {
var someCommonProperty: Int = 0
}
class B {
var someCommonProperty: Int = 0
}
class C {
var someCommonProperty: Int = 0
}

protocol UnionABC {
var someCommonProperty: Int
}

extension A: UnionABC {}
extension B: UnionABC {}
extension C: UnionABC {}


= If we using protocol


func input(value: UnionABC) {
print(value.someCommonProperty) // Compiler will know their common 
properties automatically.
if value is A {

} else if value is B {

} else if value is C {

} else {
// There are other cases? Compiler doesn't know
}
}

let a = A()
input(a)

= If we using union

func input(value: (A | B | C)) {
print(value.someCommonProperty) // Compiler will know their common 
properties automatically.

if value is A {

} else if value is B {

} else if value is C {

} else {
// There no other cases, so the compiler trigger a warning.
}
}

let a = A()
input(a)


=

If using generic enum,
the compiler doesn’t know the type relation between generic union with original 
type.
class A and UnionOf3 are totally two different types, has no 
relationship.
But class A and (A | B | C) keeps a relationship.

If using union, these two cases will be allowed:

let a = A()
let union: (A|B|C) = a // Automatically wrap.

a == union // Can be compared, Yes

sub-typing: 

var fn0: A->Void = {print(v0)}
var fn1: (A|B)->Void = {print(v0)}

fn0 = fn1 // Original Type and Union Type has a sub-typing relationship, OK

var fn2: (A|B|C)->Void = {print($0)}

fn0 = fn2 // OK
fn1 = fn2 // OK


> 在 2016年5月16日,18:17,Austin Zheng  写道:
> 
> This doesn't explain how I can use 'value' once an A() is passed into the 
> function:
> 
> func input(value: (A | B | C)) {
> 
> }
> 
> If A, B, and C are not related via protocol or class inheritance, then there 
> is almost nothing you can do with value. Otherwise you still need to test 
> against the concrete type using a case statement or a if-else ladder.
> 
> The other 'gain' is being able to call 'input(A())', rather than 
> 'input(.caseA(A()))'. I agree that the first form is prettier than the second 
> one. I also think you could make the language pervasively prettier and more 
> expressive by allowing for all sorts of implicit conversions. At some point 
> clarity at the point of use beats conciseness, especially when code within a 
> complex codebase needs to be maintained.
> 
> I understand that this is largely a matter of style - different people value 
> different things, and that's wonderful. I welcome a formal proposal submitted 
> to the swift-evolution process, and if one appears I'm happy to consider it 
> in more detail and argue for or against it based on that.
> 
> Austin
> 
> 
> 
> On Sun, May 15, 2016 at 3:34 AM, Cao Jiannan  > wrote:
> for example, there is a method input union of 3 types: A, B, C,
> 
> This is the three class.
> 
> class A {}
> 
> class B {}
> 
> class C {}
> 
> This is how it implemented under Swift 2:
> 
> enum UnionABC {
> case classA(A)
> case classB(B)
> case classC(C)
> }
> 
> func input(value: UnionABC) {
> 
> }
> 
> let a = A()
> let b = B()
> let c = C()
> input(UnionABC.classA(a))
> 
> 
> It needs announce all the cases and name each cases and cannot use class 
> names as their case names.
> 
> what about using union? It is more easy and rational.
> 
> 
> func input(value: (A | B | C)) {
> 
> }
> 
> let a= A()
> input(a)
> 
> Or you can implement it with protocol and extension, but compiler will not 
> know how many cases it should have.
> 
> 
> protocol UnionABC {
> 
> }
> 
> extension A: UnionABC {}
> extension B: UnionABC {}
> extension C: UnionABC {}
> 
> 
> func input(value: UnionABC) {
> if value is A {
> 
> } else if value is B {
> 
> } else if value is C {
> 
> } else {
> // There are other cases? Compiler doesn't know
> }
> }
> 
> let a = A()
> input(a)
> 
> 
> 
>> 下面是被转发的邮件:
>> 
>> 发件人: frog...@163.com 
>> 主题: 回复: [swift-evolution] Union instead of Optional
>> 日期: 2016年5月15日 GMT+8 18:00:55
>> 收件人: Austin Zheng mailto:austinzh...@gmail.com>>
>> 
>> 
>> Enum and Union are two things.
>> 
>> If you use Enum to implement Union, you should announce it with case name.
>> 
>> Another issue using enum instead of union is that,  union can combine types 
>> as many as possible, you just write ( A | B | C ... | Z), but for enum, you 
>> should carefully announce it for each case. 
>> 
>> 在 2016年5月15日,15:22,Austin Zheng > > 写道:
>> 
>>> In addition, not everything in Swift can be modeled in terms of inheritance 
>>> relationships.
>>> 
>>> I'm a little curious as to why union types keep on coming up, when enums 
>>> can do everything they can and much more (methods, constraints on generic 
>>> t

Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Haravikk via swift-evolution

> On 16 May 2016, at 11:17, Austin Zheng via swift-evolution 
>  wrote:
> 
> If A, B, and C are not related via protocol or class inheritance, then there 
> is almost nothing you can do with value. Otherwise you still need to test 
> against the concrete type using a case statement or a if-else ladder.

I think that a case statement or similar syntax will still be needed, and the 
case names would just be the types themselves. This would work best with 
support for type-narrowing, for example:

func someMethod(value:(A|B|C)) {
switch (value) {
case .A:
value.someMethodForTypeA()
case .B:
value.someMethodForTypeB()
case .C:
value.someMethodForTypeC()
}
}

A union should really just be though of as a lightweight, restricted form of 
enum that can be declared in a quick ad-hoc fashion, similar to how tuples are 
a simpler form of struct.

I’m generally a +1 for the feature, but I’d be interested to hear about how 
well equipped the compiler is for optimising something like this. In most cases 
an Optional covers what I need, and in more complex cases I’d probably declare 
overloads for each type (i.e- someMethod(value:A), someMethod(value:B) etc.); 
unions could make the latter case simpler, but will the compiler produce the 
same code behind the scenes, i.e- by isolating what’s unique to each type?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Austin Zheng via swift-evolution
I'm sorry, but I don't understand the point you are trying to make.

If you pass in a value of type (A | B | C) to a function, what might you want 
to do with that value?

If you want to do one thing if the value is type A, something else if the value 
is type B, and something else if the value is type C, then you need to switch 
or otherwise type check the value at runtime. You can't get around this, no 
matter whether you use enums, protocols, generics, or union type.

If you want it to do something that A, B, and C all support, use a generic 
and/or a protocol. In this case limiting the inputs to only those three types 
is probably a design smell. The whole point of a shared interface is that it 
only matters that the interface is properly implemented by a type, not what 
that type is.

If you don't care about doing anything with the value, just make your function 
generic: func(input: T).

Austin


> On May 16, 2016, at 3:29 AM, Cao Jiannan  wrote:
> 
> 
> 
> Consider this case:
> 
> class A {
> var someCommonProperty: Int = 0
> }
> class B {
> var someCommonProperty: Int = 0
> }
> class C {
> var someCommonProperty: Int = 0
> }
> 
> protocol UnionABC {
> var someCommonProperty: Int
> }
> 
> extension A: UnionABC {}
> extension B: UnionABC {}
> extension C: UnionABC {}
> 
> 
> = If we using protocol
> 
> 
> func input(value: UnionABC) {
> print(value.someCommonProperty) // Compiler will know their common 
> properties automatically.
> if value is A {
> 
> } else if value is B {
> 
> } else if value is C {
> 
> } else {
> // There are other cases? Compiler doesn't know
> }
> }
> 
> let a = A()
> input(a)
> 
> = If we using union
> 
> func input(value: (A | B | C)) {
> print(value.someCommonProperty) // Compiler will know their common 
> properties automatically.
> 
> if value is A {
> 
> } else if value is B {
> 
> } else if value is C {
> 
> } else {
> // There no other cases, so the compiler trigger a warning.
> }
> }
> 
> let a = A()
> input(a)
> 
> 
> =
> 
> If using generic enum,
> the compiler doesn’t know the type relation between generic union with 
> original type.
> class A and UnionOf3 are totally two different types, has no 
> relationship.
> But class A and (A | B | C) keeps a relationship.
> 
> If using union, these two cases will be allowed:
> 
> let a = A()
> let union: (A|B|C) = a // Automatically wrap.
> 
> a == union // Can be compared, Yes
> 
> sub-typing: 
> 
> var fn0: A->Void = {print(v0)}
> var fn1: (A|B)->Void = {print(v0)}
> 
> fn0 = fn1 // Original Type and Union Type has a sub-typing relationship, OK
> 
> var fn2: (A|B|C)->Void = {print($0)}
> 
> fn0 = fn2 // OK
> fn1 = fn2 // OK
> 
> 
>> 在 2016年5月16日,18:17,Austin Zheng > > 写道:
>> 
>> This doesn't explain how I can use 'value' once an A() is passed into the 
>> function:
>> 
>> func input(value: (A | B | C)) {
>> 
>> }
>> 
>> If A, B, and C are not related via protocol or class inheritance, then there 
>> is almost nothing you can do with value. Otherwise you still need to test 
>> against the concrete type using a case statement or a if-else ladder.
>> 
>> The other 'gain' is being able to call 'input(A())', rather than 
>> 'input(.caseA(A()))'. I agree that the first form is prettier than the 
>> second one. I also think you could make the language pervasively prettier 
>> and more expressive by allowing for all sorts of implicit conversions. At 
>> some point clarity at the point of use beats conciseness, especially when 
>> code within a complex codebase needs to be maintained.
>> 
>> I understand that this is largely a matter of style - different people value 
>> different things, and that's wonderful. I welcome a formal proposal 
>> submitted to the swift-evolution process, and if one appears I'm happy to 
>> consider it in more detail and argue for or against it based on that.
>> 
>> Austin
>> 
>> 
>> 
>> On Sun, May 15, 2016 at 3:34 AM, Cao Jiannan > > wrote:
>> for example, there is a method input union of 3 types: A, B, C,
>> 
>> This is the three class.
>> 
>> class A {}
>> 
>> class B {}
>> 
>> class C {}
>> 
>> This is how it implemented under Swift 2:
>> 
>> enum UnionABC {
>> case classA(A)
>> case classB(B)
>> case classC(C)
>> }
>> 
>> func input(value: UnionABC) {
>> 
>> }
>> 
>> let a = A()
>> let b = B()
>> let c = C()
>> input(UnionABC.classA(a))
>> 
>> 
>> It needs announce all the cases and name each cases and cannot use class 
>> names as their case names.
>> 
>> what about using union? It is more easy and rational.
>> 
>> 
>> func input(value: (A | B | C)) {
>> 
>> }
>> 
>> let a= A()
>> input(a)
>> 
>> Or you can implement it with protocol and extension, but compiler will not 
>> know how many cases it should have.
>> 
>> 
>> protocol Unio

Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Austin Zheng via swift-evolution
I like the justification of unions as lightweight restricted ad-hoc enums. 
Definitely agreed with you in that the compiler will have to do more work, and 
should be able to handle the implicit conversion without going bonkers.

Thanks!

Austin

> On May 16, 2016, at 3:35 AM, Haravikk  wrote:
> 
> 
>> On 16 May 2016, at 11:17, Austin Zheng via swift-evolution 
>>  wrote:
>> 
>> If A, B, and C are not related via protocol or class inheritance, then there 
>> is almost nothing you can do with value. Otherwise you still need to test 
>> against the concrete type using a case statement or a if-else ladder.
> 
> I think that a case statement or similar syntax will still be needed, and the 
> case names would just be the types themselves. This would work best with 
> support for type-narrowing, for example:
> 
>   func someMethod(value:(A|B|C)) {
>   switch (value) {
>   case .A:
>   value.someMethodForTypeA()
>   case .B:
>   value.someMethodForTypeB()
>   case .C:
>   value.someMethodForTypeC()
>   }
>   }
> 
> A union should really just be though of as a lightweight, restricted form of 
> enum that can be declared in a quick ad-hoc fashion, similar to how tuples 
> are a simpler form of struct.
> 
> I’m generally a +1 for the feature, but I’d be interested to hear about how 
> well equipped the compiler is for optimising something like this. In most 
> cases an Optional covers what I need, and in more complex cases I’d probably 
> declare overloads for each type (i.e- someMethod(value:A), 
> someMethod(value:B) etc.); unions could make the latter case simpler, but 
> will the compiler produce the same code behind the scenes, i.e- by isolating 
> what’s unique to each type?

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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Cao Jiannan via swift-evolution
Hi Austin,

let me repeat the example so that clarify my point from this example.

protocol cannot do this:

func input(value: ProtocolForABC) {
print(value.someCommonProperty)

if value is A {

} else if value is B {

} else if value is C {

} else {
// There no other cases, but compiler will not trigger a warning.
}
}

The compiler will not know your protocol is only conformed to these three 
classes.
So the else block will not trigger a warning.

- Jiannan


> 在 2016年5月16日,18:37,Austin Zheng  写道:
> 
> I'm sorry, but I don't understand the point you are trying to make.
> 
> If you pass in a value of type (A | B | C) to a function, what might you want 
> to do with that value?
> 
> If you want to do one thing if the value is type A, something else if the 
> value is type B, and something else if the value is type C, then you need to 
> switch or otherwise type check the value at runtime. You can't get around 
> this, no matter whether you use enums, protocols, generics, or union type.
> 
> If you want it to do something that A, B, and C all support, use a generic 
> and/or a protocol. In this case limiting the inputs to only those three types 
> is probably a design smell. The whole point of a shared interface is that it 
> only matters that the interface is properly implemented by a type, not what 
> that type is.
> 
> If you don't care about doing anything with the value, just make your 
> function generic: func(input: T).
> 
> Austin
> 

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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Leonardo Pessoa via swift-evolution
I can understand this proposal nite and I don't really think they're related to 
enums at all. You can today achieve the very same behaviour using an empty 
protocol.

protocol P { }

class A : P { }
class B : P { }
struct C : P { }

func test(value : P) { }

IMO, the proposed syntax will only create a shortcut for this. And we'd still 
need to test type and cast the to get anything useful. My question now is: is 
this such a common practice that justifies the shortcut?

-Original Message-
From: "Haravikk via swift-evolution" 
Sent: ‎16/‎05/‎2016 07:35 AM
To: "Austin Zheng" 
Cc: "Adrian Zubarev via swift-evolution" ; "Cao 
Jiannan" 
Subject: Re: [swift-evolution] Union instead of Optional


> On 16 May 2016, at 11:17, Austin Zheng via swift-evolution 
>  wrote:
> 
> If A, B, and C are not related via protocol or class inheritance, then there 
> is almost nothing you can do with value. Otherwise you still need to test 
> against the concrete type using a case statement or a if-else ladder.

I think that a case statement or similar syntax will still be needed, and the 
case names would just be the types themselves. This would work best with 
support for type-narrowing, for example:

func someMethod(value:(A|B|C)) {
switch (value) {
case .A:
value.someMethodForTypeA()
case .B:
value.someMethodForTypeB()
case .C:
value.someMethodForTypeC()
}
}

A union should really just be though of as a lightweight, restricted form of 
enum that can be declared in a quick ad-hoc fashion, similar to how tuples are 
a simpler form of struct.

I’m generally a +1 for the feature, but I’d be interested to hear about how 
well equipped the compiler is for optimising something like this. In most cases 
an Optional covers what I need, and in more complex cases I’d probably declare 
overloads for each type (i.e- someMethod(value:A), someMethod(value:B) etc.); 
unions could make the latter case simpler, but will the compiler produce the 
same code behind the scenes, i.e- by isolating what’s unique to each type?
___
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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Leonardo Pessoa via swift-evolution
I don't really get it why the compiler is to complain about the if block not 
having an else in this case. That seems like a bug that will push us to write 
unnecessary code. The compiler is not capable of inferring there are more 
conditions to evaluate in an if statement opposed to a switch statement. Even 
with the proposed union the compiler cannot infer the need for an else block 
here because the programmer might not want to do anything else with whatever 
doesn't match the first condition.

On the other hand, if you intend to add to this proposal that a switch 
statement could evaluate the type of the value like the following code, I'd 
agree with you. I'm just not sure one could do this as of today.

func input(value: (A | B | C)) {
   switch value.type {
  case A:
 ...
  case B:
 ...
  default:
 // here the compiler knows I didn't cover all possible types
 // adding 'case C' here makes 'default' unnecessary
   }
}

I would add to this discussion if this would be the best syntax for the 
proposed type. I'd think about 'union' as it matched other existing 
syntax and is a bit more explicit about what's going on the code.

> On 16 May 2016, at 7:55 am, Cao Jiannan via swift-evolution 
>  wrote:
> 
> Hi Austin,
> 
> let me repeat the example so that clarify my point from this example.
> 
> protocol cannot do this:
> 
> func input(value: ProtocolForABC) {
> print(value.someCommonProperty)
> 
> if value is A {
> 
> } else if value is B {
> 
> } else if value is C {
> 
> } else {
> // There no other cases, but compiler will not trigger a warning.
> }
> }
> 
> The compiler will not know your protocol is only conformed to these three 
> classes.
> So the else block will not trigger a warning.
> 
> - Jiannan
> 
> 
>> 在 2016年5月16日,18:37,Austin Zheng  写道:
>> 
>> I'm sorry, but I don't understand the point you are trying to make.
>> 
>> If you pass in a value of type (A | B | C) to a function, what might you 
>> want to do with that value?
>> 
>> If you want to do one thing if the value is type A, something else if the 
>> value is type B, and something else if the value is type C, then you need to 
>> switch or otherwise type check the value at runtime. You can't get around 
>> this, no matter whether you use enums, protocols, generics, or union type.
>> 
>> If you want it to do something that A, B, and C all support, use a generic 
>> and/or a protocol. In this case limiting the inputs to only those three 
>> types is probably a design smell. The whole point of a shared interface is 
>> that it only matters that the interface is properly implemented by a type, 
>> not what that type is.
>> 
>> If you don't care about doing anything with the value, just make your 
>> function generic: func(input: T).
>> 
>> Austin
> 
> ___
> 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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Tino Heth via swift-evolution
> Precisely. To me unions are to enums with associated type the same way tuples 
> are to structs.
Me too — and I think it would be beautiful if it could be modeled that way, so 
that there is always a pair of a named and an anonymous variant for functions 
(closures), types (structs) and enums (yet to come). 

> One is named, has well-defined semantics, can conform to protocols, can have 
> complex internal structure, can have methods, etc. The other is ad-hoc and 
> lightweight, easy to define at the site of use, best suited for simple 
> purposes, has special syntax to support it. 
That also true for closures, yet I'm very happy how flexible regular methods 
can be used as blocks.

> Even if we can extend tuples in the future, though, I wouldn't want structs 
> to go away. When exceeding some level of complexity structs are just more 
> explicit than tuples, and therefore easier to understand.
I don't think something as fundamental as structs should ever be removed, but 
imho it would be great to see some unification of concepts…

struct Point: Tuple {
// methods...
// "inheritance for structs"-poposal delayed until Swift 4 ;-)
}
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Michael Peternell via swift-evolution

> Am 16.05.2016 um 12:07 schrieb Austin Zheng via swift-evolution 
> :
> 
> Precisely. To me unions are to enums with associated type the same way tuples 
> are to structs. One is named, has well-defined semantics, can conform to 
> protocols, can have complex internal structure, can have methods, etc. The 
> other is ad-hoc and lightweight, easy to define at the site of use, best 
> suited for simple purposes, has special syntax to support it. 
> 
> Even if we can extend tuples in the future, though, I wouldn't want structs 
> to go away. When exceeding some level of complexity structs are just more 
> explicit than tuples, and therefore easier to understand.
> 
> Finally, please note that Ceylon is a pervasively object-oriented language 
> with a single root superclass. Neither of those is true for Swift, which 
> chooses to solve a lot of problems in a different (and I would argue, 
> superior) way. So solutions that might work well in Ceylon might not be 
> suited for Swift, at least not without modification, and vice versa. The core 
> team could certainly have chosen to model Swift's type system after that of 
> e.g. Scala, but they chose not to, and I think they did so for good reason.

Swift has a root class, it is called SwiftObject and it's visible from 
Objective-C ;) Just thinking about it.. it makes sense: the whole 
reference-counting-stuff has to live somewhere in the object, and there has to 
be some kind of isa-pointer to allow for subclassing (and Objective-C 
interoperability). So there is some common behavior regarding all classes 
defined from Swift (they all implement retain, release, autorelease, isEqual:, 
class, respondsToSelector:, the whole NSObject-protocol...) => what I want to 
express: Java has a root-class, C++ has no root class - that's uncontested; but 
Swift is somewhere in-between IMHO.

And for enums and unions.. I think they are different. enums are "sum-types" 
and unions are... well... "union-types", when you think of data types as sets. 
E.g. if A, B are data types (sets), then an enum that can be either anA(A) or 
aB(B) can be thought of as the set A+B (and if A \intersect B \not\eq 
\emptyset, you can think of this as (0,A)\union (1,B) ). A union B is not the 
same. In C, the unions are not even safe, because they are not discriminated in 
any way. In Swift they make an isomorphic set if A and B are disjoint. If 
A=String and B=Int, A `enum` B is isomorphic to A `union` B (sorry for abusing 
Haskell syntax :-/ ). But if A=Iterable and B=Array, they are 
not the same, because now A is a superset of B. So A `enum` B is a strict 
superset of A `union` B (== A). I can already imagine weird bugs coming to the 
surface from this distinction, all of which can be solved by disallowing union 
types altogether.

Therefore I think that unions are not worth the trouble at all. And they are 
even possible right now: Instead of writing

union MyUnion { Int, String }
// or typealias MyUnion = (Int | String) // ?

you'd have to write

protocol MyUnion {}
extension Int: MyUnion {}
extension String: MyUnion {}

The two definitions are basically equivalent, and the second is already valid 
Swift.

I have used unions a few times in C though, e.g. for converting from void* to 
int or stuff like that, at a time when I didn't know about reinterpret_cast 
(Swift: unsafeBitcast) yet. The few occasions where they are use in the C 
standard library, they are always discriminated, like a union between a 
struct(int type, float foo, ...) and another struct(int type, char bar[20], 
...) where the type parameter is in both values and can be used to distinguish 
them. In Swift they are always distinguishable because of runtime type 
information (except for the case described above), so you can as well just use 
an enum and make that information obvious. To unpack the information you can 
use `if let` when dealing with a union, and you can use `if case` or `switch` 
when dealing with an enum. I don't see how unions would be more convenient to 
be worth the trouble. Swift unions would be like (C unions + RTTI (runtime type 
information)), with RTTI replacing the discriminator element of enums, except 
when the types overlap. So I doubt that anyone will find a decent (realistic!) 
use-case that is not just as easily (and conveniently) implemented using enums. 
I think I just proved that there is no such use case ;) The best way to 
convince me otherwise would be to provide a realistic piece of example code.

Regards,
Michael

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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Joe Groff via swift-evolution
Unlike sum types, such as Swift enums, unions don't have parametricity, because 
(T \union Nil) \union Nil == T \union Nil. This means that things like 
collections containing Optionals don't just work, since it becomes impossible 
for operations like 'find' to distinguish 'nil' as a value in the container 
from 'nil' as a "not found" result. Languages without sum types tend to 
compensate by growing multiple "nil"-like values—ObjC has NSNull, Javascript 
has undefined and null, VB has Null, Nothing, *and* None, and so on.

-Joe

> On May 14, 2016, at 7:33 PM, Cao Jiannan via swift-evolution 
>  wrote:
> 
> 
> It’s kind of same idea of TypeScipt 2, at 46:21 in this video.
> 
> https://channel9.msdn.com/Events/Build/2016/B881
> 
> <屏幕快照 2016-05-15 10.20.36.png>
> 
> 
>> 
>> 2016-2-16 GMT+8 14:36:28
>> Hi all,
>> 
>> I think the best way to solve the either problem is to separate it from 
>> generic. 
>> Optional and Either shouldn’t work the same way of generic type. 
>> It’s just a represent of multiple type in one location.
>> 
>> Using an old friend, Union in C.
>> union {
>>  case firstType
>>  case secondType
>> }
>> 
>> This is the final solution for the sub typing problem of optional.
>> 
>> A  == union(A,A)
>> union(A,B) == union(B,A)
>> B == union(B,B)
>> 
>> B is subtype of union(A,B)
>> A is subtype of union(A,B)
>> union(A,B,C) is subtype of union(A,B,C,D,…)
>> 
>> suppose 
>> a is subclass of A
>> b is subclass of B, then
>>  union(a,B) is subtype of union(A,B)
>>  union(A,b) is subtype of union(A,B)
>>  union(a,b) is subtype of union(a,B)
>>  union(a,b) is subtype of union(A,b)
>> 
>> union can have as many case as possible. e.g., union(A,B,C,D,…)
>> 
>> So the Optional should be union(UITableView, None)
>> and Optional should be union(MyTableView, None), which is 
>> subclass of union(UITableView, None)
>> 
>> This is a final rational solution. I think.
>> 
>> -Jiannan
>> 
> 
> 
> 
> 
> ___
> 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


Re: [swift-evolution] Union instead of Optional

2016-05-16 Thread Thorsten Seitz via swift-evolution

> Am 16.05.2016 um 17:29 schrieb Michael Peternell via swift-evolution 
> :
> 
> 
>> Am 16.05.2016 um 12:07 schrieb Austin Zheng via swift-evolution 
>> :
>> 
>> Precisely. To me unions are to enums with associated type the same way 
>> tuples are to structs. One is named, has well-defined semantics, can conform 
>> to protocols, can have complex internal structure, can have methods, etc. 
>> The other is ad-hoc and lightweight, easy to define at the site of use, best 
>> suited for simple purposes, has special syntax to support it. 
>> 
>> Even if we can extend tuples in the future, though, I wouldn't want structs 
>> to go away. When exceeding some level of complexity structs are just more 
>> explicit than tuples, and therefore easier to understand.
>> 
>> Finally, please note that Ceylon is a pervasively object-oriented language 
>> with a single root superclass. Neither of those is true for Swift, which 
>> chooses to solve a lot of problems in a different (and I would argue, 
>> superior) way. So solutions that might work well in Ceylon might not be 
>> suited for Swift, at least not without modification, and vice versa. The 
>> core team could certainly have chosen to model Swift's type system after 
>> that of e.g. Scala, but they chose not to, and I think they did so for good 
>> reason.
> 
> Swift has a root class, it is called SwiftObject and it's visible from 
> Objective-C ;) Just thinking about it.. it makes sense: the whole 
> reference-counting-stuff has to live somewhere in the object, and there has 
> to be some kind of isa-pointer to allow for subclassing (and Objective-C 
> interoperability). So there is some common behavior regarding all classes 
> defined from Swift (they all implement retain, release, autorelease, 
> isEqual:, class, respondsToSelector:, the whole NSObject-protocol...) => what 
> I want to express: Java has a root-class, C++ has no root class - that's 
> uncontested; but Swift is somewhere in-between IMHO.
> 
> And for enums and unions.. I think they are different. enums are "sum-types" 
> and unions are... well... "union-types", when you think of data types as 
> sets. E.g. if A, B are data types (sets), then an enum that can be either 
> anA(A) or aB(B) can be thought of as the set A+B (and if A \intersect B 
> \not\eq \emptyset, you can think of this as (0,A)\union (1,B) ). A union B is 
> not the same. In C, the unions are not even safe, because they are not 
> discriminated in any way. In Swift they make an isomorphic set if A and B are 
> disjoint. If A=String and B=Int, A `enum` B is isomorphic to A `union` B 
> (sorry for abusing Haskell syntax :-/ ). But if A=Iterable and 
> B=Array, they are not the same, because now A is a superset of B. So 
> A `enum` B is a strict superset of A `union` B (== A). I can already imagine 
> weird bugs coming to the surface from this distinction, all of which can be 
> solved by disallowing union types altogether.

Ceylon’s type system handles these things nicely. Iterable | 
Array would reduce to Iterable, for example, and when switching 
over union types the type checker knows when types are not disjoint 
(disallowing the switch) or whether the switch is exhaustive.

For more details, see http://ceylon-lang.org/documentation/1.2/tour/types/

> 
> Therefore I think that unions are not worth the trouble at all. And they are 
> even possible right now: Instead of writing
> 
>union MyUnion { Int, String }
>// or typealias MyUnion = (Int | String) // ?
> 
> you'd have to write
> 
>protocol MyUnion {}
>extension Int: MyUnion {}
>extension String: MyUnion {}
> 
> The two definitions are basically equivalent, and the second is already valid 
> Swift.

Alas, that is only possible for explicit named unions but the power of type 
unions lies in their „ad hoc“-ness, e.g. in generic unions like

func union(a: Set, b: Set) -> Set { … }  // Note: all 
examples in hypothetically extended Swift syntax instead of Ceylon syntax

extension Dictionary {
func getOrDefault(default: Default) -> Value | Default // in 
the general simple case Default == Value, which results in Value | Default == 
Value
}

Ceylon models the concept of empty and non-empty streams by defining

protocol Iterable {
associatedtype Element
associatedtype Absent : Null = Null // Null is the type containing 
a single value null (= nil in Swift); Ceylon’s optionals are just type unions 
T? == T | Null

var first: Absent | Element { get }
var rest: Iterable where Iterable.Element == Element, Iterable.Absent 
== Null

// Produces a non-empty stream with a given initial element, followed 
by the elements of this stream, in the order in which they occur in this stream.
func follow(head: Other) -> Iterable where Iterable.Element == Element 
| Other, Iterable.Absent = Nothing
…
}

This means that
Iterable // with the default Absent = Null
can be empty, whereas
Iterab