lua-users home
lua-l archive

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


Hi David,

Possibly related; what is the state of the type inference logic you've
implemented in lua-inspect? From my reading of the code, you've
attempted to infer the types of values and parameters to assist with
detecting possibly invalid operations (although I haven't seen many
warnings related to that).

I'm not too excited about something like Roy for three (partially
contradictory) reasons:

1. I'm fairly happy with what I already have in Lua; I'll be even
happier camper when some of the type coercion rules go away.

2. I don't see how it helps me with errors like "local foo =
function()...end; do foo = 123 end". This is something that happened
to me at least once when I accidentally assigned something to "next"
without localizing it and it took me a good hour to figure out why my
code suddenly started failing in a completely unrelated module. In
fact, I resorted to "git bisect" to find out what really happened.

3. It doesn't go far enough for me. If we're going to implement some
form of static typing/inference, I'd prefer to see something similar
to F# that includes the notion of units
(http://blogs.msdn.com/b/andrewkennedy/archive/2008/08/29/units-of-measure-in-f-part-one-introducing-units.aspx).

In terms of the actual implementation, it may be interesting to look
at how to implement this as an optional component using static type
inference and hints (possibly in comments to preserve compatibility).

Paul.

P.S. in terms of compiling to JavaScript there is also lua.js
(https://github.com/mherkender/lua.js)

On Mon, Jul 9, 2012 at 10:21 PM, David Manura <dm.lua@math2.org> wrote:
> 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
>