Difference between revisions of "User:SuzannaLinn Resident/LuaLanguage2"

From Second Life Wiki
Jump to navigation Jump to search
(Created page with "= The language: Lua beyond LSL = Standard Lua and Luau have some differences. Most of the next code runs in both of them. I'm using "Luau" at the end of the comment in the fir...")
 
 
Line 1: Line 1:
= The language: Lua beyond LSL =
= The language: Lua beyond LSL =
Standard Lua and Luau have some differences. Most of the next code runs in both of them. I'm using "Luau" at the end of the comment in the first line for Luau only code.
Standard Lua and Luau have some differences. Most of the next code runs in both of them.
I'm using "Luau" at the end of the comment in the first line for Luau only code.


Remember that this is a quick overview to see what is new. Each one of the next scripts will require one or two classes to explain its content properly.
Remember that this is a quick overview to see what is new. Each one of the next scripts will require one or two classes to explain its content properly.


== Tables as lists of lists ==
== Tables as lists of lists ==
<syntaxhighlight lang="lua" line copy>
-- Tables as lists of lists (Lua)


fruitData = {
    { name = "Apple", quantity = 50, color = "Red", season = "Fall" },
    { name = "Banana", quantity = 30, color = "Yellow" },
    { name = "Cherry", quantity = 20, color = "Red" },
    { name = "Orange", quantity = 10, color = "Orange", organic = true }
}
for index, fruit in pairs(fruitData) do
    print("Fruit #" .. index)
    print("Name: " .. fruit["name"])
    print("Quantity: " .. fruit["quantity"])
    print("Color: " .. fruit["color"])
    if fruit["season"] then
        print("Season: " .. fruit["season"])
    end
    if fruit["organic"] then
        print("Organic: " .. tostring(fruit.organic))
    end
    print()
end
</syntaxhighlight>
Here we have an array of tables, a "list of lists".
Here we have an array of tables, a "list of lists".


Line 16: Line 40:


== Functions, parameters and returns / functions, anonymous functions ==
== Functions, parameters and returns / functions, anonymous functions ==
 
{| {{KBtable}}
|
<syntaxhighlight lang="lua" line copy>
print(a)
</syntaxhighlight>
|
<syntaxhighlight lang="lsl2" line>
llSay(0,"hello");
</syntaxhighlight>
|}
Let's look at the left part of the slide in the viewer.
Let's look at the left part of the slide in the viewer.


Line 49: Line 82:


== Closures / for and iterators ==
== Closures / for and iterators ==
 
{| {{KBtable}}
|
<syntaxhighlight lang="lua" line copy>
print(a)
</syntaxhighlight>
|
<syntaxhighlight lang="lsl2" line>
llSay(0,"hello");
</syntaxhighlight>
|}
Let's start with the left side and see what is a "closure".
Let's start with the left side and see what is a "closure".


Line 94: Line 136:


== Metatables and metamethods ==
== Metatables and metamethods ==
 
{| {{KBtable}}
|
<syntaxhighlight lang="lua" line copy>
print(a)
</syntaxhighlight>
|
<syntaxhighlight lang="lsl2" line>
llSay(0,"hello");
</syntaxhighlight>
|}
Now we are going to see how to make a read only table using a metatable.
Now we are going to see how to make a read only table using a metatable.


Line 115: Line 166:


== Objects ==
== Objects ==
 
{| {{KBtable}}
|
<syntaxhighlight lang="lua" line copy>
print(a)
</syntaxhighlight>
|
<syntaxhighlight lang="lsl2" line>
llSay(0,"hello");
</syntaxhighlight>
|}
Time for the objects. Both sides of the slide are the same script.
Time for the objects. Both sides of the slide are the same script.


Line 142: Line 202:


== Objects and inheritance ==
== Objects and inheritance ==
 
{| {{KBtable}}
|
<syntaxhighlight lang="lua" line copy>
print(a)
</syntaxhighlight>
|
<syntaxhighlight lang="lsl2" line>
llSay(0,"hello");
</syntaxhighlight>
|}
Let's go to inherit objects. Both sides of the slide are the same script.
Let's go to inherit objects. Both sides of the slide are the same script.


Line 155: Line 224:


== Objects and multiple inheritance ==
== Objects and multiple inheritance ==
 
{| {{KBtable}}
|
<syntaxhighlight lang="lua" line copy>
print(a)
</syntaxhighlight>
|
<syntaxhighlight lang="lsl2" line>
llSay(0,"hello");
</syntaxhighlight>
|}
Multiple inheritance is also possible.
Multiple inheritance is also possible.


Line 172: Line 250:


== Error handling ==
== Error handling ==
 
{| {{KBtable}}
|
<syntaxhighlight lang="lua" line copy>
print(a)
</syntaxhighlight>
|
<syntaxhighlight lang="lsl2" line>
llSay(0,"hello");
</syntaxhighlight>
|}
We can catch errors, to avoid run-time errors, so our script can go on running.
We can catch errors, to avoid run-time errors, so our script can go on running.



Latest revision as of 04:55, 30 September 2024

The language: Lua beyond LSL

Standard Lua and Luau have some differences. Most of the next code runs in both of them. I'm using "Luau" at the end of the comment in the first line for Luau only code.

Remember that this is a quick overview to see what is new. Each one of the next scripts will require one or two classes to explain its content properly.

Tables as lists of lists

-- Tables as lists of lists (Lua)

fruitData = {
    { name = "Apple", quantity = 50, color = "Red", season = "Fall" },
    { name = "Banana", quantity = 30, color = "Yellow" },
    { name = "Cherry", quantity = 20, color = "Red" },
    { name = "Orange", quantity = 10, color = "Orange", organic = true }
}

for index, fruit in pairs(fruitData) do
    print("Fruit #" .. index)
    print("Name: " .. fruit["name"])
    print("Quantity: " .. fruit["quantity"])
    print("Color: " .. fruit["color"])
    if fruit["season"] then
        print("Season: " .. fruit["season"])
    end
    if fruit["organic"] then
        print("Organic: " .. tostring(fruit.organic))
    end
    print()
end

Here we have an array of tables, a "list of lists".

Each table in the array can have the same elements, or different, or different quantity of elements.

The "for" loops on the array. We get the value of each element using its key, between [ and ].

In line 15, or 18, if the key doesn't exist in the table, "nil" is returned. A "nil" in a condition is false.


Functions, parameters and returns / functions, anonymous functions

print(a)
llSay(0,"hello");

Let's look at the left part of the slide in the viewer.

Functions can return several values, lines 3-9, two in this case, in line 4. The result is assigned to "add" and "mul" in line 7.

Functions can also have an indeterminate number of parameters, like in lines 12-27. The ... represents any quantity of parameters.

So the function in line 12 has from 2 to any number of parameters. We will use 4 in total in this example (line 25).

We use the system function "select" to get the parameters.

In line 16, "select" with "#" returns the quantity of parameters.

In line 17 we get each parameter by its number of position in the ..., as usual in Lua starting with 1, not 0.

Let's move to the right part.

We are sorting a table in two different ways, lines 6-12 and 15-26.

"table.sort" is a system function. Its first parameter is a table, the second parameter is a function that takes two values and returns "true" if the first value is to be placed before the second value in the sorted table.

A function in Lua is a type of data, like boolean, number, string or table.We can use functions as parameters, return functions, make a table of functions...

Functions don't need to have a name. As a parameter, we can use the name of a function, or the code of the function, like we are doing in lines 6-8. The function code goes from "function" to "end".

table.sort calls this function that we have sent to do the sorting.

In the second sort, lines 15-26, we are sorting by length of the fruit name, shorter fruits before.

And we have added a counter to see how many comparisons it needs.


Closures / for and iterators

print(a)
llSay(0,"hello");

Let's start with the left side and see what is a "closure".

We have a function that makes a counter, lines 11-12. Each time that it's called, lines 14-18, the counter is increased.

Let's look at lines 3-9.

In line 4, the keyword "local" defines "count" as a local variable, otherwise it would be global.

In line 5, we don't return a value, but a function that increases "count" and returns it, lines 5-8.

The variables counter1 and counter2 contain functions,that are executed each time that we use them with ().

But the variable "count" is local. The function createCounter finished its execution when it returned the function that increases "count"...

So what variable "count" are counter1 and counter2 increasing and how is the value preserved between calls?

This is what is called a closure, or external local variable, or upvalue.

The returned function, by using "count", encloses the variable with itself. Each function that is returned has its own "count".

From the point of view of the function is like a global variable, and its value is preserved between function calls.

For the rest of the script is like a local variable of the function, so not accessible.

Lua has three scopes of variables: globals, locals and closures, which are somewhere in the middle of the other two.

Let's move to the right of the slide.

We have seen the "for...in" with ipairs and pairs. Now we will use our own iterator.

An iterator is a function that is called by the "for...in" in each loop and returns a value. The "for" goes on until this function returns "nil".

In this example we iterate on fibonacci numbers. The parameter "limit" is how many numbers we want.

The function fibonacciIterator is called only once, when the "for" starts. What is called in each loop is the function returned by fibonacciIterator.

The iterator is the anonymous function in lines 9-17. It has 3 closures: a, b and count.

In line 14, the values on the right side of the = are all obtained before starting to assign them to the variables on the left.

For instance: a, b = b, a is a way to swap the values without using an intermediate variable.


Metatables and metamethods

print(a)
llSay(0,"hello");

Now we are going to see how to make a read only table using a metatable.

A metatable is a table that is linked to another table and has keys to control how the table works.

The main use of metatables are with classes and objects, but let's start with this less useful example.

The function createReadOnlyTable, lines 3-11, takes values for an array table and returns a table that can't be modified.

"mt", line 4, is the metatable. Its possible keys are predefined in Lua and start with __.

We are using __index, line 4, to assign the table where to access the data when we read it. In this case the table "data" in the parameters.

And __newindex, line 5, that has a function that executes when we write a new key to the table. In this a case a function that returns an error message.

In line 10, with the system function setmetatable, we assign the metatable to an empty table and return it.

After line 13, readOnlyFruits is a table, that has a metatable, that doesn't allow any new key and has a table, from which it obtains the values.


Objects

print(a)
llSay(0,"hello");

Time for the objects. Both sides of the slide are the same script.

We are creating an object "vector", lines 3-32. We will not need to do it, LuaSL will have vectors, it's only an example.

There is not an "object" type in Lua. Objects are created using metatables.

The class is a metatable that stores the functions (methods). The instance is a table that stores the values (properties) and has the class as metatable.

In our example, Vector is the class, v1 and v2 are the instances.

We start defining Vector as a table, line 3, with __index assigned to itself.

It means that when the instance doesn't find a key in its table (which will happen with the functions of the class), it will look for it in the Vector table (which has the functions).

The function "new", lines 6-12, is the constructor. We could use any name for it, but "new" is the usual one.

It returns a new table, with Vector as metatable, and the initial values.

In lines 14-28 we are defining operators for the class, using __add, __sub and __mul. There are more predefined keys for other operators.

It's not possible to overload operators, so with __mul we check the type of the parameter in line 23 to calculate Vector*number (returning a vector) or Vector*Vector (returning a number).

In lines 30-32 we define __tostring that is called when a conversion to string is needed, like in the "print" function.


Objects and inheritance

print(a)
llSay(0,"hello");

Let's go to inherit objects. Both sides of the slide are the same script.

Here we have a class "Shape" with a position (x,y). And two classes, "Circle" and "Rectangle", with area and some other properties, that inherits from it.

myCircle has Circle as metatable, and Circle has Shape as metatable.

When we call a function in myCircle, Lua looks for it in the table myCircle, then in the table Circle, and if it is not there, in the table Shape.

It looks slow, but it's optimized at compile time, and is very fast.


Objects and multiple inheritance

print(a)
llSay(0,"hello");

Multiple inheritance is also possible.

It's recommended to design our structure of classes in a way that we don't need multiple inheritance, but if we need it, we can use it.

We are adding a new class Color, at left of the slide.

At right we have the class ColoredCircle, that inherits from Circle and Color.

This script should have the classes Color and Circle (and Shape) in the same script to work. I'm not copying them to avoid repeating.

Now the __index, lines 4-6, doesn't have a table, but a function. This function returns the called function from Circle if it is there (or in Shape) or from Color.

This use of __index with a function is why multiple inheritance is not recommended. This function can't be optimized by the compiler and the process is slower than single inheritance.


Error handling

print(a)
llSay(0,"hello");

We can catch errors, to avoid run-time errors, so our script can go on running.

In this example we are trying to calculate the square root of "hello", which will throw an error, since it can't be converted to a number.

The system function to intercept errors is "pcall", in line 8.

The first parameter of "pcall" is the name of the function that we are calling and the next parameters are the parameters of our function.

The first parameter returned is true (success) or false (error).

In case of success, the next parameters are the parameters returned by our function.

In case of error, the second parameter is the description of the error.


Libraries

system functions are grouped in libraries, and called as LibraryName.FunctionName, except the functions in the basic library that doesn't need a library name.

We have seen several basic functions, like: print, type, tostring, pairs, select, setmetatable,... Other libraries are:

- table: tables manipulation

- math: mathematical operations

- string: string manipulation

- os: date and time functions

- bit32: bitwise operations on integers. Standard Lua has bitwise operators, but not Luau. So probably we will use this library instead of operators.

Standard Lua has more libraries and can use externally developed ones. Luau, for security reasons, is restricted to its own libraries.

LuaSL will add the ll library with all the ll functions, like: ll.Say, ll.GetPos,..


Modules and packages

A module is a type of script that is not executed on its own, but will be included in another script.

Modules return a table that will used in the main script. This table can be anything: values and functions, an object, several objects...

Standard Lua also has packages, which have several modules compiled together, but Luau has modules only.


Debugging

It seems that we will not have debugging in the first LuaSL version, but it will be added later.

Luau has the possibility to add a debugger to set stop points, watch variables, step on code and inspect variables


Co-routines

They will be also added later, not in the first version.

It allows that a function can pause itself while waiting for something to happen, and another function can resume it when that happens.

It will be useful for functions that use asynchronous calls or timers, and other advanced interactions.