Skip to content

Commit

Permalink
Merge pull request #48 from melange-re/revert-to-51
Browse files Browse the repository at this point in the history
Revert back to OCaml 5.1.1
  • Loading branch information
feihong authored Jun 25, 2024
2 parents c6805bf + 509e725 commit 7a48ad2
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 52 deletions.
2 changes: 1 addition & 1 deletion docs/better-sandwiches/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ chapter.
[^1]: Technically, undeclared variables produce a warning and it's possible to
tell OCaml to not treat them as compilation errors. A common way to do this is
via the [built-in `warning`
attribute](https://v2.ocaml.org/manual/attributes.html#ss:builtin-attributes).
attribute](https://ocaml.org/manual/5.2/attributes.html#ss:builtin-attributes).

[^2]: You may be wondering why a unicorn sandwich costs $80. Well, that is just
the price of ethically-sourced unicorn meat. All the "guests" at the
Expand Down
4 changes: 2 additions & 2 deletions docs/burger-discounts/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ switch (burgers) {
```

OCaml [only allows you to pattern match on arrays of fixed
length](https://v2.ocaml.org/manual/patterns.html#sss:pat-array), so to fix
length](https://ocaml.org/manual/5.2/patterns.html#sss:pat-array), so to fix
this, we must instead match on a tuple of the first and second elements of the
array:

Expand Down Expand Up @@ -546,7 +546,7 @@ and [demo](https://react-book.melange.re/demo/src/burger-discounts/) for this ch

[^1]: The official term for something like `Item.Burger` (module name followed
by value name) is [access
path](https://v2.ocaml.org/manual/names.html#sss:refer-named), but this term
path](https://ocaml.org/manual/5.2/names.html#sss:refer-named), but this term
isn't widely used.

[^2]: Another valid way to discard the return value of a function is:
Expand Down
2 changes: 1 addition & 1 deletion docs/discounts-lists/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ Add this new test to `DiscountTests` and make sure it passes:

Use
[List.filteri](https://melange.re/v4.0.0/api/re/melange/Stdlib/List/#val-filteri)
and [mod operator](https://v2.ocaml.org/manual/expr.html#ss:expr-operators).
and [mod operator](https://ocaml.org/manual/5.2/expr.html#ss:expr-operators).

:::

Expand Down
52 changes: 25 additions & 27 deletions docs/promo-codes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,19 +253,18 @@ instead use a *polymorphic variant*:
<<< Discount.re#get-free-burgers-poly{13-14}

Polymorphic variants are similar to the variants you've seen before, the main
difference being that you don't need to declare the constructors beforehand.
Instead, you can freely use polymorphic variant constructors inside a function,
and the type of the function is inferred from the usage. For example, the type
of `Discount.getFreeBurgers` is now
difference being that you don't need to define the *variant tags* beforehand.
Instead, you can freely use variant tags (like `` `NeedTwoBurgers`` and ``
`NeedOneBurger``) inside a function, and the type of the function is inferred
from the usage. For example, the type of `Discount.getFreeBurgers` is now

```reason
list(Item.t) => result(float, [> `NeedOneBurger | `NeedTwoBurgers ])
```

::: tip

The name of a polymorphic variant constructor must start with the backtick (`` `
``) character.
The name of a variant tag must start with the backtick (`` ` ``) character.

:::

Expand Down Expand Up @@ -293,14 +292,14 @@ list(Item.t) => result(float, [> `NeedMegaBurger ])

## Fixing the tests

Fixing the tests is mostly a mechanical and consists of these steps:
Fixing the tests is mostly a mechanical effort and consists of these steps:

- Replace `Some` with `Ok`
- Replace `None` with ``Error(`SomeConstructor)``
- Replace `None` with ``Error(`SomeTag)``
- Replace `equal` with `deepEqual`

However, there is a little wrinkle. What if you misspell one of the polymorphic
variant constructors?
However, there is a little wrinkle. What if you misspell one of the variant
tags?

```reason{5}
test("1 burger, no discount", () =>
Expand All @@ -315,9 +314,9 @@ The constructor should be called `` `NeedOneBurger`` but here it's been
misspelled as `` `NeedOneBurgers``, yet it still compiles! This is due to the
open-ended nature of polymorphic variants. The compiler knows that
`Discount.getFreeBurgers` currently can't return ``Error(`NeedOneBurgers)``, but
because the constructors for polymorphic variants don't need to be defined
up-front, it has no way to know that the function will **never** return
``Error(`NeedOneBurgers)`` in the future.
because variant tags don't need to be defined up-front, it has no way to know
that the function will **never** return ``Error(`NeedOneBurgers)`` in the
future.

## Runtime representation of polymorphic variants

Expand All @@ -333,12 +332,12 @@ clarity):
+ _0: 'NeedOneBurger'
```

You can see that polymorphic variant constructors without arguments are just
strings in the JS runtime.
You can see that variant tags without arguments are just strings in the JS
runtime.

For reference, the runtime representation for polymorphic variant
constructors with arguments is an object with `NAME` and `VAL` fields. For
example, `` `foo(42)`` becomes `{"NAME": "foo", "VAL": 42}`.
For reference, the runtime representation of a variant tag with an argument is
an object with `NAME` and `VAL` fields. For example, `` `foo(42)`` becomes
`{"NAME": "foo", "VAL": 42}`.

## Variants vs polymorphic variants

Expand Down Expand Up @@ -375,12 +374,11 @@ correctly, so prefer to use the functions in `Js.String`
on a sequence of numbers
- Polymorphic variants are like the variants we've already seen but with some
differences:
- The constructors don't need to defined before they are used
- The constructors must start with the backtick (`` ` ``) character
- A polymorphic variant constructor without arguments becomes a string in the
JS runtime
- A polymorphic variant constructor with argument(s) becomes an object in the
JS runtime. The keys in the object are `NAME` and `VAL`.
- The variant tags don't need to defined before they are used
- A tag must start with the backtick (`` ` ``) character
- A variant tag without arguments becomes a string in the JS runtime
- A variant tag with argument(s) becomes an object in the JS runtime. The keys
in the object are `NAME` and `VAL`.

## Exercises

Expand Down Expand Up @@ -463,6 +461,6 @@ and [demo](https://react-book.melange.re/demo/src/promo-codes/) for this chapter
[^1]: It was quite a sight to see a giant burger zipping around the fairgrounds
on a Segway while being chased by a small army of juggalos.

[^2]: Instead of creating a polymorphic variant constructor out of the phrase
"burger that has every topping", we save ourselves some typing by using the
much shorter "megaburger".
[^2]: Instead of creating a variant tag out of the phrase "burger that has every
topping", we save ourselves some typing by using the much shorter
"megaburger".
27 changes: 13 additions & 14 deletions docs/promo-component/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ In a couple of the documentation comments, you see square brackets (`[]`):

Whatever is inside the brackets gets rendered in a monospace source code font.
This is one example of the [markup
language](https://v2.ocaml.org/releases/5.0/manual/ocamldoc.html#ss:ocamldoc-formatting)
language](https://ocaml.org/manual/5.2/ocamldoc.html#ss:ocamldoc-formatting)
used inside documentation comments.

## `Promo` component
Expand Down Expand Up @@ -364,9 +364,9 @@ of data goes like this:
1. If the result of `discountFunction(items)` is `Ok(value)`, then return
`` `Discount(value)``

Because we use polymorphic variant constructors, we don't need to define a new
type. If you hover over the `discount` variable in your editor you'll see that
its inferred type is:
Because we use polymorphic variant tags, we don't need to define a new type. If
you hover over the `discount` variable in your editor you'll see that its
inferred type is:

```reason
[> `CodeError(Discount.error)
Expand Down Expand Up @@ -436,15 +436,15 @@ occur. In the next chapter, we'll integrate this `Promo` component into your
compatible with your Melange packages
- A good strategy for rendering mutually-exclusive states is to create a single
switch expression that maps your inputs to each state, where each state is
represented by a different polymorphic variant constructor.
represented by a different variant tag.

## Exercises

<b>1.</b> Render the different error messages for the `` `DiscountError`` branch
of `Promo`'s switch expression. Here's what message should be shown for each
constructor:
tag:

| Polymorphic variant constructor | Message |
| Variant tag | Message |
| ------------------------------- | ------- |
| `` `NeedOneBurger`` | Buy at least 1 more burger to enjoy this promotion |
| `` `NeedTwoBurgers`` | Buy at least 1 more burgers to enjoy this promotion |
Expand Down Expand Up @@ -565,18 +565,17 @@ The type signature of `getDiscountFunction` remains unchanged, returning a
function encased in `Ok` when it succeeds. In contrast, `getDiscountPair`
returns a 2-tuple encased in `Ok`:

- The first element of the tuple is a polymorphic variant constructor indicating
which function was returned, e.g. `` `FreeBurger``, `` `HalfOff``, etc.
- The first element of the tuple is a variant tag indicating which function was
returned, e.g. `` `FreeBurger``, `` `HalfOff``, etc.
- The second element of the tuple is the discount function

The polymorphic constructor serves to give test code something to compare
against:
The variant tag serves to give test code something to compare against:

<<< DiscountTests.re#use-discount-function-pair{2-3,20-21}

Recall that the runtime representation of a polymorphic constructor without
arguments is just a string. They can be compared using `Fest.deepEqual` without
any surprises.
Recall that the runtime representation of a variant tag without arguments is
just a string. They can be compared using `Fest.deepEqual` without any
surprises.

Run `npm run test` to verify that all tests are passing again.

Expand Down
6 changes: 3 additions & 3 deletions docs/sandwich-tests/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ Open `melange-for-react-devs.opam` and add a corresponding entry in the

```
depends: [
"ocaml" {>= "5.2.0"}
"ocaml" {>= "5.1.1"}
"reason" {>= "3.10.0"}
"dune" {>= "3.8"}
"melange" {>= "4.0.0-52"}
"melange" {>= "4.0.0-51"}
"reason-react" {>= "0.14.0"}
"reason-react-ppx" {>= "0.14.0"}
"melange-fest" {>= "0.1.0"} // [!code ++]
Expand Down Expand Up @@ -79,7 +79,7 @@ The output will look something like this:

```
# switch compiler description
→ ~/melange-for-react-devs ocaml-base-compiler.5.2.0 ~/melange-for-react-devs
→ ~/melange-for-react-devs ocaml-base-compiler.5.1.1 ~/melange-for-react-devs
default ocaml.5.1.0 default
[NOTE] Current switch has been selected based on the current directory.
Expand Down
2 changes: 1 addition & 1 deletion docs/styling-with-css/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ line to the top of `Order.re`:
```

The `{||}` string literal is known as a [quoted
string literal](https://v2.ocaml.org/manual/lex.html#sss:stringliterals), and it
string literal](https://ocaml.org/manual/5.2/lex.html#sss:stringliterals), and it
is used to represent strings of arbitrary content without escaping[^3]. They are
similar to the `{js||js}` string literals we first saw in the [Celsius
Converter](/celsius-converter-exception/#solutions) chapter, with the difference
Expand Down
4 changes: 2 additions & 2 deletions melange-for-react-devs.opam
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ license: "MIT"
homepage: "https://github.com/melange-re/melange-for-react-devs"
bug-reports: "https://github.com/melange-re/melange-for-react-devs"
depends: [
"ocaml" {>= "5.2.0"}
"ocaml" {>= "5.1.1"}
"reason" {>= "3.10.0"}
"dune" {>= "3.8"}
"melange" {>= "4.0.0-52"}
"melange" {>= "4.0.0-51"}
"reason-react" {>= "0.14.0"}
"reason-react-ppx" {>= "0.14.0"}
"melange-fest" {>= "0.1.0"}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"preinstall:opam": "opam update",
"install:opam": "opam install -y . --deps-only --with-test",
"check-npm-deps": "opam exec opam-check-npm-deps",
"init": "opam switch create . 5.2.0 -y --deps-only && npm run install:npm-opam",
"init": "opam switch create . 5.1.1 -y --deps-only && npm run install:npm-opam",
"install:npm-opam": "npm install && npm run install:opam && npm run check-npm-deps",
"dune": "opam exec -- dune",
"build": "npm run dune -- build",
Expand Down

0 comments on commit 7a48ad2

Please sign in to comment.