Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 157 additions & 10 deletions docs/intro/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,153 @@

This is a work in progress.

We'd love to hear your feedback! If you find any errors or have suggestions for
the book, please [file an
issue](https://github.com/ahrefs/melange-for-react-devs/issues) or ping @feihong
on the [#melange channel in the Reason Discord](https://discord.gg/reasonml).

:::

## Motivation
## What is Melange?

Melange is a collection of tools that bring the robustness of a mature,
statically-typed multi-paradigm programming language to the JavaScript
ecosystem. That language is OCaml, a language invented in the 1990s which has
been battle-tested by industry stalwarts. The heart of Melange is (1) a compiler
that translates OCaml to human-readable JavaScript and (2) built-in language
constructs for zero-cost interoperation with JavaScript.

## Why OCaml?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same discussion as ever, but "Why OCaml?" when you will write the book in reason is strange, confusing

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that most of the benefits of Melange come from OCaml, and the book does teach OCaml (using Reason syntax).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait, do you mean Melange in the sense of the subset of OCaml language supported by Melange?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To add my 2 cents: It might be beneficial to just add a quick note that communicates that:

Ocaml = general purpose programming language developed in the 90s (and from my understanding, derived from ML
ReasonML = a set of Ocaml extensions/different way of writing OCaml (this is my understanding as someone with lots of functional JavaScript experience, but not a whole lot of ML experience)

Also note that while we are talking about Ocaml here, the reader can expect to see a lot more ReasonML later.


OCaml codebases scale well both in terms of quantity of lines and number of
contributors. The sound type system helps to prevent ambiguous behavior in your
program---if it compiles, it runs without runtime errors. OCaml and React (via
[ReasonReact][reasonreact]) are an effective, FP-friendly combination for
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick note on how ReasonReact relates to OCaml/ReasonML - it's not clear to me. May not be important at this point, but just a thought.

building frontend UIs using JSX syntax. If the backend is also written in OCaml,
you can share types between the frontend and backend, ensuring that they stay in
sync[^1]. It's even possible to write [universal React
components](https://github.com/ml-in-barcelona/server-reason-react) that are
rendered on the server with the performance of native code[^2].

All that said, how does OCaml compare against other prominent compile-to-JS
languages?

**TypeScript** is a gradually-typed superset of JavaScript. It's easier to learn
and adopt because its design highly emphasizes compatibility with JavaScript.
This brings a few footguns, such as `any`, `as` casting, `ts-nocheck` etc,
making it less type-safe than OCaml (and all the other languages on this list)[^3].

- Zero-cost JS interop? Yes
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe for each of these lists, a quick "Pros and Cons"

- Can use with React? Yes
- Supports JSX? Yes
- Pattern matching? No
- Can use on server? Yes, via Node.

**ReScript** is very similar to OCaml, even at the syntax level. The main
difference is that ReScript's only compilation target is JS[^4].

- Zero-cost JS interop? Yes
- Can use with React? Yes, via [@rescript/react](https://github.com/rescript-lang/rescript-react), which is roughly equivalent to
Melange's ReasonReact bindings.
- Supports JSX? Yes
- Pattern matching? Yes
- Can use on server? Yes, via Node.

**Elm** is similar to OCaml. It leans strongly towards pure functional
programming.

- Zero-cost JS interop? No. Elm treats JavaScript as unsafe, interacting with JS
via ports (more like message passing than traditional FFI). Ergonomic
integration with React and other libraries isn't possible.
- Can use with React? No. Elm has its own framework with some similar concepts.
- Supports JSX? No
- Pattern matching? Yes
- Can use on server? No

**F#** is a fullstack language similar to OCaml and is strongly aligned with the
.NET ecosystem.

- Zero-cost JS interop? Probably
- Can use with React? Yes. [Feliz](https://github.com/Zaid-Ajaj/Feliz) is an F#
wrapper library for React.
- Supports JSX? No. Feliz uses ordinary function call syntax for render logic.
- Pattern matching? Yes
- Can use on server? Yes, via .NET or Node.

**Gleam** is a fullstack language similar to OCaml which is aligned with the
BEAM ecosystem.

- Zero-cost JS interop? No, but Gleam's JS compilation target is relatively new,
so it may become more optimized in the future.
- Can use with React? Yes, via [redraw](https://github.com/ghivert/redraw) and [react-gleam](https://github.com/brettkolodny/react-gleam).
- Supports JSX? No
- Pattern matching? Yes
Comment on lines +35 to +87
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see the point of this section, this is a book of Reason and Melange.

Let's encourage people to read about comparisons in the melange documentation or a blog post.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd kind of lean this way too. It reads a bit like a sales pitch. Maybe at a minimum, cut down on a few of the alternatives.

- Can use on server? Yes, via BEAM or Node.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can use jsx in Fable/Feliz: https://fable.io/blog/2022/2022-10-12-react-jsx.html , it's just that most people use the elm like syntax.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a look at JSX in Fable/Feliz, but the usage doesn't seem ergonomic to me (implemented using string templates). Probably just my opinion, but I don't think it qualifies as "JSX".

This is a project-based, guided introduction to Melange and its ecosystem.
**Kotlin** is a type-safe fullstack language strongly associated with the
Compose Multiplatform UI framework.

- Zero-cost JS interop? Unknown
- Can use with React? Yes.
[Kotlin-react](https://github.com/JetBrains/kotlin-wrappers/blob/master/kotlin-react/README.md)
is a Kotlin wrapper library for React.
- Supports JSX? No. Kotlin-react doesn't support JSX, but it does provide a
declarative syntax that is somewhat similar.
- Pattern matching? No
- Can use on server? Yes, via JVM, Node, or native compilation.

**Dart** is a type-safe fullstack language strongly associated with the Flutter
UI framework, which supports compiling UI apps to mobile, desktop, and browser
environments. There's no Dart wrapper library for modern, functional React
components.

- Zero-cost JS interop? Unknown
- Can use with React? Not really. There's no Dart wrapper library for functional
React components (only [class-based
components](https://github.com/Workiva/react-dart)). Dart users are encouraged
to use [Flutter Web](https://flutter.dev/multi-platform/web) for SPAs.
- Supports JSX? No
- Pattern matching? Yes
- Can use on server? Yes, via Dart VM or Node.

**OCaml** has another JS transpiler called
[js_of_ocaml](https://github.com/ocsigen/js_of_ocaml). Unlike Melange,
js_of_ocaml prioritizes OCaml compatibility over JavaScript interop[^5].

- Zero-cost JS interop? No. Interop with JavaScript involes some overhead.
- Can use with React? Yes, via
[jsoo-react](https://github.com/ml-in-barcelona/jsoo-react), which is roughly
equivalent to Melange's ReasonReact, although it's not as stable and
battle-tested as ReasonReact.
- Supports JSX? No
- Pattern matching? Yes
- Can use on server? Yes, via native compilation or Node

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally I had one paragraph for Rust here, but not sure if it's really in the same space as it compiles to WebAssembly and not normal JS. Should I bring it back?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a comparison to Gleam worthwhile?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And PureScript since it was mentioned in the issue?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@psb Add comparison to Gleam in 4d8e896

I haven't heard much about PureScript in recent years, so I don't think it meets the criteria of "prominent compile-to-JS language".

As you can see, each compile-to-JS language has its own design goals, which
dictate its strengths and weaknesses relative to OCaml and Melange.

If you spot any inaccuracies in this language comparison, please [file an
issue](https://github.com/melange-re/melange-for-react-devs/issues).

## What's in this book

This is a project-based, guided introduction to Melange and its ecosystem,
including ReasonReact, the dune build system, and various useful libraries.
Because Melange uses both OCaml and JavaScript ecosystems, there are quite a few
tools and concepts to learn. Therefore we try to make each chapter small and
digestible, not introducing too many things at once.
digestible, not introducing too many things at once. At the end of each chapter,
you'll find exercises with solutions.

## Audience

You should already know how to make frontend applications in JavaScript, in
particular with [React](https://react.dev/). You should be interested in
learning how to leverage your existing knowledge to build apps using
[ReasonReact](https://reasonml.github.io/reason-react/). You do not need to know
OCaml[^1]---we'll slowly introduce the basics of the language throughout the
tutorial. That said, a good complement to this guide is [OCaml Programming:
Correct + Efficient + Beautiful](https://cs3110.github.io/textbook/), which
teaches the language from the ground up and goes much deeper into its features.
[ReasonReact][reasonreact]. You do not need to know OCaml[^6]---we'll slowly
introduce the basics of the language throughout the tutorial. That said, a good
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably the audience is a bit "informed" about FP

complement to this guide is [OCaml Programming: Correct + Efficient +
Beautiful](https://cs3110.github.io/textbook/), which teaches the language from
the ground up and goes much deeper into its features.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the external resources for further reading!


## Chapters and topics

Expand All @@ -46,8 +174,27 @@ teaches the language from the ground up and goes much deeper into its features.

...and much more to come!

[^1]:
Because of the focus on ReasonReact, we won't cover traditional OCaml
[reasonreact]: https://reasonml.github.io/reason-react/

[^1]: If the backend language isn't OCaml, you can still share types between
frontend and backend through a third-party tool like
[atd](https://github.com/ahrefs/atd).

[^2]: Note that
[server-reason-react](https://github.com/ml-in-barcelona/server-reason-react)
is not yet polished. However, the parts of its API that are more stable are
already used in production by [Ahrefs](https://ahrefs.com/).

[^3]: For a more detailed comparison of Melange and TypeScript, see [Melange
docs](https://melange.re/v4.0.0/melange-for-x-developers#for-typescript-developers).

[^4]: For a more detailed comparison of Melange and ReScript, see [Melange
docs](https://melange.re/v4.0.0/melange-for-x-developers.html#for-rescript-developers).

[^5]: For a more detailed comparison of Melange and js_of_ocaml, see [Melange
docs](https://melange.re/v4.0.0/melange-for-x-developers.html#for-js-of-ocaml-developers).

[^6]: Because of the focus on ReasonReact, we won't cover traditional OCaml
syntax in this guide. Instead, we'll cover the [Reason
syntax](https://reasonml.github.io/) which works great with ReasonReact
because of its first-class support for JSX.