Julia: Passing Multiple Arguments to Anonymous Functions - arguments

In the Julia Manual under the Anonymous Functions section one of the examples that is offered is (x,y,z)->2x+y-z.
Could someone please show me how one would pass a set of arguments to this function?
Say x=(1,2,3); y=(2,3,4); z=(1,3,5).

If you define x,y and z to be arrays then you can just call the function and pass them in:
fun = (x,y,z)->2x+y-z
x=[1,2,3]
y=[2,3,4]
z=[1,3,5]
fun(x, y, z)
giving the result:
3-element Array{Int64,1}:
3
4
5
But if you want to do this with tuples, as per your example, you will need to use map:
x=(1,2,3)
y=(2,3,4)
z=(1,3,5)
map(fun, x, y, z)
this gives the same result, but this time as a tuple:
(3, 4, 5)
This is because the *, + and - operators are not defined for tuples so the formula 2x+y-z can't work. Using map gets around this by calling the function multiple times passing in scalars.

You have to assign the anonymous function to a variable, in order to call it.
julia> fun = (x,y,z)->2x+y-z
(anonymous function)
julia> fun((1,2,3),(2,3,4),(1,3,5))
ERROR: no method *(Int64, (Int64,Int64,Int64))
in anonymous at none:1
It does not work, because the tuples you set for x, does not implement the * function.

Related

Retrieve method content as an `Expr`ession

I have a function f defined as follows.
f(x, y) = 3x^2 + x*y - 2y + 1
How can I retrieve the following quote block for this method, which includes the function contents?
quote # REPL[0], line 2:
((3 * x ^ 2 + x * y) - 2y) + 1
end
As folks have mentioned in the comments, digging through the fields of the methods like this isn't a stable or officially supported API. Further, your simple example is deceiving. This isn't, in general, representative of the original code you wrote for the method. It's a simplified intermediate AST representation with single-assignment variables and drastically simplified control flow. In general, the AST it returns isn't valid top-level Julia code. It just so happens that for your simple example, it is.
That said, there is a documented way to do this. You can use code_lowered() to get access to this intermediate representation without digging through undocumented fields. This will work across Julia versions, but I don't think there are official guarantees on the stability of the intermediate representation yet. Here's a slightly more complicated example:
julia> f(X) = for elt in X; println(elt); end
f (generic function with 1 method)
julia> code_lowered(f)[1]
LambdaInfo template for f(X) at REPL[17]:1
:(begin
nothing
SSAValue(0) = X
#temp# = (Base.start)(SSAValue(0))
4:
unless !((Base.done)(SSAValue(0),#temp#)) goto 13
SSAValue(1) = (Base.next)(SSAValue(0),#temp#)
elt = (Core.getfield)(SSAValue(1),1)
#temp# = (Core.getfield)(SSAValue(1),2) # line 1:
(Main.println)(elt)
11:
goto 4
13:
return
end)
julia> code_lowered(f)[1] == methods(f).ms[1].lambda_template
true
If you really want to see the code exactly as it was written, the best way is to use the embedded file and line information and refer to the original source. Note that this is precisely the manner in which Gallium.jl (Julia's debugger) finds the source to display as it steps through functions. It's undocumented, but you can even access the REPL history for functions defined interactively. See how Gallium does it through here.
First, retrieve the method using methods(f).
julia> methods(f)
# 1 method for generic function "f":
f(x, y) at REPL[1]:1
julia> methods(f).ms
1-element Array{Method,1}:
f(x, y) at REPL[1]:1
julia> method = methods(f).ms[1]
f(x, y) at REPL[1]:1
From here, retrieving the Expression is straightforward; simply use the lambda_template attribute of the method.
julia> method.lambda_template
LambdaInfo template for f(x, y) at REPL[1]:1
:(begin
nothing
return ((3 * x ^ 2 + x * y) - 2 * y) + 1
end)
Edit: This does not work in Julia v0.6+!

What is the correct function definition syntax in CoffeeScript?

On the official CoffeeScript website the syntax for defining a function is
square = (x) -> x * x
However, on some other websites I found out that the syntax could also be
square: (x) -> x * x
Is one of the options preferred?
There is a huge difference between those two options. Firstly, they have nothing to do with function syntax, which is always (x) -> x * x. They only differs in what you are doing with the function.
The first option defines a local variable square and assign that function to it. hence afterwards you can simply call square(2) to get 4.
Second option is creating a javascript object. If this is the last line of some function, this is its return value. Object has to be assigned to some variable, otherwise it is lost:
functions =
square: (x) -> x * x
functions.square(2)

Higher order function to apply many functions to one argument

I want the common name of a higher order function that applies a list of functions onto a single argument.
In this sense it is a converse of map. map takes a function and a list of arguments and applies that function to the entire list. In Python it might look like this
map = lambda fn, args: [fn(arg) for arg in args]
I'm thinking of the function that does the same but has the alternate argument as a list type
??? = lambda fns, arg: [fn(arg) for fn in fns]
I suspect that this function exists and has a common name. What is it?
Actually, what you describe is not the converse of map, but just map applied in another way. Consider, e.g.,
map(lambda f: f(2), [lambda x: x + 1, lambda x: x, lambda x: x * x])
which in effect applies three functions (plus 1, identity, and squaring) to the argument 2. So what you wanted is just
alt_map = lambda x, fns: map(lambda f: f(x), fns)
which is still an ordinary map.

how to curry a method with one parameter

here is my code:
def f x
x
end
g = method(:f).to_proc.curry.(123)
p g
I want g to be a callable that takes no parameters and applies 123 to f. Instead, g contains the result of the application.
Am I doing it the complicated way?
EDIT: yes, g = lambda {f 123} works, but I am asking how to curry f.
The documentation for curry says that
If a sufficient number of arguments are supplied, it passes the supplied arguments to the original proc and returns the result.
So in this case you haven't really curried your function from a theoretical point of view, but practically you have. The
g = lambda {f 123}
seems to be closer to the spirit of returning a function that you can then call to evaluate, at least once all the arguments are determined.
Maybe you want to wrap your function f inside a lambda (evaluating f). Then you can curry the lambda expression, something like this:
g = lambda{f 123}.curry
p g[] // or g.call
Now g is callable that takes no parameters.

Function as parameter for Module

How is it possible to use a mathematical function as module- parameter
Such as:
PersonalPlot[fun0_, var0_, min0_, max0_] :=
Module[{fun = fun0, var = var0 , min = min0, max = max0},
(*this is incorrect*)
fun = fun[var_];
Plot[fun, {var, min, max}]
]
PersonalPlot[x^2,x,0,3];
You're right, that statement is incorrect. Mathematica evaluates it to something like
x^2[x]
when you call PersonalPlot and that evaluates to, well, in words to x to the power of 2 of x which doesn't make a lot of sense. There are a number of ways round the problem. The simplest would be to dispense with a Module altogether and define:
PersonalPlot1[fun0_, var0_, min0_, max0_] := Plot[fun0, {var0, min0, max0}]
which you would call like this:
PersonalPlot1[x^2, x, 0, 3]
Note that a call like this PersonalPlot1[x^2, y, 0, 3] produces an empty plot because the variable in the function passed in is not the same variable as the second argument. Read on.
If you want to define a module which takes a function as an argument, then this is one way of doing it:
PersonalPlot2[fun0_, var0_, min0_, max0_] :=
Module[{fun = fun0, var = var0, min = min0, max = max0},
Plot[fun[var], {var, min, max}]]
which you would call like this
PersonalPlot2[#^2 &, x, 0, 3]
Note:
The function passed into the function is a pure function. If you are not already familiar with Mathematica's pure functions now would be a good time to consult the relevant parts of the documentation.
This explicitly tells the Plot command to evaluate fun[var] over the range you specify.
Your local variables are not strictly necessary since your function works by side-effect, producing a plot rather than manipulating (copies of) the arguments passed to it. You could rewrite this simply as:
PersonalPlot2b[fun0_, var0_, min0_, max0_] := Module[{},
Plot[fun0[var0], {var0, min0, max0}]]
Another possibility would be to drop the argument which represents the variable input to the function passed to PersonalPlot, like this:
PersonalPlot3[fun0_, min0_, max0_] := Module[{x},
Plot[fun0[x], {x, min0, max0}]]
which you would call like this
PersonalPlot3[#^2 &, 0, 3]
In this version I've made x local to the Module to avoid clashes with any workspace variable also called x. This avoids errors arising from using different names for the argument to the function (the pure function has no argument names) and the second argument to PersonalPlot; that has now been dropped.
There are probably several other useful ways of passing arguments to functions whether those functions use modules or not.
EDIT
Most of us who've used Mathematica for a while don't, I think, regard #^2& as something to avoid. If you don't like it, you could use the more explicit syntax, like this:
fun1 = Function[x,x^2]
which you can then pass around like this
PersonalPlot[fun1,0.0,4.0]
By using this approach you can make your functions a bit less error prone by requiring the right types to be passed in, like this
PersonalPlot[fun_Function, min_Real, max_Real] := ...
but it's really up to you.
Off the top of my head I don't know how Plot does it, I'd have to look in the documentation.
The following three examples may add to previous answer in illustrating some of the possible ways to pass functions as arguments.
Example 1:
square[x_] := x^2/50;
fplot1[f_, x1_, x2_] := Plot[f, {x, x1, x2}];
fplot1[x^2/50, -2 Pi, 2 Pi]
fplot1[{square[x], Sin[x]}, -2 Pi, 2 Pi]
Example 2:
fplot2[f_, x1_, x2_] :=
Module [ (*
This type of function passing works also works in Module so long as x is not defined as a local variable. *)
{},
Plot[f, {x, x1, x2}]
];
fplot2[Sin[x], -2 Pi, 2 Pi]
fplot2[{Sin[x], square[x]}, -2 Pi, 2 Pi]
Example 3:
fplot3[f_, x1_, x2_] :=
Module [ (* This type of function passing works in Module with x declared as local variable. Only one function name can be passed. *)
{x},
Plot[f[x], {x, x1, x2}]
];
fplot3[Sin, -2 Pi, 2 Pi]
fplot3[square, -2 Pi, 2 Pi]

Resources