# How to make functions multipliable?

I want to make functions be able to be multiplied:

``````f(x) = x^2
g = 3 * f
g(10) # == 300
``````

Is this achievable?

No. This is not feasible. However you can do

``````g(args...) = 3 * f(args...)
``````

Shouldn’t it be `g(args... ; ka...) = 3 * f(args... ; ka...)`?

1 Like

You certainly can do this:

``````julia> function Base.:*(x::Number, f::Function)
y -> x * f(y)
end

julia> f(x) = x^2
f (generic function with 1 method)

julia> g = 3 * f
#13 (generic function with 1 method)

julia> g(10)
300
``````

but I wouldn’t recommend it. This is a form of Type Piracy which we don’t recommend because it can cause unexpected effects in other users’ code.

5 Likes

Maybe you want to pass multiple arguments to an inner function like this?

``````julia> f(x,y;z) = x^2 + y^2 + z^2 # many parameters
f (generic function with 1 method)

julia> g(func,newarg) = 3*func(newarg) # enclosing function
g (generic function with 1 method)

julia> x = 10; z = 5;

julia> y = 3
3

julia> g( y -> f(x,y,z=z), y )
402

``````

You can also compose:

``````julia> f(x) = x^2
f (generic function with 1 method)

julia> g(x) = 3*x
g (generic function with 1 method)

julia> 10 |> f |> g
300

julia> (g ∘ f)(10)   # \circ
300

``````

Sure, if it has keyword arguments then that works.

You can also do a callable struct

``````julia> struct G{T}
f::T
end

julia> (x::G)(args...; kwargs...) = 3 * x.f(args...; kwargs...);

julia> f(x, y) = x + y;

julia> g(1, 2)
9
``````
1 Like

This works but I don’t know if is a good practice:

``````multiplication(x) = y -> y*x
g = multiplication(3) ∘ f
g(10) #300
``````

or

``````g = (x -> 3x) ∘ f
g(10) #300
``````
1 Like

Maybe worth noting that every function has a type, and thus you can do this for your one specific function without piracy.

``````julia> Base.:(-)(::typeof(f)) = x -> -f(x)

julia> map(-f, [1,2,3])
3-element Vector{Int64}:
-1
-4
-9
``````
7 Likes