5 ms·
Luerl – An Implementation of Lua in Erlang
- pmarreck 5y agoHow tricky is it to simulate mutable variable semantics in a fundamentally-immutable language?
- qsort 5y agoConceptually, not at all: you simply create a copy of whatever data structure you are keeping in memory to bind names to values. (Notice that you are probably already using something like this to correctly resolve scopes -- so it's not like it's more work, either). In practice, I guess it depends on how much you care about performance and how 'smart' the functional runtime is. But if you're not writing a toy interpreter, you probably also need bytecode compilation, etc.
- dnautics 5y agoerlang is not fundamentally immutable. It's just "locally immutable". You can't mutate a variable. A function call can have side effects, just it can't change its arguments -- but if it's argument is, abstractly speaking, a reference [0], it can effect a change on the abstract contents of the reference. Using this mechanism there are TONS of escape hatches using function-called "abstract references". [0] maybe the reference refers to a file, network socket, a url over the internet, which work in the obvious way. It could also be things that erlang gives you for free: the id to another process (thread) to which you send an instruction, "change your internal data", a "process dictionary" (think: thread-local-storage ish), "ets tables" (think: a redis/memecached you get for free"). If you want to go deeper, it could even be "a wrapped, refcounted, C pointer to raw memory", there are ways to do this safely that the native interface gives the curious low-level programmer.
- Jtsummers 5y agoA couple of ways: Function parameters with a "state" structure, processes (and function parameters). A common pattern is something like this: loop(N) -> Next = do_stuff(N,...), loop(Next). That would be the first pattern. So you could have a state variable (or set of variables) which are changed on the next iteration. Since Erlang does tail call elimination, this is the same as a while/for loop in other languages but does not have explicit mutation. You can also return the new state and thread it through various function calls. With processes, you can do something similar: counter(N) -> receive Pid -> Pid ! N, end, counter(N+1). user(Count_PID) -> Counter_PID ! self(), receive N -> io:format("~p times~n", [N]) end, user(Counter_PID). (probably typos above, haven't done Erlang in a while) Between these two, and more advanced use of language modules, you can provide mutable state (of a sort). EDIT: Also worth noting that, before getting to anything beyond the basic syntax, both records and maps permit updates rather cleanly. For instance, with a map you might have: Map = #{a => 10} Updated = Map#{a := 42} So if you have a register map and do something like (again, been a while so forgive syntax errors): update_register(Rs, Register, Value) -> Rs#{ Register := Value }. The rest of the map is left unaltered, only the bit that needs to be updated gets changed. And Erlang/BEAM is careful about not making more copies than needed so in theory (at one point I studied these details, I've forgotten the specifics) this should result in very little new memory being allocated for the updated map.
- bogwog 5y agoThis is awesome, I love seeing weird projects like this. Does anyone have a practical use for this, or is it just for fun?
- dnautics 5y agoI believe this is deployed at a bank, which allows them to write programs in a sandboxed environment where they can establish certain security guarantees.
- weatherlight 5y agoOne of the inventors or Erlang made this! That's really cool, Who is the target audience though? I thought the whole point of using something like Lua is that its very fast and can be used to augment app written in a low level language (Redis and gaming engines come to mind.)
- sbuttgereit 5y agoFor an (Elixir) application I'm building, I'm hoping to use it as a scripting engine which allows end users of the application to script custom behaviors for the application. It's still early days for this project and there are many bigger fish to fry than the scripting feature, but my initial impressions are that this is a good candidate for this task.
- giraffe_lady 5y agoIt can be really fast, but usually it's included in things because it's the easiest language to include in things. In those use-cases and the ones you mentioned, the performance-intensive things are mostly handled elsewhere. You just use lua more for like configuration and automation of the other parts of the program. I don't know about redis but in MMOs that use it I think it is mostly for UI customization, not part of the main engine that runs the game.
- dnautics 5y ago> Who is the target audience though I believe this is used at a bank.
- mrdoops 5y agoNeat thing about Luerl is that you can manage many isolated Luerl vms from within an Erlang supervision model which is a very desirable trait for things like games with user defined scripts that may explode.
- sbuttgereit 5y agoThere's also a presentation from several years ago about this project by Robert Virding that's worth watching if you're into the Erlang eco-system even without need of a Lua implementation in Erlang: https://www.youtube.com/watch?v=A6_bt6tK2Is https://www.youtube.com/watch?v=A6_bt6tK2Is
- borski 5y agoWe used this at a work hackathon to enable customers to submit custom scripts, written in a Lua API we defined, to add custom vulnerability checks to our Elixir-based security scanner. It was fantastic.
- petejodo 5y agoI'd love to hear more about this. Do you have any reading material or tutorials that helped you get started?