# Implementing a pointwise arithmetic on functions

**URL:** <https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769>\
**Category:** General Usage\
**Created:** [May 2, 2019, 10:42am UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769 "2019-05-02T10:42:01Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![kkmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kkmann/32/1727_2.png) [@kkmann](https://discourse.julialang.org/u/kkmann)\
**Post date:** [May 2, 2019, 10:42am UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769/1 "2019-05-02T10:42:02Z")

</div>

Hey,

I just came across a problem that I am sure can be solved elegantly in Julia but I am lacking a good starting angle. Assume that I have a collection of functors (callable types) of the form

```julia
struct Functor
  f::function
end

(f::Functor)(x)::Real = f.f(x)

```

This makes sure that all objects of type `Functor` can be called with a single argument `x` (which would have to be checked in a proper constructor…)

What would be the best way to implement point-wise arithmetic on these functors? I.e., I’d like to be able to create a new functor via arbitrary Julia expressions treating functor objects as reals. Something like

```julia
a = Functor(sin)
b = Functor(cos)
c = @compose a + exp(b) # c should also be of type Functor
c(1) # should return sin(1) + exp(cos(1))

```

should work. Not quite sure but I suspect this is a macro problem since I essentially need to treat the argument to `@compose` as Julia expression, replace all references to functors by their pointwise evaluation and then evaluate the expression.

Are macros the way to go here or are there better options?

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 2, 2019, 10:59am UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769/2 "2019-05-02T10:59:24Z")

</div>

> [@kkmann](#):
>
> replace all references to functors

Macros work on _syntax_ but here you are talking about the _type_ of variables which are not known until the function runs. If you want to create a macro you need to think about the input and output syntax of the macro. A good start is to write down a few examples by hand, and then write the macro to do it. If you can’t write down the syntactic transformation by hand, then you can’t use a macro.

An example could be, input syntax: `a + exp(b)`, output syntax `Functor(x -> a(x) + exp(b(x)))`.

---

<div class="post-metadata">

**Author:** ![kkmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kkmann/32/1727_2.png) [@kkmann](https://discourse.julialang.org/u/kkmann)\
**Post date:** [May 2, 2019, 11:08am UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769/3 "2019-05-02T11:08:48Z")

</div>

I see, so I will essentially have to figure our which symbols in the input syntax point to objects of type Functor in the enclosing environment, and replace these with calls to \<\>(x) in the input expression. Should be doable, thx.

Generally speaking though, metaprogramming is the way to go here, right? Sub-typing `Real` won’t get me anywhere since I cannot pass arguments, I guess.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 2, 2019, 11:55am UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769/4 "2019-05-02T11:55:57Z")

</div>

If you just want a syntactic transform you could do something like

```julia
apply(f, y) = f
apply(f::Functor, y) = f(y)

macro compose(expr)
    s = gensym()
    _compose!(expr,s)
    return :(Functor($s -> $expr))
end

function _compose!(expr, s)
    isa(expr, Symbol) && return :(apply($expr, $s)
    isa(expr, Expr) || return expr
    for i in 1:length(expr.args)
        expr.args[i] = _compose!(expr.args[i], s)
    end
    return expr
end

```

```julia
julia> a = Functor(sin)
Functor(sin)

julia> b = Functor(cos)
Functor(cos)

julia> c = @compose a + exp(b) # c should also be of type Functor
Functor(getfield(Main, Symbol("##5#6"))())

julia> c(1)
2.5579966843568

```

but it is kinda strange just to replace symbols. You might have Functors being returned from other functions etc for which a macro wouldn’t work.

---

<div class="post-metadata">

**Author:** ![kkmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kkmann/32/1727_2.png) [@kkmann](https://discourse.julialang.org/u/kkmann)\
**Post date:** [May 2, 2019, 12:24pm UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769/5 "2019-05-02T12:24:32Z")

</div>

x) cool stuff, thx! Still struggling with a few things here.

First, super dummy question, how does

> `isa(expr, Expr) || return expr`

work? What does the ‘or’ do with ‘return’? Is that something like a super concise error handling? I just can’t wrap my head around it and googling didn’t help either x)

Your solution might actually work for what I had in mind, will play around with it a bit longer, thx a lot.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [May 2, 2019, 12:28pm UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769/6 "2019-05-02T12:28:56Z")

</div>

> [@kkmann](#):
>
> What would be the best way to implement point-wise arithmetic on these functors? I.e., I’d like to be able to create a new functor via arbitrary Julia expressions treating functor objects as reals.

Note that in principle you don’t need a macro for this. For example, if you define:

```julia
struct Functor{F<:Function} <: Function
  f::F
end
(f::Functor)(x)= f.f(x)

for op in (:+, :-, :*, :/, :\)
   @eval begin
        Base.$op(a::Functor, b) = Functor(x -> $op(a(x), b))
        Base.$op(a, b::Functor) = Functor(x -> $op(a, b(x)))
        Base.$op(a::Functor, b::Functor) = Functor(x -> $op(a(x), b(x)))
    end
end
for f in (:sin, :cos, :exp, :log, :+, :-)
    @eval Base.$f(a::Functor) = Functor(x -> $f(a(x)))
end

```

Then if you do

```julia
a = Functor(sin)
b = Functor(cos)
c = a + exp(b - 2)
c(1)

```

it gives `1.073777476539272`, which is equal to `sin(1) + exp(cos(1) - 2)`.

The downside of this approach, of course, is that you need to predetermine the set of functions where you want `Functor` to automatically compose. The advantage is that, for this set, it works reliably — Julia knows exactly which things are of type `Functor`, so it won’t get confused if you have a symbol of another type, e.g.:

```julia
y = 17
d = a + y
d(1)

```

will correctly give `17.841470984807895 == sin(1) + 17`. (In contrast, a macro executes right after parsing and doesn’t know the type of anything — it only knows how things are spelled.)

For a different function-composition approach, see the [GitHub - JuliaApproximation/ApproxFun.jl: Julia package for function approximation](https://github.com/JuliaApproximation/ApproxFun.jl) package. In ApproxFun, each time you compose its functions (a `Fun` type), it forms a new polynomial approximation. No matter how many functions you compose, you get a single polynomial — not only does this result in fast evaluation, but it also let’s you do things like find roots and integrate or solve PDEs.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [May 2, 2019, 12:32pm UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769/7 "2019-05-02T12:32:15Z")

</div>

> [@kkmann](#):
>
> First, super dummy question, how does
> 
> > `isa(expr, Expr) || return expr`
> 
> work? What does the ‘or’ do with ‘return’?

See [Control Flow · The Julia Language](https://docs.julialang.org/en/v1/manual/control-flow/index.html#Short-Circuit-Evaluation-1).

---

<div class="post-metadata">

**Author:** ![kkmann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kkmann/32/1727_2.png) [@kkmann](https://discourse.julialang.org/u/kkmann)\
**Post date:** [May 2, 2019, 12:54pm UTC](https://discourse.julialang.org/t/implementing-a-pointwise-arithmetic-on-functions/23769/8 "2019-05-02T12:54:54Z")

</div>

Also nice, less scoping issues and straight forward support for things like

```julia
c = a
for i in 1:3
  global c = c + a
end

```

Probably would need to implement a `register` function to allow post hoc addition of new compositional functions, e.g.

```julia
function register(f)
    @eval $f(a::Score) = Score(x -> $f(a(x)))
end

register(:(Base.sin))

```
