Javascript (JS) is arguably the most popular programming language on the plant Earth. In this chapter, I plan to demonstrate a style of co-programming with ATS and JS. In practice (of this style of co-programming), ATS is mainly intended for high-level programming (that, for instance, makes extensive use of combinators) and JS for relatively low-level programming (that, for instance, handles direct interactions with the browser running JS code).
Let us take a look at a simple webpage for computing factorials on-line. After inputing a natural number, one can click the Evaluate button to see some output mentioning the factorial of the number. Please find the HTML source for the webpage here. Note that the following JS scripts are needed for evaluating JS code generated from ATS source:
<script type="text/javascript" src="https://ats-lang.github.io/LIBRARY/libatscc2js/ATS2-0.3.2/libatscc2js_all.js"> </script> <script type="text/javascript" src="https://ats-lang.github.io/LIBRARY/libatscc2js/ATS2-0.3.2/libatscc2js_print_store_cats.js"> </script>
As a concrete example, please see the code in Factorial.dats. At the beginning of the file, the following code is present:
which indicates to patsopt that a dynload-function of the name Factorial__dynload is to be generated when the ATS source contained in Factorial.dats is compiled into C. Then this dynload-function is transpiled into JS by atscc2js, and it is supposed to be called first (to perform initialization) before any function in the generated JS code is put into use.The following lines in Factorial.dats are added for accessing the LIBATSCC2JS library, which is needed for compiling ATS to JS:
// #define LIBATSCC2JS_targetloc "$PATSHOME/contrib\ /libatscc2js/ATS2-0.3.2" // #include "{$LIBATSCC2JS}/staloadall.hats" // for prelude stuff #staload "{$LIBATSCC2JS}/SATS/print.sats" // for printing into a store //
In the following code, a function of the name funarg1_get is declared in ATS and implemented in JS:
// extern fun funarg1_get(): int = "mac#" // %{^ function funarg1_get() { return parseInt(document.getElementById("funarg1").value); } %} (* end of external code *) //
The following function is called when the Evaluate button is clicked:
// extern fun Factorial__evaluate ((*void*)): void = "mac#" // implement Factorial__evaluate ((*void*)) = let val () = the_print_store_clear() val arg = funarg1_get() val () = println! ("The factorial of ", arg, " is ", fact(arg)) // end of [val] val theOutput = document_getElementById("theOutput") // end of [val] in xmldoc_set_innerHTML(theOutput, the_print_store_join()) end // end of [Factorial__evaluate] //
For a more involved example, please visit on-line a webpage for animating the process that searches (in the depth-first fashion) for solutions to the 8-queen puzzle. The HTML source for the webpage can be viewed here, and the code implementing depth-first search is simply adapted from some sample ATS code presented in a previous chapter.
Please find on-line the entirety of the code used in this chapter. The mentioned URL link(s) can be found as follows: