lua-users home
lua-l archive

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

On Wed, May 6, 2009 at 3:42 AM, steve donovan wrote:
> Absolutely; no way to make duck-typing seamless with built-in types.

Apart from some patch that would make standard types truly virtualizable.

> Since Metalua operates with the AST of the source, it may be
> possible to rewrite expressions like:
>    s:upper():trim() into: stringx.trim(s.upper())  [sic]
> A smart implementation would also create local aliases into the module
> scope, so the resulting code becomes truly optimal...
>   local trim,upper = stringx.trim, string.upper
>   function trim_upper() return upper(trim(s)) end
> this kind of thing possible with Metalua?  I guess one
> would need some kind of static type annotation to give enough clues to
> the compiler, however.

It's very do-able.  Automatic local aliasing has been done in metalint
[1] included in Metalua. However, as you say, it may in the general
case require some annotations (pragmas, keywords, or comments) in the
code to assert to the compiler/translator when it is safe to output
more efficient code.  The annotation doesn't necessarily require
describing the type of each individual variable but could be something
as simple as asserting "all accesses to global functions in this file
are what they appear to be" -- e.g. occurrences of "string.find" refer
to the same string.find documented in the Lua reference manual.  I've
used a form of annotations embedded in Lua comments and applied
lexically, with the help of Metalua parsing, in luaanalyze [2] as well
as in an experimental version of lua2c [3] that code generates more
optimally when types are known (e.g. using real doubles on the C stack
when Lua values are known to be numbers).  This seemed simpler and
more practical than trying to infer this information automatically via
data flow analysis [4-5] in special cases (I still think the latter
would be neat, but perhaps using some existent tool like LLVM would be

You've also, perhaps unintentionally, hinted that the translator may
be free to commute the upper and trim operations: s:upper():trim() ==
s:trim():upper(), the latter possibly being slightly more efficient.

Often, we are more worried about readability/correctness/simplicity
than performance.  The Metalua code in my last post implemented the
general case without optimizing.