Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

We recently added pattern matching to Dart [1], so I'm always keen to see how it compares to similar features in other languages. In case it's interesting, here's that Ruby example ported to Dart:

    print(switch ({'name': 'John', 'friends': [{'name': 'Jane'}, {'name': 'Rajesh'}]}) {
      {'friends': [{'name': var firstFriend}, ...]} => "matched: $firstFriend",
      _ => "not matched"
    });
Pretty similar! The main differences are that Dart doesn't have symbols, so the keys are string literals instead. Also, variable bindings in patterns are explicit (using "var") here to disambiguate them from named constant patterns.

[1]: https://medium.com/dartlang/announcing-dart-3-53f065a10635



> We recently added pattern matching to Dart [1]

I've been using that and I love it, in general... but can I ask you why do we need to name a variable in a pattern like this:

    switch (p) {
      Person(name: var name) => ...
    }
That's the only thing that feels a bit annoying as you have to rename the variable... In Java, this would be something like:

    Person(var name) -> ...
EDIT: I guess it's to support `Person(name: 'literal')` matches.

> Dart doesn't have symbols

That's weird, as I actually use sometimes `#sym` (which has type `Symbol`)??

    print((#sym).runtimeType);
This prints `Symbol` :)

I know you know Dart in and out, but could you explain why this is not actually a symbol in the way Ruby symbols are?


We require "var" before variable patterns because we also allow named constants in patterns (which match if the value is equal to the constant's value):

    const pi = 3.14; // Close enough.

    switch (value) {
      (pi, var pi) => ...
    }
This case matches a record whose first field is equal to 3.14 and binds the second field to a new variable named "pi". Of course, in practice, you wouldn't actually shadow a constant like this, but we didn't want pattern syntax to require name resolution to be unambiguous, so in contexts where a constant pattern is allowed, we require you to write "var", "final", or a type to indicate when you want to declare a variable.

Swift's pattern syntax works pretty much the same way.

> > Dart doesn't have symbols

> That's weird, as I actually use sometimes `#sym` (which has type `Symbol`)??

Oh, right. I always forget about those. Yes, technically we have symbols, but they are virtually unused and are a mostly pointless wart on the language. It's not idiomatic to use them like it is in Ruby.


I don't find symbols to be pointless. They are useful as "interned strings" and that's exactly what I need sometimes. I could use `const myThing = "my thing";` for that purpose (but with symbols I don't need to declare it anywhere, just use it... for better or worse!), I suppose, but before `const` existed, I believe symbols were the only way to do that?


> They are useful as "interned strings" and that's exactly what I need sometimes.

I'm not sure exactly what you mean by "need" here, but as far as I know, Dart doesn't make any promises about the memory management or efficiency of either strings or symbols.

If I were you, I'd just use strings.


I had to double check this, because basically the only use of symbols in any languages is to provide a constant value you can treat as an internalized string (like Common Lisp keywords, for example). The would be entirely useless if that were not the case.

Luckily, the current Dart specification does guarantee this (section 17.8):

"Assume that i ∈ 1, 2, and that oi is the value of a constant expression which is a symbol based on the string si. If s1 == s2 then o1 and o2 is the same object. That is, symbol instances are canonicalized."

Apparently, there's even special treatment for "private symbols", which are only the same object "in the same library". TIL.

Source: https://spec.dart.dev/DartLangSpecDraft.pdf

EDIT: there's even a whole sentence justifying the existence of symbols as being related to reflection, actually... they say Dart literal Strings are already "canonicalized" so that fact about Symbols is not enough for that.... hence you're right that String literals are just as good for the use-cases I had in mind. I guess I will use String literals from now on after all.

EDIT 2: > I'm not sure exactly what you mean by "need"

Hopefully it's clear what I "needed" now... basically, interned Strings to avoid wastefully comparing bytes when a pointer comparison would suffice as all values are known at compile-time.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: