Talk:Lua FAQ

From Second Life Wiki
Jump to navigation Jump to search

I really love the LSL Portal and so would appreciate if Lua can get the same treatment or coexist without causing confusion to existing or new scripters.

So I'm wondering about technical documentation and conflicts with LSL. Perhaps a) it might be wisest to create a "Lua Portal" that mirrors the LSL Portal but then is expanded over time. And/Or b) would all LSL functions pages (and the LSL Function template) be updated to show the Lua version? c) What if there is Lua-only function later or syntactical differences esp with functions that use or return lists as lists may not exist in Lua or work differently to Lua tables? And d) would a lot of the function documentation diverge too much due to differences in the languages in how they may need to treat types, operators and example code?

It seems a Lua Portal will be inevitable anyway, because there needs to be a central location where all the Lua-specific pages can be accessed from easily, such as developer resources (tutorials, guides and script examples and libraries), and Lua language reference just as easily as for LSL and also avoid confusing beginners dealing with two different languages on the platform.

Another thing to look at might be that there are a lot of LSL-specific pages that may need to be prefixed with LSL_ in their pages still, e.g. State, While, If, etc since Lua will have differences to LSL. On the other hand there are also some other portals that also invade the global namespace e.g. Coding Standard, Features, Glossary. All of this affects search functionality. A disambiguation page or template akin to wikipedia may be necessary in place of some of the existing redirects. If someone searches for "string" or "if" they get fed with LSL currently.

-- Nexii Malthus 14:19, 4 July 2024 (PDT)

Hear, hear. I foresee a lot of work ahead of us SLWikians. If there is a direct 1:1 correspondence between LSL and Lua, well, in that case, we could do something similar to what Microsoft does on its documentation for .NET, where you get, for the same function, the C# and the VisualBasic variants β€” the idea being that the function is the same, it's just the language construct that uses the function that will change.
Other similar cases are those explaining, say, a RESTful API. The overall parameters are described, and then you get code snippets for implementing that call in several different programming languages, e.g. cURL/JavaScript/Python/PHP/Go, for instance.
However, I can imagine that this simplistic approach will fail in our case, especially if we start getting some divergence between actual functions (i.e., new functions that only make sense in Lua, such as those dealing with JSON; and old functions that only make sense in LSL, such as those to retrieve values from a List). While (speculatively) Lua could have its own "List-like" type β€” it shouldn't be hard to implement β€” I can imagine that accessing its members will look quite different. Or perhaps not. In any case, there will be differences. It might make more sense to have a "Lua portal" instead, and just link together equivalent functionality (so that you can look up something and see both its LSL and Lua equivalents).
Exciting times ahead :-) Lots of work to do as well. β€” Gwyneth Llewelyn (talk) 01:39, 29 August 2024 (PDT)

I πŸ’™ Lua (well, not really, but ok)! Here are a few suggestions but also some questions:

All right, so I stumbled upon this page just today, after the general announcements posted on the forums. While I was aware of the effort of doing client-side Lua scripting, I had zero knowledge of the amazing work having been done "under the hood" to get LSL running on top of Luau β€” that idea never even crossed my simple mind, and aye, it does sound crazy indeed.

On the other hand, perhaps it's not so surprising. As I'm fond to quote all over the place, Lua was designed to be an embedded programming language for games and other applications. The keyword here is "designed for embedding". Obviously, you can embed JavaScript, or Python, or LIST (a popular choice in the recent past!), or naturally Java, and you can even embed C#, and there are several other languages that I'm sure that someone, somewhere, has written an "embeddable" version of whatever programming language has been invented out there. Since I saw that the OpenSimulator code included an embedded Prolog interpreter written in C# just to do one function, I can believe that anything is possible!

That does not mean that it's efficient, clean, easy, with a small footprint, etc. It just means that these embedded languages work. That's the goal, after all.

Lua, by contrast, is not merely "the programming language". Syntax-wise, it has a wonderful long list of awesome features and concepts that make things insanely easy to do β€” aye, even compared to JavaScript. But it also has some terribly annoying quirks which make zero sense and are just a stupid way of "differentiating" the language from others in the same family. It's stupid to use ~= instead of !=. Indeed, I find it even stranger due to Lua's Brazilian origin β€” the key for the tilde ~ is a dead key (used for the Portuguese vowels Γ£ and Γ΅), which means that, on a Portuguese keyboard, you need to press three keys to get the negation symbol!

Comments are also awful. I know that the "proper" way of doing comments is open to debate, but, at the end of the day, C's 50+-years-legacy of /* ... */ and // (the latter "borrowed" from C++ and "backported" to C as well) is what everybody uses, at least on languages that are sensible enough not to consider whitespace as syntactically relevant (Python, I'm looking at you).

And arrays starting at 1? Really? Why did you guys think that this is a good idea? Not to mention the mixed approach you've taken for delimiting blocks of code. I mean, there are a few schools of thought on this, and from the perspective of the programmer, you have two main choices: using a symbol (usually the curly braces; parenthesis in LISP or Prolog or perhaps a few other purely functional languages), which has the disadvantage of being hard to figure out (without tooling) to which code block a closing curly brace/parenthesis belongs to. Or there is the horrible β€” but useful! β€” idea of using reverse keywords to begin and start code blocks, e.g. if ... fi, which are aesthetically ugly but they do the job well. Alternatively, you always have if ... endif and similar constructs β€” giving the code some structure at the expense of having to type more. But if... end (and everything else ending with, well, end...) just means typing 3 characters instead of just one, but with the same lack of semantics. If you see an end in Lua, it can belong to anything, so it has no semantical meaning by itself (unlike a fi which can only terminate a conditional block started with if).

That said (and I wish I could have added the sentence "besides all the above, the rest is fine!", but I cannot β€” the list of oddities and quirks in Lua go on and on), the whole point of "Lua" is that it's not just the programming language. That's what the developer interacts with. Lua, however, is worthless by itself; the concept always includes the notion of an interpreter/JIT/full compiler that runs embedded into an application. And that's where Lua shines: it may have its oddities, but it was designed for having all these oddities (and so much more) getting efficiently and quickly run by any 'host'. That also means the ease of passing information between the host application and the Lua engine, in a safe (and sandboxed!) way. Again: you could do it on any other language via its own embedded mechanism. It's just that Lua happens to be especially good at such interfaces. I can imagine that getting Lua to access the vast library of LSL functionality is an almost trivial exercise; it's supposed to be simple to do that, after all. In other words: it's often less about the end users (those that will ultimately write code in Lua) and much more about the environment surrounding Lua, and how its highly portable embedded engine interfaces with such an environment.

Perhaps ironically, around 2020 or so, I struggled with the same issues, although at a much tinier (and less important!) scale. While developing some code that allowed full control over groups of independent agents (let's call them 'bots), I went through the usual phases of sloppy programming: first, figure out what functionality is common to all (say, logging in, moving around...) and implement those. Then essentially have a list (or a database table) with all the independent agents, and, for each, follow a sequence of operations, all of which hard-coded, That was fine, until the edge cases started to pop in β€” such as different agents requiring different settings. That quickly became unmanageable, so the next approach was to use more fields on the table, such as keeping track of the agent's location. To deal with different orders of execution, another table was created, listing, for each agent, what the sequence of operations for that agent was instructed to perform. This essentially describes a very crude state machine, where the entries are indexed by the function call to be made next.

And then, the inevitable happens. How to deal with conditionals? How to deal with loops? Oh, and wouldn't it be great to have some place to store some results separately for each function? (it could be "registers", or a classic stack with push/pop operations...)

In essence, I was asking the wrong questions: what I needed wasn't to "reinvent the wheel" and creating what ultimately would become an embedded language, designed from scratch. Instead, what I really needed was an embedded language!

At that time, I wanted just something very simple which could be quickly implemented (and its functions mapped to those on the host application). Since I usually work (on my own) with Go, I started looking for Go-specific solutions. And sure, there are a few, but they have the disadvantage that they're even less known (or used) than LSL. The obvious choice was naturally embedding a JavaScript engine, of which the best of the best is, allegedly, Google's own. It is also... massive, to say the least. Never mind that our contemporary Chromium-based browsers use this massive engine (even the SL Viewer does!); it might make sense if you have a need to access the vast library of JavaScript code all over the place; but that wasn't my case. I just wanted something familiar and having a community of a decent number of people that are able to provide libraries and have some availability to answer questions. That's when I came up with the idea of testing out Lua. There was a semi-decent effort to write a Lua engine completely in Go (as opposed to linking it to an externally-compiled C/C++ library, which would be the "usual" choice for most solutions), and I thought it would be a nice idea to experiment with.

As it happens, there are a few people writing some helper functions on top of what the "raw" library supports, which make exposing functions to Lua (and vice-versa) an almost banal exercise. It works admirably well. In fact, the only thing that really works well in my meagre coding attempts are the bits running on Lua β€” the rest of the much more complex effort of integrating the core application with the control of the independent agents is (for me!) much, much harder. In other words: by using Lua as the choice for the embedded language, I solved one problem β€” the user-facing aspect of dealing with the actual agent scripting, using a high-level language β€” and didn't need to ever worry with it again. It just works. Now I can switch the focus to "everything else" instead.

I was super-excited (and to be truthful, I had never programmed in Lua before, and know little more than the basics; think of my level of experience as being that of a 12-year-old who learned Lua to do interactive objects in Roblox β€” that's pretty much how much I know) and astonished at how well this worked. Not in terms of performance (frankly, I didn't really make benchmarks β€” all the bottlenecks occur outside the Lua environment, anyway; Lua scripts are spending most of their time waiting for the rest of the code to produce results and feed them back to Lua β€” but even the Go developers who did this Lua engine port admit that it's not that fast or optimised), but rather in terms of integration. Now, nobody knows how the LL server code looks like, but we can at least assume that it shares some vague similarities with OpenSimulator code, for the simple reason that both technologies needs to handle functions called by LSL. While there are potentially many ways to implement that, and nobody can know if LL's code uses the "same" way as OpenSimulator (while, of course, the reverse is true!), it's worth speculating about the trouble in making every library function accessible from Lua as well. My belief is that this will be little more than a trivial exercise; compiling LSL to the Luau VM will be much more challenging, I think :)

That said, looking back, it's obvious that I shouldn't have been so "surprised" that everything worked so well. Lua is supposed to be embedded. It's one of its design features. In fact, although you can run Lua from the command line (or even compile things into executables), there is little incentive to do so: Lua will not be especially good, or fast, or "trendy", for independent, self-contained, command-line utilities. For that you already have C/C++, Python, and more recently Rust, Node.js and a bit of Go. That pretty much covers all the needs. On the other hand, the increasing number of applications using Lua as an embedded language is frankly astonishing. On my 'personal' bare metal server hosted on a remote data center, I have been running software that I never thought that they included an embedded Lua engine β€” such as one of the anti-spam services (!). Even the webserver itself (the lightweight nginx) can now have a module to allow its configuration files to be Lua programmes, as opposed to, well, configuration files.

I also have no idea, in the battle for the embedded programming languages, where Lua stands against the "competition". These days, even though LL tested out a very impressive array of choices, the truth is that JavaScript is highly likely the most used embedded language, since every browser uses it, and that means close to 5 billion users (who, of course, only benefit from JavaScript, they don't interact with it in any way). Python was once quite popular as an embedded language, but I guess that its maintenance chores are a nuisance to deal with. LISP was quite popular as an embedded language, and has probably been made famous because it used to be the embedded language used by Richard Stallman's Unix-based Emacs as well as Autodesk's AutoCAD, each running their specific dialects of LISP. Because of the widespread usage of LISP in the early days of embedded languages, I can imagine that it's still more popular than many other solutions out there. The only trouble with LISP is that it requires a very specific mindset to work with it (or else all things AI-related would be written in LISP and not in Python, which is hardly the "best" choice for that β€” but who am I to contradict millions of users?)

That said...

And that was the longest introduction ever...

I have a few questions that the original article didn't explain!

  1. Will SL-Lua also support external libraries ("external" meaning: any other Lua-asset to which we have permissions to access)? This is a crucial requirement, which LSL does not satisfy in the least; but it would make millions of lines of LSL code irrelevant, to the great relief of those needing to support the ever-increasing complexity put into LSL to allow it to do very complex tasks indeed. Imagine, for instance, a HUD library that can be easily distributed, with which 90% of the functionality would be packaged inside the library; you'd only need to add a bit of "glue code" on top of that. Or imagine the same thing for vendor machines β€” such as Casper's β€” which could therefore have a much cleaner way of integrating with "external" scripts, without needing to expose anything.
  2. In the same vein: except for the cases mentioned in the main article, does this mean that LL will essentially provide all (or most) standard libraries for Lua? This is relevant for those who really don't want to reinvent the wheel; the Lua standard libraries already do a lot of useful work, there is no need to redo everything β€” so long as these libraries can be used, of course. Even with limitations. It also means that a lot of LSL functionality which LL had to develop from scratch might not be necessary as well (when LSL needs access to those specific functions, it would just call them β€” via Lua!). I'm thinking about things such as the math library functions, for instance.
  3. Still on the issue of libraries: the article talks about a ll namespace, which in Lua can have different meanings and implementations ("everything is a table"). Does that imply that there will be one LL library with all the functions we have today for LSL β€” or that the LL library will be split according to different kinds of functionality, and just loaded on demand if needed? I'm thinking about how worthless it is for me to know that there are functions for dealing with Pathfinding, or all the vehicles and physics systems, when all I've got is an Animation Overrider to worry about. A much cleaner way to do things would be to encapsulate related functionality under different libraries or objects. Maybe that's exactly what is going to be done, and that's what will happen "under the hood" when we call a Lua function with ll.someFunction(). I'm not sufficiently familiar with Lua to know if there is a way to do that or not. My reason for asking that is just because I see the vastness of never-ending functions getting a bit out of hand, and it would be far better to aggregate them under different compartments β€” be they namespaces, libraries, tables/objects, whatever fits the concept best. The end-user (we, the scripters!) will probably never need to worry about that. Or maybe they would β€” by explicitly calling the libraries they need. This would also allow for more error-checking, i.e. you won't be able to call a similarly-named function by mistake if you have checked in a different library. A typical example are the two key/value pair stores, one implemented in one way for Experiences, the other implemented for any script running in a prim. Sometimes, it's easy to forget which is which, but if I haven't checked in the Experiences library explicitly, I will get an error for a "missing function" β€” a good hint that I'm probably trying to do something which isn't intended.
  4. Will Lua scripts be versioned, i.e. will there be a way to automatically let the programmer release a new version, and all existing copies of that asset would automatically "migrate" to the new version instead? This is becoming a more important requirement all the time, as the complexity of scripts continues to increase, and the need to get rid of obsolete versions and replace them automagically is a must; however, I'm quite aware that only a fraction of the users actually bother to do the upgrades. That happens for several reasons, but I can imagine that a lot has to do with the whole complex procedure of getting an "upgrade box", rezzing it on the ground (assuming you've got the correct permissions), then do the same with your HUD, clothing, device, etc., activate the upgrade box, and hope that it works...
  5. And how about a (better) integration with an external debugger? Having an internal one, of course, is great effort that you've done (or are in the process of doing). But let's just say that the internal code editor is not really up to modern standards... that said, I wish that the integration wt
  6. Will you include an official Lua LSP server? (There are plenty of those around! It's just that none will come with LL's library functions, of course...). This is mostly for those using external editors, since, internally, you already have something similar for LSL (similar... not quite the same, though...)
  7. While I understand that, for several reasons, mixing and matching code from LSL and Lua is, in general, a Bad Thingβ„’, I wonder if you guys have thought about the possibility of LSL to call functions in Lua. This is mostly important if the Lua support allows external libraries (which could be Lua scripts) as described above; this could be a way to allow LSL to be "expanded" with libraries as well (namely, with Lua libraries, that is). That might matter most during a transition phase, of course.
  8. Some people that I talked to about Lua, who are themselves not programmers, asked me if, with Lua, there could be an (embedded) visual programming editor, such as you have in, say, Blender (or any other complex application, especially in the 3D rendering business; but even Filter Forge filters are visually programmed that way). While such options certainly exist and could be deployed over whatever Lua-based infrastructure, the question is if LL has considered that possibility at some point?
  9. And finally, just for the sake of curiosity, will the prevailing conceptual model for Lua also be a glorified state machine, like LSL? Or will a completely different model? The state machine model was actually a quite clever concept, even though most scripts I've come across rarely employ more than 1-2 states, which defeats the purpose. I'd think that the move to Lua would imply the end of the state machine model; but, on the other hand, this would also mean a much harder effort in adapting old LSL scripts and converting them to Lua (manually, that is!). Thus my curiosity!

That said, I'm looking forward to see what you guys have come up with :)

β€” Gwyneth Llewelyn (talk) 02:32, 1 September 2024 (PDT)