how to pass tuple as function arguments - julia

Got a function that takes three arguments.
f(a, b, c) = # do stuff
And another function that returns a tuple.
g() = (1, 2, 3)
How do I pass the tuple as function arguments?
f(g()) # ERROR

Using Nanashi's example, the clue is the error when you call f(g())
julia> g() = (1, 2, 3)
g (generic function with 1 method)
julia> f(a, b, c) = +(a, b, c)
f (generic function with 1 method)
julia> g()
(1,2,3)
julia> f(g())
ERROR: no method f((Int64,Int64,Int64))
This indicates that this gives the tuple (1, 2, 3) as the input to f without unpacking it. To unpack it use an ellipsis.
julia> f(g()...)
6
The relevant section in the Julia manual is here: http://julia.readthedocs.org/en/latest/manual/functions/#varargs-functions

Answer outdated as of Julia version 0.4, released in 2015:
In modern versions of Julia, use the ... operator f(g()...).
Use apply.
julia> g() = (1,2,3)
g (generic function with 1 method)
julia> f(a,b,c) = +(a,b,c)
f (generic function with 1 method)
julia> apply(f,g())
6
Let us know if this helps.

Related

Most idiomatic solution to function currying in Julia

What is the most idiomatic way to achieve function currying?
Eg. in Haskell:
times a b = a * b
-- This can then be used uncurried:
times 2 3 -- Result is 6
-- But there is also auto-currying:
(times 2) 3 -- This works too
In Julia, some built-ins support this:
<(8, 7) # Result is false
<(8)(7) # Same
7 |> <(8) # Same
However, user-defined functions don't automatically have this functionality:
times(a, b) = a * b
times(2, 3) # Result is 6
3 |> times(2) # MethodError: no method matching times(::Int64)
I can manually define a one-argument version and then it works:
times(a) = b -> a * b
But my question is, is there a better way?
why not use curry.jl
times(a, b) = a * b
times_curry = curry(times)
times_curry(5)(2) ---> gives 10
This would be pretty tricky (impossible?) to solve in Julia without a macro, as multiple dispatch means you won't know which function you'll ultimately end up dispatching to until you see all of the arguments. I think the simplest way to implement currying is just with a struct like this:
julia> struct Curry
func::Function
args::Tuple
Curry(func, args...) = new(func, args)
end
julia> (curry::Curry)(x, args...) = Curry(curry.func, curry.args..., x, args...)
julia> (curry::Curry)() = curry.func(curry.args...)
julia> Curry(<)
Curry(<, ())
julia> Curry(<)(2)()
(::Base.Fix2{typeof(<), Int64}) (generic function with 1 method)
julia> Curry(<)(2)(3)()
true
julia> Curry(<, 2)
Curry(<, (2,))
julia> Curry(<, 2, 3)()
true
Basically, calling the Curry with at least one argument creates a new Curry with the new arguments, and calling it with 0 arguments “executes” the whole thing.

How to alias composite function with keyword arguments?

I can alias a single function like so:
julia> f(y;x=1) = x * y
f (generic function with 2 methods)
julia> const g = f
f (generic function with 1 method)
julia> g(3,x=2)
6
But if I try to do that with a composite function, the kwarg causes trouble:
julia> const gg= sqrt ∘ f
#62 (generic function with 1 method)
julia> gg(3,x=2)
ERROR: MethodError: no method matching (::Base.var"#62#63"{typeof(sqrt),typeof(f)})(::Int64; x=2)
Closest candidates are:
#62(::Any...) at operators.jl:875 got unsupported keyword argument "x"
Is there a solution to this? I am trying to pass the arguments to f and then transform that result via a shortcut (gg in the above MWE).
You have the following definition:
∘(f, g) = (x...)->f(g(x...))
and as you can see it does not support keyword arguments. Probably you can open an issue to discuss allowing them.
For now you can define your own version of it like this:
julia> ⋄(f, g) = (x...; kw...)->f(g(x...; kw...))
⋄ (generic function with 1 method)
julia> f(y;x=1) = x * y
f (generic function with 1 method)
julia> const gg = sqrt ⋄ f
#1 (generic function with 1 method)
julia> gg(3,x=2)
2.449489742783178
EDIT:
I have switched to the other OS, and I see that ⋄ does not render very sharp here. I used the following symbol:
help?> ⋄
"⋄" can be typed by \diamond<tab>
which is defined to be allowed to be an infix operator and is relatively easy to remember while not overshadowing ∘.

Deflation Method for Multiple Root Finding

I'm trying to implement the deflation method for finding multiple roots of a polynomial on Julia. In the deflation method, new functions are generated from the actual function divided by x - x_roots[i], and the root of new generated function must be found. But g(x) = g(x) / (x - x_root) gives me a Stack Overflow error, as probably it generated an infinite recursive relation. How may I generate a new function in each step?
function deflation(f::Function, order)
roots=[]
n=1
g(x)=f(x)
x_root=Muller_method(f,-5,0,5,1e-5,50)
while n<=order
x_root=Muller_method(a,-5,0,5,1e-5,50)
g(x)=g(x)/(x-x_root)
append!(roots,x_root)
n=n+1
end
return (roots)
Something like this causes infinite recursion:
julia> g(x) = x
g (generic function with 1 method)
julia> g(1)
1
julia> g(x) = g(x) / 2
g (generic function with 1 method)
julia> g(1)
ERROR: StackOverflowError:
Stacktrace:
[1] g(::Int64) at ./REPL[3]:1 (repeats 79984 times)
This is because function (or method) definitions do not work like variable assignment: each re-definition of g(x) overwrites the previous one (note how g above only ever has one method). When a method definition refers to itself, it is recursion, i.e. it refers to its own version at the time when the function gets called.
As for your deflation method, perhaps you could define a new function that closes over the vector of currently found roots. Consider the following example to see how things would work:
julia> f(x) = (x-1) * (x-2)
f (generic function with 1 method)
julia> roots = Float64[]
Float64[]
# g is defined once, and accounts for all currently found roots
julia> g(x) = f(x) / reduce(*, x-root for root in roots; init=one(x))
g (generic function with 1 method)
# No roots are identified at the beginning
julia> g(1+eps())
-2.2204460492503126e-16
julia> g(2+eps())
0.0
# But the results produced by g update as roots are identified
julia> push!(roots, 1.)
1-element Array{Float64,1}:
1.0
julia> g(1+eps())
-0.9999999999999998
julia> g(2+eps())
0.0

Specializing method calls in order in meta-programming

I have issue after calling my macro:
#introspectable square(x) = x * x
Then when calling
square(3)
i should be able to get 9, cause the function call has been specialized to execute an attribute of the structure which is Julia code, however when I enter the macro, the code seems to be directly evaluated.
What i have tried:
struct IntrospectableFunction
name
parameters
native_function
end
(f::IntrospectableFunction)(x) = f.native_function(x)
macro introspectable(expr)
name = expr.args[1].args[1]
parameters = tuple(expr.args[1].args[2:end]...)
body = expr.args[2].args[2]
:( global $name = IntrospectableFunction( :( name ), $parameters, :( body ) ))
end
#introspectable square(x) = x * x
square(3)
The answer should be 9 , however i get "Object of type symbol are not callable ". However if i replace :( body ) with x -> x * x i get the desired result, my objective is generalizing the macro-call.
I usually find it easier to work with expressions in macros (it is not the shortest way to write things, but, from my experience, it is much easier to control what gets generated).
Therefore I would rewrite your code as:
macro introspectable(expr)
name = expr.args[1].args[1]
parameters = expr.args[1].args[2:end]
anon = Expr(Symbol("->"), Expr(:tuple, parameters...), expr.args[2].args[2])
constr = Expr(:call, :IntrospectableFunction, QuoteNode(name), Tuple(parameters), anon)
esc(Expr(:global, Expr(Symbol("="), name, constr)))
end
Now, as you said you wanted generality I would define your functor like this:
(f::IntrospectableFunction)(x...) = f.native_function(x...)
(in this way you allow multiple positional arguments to be passed).
Now let us test our definitions:
julia> #introspectable square(x) = x * x
IntrospectableFunction(:square, (:x,), getfield(Main, Symbol("##3#4"))())
julia> square(3)
9
julia> #macroexpand #introspectable square(x) = x * x
:(global square = IntrospectableFunction(:square, (:x,), ((x,)->x * x)))
julia> #introspectable toarray(x,y) = [x,y]
IntrospectableFunction(:toarray, (:x, :y), getfield(Main, Symbol("##5#6"))())
julia> toarray("a", 10)
2-element Array{Any,1}:
"a"
10
julia> #macroexpand #introspectable toarray(x,y) = [x,y]
:(global toarray = IntrospectableFunction(:toarray, (:x, :y), ((x, y)->[x, y])))
julia> function localscopetest()
#introspectable globalfun(x...) = x
end
localscopetest (generic function with 1 method)
julia> localscopetest()
IntrospectableFunction(:globalfun, (:(x...),), getfield(Main, Symbol("##9#10"))())
julia> globalfun(1,2,3,4,5)
(1, 2, 3, 4, 5)
julia> function f()
v = 100
#introspectable localbinding(x) = (v, x)
end
f (generic function with 1 method)
julia> f()
IntrospectableFunction(:localbinding, (:x,), getfield(Main, Symbol("##11#12")){Int64}(100))
julia> localbinding("x")
(100, "x")
(note that it is useful to use #macroexpand to make sure our macro works as expected)
EDIT - how to handle a minimal multiple dispatch
I am writing a non-macro example because it is related to the data structure:
Use e.g. such a definition:
struct IntrospectableFunction
name::Symbol
method_array::Vector{Pair{Type{<:Tuple}, Function}}
end
function (f::IntrospectableFunction)(x...)
for m in f.method_array
if typeof(x) <: first(m)
return last(m)(x...)
end
end
error("signature not found")
end
and now you can write:
julia> square = IntrospectableFunction(:square, [Tuple{Any}=>x->x*x,Tuple{Any,Any}=>(x,y)->x*y])
IntrospectableFunction(:square, Pair{DataType,Function}[Tuple{Any}=>##9#11(), Tuple{Any,Any}=>##10#12()])
julia> square(3)
9
julia> square(2,3)
6
Keep in mind that the approach I present is not perfect and universal - it just serves to give a very simple example how you could do it.

Julia-Lang Metaprogramming: turn expression into function with expression-dependent arguments

Given a dictionary of values,
values = {:A => 3, :B => 1}
turn an (arbitrary) expression like
expr = :(2*A)
into a function foo(values) that evaluates the expression, so in this case foo(values) = 6. The resulting function will be called millions of times, so speed is an important consideration. I am happy to adopt a slightly different approach if necessary, as long as it can be automatised.
Things I tried:
The conversion using convert(Function, expr), as suggested here. Fails for me (Julia 0.3.8-pre):
convert has no method matching convert(::Type{Function}, ::Expr)
Using #eval one can do
#eval foo(A) = $(expr)
and then call foo(values[:A]), but that would require knowing that expr depends on A (and only on A).
I wrote a function find_vars(exp) to return the symbols in expr (in this case [:A]), but couldn't find how to use them in the #eval approach.
Base.Cartesian has an unexported function lreplace which may be what you're after. Then you can do something like:
julia> values = Dict(:A=>3, :B=>1)
Dict{Symbol,Int64} with 2 entries:
:B => 1
:A => 3
julia> import Base.Cartesian.lreplace
julia> expr = :(2*A)
:(2A)
julia> function lreplace_all(expr, d)
for (k, v) in d
expr = lreplace(expr, k, v)
end
expr
end
lreplace_all (generic function with 1 method)
julia> lreplace_all(expr, values)
:(2 * 3)
julia> #eval foo(A) = $(lreplace_all(:(2A), values))
foo (generic function with 1 method)
julia> foo(1)
6
Although, since A is defined by the values dict, it makes more sense to define foo as a zero-argument function (unless I've missed something).
EDIT:
After rereading your question it seems like you want to pass in the actual dictionary to the function rather than have the values available at compile time as I've done above. In that case, we have get a little creative:
First we need an lreplace like function that will work with expressions which is easy enough
julia> dictreplace!(ex, s, v) = ex
dictreplace! (generic function with 1 method)
julia> dictreplace!(ex::Symbol, s, v) = s == ex ? v : ex
dictreplace! (generic function with 2 methods)
julia> function dictreplace!(ex::Expr, s, v)
for i=1:length(ex.args)
ex.args[i] = dictreplace!(ex.args[i], s, v)
end
ex
end
dictreplace! (generic function with 3 methods)
julia> dictreplace(ex, s, v) = dictreplace!(copy(ex), s, v)
dictreplace (generic function with 1 method)
Now we want to replace every occurence of a symbol in our dict keys with a dictionary lookup
julia> function dictreplace_all(expr, kys, dsym)
for k in kys
expr = dictreplace(expr, k, :($(dsym)[$(QuoteNode(k))]))
end
expr
end
dictreplace_all (generic function with 1 method)
julia> dictreplace_all(:(2A), keys(values), :d)
:(2 * d[:A])
julia> #eval foo(args) = $(dictreplace_all(:(2A), keys(values), :args))
foo (generic function with 1 method)
julia> values[:A] = -99
-99
julia> foo(values)
-198
Thanks to the solution by #ptb and another metaprogramming question I found a simpler yet slower solution:
function foo(values, expr)
expr = quote
A = values[:A]
B = values[:B]
return $(expr)
end
eval(expr)
end
Reading in the values from the dictionary can also be done programmatically by replacing the inner evaluation by
$([:($k = $v) for (k, v) in values]...)
return $(expr)

Resources