File: ppx.wiki

package info (click to toggle)
js-of-ocaml 5.9.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 32,020 kB
  • sloc: ml: 91,250; javascript: 57,289; ansic: 315; makefile: 271; lisp: 23; sh: 6; perl: 4
file content (88 lines) | stat: -rw-r--r-- 2,378 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
= Ppx syntax extension for Js_of_ocaml

To migrate from the camlp4 extension, it is advised to use
[[https://github.com/janestreet/camlp4-to-ppx|camlp4-to-ppx]]
which provides built-in support for Js_of_ocaml syntax.

A ppx rewriter (syntax extension) is available for manipulating object properties,
invoking methods and creating objects.

The syntax and typing rules are as follows:

* Getting a property
{{{
obj : <m : u Js.prop> Js.t
--------------------------
     obj##.m : u
}}}

* Setting a property
{{{
obj : <m : u Js.prop> Js.t
     e : u
--------------------------
  obj##.m := e : unit
}}}

* Invoking a method
{{{
obj : <m : t_1 -> ... -> t_n -> u Js.meth; ..> Js.t
e_i : t_i               (1 <= i <= n)
----------------------------------------------------
        obj##m e_1 ... e_n : u
}}}
For easier chaining, the following alternative syntax is also possible: [ obj##(m e_1 ... e_n) ].

Beware, partial application is not allowed.

* Using an object constructor
{{{
constr : (t_1 -> ... -> t_n -> u Js.t) Js.constr
   e_i : t_i               (1 <= i <= n)
------------------------------------------------
          new%js constr e1 ... en : u Js.t
}}}
[ constr ] here must be an identifier. For constructors
that are not identifiers, bind them first:
<<code language="ocaml"|
  let a = Js.Unsafe.global##.A in
  new%js a
>>

* Creating a literal object
<<code language="ocaml"|
object%js (self) (* Equivalent of this *)
  val x1 = 3 (* read-only prop *)
  val x2 = 3 [@@readonly] (* read-only prop *)

  val mutable y1 = 4 (* read/write prop *)
  val y2 = 4 [@@readwrite] (* read/write prop *)

  val z = 5 [@@writeonly] (* write-only prop *)

  val t1 = Js.undefined [@@jsoo.optdef] (* optdef prop *)

  method foo i = self##.y1 := self##.x1 + i
end
>>

Properties are defined with the [val] keyword. [mutable] makes the
property writable. Properties can be annotated with attributes to change the
default semantic.
Attributes can be one of [readwrite], [readonly], [writeonly],
[optdef].

[self] can be any identifier and will be bind
to [this] in javascript.

In this case, the object has the following type:
<<code language="ocaml"|
    < foo : int -> unit Js.meth;
      t1 : 'a Js.optdef_prop;
      x1 : int Js.readonly_prop;
      x2 : int Js.readonly_prop;
      y1 : int Js.prop;
      y2 : int Js.prop;
      z : int Js.writeonly_prop >
    Js.t
>>