Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've used Ruby and Lua for about 15 years now, and looked at mruby (and possibly used it, I don't remember) about 10 years ago. Having little else to contribute to society anymore, perhaps my insight on these two languages might be of some use to some.

IIrc, Matz designed Ruby as a pet passion project, and its design was reactionary against excessiveness found in other languages, hence its minimalism in arguably excessive syntax and notation. Otoh, Tegcraf designed Lua out of pure necessity, adding only the features needed to satisfy its clients' needs.

In my opinion, necessity always leads to the better product than desire, hence C is still unbeat, having been formed under similar circumstances. Lua's C API is copied by nearly every other embeddable scripting language, including (I think) mruby. Yet they were the first to come up with it, a testament to their creativity under pressure.

Ruby (and mruby) takes the Smalltalk approach, and asks, what if everything was an object and every function call is a method call? Lua takes a less extreme approach, and merely asks, what if every data structure was built on a hashmap?

Other than that, Lua takes a very minimal approach, having break/goto but not continue, if/elseif but not switch, metamethods but not inheritance. It gets to 90% of the functionality of JavaScript with 10% of the spec and 1% of the code. You can read the entire Lua manual in one Saturday. You can read its grammar in under five minutes.

For all its cleverness, and as a price for its concise implementation and design, Lua is inconvenient to use. Hence the plethora of languages that compile to Lua and try to make it more convenient to use. One comes to mind but I can't remember or google the name successfully.



The MRuby embedding API isn't a whole lot like Lua's. Lua is a fantastic experience to embed. You might have to futz with the registry to store Lua objects in a C struct, but the abstraction allows you to almost never have to actually worry about the VM internals or the GC directly. Mruby is a lot more like MRI Ruby's API. Raw objects are exposed to you, you have to turn off strict aliasing because inheritance is implemented by the old "common meta struct as first member" idiom, you have to manually trigger VM collecting in long-running C code ( https://github.com/mruby/mruby/blob/master/doc/guides/gc-are... ), getting args in a C function involves a variadic scanf-style function. The most striking difference is documentation. The documentation of the mruby C API is actually "read the headers". There are many seemingly redundant functions that look like they do the same thing, completely without explanatory comments, or minimal inscrutable comments:

    /* mrb_gc_protect() leaves the object in the arena */
    MRB_API void mrb_gc_protect(mrb_state *mrb, mrb_value obj);
    /* mrb_gc_register() keeps the object from GC. */
    MRB_API void mrb_gc_register(mrb_state *mrb, mrb_value obj);
    /* mrb_gc_unregister() removes the object from GC root. */
    MRB_API void mrb_gc_unregister(mrb_state *mrb, mrb_value obj);
I'd rather work with Ruby as a language than Lua, but I'd much rather work with Lua than Mruby for the documentation and API alone. If mruby had anything close to the Lua reference documentation, I'd be all over it. As-is, embedding mruby kind of sucks, which is a real shame.


> you have to turn off strict aliasing because inheritance is implemented by the old "common meta struct as first member" idiom

You shouldn't have to turn off strict aliasing for that, struct pointers are allowed to alias pointers to their first member. Unless I'm missing some awkward compatibility rule that mruby breaks.


You do need to turn off strict aliasing for that, because mruby uses `struct RObject { RB_OBJECT_HEADER; ... }` and `struct RHash { MRB_OBJECT_HEADER; ... }` (where MRB_OBJECT_HEADER begins with `RClass `). You can alias objects of both types as an `RClass `, but you can't alias them as one-another, converting RHash to RObject. According to my reading of the strict aliasing rules[0], the aliasing would be legal if one of the types literally contained the other, or if they were being accessed through a union. The "compatible types"[0] section requires the types to be exactly the same in layout, not just starting as the same. It's not safe to cast incompatible structs to one another just because they have the same initial members, unless you are accessing them through a union (C11 6.5.2.3p6). Optimization can cause UB when working with mruby if strict aliasing is enabled.

[0] https://en.cppreference.com/w/c/language/object.html#Strict_... [1] https://en.cppreference.com/w/c/language/compatible_type.htm...


Oof, I get it now. I was expecting RHash to start with an actual RObject, not just the same members. I too read the "compatible first member" rule as not applying here, so I agree it breaks strict aliasing.


There are Javascript to Lua compilers, used by Roblox programmers.


And moonscript, which does a decent job as well




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: