This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
ardera's profile picture

Arderas Link API (linked primitive values)

Started by ardera, 19 October 2014 - 10:06 AM
ardera #1
Posted 19 October 2014 - 12:06 PM
Introduction
This is an utility which synces/links primitive types like numbers or strings.
These are normally passed by value:

local a = 100
local b = a
a = 50
print(b ) --still 100

in some cases, it's useful if numbers are passed by reference, like in this example:

local a = 100
local b = a
a = 50
print(b ) --its... 50! :0
This is not how this API works, it's just an example.

I made a little library with 2 functions, that uses the tables property to be passed byref (=by reference :P/>) and some metamethods.

pastebin get Qp3SYHr4 linkapi


How to use it?

It has 2 functions:

link(value, id) -- create a normal link
slink(value, id) -- create a stronglink

The normal link

Creating one is easy:

local a = link(value, id) -- value and id are optional
a.s = 125 -- set the value of the link
print(a) -- will print 125

getting the absolute value of a link:

local absolutevalue = a.g -- absolutevalue is a number, a is a table
print(absolutevalue) -- will print 125

creating copies of that link:

b = a() -- creates a new copy of that link
print(b ) -- will print 125

doing arithmetic:

local numb = 25 + a -- numb is a number (notice that, its important for the behavior of stronglinks!)
print(numb) -- will print 150
-- a and b are both tables, but they can fully be handled as numbers

only comparing doesn't work that well, lua's __eq metamethod is not thaaat optimal:

print(a == 125) -- false
print(a == b ) -- true
print(a.g == 125) -- true

You can't compare a link with a number, but you can compare it with a link and you can compare the absolute value (a.g) with the number.


The stronglink

You can use stronglinks exactly like normal links, the only difference is the behavior when doing arithmetic with them.
The absolute value of a stronglink is dependent on the stronglinks it's created with.

You can create them like a normal link:

local a = slink(150, id) -- value and id are optional again

But the behave different in arithmetic:

local b = a + 50 -- b is a stronglink (remember? the type of numb was a number!)
print(b ) -- will print 200
a.s = 200 -- lets change a to 200
print(b ) -- will print 250! (which is a + 50)


Thats it.

Links, especially stronglinks are useful for, for example when a screen or a window resizes, and you don't want to compute all your stuff again. Stronglinks will automatically recalculate your measurements.
I know, it's a bit complicated, but once you understood it, it's easy and pretty useful.
Originally, I wanted #a to return the absolute value, but the usage of the __len metamethod for tables is new in lua 5.2, but computercraft uses lua 5.1.

I hope you understand how this can be used, and I hope you understood my bad english :)/>
Edited on 19 October 2014 - 10:09 AM
Dragon53535 #2
Posted 20 October 2014 - 01:19 AM
Umm technically I believe that a string is not a primitive data type.
MKlegoman357 #3
Posted 20 October 2014 - 02:22 PM
Umm technically I believe that a string is not a primitive data type.

Technically, a string acts similar to a table (you can do: ("str")["len"]()), maybe it's something like userdata. But it is still being passed by value and not by reference. There are three types in Lua that can be passed by reference: tables, functions and coroutines.
ardera #4
Posted 20 October 2014 - 04:18 PM
Umm technically I believe that a string is not a primitive data type.

Technically, a string acts similar to a table (you can do: ("str")["len"]()), maybe it's something like userdata. But it is still being passed by value and not by reference. There are three types in Lua that can be passed by reference: tables, functions and coroutines.
well, it's not a table, and it doesn't work like a table, it's just the inbuilt StringLibrary that sets the static string metatable that you can access the Stringlibrary functions directly from the string.
I believe you could do the same with numbers and booleans if lua would allow you that.

So, in Lua, a string is a primitive type, and it's passed byval :)/>

EDIT: Isn't userdata, although you can't create it in CC without using hacks, passed by reference to?
Edited on 20 October 2014 - 02:22 PM
ElvishJerricco #5
Posted 26 October 2014 - 07:36 PM
Umm technically I believe that a string is not a primitive data type.

Technically, a string acts similar to a table (you can do: ("str")["len"]()), maybe it's something like userdata. But it is still being passed by value and not by reference. There are three types in Lua that can be passed by reference: tables, functions and coroutines.
well, it's not a table, and it doesn't work like a table, it's just the inbuilt StringLibrary that sets the static string metatable that you can access the Stringlibrary functions directly from the string.
I believe you could do the same with numbers and booleans if lua would allow you that.

So, in Lua, a string is a primitive type, and it's passed byval :)/>

EDIT: Isn't userdata, although you can't create it in CC without using hacks, passed by reference to?

Strings behave like tables in bytecode. You can call gettable and the self call instructions with a string just like a table. That isn't possible with any of the other value types in lua. I would be surprised if the implementation behind the scenes wasn't just a modified version of the table type. There's no reason to pass an entire string by value when you can just make it an immutable reference type to save memory (a la java).
ardera #6
Posted 27 October 2014 - 07:21 PM
Strings behave like tables in bytecode. You can call gettable and the self call instructions with a string just like a table. That isn't possible with any of the other value types in lua. I would be surprised if the implementation behind the scenes wasn't just a modified version of the table type. There's no reason to pass an entire string by value when you can just make it an immutable reference type to save memory (a la java).
Behind the scenes, a string has about 20 times more things in common with a number than with a table. The stringlib sets the __index metatag of the LuaString metatable to a table filled with it's functions, if it was possible to set the metatables of other LuaValues, it was possible to "gettable" them. gettable checks if the passed value is a table, or if it has a __index metatag.

So, the only 2 things that let you think a string has much in common with a table, is that you can get values of it, which theoretically is possible with all other LuaValues, and that you can do #str.

I know, strings are strictly seen passed byref, all string values are stored in a table in the String class, but because you can't modify strings, you can just create new strings, they are practically passed byval.

Strings aren't just modified tables. Tables have (I believe) 2 hashmaps containing the values, and a string does not have any hashmap, except the one to store all used string values.

Browse through the LuaJ code if you don't believe me :P/>
Edited on 27 October 2014 - 06:24 PM