Skip to content

Commit 276f8dc

Browse files
committed
Merge pull request #1 from bloomberg/readme-cleanup
Update README.md
2 parents 5679668 + 25cb86d commit 276f8dc

File tree

1 file changed

+44
-103
lines changed

1 file changed

+44
-103
lines changed

README.md

Lines changed: 44 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
# OCamlScript
22

33
## Introduction
4-
OCamlScript is a Javascript backend for [the OCaml language](https://ocaml.org/)
5-
which aims to provide a better language for the Javascript platform.
4+
OCamlScript is a JavaScript backend for [the OCaml compiler](https://ocaml.org/). Users of OCamlScript can write type-safe, high performance OCaml code, and deploy the generated JavaScript in any platform with a JavaScript execution engine.
65

7-
One OCaml module is mapped to one JS module, and no name mangling happens
8-
so that:
6+
Each OCaml module is mapped to a corresponding JavaScript module, and names are preserved so that:
97

108
1. The stacktrace is preserved, the generated code is debuggable with or without sourcemap.
11-
2. You can call `List.length` (List is a module in OCaml standard library)
12-
in a plain Javascript file.
13-
9+
2. Modules generated by OCamlScript can be used directly from other JavaScript code. For example, you can call the `List.length` function from the OCaml standard library `List` module from JavaScript.
1410

1511
### A simple example
1612

@@ -23,7 +19,7 @@ let sum n =
2319
!v
2420
```
2521

26-
Generated code is as below:
22+
OCamlScript generates code similar to this:
2723

2824
``` js
2925
function sum(n) {
@@ -35,45 +31,41 @@ function sum(n) {
3531
}
3632
```
3733

38-
As you can see, there is no name mangling in the generated code, so suppose the
39-
module is called `M`, you can call `M.sub` in vanilla Javascript
40-
41-
You can learn more by playing the online [in-browser compiler](http://zhanghongbo.me/js-demo).
34+
As you can see, there is no name mangling in the generated code, so if this module is called `M`,
35+
`M.sum()` is directly callable from other JavaScript code.
4236

37+
You can learn more by exploring the online [in-browser compiler](http://zhanghongbo.me/js-demo).
4338

4439

4540
## Disclaimer
4641

47-
This project is currently released to exchange ideas outside
48-
Bloomberg and collect some early feedback from OCaml and Javascript community,
49-
it is in an *very early* stage and not production ready
50-
for your own projects *yet*.
42+
This project has been released to exchange ideas and collect feedback from the OCaml and JavaScript communities.
43+
It is in an *very early* stage and not production ready for your own projects *yet*.
5144

5245

5346
## Build
5447

55-
Note that you have to clone this project with `--recursive` option, we can only distribute
56-
the patch of OCaml due to License restrictions.
57-
48+
Note that you have to clone this project with `--recursive` option, as the core OCaml compiler is brought into your clone as a Git `submodule`.
5849

59-
### Linux and Mac OS
50+
### Linux and Mac OSX
6051

6152

6253
1. Apply the patch to OCaml compiler and build
6354

6455
Please ignore the warnings generated by git apply
6556

66-
```
57+
```sh
6758
cd ocaml
6859
git apply ../js.diff
6960
./configure -prefix `pwd`
7061
make world.opt
7162
make install
7263
```
64+
7365
2. Build OCamlScript Compiler
7466

75-
Assume that you have ocamlopt.opt in the PATH
76-
```
67+
Assume that you have `ocamlopt.opt` in the `PATH`
68+
```sh
7769
cd ../jscomp
7870
ocamlopt.opt -I +compiler-libs -I bin -c bin/compiler.mli bin/compiler.ml
7971
ocamlopt.opt -g -linkall -o bin/ocamlscript -I +compiler-libs ocamlcommon.cmxa ocamlbytecomp.cmxa bin/compiler.cmx main.cmx
@@ -94,39 +86,41 @@ the patch of OCaml due to License restrictions.
9486
cd ../stdlib
9587
make all
9688
```
89+
9790
5. Test
9891

99-
We first create a file called `hello.ml`:
92+
Create a file called `hello.ml`:
10093

10194
```sh
10295
mkdir tmp # create tmp directory inside the stdlib
10396
cd tmp
10497
echo 'print_endline "hello world";;' >hello.ml
10598
```
106-
Then we compiled it with `ocamlscript`
99+
100+
Then compile it with `ocamlscript`
107101
```sh
108102
OCAML_RAW_JS=1 ocamlscript -I . -I ../ -c hello.ml
109103
```
110104

111-
It should generate a file called `hello.js`, then we runt the `js` file
105+
It should generate a file called `hello.js`, which can be executed with any JavaScript engine. In this example, we use Node.js
112106

113107
```sh
114108
node hello.js
115109
```
110+
116111
If everything goes well, you will see `hello world` on your screen.
117112

118113
## Windows support
119114

120-
We plan to provide a Windows Installer in the near future.
115+
We plan to provide a Windows nstaller in the near future.
121116

122117
# Licensing
123118

124-
The [OCaml](./ocaml) directory is a submodule from OCaml's official repo(4.02.3), all its rights
125-
are reserved by [INRIA](http://www.inria.fr/) (see its QPL LICENSE for more details).
119+
The [OCaml](./ocaml) directory is the official OCaml compiler (version 4.02.3). Refer to its copyright and license notices for information about its licensing.
126120

127-
Our compiler relies on a patch [(js.diff)](./js.diff) to the OCaml compiler.
121+
The `ocamlscript` backend relies on a patch [(js.diff)](./js.diff) to the OCaml compiler.
128122

129-
This project reused and adapted part of [js_of_ocaml](https://github.com/ocsigen/js_of_ocaml)'s:
123+
This project reused and adapted parts of [js_of_ocaml](https://github.com/ocsigen/js_of_ocaml):
130124
* Some small printing utilties in [pretty printer](./jscomp/js_dump.ml).
131125
* Part of the [Javascript runtime](./jscomp/runtime) support
132126

@@ -145,66 +139,34 @@ JS backend.
145139
[stdlib](jscomp/stdlib) is copied from ocaml's [stdlib](ocaml/stdlib) to have it compiled with
146140
the new JS compiler.
147141

148-
Since our work is derivative work, we choose the GPL V2 license to
149-
make it compatible with
150-
[js_of_ocaml](http://ocsigen.org/js_of_ocaml/).
142+
Since our work is derivative work of [js_of_ocaml](http://ocsigen.org/js_of_ocaml/), the license of the OCamlScript components is GPLv2, the same as js_of_ocaml.
151143

152-
Note that QPL license is not compatible with GPL V2, so we distribute
153-
our changes to the compiler as a patch instead.
154-
155-
## Design goal
144+
## Design goals
156145

157146
1. Readability
158-
1. No name mangling
159-
2. Support Javascript modules systems
160-
3. Integrate with existing javascript ecosystem, for example,
147+
1. No name mangling.
148+
2. Support JavaScript module system.
149+
3. Integrate with existing JavaScript ecosystem, for example,
161150
[npm](https://www.npmjs.com/), [webpack](https://github.com/webpack).
162-
4. Straight-forward FFI, generate tds file to target [Typescript](http://www.typescriptlang.org/) for better tooling
151+
4. Straight-forward FFI, generate tds file to target [Typescript](http://www.typescriptlang.org/) for better tooling.
163152

164153
2. Separate and *extremely fast* compilation.
165154

166155
3. Better performance than hand-written Javascript:
167-
thanks to a sound type system in OCaml so that we
168-
can play more optimizations and pipe it to Google Closure Compiler
169-
for production mode.
156+
Thanks to the solid type system in OCaml it is possible to optimize the generated JavaScript code.
170157

171-
4. Smaller code than hand written JS code, aggressive dead code elimination.
158+
4. Smaller code than hand written JavaScript, aggressive dead code elimination.
172159

173-
5. Support NodeJs, web browser and various Javascript target platform.
160+
5. Support Node.js, web browsers, and various Javascript target platforms.
174161

175-
6. Compatible with OCaml semantics modulo c-bindings and Obj, Marshal module
162+
6. Compatible with OCaml semantics modulo c-bindings and Obj, Marshal modules.
176163

177164
## More examples
178165

179-
### NodeJS support
180-
181-
Below it is an idea how it would integrate with the existing JS
182-
eco-system:
183-
184-
```js
185-
186-
var $$Array = require('./array'); // OCaml Array module
187-
var List = require ('./list'); // OCaml List module
188-
189-
List.iter(function(x){console.log('hi, nodejs '+x)},
190-
$$Array.to_list ($$Array.init(5,function(x){return x})))
191-
```
192-
193-
You get the output:
194-
195-
```sh
196-
hi, nodejs 0
197-
hi, nodejs 1
198-
hi, nodejs 2
199-
hi, nodejs 3
200-
hi, nodejs 4
201-
```
202-
203-
### A naive benchmark with Facebook immutable
204-
166+
### A naive benchmark comparing to the Immutable map from Facebook
205167

206168
Below is a *contrived* example to demonstrate our motivation,
207-
it tries to insert 1000,000 keys to an immutable map and query it
169+
it tries to insert 1,000,000 keys into an immutable map, then query it.
208170

209171
```Ocaml
210172
module IntMap = Map.Make(struct
@@ -226,8 +188,7 @@ let () = test()
226188
227189
```
228190

229-
This is an equivalent JS version by using Facebook's
230-
[immutable](http://facebook.github.io/immutable-js/) library
191+
The code generated by OCamlScript is a drop-in replacement for the Facebook [immutable](http://facebook.github.io/immutable-js/) library.
231192

232193

233194
``` js
@@ -249,20 +210,16 @@ test ()
249210
```
250211

251212
Runtime performance:
252-
- OCaml Immutable Map: 1186ms
213+
- OCamlScript Immutable Map: 1186ms
253214
- Facebook Immutable Map: 3415ms
254215

255216
Code Size:
256-
- OCaml (Prod mode): 899 Bytes
217+
- OCamlScript (Prod mode): 899 Bytes
257218
- Facebook Immutable : 55.3K Bytes
258219

259-
260220
## Status
261221

262-
263-
It covers the most of OCaml language, given that it is a quite young
264-
project (5 men-months until Jan 2016), there are still plenty of work
265-
to be done.
222+
While most of the OCaml language is covered, because this project is still young there is plenmty of work left to be done.
266223

267224
Some known issues are listed as below:
268225

@@ -271,9 +228,9 @@ Some known issues are listed as below:
271228
Recursive modules, have not looked into it yet.
272229

273230
Better Currying support. Currently, we have an inference engine for
274-
function curring and we do cross module inference, however, there
231+
function currying and we do cross module inference, however, there
275232
are some more challenging cases, for example, high order functions,
276-
it can be resolved by either aggressive inlining or fall back to a
233+
it can be resolved by either aggressive inlining or falling back to a
277234
slow path using `Function.prototype.length`. We prepared the
278235
runtime support in [module curry](jscomp/runtime/curry.ml), will support it in the near
279236
future.
@@ -286,29 +243,13 @@ Some known issues are listed as below:
286243
IO support, we have very limited support for
287244
`Pervasives.print_endline` and `Pervasives.prerr_endline`, it's
288245
non-trivial to preserve the same semantics of IO between OCaml and
289-
NodeJS, one solution is to functorize all IO operations. Functors
246+
Node.js, one solution is to functorize all IO operations. Functors
290247
are then inlined so there will no be performance cost or code size
291248
penalty.
292249

293250
Bigarray, Unix, Num, Int64
294251

295-
## License
296-
297-
The OCaml to JS compiler libraries are distributed under the GPL (version 2.0);
298-
see the LICENSE file at the top of the source tree for more information.
299-
300-
301-
The contents of some files in this distribution was derived from external
302-
sources with different licenses. The original copyright and license
303-
notice was preserved in the affected files.
304-
305252
## Question, Comments and Feedback
306253

307254
If you have questions, comments, suggestions for improvement or any other inquiries
308255
regarding this project, feel free to open an issue in the issue tracker.
309-
310-
311-
312-
313-
314-

0 commit comments

Comments
 (0)