Union types status

219 views
Skip to first unread message

Don Olmstead

unread,
Jun 19, 2015, 2:51:05 PM6/19/15
to mi...@dartlang.org
Any updates on union types? Last time they were mentioned was in http://news.dartlang.org/2015/01/dart-language-evolution-discussed-in.html and I haven't seen a DEP around them. This still something that could be added?

Gilad Bracha

unread,
Jun 19, 2015, 3:23:09 PM6/19/15
to mi...@dartlang.org
It definitely could, but it's perhaps slightly less of a priority than first seemed.  A major motivation was to help with JS interop, but with dart for the web having more leeway than it used to, it may find its way by other means. As we are more optimistic about non-nullable types than we used to, our focus has shifted a bit.

On Fri, Jun 19, 2015 at 11:51 AM Don Olmstead <don.j.o...@gmail.com> wrote:
Any updates on union types? Last time they were mentioned was in http://news.dartlang.org/2015/01/dart-language-evolution-discussed-in.html and I haven't seen a DEP around them. This still something that could be added?

--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.

Don Olmstead

unread,
Jun 19, 2015, 3:56:44 PM6/19/15
to mi...@dartlang.org
Thanks for the update Gilad. Thought it was more of a priority as typescript and closure compiler have that functionality. Is anyone planning on taking a stab at a dep for it? Been thinking about getting involved in the dep process.

Gilad Bracha

unread,
Jun 19, 2015, 4:03:49 PM6/19/15
to mi...@dartlang.org
As I said, dart2js interop was the motivation; it may be that DDC just learns to read .ts header files or something.  Hence it is less of a priority than it was.

On Fri, Jun 19, 2015 at 12:56 PM Don Olmstead <don.j.o...@gmail.com> wrote:
Thanks for the update Gilad. Thought it was more of a priority as typescript and closure compiler have that functionality. Is anyone planning on taking a stab at a dep for it? Been thinking about getting involved in the dep process.

--

Kasper Peulen

unread,
Jun 28, 2015, 7:38:12 PM6/28/15
to mi...@dartlang.org
As I said, dart2js interop was the motivation; it may be that DDC just learns to read .ts header files or something.  Hence it is less of a priority than it was.

I don't understand why this would make it less a priority. If you are doing interop in dart with union types, then I would think that it is also desriable that the analyser understand the object is an union type not just the compiler. 

To me it feels union types are really missing in the dart langauge. It is true that I mostly notice this when I'm doing js interop, but I do think that that union types can give you sometimes the freedom to come up with more elegant solution. If you write dart, you don't even think about those options, as you know it is not possible. I find it sad that there is not a nice equivalent for this in dart code, and that I need to write uglier code in dart, than the code written in javascript/typescript.


Op vrijdag 19 juni 2015 22:03:49 UTC+2 schreef Gilad:

Bob Nystrom

unread,
Jun 29, 2015, 11:57:18 AM6/29/15
to General Dart Discussion
On Sun, Jun 28, 2015 at 4:38 PM, Kasper Peulen <kasper...@gmail.com> wrote:
I don't understand why this would make it less a priority. If you are doing interop in dart with union types, then I would think that it is also desriable that the analyser understand the object is an union type not just the compiler. 

The main motivation for union types is better JS interop. But, in many cases, you can get a much tighter type by using something like TypeScript's interface overloading feature than you would get using union types.

For example, say you want to call jQuery's bind() method from Dart. If all you had is union types, its type is something like:

bind(String | Map eventTypeOrEvents, [Map | Function | bool eventDataOrHandlerOrPreventBubble, bool | Function, handlerOrPreventBubble]); 

The types aren't clear. The parameter names aren't clear, and it allows a bunch of things that are not in fact valid, like passing booleans for both of the last two parameters. If you have overloading, it's:

bind(String eventType, Function handler);
bind(String eventType, Map eventData, Function handler);
bind(String eventType, [Map eventData, bool preventBubble]);
bind(Map events);

That's much clearer and more explicit.

Since the DDC folks are investigating supporting TypeScript definition files anyway, we may have to allow overloads like this. In that case, union types may not add much additional value. (Note that TypeScript has had overloading since they first launched but is only just now getting around to adding union types.)

Cheers!

- bob

Benjamin Strauß

unread,
Jun 29, 2015, 3:11:12 PM6/29/15
to mi...@dartlang.org
Am Montag, 29. Juni 2015 17:57:18 UTC+2 schrieb Bob:
Since the DDC folks are investigating supporting TypeScript definition files anyway, we may have to allow overloads like this. In that case, union types may not add much additional value. (Note that TypeScript has had overloading since they first launched but is only just now getting around to adding union types.)

I thought type based overloading was not added into Dart because that would violate the principle that types do not change the semantics?

Bob Nystrom

unread,
Jun 29, 2015, 3:55:41 PM6/29/15
to General Dart Discussion
"Overloading" is a bit misleading in the way TypeScript uses it here. You can overload the declaration of a method in its interface. You cannot overload by having multiple actual concrete definitions of the method. You have a single method whose body uses type tests to do the right thing.

Overloads are part of the optional static types, but not part of the runtime behavior.

Another way to look at it is that the one definition of the method has a single type that's a union of function types.

Cheers!

- bob

Don Olmstead

unread,
Jun 29, 2015, 4:59:39 PM6/29/15
to mi...@dartlang.org
Yea I would assume that if Dart had union types you would be able to reduce something like

void doSomething(dynamic value) {
 
if (value is String) {
   
..
 
} else if (value is List<String>) {
   
..
 
} else {
   
throw new ArgumentError('value is not a String or List of String');
 
}
}



to

void doSomething(String|List<String> value) {
 
if (value is String) {

 
} else {
   
// I'm for sure a List<String>
   
..
 
}
}


and get type checks and be able to see exactly what the function expects.

Kasper Peulen

unread,
Jun 29, 2015, 5:45:06 PM6/29/15
to mi...@dartlang.org
The example that you gave @Bob Nystorm, I'm not very experienced, but when writing wrappers for codemirror/polymer 1, I haven't seen such an hairy example once.
I do agree that union types doesn't feel right there.

+1 for that example @Don Olmstead. This kind of code I see very often when trying to make a dart wrapper for a js library, and I do think that union types would do a very good job here.
I'm always in doubt how to documentate that as well, follow the JSDoc coventions ? Maybe just say something like:
/// This method accepts only String or List<String> as input.
void doSomething(dynamic value) {

Sometimes, I choose to do something like:
/// Make sure that one and only one of the two optional arguments are specified.
void doSomething({String string, List<String> list}) {
 if (string == null && list == null) {
  throw ....
 }
}

Which feels equally dirty... 

--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Kasper

DoHyung Kim

unread,
Jun 29, 2015, 11:20:03 PM6/29/15
to mi...@dartlang.org
Dear Don,

Considering we cannot get a guarantee that doSomething always gets either String or List<String>,removing the second check for List<String> doesn't seem so safe.

Personally I find myself preferring codes like your example below, when I create kinda DSLs. Otherwise I'll create separate methods for String and List<String> in Dart. When I do DSL stuffs, I definitely miss the union type. But I'm not sure it is worth the complexity introduced by addition of union type.

2015년 6월 30일 화요일 오전 5시 59분 39초 UTC+9, Don Olmstead 님의 말:

Cristian Garcia

unread,
Jun 29, 2015, 11:53:39 PM6/29/15
to mi...@dartlang.org

You can guarantee it with the "non-nullable types by default" proposal which (given those in favor) might be implemented.


--

DoHyung Kim

unread,
Jun 29, 2015, 11:55:38 PM6/29/15
to mi...@dartlang.org
Dear Kasper,

To my understanding, the tentative position of Dart team is not to have union type in Dart language, but supports it in the context of toolings if target functions and methods are from JS. So if we are only concern about smoother JS interop, then we may see what solution Dart team will come out with.

I was with Don on union type in Dart, but now am not sure if it is worth the complexity afer following discussions here in this thread.


2015년 6월 30일 화요일 오전 6시 45분 6초 UTC+9, Kasper Peulen 님의 말:

Lasse R.H. Nielsen

unread,
Jun 30, 2015, 2:20:12 AM6/30/15
to mi...@dartlang.org
On Mon, Jun 29, 2015 at 5:56 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:

On Sun, Jun 28, 2015 at 4:38 PM, Kasper Peulen <kasper...@gmail.com> wrote:
I don't understand why this would make it less a priority. If you are doing interop in dart with union types, then I would think that it is also desriable that the analyser understand the object is an union type not just the compiler. 

The main motivation for union types is better JS interop. But, in many cases, you can get a much tighter type by using something like TypeScript's interface overloading feature than you would get using union types.

For example, say you want to call jQuery's bind() method from Dart. If all you had is union types, its type is something like:

bind(String | Map eventTypeOrEvents, [Map | Function | bool eventDataOrHandlerOrPreventBubble, bool | Function, handlerOrPreventBubble]); 

The types aren't clear. The parameter names aren't clear, and it allows a bunch of things that are not in fact valid, like passing booleans for both of the last two parameters. If you have overloading, it's:

bind(String eventType, Function handler);
bind(String eventType, Map eventData, Function handler);
bind(String eventType, [Map eventData, bool preventBubble]);
bind(Map events);

That's much clearer and more explicit.

I would like that very much. We would probably still need union types, at least in the static type system, to account for these types, but I think it will cover enough use-cases that we won't need union type syntax.

We could even express the "number operator exceptions" of the type system as:
   int operator+(int a, int b);
   double operator+(double a, num b);
   double operator+(num a, double b);

And for Future<T>.sync:
   Future.sync(T action());
   Future.sync(Future<T> action());
And Future.catchError:
   Future.catchError(errorHandler(error), [bool test(error)]);
   Future.catchError(errorHandler(error, StackTrace stack), [bool test(error)]);

 
/L
-- 
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84
Reply all
Reply to author
Forward
0 new messages