How to alias composite function with keyword arguments? - julia

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 ∘.

Related

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

How do I retrieve keyword arguments out of a field of splatted kwargs?

If I have a function signature like f(args...; kwargs...), how can I get a specific keyword out of kwargs? Naïvely typing kwargs.x does not work:
julia> f(args...; kwargs...) = kwargs.x
f (generic function with 1 method)
julia> f(x=1)
ERROR: type Pairs has no field x
Stacktrace:
[1] getproperty(::Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:x,),Tuple{Int64}}}, ::Symbol) at ./Base.jl:20
[2] #f#7(::Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:x,),Tuple{Int64}}}, ::typeof(f)) at ./REPL[2]:1
[3] (::var"#kw##f")(::NamedTuple{(:x,),Tuple{Int64}}, ::typeof(f)) at ./none:0
[4] top-level scope at REPL[3]:1
This question appeared on the JuliaLang Slack channel in the #helpdesk. For an automatic invite to the very helpful julia slack, simply fill out https://slackinvite.julialang.org
The reason this happens is that splatted keyword arguments are not stored in a named tuple by default. We can see how they're stored like so:
julia> g(;kwargs...) = kwargs
g (generic function with 1 method)
julia> g(a=1)
pairs(::NamedTuple) with 1 entry:
:a => 1
julia> g(a=1) |> typeof
Base.Iterators.Pairs{Symbol,Int64,Tuple{Symbol},NamedTuple{(:a,),Tuple{Int64}}}
So the splatted kwargs are instead stored as some sort of iterator object. However, we can easily convert that kwargs iterator to a NamedTuple like so: (;kwargs...) and then access it in the way we'd expect, so your example would translate into
julia> f(args...; kwargs...) = (;kwargs...).x
f (generic function with 1 method)
julia> f(x=1, y=2)
1
Of course, the more idiomatic way to do this would be to instead write the function as
julia> f(args...; x, kwargs...) = x
f (generic function with 1 method)
julia> f(x=1, y=2)
1
but this assumes you know the name you want to access (x) at the time when you write the function.
A brief sidenote: If we return to our example of g(;kwargs...) = kwargs, we can ask for the fieldnames of the iterator object the was returned like so:
julia> g(x=1, y=2) |> typeof |> fieldnames
(:data, :itr)
Hm, what is this data field?
julia> g(x=1, y=2).data
(x = 1, y = 2)
Aha! so we can actually get the kwargs as a named tuple using that, i.e. f(;kwargs...) = kwargs.data.x would work, but I wouldn't recommend this approach since it seems to rely on undocumented behaviour, so it may be a mere implementation detail that is not guaranteed to be stable across julia versions.

Access function defined in another function

Is it possible to access function defined in another function in julia? For example:
julia> function f(x)
function g(x)
x^2
end
x * g(x)
end
f (generic function with 1 method)
julia> f(2)
8
julia> f.g(2)
ERROR: type #f has no field g
in eval_user_input(::Any, ::Base.REPL.REPLBackend) at ./REPL.jl:64
in macro expansion at ./REPL.jl:95 [inlined]
in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at ./event.jl:68
No. In julia, it is often more ideomatic to use a module for local functions
module F
function g(x)
x^2
end
function f(x)
x * g(x)
end
export f
end
using F
f(2)
F.g(2)
What's the use case? You can define a custom type, give it a function field, and then make the type callable (a closure) to achieve the behaviour you want. But whether that is the best way of solving your issue in julia is a different question.
You can do this if your function f is an instance of a callable type, containing a function g as an accessible field:
julia> type F
g::Function
end
julia> function(p::F)(x) # make type F a callable type
x * p.g(x)
end
julia> f = F(function (x) return x.^2 end) # initialise with a function
F(#1)
julia> f(2)
8
julia> f.g
(::#1) (generic function with 1 method)
If g is always a fixed function, then you can introduce it via an internal constructor.
But to echo Lyndon's comments above, a better question is, why would you do this instead of something relying more on julia's dynamic dispatch features?

What functions are called to display an (Array) variable on the julia REPL?

Say I enter:
julia> X = randn(3,4)
3x4 Array{Float64,2}:
-0.862092 0.78568 0.140078 -0.0409951
-0.157692 0.0838577 1.38264 -0.296809
1.40242 -0.628556 -0.500275 0.258898
What functions were called to produce the output given?
Note that overloading Base.show does not seem to be sufficient to change this behaviour, so I'm unsure where to go.
julia> Base.show(io::IO, A::Array{Float64, 2}) = println("Humbug")
show (generic function with 120 methods)
julia> X
3x4 Array{Float64,2}:
-0.862092 0.78568 0.140078 -0.0409951
-0.157692 0.0838577 1.38264 -0.296809
1.40242 -0.628556 -0.500275 0.258898
Is it perhaps the case that I would have to change Base/array.jl source code and rebuild julia before such a change would work? Note the difference between this and a user defined type:
julia> type foo
x::Float32
s::ASCIIString
end
julia> ob = foo(1., "boo")
foo(1.0f0,"boo")
julia> Base.show(io::IO, someob::foo) = print("Humbug!")
show (generic function with 123 methods)
julia> ob
Humbug!
well, you should overload display():
julia> Base.display(A::Array{Float64, 2}) = println("Humbug")
display (generic function with 11 methods)
julia> X
Humbug
you can find the definition in REPL.jl.

how to pass tuple as function arguments

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.

Resources