Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add better burgers chapter #21

Merged
merged 5 commits into from
Jan 24, 2024
Merged

Add better burgers chapter #21

merged 5 commits into from
Jan 24, 2024

Conversation

feihong
Copy link
Collaborator

@feihong feihong commented Jan 22, 2024

Overview

  • Record types are like Js.t objects but their fields must be explicitly
    defined

    • Records and Js.t objects are both JavaScript objects during runtime
  • You can get the fields out of a record using destructuring and pattern
    matching:

    • let destructuring:
      let {a, b, c} = record;
    • Switch expression branch pattern matching:
      switch (record) {
      | {a: "foo", b: "bar", c: 42} => "Magnifique!"
      | {a, b, c} => a ++ b ++ string_of_int(c)
      };
  • It's common practice to group related types and functions into a submodule

  • Try not to ignore record fields when pattern matching on records. Instead of

    | {a, b, _} =>

    Prefer

    | {a, b, c: _, d: _} =>

    Assuming c and d aren't used inside the branch.

  • Try not to pattern match on tuples of more than 2 elements because it tends to
    be hard to read

@feihong feihong requested a review from jchavarri January 22, 2024 01:25
@feihong feihong marked this pull request as ready for review January 22, 2024 01:48
See this [playground
snippet](https://melange.re/v2.2.0/playground/?language=Reason&code=Ly8gVXNlIGEgcmFuZG9tIHZhcmlhYmxlIHNvIGZ1bmN0aW9uIGludm9jYXRpb25zIGFyZW4ndCBvcHRpbWl6ZWQgYXdheQpsZXQgYyA9IFJhbmRvbS5pbnQoMTApOwoKbGV0IGFkZCA9ICh4LCB5LCB6KSA9PiB4ICsgeSArIHo7CkpzLmxvZyhhZGQoMSwgMiwgYykpOwoKLy8gQW4gZXF1aXZhbGVudCBkZWZpbml0aW9uIHRoYXQgZXhwbGljaXRseSByZXR1cm5zIGZ1bmN0aW9uczoKbGV0IHJlYWxBZGQgPSB4ID0%2BIHkgPT4geiA9PiB4ICsgeSArIHo7CkpzLmxvZyhyZWFsQWRkKDEsIDIsIGMpKTsKLy8gQ29uY2VwdHVhbGx5LCB0aGVyZSBhcmUgbXVsdGlwbGUgZnVuY3Rpb24gZGVmaW5pdGlvbnM6CkpzLmxvZyhyZWFsQWRkKDEpKDIpKGMpKTs%3D&live=off)
for an extended example and the [official OCaml
docs](https://ocaml.org/docs/values-and-functions#types-of-functions-of-multiple-parameters)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure if there's a better link that explains multiple argument functions

Copy link
Member

@jchavarri jchavarri left a comment

Choose a reason for hiding this comment

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

Looks awesome!

I wonder if the intro section with "Chapters and topics" should be updated? The table last item is "Styling with CSS":

| Styling with CSS | Styling the order confirmation using CSS | `mel.raw` extension node, `runtime_deps` field, `glob_files` term, `external`, `mel.module` attribute |

docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
Copy link
Collaborator Author

@feihong feihong left a comment

Choose a reason for hiding this comment

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

I wonder if the intro section with "Chapters and topics" should be updated? The table last item is "Styling with CSS"

I plan to update Chapters and topics table in a separate PR

docs/better-burgers/index.md Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved

The compiler wouldn't complain but the ensuing logic would likely be wrong.

The best approach here is to use the record itself as the input to the switch
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 can't find our previous thread about this (maybe it was somewhere in this old PR?), but I decided to go with switch expression without the backticks since it's more of a concept than just syntax, same as how I write if-else, ternary, etc without the backticks.

In mainstream languages that have pattern matching (C#, Swift, Java) they've mostly settled on calling this "switch". Python is the only mainstream language I know of which uses "match". But since "switch" is kind of an overloaded term, maybe I should use "pattern match expression" instead?

docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
docs/better-burgers/index.md Outdated Show resolved Hide resolved
@feihong feihong requested a review from jchavarri January 24, 2024 04:05

| Name | Type | Meaning |
| ---- | ---- | ------- |
| lettuce | bool | if `true`, include lettuce |
Copy link
Member

Choose a reason for hiding this comment

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

nit: maybe this should be either

  • bool
    or
  • boolean
    ?

Same with int: either int or integer. 🤔

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 opted to just put the field names and types in backticks in ad5f959

a number of syntactic and practical differences between them:

- Record fields must be predefined
- Records use `.` to access fields
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
- Records use `.` to access fields
- Records use `.` to access fields, while `Js.t` values use `##`

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in ad5f959


- Record fields must be predefined
- Records use `.` to access fields
- Records can be destructured and pattern matched)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
- Records can be destructured and pattern matched)
- Records can be destructured and pattern matched

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in ad5f959

Comment on lines 35 to 40
- Record use [nominal
typing](https://en.wikipedia.org/wiki/Nominal_type_system), while `Js.t`
objects use [structural
typing](https://en.wikipedia.org/wiki/Structural_type_system). This means that
two record types with exactly the same fields are still considered different
types.
Copy link
Member

Choose a reason for hiding this comment

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

This is great 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants