44 comments

[ 4.4 ms ] story [ 73.1 ms ] thread
I'm super excited about this release. I've loved pattern matching and tuples for a long long time and I've wanted to bring them to Dart literally since before 1.0.
You and the rest of the team are one of the best parts of the Dart ecosystem. I'm really excited about this release. Thanks for all the hard work.

Also I'm so glad to see that updated long term vision for Dart. I've argued for a while now that it was more constrained than it should be and it was overlooked in a lot of use cases where it was actually a great language choice (i.e I write and run a bunch of cloud native backend services using Dart gRPC and Cloud Run and to me it's one of the best kept secrets about the language). Seeing that public commitment from the team is a big deal and much appreciated.

Appreciate all the hard work, great release. Can't wait for wasm, macros, and inline classes. Macros will be such a game changer, avoiding so much boilerplate you have to go through today.
I'm wondering how garbage collection in WebAssembly is coming along?
It is behind a flag in Chrome Canary, not sure about others.
Firefox also has it behind a flag in about:config, javascript.options.wasm_gc
They should really not publish this on Medium, honestly. Dart/Flutter already have a fairly corporate feel to them, and being on Medium (which, sadly, is very heavyweight and full of self-promotion these days) really makes me feel like this will be a corporate piece, not a technical note.
Huh, I have the opposite reaction. One of Dart's biggest problems is that many people have the impression that Google doesn't take it seriously internally and will abandon it soon. Posting on an external site (weakly) corroborates that.

I associate Medium with small corporations and individuals with an ever-so-slightly scammy hustler vibe, not big corps.

I didn’t have a chance to edit (HN was down) but I meant to mention that this is a fairly nice piece with technical details about some very nice features added to the language.
My understanding is that we use Medium for the blog because it has significantly better discovery metrics than posting it on our own site or under Google's umbrella.
This is really impressive. I’ve never written Dart but this makes me very interested to give it a trial. A sound type system, pattern matching, nice syntax and seemingly solid tooling — why don’t I hear about this more often?

I’ve been working with state charts a lot and being able to target multiple platforms with the same code would make what I’m doing so much more useful. This library seems to support everything I need: https://github.com/rows/automata

Maybe a good side project! Can anyone give reasons why someone should/shouldn’t write Dart (besides a smaller ecosystem)?

>why don’t I hear about this more often?

Honestly, I think it’s just because the language is a solution in search of a problem. It doesn’t do anything significantly better than any other language and so there’s no reason for it to get traction.

I agree it’s pretty decent though, it could have been what Typescript has become but it failed for some reason.

Dart 1.0 was a fully-fledged Java-like type-unsafe OOP thing, released at just the time when such things were becoming unfashionable (for good reasons).

There was clearly a time where Google could have, and should have, killed it, but instead they decided to keep it alive and make it a core part of Flutter (Lord knows what internal politics lead to this decision). It appears that since then, just like Golang, Google has decided to plough incredible resources into turning a bad language into an OKish one. Meanwhile the world moves on.

The flutter site contains a very unconvincing explanation of why it uses Dart [1]. Unconvincing in the sense that the reasons given do not add up to a reason why a very niche language should be kept alive when many other languages would do just fine (Kotlin seems like the most obvious choice).

[1] https://docs.flutter.dev/resources/faq#why-did-flutter-choos...

It seems like your comment and a bunch of the others below it are approximately a decade out of date which is about as old as the language itself just so you know.

A huge amount has changed since then.

We kind of know what internal politics lead to this decision, Dart 1.0 was rescued by Ad Words team, as they had just migrated from GWT into AngularDart as Chrome was ramping down their relation with Dart.

Had it not been for Ad Words team, Dart wouldn't have been used for Flutter.

The reason was because Google at the time wanted to kill JavaScript and Dart was their weapon.

Around that time Google launched a few “initiatives” to build a “better and more efficient” web. AMP was later but the same spirit and of course all of this was a dystopian nightmare so people got scared and mostly ignored Google.

Dart only exists today as an actively developed language because of Flutter.

(comment deleted)
> "The goal of the Dash effort is ultimately to replace JavaScript as the lingua franca of web development on the open web platform. We will proactively evangelize Dash with web developers and all other browser vendors and actively push for its standardization and adoption across the board. This will be a difficult effort requiring finesse and determination, but we are committed to doing everything possible to help it succeed."
The sad thing is, around 2010, most of the JS world (at least JSconf people, which tend to be pretty influential) were interested in Dash as a JS replacement. We were aware of various inconsistencies around typing, Arrays being fancy Objects, the language allowing developers to do weird things rather than warning, type coersion in == etc. There was an appetite for better languages, CoffeeScript was big.

Then they released a 1.0 with zero consultation about what JS developers wanted. Just inflicted by Google as "here's what you'll have". Everyone ignored Dash (and still ignores Dart).

Historically there was always a bit of a funky story about what JS <-> Dart interop looked like that made it not a particularly practical option for most people.

That is about to change however examples here https://youtu.be/yRlwOdCK7Ho 28:30 mark)

But the fact that unlike Typescript it will now also natively target WASM along with the fact that it’s generally a much more pleasant language to use I hope it starts to get much more serious consideration moving forward.

Simple example here looking at Mixins (a fairly basic pattern to describe any kind of a “is-a” rather than a “has-a” relationship in OOP).

Here’s TypeScript

https://media.infosec.exchange/infosecmediaeu/media_attachme...

Here’s Dart https://media.infosec.exchange/infosecmediaeu/media_attachme...

> That is about to change however examples here https://youtu.be/yRlwOdCK7Ho 28:30 mark)

But it doesn't explain what js.window IS. I assume it's implemented via static interop (https://pub.dev/packages/js#staticinterop), but not sure.

Is it out of some secret library they have somewhere, generated from Web IDL? Do I have to implement every function/property on window myself via static interop?

Btw, you can link to youtube with a timestamp: https://youtu.be/yRlwOdCK7Ho?t=1724

Update: I did find this package, which seems to generate bindings from Web IDL: https://pub.dev/packages/js_bindings, but it's not from the Dart team, and prob not what they're using here.

Work on that is happening here https://github.com/dart-lang/web. I expect it will be fully baked by the time Dart 3.1 drops and in-line classes are a thing as it ends up making a big difference as far as I can tell.
Looks like Flutter has been updated as well. I only wish the state management wasn't so convoluted in Flutter
Yes, Google people always have to do some big-brain stuff in their projects.

I’m sure the initial reasons for their state management were valid and their heart was pure, but god damn it’s a mess.

I don’t know if I actually buy this statement at face value.

It mostly extends from the fact that the Flutter community in general is stuck on a perpetual loop talking about it because there is no “one true way blessed by Google wrapped up into a single package that is appropriate for all use cases”.

But in practice it’s exactly the same as any other OOP language or framework where you can pick from multiple paradigms depending on your use case.

Want to use a state machine? There are options for that. Same goes for Rx patterns, local state, redux patterns and more.

There are a lot of extremely complicated apps who don’t have any issue with it in reality and the drama is very much a community problem rather than a real issue.

That too, but the existence of this page: https://docs.flutter.dev/data-and-backend/state-mgmt/options on the official site it's an indication that something's up with state management.

The existence of the Stateless vs Stateful widgets, the "class YourState extends State<>" classes, you can't put a stateful widget inside a stateless widget and a range of many other things that aren't at the top of my mind right now.

Of course that are valid reasons of all of this, of course there are "other better ways", but when a large part of your user base wrestles with this for years, it really doesn't matter how smart and correct you are because it is in fact a problem.

There are ways of handling state - which have been in use for decades! and in applications with a lot of UI state with dozens of forms (screens) etc. How many of them had these convoluted ideas of state vs stateless widgets, watch, notifiers etc? Consider examples like Visual Basic, Delphi etc..

The GUI components would be aware when their state changed and would update its own display. But now you can't do that anymore - either you redraw the whole screen or not at all.

You could receive/send data asynchronously if needed in a separate thread and update the main thread which managed the GUI etc. None of this required jumping through hoops like we are doing now.

Example: This is how data could be fetched asynchronously and the UI updated on termination of the call in Delphi:

procedure TMainForm.ButtonClick(Sender: TObject);

begin

  RESTRequest.ExecuteAsync(

    procedure

    begin

      Memo.Lines.Add(RESTResponse.Content);

    end,

    True, True,

    procedure(Error: TObject)

    begin

      Memo.Lines.Add(Exception(Error).Message);

    end;
end;

Note: even with all of the Pascal ceremony of begin/end etc, this code is more succinct and far cleaner and much easier to debug than the state/stateless nonsense that is spread out all over a Flutter codebase.

And yes, I do remember that Visual C++ had a bit of a convoluted state management logic for MFC.

> applications with a lot of UI state with dozens of forms (screens) etc. How many of them had these convoluted ideas of state vs stateless widgets, watch, notifiers etc? Consider examples like Visual Basic, Delphi etc. ... The GUI components would be aware when their state changed and would update its own display.

I wrote and maintained a lot of large GUI applications in that style during that time, as well as building a couple of GUI frameworks that operated that way.

It's fine for a while and as long as the UI is fairly static and there's mostly a 1:1 mapping between pieces of data and UI that shows it. But it scales horribly once you find yourself in a situation where you have lots of computed model data, or model data that is shown in many places in the UI, or a highly flexible UI that changes a lot. You end up in a sprawling mess of event handlers, orphaned bits of UI that aren't on screen but are still inadvertently listening to events, zombie UI that forgot to register an event handler and isn't updating, computer model state that for now good reason lives inside one random button, and then other UI code that is pulling that state from that button and breaks if the button isn't on screen, etc.

The reactive style / immediate mode style where you essentially redraw the entire UI based on the current model state is so much simpler and cleaner.

Yes, state management can still be weird, but that's because mutable state is hard. There's no silver bullet.

How often do you show multiple screens open to a user at the same time? Even in desktop ERP type software you rarely ever show more than 3 to 4 screens open at a time and how often do these screens all show the EXACT SAME data fields?

How often do you show more than one screen open at a time in a mobile app?

How often would you then need to display the same data field in multiple screens?

I think the state management in mobile apps is extremely over engineered for a use case that rarely ever happens.

Imagine you have a list of items. The list supports multiple selection. Elsewhere on the screen, you have a little box that shows the number of selected items, and the total order price of all of them. Elsewhere, there is an alert that shows up if the total order price is greater than some budget field. There is a button to order the selected items. The button should be disabled if the total price is greater than the budget. The budget amount is also a field that can be edited.

First off, you have to decide where the selection itself is stored. Is whether or not an item is selected "model" state? Or "view model"? If the latter, is there a well defined place where that kind of data is stored or does it literally just list in the list UI element itself? If so, how do all of the other UI elements that need that state get it? Are they directly coupled to the list box?

If a user selects "undo" does that change the selection? Is selecting or unselecting an item and undoable operation or not?

If the back-end server sends an update that some item is no longer available, does the UI handle that appropriately?

When the budget number changes, where does the validation logic to ensure the user chooses a reasonable number live?

This is just a very simple example, but stuff like this comes up all the time and gets gnarly real fast.

I have handled far more complex cases than this using desktop based GUI apps in a client-server model before the word AJAX etc was even invented. Example: dependent dropdowns or even tables with row-selection leading to more detailed views. The ability to display multiple views for the same data type at the same point - example: displaying orders from multiple clients simultaneously in two different sub-screens at the same time.

Also, MVC as a concept has existed for decades. GUI controls have always had a concept of a "onChange" events and when it came to the code which fetches changes from the server, there were multiple ways of handling that - from using polling, to using message queues to using db triggers, from using plain socket calls etc.

And also very sophisticated applications with literally 100s of screens - example: plane/hotel ticketing apps, stock trading applications, ERP/MRP software etc, have all existed for decades.

> And also very sophisticated applications with literally 100s of screens - example: plane/hotel ticketing apps, stock trading applications, ERP/MRP software etc, have all existed for decades.

Yes, and many of those applications are being migrated from an event-based architecture to a reactive one because their authors find them easier to maintain.

This is how flet.dev handles state and UI. Note how simple this is vs the crap that is the standard way of managing state in flutter: By the way, flet.dev is actually using Flutter for rendering!!

def main(page: ft.Page): page.title = "Flet counter example" page.vertical_alignment = ft.MainAxisAlignment.CENTER

    txt_number = ft.TextField(value="0", text_align=ft.TextAlign.RIGHT, width=100)

    def minus_click(e):
        txt_number.value = str(int(txt_number.value) - 1)
        page.update()

    def plus_click(e):
        txt_number.value = str(int(txt_number.value) + 1)
        page.update()

    page.add(
        ft.Row(
            [
                ft.IconButton(ft.icons.REMOVE, on_click=minus_click),
                txt_number,
                ft.IconButton(ft.icons.ADD, on_click=plus_click),
            ],
            alignment=ft.MainAxisAlignment.CENTER,
        )
    )
Are we just debating imperative vs declarative UI patterns? I think that debate was settled a long time ago to be fair.

If you happen to like that approach more that’s cool keep using it but it’s not the done thing in any mainstream modern UI framework that I’m aware of for a reason.

Delphi is still being used. And by the way, there is really no reason to use the complicated state management functions even in a declarative UI pattern
Delphi is most certainly not a solution that anyone is reaching for of any kind of regularity in 2023 but again, if you like it keep using it but I’m more than happy to put Flutter up against Delphi as a way of building user interfaces.
Functional features slowly trickle in after many years.
This is great! Pattern matching (+tuples, records) is going to make conditional rendering, conditional styles and state management even nicer in Flutter. Thank you Dart team.

BTW, all the negative comments I see here seem to come from people who haven't worked with Dart and Flutter which is a cultish reactive showing of `google meh` `apple cool!` sentiment that permeates HN.

If you haven't tried Flutter and Dart give it a good try, it is really nice.