17 ms·
Dart 3.1 and a retrospective on functional style programming in Dart
- ducktective 3y agoI'm seeing Flutter is gaining more momentum at least in social media. Last I checked, I concluded the framework inherently depends on layers of abstractions that make it slower/less-responsive than say QT or native toolkits of the OS. Since Dart's raison d'etre is pretty much Flutter dev, I was wondering if it is worth learning if one's intention is knowing a handy cross-platform GUI dev toolkit that just works. That said, the competition in this scene don't have better to offer anyway namely react native (web tech) and QT (LGPL).
- mhitza 3y ago> That said, the competition in this scene don't have better to offer anyway namely react native (web tech) and QT (LGPL). What's the downside in your perspective of Qt being LGPL? I'm more familiar with GPL and AGPL, but with LGPL as long as the user can swap out the linked LGPL libraries you should be good. What is the downside in that? I can only think of it being an issue if the application you build statically links all the libraries it depends upon.
- ducktective 3y agoThe LGPL is just a nuisance that startups always have to be wary about. Personally, yeah, I think Qt is leagues ahead of the alternatives.
- seabass-labrax 3y agoYou can just buy[1] Qt, which is of course why they chose the dual-licensing model in the first place. In my opinion, though, the amount of extremely high-quality free and open source software that is available to include in one's programs is so great, it really is worth spending the time to create a proper FOSS licence compliance plan and form a OSPO (Open Source Programme Office) in your organisation to execute it. If you actively pursue the benefits that can come from directly contributing to existing FOSS projects, the rewards are even greater. [1]: https://www.qt.io/pricing https://www.qt.io/pricing
- pzo 3y agoIt's not sure if you can use LGPL when you release app too iOS App Store - both from technical and legal perspective. Technical because there is no easy way for user to swap dynamically linked libraries. Another issue is most recent QT modules are released using GPL.
- yellow_lead 3y agoQt also depends on layers of abstraction and is slower than native GUI (on mobile) and also integrated badly with mobile IMO. On Android you have basic issues like the scrolling has no inertia, text rendering cannot support emojis well, and Text QML components don't play well with autocorrect and other mobile features. (This is all QML experience btw, widgets are not supported too well on mobile anymore) I'm going to take a look at Flutter to see how it handles these issues soon, but I can't make a real comparison now.
- ngrilly 3y agoI didn't know the state of Qt on mobile was so abysmal. Good to know.
- pjmlp 3y agoAll frameworks beside the native ones on mobile are abysmal, people delude themselves thinking that they don't need to master the underlying stack as well. On the Android side it is even more difficult, because the NDK as matter of principle only exposes APIs for games and implementing native methods, so anything else has to be full of JNI calls into Java, even if those Java classes are mostly composed by native methods.
- ngrilly 3y agoAre you saying that all the non-native mobile frameworks are abysmal because they have to map to JNI calls on Android and Objective-C/Swift on iOS?
- pjmlp 3y agoThey are abysmal, because they are leaky, yes. The dream of one code base to rule them all, can easily turn into a nightmare when going outside the golden path. And really, a large majority of apps are doing basic CRUD stuff, easily doable as mobile Web.
- 3y ago
- zogrodea 3y agoNot a fan of XAML after trying to get into it, but there is Uno Platform. It wraps native widgets on mobile, just like React Native (which is good for accessibility), and uses C#. https://platform.uno/ https://platform.uno/ My guess is that it's mainly focused on mobile. On Windows, it has no overhead (behaving like a normal WinUI 3 app), on macOS I think it uses Catalyst by default (which was developed by Apple to make more iOS apps available for Mac desktops) and on Linux it draws its own widgets that the devs try imitating the GTK style with. On Android and iOS, it just uses the native widgets which I think is a better experience so you can see my reasons for guessing it's mobile-first. That may or may not be what you want.
- la_fayette 3y agoI would bet on the web. Applications like VS Code or MS Teams are built with web technology and just work fine...
- Cthulhu_ 3y agoThey work "fine", granted, but they're a compromise; their performance is much lower, user experience is unique compared to native applications, etc.
- realusername 3y agoVSCode okay I agree but Teams, the performance is attrocious. VSCode is pretty much the only fast web app and they managed it because they have done a massive amount of work to compensate it, I'm not sure other apps have the resources to go as far as them.
- deleted 3y ago[deleted]
- pzo 3y agoI was pessimistic about flutter 4 years ago but rechecked it recently (learning right now) and IMO it's really good user/developer proposition these days. They resolved most of issues on mobile devices and desktops - only web version still off but once wasmGC is ready (hopefully this year) probably things will improve. Best way for developer elevator pitch just download few flutter apps and see how you like the experience: 1. wonderous - https://flutter.gskinner.com/wonderous/ https://flutter.gskinner.com/wonderous/ 2. flutterflow (low code + gui editor for flutter) - https://flutterflow.io/ https://flutterflow.io/ 3. appflowy (notion alternative) - https://appflowy.io/ https://appflowy.io/ 4. flutter gallery (official flutter kitchen sink) - Android (Google Play Store) - https://play.google.com/store/apps/details?id=io.flutter.demo.gallery https://play.google.com/store/apps/details?id=io.flutter.dem... web (gallery.flutter.dev) - https://gallery.flutter.dev/ https://gallery.flutter.dev/ macOS (.zip) - https://github.com/flutter/gallery/releases/latest https://github.com/flutter/gallery/releases/latest 5. official material 3.0 demo - https://flutter.github.io/samples/web/material_3_demo/#/ https://flutter.github.io/samples/web/material_3_demo/#/
- zgluck 3y agoWonderous: A showcase app for the Flutter SDK. Built by gskinner in partnership with the Flutter team, Wonderous deliberately pushes visual fidelity, effects and transitions to showcase what Flutter is truly capable of on modern mobile hardware. https://github.com/gskinnerTeam/flutter-wonderous-app https://github.com/gskinnerTeam/flutter-wonderous-app
- jillesvangurp 3y agoCompose multiplatform is a newcomer in this space but worth mentioning. Built on Google's Jetpack Compose framework and Kotlin but with experimental build targets for IOS and Wasm. You can play with it now but this is pre-release quality; so expect issues. But once the feature flags for GC and Threads are removed in browsers and Kotlin 2.0 ships (early next year probably), this could change rapidly. I've not done much with compose yet but I'm keeping an eye on the kotlin slack channels related to this. There is a lot of stuff happening there.
- brabel 3y agoI have played with Kotlin Multiplatform. It's all very alpha quality in my opinion, and even more so if you use Jetpack Compose. Lots of basic things are still in "incubator" mode, which means it can and will change, so you need to keep changing stuff on upgrades. The technology is very cool and Kotlin is a great language. However, if you need to do something right now, there's no comparison with Flutter, which has been production ready for years.
- jillesvangurp 3y agoYou're not wrong. I've been developing with kotlin-js and kotlin multiplatform for three years now. Kotlin-js and multi platform is pretty usable but the upgrades can be challenging. Parts of the ecosystem have been pretty stable for years at this point and there are lots of multi platform libraries that are very usable and stable. I use quite a few of those on jvm and js. Even though it is in beta since October, KMM (Kotlin Multiplatform for mobile) is already used by a lot of apps; including some flutter apps. It doesn't provide a UI layer but you use it to share business logic across Android and Ios. Jetbrains has done a lot of work on the native compiler to get IOS more stable. Quite usable at this point but still some instability indeed. I expect they will announce a 1.0 release some time after kotlin 2.0 is released, which includes the revamped compiler. Kotlin 2.0 should happen by early/mid 2024. Compose multiplatform is yet a different thing that relates to this. Some of the compilation targets are still experimental (IOS, WASM) and indeed not ready for production usage. That too is going to benefit a lot from Kotlin 2.0. The whole compiler chain for wasm is basically built on that.
- synergy20 3y agoI actually use wxwidgets after flutter and qt these days flutter is cool for mobile but so so on desktop to me. Qt's license is complex for me as well. so far wxwidgets is a great fit.
- toastal 3y agoIs there a functional language that compiles to Dart? There’s a difference between FP features & FP ergonomics. This seems like a very verbose way to go about things I’m used to being simple/easy.
- zogrodea 3y agoF# is meant to, via Fable. I don't know what the progress is there. https://fable.io/blog/2022/2022-06-06-Snake_Island_alpha.html https://fable.io/blog/2022/2022-06-06-Snake_Island_alpha.htm...
- ollysb 3y agoWow this looks great. One to watch for the future.
- bmitc 3y agoFable is cool, but I worry about its longevity.
- gsuuon 3y agoWhy do you say that?
- bmitc 3y agoStuff like this: https://github.com/fable-compiler/Fable/issues/1822 https://github.com/fable-compiler/Fable/issues/1822 And this Flutter binding launched a year ago by one person and then never touched again: https://github.com/fable-compiler/Fable.Flutter https://github.com/fable-compiler/Fable.Flutter It just seems like an incredibly ambitious project that appears to have very little equal but is mainly worked on by a handful of people but no corporate backing. I get the feeling that if you want to use it, you'll either be the only one doing what you're doing or among just a few people. I already use F# and feel this way about the core language itself.
- tasubotadas 3y agoThe last time I've checked, OOP and functional programming are orthogonal concepts. EDIT: It means that there is no problem for the language to have both OOP & Functional. They don't have to choose one over another.
- Cthulhu_ 3y agoThat must've been a while ago, I find factors of both working pretty well together. Most languages are a mix nowadays anyway.
- kaba0 3y agoWhy would they be orthogonal? There are entire languages built on top both, like F# and Scala.
- tasubotadas 3y ago>Scala Exactly
- maleldil 3y agoThat's what orthogonal means. They're separate things, and they don't interefere with each other.
- layer8 3y agoOrthogonal means they are independent principles that can be combined freely and don’t contradict each other.
- chriswarbo 3y ago> there is no problem for the language to have both OOP & Functional. They don't have to choose one over another. Sure a language can have both; but us programmers still have to choose one or the other when modelling some domain. The article is basically describing the "expression problem": how to implement a solution in a way that allows new cases to be added https://en.wikipedia.org/wiki/Expression_problem https://en.wikipedia.org/wiki/Expression_problem The OOP approach makes it easy to add new sorts of data: we just write a new subclass, with implementations for all the interface's methods. However, it's hard to add new sorts of operations: we would have to add new methods to the interface, and update every subclass to implement those methods (very hard if we're writing a library that third parties are subclassing!) The functional/ADT approach makes it easy to add new sorts of operations: we just write a new function, which pattern-matches on all the constructors. However, it's hard to add new sorts of data: we would have to add new constructors to the ADT, and update every function to pattern-match on those constructors (very hard if we're writing a library that third parties are pattern-matching on!) When we're choosing how to represent something, it's important to consider whether future extensions are more likely to be adding new sorts of data (in which case the OOP representation may be best) or more likely to be adding new sorts of operations (in which case the ADT representation may be best). Having to extend such representations in their intended way can feel very natural and satisfying; but having to extend them the other way can be frustrating and laborious.
- kalekold 3y agoRob Pike was right: "features were being added by taking them from one language and adding it to another" "...and I realised all of these languages are turning into the same language." "we don't want one tool, we want a set of tools, each best at one task" https://www.youtube.com/watch?v=rFejpH_tAHM https://www.youtube.com/watch?v=rFejpH_tAHM
- Cthulhu_ 3y agoThis is one reason why I love Go, in that it doesn't follow. I've been primarily doing Javascript and the like for the past decade, and while I appreciate new features like functional operations added to the standard library - although that was a long process - and arrow functions, I lost it when they added object-oriented structuring like classes, but only half an implementation because there wasn't any good access modifiers. And they added OOP before they added modules and imports. I don't understand.
- kaba0 3y agoJS has been OOP since the beginnings, one might even argue that prototype-based inheritance is the real deal compared to classes.
- pjmlp 3y agoJavaScript like SELF and NewtonScript is based on prototypal inheritance as OOP model, even classes in JavaScript are mostly syntax sugar for how that is done at low level.
- kaba0 3y agoDeliberately being different from other languages… that actually makes a lot of sense why go is the way it is. And I don’t mean it in a good sense.
- threatofrain 3y agoDart's reason for existing is as a cross-platform GUI language via Flutter. It's not obvious that adding on some language ergonomics detracts or adds to that goal in a fundamental way. Sometimes languages converge because of informal consensus that something is a good idea. Maybe Go adding generics is a good idea, even if it's a step in the direction of following trends. Either way, most languages don't have syntax which is significantly challenging or easy (with exceptions like Rust), and it's the ecosystem which makes the language so productive. So whether or not Go added generics today or a decade ago, Go was still great anyway thanks to its standard library and ecosystem.
- randyrand 3y agoDart is a seriously good language. Shares a lot in common with C#, and is just incredibly productive.
- trashburger 3y agoI'm all for ADTs but the reasons the article gives are all wrong, and in fact I think it makes the code a lot worse as a result. Object programming doesn't mean "inheritance trees", that's just the (IMHO overly simplified) flavor of object programming that we call "OOP". (I'm omitting a full rant from here, which I ought to put on an article at some point.) Object programming is all about state and behavior, just like functional programming; it only differs in how it lays out the behavior namespace (object programming uses inheritance of behavior through lookup chains, which puts the object in focus; functional programming inverts that and uses the structure of the object to dispatch, putting the function in focus). Grouping behavior together in a single function like the article suggests is, IMO, an anti-pattern and one that I consider to be one of the great disadvantages of a functional programming style. Bundling behavior together means the behavior is out of the control of the object; the object's identity now becomes a critical part of the operation being performed. IMO, putting the focus on behavior is the wrong approach here. Don't get me wrong, I'm all for some features in functional programming; immutability is great for being able to make assumptions about program state and re-entrancy, for example. But I think the tendency to "lock" behavior into functions and not letting objects define their own behavior is a major shortcoming.
- grumblingdev 3y ago> Bundling behavior together means the behavior is out of the control of the object; the object's identity now becomes a critical part of the operation being performed. IMO, putting the focus on behavior is the wrong approach here. Why? Do you have an example to better explain? If find people rarely talk about the evaluation criteria for which approach to programming is better. That is, what are you optimizing for?
- trashburger 3y agoI'll respond in reverse order ;) > That is, what are you optimizing for? I'm optimizing for other programmers to easily be able to see how objects fit together and behave, and for them to be able to easily extend the system without touching the behavior of other components (which you cannot do if you bundle behavior together). I've slowly shifted towards this approach throughout the last few years of my programming journey. > Do you have an example to better explain? Let me make an attempt to do so. Let's say that you have an HTML form builder in code (this is something I'm currently working on, if you can't tell ;). Your form builder lets you design the form such that you can split the form into sections, rows and columns. You might design a registration form like this, for example (I'm using Python-like pseudocode here): layout = FormLayout( Section( title=_("Account information"), contents=Column( Field("username"), Row( Column(Field("password")), Column(Field("password_repeat")), ), ), ), # etc. you get the idea ) Now, how would I go about rendering this into a tree? If I were to take the approach that the article suggests, I would have to do something like this: def render_element(element: Element) -> SafeString: # Let's use Python 3.10's match as an analogue for the Dart switch match element: case FormLayout(children): return "".join(render_element(child) for child in children) case Column(css_class, children): return format_html( '<div class="{css_class}">{children}</div>', css_class=css_class or "col-md", children=mark_safe( "".join(render_element(child) for child in children), ), ) # case Row, Field, ... As you can probably tell, this is bound to get super unwieldy over time. And this is just for one property of this HTML form builder; now imagine if we had to do some operation to the tree (like checking all fields in a form are actually rendered)! You might, at this point, suggest that we could just split the behavior into different functions... and that would just make us re-implement the dynamic dispatch system that's found in object programming already ;) You can see how we tend to move the behavior to the object in this case, because it lets each object only worry about its own behavior. I hope this helped with giving a bit of an idea of why I'm for a more object programming-based approach over the pattern matching described in the article.
- activitypea 3y ago> Object-oriented (OO) and functional languages differ in many ways, but it’s arguable that how each paradigm models data is the defining characteristic that separates them. Specifically, the question of modeling different variations of related data and the operations on those variants. Then why is the first example they present about organizing behavior lol
- grumblingdev 3y ago> It’s typical to listen to this stream of events and use chained if-else statements to determine an action based on the type of the events that occur. You'd think something like directory watching would have a clear set of events that would make nice objects with consistent meanings, but in my experience file watching gets crazy complicated, and can have all sorts of edge cases. Just take a looked here for all the various edge cases that crop up: https://github.com/paulmillr/chokidar/issues https://github.com/paulmillr/chokidar/issues Then you have linux, windows, macos, and maybe you want to abstract over some underlying implementation like chokidar vs fb/watchman vs webpack/watchpack. Every new OS release could also cause things to change. A big leaky abstraction. So usually its going to be a bunch of if-else statements hacked together to get around edge cases, and have to be revisited later on. Any attempt to abstract this into objects, just obfuscates things. And OO forces you to name things, when in fact they might be un-nameable. `FileSystemModifyEventExceptWhenXAndYAndSometimesZ`. The behavior might rely on a series of events together, so the object hierarchy must be re-worked. OO has this rosy idea that we just have to come up with the perfect hierarchy, but things change in unexpected ways, and everything must have a descriptive noun.
- the_gipsy 3y agoThe hierarchy always looks nice on the whiteboard but always breaks down as soon as you start to write it out in code.
- taeric 3y agoI've long thought it was less OO that was problematic, and more the idea that you can make a taxonomy that covered your entire problem domain. Worse, people seem to get caught up in the taxonomy for the sake of the taxonomy.
- tempodox 3y agoThe thing is that OO forces taxonomy on you, especially if you have to deal with lots of inheritance.
- 3y ago
- frou_dh 3y agoPoor Martin Odersky was demonstrating this fusion with Scala like 15+ years ago. But he's a nice guy so I'm sure he thinks the more the merrier!
- eweise 3y agoSeems like all the languages are following in the path of Scala, Go being the big exception.
- munificent 3y agoCase classes in Scala were a direct inspiration for how we designed this feature in Dart. We stand on the shoulders of giants.
- ac130kz 3y agoSo sad there is still no static metaprogramming. I've switched my career from a Flutter mobile dev over to backend, and there are still no updates on this an utterly important feature for Dart. This could've eliminated so much sickening codegen.
- mathisfun123 3y agoThis doc was updated 3 weeks ago? https://github.com/dart-lang/language/blob/main/working/macros/feature-specification.md https://github.com/dart-lang/language/blob/main/working/macr... > This could've eliminated so much sickening codegen. Also this is funny because what do you think static metaprogramming is if not codegen? Templates macros etc are all codegen. They're just codegen you can't see (or easily steer either).
- ac130kz 3y agoIt was really stuck at "in progress" for a looong time, and it's still in the working set, so it means that's going to take yet another 2-3 Dart releases and a few more to stabilize for production. > They're just codegen you can't see Yes, and that's exactly how it should have been in the first place. No need to run buggy services, no need to constantly juggle newly generated files.
- mathisfun123 3y agodo you understand that things that you can't see still need to be juggled? the problems don't magically go away just because you can't see the artifacts. what happens is you lose complete control over how they're juggled and you retain as much control as the compiler owner deigns to give you (see generic in Go). please see all the pain of working templates in C++.
- ac130kz 3y agoI do, I work with Rust templates and worked with C++ templates. Obviously, people aren't asking for such a granular level of metaprogramming.
- jononomo 3y agoShouldn't Dart be merged with Flutter and be thought of as a single animal? There doesn't seem to be any point in thinking up scenarios for Dart that don't relate to Flutter.
- cercatrova 3y agoSome people are using it for serverside, ie the dartfrog library. It's a decent enough Algol language for backend, better than Go I'd say due to having ADTs and exhaustiveness matching.
- no_wizard 3y agoThe one fork of history I wish I could have seen come to fruition was Dart in the browser (natively) as was originally proposed. I'm very curious to see how web development would have evolved if that had come to pass.
- err4nt 3y agoAs someone inexperienced with Dart, but ever curious about it - is there anything more you can share about that, or what might have been? I end up writing almost all my work in browser-based JavaScript so I'm curious how different my work might have been.
- cogman10 3y agoHad it actually succeeded and become the defacto UI language, it has a lot of nice properties that make it well suited for optimizations. Javascript is a hard language to optimize and the current javascript engines have gone to heroic efforts to get there. Dart took what made javascript hard to optimize and removed it (mostly removing dynamism around types, you can't just add/remove random fields and functions to an object). Dart was (at least initially) designed by some of the engineers behind V8 specifically for the purpose of "let's make something that can be fast without a 10 MLoC super JIT". The other nice thing about dart is it was entirely boring. If you know Java/C# you know Dart. There weren't a whole lot of weird surprises around what "this" is, how `var` scoping works, or wrapping your mind around prototype inheritance. It was just pretty plain OO programming. That "boring" nature of dart makes it easy to maintain and to write nice IDEs around. Even today, Typescript has some neat things but by god do I hate it when devs make an uber complex macros impossible for my IDE to grok. (littering the code with red squiggles). All because they've done a bit too much Haskell. When the type signature spans multiple lines because "any" was too lose, but they did want to support anything which could be turned into a string, was undefined, could be null, could be a number, and also stuff that has a method `foo` that can be invoked on easter.
- err4nt 3y agoThanks, that makes a ton of sense, smaller/better by design but equipped to handle the same kinds of problems that JavaScript does. Is there any advantage to writing in Dart and transpiling that to JavaScript?
- leetrout 3y agoSince learning Go so many years ago it influenced how I build things in every language much in the way this article is espousing. I MUCH prefer functions that take some kind of type/interface/protocol over methods on objects. I committed many sins in my past in Python with mixins that added functionality before I understood how to use Zope Interface and with Go it all finally clicked for me. I don't think any pattern is Right all the time but inversion of control and interfaces rarely bite me to the same degree other patterns have.
- thomascgalvin 3y agoI have also moved towards "dumb data objects", immutable if possible, and a library of functions that operate on them. Exactly what this looks like will obviously depend on the language, though. In Java, I might have a Foo object and a FooController. In Kotlin, I'd probably have a Foo object and a FooController file, but that file would contain functions, not a controller object. Of course, in the bytecode this would map to a FooControllerKt object. Kotlin also offers extension functions, which are similar to how Go declares object methods. I use these for utility functions, as opposed to business logic. If I wanted a function to camel-case a string, for example, I'd use an extension function. If I wanted a function to determine if a string is a valid zip code, I'd use a method that takes in a string.
- brabel 3y agoIn Kotlin and Dart, the better way to do it is extension functions. Just having free functions that take your data object as arguments is almost the same, but has the huge disadvantage that looking up which functions you can call on the object is much harder.
- LinXitoW 3y agoThe biggest issue with that is autocompletion in IDEs. I agree that it's nicer "ideologically", but being able to just go "I got this thing, what can I do with it?" with a simple dot is really nice. Maybe LSPs will at some point be easy to query for that.
- lbhdc 3y agoI have really liked dart, and started playing with it when it came out. I just wish I could use it more. Unfortunately it and its tools are so opinionated its kind of hard to use outside of the specific cases they have dreamed of. I really wish there were opt outs, even if it broke things that would be worth it.
- markdog12 3y agoWhich of its tools are opinionated and how? Do you mean the formatter, perhaps?
- lbhdc 3y agoThe one I hate the most is file structure. In order for something to be a "package" it has be be in a `/lib` dir or some other magic name. I wanna nest modules and flatten their structure. If there were a flag to disable this, even if it meant I couldn't use any published third party lib or publish any packages, I would have many many new dart projects. I could probably extend my dislike of this to the entire import system. There are so many aspects of it that I dislike.
- brabel 3y agoThis is one of the weirdest complaints I've ever heard. Almost every language has some sort of requirement for where you put files to properly compose a library. Dart is one of the sanest I know of, just throw your stuff in `lib/mylib.dart`. This file is normally only used to `export` what your lib API should look like, and it's a convention that the implementations go in `lib/src/`. That's all there is! You can break up files apart any way you want from there. To import a file from another file you do `import 'relative/path/to/file.dart`. Dart doesn't care where your imported files are as long as it can find them. There's no "packages" like in Java, but that's never a problem because imports can be named. So you do stuff like: import 'mylib.dart' as mylib; // call mylib function main() => mylib.foo(); So simple, so great... I really can't understand why someone would complain about such an elegant system.
- zengid 3y agoFrom the article: Functional languages generally implement algebraic data types by pattern matching over the cases in a sum type to assign behavior to each variant. Dart 3 achieves the same with pattern matching in switch cases, and takes advantage of the fact that OO subtyping already naturally models sum types. I like that they're saying this part out loud, while languages like C# have been able to do this for years but they never came out and spoke about it in this way. It might have made folks get excited about C# when everyone was really excited about how nice Rust's enums are (they're still exciting to me though).
- sproketboy 3y ago[dead]
- andreypopp 3y agoDoes it (Dart, C#) support exhaustivity checking for such matching over subclasses?
- zengid 3y agoNot sure about Dart, but for C# I don't think it can (due to classes being open by default). If anyone is interested in a deeper dive on C# and adding Discriminated Unions, this interview by Nick Chapsas with Mads Torgersen is a great discussion: https://youtu.be/Nuw3afaXLUc?t=3939 https://youtu.be/Nuw3afaXLUc?t=3939 (note, I'm pretty sure this time stamp is the right part, but the discussion might start before this. I'm at work and can't listen too closely to the video atm).
- zengid 3y agoAfter re-watching, exhaustiveness is not a feature yet. If you look above to munificent's comment, you'll see that Dart has it! very cool!
- munificent 3y agoI don't know about C#, but, yes Dart has quite sophisticated exhaustiveness checking over sealed class hiearchies, including hierarchies that are DAGs and not just trees. It also handles record/tuple types and generics, nested arbitrarily deeply. And patterns that call arbitrary getters on objects. For example, if you have this class hierarchy: sealed class A {} sealed class B1 implements A {} sealed class B2 implements A {} class C1 implements B1 {} class C2 implements B1, B2 {} class C3 implements B2 {} // A // / \ // B1 B2 // / \ / \ // C1 C2 C3 Then it understands that this switch statement is exhaustive: void test(A a1, A a2) { switch ((a1, a2)) { case (A(), C1()): print(1); case (C2(), C2()): print(2); case (C3(), B2()): print(3); case (B1(), B2()): print(4); } } Because they cover the Cartesian product of all possible combinations of subtypes like: a1 A / \ B1 B2 / \ / \ C1 C2 C3 a2 +----+----+----+ C1| 1 | B1< +----+----+----+ A< C2| | 2 | | B2< + +----+ 3 + C3| 4 | | +----+----+----+ This can extend to arbitrary dimensions based on how many record fields there are. Figuring that all out was quite the challenge! The full design is here: https://github.com/dart-lang/language/blob/main/accepted/3.0/patterns/exhaustiveness.md https://github.com/dart-lang/language/blob/main/accepted/3.0...
- pron 3y agoBrian Goetz published a similar article about Java a year ago: https://www.infoq.com/articles/data-oriented-programming-java/ https://www.infoq.com/articles/data-oriented-programming-jav... (taking care not to call it "functional style programming" but rather "data oriented programming")
- dgb23 3y agoThank you for sharing this one! Also there are interesting talks published on YT where he discusses data/functional programming, OOP etc. Multiparadigm (including plain old procedural) seems to be the most pragmatic approach to me, because I don’t need to bend over backwards to express something in a particular way. Aside: It’s really fascinating how Java and the JVM manage to evolve while retaining reliability. He talks about that here: https://youtu.be/2y5Pv4yN0b0 https://youtu.be/2y5Pv4yN0b0
- Daegalus 3y agoI loved Dart, but these days, it's not very usable for me. The backend development capabilities have been left to rot. It's all flutter. When it came out it had so much potential to displace NodeJS. But they threw that away when they couldn't get into the browser and pivoted to flutter. I still maintain some of my packages like uuid, otp, etc. But my API handlers and other backend stuff is kinda dead as there is 0 interest in it nowadays. I would use Deno before Dart for backend nowadays, even though I would prefer Dart.
- Alifatisk 3y agoYea, I see Dart as mostly useful for developing frontends.
- Alifatisk 3y agoAny updates on type union? Using dynamic removes all the type hints. I’d like to statically type which two types a function might return.