I am wondering if it is possible to have a function get a variable if it is not passed explicitly.
The issue is mainly about cleaning up my code, as I have many functions that need to pass every variable that will ever be used to the next function.
In SML for example, one could easily accomplish this with something like:
fun myFun varx vary varz
let
fun otherFun () = varx
fun otherFun2 () = vary
in
otherFun() + otherFun()
end
Is there a way to allow other functions to see variables that are not explicitly passed to it? Or is this just not the way one would program in erlang?
Erlang variable scope works much in the same way:
E.g:
add_two(X) ->
F = fun(Y) ->
X + Y
end,
F(2).
Hope this helps.
Related
The context in this example is Python 3
I see a lot of code that runs a function() and assign it to some var, but doesn't use this variable later.
def func():
# do some stuff
return value
var = func(x)
# then never use var
Does it matter whether I assign var or not because the func already returned it?
Does this behave the same if func is a recursive function and returns at a deeper level of recursion?
[edit]: Consider func is a recursive function (I'll recursively call it until i find what I need from return)
Note: Yes, the code could work regardless of assignment to var (as pointed out in comments e.g. print() doesn't need to be assigned), and regardless of language given specific safeguards, but the question is more about best practices, pitfalls, gotchas, etc.
THANK YOU, community!
So I'm trying to do an assignment for an ml course, the issue is that the function requires a set type: int * int -> int for example, and the way that I see to solve the problem is to use another function (say for iteration) to solve the problem.
I believe that lisp has some kind of way of having a function be in scope for only one other function.
I think that this could be done:
fun a (x, y) =
let
fun b (i,j) = ...;
in
...;
[Not sure of exact syntax for this but I remember reading something like this only it was for temporary variables (which could be functions?]
but please correct me if this is wrong.
In ML, functions are first class citizens (i.e. values). You can bind them via let just like any other value.
Therefore, your idea is correct. It is especially a good design for functions passed as "iterators" (i.e. to map/fold/iter). Your question is too vague however for any further advise.
I'm trying to figure out a way to get all functions in a Lua script. This script has been compiled into a function through loadfile. For example, I'd want to get every function defined in the script below.
function example1()
end
local function example2()
end
local library = {}
function library:example3()
end
(function()
-- Functions like this too.
end)
The names aren't important, I'm just looking for a way to get the actual functions so I can use them in debug.getinfo and get information like the lines they were defined in. I have LuaJIT, if that makes this any easier. Is something like this even possible? Thanks in advance.
I guess the file declares its functions as global, or it would be really easy to track what is returned.
If that's the case, you can cycle through all the global items with a generic for loop, and only take the functions from them:
allFuncs = {}
for key, item in pairs(_G) do
if type(item) == "function" then
allFuncs[#allFuncs + 1] = item
end
end
(_G is the table holding all the global variables)
Then you will have a list (allFuncs) holding all the functions declared, but be aware that it will also contain default functions like setmetatable or xpcall.
It's easy to modify the code to not make this happen, but only use this for testing / learning:
function allFuncs()
local funcsTab = {}
for key, item in pairs(_G) do
if type(item) == "function" then
funcsTab[#funcsTab + 1] = item
end
end
return funcsTab
end
defaultFuncs = allFuncs()
--then you load your file: other functions get declared
--we create another table containg the default + the new functions
myFuncs = allFuncs()
--then you subtract the first table from the second
for i = 1, #myFuncs do
for o = 1, #defaultFuncs do
if myFuncs[i] == defaultFuncs[o] then
table.remove(myFuncs, i)
end
end
end
This is if your file doesn't return anything and declares its functions as globals.
If the file declares them as local and then returns a table containing them, just use the first piece of code replacing _G with that returned table.
This is not likely to be possible without syntax or bytecode analysis as each function definition is an assignment (just has different forms in your examples). See the bytecode inspector and a related discussion here. For the syntax analysis you can use metalua or something like lua-loose-parser. Keep in mind that even those tools won't give you the entire list of functions as some functions may be defined dynamically using loadstring (or similar methods).
If you only have access to the result of loadfile, then you best bet is to use the bytecode analyzer.
This is possible using jit.attach in LuaJIT.
You can attach callbacks to a number of compiler events with
jit.attach. The callback can be called:
when a function has been compiled to bytecode ("bc");
when trace recording starts or stops ("trace");
as a trace is being recorded ("record");
or when a trace exits through a side exit ("texit").
http://wiki.luajit.org/JIT-Compiler-API#jit-attach
jit.attach(function(f)
local funcInfo = jit.util.funcinfo(f)
end, "bc")
I have to create a function which will display each element from a set of strings. I did the following:
module S = Set.Make(String);;
module P = Pervasives;;
let write x = (
P.print_string("{"); let first = true;
S.iter (fun str -> (if first then () else P.print_string(","); P.print_string(str))) x;
P.print_string("}");
P.print_newline
);;
^
At the end of the program (where I placed that sign) it appears I have an error: Syntax error: operator expected.
Please help me solve this.
I believe your syntactic problem is with let. Except in top-level code (outermost level of a module), let must be followed by in.
There are many other problems with this code, but maybe this will let you find the next problem :-)
A few notes:
Variables in OCaml are immutable. So your variable named first will always be true. You can't change it. This (seemingly minor) point is one of the keys to functional programming.
You don't need to reference the Pervasives module by name. That's why it's called "pervasive". You can just say print_string by itself.
Your last call to print_newline isn't a call. This expression just evaluates to the function itself. (You need to give it an argument if you want to call the function.)
Try replacing the semicolon after the let first = true with the keyword in.
I am writing program in Octave and I encountered a problem, I implemented Gauss-Legandre Quadrature and I pass to my Gauss-Legandre function few arguments, and I pass the function to be intergrated in a cell cube, so I can pass few function at a time. I have this piece of code:
for weight=1:length(w)
temp=1;
for fun=1:length(c)
%liczenie iloczynu f(x_i)g(x_i), x_i - pieriwastki wielomianu Legandra
f=c{fun};
nargin(func2str(c{fun}))
if (nargin (func2str(c{fun})) == 1)
disp('a');
temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
else
(b-a)/2 * x(weight) + (a+b)/2;
temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
end
end
%mnozenie wyniku przez odpowiedni wspolczynnik - wage
temp*=w(weight);
result+=temp;
end
In cell array there are function handlers to functions which I want to integrate. Depending on number of arguments that function takes i want to use two different calls for function. If in cell array there is handler to a function that is written in .m file in the same directory as my Octave working directory everything works fine, but when i define function in Octave running time, for example:
function result=a(x)
result=x*x
end
Type
c{1}=#a
and pass this cell array to my function Kwadratury there is an error of nargin
error: nargin: invalid function
error: called from:
Why is that and how can I solve it, so I can define function not only in .m files but also in Octave.
I suspect I have a solution, but as this is Octave-specific and I'm mostly used to MATLAB, your mileage may vary.
You call the nargin function by supplying a string argument, this means that nargin will have to resolve that function and check the number of arguments. When you declare a function in-line, that function is defined within that scope (i.e. your base scope), so resolving the function name will not work from within any function (or it might resolve to a built-in function, which is even worse behavior).
The best solution is to use nargin(c{fun}) instead of nargin(func2str(c{fun})). That way you pass the actual function handle along, and there is no need to resolve the function name to the actual function, and hence no possible ambiguity.
In general I recommend against using strings to pass functions: that why function handles are included in MATLAB, so anyone reading your code (or a static code analysis tool) will be able to understand you are working with functions. When using strings, everything becomes ambiguous: does a string 'a' refer to the function a or to the first letter in the alphabet?
With regard to using inline functions, I don't know whether Octave supports this, but if you function is quite simple, it's easier to define an anonymous function, such as your example, by a = #(x)(x*x);. That is a construct that is supported by MATLAB, so that makes your code more portable to other environments (well, you'd still need to replace X *= A with X = X * A; to be MATLAB compatible).
edit:
Another possibility could be to just try out whether a form with multiple parameters works and fall back to the one parameter form when necessary:
try
(b-a)/2 * x(weight) + (a+b)/2;
temp*=f((b-a)/2 * x(weight) + (a+b)/2,I,points);
catch ME
try
disp('a');
temp*=c{fun}((b-a)/2 * x(weight) + (a+b)/2);
catch ME
end
end
You might want to check whether the returned error ME really states that a wrong number of arguments is used to allow other errors through. I do admit this is an ugly work-around, but since Octave apparently doesn't support function handles for nargin, it might be the only way you'd get what you want for inline functions.