Discussion:
[dart-misc] Replacing the switch statement with a match expression for Dart 2.0?
Rasmus Eneman
2015-10-31 14:14:00 UTC
Permalink
Me and a friend started working on a DEP for pattern matching using a Rust
like match expression <https://doc.rust-lang.org/book/patterns.html>
however, as we were creating examples and translated them to actual Dart
code we saw that the big benefit is as a replacement for the
switch-statement. They can provide nice syntactic suger for multiple if
else branches, but is that enough to introduce a new concept?
However switch statements are a pretty complex concepts with fall though,
or in Darts case not which already breaks with other languages.
To re-add fall though Dart do have labels which is another concept for a
very limited use case.

Therefore I would like to raise the discussion if the switch statement
should be dropped for Dart 2.0 and instead be replaced with a Rust like
match expression.

When compared to switch statements the match expression does have a nicer
syntax which is more similar to the rest of the language (switch the only
statements where bocks starts with a colon and ends by magic),
and is simpler because there no fall though or labels (that behaviour can
easily be replaced with function calls anyway) and does not break semantics
with other popular languages.

The places were it would be a bit nicer than if/else would only come as an
additional bonus.
--
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+***@dartlang.org.
Eric Leese
2015-11-02 20:05:45 UTC
Permalink
I personally agree with this; I would love to see the goto-label inspired
syntax go away along with the confusing goto-inspired semantics (implicit
fallthrough) that have already gone. But for my tastes, Rust has not gone
far enough. Why make the syntax special at all? Why create a new way of
denoting a block, but reserve it only for one of the least used control
flow structures? Also, why change the semantics of operators like | in a
case?

My preferred syntax would be this:

match (someExpression)
case 1 {
// matches if someExpression == 1
} case 2, 3 {
// matches if someExpression == 2 or someExpression == 3
} case 2 | 3 {
// matches if someExpression == 2 | 3, that is if someExpression == 6
} case [x] {
// matches if someExpression is a list with one element, and that element
== x. (x must already be defined)
} case [var y] {
// matches any list with one element, assigns the value of that element
to y
} case [_, x, var y] {
// matches a list with three elements if the middle is equal to x,
assigns the last element to y
}

No special block syntax; it looks like an if. Potentially any expression
can be used in a case statement, though not every expression can contain a
variable declaration or an _.
Post by Rasmus Eneman
Me and a friend started working on a DEP for pattern matching using a Rust
like match expression <https://doc.rust-lang.org/book/patterns.html>
however, as we were creating examples and translated them to actual Dart
code we saw that the big benefit is as a replacement for the
switch-statement. They can provide nice syntactic suger for multiple if
else branches, but is that enough to introduce a new concept?
However switch statements are a pretty complex concepts with fall though,
or in Darts case not which already breaks with other languages.
To re-add fall though Dart do have labels which is another concept for a
very limited use case.
Therefore I would like to raise the discussion if the switch statement
should be dropped for Dart 2.0 and instead be replaced with a Rust like
match expression.
When compared to switch statements the match expression does have a nicer
syntax which is more similar to the rest of the language (switch the only
statements where blocks starts with a colon and ends by magic),
and is simpler because there no fall though or labels (that behaviour can
easily be replaced with function calls anyway) and does not break semantics
with other popular languages.
The places were it would be a bit nicer than if/else would only come as an
additional bonus.
--
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+***@dartlang.org.
'Bob Nystrom' via Dart Misc
2015-11-02 20:31:11 UTC
Permalink
Post by Rasmus Eneman
Me and a friend started working on a DEP for pattern matching using a Rust
like match expression <https://doc.rust-lang.org/book/patterns.html>
Awesome! I have a similiar proposal from a very long time ago (back before
Dart had been publicly released). I'm excited to see other people wanting
it too.
Post by Rasmus Eneman
however, as we were creating examples and translated them to actual Dart
code we saw that the big benefit is as a replacement for the
switch-statement. They can provide nice syntactic suger for multiple if
else branches, but is that enough to introduce a new concept?
To me, I think the real value is that it combines a type test and a
binding. In Dart today, it's pretty common to have code like:

if (foo.bar is SomeType) {
var bar = foo.bar as SomeType;
...
}


That redundancy drives me crazy. But as more and more people use strong
mode, users will find themselves hitting code like this more often.
Post by Rasmus Eneman
However switch statements are a pretty complex concepts with fall though,
or in Darts case not which already breaks with other languages.
Yes, the scoping for switch is weird. For a pattern-matching system that
did scoped binding, you obviously cannot allow fallthrough.
Post by Rasmus Eneman
Therefore I would like to raise the discussion if the switch statement
should be dropped for Dart 2.0 and instead be replaced with a Rust like
match expression.
Another option would be to just have both.

I'd personally be happy removing switch to make the language simpler, but
there's a lot to be said for compatibility and familiarity.

Cheers!

– bob
--
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+***@dartlang.org.
Robert Åkerblom-Andersson
2015-11-02 21:56:33 UTC
Permalink
Hi,

Speaking of the switch statement, have the team considered removing the
need for an explicit need for "break" in switches. I think removing it
could be done pretty easily (could even be implemented as a transformer
inserting "break;" statements as a first version) without breaking any or
much code.

Bob, as I understand it you have looked quite a bit on how Dart is used
internally, is there any code you can think of that relies on the "fall
through" behavior of the current switch design? I personally at least have
never wrote a single program using a switch without using break... But
maybe I am missing something useful with the fall through design? If so it
would be interesting to know how people uses it...

Removing the explicit "break" from switch statements might be small enough
that it does not break too much code, big enough that it's a feature that
could be worth doing (and simple enough to implement that it does not take
too much resources).

Example:

final x = 1;

switch(x) {
case 1: print("one");
case 2: print("two");
case 3: print("three");
default: print("anything");
}



Regards, Robert
Post by 'Bob Nystrom' via Dart Misc
Post by Rasmus Eneman
Me and a friend started working on a DEP for pattern matching using a Rust
like match expression <https://doc.rust-lang.org/book/patterns.html>
Awesome! I have a similiar proposal from a very long time ago (back before
Dart had been publicly released). I'm excited to see other people wanting
it too.
Post by Rasmus Eneman
however, as we were creating examples and translated them to actual Dart
code we saw that the big benefit is as a replacement for the
switch-statement. They can provide nice syntactic suger for multiple if
else branches, but is that enough to introduce a new concept?
To me, I think the real value is that it combines a type test and a
if (foo.bar is SomeType) {
var bar = foo.bar as SomeType;
...
}
That redundancy drives me crazy. But as more and more people use strong
mode, users will find themselves hitting code like this more often.
Post by Rasmus Eneman
However switch statements are a pretty complex concepts with fall though,
or in Darts case not which already breaks with other languages.
Yes, the scoping for switch is weird. For a pattern-matching system that
did scoped binding, you obviously cannot allow fallthrough.
Post by Rasmus Eneman
Therefore I would like to raise the discussion if the switch statement
should be dropped for Dart 2.0 and instead be replaced with a Rust like
match expression.
Another option would be to just have both.
I'd personally be happy removing switch to make the language simpler, but
there's a lot to be said for compatibility and familiarity.
Cheers!
– bob
--
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+***@dartlang.org.
tatumizer-v0.2
2015-11-03 00:52:58 UTC
Permalink
Switch is used in parsers where fall-through is common:
switch (c) {
case CR:
case LF:
case SPACE:
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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+***@dartlang.org.
Jan Mostert
2015-11-03 05:42:27 UTC
Permalink
It'd be nice to have an optional paramater in a switch to prevent
fallthrough:

switch (c, noFallThrough: true){
case CR:
// do something
case LF:
continue; // instead of break, now use continue to trigger fallthrough
case SPACE:
// do something else
default:
// throw exception
}

I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.

Would it hurt having both switch and match?
Or maybe allowing an optional param inside a switch that will allow a
switch to operate like match ?

switch (c, noFallThrough: true, regex: true){
case "[0-9]+":
// do something
case "[A-Z]+":
// do something else
default:
// meh
}
Post by tatumizer-v0.2
switch (c) {
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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
--
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+***@dartlang.org.
Jan Mostert
2015-11-03 05:45:47 UTC
Permalink
Or even cleaner, to use regex inside switch:

switch(match(c), noFallThrough: true){

}
Post by Jan Mostert
It'd be nice to have an optional paramater in a switch to prevent
switch (c, noFallThrough: true){
// do something
continue; // instead of break, now use continue to trigger fallthrough
// do something else
// throw exception
}
I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.
Would it hurt having both switch and match?
Or maybe allowing an optional param inside a switch that will allow a
switch to operate like match ?
switch (c, noFallThrough: true, regex: true){
// do something
// do something else
// meh
}
Post by tatumizer-v0.2
switch (c) {
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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
--
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+***@dartlang.org.
Jan Mostert
2015-11-03 06:01:34 UTC
Permalink
The above syntax will also allow more advance usages of switch:

switch(not match(c), noFallThrough: true){

or

switch(!match(c), noFallThrough: true){

switch(is(c), noFallThrough: true){
case String:
case bool:
case int:
default:
}

or not is:

switch(!is(c), noFallThrough: true){
Post by Jan Mostert
switch(match(c), noFallThrough: true){
}
Post by Jan Mostert
It'd be nice to have an optional paramater in a switch to prevent
switch (c, noFallThrough: true){
// do something
continue; // instead of break, now use continue to trigger fallthrough
// do something else
// throw exception
}
I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.
Would it hurt having both switch and match?
Or maybe allowing an optional param inside a switch that will allow a
switch to operate like match ?
switch (c, noFallThrough: true, regex: true){
// do something
// do something else
// meh
}
Post by tatumizer-v0.2
switch (c) {
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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
--
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+***@dartlang.org.
Jan Mostert
2015-11-03 06:14:15 UTC
Permalink
How about taking it one step further and allowing matching all case lines
at once using async and then executing the first matching block to complete
in order from top to bottom:

switch(match(c), noFallThrough:true) async {
case retreiveA():

case retreiveB():

case retreiveC():

default:

}

Retreive A / B / C returns Future<String>, all are executed at the same
time, once A is complete, try and match the result with the regular
expression c, if it doesn't match, wait for B, then wait for C etc.

Without the async keyword, it would do them one-by-one from top-to-bottom.
with async it executes all of them at the same time, but waits from top to
bottom.

There's plenty of reason to keep the switch statement and just wrap the
paramater that usually goes into switch with something to indicate a
different type of switch.
Post by Jan Mostert
switch(not match(c), noFallThrough: true){
or
switch(!match(c), noFallThrough: true){
switch(is(c), noFallThrough: true){
}
switch(!is(c), noFallThrough: true){
Post by Jan Mostert
switch(match(c), noFallThrough: true){
}
Post by Jan Mostert
It'd be nice to have an optional paramater in a switch to prevent
switch (c, noFallThrough: true){
// do something
continue; // instead of break, now use continue to trigger fallthrough
// do something else
// throw exception
}
I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.
Would it hurt having both switch and match?
Or maybe allowing an optional param inside a switch that will allow a
switch to operate like match ?
switch (c, noFallThrough: true, regex: true){
// do something
// do something else
// meh
}
Post by tatumizer-v0.2
switch (c) {
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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
--
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+***@dartlang.org.
'Erik Ernst' via Dart Misc
2015-11-03 09:43:22 UTC
Permalink
I think there is a tension between two different goals here: A
simpleminded, low-level `switch` construct allows for compilation to code
that runs fast (e.g., a single table lookup based on a set of simple values
"sufficiently similar to the natural numbers up to N"), and it allows for
non-structured control flow ("goto"). This is the C-ish version of `switch`.

A more general `switch` construct could be defined as syntactic sugar on
top of other constructs, e.g., a chain of `if`s (surely we could invent a
definition that would allow for general expression evaluation for the
value tested in each `case`, we could allow for `async`, etc.). A good
example of a pretty general mechanism in this area is Scala pattern
matching, for instance, `x match { case 1 => "one"; case y: Int => "not
one"; case _ => "not a number" }`. This allows for invocation: the `{ case
.. }` construct is a function literal that matches several different cases
based on value comparison, type tests, or `unapply` based pattern matching,
which is completely user-defined.

I tend to think that it is better to have the ability to express the
general constructs in the language already available, rather than setting
out to do some fine-grained tailoring on specific control structures.

So maybe the really nice thing to have would be a construct that works a
bit like the Scala pattern matching function literals? Setting out from a
`Map` literal (which already handles the cases where `==` is all we need),
it just needs to support extra tests (like `is int`, or `(x) => x % 2 ==
0`, or `unapply`). Those functions would then support a variety of
generalized `switch` constructs (even though we may need to put the
scrutinee after the list of cases unless we also add a bit of syntactic
sugar for pipeline style function invocation, like "->" in BETA or "|>" in
F#). In that case it might be a reasonable trade-off to keep the built-in
`switch` simple, or to eliminate it from the language entirely.
Post by Jan Mostert
How about taking it one step further and allowing matching all case lines
at once using async and then executing the first matching block to complete
switch(match(c), noFallThrough:true) async {
}
Retreive A / B / C returns Future<String>, all are executed at the same
time, once A is complete, try and match the result with the regular
expression c, if it doesn't match, wait for B, then wait for C etc.
Without the async keyword, it would do them one-by-one from top-to-bottom.
with async it executes all of them at the same time, but waits from top to
bottom.
There's plenty of reason to keep the switch statement and just wrap the
paramater that usually goes into switch with something to indicate a
different type of switch.
Post by Jan Mostert
switch(not match(c), noFallThrough: true){
or
switch(!match(c), noFallThrough: true){
switch(is(c), noFallThrough: true){
}
switch(!is(c), noFallThrough: true){
Post by Jan Mostert
switch(match(c), noFallThrough: true){
}
Post by Jan Mostert
It'd be nice to have an optional paramater in a switch to prevent
switch (c, noFallThrough: true){
// do something
continue; // instead of break, now use continue to trigger fallthrough
// do something else
// throw exception
}
I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.
Would it hurt having both switch and match?
Or maybe allowing an optional param inside a switch that will allow a
switch to operate like match ?
switch (c, noFallThrough: true, regex: true){
// do something
// do something else
// meh
}
Post by tatumizer-v0.2
switch (c) {
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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
--
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
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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+***@dartlang.org.
Jan Mostert
2015-11-03 09:56:04 UTC
Permalink
Wouldn't it be possible to decide on compile time whether that
switch-statement is a simple low-level switch or a switch on steroids?
The type information should be enough to determine whether we're looking at
a simple enum / integer type switch or a more complicated switch that needs
to be converted to if-else statements. If no type information is available,
falling back to if-else doesn't sound to bad - for better performing switch
statements, you'd want the type information present.

Sounds much better re-using switch than introducing a new control structure
to evaluate a new "type of switch".
Now if we want a switch-like structure for something other than regex (for
which match was suggested), we'd need to invent a new control structure.

I'm not familiar with the way Scala does it, will do a bit of reading,
sounds interesting.
Post by 'Erik Ernst' via Dart Misc
I think there is a tension between two different goals here: A
simpleminded, low-level `switch` construct allows for compilation to code
that runs fast (e.g., a single table lookup based on a set of simple values
"sufficiently similar to the natural numbers up to N"), and it allows for
non-structured control flow ("goto"). This is the C-ish version of `switch`.
A more general `switch` construct could be defined as syntactic sugar on
top of other constructs, e.g., a chain of `if`s (surely we could invent a
definition that would allow for general expression evaluation for the
value tested in each `case`, we could allow for `async`, etc.). A good
example of a pretty general mechanism in this area is Scala pattern
matching, for instance, `x match { case 1 => "one"; case y: Int => "not
one"; case _ => "not a number" }`. This allows for invocation: the `{ case
.. }` construct is a function literal that matches several different cases
based on value comparison, type tests, or `unapply` based pattern matching,
which is completely user-defined.
I tend to think that it is better to have the ability to express the
general constructs in the language already available, rather than setting
out to do some fine-grained tailoring on specific control structures.
So maybe the really nice thing to have would be a construct that works a
bit like the Scala pattern matching function literals? Setting out from a
`Map` literal (which already handles the cases where `==` is all we need),
it just needs to support extra tests (like `is int`, or `(x) => x % 2 ==
0`, or `unapply`). Those functions would then support a variety of
generalized `switch` constructs (even though we may need to put the
scrutinee after the list of cases unless we also add a bit of syntactic
sugar for pipeline style function invocation, like "->" in BETA or "|>" in
F#). In that case it might be a reasonable trade-off to keep the built-in
`switch` simple, or to eliminate it from the language entirely.
Post by Jan Mostert
How about taking it one step further and allowing matching all case lines
at once using async and then executing the first matching block to complete
switch(match(c), noFallThrough:true) async {
}
Retreive A / B / C returns Future<String>, all are executed at the same
time, once A is complete, try and match the result with the regular
expression c, if it doesn't match, wait for B, then wait for C etc.
Without the async keyword, it would do them one-by-one from
top-to-bottom. with async it executes all of them at the same time, but
waits from top to bottom.
There's plenty of reason to keep the switch statement and just wrap the
paramater that usually goes into switch with something to indicate a
different type of switch.
Post by Jan Mostert
switch(not match(c), noFallThrough: true){
or
switch(!match(c), noFallThrough: true){
switch(is(c), noFallThrough: true){
}
switch(!is(c), noFallThrough: true){
Post by Jan Mostert
switch(match(c), noFallThrough: true){
}
Post by Jan Mostert
It'd be nice to have an optional paramater in a switch to prevent
switch (c, noFallThrough: true){
// do something
continue; // instead of break, now use continue to trigger fallthrough
// do something else
// throw exception
}
I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.
Would it hurt having both switch and match?
Or maybe allowing an optional param inside a switch that will allow a
switch to operate like match ?
switch (c, noFallThrough: true, regex: true){
// do something
// do something else
// meh
}
Post by tatumizer-v0.2
switch (c) {
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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,
--
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
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
--
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+***@dartlang.org.
Jan Mostert
2015-11-03 10:07:43 UTC
Permalink
This Scala syntax does look useful for inlinining switches:

Scala:

val x = (i: @switch) match {
case 1 => "One"
case Two => "Two" // replaced the '2'
case _ => "Other"
} Dart equivalent could be
String c = ... String s = switch(match(c), noFallThrough:true){
case "[0-9]+": "Number";
case "[A-Za-z]+": "Word";
default: "Unknown";

} or // equals(c) or just c since equals is implied: String c = ...
String s = switch(equals(c), noFallThrough:true){
case "1": "One";
case "2": "Two";
...
default: "Unknown";
} or var c = ...
String s = switch(is(c), noFallThrough:true){
case int: "Integer";
case bool: "Boolean";
...
default: "Unknown";
}


In this scenario we added an int type, so the switch can act like a "normal
low-level" switch.
int c = ...
String s = switch(c, noFallThrough:true){
case 1: "One";
case 2: "Two";
...
default: "Unknown";
}
Post by Jan Mostert
Wouldn't it be possible to decide on compile time whether that
switch-statement is a simple low-level switch or a switch on steroids?
The type information should be enough to determine whether we're looking
at a simple enum / integer type switch or a more complicated switch that
needs to be converted to if-else statements. If no type information is
available, falling back to if-else doesn't sound to bad - for better
performing switch statements, you'd want the type information present.
Sounds much better re-using switch than introducing a new control
structure to evaluate a new "type of switch".
Now if we want a switch-like structure for something other than regex (for
which match was suggested), we'd need to invent a new control structure.
I'm not familiar with the way Scala does it, will do a bit of reading,
sounds interesting.
Post by 'Erik Ernst' via Dart Misc
I think there is a tension between two different goals here: A
simpleminded, low-level `switch` construct allows for compilation to code
that runs fast (e.g., a single table lookup based on a set of simple values
"sufficiently similar to the natural numbers up to N"), and it allows for
non-structured control flow ("goto"). This is the C-ish version of `switch`.
A more general `switch` construct could be defined as syntactic sugar on
top of other constructs, e.g., a chain of `if`s (surely we could invent a
definition that would allow for general expression evaluation for the
value tested in each `case`, we could allow for `async`, etc.). A good
example of a pretty general mechanism in this area is Scala pattern
matching, for instance, `x match { case 1 => "one"; case y: Int => "not
one"; case _ => "not a number" }`. This allows for invocation: the `{ case
.. }` construct is a function literal that matches several different cases
based on value comparison, type tests, or `unapply` based pattern matching,
which is completely user-defined.
I tend to think that it is better to have the ability to express the
general constructs in the language already available, rather than setting
out to do some fine-grained tailoring on specific control structures.
So maybe the really nice thing to have would be a construct that works a
bit like the Scala pattern matching function literals? Setting out from a
`Map` literal (which already handles the cases where `==` is all we need),
it just needs to support extra tests (like `is int`, or `(x) => x % 2 ==
0`, or `unapply`). Those functions would then support a variety of
generalized `switch` constructs (even though we may need to put the
scrutinee after the list of cases unless we also add a bit of syntactic
sugar for pipeline style function invocation, like "->" in BETA or "|>" in
F#). In that case it might be a reasonable trade-off to keep the built-in
`switch` simple, or to eliminate it from the language entirely.
Post by Jan Mostert
How about taking it one step further and allowing matching all case
lines at once using async and then executing the first matching block to
switch(match(c), noFallThrough:true) async {
}
Retreive A / B / C returns Future<String>, all are executed at the same
time, once A is complete, try and match the result with the regular
expression c, if it doesn't match, wait for B, then wait for C etc.
Without the async keyword, it would do them one-by-one from
top-to-bottom. with async it executes all of them at the same time, but
waits from top to bottom.
There's plenty of reason to keep the switch statement and just wrap the
paramater that usually goes into switch with something to indicate a
different type of switch.
Post by Jan Mostert
switch(not match(c), noFallThrough: true){
or
switch(!match(c), noFallThrough: true){
switch(is(c), noFallThrough: true){
}
switch(!is(c), noFallThrough: true){
Post by Jan Mostert
switch(match(c), noFallThrough: true){
}
Post by Jan Mostert
It'd be nice to have an optional paramater in a switch to prevent
switch (c, noFallThrough: true){
// do something
continue; // instead of break, now use continue to trigger fallthrough
// do something else
// throw exception
}
I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.
Would it hurt having both switch and match?
Or maybe allowing an optional param inside a switch that will allow a
switch to operate like match ?
switch (c, noFallThrough: true, regex: true){
// do something
// do something else
// meh
}
Post by tatumizer-v0.2
switch (c) {
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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,
--
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
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
--
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+***@dartlang.org.
Joel Trottier-Hébert
2015-11-03 12:31:29 UTC
Permalink
I don't give my output often on these DEP proposals. But my vote would go
to a F# like (or Ocaml, Scala, whatever) pattern matching mechanism. It is
just so powerful, gives possibility to have very readable code.

Yet I don't know if the current way things are implemented in Dart would
allow doing this.

Thanks!
Post by Jan Mostert
case 1 => "One"
case Two => "Two" // replaced the '2'
case _ => "Other"
} Dart equivalent could be
String c = ... String s = switch(match(c), noFallThrough:true){
case "[0-9]+": "Number";
case "[A-Za-z]+": "Word";
default: "Unknown";
} or // equals(c) or just c since equals is implied: String c = ...
String s = switch(equals(c), noFallThrough:true){
case "1": "One";
case "2": "Two";
...
default: "Unknown";
} or var c = ...
String s = switch(is(c), noFallThrough:true){
case int: "Integer";
case bool: "Boolean";
...
default: "Unknown";
}
In this scenario we added an int type, so the switch can act like a
"normal low-level" switch.
int c = ...
String s = switch(c, noFallThrough:true){
case 1: "One";
case 2: "Two";
...
default: "Unknown";
}
Post by Jan Mostert
Wouldn't it be possible to decide on compile time whether that
switch-statement is a simple low-level switch or a switch on steroids?
The type information should be enough to determine whether we're looking
at a simple enum / integer type switch or a more complicated switch that
needs to be converted to if-else statements. If no type information is
available, falling back to if-else doesn't sound to bad - for better
performing switch statements, you'd want the type information present.
Sounds much better re-using switch than introducing a new control
structure to evaluate a new "type of switch".
Now if we want a switch-like structure for something other than regex
(for which match was suggested), we'd need to invent a new control
structure.
I'm not familiar with the way Scala does it, will do a bit of reading,
sounds interesting.
Post by 'Erik Ernst' via Dart Misc
I think there is a tension between two different goals here: A
simpleminded, low-level `switch` construct allows for compilation to code
that runs fast (e.g., a single table lookup based on a set of simple values
"sufficiently similar to the natural numbers up to N"), and it allows for
non-structured control flow ("goto"). This is the C-ish version of `switch`.
A more general `switch` construct could be defined as syntactic sugar on
top of other constructs, e.g., a chain of `if`s (surely we could invent a
definition that would allow for general expression evaluation for the
value tested in each `case`, we could allow for `async`, etc.). A good
example of a pretty general mechanism in this area is Scala pattern
matching, for instance, `x match { case 1 => "one"; case y: Int => "not
one"; case _ => "not a number" }`. This allows for invocation: the `{ case
.. }` construct is a function literal that matches several different cases
based on value comparison, type tests, or `unapply` based pattern matching,
which is completely user-defined.
I tend to think that it is better to have the ability to express the
general constructs in the language already available, rather than setting
out to do some fine-grained tailoring on specific control structures.
So maybe the really nice thing to have would be a construct that works a
bit like the Scala pattern matching function literals? Setting out from a
`Map` literal (which already handles the cases where `==` is all we need),
it just needs to support extra tests (like `is int`, or `(x) => x % 2 ==
0`, or `unapply`). Those functions would then support a variety of
generalized `switch` constructs (even though we may need to put the
scrutinee after the list of cases unless we also add a bit of syntactic
sugar for pipeline style function invocation, like "->" in BETA or "|>" in
F#). In that case it might be a reasonable trade-off to keep the built-in
`switch` simple, or to eliminate it from the language entirely.
Post by Jan Mostert
How about taking it one step further and allowing matching all case
lines at once using async and then executing the first matching block to
switch(match(c), noFallThrough:true) async {
}
Retreive A / B / C returns Future<String>, all are executed at the same
time, once A is complete, try and match the result with the regular
expression c, if it doesn't match, wait for B, then wait for C etc.
Without the async keyword, it would do them one-by-one from
top-to-bottom. with async it executes all of them at the same time, but
waits from top to bottom.
There's plenty of reason to keep the switch statement and just wrap the
paramater that usually goes into switch with something to indicate a
different type of switch.
Post by Jan Mostert
switch(not match(c), noFallThrough: true){
or
switch(!match(c), noFallThrough: true){
switch(is(c), noFallThrough: true){
}
switch(!is(c), noFallThrough: true){
Post by Jan Mostert
switch(match(c), noFallThrough: true){
}
Post by Jan Mostert
It'd be nice to have an optional paramater in a switch to prevent
switch (c, noFallThrough: true){
// do something
continue; // instead of break, now use continue to trigger fallthrough
// do something else
// throw exception
}
I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.
Would it hurt having both switch and match?
Or maybe allowing an optional param inside a switch that will allow
a switch to operate like match ?
switch (c, noFallThrough: true, regex: true){
// do something
// do something else
// meh
}
Post by tatumizer-v0.2
switch (c) {
// handle whitespace
...
}
Dart doesn't have any other syntax for multiple cases.
--
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,
--
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
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
--
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
--
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+***@dartlang.org.
kc
2015-11-03 15:35:59 UTC
Permalink
Post by Joel Trottier-Hébert
I don't give my output often on these DEP proposals. But my vote would go
to a F# like (or Ocaml, Scala, whatever) pattern matching mechanism. It is
just so powerful, gives possibility to have very readable code.
Yet I don't know if the current way things are implemented in Dart would
allow doing this.
A question was raised re pattern matching at the Dart Summit:



K.
--
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+***@dartlang.org.
Joel Trottier-Hébert
2015-11-03 15:48:31 UTC
Permalink
Yeah I've seen that. I've also opened an issue for the SDK more than a year
ago, and they closed it so ... :P
Post by kc
Post by Joel Trottier-Hébert
I don't give my output often on these DEP proposals. But my vote would go
to a F# like (or Ocaml, Scala, whatever) pattern matching mechanism. It is
just so powerful, gives possibility to have very readable code.
Yet I don't know if the current way things are implemented in Dart would
allow doing this.
http://youtu.be/hYt9lhMie-o
K.
--
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
--
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+***@dartlang.org.
Rasmus Eneman
2015-11-03 19:53:42 UTC
Permalink
I maybe should have created two different threads, one for pattern matching
and another one for replacing the switch statement :)
While I would like it removed as said, introducing pattern matching as well
would be great by itself.

One thing we are debating is every kind of pattern should be specified on a
syntactical level or if it should handle expressions producing objects
which can implement a method to handle matching.

The expression route is pretty interesting, say if we added a
hasMatch(other) method to Object that the match expression calls to check
if the current pattern matches, implemented as other == this. Then we have
support for matching simple values. RegExp already overrides hasMatch which
means that we also have support for matching against regexes. It can be
expanded by libraries with ranges and other stuff. To support type tests or
comparisons bool could override hasMatch as other is bool ? other == this :
other and we could have patterns like x is num or x < 10.
What's tricky in this route is declaration, as we use the scope variables
can't just be declared to the value we are matching. This could be solved
by variables being declared with var but that start to become pretty
different from other languages with pattern matching. Another problem is
destructuring of lists, if we use brackets justs like list literals (and
like array destructuring in ES2015) we would have a hard time
distinguishing them from list literals.

The other route would be much closer to languages like Scala and Rust and
we wouldn't need to invent a lot of solutions, just specify what kind of
patterns we want to allow.
The values checks would probably be covered with nullLiteral,
numericLiteral, booleanLiteral, stringLiteral, symbolLiteral
And then we probably want typeTest and identifier (for a catch all state, _
is a normal parameter in rest of Dart so why stop now...).
List destructuring is pretty important, to handle matching on multiple
values on the same time.
Object destructuring would be cool, and maybe comparison operators and
ranges?

Some way to define alternative patterns is also needed. I like the pipe
because it's used in other patterns like regex but as said it can be
confused with a boolean or...
Post by Joel Trottier-Hébert
Yeah I've seen that. I've also opened an issue for the SDK more than a
year ago, and they closed it so ... :P
Post by kc
Post by Joel Trottier-Hébert
I don't give my output often on these DEP proposals. But my vote would
go to a F# like (or Ocaml, Scala, whatever) pattern matching mechanism. It
is just so powerful, gives possibility to have very readable code.
Yet I don't know if the current way things are implemented in Dart would
allow doing this.
http://youtu.be/hYt9lhMie-o
K.
--
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
--
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
--
Rasmus Eneman
--
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+***@dartlang.org.
'Erik Ernst' via Dart Misc
2015-11-16 13:41:50 UTC
Permalink
It's interesting. It's only destructuring of lists and maps, not custom
values, but I do like the "rest" pattern (and we should have
rest-parameters on functions too!).
It's actually lists and objects. Maps could be added as well but I don't
know if you use Maps in this way in Dart?
And I would love rest-parameters :)
The [a, a] pattern needs to be specified clearly. That is, something
like: "if the same identifier binding occurs multiple times in the same
pattern, it corresponds to an extra condition that all the values matched
by these identifier patterns are equal". Or identical?
Oh, yeah. That's a big omission. The current idea is equality, like if you
had specified a literal.
Interesting! The [a, a] patterns and other features that introduce
equality constraints are somewhat tricky, though: If you can say 'match (x)
{ a as List { next: a } => .. }' then the pattern >matcher is required to
check that the whole list is identical to its tail (i.e, sublist(1)). This
is true for a cyclic list, so you cannot just compile that down to "don't
ever choose this case", but you >have to be careful in order to know that
you're done, and that's a lot of algorithmic magic to expect from your
compiler and/or runtime system. ;-)
With the current idea that would transpile to (if we say that a is in
scope)
if (a is List && a.next == a)
personally I don't think you should have something similar to (head, tail)
of functional languages where head is the first element and tail is the
rest of the list on a syntactical plane. Instead I would prefer adding a
"tail" getter to List.
Ah, my intention was simply to illustrate what happens if we use patterns
that imply equality constraints (you just confirmed that it was intended to
mean equality, that is `==` and not `identical`), if they are combined with
recursion in types.

So I should not have used `List` as the example, because a Dart list
actually has a different structure. A suitable definition would be
something very basic like `class MyList { MyList next; .. }`, where we use
recursion in the type (i.e., `MyList` contains a field of type `MyList`).
Equality would be defined structurally on the list (and it would use
whatever `operator ==` does on the elements because it has no choice, but
it doesn't matter for this argument whether the equality on elements is
structural or identity-based).

With that setup, a pattern like `match (x) { a as MyList { next: a } => ..
}` would correspond to the criterion "succeed if `a` is a `MyList` which is
equal to its tail", and then the rest of my explanations would remain
unchanged. (That is, with a finite heap only a cyclic `MyList` could ever
satisfy that criterion, but it's questionable whether a language mechanism
should be required to include enough algorithmic smarts to be able to
handle such a situation gracefully).

In summary, my message was something like "equality constraints may be too
expensive for a language mechanism, so we probably don't want that". ;)
In most languages calling symbol twice with same value returns the exact
same instance of symbol. If this is not true in dart it needs to be fixed.
Syntax looks awesome, especially Object and List matching!
On Fri, 13 Nov 2015 at 17:50 'Erik Ernst' via Dart Misc <
Interesting! The [a, a] patterns and other features that introduce
equality constraints are somewhat tricky, though: If you can say 'match (x)
{ a as List { next: a } => .. }' then the pattern matcher is required to
check that the whole list is identical to its tail (i.e, sublist(1)). This
is true for a cyclic list, so you cannot just compile that down to "don't
ever choose this case", but you have to be careful in order to know that
you're done, and that's a lot of algorithmic magic to expect from your
compiler and/or runtime system. ;-)
On Fri, Nov 13, 2015 at 4:16 PM, 'Lasse R.H. Nielsen' via Dart Misc <
While it's not ready for submitting to the committee yet we thought
that we should post our current draft of the DEP as it might be interesting
for the discussion
https://github.com/drager/dep-pattern-matching/blob/master/proposal.md
It's interesting. It's only destructuring of lists and maps, not
custom values, but I do like the "rest" pattern (and we should have
rest-parameters on functions too!).
The [a, a] pattern needs to be specified clearly. That is, something
like: "if the same identifier binding occurs multiple times in the same
pattern, it corresponds to an extra condition that all the values matched
by these identifier patterns are equal". Or identical?
Pattern matching usually occurs in functional languages where values
are immutable, so equal and identical is the same thing. In Dart, you can
have equal objects that are not identical, so would the pattern [a, a]
match [new Symbol("a"), new Symbol("a")].
It probably needs to be "equals" because that's what you will expect
for string values, and then you need to specify which of the equal values
is bound to "a".
For type tests, I have been thinking in terms of type annotations -
which would be slightly misleading until we get non-null-by-default types.
That is, instead of [x is int, y is int], the pattern would be [int x, int
y].
That makes it possible to see a normal variable declaration "int x =
42;" as a pattern matched with a value, and we could consider generalizing
it to [var x, var y] = [2, 4].
/L
On Fri, Nov 13, 2015 at 12:37 PM, 'Erik Ernst' via Dart Misc <
I don't think we have to consider this to be a mechanism for
generating bindings at runtime, it could as well be syntactic sugar for a
rewriting of the patterns into something that calls some methods and uses
`if` or similar constructs to choose the right piece of code to execute,
and sprinkles some normal local variable declarations in the code (final,
presumably, initialized with the relevant sub-object-extraction
invocations), such that the body of each case can use the names used in the
pattern. It takes some collaboration from the compiler to be able to
distinguish a fresh name (which is "declared" by the pattern) and an
existing name (which would be a constraint: "if your subobject at this
location is `==` to the value of this name, proceed"), but it would mostly
be a syntactic rewrite.
On Fri, Nov 13, 2015 at 12:25 PM, 'Lasse R.H. Nielsen' via Dart Misc
Function.apply.
So: https://dartpad.dartlang.org/84e60be831465ae49f79
It still requires parameters to be named. Converting the bindings
to positions is possible, but probably confusing and error prone. The
alternative would be to have a way to specify an index for the matcher
binding.
/L
On Fri, Nov 13, 2015 at 11:53 AM, 'Erik Ernst' via Dart Misc <
Cool, Lasse! And, Paul: Yes, I had actual language bindings in
mind. But the example gets close to showing how it would work, using a
`Map<Symbol, dynamic>` to represent the binding environment and a `List`
(with a fixed order and number of elements) to represent the scrutinee's
fields. Now we just need something similar for real! ;-)
On Fri, Nov 13, 2015 at 11:28 AM, 'Paul Brauner' via Dart Misc <
That's what I meant by "having match be the minimum syntactic
sugar for making first-class patterns (patterns as values) user friendly".
You need language support for introducing real bindings.
On Fri, Nov 13, 2015 at 11:25 AM 'Lasse R.H. Nielsen' via Dart
Much of what you are describing here can be done in code,
without language changes.
You want a way to add a user-defined match, deconstruct and bind
operation for new classes, so you might as well do that for all classes,
and not require language support for some of them.
(Although language support does make the code look more crisp :).
https://dartpad.dartlang.org/e26063664104cd4a5e92
/L
On Fri, Nov 13, 2015 at 10:22 AM, 'Erik Ernst' via Dart Misc <
+1 for smart pattern matching! ;-)
I think it makes sense to allow a pattern matching mechanism to
be expressive, and at the same time tolerate that it may not be as fast as
the traditional low-level switch statement (each of them may be the best
choice, depending on the situation). Presumably, this means that any given
pattern corresponds to a decision tree: For any given scrutinee object the
decision ("does it or does it not match this pattern?") will be taken by
traversing this tree, invoking methods on the scrutinee at each node; each
test may bind a name to the current scrutinee, and each step from a node to
the next one will potentially obtain a "subobject" from the current
scrutinee which will then be the next scrutinee in that subtree. All these
actions will be carried out using standard method invocation, so any object
that satisfies the protocol can be scrutinized. It's entirely up to the
scrutinee to decide whether it wants to deliver "an actual subobject"
(maybe that means the value of a field with the name that we are matching
against) or some other object when stepping into a subtree, but some
syntactic sugar would be nice in order to make "something obvious" an
easily achievable default.
On Fri, Nov 13, 2015 at 9:24 AM, 'Paul Brauner' via Dart Misc <
On Wed, Nov 11, 2015 at 8:39 PM 'Justin Fagnani' via Dart Misc
On Wed, Nov 11, 2015 at 10:20 AM, 'Paul Brauner' via Dart
Whatever syntax/semantics we choose, I wish it was based on
some view mechanism
<http://homepages.inf.ed.ac.uk/wadler/papers/view/view.ps> like
in Scala and F# (or Haskell with extensions) which is allows to foreserving
abstractions. That is, you don't have to know the concrete type of some
object in order to match against it.
Why would you have to know the concrete type? I would assume
that pattern matching would work against interfaces. If that's true, then
Views as described look a bit like interface injection + default methods or
extension methods.
I don't know why you would *have to* know the concrete type,
but in many languages who historically implemented pattern matching it is
the case. (In SML for instance, patterns of the form x::xs only match
things of type 'a list, where list is a concrete type). I'm just saying
that we need some mechanism that allows objects to answer "pattern matching
requests". User-defined destructuring as Bob puts it later in the thread.
Then will in particular be able to match against interfaces. Against any
object really.
Also it'd be nice to consider having match be the minimum
syntactic sugar for making first-class patterns (patterns as values) user
friendly, like in this newspeak paper
<http://www.hpi.uni-potsdam.de/hirschfeld/publications/media/GellerHirschfeldBracha_2010_PatternMatchingForAnObjectOrientedAndDynamicallyTypedProgrammingLanguage_HPI36.pdf>
.
Paul
On Tuesday, November 3, 2015 at 3:48:44 PM UTC, Joel
Post by Joel Trottier-Hébert
Yeah I've seen that. I've also opened an issue for the SDK
more than a year ago, and they closed it so ... :P
Lars Bak is half-right and half-wrong.
Right - simple semantics are good. No magic or weird
deopts/insecurity.
Wrong - expressiveness (without boilderplate) is important.
A switch with weird/tricky limitations from 1972 seems wrong when compared
with what other (lower level!) langs are offering.
K.
--
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
--
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
---
You received this message because you are subscribed to the
Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails
--
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
---
You received this message because you are subscribed to the
Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from
--
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
---
You received this message because you are subscribed to the
Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the
Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from
--
'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
--
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
---
You received this message because you are subscribed to the
Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from
--
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
---
You received this message because you are subscribed to the
Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
--
'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
--
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
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to a topic in
the Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it,
--
'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
--
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
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
--
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
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
--
Daniel Joyce
The meek shall inherit the Earth, for the brave will be among the stars.
--
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
---
You received this message because you are subscribed to a topic in the
Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
'Bob Nystrom' via Dart Misc
2015-11-18 17:07:16 UTC
Permalink
On Mon, Nov 16, 2015 at 5:54 AM, 'Paul Brauner' via Dart Misc <
I agree, non-linear patterns are a gadget in my opinion. They are
superseded by guards, which don't force you to bake one particular notion
of equality into the semantics of the language.
+1.

The simplest, safest option is to have it be a syntax error for a variable
to appear twice in the same pattern. I don't think allowing repetition
there adds much value (like Paul says, you can always just guard on
equality) and I think it adds a lot of complexity.

It also makes patterns work less like variable declarations, which I think
is generally a bad idea. Variable declarations basically *are* patterns (or
a special subset of them) so I think we should encourage them to converge
as much as possible.

Cheers!

– bob
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
Rasmus Eneman
2015-11-22 13:11:17 UTC
Permalink
I updated it now to be a syntax error, as you said it's simple to do
anyway, no need to complicate the spec or expectations on behavior.
One pattern I'm still unsure about though is Point {x, y: x} where the
second x is clearly not being declared, should that be allowed?
It's still easy to do with a guard but it might be expected that it would
be allow because that difference of literal and variable is never done
anywhere else in the language.

One other thing is p as Point {x, y} which you have used as a pattern
above. As currently written it is not allowed, but could be easily added.
I have no opinion on either but I think that it might be unnecessary as in
most cases you would have the object being matched in a variable
that is in scope anyway.

I also added initial wording on warnings. There probably should be more but
it's a start at least.

I think Scalas extractor objects needs to be mentioned. Personally I don't
see much of a value with them when there are object destructuring
but there are probably other opinions out there. But all classes that would
use them should be able to add getters for those values instead.

For example Some/None could be used like:
match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}

On Wed, Nov 18, 2015 at 6:07 PM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
On Mon, Nov 16, 2015 at 5:54 AM, 'Paul Brauner' via Dart Misc <
I agree, non-linear patterns are a gadget in my opinion. They are
superseded by guards, which don't force you to bake one particular notion
of equality into the semantics of the language.
+1.
The simplest, safest option is to have it be a syntax error for a variable
to appear twice in the same pattern. I don't think allowing repetition
there adds much value (like Paul says, you can always just guard on
equality) and I think it adds a lot of complexity.
It also makes patterns work less like variable declarations, which I think
is generally a bad idea. Variable declarations basically *are* patterns
(or a special subset of them) so I think we should encourage them to
converge as much as possible.
Cheers!
– bob
--
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
---
You received this message because you are subscribed to a topic in the
Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
Rasmus Eneman
2015-11-22 20:32:56 UTC
Permalink
I just realized that it may be hard to get static warnings for exhaustion
to work as intended with

match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}

if the static type of x is Option and we have the type hierarchy

abstract class Option<T> {}
class Some<T> extends Option<T> {}
class None extends Option {}

Then the only way for the analyzer to realize that the above expression
fully exhausts x is to know all subclasses of Option.
If Dart had type aliases and union types it could have been defined as

type Option<T> = Some<T> | None;
class Some<T> {}
class None {}

But the only options I see now is
1. Issue a warning which forces people to add a default case that is never
reached, or use the default case for None which
would make it harder to understand the intent.
2. Don't issue warnings at all
3. Don't issue warnings for other cases than when the static type of x is
an enumerable.

What I'm leaning towards is option 3 and add warnings for everything else
if Dart ever gets union types and the above
case becomes possible for the analyzer to understand without knowing all
subclasses of a class.
Post by Rasmus Eneman
I updated it now to be a syntax error, as you said it's simple to do
anyway, no need to complicate the spec or expectations on behavior.
One pattern I'm still unsure about though is Point {x, y: x} where the
second x is clearly not being declared, should that be allowed?
It's still easy to do with a guard but it might be expected that it would
be allow because that difference of literal and variable is never done
anywhere else in the language.
One other thing is p as Point {x, y} which you have used as a pattern
above. As currently written it is not allowed, but could be easily added.
I have no opinion on either but I think that it might be unnecessary as in
most cases you would have the object being matched in a variable
that is in scope anyway.
I also added initial wording on warnings. There probably should be more
but it's a start at least.
I think Scalas extractor objects needs to be mentioned. Personally I don't
see much of a value with them when there are object destructuring
but there are probably other opinions out there. But all classes that
would use them should be able to add getters for those values instead.
match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}
On Wed, Nov 18, 2015 at 6:07 PM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
On Mon, Nov 16, 2015 at 5:54 AM, 'Paul Brauner' via Dart Misc <
I agree, non-linear patterns are a gadget in my opinion. They are
superseded by guards, which don't force you to bake one particular notion
of equality into the semantics of the language.
+1.
The simplest, safest option is to have it be a syntax error for a
variable to appear twice in the same pattern. I don't think allowing
repetition there adds much value (like Paul says, you can always just guard
on equality) and I think it adds a lot of complexity.
It also makes patterns work less like variable declarations, which I
think is generally a bad idea. Variable declarations basically *are* patterns
(or a special subset of them) so I think we should encourage them to
converge as much as possible.
Cheers!
– bob
--
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
---
You received this message because you are subscribed to a topic in the
Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
'Erik Ernst' via Dart Misc
2015-11-24 12:48:04 UTC
Permalink
With guards, which would be able to do anything because they are just
boolean expressions (even though it would be bad style to have
side-effects), it very quickly gets impossible to check for exhaustive
matching anyway. E.g., if you can show that `e` is pure then `e` and `!e`
will be an exhaustive set of cases, but in general it's of course an
undecidable problem.

So the no-warnings approach would be forced in some cases, and warnings
would then necessarily be confined to some "nice" subset of all the
possible match expressions. On the other hand, it makes sense to detect
such a "nice" subset if we can come up with something that is easy to
understand.
Post by Rasmus Eneman
I just realized that it may be hard to get static warnings for exhaustion
to work as intended with
match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}
if the static type of x is Option and we have the type hierarchy
abstract class Option<T> {}
class Some<T> extends Option<T> {}
class None extends Option {}
Then the only way for the analyzer to realize that the above expression
fully exhausts x is to know all subclasses of Option.
If Dart had type aliases and union types it could have been defined as
type Option<T> = Some<T> | None;
class Some<T> {}
class None {}
But the only options I see now is
1. Issue a warning which forces people to add a default case that is never
reached, or use the default case for None which
would make it harder to understand the intent.
2. Don't issue warnings at all
3. Don't issue warnings for other cases than when the static type of x is
an enumerable.
What I'm leaning towards is option 3 and add warnings for everything else
if Dart ever gets union types and the above
case becomes possible for the analyzer to understand without knowing all
subclasses of a class.
Post by Rasmus Eneman
I updated it now to be a syntax error, as you said it's simple to do
anyway, no need to complicate the spec or expectations on behavior.
One pattern I'm still unsure about though is Point {x, y: x} where the
second x is clearly not being declared, should that be allowed?
It's still easy to do with a guard but it might be expected that it would
be allow because that difference of literal and variable is never done
anywhere else in the language.
One other thing is p as Point {x, y} which you have used as a pattern
above. As currently written it is not allowed, but could be easily added.
I have no opinion on either but I think that it might be unnecessary as
in most cases you would have the object being matched in a variable
that is in scope anyway.
I also added initial wording on warnings. There probably should be more
but it's a start at least.
I think Scalas extractor objects needs to be mentioned. Personally I
don't see much of a value with them when there are object destructuring
but there are probably other opinions out there. But all classes that
would use them should be able to add getters for those values instead.
match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}
On Wed, Nov 18, 2015 at 6:07 PM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
On Mon, Nov 16, 2015 at 5:54 AM, 'Paul Brauner' via Dart Misc <
I agree, non-linear patterns are a gadget in my opinion. They are
superseded by guards, which don't force you to bake one particular notion
of equality into the semantics of the language.
+1.
The simplest, safest option is to have it be a syntax error for a
variable to appear twice in the same pattern. I don't think allowing
repetition there adds much value (like Paul says, you can always just guard
on equality) and I think it adds a lot of complexity.
It also makes patterns work less like variable declarations, which I
think is generally a bad idea. Variable declarations basically *are* patterns
(or a special subset of them) so I think we should encourage them to
converge as much as possible.
Cheers!
– bob
--
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
---
You received this message because you are subscribed to a topic in the
Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
'Erik Ernst' via Dart Misc
2015-11-24 13:00:29 UTC
Permalink
Post by Rasmus Eneman
I updated it now to be a syntax error, as you said it's simple to do
anyway, no need to complicate the spec or expectations on behavior.
One pattern I'm still unsure about though is Point {x, y: x} where the
second x is clearly not being declared, should that be allowed?
That's probably just as unmanageable as the equality constraints. In the
general case, this allows us to require that, say, the left and right
subtree of a `Tree` node must be equal to each other (just use `Tree`
rather than `Point`). That might be defined in terms of structural
equality, which would entail a traversal and comparison of arbitrarily
large structures which might be overlapping and/or cyclic. Just think about

var t = new Tree(new Tree(t, t), t);

(ignoring that we'd need spell it out as a couple of statements involving a
destructive update in order to actually create such a cyclic structure).
That tree has identical "infinite" (that is, cyclic) right and left
subtrees, but since the right subtree is always returning to the top level
one step faster than the left subtree, it gets tricky to know when we can
stop and say "true", respectively how we can avoid going into an infinite
loop. We should leave that kind of traversal/checking to the domain
programmer, not the language.
Post by Rasmus Eneman
It's still easy to do with a guard but it might be expected that it would
be allow because that difference of literal and variable is never done
anywhere else in the language.
One other thing is p as Point {x, y} which you have used as a pattern
above. As currently written it is not allowed, but could be easily added.
I have no opinion on either but I think that it might be unnecessary as in
most cases you would have the object being matched in a variable
that is in scope anyway.
I also added initial wording on warnings. There probably should be more
but it's a start at least.
I think Scalas extractor objects needs to be mentioned. Personally I don't
see much of a value with them when there are object destructuring
but there are probably other opinions out there. But all classes that
would use them should be able to add getters for those values instead.
match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}
On Wed, Nov 18, 2015 at 6:07 PM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
On Mon, Nov 16, 2015 at 5:54 AM, 'Paul Brauner' via Dart Misc <
I agree, non-linear patterns are a gadget in my opinion. They are
superseded by guards, which don't force you to bake one particular notion
of equality into the semantics of the language.
+1.
The simplest, safest option is to have it be a syntax error for a
variable to appear twice in the same pattern. I don't think allowing
repetition there adds much value (like Paul says, you can always just guard
on equality) and I think it adds a lot of complexity.
It also makes patterns work less like variable declarations, which I
think is generally a bad idea. Variable declarations basically *are* patterns
(or a special subset of them) so I think we should encourage them to
converge as much as possible.
Cheers!
– bob
--
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
---
You received this message because you are subscribed to a topic in the
Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
'Burak Emir' via Dart Misc
2015-11-25 01:28:35 UTC
Permalink
Some comments:

* I'd keep the 'case' in match expressions. Consider i.e. exp match { case
x => (y) => z case 1 => 2 case _ => ... } without the 'case'.

* exhaustiveness checking for testing subtypes works if you can assume a
closed world (e.g. knowledge of all subtypes).

In Java, Scala, ML, things like separate compilation or dynamic
class-loading break that assumption, so Scala introduced a keyword "sealed"
that would forbid subtypes other than the ones known. I'm not sure what the
plan is for dart.

* there are also situations where exhaustiveness checking may be
undesirable; for instance one may define classes that represent a rich set
of operators of propositional logic, but then after some point, they all
get translated to some subset (say NOT and AND). Another example is
abstract syntax tree classes in compilers where earlier passes translate
away / desugar constructs into simpler ones. Finally, extending an enum
with a new value, that can only appear in a certain place. Consequently, it
would be good to have a way to suppress the warning.

* about the added value of extractors aka "unapply" methods. These give
users an easy way to define their own patterns *and give them a name*,
hence it does not make much sense to compare it with object destructuring.
E.g. consider the following, with suitable SELECT, FROM and WHERE
extractors:
foo(String queryString) => queryString match { case SELECT(x, FROM(y,
WHERE, condition))) => ... }

or a network protocol's pattern like: byteIterable match { case
MESSAGE(header, payLoadSize, payLoadBytes) => }

* exaustiveness checking won't easily be extended to extractors, though.

* The DEP makes me curious: what happens if one wants to match against
generic types? Would you support type variable binding or type variable
checking in addition to variable binding?

<T> foo(x) => x match { case y is List<T> => new Set<T>..addAll(y) }

* one thing that is frequently found in match statements is the ability to
match against variables declared in scope. So with a suitable extractor
"twice", we may want to check that y is 2*x, however we need a way to
reference a variable (instead of declaring a new variable x). In Scala,
variables from outside had to be capitalized, i.e.

foo(String X) => (y) => y match { case twice(X) => /* we now know that y ==
2 * X */ }

cheers,
Burak

On Tue, Nov 24, 2015 at 2:00 PM, 'Erik Ernst' via Dart Misc <
Post by 'Erik Ernst' via Dart Misc
Post by Rasmus Eneman
I updated it now to be a syntax error, as you said it's simple to do
anyway, no need to complicate the spec or expectations on behavior.
One pattern I'm still unsure about though is Point {x, y: x} where the
second x is clearly not being declared, should that be allowed?
That's probably just as unmanageable as the equality constraints. In the
general case, this allows us to require that, say, the left and right
subtree of a `Tree` node must be equal to each other (just use `Tree`
rather than `Point`). That might be defined in terms of structural
equality, which would entail a traversal and comparison of arbitrarily
large structures which might be overlapping and/or cyclic. Just think about
var t = new Tree(new Tree(t, t), t);
(ignoring that we'd need spell it out as a couple of statements involving
a destructive update in order to actually create such a cyclic structure).
That tree has identical "infinite" (that is, cyclic) right and left
subtrees, but since the right subtree is always returning to the top level
one step faster than the left subtree, it gets tricky to know when we can
stop and say "true", respectively how we can avoid going into an infinite
loop. We should leave that kind of traversal/checking to the domain
programmer, not the language.
Post by Rasmus Eneman
It's still easy to do with a guard but it might be expected that it would
be allow because that difference of literal and variable is never done
anywhere else in the language.
One other thing is p as Point {x, y} which you have used as a pattern
above. As currently written it is not allowed, but could be easily added.
I have no opinion on either but I think that it might be unnecessary as
in most cases you would have the object being matched in a variable
that is in scope anyway.
I also added initial wording on warnings. There probably should be more
but it's a start at least.
I think Scalas extractor objects needs to be mentioned. Personally I
don't see much of a value with them when there are object destructuring
but there are probably other opinions out there. But all classes that
would use them should be able to add getters for those values instead.
match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}
On Wed, Nov 18, 2015 at 6:07 PM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
On Mon, Nov 16, 2015 at 5:54 AM, 'Paul Brauner' via Dart Misc <
I agree, non-linear patterns are a gadget in my opinion. They are
superseded by guards, which don't force you to bake one particular notion
of equality into the semantics of the language.
+1.
The simplest, safest option is to have it be a syntax error for a
variable to appear twice in the same pattern. I don't think allowing
repetition there adds much value (like Paul says, you can always just guard
on equality) and I think it adds a lot of complexity.
It also makes patterns work less like variable declarations, which I
think is generally a bad idea. Variable declarations basically *are* patterns
(or a special subset of them) so I think we should encourage them to
converge as much as possible.
Cheers!
– bob
--
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
---
You received this message because you are subscribed to a topic in the
Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
'Paul Brauner' via Dart Misc
2015-11-25 09:01:29 UTC
Permalink
On Wed, Nov 25, 2015 at 2:29 AM 'Burak Emir' via Dart Misc <
Post by 'Burak Emir' via Dart Misc
* I'd keep the 'case' in match expressions. Consider i.e. exp match { case
x => (y) => z case 1 => 2 case _ => ... } without the 'case'.
* exhaustiveness checking for testing subtypes works if you can assume a
closed world (e.g. knowledge of all subtypes).
In Java, Scala, ML, things like separate compilation or dynamic
class-loading break that assumption, so Scala introduced a keyword "sealed"
that would forbid subtypes other than the ones known. I'm not sure what the
plan is for dart.
* there are also situations where exhaustiveness checking may be
undesirable; for instance one may define classes that represent a rich set
of operators of propositional logic, but then after some point, they all
get translated to some subset (say NOT and AND). Another example is
abstract syntax tree classes in compilers where earlier passes translate
away / desugar constructs into simpler ones. Finally, extending an enum
with a new value, that can only appear in a certain place. Consequently, it
would be good to have a way to suppress the warning.
* about the added value of extractors aka "unapply" methods. These give
users an easy way to define their own patterns *and give them a name*,
hence it does not make much sense to compare it with object destructuring.
E.g. consider the following, with suitable SELECT, FROM and WHERE
foo(String queryString) => queryString match { case SELECT(x, FROM(y,
WHERE, condition))) => ... }
or a network protocol's pattern like: byteIterable match { case
MESSAGE(header, payLoadSize, payLoadBytes) => }
* exaustiveness checking won't easily be extended to extractors, though.
* The DEP makes me curious: what happens if one wants to match against
generic types? Would you support type variable binding or type variable
checking in addition to variable binding?
<T> foo(x) => x match { case y is List<T> => new Set<T>..addAll(y) }
* one thing that is frequently found in match statements is the ability to
match against variables declared in scope. So with a suitable extractor
"twice", we may want to check that y is 2*x, however we need a way to
reference a variable (instead of declaring a new variable x). In Scala,
variables from outside had to be capitalized, i.e.
foo(String X) => (y) => y match { case twice(X) => /* we now know that y
== 2 * X */ }
I would rather use a guard for this, I find this feature of scala confusing
:)
Post by 'Burak Emir' via Dart Misc
cheers,
Burak
On Tue, Nov 24, 2015 at 2:00 PM, 'Erik Ernst' via Dart Misc <
Post by 'Erik Ernst' via Dart Misc
Post by Rasmus Eneman
I updated it now to be a syntax error, as you said it's simple to do
anyway, no need to complicate the spec or expectations on behavior.
One pattern I'm still unsure about though is Point {x, y: x} where the
second x is clearly not being declared, should that be allowed?
That's probably just as unmanageable as the equality constraints. In the
general case, this allows us to require that, say, the left and right
subtree of a `Tree` node must be equal to each other (just use `Tree`
rather than `Point`). That might be defined in terms of structural
equality, which would entail a traversal and comparison of arbitrarily
large structures which might be overlapping and/or cyclic. Just think about
var t = new Tree(new Tree(t, t), t);
(ignoring that we'd need spell it out as a couple of statements involving
a destructive update in order to actually create such a cyclic structure).
That tree has identical "infinite" (that is, cyclic) right and left
subtrees, but since the right subtree is always returning to the top level
one step faster than the left subtree, it gets tricky to know when we can
stop and say "true", respectively how we can avoid going into an infinite
loop. We should leave that kind of traversal/checking to the domain
programmer, not the language.
Post by Rasmus Eneman
It's still easy to do with a guard but it might be expected that it
would be allow because that difference of literal and variable is never done
anywhere else in the language.
One other thing is p as Point {x, y} which you have used as a pattern
above. As currently written it is not allowed, but could be easily added.
I have no opinion on either but I think that it might be unnecessary as
in most cases you would have the object being matched in a variable
that is in scope anyway.
I also added initial wording on warnings. There probably should be more
but it's a start at least.
I think Scalas extractor objects needs to be mentioned. Personally I
don't see much of a value with them when there are object destructuring
but there are probably other opinions out there. But all classes that
would use them should be able to add getters for those values instead.
match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}
On Wed, Nov 18, 2015 at 6:07 PM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
On Mon, Nov 16, 2015 at 5:54 AM, 'Paul Brauner' via Dart Misc <
I agree, non-linear patterns are a gadget in my opinion. They are
superseded by guards, which don't force you to bake one particular notion
of equality into the semantics of the language.
+1.
The simplest, safest option is to have it be a syntax error for a
variable to appear twice in the same pattern. I don't think allowing
repetition there adds much value (like Paul says, you can always just guard
on equality) and I think it adds a lot of complexity.
It also makes patterns work less like variable declarations, which I
think is generally a bad idea. Variable declarations basically *are* patterns
(or a special subset of them) so I think we should encourage them to
converge as much as possible.
Cheers!
– bob
--
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
---
You received this message because you are subscribed to a topic in the
Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
'Erik Ernst' via Dart Misc
2015-11-25 09:02:55 UTC
Permalink
Cool stuff, Burak! ;-)

Type variable binding would be difficult in Dart, I guess. For instance, we
would expect a `List` (that is, `List<dynamic>`) to match a typing
requirement specified as `List<List<T>>`, but how would we then come up
with a suitable T, presumably extracting it from somewhere inside the black
hole called `dynamic`? Maybe we could use `dynamic`, but we would certainly
have to be careful.

We could also have an upper bound on the type variable that we are trying
to extract from somewhere inside `dynamic`, and it might be an F-bound
(say, the type variable is declared as `X extends Foo<X, Y>` along with `Y
extends Bare<X, Y>`); again, we might get away with "X is dynamic, and so
is Y".

Hence, it looks like we could often end up in a branch of the pattern
matching construct where we _think_ we know a lot about the situation, but
in practice we are just looking at something whose typing characteristics
are very loose..

On Wed, Nov 25, 2015 at 2:28 AM, 'Burak Emir' via Dart Misc <
Post by 'Burak Emir' via Dart Misc
* I'd keep the 'case' in match expressions. Consider i.e. exp match { case
x => (y) => z case 1 => 2 case _ => ... } without the 'case'.
* exhaustiveness checking for testing subtypes works if you can assume a
closed world (e.g. knowledge of all subtypes).
In Java, Scala, ML, things like separate compilation or dynamic
class-loading break that assumption, so Scala introduced a keyword "sealed"
that would forbid subtypes other than the ones known. I'm not sure what the
plan is for dart.
* there are also situations where exhaustiveness checking may be
undesirable; for instance one may define classes that represent a rich set
of operators of propositional logic, but then after some point, they all
get translated to some subset (say NOT and AND). Another example is
abstract syntax tree classes in compilers where earlier passes translate
away / desugar constructs into simpler ones. Finally, extending an enum
with a new value, that can only appear in a certain place. Consequently, it
would be good to have a way to suppress the warning.
* about the added value of extractors aka "unapply" methods. These give
users an easy way to define their own patterns *and give them a name*,
hence it does not make much sense to compare it with object destructuring.
E.g. consider the following, with suitable SELECT, FROM and WHERE
foo(String queryString) => queryString match { case SELECT(x, FROM(y,
WHERE, condition))) => ... }
or a network protocol's pattern like: byteIterable match { case
MESSAGE(header, payLoadSize, payLoadBytes) => }
* exaustiveness checking won't easily be extended to extractors, though.
* The DEP makes me curious: what happens if one wants to match against
generic types? Would you support type variable binding or type variable
checking in addition to variable binding?
<T> foo(x) => x match { case y is List<T> => new Set<T>..addAll(y) }
* one thing that is frequently found in match statements is the ability to
match against variables declared in scope. So with a suitable extractor
"twice", we may want to check that y is 2*x, however we need a way to
reference a variable (instead of declaring a new variable x). In Scala,
variables from outside had to be capitalized, i.e.
foo(String X) => (y) => y match { case twice(X) => /* we now know that y
== 2 * X */ }
cheers,
Burak
On Tue, Nov 24, 2015 at 2:00 PM, 'Erik Ernst' via Dart Misc <
Post by 'Erik Ernst' via Dart Misc
Post by Rasmus Eneman
I updated it now to be a syntax error, as you said it's simple to do
anyway, no need to complicate the spec or expectations on behavior.
One pattern I'm still unsure about though is Point {x, y: x} where the
second x is clearly not being declared, should that be allowed?
That's probably just as unmanageable as the equality constraints. In the
general case, this allows us to require that, say, the left and right
subtree of a `Tree` node must be equal to each other (just use `Tree`
rather than `Point`). That might be defined in terms of structural
equality, which would entail a traversal and comparison of arbitrarily
large structures which might be overlapping and/or cyclic. Just think about
var t = new Tree(new Tree(t, t), t);
(ignoring that we'd need spell it out as a couple of statements involving
a destructive update in order to actually create such a cyclic structure).
That tree has identical "infinite" (that is, cyclic) right and left
subtrees, but since the right subtree is always returning to the top level
one step faster than the left subtree, it gets tricky to know when we can
stop and say "true", respectively how we can avoid going into an infinite
loop. We should leave that kind of traversal/checking to the domain
programmer, not the language.
Post by Rasmus Eneman
It's still easy to do with a guard but it might be expected that it
would be allow because that difference of literal and variable is never done
anywhere else in the language.
One other thing is p as Point {x, y} which you have used as a pattern
above. As currently written it is not allowed, but could be easily added.
I have no opinion on either but I think that it might be unnecessary as
in most cases you would have the object being matched in a variable
that is in scope anyway.
I also added initial wording on warnings. There probably should be more
but it's a start at least.
I think Scalas extractor objects needs to be mentioned. Personally I
don't see much of a value with them when there are object destructuring
but there are probably other opinions out there. But all classes that
would use them should be able to add getters for those values instead.
match (x) {
Some {value} => print('got $value');
None {} => print("it's empty");
}
On Wed, Nov 18, 2015 at 6:07 PM, 'Bob Nystrom' via Dart Misc <
Post by 'Bob Nystrom' via Dart Misc
On Mon, Nov 16, 2015 at 5:54 AM, 'Paul Brauner' via Dart Misc <
I agree, non-linear patterns are a gadget in my opinion. They are
superseded by guards, which don't force you to bake one particular notion
of equality into the semantics of the language.
+1.
The simplest, safest option is to have it be a syntax error for a
variable to appear twice in the same pattern. I don't think allowing
repetition there adds much value (like Paul says, you can always just guard
on equality) and I think it adds a lot of complexity.
It also makes patterns work less like variable declarations, which I
think is generally a bad idea. Variable declarations basically *are* patterns
(or a special subset of them) so I think we should encourage them to
converge as much as possible.
Cheers!
– bob
--
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
---
You received this message because you are subscribed to a topic in the
Google Groups "Dart Misc" group.
To unsubscribe from this topic, visit
https://groups.google.com/a/dartlang.org/d/topic/misc/MJXLjFxZu0A/unsubscribe
.
To unsubscribe from this group and all its topics, send an email to
--
Rasmus Eneman
--
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
---
You received this message because you are subscribed to the Google
Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
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
---
You received this message because you are subscribed to the Google Groups
"Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
'Bob Nystrom' via Dart Misc
2015-11-03 18:53:50 UTC
Permalink
Post by Jan Mostert
switch (c, noFallThrough: true){
// do something
continue; // instead of break, now use continue to trigger fallthrough
// do something else
// throw exception
}
I quite like the match idea, would be nice to have similar option to
fallthrough or not fall through using continue / break to trigger
fallthrough / not falling through.
Aside from the general weird of having a "named parameter" as part of a
statement syntax, consider:

var string = "continue";
var flag = true;
while (true) {
switch (string, noFallThrough: flag) {
case "turn off fallthrough":
flag = false;
string = "continue";
break;

case "continue":
continue;

default:
print("fell through");
}

print("didn't continue");
}


You really *really* don't want the semantics of a reserved word changing
based on a value at runtime.
Post by Jan Mostert
Would it hurt having both switch and match?
No, I think it's feasible to have two separate statements.

Cheers!

– bob
--
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+***@dartlang.org.
kc
2015-11-23 13:37:51 UTC
Permalink
ES6 uses {} for object literals. And Strong Mode/SoundScript makes them
more record-like - especially with the new 'proper' Map object - which may
get literal syntax.

Dart followed Python and used {} for Map. (Another area where 'familiar'
Dart deviates from both JS and Java/C#).

So I'm not sure how appropriate it is to use {} for de-structuring/pattern
matching.

Also Dart could use something in the tuple/object literal space which plays
well with an eventual pattern matching proposal.

K.
Post by Rasmus Eneman
Me and a friend started working on a DEP for pattern matching using a Rust
like match expression <https://doc.rust-lang.org/book/patterns.html>
however, as we were creating examples and translated them to actual Dart
code we saw that the big benefit is as a replacement for the
switch-statement. They can provide nice syntactic suger for multiple if
else branches, but is that enough to introduce a new concept?
However switch statements are a pretty complex concepts with fall though,
or in Darts case not which already breaks with other languages.
To re-add fall though Dart do have labels which is another concept for a
very limited use case.
Therefore I would like to raise the discussion if the switch statement
should be dropped for Dart 2.0 and instead be replaced with a Rust like
match expression.
When compared to switch statements the match expression does have a nicer
syntax which is more similar to the rest of the language (switch the only
statements where blocks starts with a colon and ends by magic),
and is simpler because there no fall though or labels (that behaviour can
easily be replaced with function calls anyway) and does not break semantics
with other popular languages.
The places were it would be a bit nicer than if/else would only come as an
additional bonus.
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
Anders Holmgren
2015-11-24 03:29:28 UTC
Permalink
Objects in js are just maps with a bit of sugar aren't they?
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
Continue reading on narkive:
Loading...