Skip to content
Merged
Show file tree
Hide file tree
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
10 changes: 9 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@ jobs:
- uses: ocaml/setup-ocaml@v2
with:
ocaml-compiler: 4.14.x
dune-cache: true
dune-cache: false # can cause trouble when generating melange docs in step below: https://github.com/ocaml/dune/issues/7720
- name: Install all deps
run: make install
- name: Generate melange docs
run: opam reinstall -y melange --with-doc
- uses: actions/upload-artifact@v3
with:
name: docs
path: _opam/.opam-switch/build/melange.dev/_build/default/_doc/_html/melange
- name: Copy melange docs
run: cp -r _opam/.opam-switch/build/melange.dev/_build/default/_doc/_html docs
- name: Check Reason syntax
run: make check-reason
- name: Build playground
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ _opam
.DS_Store

docs/playground
docs/_html
7 changes: 4 additions & 3 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
Melange exposes three libraries:

- A standard library, which mostly replicates that of OCaml for compatibility;
see the docs: the [`Stdlib`](todo-fix-me.md) library
see the docs: the [`Stdlib`](../_html/melange/Stdlib) library
- Bindings to several browser and Node JavaScript APIs in the [`Js`
library](todo-fix-me.md).
- Data structures and collection types in the [`Belt` library](todo-fix-me.md)
library](../_html/melange/Js).
- Data structures and collection types in the [`Belt`
library](../_html/melange/Belt)

Using one or the other will depend on your application requirements, how much
integration you need with existing JavaScript libraries, or other specific
Expand Down
87 changes: 52 additions & 35 deletions docs/communicate-with-javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,9 @@ class="text-reasonml">\-\></code>.
As its name suggests, the pipe first operator is better suited for functions
where the data is passed as the first argument.

The functions in the [`Belt` library](todo-fix-me.md) included with Melange have
been designed with the data-first convention in mind, so they work best with the
pipe first operator.
The functions in the [`Belt` library](../_html/melange/Belt) included with
Melange have been designed with the data-first convention in mind, so they work
best with the pipe first operator.

For example, we can rewrite the example above using `Belt.List.map` and the pipe
first operator:
Expand Down Expand Up @@ -460,8 +460,8 @@ This is how each Melange type is converted into JavaScript values:
| array | array |
| tuple `(3, 4)` | array `[3, 4]` |
| bool | boolean |
| [Js.Nullable.t](todo-fix-me.md) | `null` / `undefined` |
| [Js.Re.t](todo-fix-me.md) | [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) |
| [Js.Nullable.t](../_html/melange/Js/Nullable) | `null` / `undefined` |
| [Js.Re.t](../_html/melange/Js/Re) | [`RegExp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) |
| Option.t `None` | `undefined` |
| Option.t <code class="text-ocaml">Some( Some .. Some (None))</code><code class="text-reasonml">Some(Some( .. Some(None)))</code> | internal representation |
| Option.t <code class="text-ocaml">Some 2</code><code class="text-reasonml">Some(2)</code> | `2` |
Expand Down Expand Up @@ -576,9 +576,9 @@ You can surround the interpolation variable in parentheses too: `{j|你
好,$(world)|j}`.

To work with strings, the Melange standard library provides some utilities in
the [`Stdlib.String` module](todo-fix-me.md). The bindings to the native
JavaScript functions to work with strings are in the [`Js.String`
module](todo-fix-me.md).
the [`Stdlib.String` module](../_html/melange/Stdlib/String). The bindings to
the native JavaScript functions to work with strings are in the [`Js.String`
module](../_html/melange/Js/String).

#### Floating-point numbers

Expand All @@ -589,8 +589,9 @@ same encoding as [JavaScript
numbers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#number_encoding),
so values of these types can be used transparently between Melange code and
JavaScript code. The Melange standard library provides a [`Stdlib.Float`
module](todo-fix-me.md). The bindings to the JavaScript APIs that manipulate
float values can be found in the [`Js.Float`](todo-fix-me.md) module.
module](../_html/melange/Stdlib/Float). The bindings to the JavaScript APIs that
manipulate float values can be found in the
[`Js.Float`](../_html/melange/Js/Float) module.

#### Integers

Expand All @@ -606,9 +607,9 @@ allowing for a larger range of representable integers in JavaScript compared to
Melange. When dealing with large numbers, it is advisable to use floats instead.
For instance, floats are used in bindings like `Js.Date`.

The Melange standard library provides a [`Stdlib.Int` module](todo-fix-me.md).
The bindings to work with JavaScript integers are in the
[`Js.Int`](todo-fix-me.md) module.
The Melange standard library provides a [`Stdlib.Int`
module](../_html/melange/Stdlib/Int). The bindings to work with JavaScript
integers are in the [`Js.Int`](../_html/melange/Js/Int) module.

#### Arrays

Expand All @@ -618,10 +619,10 @@ arrays, all the values in a Melange array need to have the same type.
Another difference is that OCaml arrays are fixed-sized, but on Melange side
this constraint is relaxed. You can change an array’s length using functions
like `Js.Array.push`, available in the bindings to the JavaScript APIs in
[`Js.Array`](todo-fix-me.md).
[`Js.Array`](../_html/melange/Js/Array).

Melange standard library also has a module to work with arrays, available in
`Stdlib.Array`(todo-fix-me.md) module.
[`Stdlib.Array`](../_html/melange/Stdlib/Array) module.

#### Tuples

Expand Down Expand Up @@ -684,7 +685,7 @@ var r = /b/g;
```

A regular expression like the above is of type `Js.Re.t`. The
[`Js.Re`](todo-fix-me.md) module provides the bindings to the JavaScript
[`Js.Re`](../_html/melange/Js/Re) module provides the bindings to the JavaScript
functions that operate over regular expressions.

## Non-shared data types
Expand All @@ -698,10 +699,11 @@ them before doing so.
[some helpers](#generate-getters-setters-and-constructors) to do so.
- Exceptions
- Option (a variant type): Better use the `Js.Nullable.fromOption` and
`Js.Nullable.toOption` functions in the [`Js.Nullable` module](todo-fix-me.md)
to transform them into either `null` or `undefined` values.
`Js.Nullable.toOption` functions in the [`Js.Nullable`
module](../_html/melange/Js/Nullable) to transform them into either `null` or
`undefined` values.
- List (also a variant type): use `Array.of_list` and `Array.to_list` in the
[`Array` module](todo-fix-me.md).
[`Array` module](../_html/melange/Stdlib/Array).
- Character
- Int64
- Lazy values
Expand All @@ -726,9 +728,9 @@ These attributes are used to annotate `external` definitions:
- [`bs.return`](#wrapping-returned-nullable-values): automate conversion from
nullable values to `Option.t` values
- [`bs.send`](#calling-an-object-method): call a JavaScript object method using
[pipe first](todo-fix-me.md) convention
[pipe first](#pipe-first) convention
- [`bs.send.pipe`](#calling-an-object-method): call a JavaScript object method
using [pipe last](todo-fix-me.md) convention
using [pipe last](#pipe-last) convention
- [`bs.set`](#bind-to-object-properties): set JavaScript object properties
statically by name, using the dot notation `.`
- [`bs.set_index`](#bind-to-object-properties): set JavaScript object properties
Expand Down Expand Up @@ -1354,8 +1356,8 @@ Sometimes JavaScript objects are used as dictionaries. In these cases:

For this particular use case of JavaScript objects, Melange exposes a specific
type `Js.Dict.t`. The values and functions to work with values of this type are
defined in the [`Js.Dict`](todo-fix-me.md) module, with operations like `get`,
`set`, etc.
defined in the [`Js.Dict`](../_html/melange/Js/Dict) module, with operations
like `get`, `set`, etc.

Values of the type `Js.Dict.t` compile to JavaScript objects.

Expand Down Expand Up @@ -1430,7 +1432,7 @@ let () = clearTimeout(id);

> **_NOTE:_** The bindings to `setTimeout` and `clearTimeout` are shown here for
> learning purposes, but they are already available in the
> [`Js.Global`](todo-fix-me.md) module.
> [`Js.Global`](../_html/melange/Js/Global) module.

Generates:

Expand Down Expand Up @@ -2290,10 +2292,14 @@ discarded. The value returned from the operation would not be the addition of
the two numbers, but rather the inner anonymous callback.

To solve this mismatch between OCaml and JavaScript functions and their
application, Melange provides a special attribute `@bs` that can be used to annotate
external functions that need to be "uncurried".
application, Melange provides a special attribute `@bs` that can be used to
annotate external functions that need to be "uncurried".

<span class="text-reasonml">In Reason syntax, this attribute does not need to be written explicitly, as it is deeply integrated with the Reason parser. To specify some function type as "uncurried", one just needs to add the dot character `.` to the function type. For example, `(. 'a, 'b) => 'c` instead of `('a, 'b) => 'c`.</span>
<span class="text-reasonml">In Reason syntax, this attribute does not need to be
written explicitly, as it is deeply integrated with the Reason parser. To
specify some function type as "uncurried", one just needs to add the dot
character `.` to the function type. For example, `(. 'a, 'b) => 'c` instead of
`('a, 'b) => 'c`.</span>

In the example above:

Expand All @@ -2307,7 +2313,12 @@ external map : 'a array -> 'b array -> (('a -> 'b -> 'c)[@bs]) -> 'c array
external map: (array('a), array('b), (. 'a, 'b) => 'c) => array('c) = "map";
```

Here <span class="text-ocaml">`('a -> 'b -> 'c [@bs])`</span><span class="text-reasonml">`(. 'a, 'b) => 'c`</span>will be interpreted as having arity 2. In general, <span class="text-ocaml">`'a0 -> 'a1 ...​ 'aN -> 'b0 [@bs]` is the same as `'a0 -> 'a1 ...​ 'aN -> 'b0`</span><span class="text-reasonml">`. 'a0, 'a1, ...​ 'aN => 'b0` is the same as `'a0, 'a1, ...​ 'aN => 'b0`</span> except the former’s arity is guaranteed to be N while the latter is unknown.
Here <span class="text-ocaml">`('a -> 'b -> 'c [@bs])`</span><span
class="text-reasonml">`(. 'a, 'b) => 'c`</span>will be interpreted as having
arity 2. In general, <span class="text-ocaml">`'a0 -> 'a1 ...​ 'aN -> 'b0 [@bs]`
is the same as `'a0 -> 'a1 ...​ 'aN -> 'b0`</span><span class="text-reasonml">`.
'a0, 'a1, ...​ 'aN => 'b0` is the same as `'a0, 'a1, ...​ 'aN => 'b0`</span>
except the former’s arity is guaranteed to be N while the latter is unknown.

If we try now to call `map` using `add`:

Expand All @@ -2328,7 +2339,8 @@ This expression has type int -> int -> int
but an expression was expected of type ('a -> 'b -> 'c) Js.Fn.arity2
```

To solve this, we add <span class="text-ocaml">`@bs`</span><span class="text-reasonml">`.`</span> in the function definition as well:
To solve this, we add <span class="text-ocaml">`@bs`</span><span
class="text-reasonml">`.`</span> in the function definition as well:

```ocaml
let add = fun [@bs] x y -> x + y
Expand Down Expand Up @@ -2428,12 +2440,13 @@ Note that the first argument will be reserved for `this`.
### Wrapping returned nullable values

JavaScript models `null` and `undefined` differently, whereas it can be useful
to treat both as <span class="text-ocaml">`'a option`</span><span class="text-reasonml">`option('a)`</span> in Melange.
to treat both as <span class="text-ocaml">`'a option`</span><span
class="text-reasonml">`option('a)`</span> in Melange.

Melange understands the `bs.return` attribute in externals to model how
nullable return types should be wrapped at the bindings boundary.
An `external` value with `bs.return` converts the return value to an `option`
type, avoiding the need for extra wrapping / unwrapping with functions such as
Melange understands the `bs.return` attribute in externals to model how nullable
return types should be wrapped at the bindings boundary. An `external` value
with `bs.return` converts the return value to an `option` type, avoiding the
need for extra wrapping / unwrapping with functions such as
`Js.Nullable.toOption`.

```ocaml
Expand Down Expand Up @@ -2476,7 +2489,11 @@ function test($$document) {
}
```

The `bs.return` attribute takes an attribute payload, as seen with <span class="text-ocaml">`[@@bs.return nullable]`</span><span class="text-reasonml">`[@bs.return nullable]`</span> above. Currently 4 directives are supported: `null_to_opt`, `undefined_to_opt`, `nullable` and `identity`.
The `bs.return` attribute takes an attribute payload, as seen with <span
class="text-ocaml">`[@@bs.return nullable]`</span><span
class="text-reasonml">`[@bs.return nullable]`</span> above. Currently 4
directives are supported: `null_to_opt`, `undefined_to_opt`, `nullable` and
`identity`.

`nullable` is encouraged, as it will convert from `null` and `undefined` to
`option` type.
Expand Down
13 changes: 7 additions & 6 deletions docs/melange-for-x-developers.md
Original file line number Diff line number Diff line change
Expand Up @@ -583,8 +583,8 @@ Melange is compatible with the version 4.14 (as of May 2023).

The [Melange
roadmap](https://docs.google.com/document/d/1279euT9LeJIkwAUYqazqeh2lc8c7TLQap2_2vBNcK4w)
for Q2 includes a milestone to upgrade to the latest version of the
compiler to the 5.x release line.
for Q2 includes a milestone to upgrade to the latest version of the compiler to
the 5.x release line.

### Editor integration

Expand Down Expand Up @@ -645,7 +645,8 @@ documented. Reason syntax is no longer supported.

Melange supports and documents both Reason and OCaml syntaxes. It also includes
a best-effort support for ReScript syntax for backwards compatibility, provided
through the `rescript-syntax` package, available [in opam](todo-fix-me.md). To
build any code written using ReScript syntax, the only requirement is to
download this package, as Melange and Dune will already coordinate to make use
of it when `res` or `resi` files are found.
through the `rescript-syntax` package, available [in
opam](https://opam.ocaml.org/packages/rescript-syntax/). To build any code
written using ReScript syntax, the only requirement is to download this package,
as Melange and Dune will already coordinate to make use of it when `res` or
`resi` files are found.
2 changes: 1 addition & 1 deletion mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ nav:
- Reference:
- API: api.md
- Try:
- Playground: playground
- Playground: playground/index.html
- About:
- Community: community.md
- Roadmap: roadmap.md
Expand Down