[erlang-questions] Luerl - Lua in Erlang

319 views
Skip to first unread message

Robert Virding

unread,
Feb 18, 2012, 11:59:28 AM2/18/12
to Erlang Questions
I just want to announce that I have released the first version of Luerl - Lua in Erlang. It is a Lua interpreter written in Erlang which started off as a proof of concept and an experiment with handling mutable data, but it grew. You can find it at:

https://github.com/rvirding/luerl

It is not a full Lua but it implements most of the language and a sizeable portion of the standard libraries. The user interface is lacking but I am working on that. I am also working on improving the speed and extending the libraries.

Robert
_______________________________________________
erlang-questions mailing list
erlang-q...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions

Matthew Evans

unread,
Feb 18, 2012, 1:29:07 PM2/18/12
to robert....@erlang-solutions.com, erlang-q...@erlang.org
Very nice.

Is it possible to call Erlang functions from inside a Lua script?

Matt

> Date: Sat, 18 Feb 2012 16:59:28 +0000
> From: robert....@erlang-solutions.com
> To: erlang-q...@erlang.org
> Subject: [erlang-questions] Luerl - Lua in Erlang

Robert Virding

unread,
Feb 18, 2012, 2:09:00 PM2/18/12
to Matthew Evans, erlang-q...@erlang.org
Not yet, but it would easy to fix an erlang interface. I have been more concentrating on the low-level stuff.

Robert


Robert Virding

unread,
Feb 18, 2012, 2:27:06 PM2/18/12
to Erlang Questions
Seeing there is a discussion about scripting languages I thought I would add an extra one in the fray. Doing PHP in Erlang would not be impossible but the syntax is a right mess and there are a LOT of libraries to do.

Robert

Tim Watson

unread,
Feb 18, 2012, 7:25:26 PM2/18/12
to Robert Virding, Erlang Questions
On 18 February 2012 19:27, Robert Virding

<robert....@erlang-solutions.com> wrote:
> Seeing there is a discussion about scripting languages I thought I would add an extra one in the fray. Doing PHP in Erlang would not be impossible but the syntax is a right mess and there are a LOT of libraries to do.
>
> Robert

This is major cool-ness. I am not going to sleep this weekend. :)

Robert Virding

unread,
Feb 18, 2012, 7:32:06 PM2/18/12
to Tim Watson, Erlang Questions
Report bugs and missing features.

Tim Watson

unread,
Feb 18, 2012, 7:45:51 PM2/18/12
to Robert Virding, Erlang Questions
On 19 February 2012 00:32, Robert Virding

<robert....@erlang-solutions.com> wrote:
> Report bugs and missing features.
>

Sure will! Matthew has already mentioned the most important one -
calling Erlang modules/functions. My laundry list for the standard
libraries would definitely be io + file, followed closely by
coroutines, modules and packages. It looks a lot like the stdlib
implementations just need to take their proper inputs (and the
stack/state), call the relevant Erlang stdlib implementation and
return this in the correct format along with St.

Is this the right general pattern? Allowing (obviously) for the
implementation to try and remain faithful to the documented semantics
of Lua's standard library - because if so, it looks like assisting
with implementing additional standard library functions should be
relatively easy.

Robert Virding

unread,
Feb 19, 2012, 9:38:16 PM2/19/12
to Tim Watson, Erlang Questions

----- Original Message -----
> On 19 February 2012 00:32, Robert Virding
> <robert....@erlang-solutions.com> wrote:
> > Report bugs and missing features.
> >
>
> Sure will! Matthew has already mentioned the most important one -
> calling Erlang modules/functions. My laundry list for the standard
> libraries would definitely be io + file, followed closely by
> coroutines, modules and packages. It looks a lot like the stdlib
> implementations just need to take their proper inputs (and the
> stack/state), call the relevant Erlang stdlib implementation and
> return this in the correct format along with St.

Some of this is more difficult. The current interpreter is not really suitable to do coroutines on. The others should be doable, some are just work like implementing there own (non) regular expression patterns. What is also needed is a good interface between erlang and Lua.

> Is this the right general pattern? Allowing (obviously) for the
> implementation to try and remain faithful to the documented semantics
> of Lua's standard library - because if so, it looks like assisting
> with implementing additional standard library functions should be
> relatively easy.

At the moment I am still working with the internal data structures and many of the libraries need this information. Fro examples I have tables as orddicts; while this is not a bad choice if it were to change them many internal functions would have to change. I am now looking at alternatives for storing the tables; I am testing orddicts, arrays, the process dictionary and ETS. Arrays and the process dictionaries seem the best so far.

I have given some more comments in http://news.ycombinator.com/item?id=3610332 .

Suggestions are welcome.

Robert

Henning Diedrich

unread,
Feb 19, 2012, 11:43:53 PM2/19/12
to Robert Virding, Erlang Questions
On 2/18/12 8:27 PM, Robert Virding wrote:
 Doing PHP in Erlang would not be impossible ...
I am so glad to hear that. I just read about female gladiators and PHP in Erlang somehow sounds equally chilling.

H*

Henning Diedrich

unread,
Feb 20, 2012, 12:16:54 AM2/20/12
to Robert Virding, Erlang Questions
On 2/20/12 3:38 AM, Robert Virding wrote:
I have given some more comments in http://news.ycombinator.com/item?id=3610332 .

Suggestions are welcome.

>> Re ycombinator:

>> "Lua is a nice, small, relatively clean language."

I experience Lua as very magic, in the non-least surprising sense.

It can be so overloaded that it can be hard to guess what a simple bit of Lua code really does. Which is maybe not ideal for an DSL

Since __metatable is on the TODO list, maybe Luerl hasn't yet run into those waters.

I'd expect challenges there because the magic stems from Lua's formidable small- & cleanness -- or maybe Erlang turns out a marvelous fit. Certainly a very exciting side of the experiment.

>> "However, the interface between Erlang and Lua in luerl is definitely faster so for smaller amounts of work it may be better."

This is a very exciting point - and all it needs for an answer to the 'practical use' question. I'm anxious to see how you will eventually implement the tables.

To go for speed, wouldn't you have to make a choice based on table size? Isn't there an absolute threshold where lists and trees just become to expensive to 'udate'? I measured structures once and the cost of flat vs deep structures' mutations was as expected [1].

Is it known lore from when on ets are more performant than, say, trees?

The table structure in Lua has been endlessly debated on the Lua list. Good thing you are probably striving for a true image rather than a 'better' Lua. The temptations would be endless.

However, if you were to restrict yourself to a version that e.g. leaves metatables out, it would not really be Lua, but as a DSL still very useful. Maybe -- even more so.

Henning


[1] http://www.eonblast.com/blog/cost-of-mutation/

Robert Virding

unread,
Feb 20, 2012, 8:41:15 AM2/20/12
to Henning Diedrich, Erlang Questions
Hi Henning,


On 2/20/12 3:38 AM, Robert Virding wrote:
I have given some more comments in http://news.ycombinator.com/item?id=3610332 .

Suggestions are welcome.
>> Re ycombinator:
>> "Lua is a nice, small, relatively clean language."

I experience Lua as very magic, in the non-least surprising sense.

It can be so overloaded that it can be hard to guess what a simple bit of Lua code really does. Which is maybe not ideal for an DSL

Since __metatable is on the TODO list, maybe Luerl hasn't yet run into those waters.

I do implement metatables. What I meant was that in getmetatable and setmetatable I don't check for the __metatable key in the metatable, I just happily get/set the metatable. A bit of laziness from my side.


I'd expect challenges there because the magic stems from Lua's formidable small- & cleanness -- or maybe Erlang turns out a marvelous fit. Certainly a very exciting side of the experiment.

>> "However, the interface between Erlang and Lua in luerl is definitely faster so for smaller amounts of work it may be better."

This is a very exciting point - and all it needs for an answer to the 'practical use' question. I'm anxious to see how you will eventually implement the tables.

I now implement tables using orddict, it mightn't be the most efficient for larger tables but for smaller tables it is good. It is also an easy data-structure to explicitly handle, which I need to do in some of the libraries. The global data record, #luerl{}, contains a tabs field which is the table store. Tables are referenced by index in the store, 0,1,2,3,4,... . Initially the store is also an orddict but I have versions where it is an array, the process dictionary and ETS tables. It works through macros. Orddicts are easy to read when testing/developing. #luerl{} also has fields for free indexes and the next index into the table store. There is a simple garbage collector for freeing/reclaiming unused table indexes.

You could vary the table implementation depending on their size; I have no feeling for how big tables get.

I also use tables for the block/function environments. It could probably done more efficiently, but most of the environments I have seen are quite small.


To go for speed, wouldn't you have to make a choice based on table size? Isn't there an absolute threshold where lists and trees just become to expensive to 'udate'? I measured structures once and the cost of flat vs deep structures' mutations was as expected [1].

Is it known lore from when on ets are more performant than, say, trees?

A bit difficult to say, it depends on the number of elements and their size. Ets is efficient on looking up elements, at least with their key, but copying large elements costs. I will get the different versions doing properly and do some proper timing.


The table structure in Lua has been endlessly debated on the Lua list. Good thing you are probably striving for a true image rather than a 'better' Lua. The temptations would be endless.

However, if you were to restrict yourself to a version that e.g. leaves metatables out, it would not really be Lua, but as a DSL still very useful. Maybe -- even more so.

Metatables are IN, they are definitely one of the more powerful features of Lua. I definitely want a "proper" Lua so I am striving to do as lua does.

Robert

Henning


[1] http://www.eonblast.com/blog/cost-of-mutation/


Henning Diedrich

unread,
Feb 20, 2012, 8:57:25 AM2/20/12
to Robert Virding, Erlang Questions
On 2/20/12 3:38 AM, Robert Virding wrote:
----- Original Message -----
On 19 February 2012 00:32, Robert Virding
<robert....@erlang-solutions.com> wrote:
Report bugs and missing features.

I don't get it to run. I tried basically:

    mkdir ebin
    erl
    1> yecc:file("luerl_parse.yrl").
    erl -make
    erl
    2> luerl:eval(<<"Hello Robert!">>).
** exception error: undefined function luerl_scan:string/1
     in function  luerl:eval/1

Need I compile the .xrl?


What is also needed is a good interface between erlang and Lua. 

What requirements would a good interface meet?

Henning

Robert Virding

unread,
Feb 20, 2012, 9:18:52 AM2/20/12
to Henning Diedrich, Erlang Questions
3>You need to compile both the .yrl and .xrl file.

If you start erlang in the luerl top directory with :

erl -pa ebin
...
1> yecc:file("src/luerl_parse").
src/luerl_parse.yrl: Warning: conflicts: 2 shift/reduce, 0 reduce/reduce
{ok,"src/luerl_parse.erl"}
2> leex:file("src/luerl_scan").
{ok,"src/luerl_scan.erl"}
3> make:all([load]).
...
up_to_date
4>

- The -pa ebin is to make sure it finds all the .beam files in ebin.
- Both yecc and leex by default put their generated .erl files in the same directory as the .yrl and .xrl source files.
- The Emakefile contains data for compiling all the .erl files in src and putting them in ebin.

I added lines in .gitignore to exclude the generated luerl_parse/scan.erl files as small changes in the source files can cause big changes in the .erl files. That was probably a mistake and I will revert it next commit.

Robert



Henning Diedrich

unread,
Feb 20, 2012, 2:59:07 PM2/20/12
to Robert Virding, Erlang Questions
Regarding interface function names:

I wonder what logic Luerl's names of do and eval follow:

dofile/1, like eval/1, returns a pragmatic Ret

while do/2 returns {String, State}

Since you are exporting ps/1, there should maybe be a dochunk/2?

And /1, too?

Or should it maybe be evalchunk/1, dochunk/2 (the /2s with State as second parameter)?

Here are some relevant functions from Lua's C interface.

luaL_dofile

[-0, +?, m]
int luaL_dofile (lua_State *L, const char *filename);
Loads and runs the given file. It is defined as the following macro:

     (luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
It returns false if there are no errors or true in case of errors.

luaL_dostring

[-0, +?, –]
int luaL_dostring (lua_State *L, const char *str);
Loads and runs the given string. It is defined as the following macro:

     (luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
It returns false if there are no errors or true in case of errors.

luaL_loadstring

[-0, +1, –]
int luaL_loadstring (lua_State *L, const char *s);
Loads a string as a Lua chunk. This function uses lua_load to load the chunk in the zero-terminated string s.

This function returns the same results as lua_load.

Also as lua_load, this function only loads the chunk; it does not run it.

luaL_newstate

[-0, +0, –]
lua_State *luaL_newstate (void);
Creates a new Lua state. It calls lua_newstate with an allocator based on the standard C realloc function and then sets a panic function (see §4.6) that prints an error message to the standard error output in case of fatal errors.

Returns the new state, or NULL if there is a memory allocation error.

Source: http://www.lua.org/manual/5.2/manual.html

Robert Virding

unread,
Feb 20, 2012, 4:59:03 PM2/20/12
to Henning Diedrich, Erlang Questions
Yes, the interface is a bit of a mess. I just threw it together so people would have something. I had planned something along the lines of:

luerl:eval(String|Chunk) -> Result.
luerl:dofile(String) -> Result.

Basic simple interface which initialises a state and evaluates the chunk String in it returning a list of return values (if any). For example luer:eval("local t={'a','b'} return t[1],t[2]") will return [<<"a">>,<<"b">>]. luerl:dofile/1 is not really necessary.

luerl:new() -> State.
luerl:eval(String|Chunk, State) -> {Result,NewState}.
luerl:dofile(String, State) -> {Result,NewState}.
luerl:compile(String) -> {ok,Chunk}.

A more complex interface. luerl:new/0 creates an initial state. luerl:eval/2 will evaluate a chunk in a state and return the values and the updated state. This state can be reused to evaluate new chunks. Again luerl:dofile/2 is not really necessary. luerl:compile(String) compiles the string into an internal form ready to run in eval/1/2.

Result is always a list of return values which may be empty if the chunk does not do a return with values. For data types:

Lua strings are binaries
Lua numbers are floats
Lua tables are orddicts (property lists) of key-value tuples
Lua true, false, nil are just the atoms true, false, nil

Anyway something along those lines. It might be nice to have a function call wrapper which would allow you a more erlang like way of calling a luerl function.

Robert


Henning Diedrich

unread,
Feb 20, 2012, 10:22:39 PM2/20/12
to Erlang Questions, Lua mailing list
Hi Robert,

To allow for String|Chunk, the chunks returned from ps/1 would have to be wrapped to be distinguishable from the Strings. I think 'functiondef' could be the right choice.

For the names, I'd propose to maybe stay closer to the Lua language function names and its C interface [1].

But at any rate, to maybe decide for one of "do" and "eval" to 1) return bare results 2) return {Result, State}. Rather than making this dependent on whether State was handed in or not as a parameter?

Since Lua uses dofile() both in the Lua language and the C interface, (and since of course neither case returns state), the "do" functions look earmarked for returning the simple, bare bones Result. However ... somehow "eval" is a better fit for a function that is expected to return something.

Lua's C interface uses "load" for parsing-only: load, loadfile, lua_load [2], lua_loadfile, lua_loadstring, lua_loadbuffer.

This could be an alternative to wrapping the chunks: for load, in Lua "the string mode controls whether the chunk can be text or binary (that is, a precompiled chunk). It may be the string "b" (only binary chunks), "t" (only text chunks), or "bt" (both binary and text). The default is "bt". [5]

The type that the loads return is 'function': "If there are no syntactic errors, returns the compiled chunk as a function; otherwise, returns nil plus the error message." --- therefore, the right chunk wrapper could be { functiondef, ... }, instead of compiled chunks being lists as outermost type.

Execution of pre-parsed/compiled chunks is "call": pcall, xpcall, lua_call, lua_pcall [3],  and lua_pcallk.

State is created and destroyed by lua_newstate and lua_close.

There is no "eval" in Lua.

So here's my proposal:

luerl:eval(String|Chunk[, State]) -> Result.
luerl:evalfile(PathString[, State]) -> Result.

luerl:do(String|Chunk[, State]) -> {Result, NewState}.
luerl:dofile(PathString[, State]) -> {Result, NewState}.

luerl:newstate() -> State.
luerl:close(State) -> ok.

luerl:load(String) -> {ok, Chunk}.
luerl:loadfile(PathString) -> {ok, Chunk}.
luerl:call(Chunk[, State][, ErlParamList()]) -> {Result, NewState}.

luerl:tolua(list()) -> LuerlTermsList().
luerl:toerlang(LuerlTermsList()) -> list().

This would be somewhat in keeping with Lua's naming.

I am unclear about error state returns. Simply in the Result I guess?

Relative to your proposal that is:
luerl:eval(String|Chunk) -> Result. => luerl:eval(String|Chunk[, State]) -> Result.
luerl:dofile(String) -> Result. => luerl:dofile(PathString[, State]) -> {Result,State}.
luerl:new() -> State. (currently luerl:init() -> State.) =>luerl:newstate() -> State.
luerl:eval(String|Chunk, State) -> {Result,NewState}. => luerl:eval(String|Chunk, State) -> {Result,NewState}.
luerl:dofile(String, State) -> {Result,NewState}. => same
luerl:compile(String) -> {ok,Chunk}. => luerl:load(String) -> {ok,Chunk}.

Beyond that, I had thought with 'interface' you would be addressing the direct interchange of values between Erlang and Lua. I'd be all for making the collection of tables in the Lua state accessible and writable, directly, somehow navigating into it using a key structure. And if possible, vice versa: giving Lua direct access to Erlang state.

Best,
Henning


[1] http://www.lua.org/manual/5.2/manual.html#4.8

[2] One note I like, in the description of the C function lua_load : "The source argument gives a name to the chunk, which is used for error messages and in debug information (see §4.9)." http://www.lua.org/manual/5.2/manual.html#lua_load - http://www.lua.org/manual/5.2/manual.html#2.3

[3] When you use xpcall or lua_pcall, you may give a message handler to be called in case of errors. This function is called with the original error message and returns a new error message. It is called before the error unwinds the stack, so that it can gather more information about the error, for instance by inspecting the stack and creating a stack traceback. This message handler is still protected by the protected call; so, an error inside the message handler will call the message handler again. If this loop goes on, Lua breaks it and returns an appropriate message. -
http://www.lua.org/manual/5.2/manual.html#2.3

[4] In Lua (not the C interface), dofile does not run in protected mode. http://www.lua.org/manual/5.2/manual.html#6.1

[5] http://www.lua.org/manual/5.2/manual.html#6.1



On 2/20/12 10:59 PM, Robert Virding wrote:
[snip] I had planned something along the lines of:

Robert Virding

unread,
Feb 21, 2012, 9:04:46 PM2/21/12
to Henning Diedrich, Lua mailing list, Erlang Questions
Hi,

Most of the difference is just in terminology and from which side you view it, from erlang or Lua. For example, for me loading means actually getting it into the sytem not just compiling it into a runnable form. And I view these functions from the erlang side. I will also admit that I am a bit hazy as to how the C-side functions work, it seems easier within the language.

'eval' and 'do' work well for me, though I do wonder if we need 'evalfile' and 'dofile'. I prefer 'compile' instead of 'load' as this is what is does. 'call' is fine. What is the difference between 'call' and 'do'? For creating and destroying state I would prefer either 'new' / 'delete' or 'start' / 'stop' depending on whether you want to view the state as just data or as some form of concurrent activity, a separate process in Erlang.

I would use 'encode' / 'decode' for converting between an Erlang representation and an internal luerl representation. So:

luerl:encode(Erlang, State) -> {Luerl,State}.
luerl:decode(Luerl, State) -> Erlang.


Encoding will modify the state as tables only exist within that state. If it not done this way then there is no need of these functions as the representation is the same and this conversion will be done in the other interface functions. So for example a Lua strings are Erlang binaries and tables will are a list of tuple pairs,

Lua {['a']=97,['b']=98,10,20,30} <==> Erlang [{1.0,10.0},{2.0,20.0},{3.0,30.0},{<<"a">>,97.0},{<<"b">>,98.0}]

Putting Lua tables into the state is also the only way to handle the difference in the meaning of equality between Lua and Erlang.

For errors I have been thinking in the Erlang way. The only function to actually return an error value would be 'compile' (or 'load') which would become

luerl:compile(String) -> {ok,Chunk} | {error,Reason}.

All errors during the Lua execution, unless they are caught internally, would result in Erlang exceptions which would handled in the normal Erlang way, either by catching it or having the Erlang process die.

The result returned from Lua and the arguments to a call would be a list of Erlang values. If no values are returned the list is empty otherwise it would contain same number of elements as in the 'return' statement.

Those are my thoughts for the moment. Now I will go back and try and code the idiosyncrasies of string.sub.

Robert


Henning Diedrich

unread,
Feb 22, 2012, 2:51:46 AM2/22/12
to Lua mailing list, Erlang Questions
Hi Robert,

Thanks for the feedback. Yes, it's a matter of viewpoint, from Erlang or Lua.

If you feel the audience for Luerl would be people who did work with Lua before, many of them would know the C interface and thus, it could be helpful for them to stick to these names.

Since I work with Lua, embedded Lua and Erlang, I would treasure consistency between the C and Erlang underside of Lua.

Lua is so much for embedding that the C interface functions are actually listed in the manual earlier than the language functions (or at least once it was so).

I'll agree that 'load' is not intuitively right. But it would increase consistency.

'dofile' is a staple of Lua proper, also exists in the C interface and again would probably be what somebody coming from Lua would look for, so would be --- nice to have in my view. 'evalfile' exists for symmetry.

As I wrote, my interface proposal is bloated, but the differences between 'do' and 'call' would be that 'call' only takes pre-compiled chunks and crashes with anything else. While "do" is more careless and can be fed anything: Lua code in Strings, Binaries, or pre-compiled chunks.

"eval" - for easiest use, in place, returns pure Result
"do" - same as eval but returns Result and State*
"call" - takes only precompiled chunks, returns
Result and State

*
(in Erlang, you can't just not fetch the second return value, as is possible in Lua)

My two cents on: "encode" and "decode" I find them better but still not perfect. It's really again the perspective from Erlang. "wrap"/ "unwrap"? "stage"/"unstage"? (Looks like no difference to "encode" at first sight -- but I do think there is one.)

As for error handling: I came to think that a try-catch wrap in eval as standard service would be nice. So using eval you'd be sure it will always return, of with an error message. While that may in fact be too much Lua thinking, and too alien to Erlang, it's what comes to mind for how I would like "eval" to be a carefree, fast thing to use.
(Erlang has a "let it crash" philosophy where errors are usually handled but a process automatically restarted.)

The whole point of "pcall" is to be a protected version of "call". Using "pcall" in Lua/C interface one can be sure that errors don't crash the program and can be handled. Specifically by a handler function which has access to the state before the stack is discarded.

I think it may make sense to treat errors that originate in Lua (or even in the Luerl VM itself, while in development) differently from errors that originate in the Erlang source.
 
Best,
Henning

--
Henning Diedrich
CEO



Eonblast Corporation
hdie...@eonblast.com
+1.404.418.5002 w
www.eonblast.com

This email contains confidential and/or privileged information. If you are not the intended recipient (or have received this email in error) please notify the sender immediately and destroy this email. Any unauthorized copying, disclosure or distribution of the material in this email is prohibited.

Robert Virding

unread,
Feb 23, 2012, 6:19:21 PM2/23/12
to Henning Diedrich, Lua mailing list, Erlang Questions
Hi Henning,

Ok we will go towards making them more Lua-C like. But we are running in an Erlang environment so they will handle errors in an Erlangy way:

- The 'eval' functions will catch errors and return {ok,Result} | {error,Reason}.
- The 'do' and 'call' functions will not catch errors and return {Result,NewState}. Errors caught in the Lua code, with 'pcall' which does not exist yet, will of course not generate an error at the Erlang interface.
- We will initialise/cleanup the state with 'start'/'stop' in an Erlangy way.
- We will 'encode'/'decode' Lua data.
- And we will both 'load' and 'compile' Lua and load/compile(String) -> {ok,Form} | {error,Reason}.

The erlang format of errors from the luerl runtime will be something {luerl_error,Error} where will be something like {badarg,sub,Args}. I will try to give them similar names as in Lua. Erlang errors are very seldom string values, in some cases there are format_error/1 functions which return string values. This will also make it easy to see which are Lua errors and which are from the Erlang code.

Robert


Rudolph van Graan

unread,
Feb 24, 2012, 5:15:13 AM2/24/12
to Erlang Questions
Hi there,

I haven't posted to the mailing for a very long time, but this post got my imagination going. Can someone describe to me the capabilities of a Lua interpreter (i.e. this one) and what it can be used for? I haven't had the time to look into Lua yet, so I am a complete ignoramus on this subject :)

Thanks,

Rudolph

Robert Virding

unread,
Feb 24, 2012, 11:16:02 AM2/24/12
to Rudolph van Graan, Erlang Questions
Best to start off with why I did this:

1. I want to experiment with implementing an imperative language with mutable global state on top of Erlang. A goal was to do it in straight Erlang without extensions.

2. I am giving a talk on implementing DSL's on Erlang at the next Erlang Factory in San Francisco in March, http://www.erlang-factory.com/conference/SFBay2012 (be there, it's going to be good, the whole factory I mean), and I wanted to be able to give practical experience from implementing a real-life imperative mutable data language. Lua is a nice, small, relatively clean language and is a good choice for this. And it is actually in use. I was also considering PHP or Javascript but they are definitely not small and clean.

3. Lua is an interseting language in its own right and has some cool ideas. You can get quite far with a few simple primitives. I don't know if these would be transferable to Erlang.

4. I like implementing languages.

Because Lua has mutable data and we are implementing it on top of Erlang it will never be as fast as a "real" Lua implementation. Some valid reasons you may want to use it:

- You only have to run a little Lua code but don't want the hassle of including a Lua system.
- The Lua code are running is only in small short Lua chunks so the the extra execution time may be offset by the faster data transfer.
- You have many cores and this would allow you to run Lua in parallel.
- ...

Luerl is a subset of Lua but most of the language now works. I am working on the standard libraries but they are still lacking. Some will never been done as they are very implementation specific, for example debug.

Robert

Henning Diedrich

unread,
Feb 25, 2012, 1:46:38 AM2/25/12
to Robert Virding, Lua mailing list, Erlang Questions
This may come close:

https://github.com/Eonblast/luerl/tree/henning

For the criticism I still have, see inline comments please.



On 2/24/12 12:19 AM, Robert Virding wrote:
Hi Henning,

Ok we will go towards making them more Lua-C like. But we are running in an Erlang environment so they will handle errors in an Erlangy way:

- The 'eval' functions will catch errors and return {ok,Result} | {error,Reason}.
What this gives away is the chance of less cluttered code, to use eval 'in-line' with no pattern matching result extraction, if so wanted.

- The 'do' and 'call' functions will not catch errors and return {Result,NewState}. Errors caught in the Lua code, with 'pcall' which does not exist yet, will of course not generate an error at the Erlang interface.

Isn't the chance to look at the soon to be discarded stack something that needs the support of giving over a suitable callback. And thus offer pcall from Erlang?


- We will initialise/cleanup the state with 'start'/'stop' in an Erlangy way.
- We will 'encode'/'decode' Lua data.
- And we will both 'load' and 'compile' Lua and load/compile(String) -> {ok,Form} | {error,Reason}.
I did all those changes, and see /examples/hello/hello2.erl. The interface comes across as bloated like this. I think.

Best,
Henning
Reply all
Reply to author
Forward
0 new messages