Currently investigating migrating from mvBase to Unidata and would like to know if User Defined Functions are supported as I cannot see this in the documentation I have downloaded?
e.g I have DATABASIC program with something like
A = #FUNCTION_NAME(VAR1)
Yes, Unidata supports user defined functions.
To create a function in Unidata, use a line like this on line 1 of the code file:
FUNCTION MY.FUNCTION.NAME( ARG1, ARG2 )
Inside the function, use the RETURN statement to return a result:
RETURN ARG1 + ARG2
To call it, you have to indicate that you're going to use it with the DEFFUN statement in the program that will use the function:
DEFFUN MY.FUNCTION.NAME( ARG1, ARG2 )
I usually put my DEFFUN statements near the top of the program, right after any $INCLUDEs. (The parameter names don't have to match between the FUNCTION and DEFFUN lines, but I don't know of any reason to purposefully make them different.)
After that setup, you can call the function by using its name in an expression:
TOTAL = MY.FUNCTION.NAME( 10, 15 )
After that statement, TOTAL will have a value of 25.
I've never seen a function called with the #FUNCTION_NAME syntax in Unidata.
Related
I'm having trouble with function declarations and scope in julia. I have a main function, let's call it mainfunc which accepts some arguments. Within this function, I would ultimately like to call a different function, say callfunc, which takes a function as an argument. This function I will call passfunc.
One further complication I have is that there is a final function which I define outside of the logic which depends on the arguments but still depends on the arguments in a different way. I can call this initfunc. This must be composed with some other function, depending on the arguments, to create passfunc.
Based on the arguments given to mainfunc, I will have different definitions of passfunc. Given the answer I got to a related question here, I initially tried to define my function logic in the following way, using anonymous functions which are apparently more efficient:
function mainfunc(args)
init_func = x -> funcA(x, args)
if args[1] == "foo"
anon_func = x -> func1(x, args)
elseif args[1] == "bar"
anon_func = x -> func2(x, args)
end
function passfunc(x)
return init_func(x) + anon_func(x)
end
# ... define other args...
callfunc(passfunc, other_args)
end
Defining my function in this way leads to errors in julia - apparently passfunc is an undefined variable when I run this code. Does the scope not allow the anonymous functions to be defined in the if statements? How else could I write code that achieves this?
I feel like a better understanding of functional programming principles would make the solution here obvious. Thank you in advance for any tips you can offer on improving this.
Also, I am running this with julia v0.7
I have a list with special users and normal users. Special users have their own special func, while normal users use a standard func.
I came up with this code design, but I feel that this is not optimal (performance wise).
So my question is: How would I get the best performance when calling inner functions like the example below?
if something then
CallFunc(var)
end
Special/normal user logic
function CallFunc(var)
if table[name] then
table[name](var)
else
Standard_Func(var)
end
end
local table = {
["name1"] = function(var) Spec_Func1(var) end,
["name2"] = function(var) Spec_Func2(var) end,
["name3"] = function(var) Spec_Func3(var) end,
...
--40 more different names and different funcs
}
Special user funcs
function Spec_Func1(var)
--lots of code
end
function Spec_Func2(var)
--lots of code
end
...
--more funcs
EDIT:
see #hjpotter92's answer:
I cant find the user in the table.
local function_lookups = {
name1 = Spec_Func1, --this doesnt let me find the user
--name1 = 1 --this does let me find the user (test)
}
if function_lookups[name] then --this fails to find the user
--do something
end
You do not need another anonymous function. Simply use the lookup table as follows:
local function_lookups = {
name1 = Spec_Func1,
name2 = Spec_Func2,
name3 = Spec_Func3,
...
--40 more different names and different funcs
}
Do not use the variable name table. It is a library available in Lua itself, and you are overwriting it.
You don't need a special function at all! You can use a generic function that's behaviour depends on the caller! Lemme explain with a piece of code:
local Special = {Peter=function(caller)end} --Put the special users' functions in here
function Action(caller)
if Special[caller] then
Special[caller](caller)
else
print("Normal Action!")
end
end
So whenever a user does a certain action, you can fire this function and pass a caller argument, the function then does the work behind the scenes determining if the caller is special, and if so what to do.
This makes your code clean. It also makes it easier to add more than 2 user statuses!
In elixir is possible to use default arguments in function definitions, but I found it impossible to do so with single keyword list arguments like:
def do_stuff(
success: sucess \\ fn(conn) -> conn end,
error: error
) do
# ...
end
Also, I thought about avoiding this kind of "callback passing" style of coding by using something like JS promises but I couldn't find an implementation of promises for Elixir.
Maybe there's something built in right into the language that could help me write better code and closer abide to the elixir standards.
Main question: is possible to use default keyword arguments?
Side question: Is there something Elixir provides to help avoid this "callback passing" style of programming in favor of a more reactive/composable mechanism?
No, it's not possible to use default keyword arguments as keyword arguments are just syntactic sugar over a single keyword list:
do_stuff(success: ..., failure: ...)
is the same as
do_stuff([success: ..., failure: ...])
So a keyword list is really just a single argument. What you're doing in your function definition is matching on the keyword list passed to do_stuff/1: be sure to watch out for this as well, because your function definition will not match if the order of the keywords is not the same (i.e., do_stuff(failure: ..., success: ...)).
I think a nice way to overcome this is simply use two different arguments for the do_stuff function:
def do_stuff(success \\ fn(conn) -> conn end, failure \\ fn(err) -> err end)
This way default arguments work as expected. If you really need your argument to be a keyword list, then you can handle defaults inside the body of the function:
def do_stuff(options) do
success = options[:success] || (fn(conn) -> conn end)
failure = options[:failure] || (fn(err) -> err end)
end
Finally, about the "callback style" you mentioned, I don't know about anything that works much differently than just passing fn for when something is done, unless you start looking into concurrency and message passing.
I have a strange issue (which I can overcome however I would like to get a proper understanding of my error).
I have a small random number generator function which I use often:
func ranNum(low: Int, high:Int) -> UInt32 {
var result = arc4random_uniform(UInt32((high+1)-low)) + low
return result
}
When I use this in XCode playgrounds it works just fine if I pass in something like:
ranNum(1, 10)
However, in a regular Swift file it generates the error message : Missing argument label 'hi:' in call. Now I can overcome this by calling the function this way:
ranNum(1, hi:10)
Apart from it just being a little harder to read, it just isn't making sense why it works in Playgrounds but also why it requires only the 2nd argument label and not both. Any help as to what I am not understandinh would be greatly appreciated.
That's called external parameter name, and by default:
global functions: don't have implicit external names
class/struct methods: external names are automatically defined for all parameters after the first
initializers: external names are automatically defined for all parameters
If not explicitly specified, external names take the same name as the local parameter.
You can override that by prefixing a local parameter name with _. In your case:
func ranNum(low: Int, _ high:Int) -> UInt32 {
...
}
You mentioned that in playground calling the function works without any external parameter name - I may argue that:
in playground you have that function as a global function
in other tests, that function is a class/struct method
Am I right?
As an example: getche() I understand what getche does, but why the () at the end?
If you are not putting anything in the parenthesis, why do you need them to be there? Just because of standards?
Thanks
Whether a function/method call needs to have parentheses at the end is a syntax particularity that varies from language to language. In Ruby, for example, you don't need it, while in Java, you do.
The compiler can use it to determine that you're making a function/method call. In many languages, you can reference a function as an object, so you need the parentheses to distinguish a reference to a function from a call to a function.
For example, in javascript:
function something(){
return "hello";
}
var a = something;
var b = something();
The variable a will contain the actual function something, while the variable b will contain "hello".
It executes the function without passing any parameters.
In languages with first-class functions, foo and foo() have different meanings. Consider these two examples, in Lua:
local bar = foo -- Assigns foo to bar. bar is now the function at foo.
local bar = foo() -- Executes foo, and assigns the return value to bar.
This, of course, depends on the language you are using. For example, in Haskell, no parenthesis are used to call functions.
This is syntax for Method/function.
Why is the need of it ? Because in the () you can provide the input arguments as well.
like for example :
var sum = addition(3,4);
Here addition can be defined as:
int addition(int a, int b)
{
return (a+b);
}