6 ms·
[disclaimer: I work on Dart, though not on the language team] With primary constructors this will become something along the lines of: sealed class Messag
by mraleph 3y ago
[disclaimer: I work on Dart, though not on the language team]
With primary constructors this will become something along the lines of:
sealed class Message();
class IncrementBy(final int value) extends Message;
class DecrementBy(final int value) extends Message;
class Set(final int value) extends Message;
Which is considerably less repetitive, though `extends Message` is still there. I am fairly optimistic that the next step would be to eliminate that[1], though I think we would need to gather a bit more feedback from users as people are getting more and more reps in with Dart 3.0 features. I personally would prefer something along the lines of:
sealed class Message() {
case IncrementBy(final int value);
case DecrementBy(final int value);
case Set(final int value);
}
Current syntax is not all that bad if you are going to do OO and add various helper methods on `Message` and its subclasses, but if you just want to define your data and no behavior / helpers - then it is exceedingly verbose.
[1]: https://github.com/dart-lang/language/issues/3021 https://github.com/dart-lang/language/issues/3021
- ollysb 3y agoThat syntax does look a lot nicer and makes sense if you're going to do OO anyway. I do wonder if it's trying to shoe horn OO into functional clothing but seems practical nonetheless. Primary constructors would definitely be a welcome change.
- danieldisu 3y agoIt is way easier for me to read than what you proposed in Typescript, more characters to write? sure but how many times do I have to write a piece of code and how many times do I have to read it? I guess ultimately it depends on which language you are more familiar with...
- ollysb 3y agoI'm more than happy with either of those variations. My favourite though would be Elm's syntax ;) type Message = IncrementBy Int | DecrementBy Int | Set Int
- munificent 3y agoOne big difference between how Dart (and other OO languages that take a similar approach) and what Elm and other functional languages do is that in Dart, each of the cases is also its own fully usable type. In Dart, if you do: sealed class Message {} class IncrementBy extends Message { final int amount; IncrementBy(this.amount); } class DecrementBy extends Message { final int amount; DecrementBy(this.amount); } class Set extends Message { final int amount; Set(this.amount); } You can then write functions that accept specific cases, like: onlyOnIncrement(IncrementBy increment) { ... } In Elm and friends, IncrementBy is just a type constructor, not a type. Further, we can use the class hierarchy to reuse shared state and behavior in a way that sum types don't let you easily do. In your example, each case has an int and it so happens that they reasonably represent roughly the same thing, so you could do: sealed class Message { final int amount; Message(this.amount); } class IncrementBy extends Message { IncrementBy(super.amount); } class DecrementBy extends Message { DecrementBy(super.amount); } class Set extends Message { Set(super.amount); } And now you can write code that works with the amount of any Message without having to pattern match on all of the cases to extract it: showAmount(Message message) { print(message.amount); } So, yes, it's more verbose than a sum type (and we do have ideas to trim it down some), but you also get a lot more flexibility in return.
- toastal 3y agoIn an FP code base, it’s common for ADTs to be the backbone of all data structures from Maybe to Either, to anything you use to model data types. That being the case changing 4 lines into 13 scaled into a entire code base is a massive amount of sludge to wade thru & one of the best way to up the code quality is to increase readability for maintainers. More LoC is more LoC to maintain even if it seems like it’s just a few more lines.
- munificent 3y ago> changing 4 lines into 13 scaled into a entire code base is a massive amount of sludge to wade thru It's only more verbose for the code that is defining new types. Code that is simply defining behavior (either in functions or methods) is unaffected and my experience is that that's the majority of code.