I'm trying to create a calculator using closures and functions. I got until the actual calculation function which takes in two values, then the user can select which operator to use (addition, multiplication, etc). I don't know how to actually return the value of that calculation.
A closure is, effectively, a function and you simply invoke it as such.
return operator(numberOne:valueOne, numberTwo:valueTwo)
Related
It's easy to create an array of functions and execute them in a loop.
It's easy to provide arguments in either a corresponding array of the same length or the array could be of tuples (fn, arg).
For 2, the loop is just
for fn_ar in arr # arr is [(myfunc, [1,2,3]), (func2, [10,11,12]), ...]
fn_ar[1](fn_ar[2])
end
Here is the problem: the arguments I am using are arrays of very large arrays. In #2, the argument that will be called with the function will be the current value of the array when the arg entry of the tuple is initially created. What I need is to provide the array names as the argument and defer evaluation of the arguments until the corresponding function is run in the loop body.
I could provide the arrays used as input as an expression and eval the expression in the loop to supply the needed arguments. But, eval can't eval in local scope.
What I did that worked (sort of) was to create a closure for each function that captured the arrays (which are really just a reference to storage). This works because the only argument to each function that varies in the loop body turns out to be the loop counter. The functions in question update the arrays in place. The array argument is really just a reference to the storage location, so each function executed in the loop body sees the latest values of the arrays. It worked. It wasn't hard to do. It is very, very slow. This is a known challenge in Julia.
I tried the recommended hints in the performance section of the manual. Make sure the captured variables are typed before they are captured so the JIT knows what they are. No effect on perf. The other hint is to put the definition of the curried function with the data for the closure in let block. Tried this. No effect on perf. It's possible I implemented the hints incorrectly--I can provide a code fragment if it helps.
But, I'd rather just ask the question about what I am trying to do and not muddy the waters with my past effort, which might not be going down the right path.
Here is a small fragment that is more realistic than the above:
Just a couple of functions and arguments:
(affine!, "(dat.z[hl], dat.a[hl-1], nnw.theta[hl], nnw.bias[hl])")
(relu!, "(dat.a[hl], dat.z[hl])")
Of course, the arguments could be wrapped as an expression with Meta.parse. dat.z and dat.a are matrices used in machine learning. hl indexes the layer of the model for the linear result and non-linear activation.
A simplified version of the loop where I want to run through the stack of functions across the model layers:
function feedfwd!(dat::Union{Batch_view,Model_data}, nnw, hp, ff_execstack)
for lr in 1:hp.n_layers
for f in ff_execstack[lr]
f(lr)
end
end
end
So, closures of the arrays is too slow. Eval I can't get to work.
Any suggestions...?
Thanks,
Lewis
I solved this with the beauty of function composition.
Here is the loop that runs through the feed forward functions for all layers:
for lr in 1:hp.n_layers
for f in ff_execstack[lr]
f(argfilt(dat, nnw, hp, bn, lr, f)...)
end
end
The inner function parameter to f called argfilt filters down from a generic list of all the inputs to return a tuple of arguments needed for the specific function. This also takes advantage of the beauty of method dispatch. Note that the function, f, is an input to argfilt. The types of functions are singletons: each function has a unique type as in typeof(relu!), for example. So, without any crazy if branching, method dispatch enables argfilt to return just the arguments needed. The performance cost compared to passing the arguments directly to a function is about 1.2 ns. This happens in a very hot loop that typically runs 24,000 times so that is 29 microseconds for the entire training pass.
The other great thing is that this runs in less than 1/10 of the time of the version using closures. I am getting slightly better performance than my original version that used some function variables and a bunch of if statements in the hot loop for feedfwd.
Here is what a couple of the methods for argfilt look like:
function argfilt(dat::Union{Model_data, Batch_view}, nnw::Wgts, hp::Hyper_parameters,
bn::Batch_norm_params, hl::Int, fn::typeof(affine!))
(dat.z[hl], dat.a[hl-1], nnw.theta[hl], nnw.bias[hl])
end
function argfilt(dat::Union{Model_data, Batch_view}, nnw::Wgts, hp::Hyper_parameters,
bn::Batch_norm_params, hl::Int, fn::typeof(relu!))
(dat.a[hl], dat.z[hl])
end
Background: I got here by reasoning that I could pass the same list of arguments to all of the functions: the union of all possible arguments--not that bad as there are only 9 args. Ignored arguments waste some space on the stack but it's teeny because for structs and arrays an argument is a pointer reference, not all of the data. The downside is that every one of these functions (around 20 or so) all need to have big argument lists. OK, but goofy: it doesn't make much sense when you look at the code of any of the functions. But, if I could filter down the arguments just to those needed, the function signatures don't need to change.
It's sort of a cool pattern. No introspection or eval needed; just functions.
It's not "Parameter" or "Argument", but "variable function" and "variable arguments", "variable number of arguments". I found this confusing and want to know what are these things.
I found it inside Programming in Lua First Edition 5.1
An important use for unpack is in a generic call mechanism. A generic call mechanism allows you to call any function, with any arguments, dynamically. In ANSI C, for instance, there is no way to do that. You can declare a function that receives a variable number of arguments (with stdarg.h) and you can call a variable function, using pointers to functions. However, you cannot call a function with a variable number of arguments: Each call you write in C has a fixed number of arguments and each argument has a fixed type. In Lua, if you want to call a variable function f with variable arguments in an array a, you simply write
That paragraph is rather sloppily written, construing "parameter" and "argument" and uses the bespoke term "variable function" for what I assume was intended to be "variadic function", which is what C actually has.
In any case, the point I believe this paragraph is intended to convey is the following.
C has variadic functions: functions which can take a variable number of parameters. This means you can call them with an arbitrary number of arguments, which the function will then process according to its needs. However, the sequence of arguments given to a function is always hard-coded at the call site. You cannot build a runtime list of values and pass each value to a variadic function as multiple distinct arguments, such that the function would see each value from the list as a separate parameter. At least, you cannot do this without hard-coding the length of the list at the call site.
In Lua, you can do this, taking a list of "arbitrary" length (arguments do have a maximum limit) and calling a function such that the function sees each value in the list as a distinct parameter. No matter the number of values in the list, f(unpack(list)) will pass each value as a separate parameter to f.
In Lua reference manual, it says that every value has a type which might be one of the local, global, table field types. My question is what's the type of the anonymous function in Lua? What life cycle the anonymous function has? I just show an example.
local co = coroutine.create( function () print "hi" end )
print(coroutine.status(co))
I think there is some mix of concepts here. As others already said, Lua only has anonymous functions, which have type function (type(function() end) == 'function'). These anonymous functions can be assigned to variables, which can then be used to call functions; these are conveniently used as "names" for functions, but they are really names for variables that store values of type "function".
In terms of their lifecycle, they are not different from any other variable: if the function is no longer reacheable, it will be garbage collected at some point. For example, a function inside this block do local func = function() end end is not reachable from outside of the block and will be collected.
The example you have shown creates a coroutine, which takes a function and creates a value of type thread: type(coroutine.create(function() end)) == "thread". These coroutines may be in different states and their state is returned by coroutine.status function; in your case it's going to be "suspended".
You are confusing values and variables. Values have data types like string, table, function, etc. Call the type function on an expression to get its type.
Variables refer to values but don't have a data type. The categories you are referring to: global, local and table field are not data types.
The concepts are orthogonal. For example: A local value can be of any data type; A function can be referred to by a global, local or table field.
As explained elsewhere (manual and comments), all function values are anonymous so that is not a separate category.
The lifetime of a value is always from the time it was first evaluated until no variable references it.
A function has the type of function. In Lua, functions are first class citizen: First-Class Function
In actual memory, the function is just some block of memory that contains set of commands (similar to any other type e.g. integers)
I am using SpreadsheetGear and have been given a spreadsheet with a VBA macro that I need to convert to a custom function (as SSG can't handle VBA code). The macro calls Excel functions (Match, Index) and I can't see how to call these functions from within my custom function. Any ideas if this is possible and how to do it?
Thanks
You can evaluate Excel formula strings by using the ISheet.EvaluateValue(...) method. Example:
// A1:A3 on "Sheet1" will be summed up.
object val = workbook.Worksheets["Sheet1"].EvaluateValue("SUM(A1:A3)");
// Ensure we actually get a numeric value back
if(val != null && val is double)
{
double sum = (double)val;
Console.WriteLine(sum);
}
However, it sounds like you will be using this method inside your custom function, so I should point out that you cannot use this method for any sheet that belongs to any workbook in the IWorkbookSet that is currently being calculated. Please review the rules that are laid out in the Remarks section for the Function.Evaluate(...) method, pasted below, particularly the ones I bolded:
The implementation of this method must follow a number of rules:
The method must be thread safe. Some versions of SpreadsheetGear call this method from multiple threads at the same time.
The method must not use any API in the workbook set which is being calculated except for IArguments.CurrentWorksheet.Name, IArguments.CurrentWorksheet.Index or IArguments.CurrentWorksheet.Workbook.Name.
All access to cells must be through arguments.
Accessing the IArguments indexer has the side effect of converting references to ranges or arrays to a single simple value. Use GetArrayDimensions and GetArrayValue to access the individual values of a range or array. For example, if the first custom function argument is the range A1:C3, setting a watch on arguments[0] in a debugger will convert this range to a single simple value.
No references to interfaces or objects passed to, or acquired during the execution of this method should be used after this method completes execution.
So if you call ISheet.EvaluateValue(...) within your custom function, it would have to be done on some sheet that belongs to an IWorkbookSet other than the one currently being calculated. It would also need to be done in a thread-safe manner, as per the first rule mentioned above.
I'm planning to have collection of items stored in a TCollection.
Each item will derive from TBaseItem which in turn derives from TCollectionItem,
With this in mind the Collection will return TBaseItem when an item is requested.
Now each TBaseItem will have a Calculate function, in the the TBaseItem this will just return an internal variable, but in each of the derivations of TBaseItem the Calculate function requires a different set of parameters.
The Collection will have a Calculate All function which iterates through the collection items and calls each Calculate function, obviously it would need to pass the correct parameters to each function
I can think of three ways of doing this:
Create a virtual/abstract method for each calculate function in the base class and override it in the derrived class, This would mean no type casting was required when using the object but it would also mean I have to create lots of virtual methods and have a large if...else statement detecting the type and calling the correct "calculate" method, it also means that calling the calculate method is prone to error as you would have to know when writing the code which one to call for which type with the correct parameters to avoid an Error/EAbstractError.
Create a record structure with all the possible parameters in and use this as the parameter for the "calculate" function. This has the added benefit of passing this to the "calculate all" function as it can contain all the parameters required and avoid a potentially very long parameter list.
Just type casting the TBaseItem to access the correct calculate method. This would tidy up the TBaseItem quite alot compared to the first method.
What would be the best way to handle this collection?
If they all have different method signatures, then you're not really gaining anything by having virtual methods - they might as well be static. I would be in favor of a "generic"/"canonical" set of parameters as in your case 2, and virtual/overridden Calculate methods, at least based on the description you've given so far.