lua-users home
lua-l archive

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

On Feb 19, 2012, at 6:50 AM, Xavier Wang wrote:

> hi list, Does anyone knows Scheme?

One of the VLISP authors has released a couple of Lua apps, so there is an existence proof. I forget if he's paying attention to lua-l.

I describe Lua as "it's JavaScript as if redesigned by Scheme programmers, implemented in 100kbytes of ANSI C object code. Oh, and it's at the top of the Language Shootout and it's the most common embedded language in games." At this point some people pull out their smartphones in disbelief, looking for contrary evidence....

> I found a interesting thing:
> does anyone have interest to implement it in Lua?

I suspect there's a translation to coroutines and pcall/error, but it does look like another example of pain by lack of macros and/or concise lambdas. In Lua you'd have to thunk all the arguments to amb. That is, wrap them in lamb--uh, function () expr end.

Continuing with my $"" token filter hack, my cheeseball concise lambda syntax is L$[[1 + %a]]. Since we've sufficiently recovered from the upvalue trauma, it's time for another dose.

Hm, L$[] is an unambiguous parse too, but it's not just a token filter hack.

There's another interesting way to pass lexical values when we know it is in a function invocation context. Following the precedent of "o:m" not having a freestanding value, we use the colon operator to signify this: 

   f:[[ %b ${a}]]

is sugar for:

    f( " %b ${a}", {a=2, b=1}, b, a) 

except the table goes in an anonymous chunk-level table or local, not created fresh on each invocation. If we're going to recapitulate upvalues, we might as well do it efficiently. For diagnostics, maybe throw a debug.getinfo into the table too. Sophisticated versions of f can use the passed table as a key to a weak table caching generated functions. 

Maybe f could use the string as the key, if we are willing to make the mapping from parsed strings to vararg positions deterministic for a compile/run combination. In fact, there's no need to pass the table at all if there's a function which returns {a=2,b=1} the same way the compiler mapped names to argument positions.

This is edging closer and closer to the parts needed for efficient macro systems in the presence of lexical scoping, at least for little languages which have a $- or %-upvalue syntax. For better or worse because we still aren't running code at compile time, we can't syntax-check or generate until run time.

I dunno, now that I'm writing a lot of modern Lua code, I sure seem to spend a lot of time typing "a=a" either in tables or localizers. Flunks DontRepeatYourself in the most trivial way--well, the good news is that we have a decade of experience with 5.x and there are a lot of ways other kinds of repetition have already been done away with. Unfortunately "a=a" is lexical and we can't do anything about it outside the compiler. A codewalker could mechanically generate a "localize a, b, c" line from the global references. Maybe I'll try that someday.

Interestingly, "local a=a" is privately binding a name (often a global), and "{a=a}" is exposing a private binding. They're not the same, they're opposites.