---
created_at: '2015-07-26T21:30:25.000Z'
title: SMLtoJs – A Standard ML to JavaScript Compiler (2008)
url: http://www.smlserver.org/smltojs/
author: networked
points: 42
story_text: 
comment_text: 
num_comments: 10
story_id: 
story_title: 
story_url: 
parent_id: 
created_at_i: 1437946225
_tags:
- story
- author_networked
- story_9952256
objectID: '9952256'

---
[Source](http://www.smlserver.org/smltojs/ "Permalink to SMLtoJs - A Standard ML to JavaScript Compiler")

# SMLtoJs - A Standard ML to JavaScript Compiler


| ----- |
|  ![][1]

## A Standard ML to JavaScript Compiler

#### By [Martin Elsman][2], 2008-2015

* * *

### Introduction

SMLtoJs (pronounced "SML toys") is a compiler from Standard ML to JavaScript, which allows programmers to enjoy the power of Standard ML static typing, higher-order functions, pattern matching, and modules for programming client-side web applications. 

SMLtoJs compiles all of Standard ML, including most of the Standard ML Basis Library. It also has support for calling JavaScript functions and for executing plain JavaScript. 

### Features

* **All of Standard ML**. SMLtoJs has support for all of Standard ML, including modules, pattern matching, higher-order functions, generative exceptions, etc.
* **Standard ML Basis Library support.** SMLtoJs has support for most of the Standard ML basis library, including the following structures: `Array2 ArraySlice Array Bool Byte Char CharArray CharArraySlice CharVector CharVectorSlice Date General Int Int31 Int32 IntInf LargeWord ListPair List Math Option OS.Path Pack32Big Pack32Little Random Real StringCvt String Substring Text Time Timer Vector VectorSlice Word Word31 Word32 Word8 Word8Array Word8ArraySlice Word8Vector Word8VectorSlice`. 
* **JavaScript integration**. SMLtoJs has support for calling JavaScript functions and for executing plain JavaScript. Moreover, Standard ML functions may be exported and called by JavaScript code.
* **Simple DOM access**. Simple DOM access and support for installing Standard ML functions as DOM event handlers and timer call back functions.
* **Optimization**. All Standard ML module language constructs, including functors, functor applications, and signature constraints, are eliminated by SMLtoJs at compile time. Moreover, SMLtoJs performs a series of compile time optimizations, including function inlining and specialization of higher-order recursive functions, such as map and foldl. Optimizations can be controlled using compile-time flags. As a result, SMLtoJs generates fairly efficient JavaScript code, although there are rooms for improvements; see below.
* **Reactive Web Programming**. SMLtoJs has library support for Reactive Web Programming. See the [rwp_ex1 example][3] for an introduction to what you can do with this library. The [simple library API][4] captures the basic notions of behaviors and event streams as well as the concepts of behavior transformers and event stream transformers.

### Online Demonstration

To see SMLtoJs in action, click on the examples in the table to the right; there are also links to the Standard ML source code. To learn more about the details of the SMLtoJs implementation, see the [paper][5] presented at PLASTIC'2011. 

### Getting the Sources

SMLtoJs compiles on Debian Linux systems with MLton or MLKit installed. The latest version of the SMLtoJS sources are available through an MLKit github checkout: 
    
    
     $ git clone https://github.com/melsman/mlkit.git smltojs
    

This command copies the sources to the directory smltojs. 

For older (and perhaps more stable) versions of SMLtoJS, you may browse the [list of releases][6]. 

### Building SMLtoJs

To compile SMLtoJs from the sources (MLKit svn checkout; see above), simply type 
    
    
      $ cd smltojs
      $ ./autobuild
      $ ./configure
      $ make smltojs
    

If compilation succeeds, an executable file [`bin/smltojs`][7] should now be available.

### How it Works

The SMLtoJs executable [`bin/smltojs`][7] takes as argument an sml-file (or an mlb-file referencing the sml-files and other mlb-files of the project) and produces an html file called `run.html` provided there are no type errors! The resulting html-file mentions the generated JavaScript files and a file `prims.js`, which contains a set of primitive JavaScript functions used by the generated code. 

Hint: Adding the flag `"-o name"` as command-line argument to [`smltojs`][7] results in the file name.html being generated instead of `run.html`. 

### Testing that it Works

To compile and test the test programs, cd to the `js/test` directory and run `"make clean all"`: 
    
    
     $ cd js/test
     $ make clean all
    

You can now start Firefox on the generated html-files; the file all.html includes links to all the test files: 
    
    
     $ firefox all.html
    

The examples temp.html, counter.html, and life.html are the most interesting examples at the moment (more will come). 

### Issues

Currently, SMLtoJs does not implement tail-calls properly, as all calls are translated into JavaScript calls. We are planning in the near future to implement tail-calls using trampolines. 

There is a known issue with a bug in the following test (in some cases, the implementation pretty prints reals slightly different than suggested by the spec): 
    
    
      real
      ----
       test13c: WRONG
    

There are plenty of possibilities for further improvements, including: 

1. Using numbers to represent constructors (instead of strings).
2. Unboxing of datatypes; currently, a boxed representation is used for lists, for example.

### Copyright and License

SMLtoJs is distributed under the GPL license; see the files in `smltojs/doc/license` for copyright notices and detailed license information. 

 | 

| 

| 

| **News** |  
|  **2013-09-17: **Version 4.3.7 of SMLtoJs is released. |  | | | | 
|  **2011-04-16: **Use [SMLtoJsOnline][8] for compiling and running Standard ML programs in your browser (improved 2013). |  
|  **2010-09-25: **Martin gave a talk at the 2010 ML Workshop on using SMLtoJs for [Hosting a Standard ML Compiler in a Web Browser][9]. |  
|  **2008-08-16: **SMLtoJs **version 4.3.5** is available. |  
|  **2007-11-27: **Martin gave a talk in the DIKU TOPPS group ([slides][10]). |  
|  **2007-09-17: **Martin gave a talk on the PLS Monday lunch meeting ([slides][11]). |  
|  **2007-09-05: **SMLtoJs **version 4.3.4** is available. |  
|  **2007-08-31: **SMLtoJs **version 4.3.3** is available. |  
|  **2007-08-08: **SMLtoJs **version 4.3.2** is available. | 

 | 

 | 

|   | 
| 

| 

| **SMLtoJs Examples** |  
| 

| **program** |  **sources** |  
|  [Ex: rwp_ex1][3]  | [src][12] |  |
|  [Ex: rwp_ex2][13]  | [src][14] | 
|  [Ex: rwp_ex3][15]  | [src][16] | 
|  [Ex: counter][17]  | [src][18] | 
|  [Ex: temp][19]  | [src][20] | 
|  [Ex: life][21]  | [src][22] | 
|  [Ex: cal][23]  | [src][24] | 
|  [Test: array2][25]  | [src][26] | 
|  [Test: int31][27]  | [src][28] | 
|  [Test: int][29]  | [src][30] | 
|  [Test: vectorslice][31]  | [src][32] | 
|  [Test: word8arrayslice][33]  | [src][34] | 
|  [Test: word8vector][35]  | [src][36] | 
|  [Test: arrayslice][37]  | [src][38] | 
|  [Test: general][39]  | [src][40] | 
|  [Test: int32_2][41]  | [src][42] | 
|  [Test: math][43]  | [src][44] | 
|  [Test: stringcvt][45]  | [src][46] | 
|  [Test: testdyn1][47]  | [src][48] | 
|  [Test: vector][49]  | [src][50] | 
|  [Test: word8array][51]  | [src][52] | 
|  [Test: array][53]  | [src][54] | 
|  [Test: int_2][55]  | [src][56] | 
|  [Test: int32][57]  | [src][58] | 
|  [Test: listpair][59]  | [src][60] | 
|  [Test: string][61]  | [src][62] | 
|  [Test: testmatc][63]  | [src][64] | 
|  [Test: word][65]  | [src][66] | 
|  [Test: word8][67]  | [src][68] | 
|  [Test: word31][69]  | [src][70] | 
|  [Test: word32][71]  | [src][72] | 
|  [Test: bytechar][73]  | [src][74] | 
|  [Test: int31_2][75]  | [src][76] | 
|  [Test: intinf][77]  | [src][78] | 
|  [Test: list][79]  | [src][80] | 
|  [Test: real][81]  | [src][82] | 
|  [Test: substring][83]  | [src][84] | 
|  [Test: word8vectorslice][85]  | [src][86] | 
|  [Test: time][87]  | [src][88] | 
|  [Test: date][89]  | [src][90] | 
|  [Test: unixpath][91]  | [src][92] | 
|  [Test: exec][93]  | [src][94] | 
| 

 | 

 | 

 | 

 | 

* * *

[mael@elsman.com][95]

[1]: smltojs_logo_color.png
[2]: http://www.elsman.com
[3]: http://www.smlserver.org/test/rwp_ex1.html
[4]: https://github.com/melsman/mlkit/blob/master/js/basis/RWP.sig
[5]: http://www.elsman.com/pdf/smltojs-final.pdf
[6]: https://github.com/melsman/mlkit/releases
[7]: http://www.smlserver.org/smltojs.man.html
[8]: http://www.smlserver.org/ide
[9]: http://www.elsman.com/pdf/mlwork2010.pdf
[10]: http://www.smlserver.org/slides_diku_2007-11-27.pdf
[11]: http://www.smlserver.org/slides_lunch_2007-09-17.pdf
[12]: https://github.com/melsman/mlkit/blob/master/js/test/rwp_ex1.mlb
[13]: http://www.smlserver.org/test/rwp_ex2.html
[14]: https://github.com/melsman/mlkit/blob/master/js/test/rwp_ex2.mlb
[15]: http://www.smlserver.org/test/rwp_ex3.html
[16]: https://github.com/melsman/mlkit/blob/master/js/test/rwp_ex3.mlb
[17]: http://www.smlserver.org/test/counter.html
[18]: https://github.com/melsman/mlkit/blob/master/js/test/counter.mlb
[19]: http://www.smlserver.org/test/temp.html
[20]: https://github.com/melsman/mlkit/blob/master/js/test/temp.mlb
[21]: http://www.smlserver.org/test/life.html
[22]: https://github.com/melsman/mlkit/blob/master/js/test/life.mlb
[23]: http://www.smlserver.org/test/cal.html
[24]: https://github.com/melsman/mlkit/blob/master/js/test/cal.mlb
[25]: http://www.smlserver.org/test/array2.html
[26]: https://github.com/melsman/mlkit/blob/master/js/test/array2.sml
[27]: http://www.smlserver.org/test/int31.html
[28]: https://github.com/melsman/mlkit/blob/master/js/test/int31.sml
[29]: http://www.smlserver.org/test/int.html
[30]: https://github.com/melsman/mlkit/blob/master/js/test/int.sml
[31]: http://www.smlserver.org/test/vectorslice.html
[32]: https://github.com/melsman/mlkit/blob/master/js/test/vectorslice.sml
[33]: http://www.smlserver.org/test/word8arrayslice.html
[34]: https://github.com/melsman/mlkit/blob/master/js/test/word8arrayslice.sml
[35]: http://www.smlserver.org/test/word8vector.html
[36]: https://github.com/melsman/mlkit/blob/master/js/test/word8vector.sml
[37]: http://www.smlserver.org/test/arrayslice.html
[38]: https://github.com/melsman/mlkit/blob/master/js/test/arrayslice.sml
[39]: http://www.smlserver.org/test/general.html
[40]: https://github.com/melsman/mlkit/blob/master/js/test/general.sml
[41]: http://www.smlserver.org/test/int32_2.html
[42]: https://github.com/melsman/mlkit/blob/master/js/test/int32_2.sml
[43]: http://www.smlserver.org/test/math.html
[44]: https://github.com/melsman/mlkit/blob/master/js/test/math.sml
[45]: http://www.smlserver.org/test/stringcvt.html
[46]: https://github.com/melsman/mlkit/blob/master/js/test/stringcvt.sml
[47]: http://www.smlserver.org/test/testdyn1.html
[48]: https://github.com/melsman/mlkit/blob/master/js/test/testdyn1.sml
[49]: http://www.smlserver.org/test/vector.html
[50]: https://github.com/melsman/mlkit/blob/master/js/test/vector.sml
[51]: http://www.smlserver.org/test/word8array.html
[52]: https://github.com/melsman/mlkit/blob/master/js/test/word8array.sml
[53]: http://www.smlserver.org/test/array.html
[54]: https://github.com/melsman/mlkit/blob/master/js/test/array.sml
[55]: http://www.smlserver.org/test/int_2.html
[56]: https://github.com/melsman/mlkit/blob/master/js/test/int_2.sml
[57]: http://www.smlserver.org/test/int32.html
[58]: https://github.com/melsman/mlkit/blob/master/js/test/int32.sml
[59]: http://www.smlserver.org/test/listpair.html
[60]: https://github.com/melsman/mlkit/blob/master/js/test/listpair.sml
[61]: http://www.smlserver.org/test/string.html
[62]: https://github.com/melsman/mlkit/blob/master/js/test/string.sml
[63]: http://www.smlserver.org/test/testmatc.html
[64]: https://github.com/melsman/mlkit/blob/master/js/test/testmatc.sml
[65]: http://www.smlserver.org/test/word.html
[66]: https://github.com/melsman/mlkit/blob/master/js/test/word.sml
[67]: http://www.smlserver.org/test/word8.html
[68]: https://github.com/melsman/mlkit/blob/master/js/test/word8.sml
[69]: http://www.smlserver.org/test/word31.html
[70]: https://github.com/melsman/mlkit/blob/master/js/test/word31.sml
[71]: http://www.smlserver.org/test/word32.html
[72]: https://github.com/melsman/mlkit/blob/master/js/test/word32.sml
[73]: http://www.smlserver.org/test/bytechar.html
[74]: https://github.com/melsman/mlkit/blob/master/js/test/bytechar.sml
[75]: http://www.smlserver.org/test/int31_2.html
[76]: https://github.com/melsman/mlkit/blob/master/js/test/int31_2.sml
[77]: http://www.smlserver.org/test/intinf.html
[78]: https://github.com/melsman/mlkit/blob/master/js/test/intinf.sml
[79]: http://www.smlserver.org/test/list.html
[80]: https://github.com/melsman/mlkit/blob/master/js/test/list.sml
[81]: http://www.smlserver.org/test/real.html
[82]: https://github.com/melsman/mlkit/blob/master/js/test/real.sml
[83]: http://www.smlserver.org/test/substring.html
[84]: https://github.com/melsman/mlkit/blob/master/js/test/substring.sml
[85]: http://www.smlserver.org/test/word8vectorslice.html
[86]: https://github.com/melsman/mlkit/blob/master/js/test/word8vectorslice.sml
[87]: http://www.smlserver.org/test/time.html
[88]: https://github.com/melsman/mlkit/blob/master/js/test/time.sml
[89]: http://www.smlserver.org/test/date.html
[90]: https://github.com/melsman/mlkit/blob/master/js/test/date.sml
[91]: http://www.smlserver.org/test/unixpath.html
[92]: https://github.com/melsman/mlkit/blob/master/js/test/unixpath.sml
[93]: http://www.smlserver.org/test/exec.html
[94]: https://github.com/melsman/mlkit/blob/master/js/test/exec.mlb.html
[95]: mailto:mael%40elsman.com

