lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Roy [1-3] is a functional, statically typed (Hindley–Milner/ML-style)
language that compiles to JavaScript, and it otherwise preserves
JavaScript semantics in the interest of lightweight output (in
contrast to full-scale OCaml/Haskell -> JavaScript compilers).  Given
that a number of languages compile to JavaScript (like CoffeeScript
and others [4]), some languages compile to Lua (like MoonScript [5]
and others [6]), and the similarities between Lua and JavaScript, it
would be fairly straightforward to implement a Roy-like language in
Lua.  I wonder what others think of the merits of this approach for
Lua.

A useful benchmark may be the success of Roy, but I don't see examples
of non-trivial code implemented in it yet.  As my own test, Appendix 1
shows lua-5.1.5/test/cf.lua manually translated into Roy syntax, which
Roy then automatically translates to JavaScript in Appendix 2.  Other
than the anonymous functions (which are simple to elide) and lack of
string.format (blame JavaScript), there's little overhead.  Other
examples like lua-5.1.5/test/sort.lua (list manipulation) may be
another matter.  To illustrate static type checking, omission of the
last argument to write_temp_table gives the error "Function(Number,
Number, #as) is not Function(Number, Number, Number, Number)".

The topic of static type checking and Lua has come up before [7] but
perhaps with a different emphasis of extending rather than replacing
Lua syntax.  The motivation of course is proactively reducing errors
while preserving the Lua runtime and interoperability with regular Lua
modules (much like F# on .NET).  Simple problems in Lua like static
detection of typos in local variables [8] I consider solved *and then
some* by means of the newer generation of semantic Lua text editors
(e.g. the editor syntax highlights variables by scope and usage), but
more complex analysis is still a challenge without more support from
the language.  That is why the typical suggestion for dynamic
languages has often been greater emphasis on unit testing.

[1] http://brianmckenna.org/blog/roy_ieee
[2] http://roy.brianmckenna.org/
[3] http://guide.roylang.org/
[4] http://altjs.org/
[5] http://moonscript.org/
[6] http://lua-users.org/wiki/LuaImplementations
[7] http://stackoverflow.com/questions/813926/strongly-typed-lua
[8] http://lua-users.org/wiki/DetectingUndefinedVariables

--- Appendix 1 ---

let write s =
  process.stdout.write s

let string_length s =
  (String s).length

let pad acc n =
  if (string_length acc) < n then
    pad (' ' ++ acc) n
  else
    acc

let format (x : Number) =
  let y = (Number x).toFixed 0
  pad y 3

let write_cline c cmax =
  write ( format c )
  write " "
  if c >= cmax then
    0
  else
    write_cline (c + 1) cmax

let write_fline c cmax =
  let f = (9/5)*c + 32
  write ( format f )
  write " "
  if c >= cmax then
    0
  else
    write_fline (c + 1) cmax

let write_temp_table c0 cend cstep =
  write "C "
  write_cline c0 (c0 + 9)
  write "\nF "
  write_fline c0 (c0 + 9)
  write "\n\n"
  if c0 + cstep >= cend then
    0
  else
    write_temp_table (c0 + cstep) cend cstep

let _ = write_temp_table -20 50 10

--- Appendix 2 ---

var write = function(s) {
    return process.stdout.write(s);
};
var string_length = function(s) {
    return String(s).length;
};
var pad = function(acc, n) {
    return (function() {
        if(string_length(acc) < n) {
            return pad((' ' + acc), n);
        } else {
            return acc;
        }
    })();
};
var format = function(x) {
    var y = Number(x).toFixed(0);
    return pad(y, 3);
};
var write_cline = function(c, cmax) {
    write(format(c));
    write(" ");
    return (function() {
        if(c >= cmax) {
            return 0;
        } else {
            return write_cline((c + 1), cmax);
        }
    })();
};
var write_fline = function(c, cmax) {
    var f = (9 / 5) * c + 32;
    write(format(f));
    write(" ");
    return (function() {
        if(c >= cmax) {
            return 0;
        } else {
            return write_fline((c + 1), cmax);
        }
    })();
};
var write_temp_table = function(c0, cend, cstep) {
    write("C ");
    write_cline(c0, (c0 + 9));
    write("\nF ");
    write_fline(c0, (c0 + 9));
    write("\n\n");
    return (function() {
        if(c0 + cstep >= cend) {
            return 0;
        } else {
            return write_temp_table((c0 + cstep), cend, cstep);
        }
    })();
};
var _ = write_temp_table(-20, 50, 10);
//@ sourceMappingURL=dm.js.map