Can a local function replace\override itself in Lua - function

In Lua is it possible to replace a local function from within itself? For example:
local function emptyFunction(arg)
return
end
local function exampleFunction(arg)
local result, err = io.open("/tmp/BadFile","w")
if result == nil then
print(err)
exampleFunction = emptyFunction
return
end
io.close(result)
end

To redefine a function within the function itself, you need a reference to the function in a variable that has already been declared before the variable is assigned a reference to the function.
First example -- how not to do it -- does not work because "fx" is not in scope inside fx, as intuition suggests (to me) it would not be.
Frankly, I don't know how to precisely describe what "fx" inside the function represents -- but it seems to be a global variable that is in a scope that is somehow "more global than a 'global local' declaration."
In the global space, I always assumed these two were equivalent:
foo = 'bar';
local foo = 'bar';
Precisely speaking, they apparently are not genuinely equivalent, if you have a way of accessing both. This first example does exactly that, and here's why:
When you do this...
local myfunc = function () ...
... what are you actually doing?
You're first declaring an anonymous function, and second declaring "myfunc" and third setting "myfunc" as a reference to the anonymous function you just created. Until the moment the function begins to exist, "local myfunc" does not yet exist, because the statement that declares it hasn't actually been executed yet. (At least, that's how I perceive it.)
Here's the non-working version that illustrates this:
local fx = function ()
print(fx);
print("inside the original fx")
fx = function() print "I was redefined" end
end
function f2()
print("f2")
f2 = fx
end
f = f2
print(fx);
fx(); fx(); f2(); f2() f();
function: 0x21a6140 -- original "fx" ref is in "global local fx"
nil -- inner "fx" -- NOT set on first iteration, so it
inside the original fx -- can't be the same varliable
function: 0x21a6510 -- now it's set, but to new function,
inside the original fx -- but the "global local fx" does not contain our new function
f2
function: 0x21a6510
inside the original fx
f2
Second example, we declare local fx first, and then set it to a reference to the function. There are no other changes.
local fx; -- declare before assignment
fx = function ()
print(fx);
print("inside the original fx")
fx = function() print "I was redefined" end
end
function f2()
print("f2")
f2 = fx
end
f = f2
print(fx);
fx(); fx(); f2(); f2() f();
function: 0x2188e50 -- original function
function: 0x2188e50 -- same reference, so this one *is* in scope
inside the original fx
I was redefined -- and redefining it works exactly as expected
f2
I was redefined
f2
So, yes, there is a way. You need a global local variable that is declared, and subsequently you need to set that to a reference to the function so that it is in scope in the function that tries to redefine it.
In a similar way, the f2 function can't redefine itself. It only redefines what f2 means, inside f2 while f2() is running.

Nothing prevents you from doing so. Local or not function name in Lua is actually variable name which points to function itself.
So there is no any difference between
local function f1()
...
end
and
local f1 = function()
...
end
In both cases f1 is in scope of function body.
However, such replace won't change no any external references
function f1()
print("f1")
end
function f2()
print("f2")
f2 = f1
end
f = f2
f1(); f2(); f2() f();
will lead to output
f1
f2
f1
f2
Note, that if you add local keyword to declarations - nothing changes

Related

Arguments not properly passed to function

I am new to Lua, and I downloaded and wanted to use the class.lua file from this link.
However, when I attempt to call the Board:addSign function from anywhere, no matter what I do, the arguments passed are the value of the place variable and nil instead of the values of the sign and place variables. How would I go around fixing that?
Here's my code, both main and the class itself.
Class = require 'class'
require 'Board'
board = Board()
for place = 1, 9 do
print('Input sign: ')
sign = io.read()
board.addSign(sign, place)
end
Board = Class{}
function Board:init()
array = {}
for n = 1, 9 do
array[n] = ' '
end
--
self.array = array
end
function Board:addSign(sign, place)
print(sign) -- outputs whatever I passed as place
print(place) -- outputs nil no matter what
self.array[place] = sign -- crashes here since place is nil
end
Use board:addSign instead of board.addSign.
function Board:addSign(sign, place) end
is syntactic sugar for
function Board.addSign(self, sign, place) end
This allows you to do things like self.array[place] = sign inside that function.
So you defined a function with 3 parameters but you only provide 2 when calling it.
board.addSign(sign, place)
Inside your function that basically results in
local self = sign
local sign = place
local place = nil
So either call Board:addSign(sign, place) or Board.addSign(Board, sign, place)

Corona Lua call external function

I have block_basic.lua that I want to call another function in touch_input.lua
block_basic.lua does:
local screen_touch = require( "touch_input")
local onScreenTouch = screen_touch.onScreenTouch
local function touched( event )
-- 'self' parameter exists via the ':' in function definition
print(onScreenTouch, screen_touch, event)
end
From what I am seeing event seems to be correct (a table), screen_touch is also correct. But the function (screen_touch.onScreenTouch) is always nil and I don't know why
In touch_input.lua I simply have:
local function onScreenTouch( event )
-- no 'self' parameter
etc. etc.
Why is it nil? Why can't I call it?
You don't show what you return in touch_input.lua, but if you expect the first two lines of your script to work, it needs to be something like this:
local function onScreenTouch( event )
...
return {
onScreenTouch = onScreenTouch
}
Since you don't get a run-time error on line 2, you may be returning a table already, but you need to make sure that onScreenTouch field of that table points to onScreenTouch function.
Here is how your files should be:
touch_input.lua:
local M = {}
M.onScreenTouch = function( event )
--some code here
end
return M
block_basic.lua:
local screen_touch = require( "touch_input")
local onScreenTouch = screen_touch.onScreenTouch
print(onScreenTouch, screen_touch, event)
I tested it. It works 100%.
More info:
http://www.coronalabs.com/blog/2012/08/28/how-external-modules-work-in-corona/
http://www.coronalabs.com/blog/2011/09/05/a-better-approach-to-external-modules/
http://developer.coronalabs.com/content/modules
http://www.coronalabs.com/blog/2011/07/06/using-external-modules-in-corona/

How do I set a function to a variable in MATLAB

As a homework assignment, I'm writing a code that uses the bisection method to calculate the root of a function with one variable within a range. I created a user function that does the calculations, but one of the inputs of the function is supposed to be "fun" which is supposed to be set equal to the function.
Here is my code, before I go on:
function [ Ts ] = BisectionRoot( fun,a,b,TolMax )
%This function finds the value of Ts by finding the root of a given function within a given range to a given
%tolerance, using the Bisection Method.
Fa = fun(a);
Fb = fun(b);
if Fa * Fb > 0
disp('Error: The function has no roots in between the given bounds')
else
xNS = (a + b)/2;
toli = abs((b-a)/2);
FxNS = fun(xns);
if FxNS == 0
Ts = xNS;
break
end
if toli , TolMax
Ts = xNS;
break
end
if fun(a) * FxNS < 0
b = xNS;
else
a = xNS;
end
end
Ts
end
The input arguments are defined by our teacher, so I can't mess with them. We're supposed to set those variables in the command window before running the function. That way, we can use the program later on for other things. (Even though I think fzero() can be used to do this)
My problem is that I'm not sure how to set fun to something, and then use that in a way that I can do fun(a) or fun(b). In our book they do something they call defining f(x) as an anonymous function. They do this for an example problem:
F = # (x) 8-4.5*(x-sin(x))
But when I try doing that, I get the error, Error: Unexpected MATLAB operator.
If you guys want to try running the program to test your solutions before posting (hopefully my program works!) you can use these variables from an example in the book:
fun = 8 - 4.5*(x - sin(x))
a = 2
b = 3
TolMax = .001
The answer the get in the book for using those is 2.430664.
I'm sure the answer to this is incredibly easy and straightforward, but for some reason, I can't find a way to do it! Thank you for your help.
To get you going, it looks like your example is missing some syntax. Instead of either of these (from your question):
fun = 8 - 4.5*(x - sin(x)) % Missing function handle declaration symbol "#"
F = # (x) 8-4.5*(x-sin9(x)) %Unless you have defined it, there is no function "sin9"
Use
fun = #(x) 8 - 4.5*(x - sin(x))
Then you would call your function like this:
fun = #(x) 8 - 4.5*(x - sin(x));
a = 2;
b = 3;
TolMax = .001;
root = BisectionRoot( fun,a,b,TolMax );
To debug (which you will need to do), use the debugger.
The command dbstop if error stops execution and opens the file at the point of the problem, letting you examine the variable values and function stack.
Clicking on the "-" marks in the editor creates a break point, forcing the function to pause execution at that point, again so that you can examine the contents. Note that you can step through the code line by line using the debug buttons at the top of the editor.
dbquit quits debug mode
dbclear all clears all break points

Passing variables into a function in Lua

I'm new to Lua, so (naturally) I got stuck at the first thing I tried to program. I'm working with an example script provided with the Corona Developer package. Here's a simplified version of the function (irrelevant material removed) I'm trying to call:
function new( imageSet, slideBackground, top, bottom )
function g:jumpToImage(num)
print(num)
local i = 0
print("jumpToImage")
print("#images", #images)
for i = 1, #images do
if i < num then
images[i].x = -screenW*.5;
elseif i > num then
images[i].x = screenW*1.5 + pad
else
images[i].x = screenW*.5 - pad
end
end
imgNum = num
initImage(imgNum)
end
end
If I try to call that function like this:
local test = slideView.new( myImages )
test.jumpToImage(2)
I get this error:
attempt to compare number with nil
at line 225. It would seem that "num" is not getting passed into the function. Why is this?
Where are you declaring g? You're adding a method to g, which doesn't exist (as a local). Then you're never returning g either. But most likely those were just copying errors or something. The real error is probably the notation that you're using to call test:jumpToImage.
You declare g:jumpToImage(num). That colon there means that the first argument should be treated as self. So really, your function is g.jumpToImage(self, num)
Later, you call it as test.jumpToImage(2). That makes the actual arguments of self be 2 and num be nil. What you want to do is test:jumpToImage(2). The colon there makes the expression expand to test.jumpToImage(test, 2)
Take a look at this page for an explanation of Lua's : syntax.

How to pass a function as argument

I'm using Scilab and I'm trying to make a function like the following:
function p = binary_search(myf,a,b)
The target is to make a binary_search to find such p that: myf(p) = 0 in [a,b].
I want to do something like this:
root = binary_search("x^3 - 10",1,2)
Where the first string is a definition of a function.
The only way I found is defining a function called x3:
function x = x3(p)
x = p^3 - 10;
endfunction
and then, inside binary_search, do something like:
fa = x3(a);
Any ideas?
Thank You!
If you have defined the function f(x) = x^3 - 10 , either using deff('y=f(x)','y=x^3-10') or the regular "function ... endfunction" syntax, then you can simply pass f as an argument: define
function r = binary_search(f,a,b)
% do the binary search here and store the result in r
endfunction
Then you can call
---> binary_search(f, 1, 2)
which works fine in SciLab.
In MATLAB/octave, the interpreter considers " f " as an equivalent for f(), i.e., it would execute the function f without arguments, which will result in an error "x undefined". To avoid this, you have to type an # in front of f:
---> binary_search( #f, 1, 2) %% in MATLAB/octave
Functions in Scilab can be passed as arguments to other functions. Therefore, if you have one function, f:
function y=f(x)
y = x^3 - 10
endfunction
you are free to pass that to another function,
root = binary_search("x^3 - 10",1,2)
deff is simply a way to quickly define a function- usually inline on the interpreter.
Alternatively, you can also pass an expression as a string to a function and have that evaluated using the evstr command:
function p = binary_search(expression, a, b)
evstr expression
//Rest of your code
endfunction
You would implement this on the interpreter thus:
expression = "a^3 - 10"
root = binary_search(expression, 1, 2)
I found a solution:
In the main window (the interpreter), I define the function like:
deff('[y] = square(x)','y=x^2')
Then, I call
bi(square,0,2)
In the function, I just do 'f(x)':
function [x] = bi(f,a,b)
fa = f(a);