- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Union types
Fri, 2011-04-15, 17:00
hi,
I wanted to put an idea in the round that came up in a comment of a stackoverflow entry ( http://stackoverflow.com/questions/5645700/whats-the-difference-between-... ):
We have a sort of type intersection in the form of `A with B`, so that in
def perform( x: A with B ) { ... }
we can assume the functionality of both types `A` and `B`. Wouldn't it be a very interesting idea to explore the possibility of a type *union*, like
def perform( x: A or B ) { ... }
so that the main body of that method can safely invoke anything on `x` which is common between types `A` and `B`. It would then be possible to do an exhaustive match like this:
def perform( x: A or B ) {
...
x match {
case a: A => ...
case b: B => ...
}
}
and that way in some distant version of Scala one would overcome the need to have method overloading and multiple constructors.
Although we will hopefully in this distant version have fully supported runtime generics, this could also solve the case of
def perform( a: List[ A ]) { ... }
def perform( b: List[ B ]) { ... }
under the condition that erasure is still happening, because then you could do
def perform( a: List[ A or B ]) { ... }
i know there is `Either` but that has many disadvantages against this union types -- it is extra verbose, cannot handle view bounds on its type parameters without much extra bloat of implicits work, and it cannot handle more than two types.
best, -sciss-
Fri, 2011-04-15, 17:27
#2
Re: Union types
How often would you use that where the more general structural types wouldn't work?
On 15 Apr 2011 18:00, "Sciss" <contact@sciss.de> wrote:
hi,
I wanted to put an idea in the round that came up in a comment of a stackoverflow entry ( http://stackoverflow.com/questions/5645700/whats-the-difference-between-scala-and-red-hats-ceylon-language/5646305#comment-6468943 ):
We have a sort of type intersection in the form of `A with B`, so that in
def perform( x: A with B ) { ... }
we can assume the functionality of both types `A` and `B`. Wouldn't it be a very interesting idea to explore the possibility of a type *union*, like
def perform( x: A or B ) { ... }
so that the main body of that method can safely invoke anything on `x` which is common between types `A` and `B`. It would then be possible to do an exhaustive match like this:
def perform( x: A or B ) {
...
x match {
case a: A => ...
case b: B => ...
}
}
and that way in some distant version of Scala one would overcome the need to have method overloading and multiple constructors.
Although we will hopefully in this distant version have fully supported runtime generics, this could also solve the case of
def perform( a: List[ A ]) { ... }
def perform( b: List[ B ]) { ... }
under the condition that erasure is still happening, because then you could do
def perform( a: List[ A or B ]) { ... }
i know there is `Either` but that has many disadvantages against this union types -- it is extra verbose, cannot handle view bounds on its type parameters without much extra bloat of implicits work, and it cannot handle more than two types.
best, -sciss-
Fri, 2011-04-15, 17:27
#3
Re: Union types
note that A and B do not necessarily have any substantial common interface! the pattern matching example below is exactly where union types would fit in and structural types clearly not.
On 15 Apr 2011, at 17:13, Chris Twiner wrote:
> How often would you use that where the more general structural types wouldn't work?
>
>
>> On 15 Apr 2011 18:00, "Sciss" wrote:
>>
>> hi,
>>
>> I wanted to put an idea in the round that came up in a comment of a stackoverflow entry ( http://stackoverflow.com/questions/5645700/whats-the-difference-between-... ):
>>
>> We have a sort of type intersection in the form of `A with B`, so that in
>>
>> def perform( x: A with B ) { ... }
>>
>> we can assume the functionality of both types `A` and `B`. Wouldn't it be a very interesting idea to explore the possibility of a type *union*, like
>>
>> def perform( x: A or B ) { ... }
>>
>> so that the main body of that method can safely invoke anything on `x` which is common between types `A` and `B`. It would then be possible to do an exhaustive match like this:
>>
>> def perform( x: A or B ) {
>> ...
>> x match {
>> case a: A => ...
>> case b: B => ...
>> }
>> }
>>
>> and that way in some distant version of Scala one would overcome the need to have method overloading and multiple constructors.
>>
>> Although we will hopefully in this distant version have fully supported runtime generics, this could also solve the case of
>>
>> def perform( a: List[ A ]) { ... }
>> def perform( b: List[ B ]) { ... }
>>
>> under the condition that erasure is still happening, because then you could do
>>
>> def perform( a: List[ A or B ]) { ... }
>>
>> i know there is `Either` but that has many disadvantages against this union types -- it is extra verbose, cannot handle view bounds on its type parameters without much extra bloat of implicits work, and it cannot handle more than two types.
>>
>> best, -sciss-
>>
>
Fri, 2011-04-15, 17:37
#4
Re: Union types
Hooray !!!
`List(1.0, 2)` by the way is a good example of where this could be extremely useful, too.
best, -sciss-
On 15 Apr 2011, at 17:12, Paul Phillips wrote:
> On 4/15/11 9:00 AM, Sciss wrote:
>> we can assume the functionality of both types `A` and `B`. Wouldn't it be a very interesting idea to explore the possibility of a type *union*, like
>>
>> def perform( x: A or B ) { ... }
>
> https://lampsvn.epfl.ch/trac/scala/ticket/3749
>
> "We plan to address this issue in future versions of Scala by introducing union types, so that the approximation of the least upper bound you see here could be denoted directly (and precisely) as java.lang.Double or java.lang.Long. [...]
>
> First, we need to work out the nitty gritty details of the theory, though."
Fri, 2011-04-15, 17:47
#5
Re: Union types
Mitch Blevins implements this in his blog entry "Stuttering Or":
http://cleverlytitled.blogspot.com/2009/03/so-i-read-both-jim-mcbeath-an...
--
Jim
On Fri, Apr 15, 2011 at 05:00:30PM +0100, Sciss wrote:
> Date: Fri, 15 Apr 2011 17:00:30 +0100
> From: Sciss
> To: scala-language@googlegroups.com
> Subject: [scala-language] Union types
>
> hi,
>
> I wanted to put an idea in the round that came up in a comment of a stackoverflow entry ( http://stackoverflow.com/questions/5645700/whats-the-difference-between-... ):
>
> We have a sort of type intersection in the form of `A with B`, so that in
>
> def perform( x: A with B ) { ... }
>
> we can assume the functionality of both types `A` and `B`. Wouldn't it be a very interesting idea to explore the possibility of a type *union*, like
>
> def perform( x: A or B ) { ... }
>
> so that the main body of that method can safely invoke anything on `x` which is common between types `A` and `B`. It would then be possible to do an exhaustive match like this:
>
> def perform( x: A or B ) {
> ...
> x match {
> case a: A => ...
> case b: B => ...
> }
> }
>
> and that way in some distant version of Scala one would overcome the need to have method overloading and multiple constructors.
>
> Although we will hopefully in this distant version have fully supported runtime generics, this could also solve the case of
>
> def perform( a: List[ A ]) { ... }
> def perform( b: List[ B ]) { ... }
>
> under the condition that erasure is still happening, because then you could do
>
> def perform( a: List[ A or B ]) { ... }
>
> i know there is `Either` but that has many disadvantages against this union types -- it is extra verbose, cannot handle view bounds on its type parameters without much extra bloat of implicits work, and it cannot handle more than two types.
>
> best, -sciss-
>
Fri, 2011-04-15, 17:57
#6
Re: Union types
very neat!
the only downsides are that the compiler cannot check the matches for exhaustiveness, that i cannot use common interface between the types, and that you need to import half a dozen imports (that always makes me slightly depressed and i think this is an example of why people keep having the impression that scala is too complicated).
best, -sciss-
On 15 Apr 2011, at 17:23, Jim McBeath wrote:
> Mitch Blevins implements this in his blog entry "Stuttering Or":
> http://cleverlytitled.blogspot.com/2009/03/so-i-read-both-jim-mcbeath-an...
>
> --
> Jim
>
> On Fri, Apr 15, 2011 at 05:00:30PM +0100, Sciss wrote:
>> Date: Fri, 15 Apr 2011 17:00:30 +0100
>> From: Sciss
>> To: scala-language@googlegroups.com
>> Subject: [scala-language] Union types
>>
>> hi,
>>
>> I wanted to put an idea in the round that came up in a comment of a stackoverflow entry ( http://stackoverflow.com/questions/5645700/whats-the-difference-between-... ):
>>
>> We have a sort of type intersection in the form of `A with B`, so that in
>>
>> def perform( x: A with B ) { ... }
>>
>> we can assume the functionality of both types `A` and `B`. Wouldn't it be a very interesting idea to explore the possibility of a type *union*, like
>>
>> def perform( x: A or B ) { ... }
>>
>> so that the main body of that method can safely invoke anything on `x` which is common between types `A` and `B`. It would then be possible to do an exhaustive match like this:
>>
>> def perform( x: A or B ) {
>> ...
>> x match {
>> case a: A => ...
>> case b: B => ...
>> }
>> }
>>
>> and that way in some distant version of Scala one would overcome the need to have method overloading and multiple constructors.
>>
>> Although we will hopefully in this distant version have fully supported runtime generics, this could also solve the case of
>>
>> def perform( a: List[ A ]) { ... }
>> def perform( b: List[ B ]) { ... }
>>
>> under the condition that erasure is still happening, because then you could do
>>
>> def perform( a: List[ A or B ]) { ... }
>>
>> i know there is `Either` but that has many disadvantages against this union types -- it is extra verbose, cannot handle view bounds on its type parameters without much extra bloat of implicits work, and it cannot handle more than two types.
>>
>> best, -sciss-
>>
Sat, 2011-04-16, 05:37
#7
Re: Union types
On Friday April 15 2011, Paul Phillips wrote:
> On 4/15/11 9:00 AM, Sciss wrote:
> > we can assume the functionality of both types `A` and `B`. Wouldn't
> > it be a very interesting idea to explore the possibility of a type
> > *union*, like
> >
> > def perform( x: A or B ) { ... }
>
> https://lampsvn.epfl.ch/trac/scala/ticket/3749
>
> "We plan to address this issue in future versions of Scala by
> introducing union types, so that the approximation of the least upper
> bound you see here could be denoted directly (and precisely) as
> java.lang.Double or java.lang.Long. [...]
The LUB of two arbitrary types will in general subsume many types that
would not otherwise be compatible with either of the two original
types, so this does not seem to me like a proper interpretation of the
union of two types.
> First, we need to work out the nitty gritty details of the theory,
> though."
Randall Schulz
Sat, 2011-04-16, 08:07
#8
Re: Union types
Thanks; curious, familiar technique: building colimits in toposes (Mikkelsen, Pare)
On Fri, Apr 15, 2011 at 9:23 AM, Jim McBeath <scala@j.jimmc.org> wrote:
On Fri, Apr 15, 2011 at 9:23 AM, Jim McBeath <scala@j.jimmc.org> wrote:
Mitch Blevins implements this in his blog entry "Stuttering Or":
http://cleverlytitled.blogspot.com/2009/03/so-i-read-both-jim-mcbeath-and-michids.html
--
Jim
On Fri, Apr 15, 2011 at 05:00:30PM +0100, Sciss wrote:
> Date: Fri, 15 Apr 2011 17:00:30 +0100
> From: Sciss <contact@sciss.de>
> To: scala-language@googlegroups.com
> Subject: [scala-language] Union types
>
> hi,
>
> I wanted to put an idea in the round that came up in a comment of a stackoverflow entry ( http://stackoverflow.com/questions/5645700/whats-the-difference-between-scala-and-red-hats-ceylon-language/5646305#comment-6468943 ):
>
> We have a sort of type intersection in the form of `A with B`, so that in
>
> def perform( x: A with B ) { ... }
>
> we can assume the functionality of both types `A` and `B`. Wouldn't it be a very interesting idea to explore the possibility of a type *union*, like
>
> def perform( x: A or B ) { ... }
>
> so that the main body of that method can safely invoke anything on `x` which is common between types `A` and `B`. It would then be possible to do an exhaustive match like this:
>
> def perform( x: A or B ) {
> ...
> x match {
> case a: A => ...
> case b: B => ...
> }
> }
>
> and that way in some distant version of Scala one would overcome the need to have method overloading and multiple constructors.
>
> Although we will hopefully in this distant version have fully supported runtime generics, this could also solve the case of
>
> def perform( a: List[ A ]) { ... }
> def perform( b: List[ B ]) { ... }
>
> under the condition that erasure is still happening, because then you could do
>
> def perform( a: List[ A or B ]) { ... }
>
> i know there is `Either` but that has many disadvantages against this union types -- it is extra verbose, cannot handle view bounds on its type parameters without much extra bloat of implicits work, and it cannot handle more than two types.
>
> best, -sciss-
>
Mon, 2011-04-18, 00:07
#9
Re: Union types
FWIW, I was wanting the same capability myself last week, to address
the difficulty of overloading methods by parameter type, when the
types are parametrized.
I often find myself wanting an API to respond to several related
parametrized types. Some common examples:
aMethod(t: T)
aMethod(optT: Option[T])
aMethod(ts: Seq[T])
It would be nice to support this without requiring implicit conversions.
-Ben
On Sat, Apr 16, 2011 at 2:00 AM, Sciss wrote:
Wouldn't it be a very interesting idea to explore the possibility of a
type *union*, like
>
> def perform( x: A or B ) { ... }
>
> so that the main body of that method can safely invoke anything on `x` which is common between types `A` and `B`. It would then be possible to do an exhaustive match like this:
>
> def perform( x: A or B ) {
> ...
> x match {
> case a: A => ...
> case b: B => ...
> }
> }
>
> and that way in some distant version of Scala one would overcome the need to have method overloading and multiple constructors.
Mon, 2011-04-18, 09:17
#10
Re: Union types
2011/4/18 Ben Hutchison <ben@playscapegames.com>
FWIW, I was wanting the same capability myself last week, to address
the difficulty of overloading methods by parameter type, when the
types are parametrized.
I often find myself wanting an API to respond to several related
parametrized types. Some common examples:
aMethod(t: T)
aMethod(optT: Option[T])
aMethod(ts: Seq[T])
It would be nice to support this without requiring implicit conversions.
Not exactly the same problem. What you want is syntactic sugar to port some methods to container types, but that is not exactly what union types would create. Union types would allow you to do
aMethod(a: A or Option[A]) : B
which is somehow equivalent to what you're looking for. This example can clearly be desugared to :
aMethod(a: A) : B
aMethod(Option[A]) : B
I personnally think that implicits are the right way to go for that case.
Union types would also allow you to do :
anotherMethod(abs: Seq[A or B]) : C
or even stranger :
another method(a: A) : B or C
which means that the Seq requested as parameter would contain potentially A instances and B instances at same time. The problem is more complex and as Martin said, I think the integration of such thing in Scala has to be studied first, to check it doesn't break the coherence of the type system.
-Ben
On Sat, Apr 16, 2011 at 2:00 AM, Sciss <contact@sciss.de> wrote:
Wouldn't it be a very interesting idea to explore the possibility of a
type *union*, like
>
> def perform( x: A or B ) { ... }
>
> so that the main body of that method can safely invoke anything on `x` which is common between types `A` and `B`. It would then be possible to do an exhaustive match like this:
>
> def perform( x: A or B ) {
> ...
> x match {
> case a: A => ...
> case b: B => ...
> }
> }
>
> and that way in some distant version of Scala one would overcome the need to have method overloading and multiple constructors.
On 4/15/11 9:00 AM, Sciss wrote:
> we can assume the functionality of both types `A` and `B`. Wouldn't it be a very interesting idea to explore the possibility of a type *union*, like
>
> def perform( x: A or B ) { ... }
https://lampsvn.epfl.ch/trac/scala/ticket/3749
"We plan to address this issue in future versions of Scala by
introducing union types, so that the approximation of the least upper
bound you see here could be denoted directly (and precisely) as
java.lang.Double or java.lang.Long. [...]
First, we need to work out the nitty gritty details of the theory, though."