I think you can get this feature with less language additions...
interface Matcher {
bool matches(object);
Matcher.any() {
// return a matcher that matches anything
}
Matcher.not(matcher) {
// etc
}
}
bool match(pattern, object) {
return (pattern is Matcher)
? pattern.matches(object)
: pattern == object;
}
class List<T> implements Matcher {
bool match(obj) {
if (obj is! List || obj.length != length) return false;
for (var i=0; i<length; i++) {
if (!matches(this[i], object[i])) return false;
}
return true;
}
}
Now allow a 'match' clause in a switch statement. Like 'case' but evaluates matches(matchPattern, switchValue).
Now you can write:
switch([a, b, c]) {
match [true, 42, "x"]:
return 1;
match [true, Matcher.not(42), Matcher.any()]:
return 2;
default:
return 3;
}
Not to mention having Regex, Range, and Function implement Matcher...
(Hope this is clear, on phone...)
I'm really not sure. (I'm not on the dart team btw, just an interested observer).
I think having special 'low-level switch' syntax and no 'high-level switch' would be unfortunate in a language like Dart, I'd like the reverse.
You could still fake one with a pure library...
Match
.when([true, 42, "x"], (){ ... })
.when(...)
.evaluate([a,b,c]);
But it's harder to read, you're limited by non-local returns, etc.
I wonder how your approach would work in light of today's public
announcement regarding intention to restrict switch to compile-time
constant int/String?
http://news.dartlang.org/2012/04/dart-language-progress-update.html
I just wanted to point out that most of the work we're doing on our
Dart-to-JavaScript compiler happens in lib/compiler, where our new
compiler is shaping up to be a replacement for frog. We still have
more work to do -- in particular on the size of the generated code --
but we are planning on making dart2js (which is based on the
lib/compiler code) available in the SDK pretty soon so people can
start experimenting with it.
Cheers,
Kasper
Matching without binding is a lost opportunity.
A successful match tells you something - the type of a value, the
structure of a datatype, etc.
Something should carry that information into the following code.
In your example above, you want expr to carry the match information
itself, but if expr is a large
expression, it probably won't be repeated anyway.
If instead it was:
case Pattern x => ...
then x would carry the value of expr *and* the information that it
matched the Pattern.
Same with the type checks. They are separated from their consequences:
if (expr is Type)
doesn't capture the success of the match. If instead it was
typecase expr { case Type x: ... }
then the identifier x would carry the type.
Said differently: A test should not (always) be just an expression
that results in a binary value, it should be the guardian of a scope
where the test is known to be true (or false), and the consequences of
the test should be available in the scope, e.g., as a correctly typed
variable.
It's probably the functional influence that makes me think like that -
bindings are cheap when they are immutable.
/L
--
Lasse R.H. Nielsen
l...@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K -
Denmark - CVR nr. 28 86 69 84
On Wed, Apr 18, 2012 at 10:51, Lars Tackmann <ltac...@gmail.com> wrote:Matching without binding is a lost opportunity.
> it would be really nice to be able to write
>
> ----
> expr match {
> case SpecificExpr => {
> // in this block the dart editor could auto complete expr as type
> SpecificExpr
> :
> }