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...)?

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.

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

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

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