Me and a friend started working on a DEP for pattern matching using a Rust like match expression
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?
if (foo.bar is SomeType) {var bar = foo.bar as SomeType;...}
However switch statements are a pretty complex concepts with fall though, or in Darts case not which already breaks with other languages.
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.
final x = 1;
switch(x) {
case 1: print("one");
case 2: print("two");
case 3: print("three");
default: print("anything");
}
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
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";
}
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.
--
switch (c, noFallThrough: true){case CR:// do somethingcase LF:continue; // instead of break, now use continue to trigger fallthroughcase SPACE:// do something elsedefault:// 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.
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");}
Would it hurt having both switch and match?
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
--
Whatever syntax/semantics we choose, I wish it was based on some view mechanism 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.
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.PaulOn Wed, Nov 11, 2015 at 4:09 PM kc <kevin...@gmail.com> wrote:On Tuesday, November 3, 2015 at 3:48:44 PM UTC, Joel Trottier-Hébert wrote:Yeah I've seen that. I've also opened an issue for the SDK more than a year ago, and they closed it so ... :PLars 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 from it, send an email to misc+uns...@dartlang.org.
--
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.
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.
if (foo.bar is Baz) {var bar = foo.bar as Baz;...}
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.
Whatever syntax/semantics we choose, I wish it was based on some view mechanism 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. 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.
On Wed, Nov 11, 2015 at 10:20 AM, 'Paul Brauner' via Dart Misc <mi...@dartlang.org> wrote:Whatever syntax/semantics we choose, I wish it was based on some view mechanism 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.
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 misc+uns...@dartlang.org.
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
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.
>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 :)Oh, yeah. That's a big omission. The current idea is equality, like if you had specified a literal.
>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?
>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.
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.
--
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 misc+uns...@dartlang.org.
Me and a friend started working on a DEP for pattern matching using a Rust like match expression 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.
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+uns...@dartlang.org.
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?
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+uns...@dartlang.org.
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 */ }