reasonml/reason

[RFC] What does reason + react native look like?

jaredly opened this issue ยท 15 comments

3 options in my mind

Reason->JS + current React Native

for speed & ease of development, you could compile reason to JS and just interface with react-native as usual

This seems pretty simple to accomplish -- there are a variety of reactjs - ocaml bindings out there, and reason would work just as well. There would be some gymnastics with the react-native bundler, but nothing too difficult I imagine.

Note: need to think about incremental reason adoption in react(native) projects.

Reason->Native + modified React Native

for performance in deployment, you could compile reason to binary (android or ios), and interface with react native without needing a javascript vm. (this brings a large size win on android as well, removing the need to ship JSCore)

This would probably require a fair amount of work on react-native, to enable it to communicate with a binary instead of a js vm.

Reason->Both JS + Native

This would be most complicated, where you compile some things to Native that need lots of speed (animations?), but leave other things compiled to JS so that you can do hot code-pushing to apps.
Not sure if this is at all worth it.

This is nice for greenfield projects, but no existing project is going to drop everything and rewrite everything in Reason. We need a solid migration path. So I like to add existing React app + webpack + Reason.

tbh I would guess that most RN apps are greenfield :D or do you mean web react?

Ah yes, I was thinking of web - however also for native I want a migration path.

(Reason->Native + modified React Native) This would probably require a fair amount of work on react-native, to enable it to communicate with a binary instead of a js vm.

It actually wouldn't be too bad. Currently, the bridge between React and React Native native infra is mostly serializable. That means you can just generate strings and convert those strings from the OCaml runtime/string representation into plain C strings. The cool thing about that, is that on the Reason side, you could be using ocamlopt native, ocaml bytecode with a VM, or compile-to-js, without really having to change much in React Native's side of things. React Native's bridge was designed with this use case in mind, though we never explicitly committed to supporting other languages/runtimes.

Reason->JS + current React Native

Yeah, this would be a great way to get the toolchains in place. You would likely see some improvements in your JS execution speed for things authored in Reason, and compiled with jsoo or bucklescript. Dead code would be better eliminated etc.

Reason->Both JS + Native
This would be most complicated, where you compile some things to Native that need lots of speed (animations?), but leave other things compiled to JS so that you can do hot code-pushing to apps. Not sure if this is at all worth it.

People already want to do this for some things such as css-layout. Reason would be as suitable for this task as using C++ or another ahead of time compiled language. The benefit to using Reason is that you only have to learn one language, but then you can play the role of "JS/app developer", or "native infra developer". You can also reuse libraries on either side of this compilation model.

The downsides to this approach are the same as the downsides to C++. The things you compile to JS do not perfectly interoperate with the things you compile into the native runtime. Imagine that you have a cycle in the memory graph between the two worlds - that would leak. Somewhere in this idea is the glimpse into the ideal, though. Imagine something like a bridge between the JSC VM's collector and ocamlopt's! That would allow you to have perfectly seamless interop between the two - never leaking cycles, but with the ability to compile to either JS, or native for the stuff that matters most (imagine being able to mark the native compilation ability at the granularity of files even!) [@ThisNeedsToBeFastSoToggleNativeCompilation]. Of course, unifying two allocators and collectors is a notoriously difficult task - I've yet to witness it done successfully. But I do believe there's a way to accomplish the goal successfully that would require a larger investment (but with great payoff).

Practically speaking, a good experiment would be to implement the css-layout algorithm in Reason. We've long had a system where we use a hacky regex approach to transform pseudo-js into C. The benefit there is that we can have one canonical implementation that can run in JS, or be compiled into more efficient code ahead of time. But really, isn't that what you can accomplish with Reason + ocamlopt + jsoo/BuckleScript? That's what makes this a good experiment. We can write the layout algorithm in Reason and then measure the benefits of various compilation models. It will be hard to beat raw C performance, but if you write the code imperatively without allocating much (like the C implementation), you may come closer than you'd expect.

I'm about 80% of the way porting the implementation (80% getting it to compile - after that, there will be bugs that need to be worked out). I got distracted somewhat because I wanted it to be as easy as doing npm install reSS, which meant I needed to get the entire compiler toolchain to be installable via npm (which I've done now - try npm install https://github.com/facebook/reason.git and it installs the entire toolchain locally in your node_modules).

@jordwalke reSS: Exciting! I've been toying with the idea of reimplement a boiled down version of React's rendering model to be able to write ios apps more "declaratively" and avoid too much OO (mainly because I find OO harder to read in OCaml).

So I was wondering if there was any progress on this?

@awitherow there has been for

Reason->JS + current React Native

Use:

the bs-react-native readme describes how to get started

Nice @kennetpostigo thanks! So has this issue been "resolved" with the existence of these two libraries @jaredly ?

the first option is working ok, but I'd like to keep this open to explore the possibility of native reason compilation

We were thinking a lot at Callstack about the 2nd option which would bring React Native more to Flutter with Reason running natively w/o Javascript VM.

Is there anyone working or thinking actively about this development? Would love to kickstart pre-preliminary discussions and get this going.

Is there any app in production using Reason and RN? I really love ELM robustness and I wanted to use that for mobile but I also want the reliability that RN project gave me in the last year with my company app. Reason seems like the sweet spot right now.

@grabbou here's the most developed exploration so far https://github.com/pasmomusic/reason-react

We have proper docs at https://github.com/reasonml/reason-react/blob/master/FUTURE-NATIVE.md and such now, so I'll close it here! We can also file such issue in the ReasonReact repo.