3 ms·
I generally agree with you but the one point they make in this article that really matters for Dart is it does not have pattern matching. Dart’s nominative type
by rokob 6y ago
I generally agree with you but the one point they make in this article that really matters for Dart is it does not have pattern matching. Dart’s nominative type system makes much of standard FP much harder than you’d imagine. I know Rust is nominal too but Rust has a lot of complexity to support these things.
It is very simple to add a Maybe and Either type to Dart (my code base has variants of these to deal with null issues) but imperative destructing is a pain. You can get most of the benefits of those techniques in user land without the language knowing about it, but I agree it still misses out on some stuff.
If Dart already had pattern matching or was willing to add it first then the ADT version could have been chosen, but without that prerequisite nullable types was the only ergonomic choice.
- markdog12 6y agoDart is looking at adding pattern matching and "record" types: https://github.com/dart-lang/language/tree/master/working/0546-patterns https://github.com/dart-lang/language/tree/master/working/05...
- bern4444 6y agoThat's an interesting counter point, though another comment in a different post for this same article[1] pointed out that Dart is considering adding pattern matching too. Though I have trouble understanding how a nominal type system affects this? Does dart not have generics? That's all you need to support these patterns? I'm having trouble understanding how the type of type system plays a role here. Also, what's 'imperative destructing'? Haven't heard that term before, is that just pulling out a property from an object like this from JS? const { foo } = objectWithPropertyFoo; [1]https://news.ycombinator.com/item?id=25334283 https://news.ycombinator.com/item?id=25334283
- rokob 6y agoYes Dart has generics which is how you would implement optional types yourself. The type of type system doesn't play a role here you are right. I was thinking of the really good pattern matching I have experienced usually being present with structural subtyping. Dart is considering adding pattern matching (and real tuples!) and I think they will eventually get there. I just think that would have had to come first to make the case of optionals over nullable types more compelling. I would call that example destructing in the normal sense and it is basically a form of pattern matching. To do that in an imperative language without pattern matching (i.e. what I am calling imperative destructuring), you end up with code like if (maybeFoo.isSome) { final foo = maybeFoo.asValue; ... } when you really want if let Some(foo) = maybeFoo {...}
- codebje 6y agoYou may prefer for foo in maybeFoo { ... } This (AIUI) isn't valid Dart code though, but this would be: maybeFoo.forEach((foo) { ... })
- kelnos 6y agoI don't buy the pattern matching argument. I've been using Vavr's Option type in Java a lot lately (having banned the use of null from my code), and I don't have any issues with it. I avoid Vavr's pattern matching because I find the syntax to be clunky (not a criticism of the Vavr developers; I think what they've done is impressive within Java's syntax limitations). I do miss pattern matching in general, but I don't find using Option to be any more difficult without it. And no, I never use Option.get(); I have an ArchUnit test set up that will fail the build if anyone tries. On the flip side, I do find Option a pain to use in Rust sometimes, which does have pattern matching. I think that's a function of the borrow checker making some things harder to express. So perhaps it's not Dart's missing pattern matching that would make Option hard to use there, but some other feature (or missing feature) of the language or type system?