From 25cb86dcc5fc5744a4813ebdba13cdbb4303f0b9 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Thu, 7 Jan 2016 15:05:52 -0500 Subject: [PATCH] Update README.md Improve wording and grammar, properly capitalize project names, correct some typos --- README.md | 147 ++++++++++++++++-------------------------------------- 1 file changed, 44 insertions(+), 103 deletions(-) diff --git a/README.md b/README.md index a8ec7281b0..45af3e9eac 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,12 @@ # OCamlScript ## Introduction -OCamlScript is a Javascript backend for [the OCaml language](https://ocaml.org/) -which aims to provide a better language for the Javascript platform. +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. -One OCaml module is mapped to one JS module, and no name mangling happens -so that: +Each OCaml module is mapped to a corresponding JavaScript module, and names are preserved so that: 1. The stacktrace is preserved, the generated code is debuggable with or without sourcemap. -2. You can call `List.length` (List is a module in OCaml standard library) - in a plain Javascript file. - +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. ### A simple example @@ -23,7 +19,7 @@ let sum n = !v ``` -Generated code is as below: +OCamlScript generates code similar to this: ``` js function sum(n) { @@ -35,45 +31,41 @@ function sum(n) { } ``` -As you can see, there is no name mangling in the generated code, so suppose the -module is called `M`, you can call `M.sub` in vanilla Javascript - -You can learn more by playing the online [in-browser compiler](http://zhanghongbo.me/js-demo). +As you can see, there is no name mangling in the generated code, so if this module is called `M`, +`M.sum()` is directly callable from other JavaScript code. +You can learn more by exploring the online [in-browser compiler](http://zhanghongbo.me/js-demo). ## Disclaimer -This project is currently released to exchange ideas outside -Bloomberg and collect some early feedback from OCaml and Javascript community, -it is in an *very early* stage and not production ready -for your own projects *yet*. +This project has been released to exchange ideas and collect feedback from the OCaml and JavaScript communities. +It is in an *very early* stage and not production ready for your own projects *yet*. ## Build -Note that you have to clone this project with `--recursive` option, we can only distribute -the patch of OCaml due to License restrictions. - +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`. -### Linux and Mac OS +### Linux and Mac OSX 1. Apply the patch to OCaml compiler and build Please ignore the warnings generated by git apply - ``` + ```sh cd ocaml git apply ../js.diff ./configure -prefix `pwd` make world.opt make install ``` + 2. Build OCamlScript Compiler - Assume that you have ocamlopt.opt in the PATH - ``` + Assume that you have `ocamlopt.opt` in the `PATH` + ```sh cd ../jscomp ocamlopt.opt -I +compiler-libs -I bin -c bin/compiler.mli bin/compiler.ml 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. cd ../stdlib make all ``` + 5. Test - We first create a file called `hello.ml`: + Create a file called `hello.ml`: ```sh mkdir tmp # create tmp directory inside the stdlib cd tmp echo 'print_endline "hello world";;' >hello.ml ``` - Then we compiled it with `ocamlscript` + + Then compile it with `ocamlscript` ```sh OCAML_RAW_JS=1 ocamlscript -I . -I ../ -c hello.ml ``` - It should generate a file called `hello.js`, then we runt the `js` file + It should generate a file called `hello.js`, which can be executed with any JavaScript engine. In this example, we use Node.js ```sh node hello.js ``` + If everything goes well, you will see `hello world` on your screen. ## Windows support -We plan to provide a Windows Installer in the near future. +We plan to provide a Windows nstaller in the near future. # Licensing -The [OCaml](./ocaml) directory is a submodule from OCaml's official repo(4.02.3), all its rights -are reserved by [INRIA](http://www.inria.fr/) (see its QPL LICENSE for more details). +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. -Our compiler relies on a patch [(js.diff)](./js.diff) to the OCaml compiler. +The `ocamlscript` backend relies on a patch [(js.diff)](./js.diff) to the OCaml compiler. -This project reused and adapted part of [js_of_ocaml](https://github.com/ocsigen/js_of_ocaml)'s: +This project reused and adapted parts of [js_of_ocaml](https://github.com/ocsigen/js_of_ocaml): * Some small printing utilties in [pretty printer](./jscomp/js_dump.ml). * Part of the [Javascript runtime](./jscomp/runtime) support @@ -145,66 +139,34 @@ JS backend. [stdlib](jscomp/stdlib) is copied from ocaml's [stdlib](ocaml/stdlib) to have it compiled with the new JS compiler. -Since our work is derivative work, we choose the GPL V2 license to -make it compatible with -[js_of_ocaml](http://ocsigen.org/js_of_ocaml/). +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. -Note that QPL license is not compatible with GPL V2, so we distribute -our changes to the compiler as a patch instead. - -## Design goal +## Design goals 1. Readability - 1. No name mangling - 2. Support Javascript modules systems - 3. Integrate with existing javascript ecosystem, for example, + 1. No name mangling. + 2. Support JavaScript module system. + 3. Integrate with existing JavaScript ecosystem, for example, [npm](https://www.npmjs.com/), [webpack](https://github.com/webpack). - 4. Straight-forward FFI, generate tds file to target [Typescript](http://www.typescriptlang.org/) for better tooling + 4. Straight-forward FFI, generate tds file to target [Typescript](http://www.typescriptlang.org/) for better tooling. 2. Separate and *extremely fast* compilation. 3. Better performance than hand-written Javascript: - thanks to a sound type system in OCaml so that we - can play more optimizations and pipe it to Google Closure Compiler - for production mode. + Thanks to the solid type system in OCaml it is possible to optimize the generated JavaScript code. -4. Smaller code than hand written JS code, aggressive dead code elimination. +4. Smaller code than hand written JavaScript, aggressive dead code elimination. -5. Support NodeJs, web browser and various Javascript target platform. +5. Support Node.js, web browsers, and various Javascript target platforms. -6. Compatible with OCaml semantics modulo c-bindings and Obj, Marshal module +6. Compatible with OCaml semantics modulo c-bindings and Obj, Marshal modules. ## More examples -### NodeJS support - -Below it is an idea how it would integrate with the existing JS -eco-system: - -```js - -var $$Array = require('./array'); // OCaml Array module -var List = require ('./list'); // OCaml List module - -List.iter(function(x){console.log('hi, nodejs '+x)}, - $$Array.to_list ($$Array.init(5,function(x){return x}))) -``` - -You get the output: - -```sh -hi, nodejs 0 -hi, nodejs 1 -hi, nodejs 2 -hi, nodejs 3 -hi, nodejs 4 -``` - -### A naive benchmark with Facebook immutable - +### A naive benchmark comparing to the Immutable map from Facebook Below is a *contrived* example to demonstrate our motivation, -it tries to insert 1000,000 keys to an immutable map and query it +it tries to insert 1,000,000 keys into an immutable map, then query it. ```Ocaml module IntMap = Map.Make(struct @@ -226,8 +188,7 @@ let () = test() ``` -This is an equivalent JS version by using Facebook's -[immutable](http://facebook.github.io/immutable-js/) library +The code generated by OCamlScript is a drop-in replacement for the Facebook [immutable](http://facebook.github.io/immutable-js/) library. ``` js @@ -249,20 +210,16 @@ test () ``` Runtime performance: -- OCaml Immutable Map: 1186ms +- OCamlScript Immutable Map: 1186ms - Facebook Immutable Map: 3415ms Code Size: -- OCaml (Prod mode): 899 Bytes +- OCamlScript (Prod mode): 899 Bytes - Facebook Immutable : 55.3K Bytes - ## Status - -It covers the most of OCaml language, given that it is a quite young -project (5 men-months until Jan 2016), there are still plenty of work -to be done. +While most of the OCaml language is covered, because this project is still young there is plenmty of work left to be done. Some known issues are listed as below: @@ -271,9 +228,9 @@ Some known issues are listed as below: Recursive modules, have not looked into it yet. Better Currying support. Currently, we have an inference engine for - function curring and we do cross module inference, however, there + function currying and we do cross module inference, however, there are some more challenging cases, for example, high order functions, - it can be resolved by either aggressive inlining or fall back to a + it can be resolved by either aggressive inlining or falling back to a slow path using `Function.prototype.length`. We prepared the runtime support in [module curry](jscomp/runtime/curry.ml), will support it in the near future. @@ -286,29 +243,13 @@ Some known issues are listed as below: IO support, we have very limited support for `Pervasives.print_endline` and `Pervasives.prerr_endline`, it's non-trivial to preserve the same semantics of IO between OCaml and - NodeJS, one solution is to functorize all IO operations. Functors + Node.js, one solution is to functorize all IO operations. Functors are then inlined so there will no be performance cost or code size penalty. Bigarray, Unix, Num, Int64 -## License - -The OCaml to JS compiler libraries are distributed under the GPL (version 2.0); -see the LICENSE file at the top of the source tree for more information. - - -The contents of some files in this distribution was derived from external -sources with different licenses. The original copyright and license -notice was preserved in the affected files. - ## Question, Comments and Feedback If you have questions, comments, suggestions for improvement or any other inquiries regarding this project, feel free to open an issue in the issue tracker. - - - - - -