Can you create anonymous code blocks in Lua? - lua

In programming languages such as C you can create an anonymous code block to limit the scope of variables to inside the block can the same be done with Lua?
If so what would be the Lua equivalent of the following C code?
void function()
{
{
int i = 0;
i = i + 1;
}
{
int i = 10;
i = i + 1;
}
}

You want to use do...end. From the manual:
A block can be explicitly delimited to produce a single statement:
stat ::= do block end
Explicit blocks are useful to control the scope of variable
declarations. Explicit blocks are also sometimes used to add a return
or break statement in the middle of another block
function fn()
do
local i = 0
i = i + 1
end
do
local i = 10
i = i + 1
end
end

You can delimit a block with keyword do & end.
Reference: Programming in Lua

Running an anonymous function happens as follows:
(function(a,b) print(a+b) end)(1,4)
It outputs 5.

Related

How to modify a functions internal variables at runtime and pass it to another function?

Functions in Dart are first-class objects, allowing you to pass them to other objects or functions.
void main() {
var shout = (msg) => ' ${msg.toUpperCase()} ';
print(shout("yo"));
}
This made me wonder if there was a way to modify a function a run time, just like an object, prior to passing it to something else. For example:
Function add(int input) {
return add + 2;
}
If I wanted to make the function a generic addition function, then I would do:
Function add(int input, int increment) {
return add + increment;
}
But then the problem would be that the object I am passing the function to would need to specify the increment. I would like to pass the add function to another object, with the increment specified at run time, and declared within the function body so that the increment cannot be changed by the recipient of the function object.
The answer seems to be to use a lexical closure.
From here: https://dart.dev/guides/language/language-tour#built-in-types
A closure is a function object that has access to variables in its
lexical scope, even when the function is used outside of its original
scope.
Functions can close over variables defined in surrounding scopes. In
the following example, makeAdder() captures the variable addBy.
Wherever the returned function goes, it remembers addBy.
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(int addBy) {
return (int i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
In the above cases, we pass 2 or 4 into the makeAdder function. The makeAdder function uses the parameter to create and return a function object that can be passed to other objects.
You most likely don't need to modify a closure, just the ability to create customized closures.
The latter is simple:
int Function(int) makeAdder(int increment) => (int value) => value + increment;
...
foo(makeAdder(1)); // Adds 1.
foo(makeAdder(4)); // Adds 2.
You can't change which variables a closure is referencing, but you can change their values ... if you an access the variable. For local variables, that's actually hard.
Mutating state which makes an existing closure change behavior can sometimes be appropriate, but those functions should be very precise about how they change and where they are being used. For a function like add which is used for its behavior, changing the behavior is rarely a good idea. It's better to replace the closure in the specific places that need to change behavior, and not risk changing the behavior in other places which happen to depend on the same closure. Otherwise it becomes very important to control where the closure actually flows.
If you still want to change the behavior of an existing global, you need to change a variable that it depends on.
Globals are easy:
int increment = 1;
int globalAdder(int value) => value + increment;
...
foo(globalAdd); // Adds 1.
increment = 2;
foo(globalAdd); // Adds 2.
I really can't recommend mutating global variables. It scales rather badly. You have no control over anything.
Another option is to use an instance variable to hold the modifiable value.
class MakeAdder {
int increment = 1;
int instanceAdd(int value) => value + increment;
}
...
var makeAdder = MakeAdder();
var adder = makeAdder.instanceAdd;
...
foo(adder); // Adds 1.
makeAdder.increment = 2;
foo(adder); // Adds 2.
That gives you much more control over who can access the increment variable. You can create multiple independent mutaable adders without them stepping on each other's toes.
To modify a local variable, you need someone to give you access to it, from inside the function where the variable is visible.
int Function(int) makeAdder(void Function(void Function(int)) setIncrementCallback) {
var increment = 1;
setIncrementCallback((v) {
increment = v;
});
return (value) => value + increment;
}
...
void Function(int) setIncrement;
int Function(int) localAdd = makeAdder((inc) { setIncrement = inc; });
...
foo(localAdd); // Adds 1.
setIncrement(2);
foo(localAdd); // Adds 2.
This is one way of passing back a way to modify the local increment variable.
It's almost always far too complicated an approach for what it gives you, I'd go with the instance variable instead.
Often, the instance variable will actually represent something in your model, some state which can meaningfully change, and then it becomes predictable and understandable when and how the state of the entire model changes, including the functions referring to that model.
Using partial function application
You can use a partial function application to bind arguments to functions.
If you have something like:
int add(int input, int increment) => input + increment;
and want to pass it to another function that expects to supply fewer arguments:
int foo(int Function(int input) applyIncrement) => applyIncrement(10);
then you could do:
foo((input) => add(input, 2); // `increment` is fixed to 2
foo((input) => add(input, 4); // `increment` is fixed to 4
Using callable objects
Another approach would be to make a callable object:
class Adder {
int increment = 0;
int call(int input) => input + increment;
}
which could be used with the same foo function above:
var adder = Adder()..increment = 2;
print(foo(adder)); // Prints: 12
adder.increment = 4;
print(foo(adder)); // Prints: 14

Lua: Workaround for boolean conversion of a class variable when enclosed in parentheses

In the below code, can anyone explain why does t1:print() works but (t1):print fails. I am attempting to make something like (t1 * 3):print() work without using an intermediate variable.
function classTestTable(members)
members = members or {}
local mt = {
__metatable = members;
__index = members;
}
function mt.print(self)
print("something")
end
return mt
end
TestTable = {}
TestTable_mt = ClassTestTable(TestTable)
function TestTable:new()
return setmetatable({targ1 = 1}, TestTable_mt )
end
TestTable t1 = TestTable:new()
t1:print() -- works fine.
(t1):print() -- fails with error "attempt to call a boolean value"
Lua expressions can extend over multiple lines.
print
(3)
Will print 3
So
t1:print()
(t1):print()
actually is equivalent to
t1:print()(t1):print()
or
local a = t1:print()
local b = a(t1)
b:print()
So you're calling the return value of t1:print()
To avoid that follow Egors advice and separate both statements with a semicolon.
t1:print();(t1):print()

Simple LZW Compression doesnt work

I wrote simple class to compress data. Here it is:
LZWCompressor = {}
function LZWCompressor.new()
local self = {}
self.mDictionary = {}
self.mDictionaryLen = 0
-- ...
self.Encode = function(sInput)
self:InitDictionary(true)
local s = ""
local ch = ""
local len = string.len(sInput)
local result = {}
local dic = self.mDictionary
local temp = 0
for i = 1, len do
ch = string.sub(sInput, i, i)
temp = s..ch
if dic[temp] then
s = temp
else
result[#result + 1] = dic[s]
self.mDictionaryLen = self.mDictionaryLen + 1
dic[temp] = self.mDictionaryLen
s = ch
end
end
result[#result + 1] = dic[s]
return result
end
-- ...
return self
end
And i run it by:
local compressor = LZWCompression.new()
local encodedData = compressor:Encode("I like LZW, but it doesnt want to compress this text.")
print("Input length:",string.len(originalString))
print("Output length:",#encodedData)
local decodedString = compressor:Decode(encodedData)
print(decodedString)
print(originalString == decodedString)
But when i finally run it by lua, it shows that interpreter expected string, not Table. That was strange thing, because I pass argument of type string. To test Lua's logs, i wrote at beggining of function:
print(typeof(sInput))
I got output "Table" and lua's error. So how to fix it? Why lua displays that string (That i have passed) is a table? I use Lua 5.3.
Issue is in definition of method Encode(), and most likely Decode() has same problem.
You create Encode() method using dot syntax: self.Encode = function(sInput),
but then you're calling it with colon syntax: compressor:Encode(data)
When you call Encode() with colon syntax, its first implicit argument will be compressor itself (table from your error), not the data.
To fix it, declare Encode() method with colon syntax: function self:Encode(sInput), or add 'self' as first argument explicitly self.Encode = function(self, sInput)
The code you provided should not run at all.
You define function LZWCompressor.new() but call CLZWCompression.new()
Inside Encode you call self:InitDictionary(true) which has not been defined.
Maybe you did not paste all relevant code here.
The reason for the error you get though is that you call compressor:Encode(sInput) which is equivalent to compressor.Encode(self, sInput). (syntactic sugar) As function parameters are not passed by name but by their position sInput inside Encode is now compressor, not your string.
Your first argument (which happens to be self, a table) is then passed to string.len which expects a string.
So you acutally call string.len(compressor) which of course results in an error.
Please make sure you know how to call and define functions and how to use self properly!

lua's loadstring() not working with tables

I have some text and I'm trying to load it via load string. The following works:
local m = loadstring("data = 5")()
But when the data is a table it doesn't work and gives the error "attempt to call a nil"
local m = loadstring("data = { 1 = 10}")()
The table declaration in lua require integer keys to be put inside square brackets:
data = {
[1] = value,
}
The enclosing of keys in square brackets is always allowed, valid and possible. It can be skipped iff your key follows the pattern: [A-Za-z_][A-Za-z0-9_]* (which is the same as a valid variable name in lua)
If you had added an assert you would have got a more helpful message:
local m = assert (loadstring("data = { 1 = 10}"))()
Result:
stdin:1: [string "data = { 1 = 10}"]:1: '}' expected near '='
stack traceback:
[C]: in function 'assert'
stdin:1: in main chunk
[C]: ?
And to actually answer the question, unless the table key happens to follow Lua variable naming rules, you have to put it inside square brackets, eg.
local m = assert (loadstring("data = { [1] = 10}"))()
m is still nil when I do this
What does that matter? The loadstring is done.
Just do this:
assert (loadstring("data = { 1 = 10}"))()
print (data [1])
You don't need the variable m. The loadstring puts a table into data - that is the important thing.

What does independent curly brackets do in Objective-C

So I have this block of code on the book I'm studying. What does this independent {} actually do?
self = [super initWithImageNamed:#"character.png"];
{
self.name = playerName;
self.zPosition = 10;
}
Is this different from
self = [super initWithImageNamed:#"character.png"];
self.name = playerName;
self.zPosition = 10;
It's just scope, there is no difference in the 2 pieces of code you posted, but you could declare a short lived variable inside curly braces and scope it to just those few lines of code.
{
int x = 5;
}
NSLog("%d", x); //error
int x = 10; //legal
The first x variable goes out of scope after the curly's end, so that variable will be cleaned up. It's not a commonly used feature, but could be useful to scope certain variables. You can think of it just like an if or while block with no stipulation to enter that will run once.
Curly braces define a local scope. It can be used simply for code readability, or you can also use it to limit the scope of local variables:
For example:-
-(void)yourMethod
{
{
NSString *str=#test;
}
{
NSString *str=#testing;
}
}
So in the above you can define two same name local variable within the two scope. This is use of independent curly braces.
What Kevin said. More precisely, a group of statements surrounded by {} can be used anywhere a single statement can be. When you code, eg:
if (x == y) {
a = b;
}
you are simply applying this rule to the basic structure of:
if (<test>) <statement>
substituting { <statement_list> } for <statement>.
Likewise with for and do and so forth.

Resources