It's important to provide context for why this project was created.
It's sponsored by Roam Research.
Roam Research has a complex web app (a note taking tool) written in Clojure.
They also wanted to build a mobile app for iOS and Android.
So instead of re-implementing everything from scratch in a new language they sponsored this project to compile Clojure to Dart.
That way they can re-use lots of code they've already written for web app and only write mobile front-end once in Flutter (but still in Clojure syntax) and create a mobile app.
This plan worked i.e. they do now have mobile apps for iOS and Android written this way.
I have no inside info so I don't know how much code they could reuse, how easy or not easy it was etc.
It's all based on publicly available information.
The point being: if you don't already have a large Clojure code base you want to reuse, then maybe doing just Dart + Flutter will be easier and faster.
I wonder why they didn’t simply opt to use ClojureScript with React Native. That seems like a much more pragmatic move than creating and supporting your own compiler to Dart just so you can use Flutter.
React Native apps are slow if not engineered well. Naïve implementations of RN apps tend to scale really badly. FB is fixing this with their new architecture (Fabric Render and TurboModule) but the rollout and adoption is even slower than their apps. Flutter on the other hand performs reasonably well (generally speaking) even if you outsource the engineering to the lowest bidder in Eastern Europe or South Asia. Flutter also has better defaults for subtle details like transitions and animations with their material design stack. RN essentially gives you a blank canvas like a web page and YMMV depending on how much design talent your engineering team has. The third party RN design toolkits are rarely up to the standard of Google's massive design team where each pixel and transition is carefully scrutinized across all major platforms. RN is a great tech when you have entire teams of mobile staff engineers and designers. But if you just want to build something quickly that works reasonably well cross-platform, Flutter has the edge here.
I consider it telling that Facebook doesn’t dog food React Native when it comes to their primary source of income (their application or their ads manager depending how you want to look at the problem) but Google Ads is totally done in AngularDart on web and Flutter on mobile.
> Flutter on the other hand performs reasonably well (generally speaking) even if you outsource the engineering to the lowest bidder in Eastern Europe or South Asia.
> "Unfortunately, Flutter is currently a pile of hot garbage from the performance PoV.
> Their own Hello World example, which has one animated button on screen, which updates the label when you press it (see their screenshot) in Release manages to stutter on Moto G7 Power, a phone from 2019. Which smoothly runs quite demanding 3D games.
> According to Android Studio's profiler, about 20% of the frames do not fit into the time slot when the button is pressed. I don't know how did they manage to achieve this with such a trivial example on a Snapdragon 632, but they did it. So, to run smoothly on not-latest phones, your app should somehow be even simpler than their Hello World example, which seems hard to do.
I don’t understand all the marketing hype about Flutter’s good performance. I can often tell an app is written with Flutter just based on how slow it feels on my iPhone 13 Pro. I think the 120 Hz screen doesn’t help, but there are obvious stutters in even simple apps.
If a current generation flagship phone struggles, then I just can’t imagine how a more affordable phone that is a couple years old would fare.
See Google’s own Google Pay app as an example. Its performance is unforgivably bad. Perhaps it runs better on Android, but on iOS it feels bad.
On iOS there are issues with shader compilation that cause stuttering. A fix is being worked on for quite some time now.
The hype around performance is (I think) because it uses lower level rendering stack and a AOT compiler, but the comparision is being made mainly to JavaScript and web stack tech.
It could be fast as rendering speed depends mainly on how quickly can you rasterize and compose the graphic to the canvas. It uses Skia as the graphics backend, but Skia, while being very feature rich, is not the fastest. Dart is also not the fastest language around, but it has a lot of headroom for optimization. I'm also a bit skeptical about the performance impact of the immutable widgets tree, but maybe it doesn't have such a big performance impact as I imagine.
Overall, Flutter has potential to be quite fast. But currently, due to various issues, it's often not. I do love it though, due to how flexible is the rendering and due to the fact there is no markup language. It's really a joy to work with.
ClojureScript maintainers are actively hostile to making runtime errors understandable even if you offer contributions to help. I wouldn’t go back to that ecosystem.
I am one of the co-author of ClojureDart. ClojureDart has been in the making for a year when we met the RoamResearch folks. They provided a definite boost and were bold enough to bet their mobile strategy on it. Its development was not commissioned by Roam though. It’s a project we wanted to work on for a long time and free time during Covid lockdowns helped.
This is very interesting to see, lots of fun use cases with Clojure + Flutter.
> no REPL yet
Seems the most vital part is missing so far, but impressive enough with this first version released. Something I personally I do when hacking on my own lisps (happens too often maybe), is implementing support for the nrepl protocol so I can use neovim + conjure with it as soon as possible, to help further the development of course :)
> When you edit your cljd file, the watcher recompiles cljd files and, on success, hot reloads the application. Sometimes the application may not pick up your change so hit the return key to get the watcher to restart the application.
Is this something specific to ClojureDart, is it because of Dart or because of Flutter? If it's because ClojureDart, it's alright as the project seems to be in early stages, but if it's because of Dart/Flutter it doesn't bode well. I have almost zero experience with either Dart/Flutter so interested to hear where the problem lies.
I haven't looked at ClojureDart, but Flutter/Dart certainly had excellent hot reload, usually maintaining state and so on. Perhaps it's just the immaturity of this project. I do remember the hot reload might not have worked like a file watcher? I vaguely remember I had to integrate a server call into vim or something on save, but it was a while ago.
ClojureDart co-author here. It happens in Dart too. Some changes are not compatible with the current application state. It may occur a bit more frequently because of Clojure being less stringent than dart about giving names to everything (which is tedious but definitely helps with hotreloading).
For those wondering how this is done, it involves: a new Clojure dialect and it's reader, core libs and a compiler.
The reader reads the specific tokens that define the Clojure Dart dialect via the data readers extension mechanism of the standard Clojure reader. Note, this dialect is not strictly compatible with other Clojure dialects, only with Clojure code that is host platform neutral 'pure Clojure', or code that uses dialect 'reader conditionals' to have specialised functionality. This is as it is with Clojurescript, and libraries made cljs friendly will not doubt be trivially made cljd friendly.
The core libs is where the bulk of the work lies, by lines of code at least. core.cljd is 7135 lines, with all the Java-isms (mainly IO, String and Math fns) replaced by Dart wrapper libs. A lot of it, however, is pure Clojure lifted straight from the original. Furthermore, there's a ready-made test suite.
Finally, the compiler. 4000 lines to produce Dart source from AST generated by the standard Clojure reader (but with Dart extensions support via tagged data).
Nice work! I'm actually pretty excited to give this a shot. I like Flutter and Clojure. But writing Dart isn't the most fun thing I can imagine doing. Fun is something I find important in personal projects, but not so much my day to day work. I don't care about the language that pays the bills, the type of projects is way more important there.
>But writing Dart isn't the most fun thing I can imagine doing
I really really do not understand this. Dart 2 is one of the most beautiful languages out there. Dart is a composition of the best parts of python (or maybe ruby?), javascript, c# and java.
Have you actually used Dart on a non-trivial project ? It's boilerplate hell and spaghetti code generator nightmare that works around the nonexistent reflection system and closed object model.
If you look at libraries like built_value and built_collection and think that's beautiful when comparing it with Clojure than I'm sorry but you just don't know what you're talking about. Even the authors of these libraries (AFAIK from the Dart team) acknowledge the design decisions they had to make are a result of language limitations.
IMO it's literally the worst of Java and JavaScript - off the top of my head I've had several cases where I would get runtime exceptions about a type mismatch in a ternary expression that wasn't caught by type-checker, JS style. Type system was very weak in general. And the ammount of boilerplate and code generators I had to work with brought me back to Java 6 days.
TypeScript is miles ahead of Dart in terms of expressiveness and productivity, even when built on a pile of shit that is JS.
Flutter is an interesting project (the asynchronous IPC rendering architecture has some major drawbacks when interoperating with native components), but Dart is hands down the reason I wouldn't touch it in the future unless the team spends some serious effort on language ergonomics.
A decent implementation of Clojure + Flutter would change that equation for me considerably and Clojure would be a really good fit for Flutter.
Not only have used in non trivial situations but 1000% would use again and now consider it my default go to language of choice.
As mentioned elsewhere in this thread it clearly DOES do well at exceptional scale given that the majority of Google’s revenue is all run through Dart. It’s also a really critical part of the new operating system they are currently spending stupid amounts of money building.
It’s funny that you mention TypeScript because for me every time I touch it I wish it was Dart for a million different reasons.
Not sure when the last time you used Dart but some of the things you mentioned gave me the impression it was either a while ago or you were doing some very specific stuff with it. I absolutely do not associate Dart with large amounts of boilerplate and especially not compared to a language like Java.
The package you mentioned built_value was just a clone of auto value in Java and similar to how the language made auto value no longer needed the same is happening in Dart this year as they are bringing in the concept of static metaprogramming to remove the limitations that lead to its initial existence.
I actually think of it as having the best language ergonomics of any C style language I’ve ever seen.
what dart should add a way to automatically understand json and turn it into an object. that would be nice for those of us who don't like creating models
"Beautifulness" of programming languages is so subjective it's hard to have a productive conversation around it.
But I'll bite. Most of the languages you've listed are C-like and all of them have mostly similar syntax and function although the ecosystems are very different. Have you ever experienced larger applications written in completely different class of languages? Languages like various lisps, Prolog, ML and so on.
AngularDart is sadly basically dead these days at least publicly. It still runs all of Google Ads so it’s very well maintained internally I imagine but it’s officially unsupported publicly at this point which I agree is a shame.
Flutter for web is at a weird stage right now. I think once AOM, WASM-GC and WebGPU are in place and well supported across browsers it will be a very different story but thats probably a year or two away at this point.
The public version of AngularDart (i.e. not the one that Google maintains for its internal teams) is in maintenance mode, which is a shame because it was awesome.
Super excited to see this! Clojure is an absolutely delightful language to use professionally (not to mention insanely productive). I've heard great things about Flutter and Dart also from people I trust and admire.
I love LISP but this is too much to digest. Just because you can, you shouldn't do it. Flutter with Dart and component based architecture is still awesome.
What? Is Clojure too much to digest as well? Or ClojureScript? They are basically the same thing as this project, except they compile to JVM/JS code instead of Dart.
> Just because you can, you shouldn't do it.
Fuck that. If you can, have the time and have the resources, go for it! The world will be a better place if you do it and publish whatever comes out of it, success or failure.
It's sponsored by Roam Research.
Roam Research has a complex web app (a note taking tool) written in Clojure.
They also wanted to build a mobile app for iOS and Android.
So instead of re-implementing everything from scratch in a new language they sponsored this project to compile Clojure to Dart.
That way they can re-use lots of code they've already written for web app and only write mobile front-end once in Flutter (but still in Clojure syntax) and create a mobile app.
This plan worked i.e. they do now have mobile apps for iOS and Android written this way.
I have no inside info so I don't know how much code they could reuse, how easy or not easy it was etc.
It's all based on publicly available information.
The point being: if you don't already have a large Clojure code base you want to reuse, then maybe doing just Dart + Flutter will be easier and faster.