1. 51
  1. 22

    It’s really interesting to see where they diverge from mainline Lua since they based it on PUC 5.1, which is frankly pretty awful. (LuaJIT also uses PUC 5.1 as a baseline but fixes its most egregious faults, sadly in some ways which are off by default.) For context: when Lua 5.1 came out, Java was at version 5.

    • they fix the issue of resuming coroutines across pcall, which is an enormous problem in 5.1
    • they haven’t backported the ability to iterate with metatables, which is my #1 complaint in 5.1 by a long shot, but they admit that their solution isn’t great and that they might add this later. hope they do!
    • they didn’t backport goto (good!)
    • backported UTF8 and bitwise ops
    • … aaaaaand they somehow decided to remove tail-call optimization

    Honestly that last point just completely kills whatever interest I may have had in this. What the hell.

    1. 8

      … aaaaaand they somehow decided to remove tail-call optimization

      I would have to guess that the aggressive optimizations made to the bytecode / interpreter made it difficult to support generalized TCO (between methods). I don’t see why they can’t rewrite self calls into a loop but maybe it got dropped to avoid explaining that self-calls are fine, but generalized is not?

      Update: Oh, they actually explain it, which I missed:

      Tail calls are not supported to simplify implementation, make debugging/stack traces more predictable and allow deep validation of caller identity for security

      1. 5

        they didn’t backport goto (good!)

        The biggest reason I use goto in Lua is as a “pseudo-continue”:

        for [..]
            if [..]
                goto continue
            end
        
            ::continue::
        end
        

        I tried doing without it, but for, if, if, and then all of the loop contents inside of it (and similar things) is just awkward.

        1. 3

          IMO code becomes a lot easier to read when you can make certain assumptions about its structure, like the fact that it doesn’t jump around randomly and the fact that the return value always can be found in tail positions. But by supporting early returns Lua has already lost this battle, so the argument isn’t as strong as it is in more expression-oriented languages.

          1. 6

            I find it a lot easier if I can read things from top-to-bottom without keeping too much in my head. Early return and “early continue” really helps with that. Obviously there is no “one right way” because different people read things different, but I suspect this applies to a significant chuck of devs.

            1. 2

              I’ve noticed that people tend to have surprisingly different opinions on this one. There’s definitely a camp of purely functional programmers who prefer visually nested expressions.

              https://www.teamten.com/lawrence/programming/avoid-continue.html is an interesting bit of writing here which argues against continue, but for early return, from imperative programming perspective.

              1. 2

                From the link:

                In English, the word continue means “go on”.

                It’s funny, because the English word “continue” also requires context. “Continue what, exactly?” In programming, the context is “the top of the closest scoped loop.” It’s actually probably less clear of the context in most English uses, because English is so often ambiguous!

                (I do theoretically like next as a replacement for continue, but it has the same problem in English, so it’s kind of no different…)

        2. 3

          From my very limited experience with Lua, the biggest problem with the version LuaJIT used was that it couldn’t represent 64-bit integers (which was really important for the kinds of things I wanted to do, which required handling things like 64-bit inode numbers) but with 5.3 you had 64-bit integer and 64-bit float types (I think you can turn off floats for builds in environments that don’t support them?). The biggest advantage of Lua for embedding is that it’s tiny - around 300 KiB for a complete version and tuneable to something smaller if you want a subset. I don’t see any binary size numbers om the Luau page, so I guess it’s aiming for a different use case.

          1. 2

            In LuaJIT you can use any C type via ffi.cdef - including int64_t. Handling unsigned 64-bit integers in LuaJIT was an important feature to me in the pre-5.3 days.

        3. 2

          Too bad it is implemented in C++ rather than C, which makes it harder to implement it in C projects that support Lua already.

          1. 2

            Why not moonscript i wonder

            1. 3

              Moonscript transpiles into Lua, it’s not an interpreter.

              1. 2

                There is a valid question, here, I think. Moonscript’s purpose is to fix some perceived problems with Lua. Luau also aims for this. The reality seems to be that the set of problems the Moonscript team sees worth solving are at a different part of the language (syntax and ease of use (eg class instead of manually doing prototypes), rather than Luau’s which is performance, compatibility, tooling, and better ergonomics (keeping compatibility).

                Would, of course, work to port Moonscript to Luau, I am sure.