Exponentiation operator for iterated functions?

Would it make sense to define the ^ operator for iterated functions? Something like:

^(f::Function, n::Integer) = ∘(fill(f,n)...)

Then we can do things like

typeof(1.0) |> supertype^3

Instead of

typeof(1.0) |> supertype |> supertype |> supertype

A possible downside: people might expect (sin^2)(x) to mean sin(x)^2 instead of sin(sin(x)) (although they should not IMO :wink:).

I think not. Whatever works for functions should work for all callables, and some types can be callables and at the same time define methods for ^ (eg as an operator on some algebra).

The basic issue is that ^ in Julia is for iteration of *. So it would be inconsistent (and poorly composable as @Tamas_Papp notes) to overload it for iteration of .

1 Like

Ah right it makes sense. Maybe at some point another operator will prove adequate…

In case you’re not aware, you can do it for your own functions if you want!

julia> supertype(T) = Base.supertype(T)
supertype (generic function with 1 method)

julia> Base.:^(::typeof(supertype), n::Integer) = n == 1 ? supertype : supertype ∘ supertype^(n-1)

julia> (supertype^3)(Float64)
Number

Thanks, my original post actually included a working implementation, but it’s nice to see another one using recursion. It makes me realize that my version only works for n>=2.

The difference is that your original version commits type piracy if it’s not in Base because it applies to all Function. That’s (one of) the reason(s) why you were suggesting its inclusion, I thought.

Mine applies only to the function that I own. That’s also the reason why I created a new function (with the same name) in the first place.

Does that make sense? I should have made the distinction clearer.

1 Like

Ah sorry I read your message too fast and missed the point, it makes perfect sense.

1 Like