-
Notifications
You must be signed in to change notification settings - Fork 7
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
Update communicate-with-javascript.md #135
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -15,6 +15,8 @@ JavaScript, and the features that Melange exposes to do so. | |||||
|
||||||
### Attributes and extension nodes | ||||||
|
||||||
<!-- | ||||||
|
||||||
In order to interact with JavaScript, Melange needs to extend the language to | ||||||
provide blocks that express these interactions. | ||||||
|
||||||
|
@@ -30,6 +32,8 @@ javascript add : int -> int -> int = {|function(x,y){ | |||||
But this would break compatibility with OCaml, which is one of the main goals of | ||||||
Melange. | ||||||
|
||||||
I would explain this positively instead. Instead of what melange needs to add, can we explain what’s the actual mechanism? Like OCaml with C bindings: https://v2.ocaml.org/manual/intfc.html#:~:text=User primitives are,C-function-name --> | ||||||
|
||||||
Fortunately, OCaml provides mechanisms to extend its language without breaking | ||||||
compatibility with the parser or the language. These mechanisms are composed by | ||||||
two parts: | ||||||
|
@@ -80,7 +84,7 @@ additional information. In Melange, attributes are used in two ways to enhance | |||||
the expressiveness of generating JavaScript code: either reusing existing OCaml | ||||||
built-in attributes or defining new ones. | ||||||
|
||||||
##### Reusing OCaml attributes | ||||||
##### Supported OCaml attributes | ||||||
|
||||||
The first approach is leveraging the existing [OCaml’s built-in | ||||||
attributes](https://v2.ocaml.org/manual/attributes.html#ss:builtin-attributes) | ||||||
|
@@ -117,7 +121,7 @@ var student_name = "alice"; | |||||
Other OCaml pre-built attributes like `alert` or `deprecated` can be used with | ||||||
Melange as well. | ||||||
|
||||||
##### Defining new attributes | ||||||
##### Melange attributes | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that sounds good |
||||||
|
||||||
The second approach is introducing new attributes specifically designed for | ||||||
Melange, such as the [`mel.set` attribute](#bind-to-object-properties) used to | ||||||
|
@@ -919,6 +923,8 @@ function f (x,y) { | |||||
Melange provides a relatively type safe approach to use globals that might be | ||||||
defined either in the JavaScript runtime environment: `mel.external`. | ||||||
|
||||||
<!-- lol, I didn’t know about mel.external. Rather rare considering `external` is a keyword. What about mel.global? --> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you feel strongly about this, it should be an issue in https://github.com/melange-re/melange. There's not much to do from the docs perspective until the renaming is implemented. |
||||||
|
||||||
`[%mel.external id]` will check if the JavaScript value `id` is `undefined` or | ||||||
not, and return an `Option.t` value accordingly. | ||||||
|
||||||
|
@@ -1034,6 +1040,8 @@ JavaScript objects are used in a variety of use cases: | |||||
- As a class. | ||||||
- As a module to import/export. | ||||||
|
||||||
<!-- Mention that Everything in JavaScript is an object --> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you elaborate? Some things in JS are not an object: strings, numbers, booleans,... are primitives: let str = "neal";
str.age = 22;
console.log(str.age); |
||||||
|
||||||
Melange separates the binding methods for JavaScript objects based on these four | ||||||
use cases. This section documents the first three. Binding to JavaScript module | ||||||
objects is described in the ["Using functions from other JavaScript | ||||||
|
@@ -1069,6 +1077,15 @@ type person = { | |||||
}; | ||||||
|
||||||
[@mel.module "MySchool"] external john: person = "john"; | ||||||
(* | ||||||
I would explain how to create a record "manually" and latter as a bind | ||||||
let reason_person = { | ||||||
name: "Javier", | ||||||
friends: [| "David", "Antonio", "Jordi" |], | ||||||
age: 99, | ||||||
}; | ||||||
Comment on lines
+1081
to
+1086
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean, you would swap the order of the sections "Using OCaml records" and "Objects with extensible shape or unknown shape"? |
||||||
|
||||||
*) | ||||||
let john_name = john.name; | ||||||
``` | ||||||
|
||||||
|
@@ -1146,12 +1163,14 @@ var value = [ | |||||
]; | ||||||
``` | ||||||
|
||||||
#### Using `Js.t` objects | ||||||
#### “Objects with extensible shape” or unknown shape? | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👌 |
||||||
|
||||||
Alternatively to records, Melange offers another type that can be used to | ||||||
produce JavaScript objects. This type is `'a Js.t`, where `'a` is an [OCaml | ||||||
object](https://v2.ocaml.org/manual/objectexamples.html). | ||||||
|
||||||
<!-- I would explain the difference here, since it's a source of confusion for some users --> | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are two paragraphs just below that mention the differences:
What other differences do you think we should mention, or in what order? |
||||||
|
||||||
The advantage of objects versus records is that no type declaration is needed in | ||||||
advance, which can be helpful for prototyping or quickly generating JavaScript | ||||||
object literals. | ||||||
|
@@ -1180,7 +1199,7 @@ var john = { | |||||
var t = john.name; | ||||||
``` | ||||||
|
||||||
Note that object types allow for some flexibility that the record types do not | ||||||
Note that Js.t objects types allow for some flexibility that the record types do not | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
have. For example, an object type can be coerced to another with fewer values or | ||||||
methods, while it is impossible to coerce a record type to another one with | ||||||
fewer fields. So different object types that share some methods can be mixed in | ||||||
|
@@ -1442,6 +1461,7 @@ like with objects. But unlike objects, there is no need to add any attributes: | |||||
|
||||||
```ocaml | ||||||
(* Abstract type for `timeoutId` *) | ||||||
(* Explain that abstract type here is a super nicety of abstract types. “We could bind to integer, that would be correct, but by being abstract we ensure more safety and express intentionaly” *) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a whole section for abstract types at the top of the document:
Do you think this addition should be added over there? To have all the info about abstract types upfront, and avoid having to include it in the examples to explain it. |
||||||
type timeoutId | ||||||
external setTimeout : (unit -> unit) -> int -> timeoutId = "setTimeout" | ||||||
external clearTimeout : timeoutId -> unit = "clearTimeout" | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree this is a bit confusing. I would probably remove all of it and just write a small intro saying something like
wdyt?