Fork me on GitHub
#clojurescript
<
2019-06-30
>
George Ciobanu01:06:53

Hi everyone! I have a question that is a mix of noob and advanced. I'd like to write a Clojure -> Dart compiler. I think I can use the existing CLJS reader as is, the analyzer for CLJS with small changes. and completely rewrite the emitter (to generate Dart instead of JS). Are these assumptions right? If I were to write the emitter, will I also have to reimplement the core persistent collections (PersistentMap/Vector etc) in JS or will the compiler magically translate them from the Clojure implementation? Last question, if I spend time to become intimately acquainted to the inner workings of the analyzer and emitter and put the time to do the work I outlined above, given that I have Clojurescript as a guideline (and can potentially reuse or, more or less, translate the existing logic), is this something I can achieve in 3-6 months or is it a much larger project that will take years? Assuming of course I'm an average developer (whatever that means). For more context as of why I want to do this: I'd like to create a web tool that allows people to visually create a mobile app including the GUI, a predefined set of actions tied to events (e.g. send email, create a new db record, make a UI element invisible). More specifically, I would ideally like to use Hoplon to create this visual tool (Hoplon is a Clojure/script web framework). As for the mobile part, I'd like to use Flutter since it targets both Android and iOS. As a parallel think of http://bubble.is but optimized for mobile. So the dream is that I write Clojure code and it generates Dart code that uses the Flutter framework. This app would then communicate to the backend etc. I am aware that even if I write a compiler I'd have to also create wrappers for any Flutter APIs I want to use from Clojure. Of course if this path is too complicated I can build the web using Hoplon, it creates a datastructure that defines the app, and then I interpret this datastructure in a Flutter app, using an interpreter written in Dart. But I'd really like to stick to writing Clojure as much as possible 🙂

dnolen01:06:13

@geo.ciobanu I'd be skeptical it could be done in 3 months and 6 months is probably generous but does seem possible - you do have a lot of guides to go on

dnolen01:06:29

however I think removing the JS specific bits at this point would probably be a lot of work - we haven't spent much effort keeping those things apart

dnolen01:06:05

(due to the lack of any real value from our perspective)

dnolen01:06:45

the other question is of course how well you want all of this to work - if it's just compiling stuff to Dart then less work - getting all the bits for REPLs to work as expected often ends up being a lot of effort

dnolen01:06:20

fwiw, I do think Clojure on Dart via ClojureScript is an interesting project worth pursuing - but it seems like a big task to me

George Ciobanu01:06:23

@dnolen wow a response from David Nolen himself (blushes). Thank you so much! I don't need the REPL at all and I'm not hung up on doing this via Clojurescript (if there's a better path happy to listen to ideas). I'm processing what you've said and looking through the compiler code again to get a better sense of whether I want/need to do this (which would be hard but so so enjoyable and enlightening) or take she shorter route of building the client side directly in Dart (on Flutter)

dnolen01:06:53

@geo.ciobanu ClojureScript started as a 500 line project written entirely by Rich Hickey and it mostly worked

dnolen01:06:34

it took about 3 months to get most of the standard lib in place - and a couple more to get a usable if extremely simple browser REPL

dnolen01:06:11

ClojureScript is now some 40,000 lines of Clojure

dnolen02:06:32

a lot of that came from implementing all the persistent data structures, moving macros in ClojureScript for bootstrapping, bootstrapping, REPL implementation, REPL integrations, CLI stuff, and tons of tweaks to the compiler for generating more warnings, generating optimizations, and and large number features to enhance usage for end users trying to integrate w/ JS

dnolen02:06:25

so whether your project is reasaonable is mostly dependent on whether you have a good scope for your goals and you leave stuff out that doesn't matter

dnolen02:06:12

FWIW, I think the REPL bit is the thing you probably don't want to drop - and your task is much simpler

dnolen02:06:23

you don't have to support N runtimes/browsers

dnolen02:06:36

you could probably go back to the early stages of the ClojureScript repo and make something that works for you

dnolen02:06:59

stick w/ copy-on-write data structures and decent REPL

dnolen02:06:31

the whole thing could probably done < 2000 LOC for the analyzer/compiler, and then whatever you want for standard lib

dnolen02:06:15

then you have something you can use

dnolen02:06:19

you know 1. make it work 2. make it fast

George Ciobanu02:06:41

thank you so much, grateful for this reply. I do have a clear scope in mind and you give me courage to start with a simple version. One last question (pure curiosity) where are the persistent data structures implemented for CLJS? I looked through the code and could not figure it out (I did find the code for Clojure's implementation in Java). I would expect to find an implementation for cljs.core.PersistentArrayMap.createAsIfByAssoc in JS but not sure where it actually is (and maybe I'm wrong and totally misunderstood how this works)

dnolen02:06:08

ClojureScript isn't written in JS

dnolen02:06:20

ClojureScript has all its data structures written in ClojureScript

George Ciobanu02:06:31

b/c of the bootstrap, I get it

dnolen02:06:48

because no one wants to write JavaScript

👍 24
16
dnolen02:06:14

those data structures preceded bootstrapping by 2 1/2 years or so if not more

dnolen02:06:27

that work was concurrent with a ton of code gen optimization work, since even after they were ported they lagged behind the JS reference implementations

dnolen02:06:34

there's no difference now

dnolen02:06:07

and far as I know we outperform all the comprehensive persistent datastructure JS libs

dnolen02:06:19

by avoiding VM pitfalls like inheritance, excessive polymorphism etc.

dnolen02:06:51

not exactly light reading I must say

George Ciobanu02:06:16

haha if I was expecting easy I shouldn't ask these questions 🙂 Thank you!

dnolen02:06:55

like I said, definitely something I would avoid unless you want to triple the work

👍 4