# Function reusing in Julia without inheritance

**URL:** <https://discourse.julialang.org/t/function-reusing-in-julia-without-inheritance/66108>\
**Category:** New to Julia\
**Tags:** inheritance\
**Created:** [August 10, 2021, 5:52am UTC](https://discourse.julialang.org/t/function-reusing-in-julia-without-inheritance/66108 "2021-08-10T05:52:31Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![hideakiv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hideakiv/32/22193_2.png) [@hideakiv](https://discourse.julialang.org/u/hideakiv)\
**Post date:** [August 10, 2021, 5:52am UTC](https://discourse.julialang.org/t/function-reusing-in-julia-without-inheritance/66108/1 "2021-08-10T05:52:32Z")

</div>

Suppose I have

```julia
struct Var
    x::Float64
end

```

and

```julia
function square(x::Float64)
    return x^2
end

```

To define a function for squaring a Var and returning a Var, I could write

```julia
function square(var::Var)
    y = square(var.x)
    return Var(y)
end

```

However, if I have many other functions like square (cube, square\_root, etc), how can I avoid rewriting the function for every function that uses Float64 as an input? I could think of a way in an OOP language by inheriting from an abstract class with undefined function, but not sure how to do this in Julia.

---

<div class="post-metadata">

**Author:** ![lungben](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lungben/32/12314_2.png) [@lungben](https://discourse.julialang.org/u/lungben)\
**Post date:** [August 10, 2021, 6:26am UTC](https://discourse.julialang.org/t/function-reusing-in-julia-without-inheritance/66108/2 "2021-08-10T06:26:14Z")

</div>

In a rather similar way - define an abstract supertype.

```julia
abstract type MyVars end

struct Var <: MyVars
    x:: Float64
end

square(var:: MyVars) = square(var.x)

```

---

<div class="post-metadata">

**Author:** ![hideakiv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hideakiv/32/22193_2.png) [@hideakiv](https://discourse.julialang.org/u/hideakiv)\
**Post date:** [August 10, 2021, 6:40am UTC](https://discourse.julialang.org/t/function-reusing-in-julia-without-inheritance/66108/3 "2021-08-10T06:40:10Z")

</div>

I’m trying to figure out a way that doesn’t involve rewriting the same things.  
Code generation might be the one I am looking for:

```julia
op = (:square, :cube)
for p in op
    @eval $p(var::Var) = Var($p(var.x))
end

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [August 10, 2021, 7:14am UTC](https://discourse.julialang.org/t/function-reusing-in-julia-without-inheritance/66108/4 "2021-08-10T07:14:49Z")

</div>

> [@hideakiv](#):
>
> However, if I have many other functions like square (cube, square\_root, etc), how can I avoid rewriting the function for every function that uses Float64 as an input?

If a function limits itself to `Float64`, it either

- really only works on `Float64` (because it manipulates them in a way that usually only works on `Float64` specifically, like some bit-level manipulation) or
- it’s limited unnaturally to `Float64`, even though it doesn’t require `Float64` per se and rather depends on some other contract.

In the case you posted, `square` doesn’t actually care about `Float64` at all - it only cares about having a `pow` method that takes as it’s first argument something and as its second argument an `Integer`. So in this case, `square` is erronously limited to `Float64`.

I’d solve this by

1. not limiting my methods arbitrarily
2. implementing `^` (and whatever else you may need, I think there are some packages that can do this kind of forwarding for wrapper types almost automatically)

Then, `square(x)` with `typeof(x) === Var` just works™. Moreover, because [julia compiles specialized methods for each combination of input argument types](https://docs.julialang.org/en/v1/manual/methods/#Methods), this will make your code much more composable and still keep performance. For example, not limiting your methods to `::Float64` would allow something like DifferentialEquations.jl to automatically take advantage of your code, by passing in a `Dual` number (which behaves like a float, i.e. has the same kinds of methods like `^` and `*` etc. implemented, but _isn’t_ just a wrapper around `Float64`) to do automatic differentiation, enable execution tracing and a number of other things.

> [@hideakiv](#):
>
> I could think of a way in an OOP language by inheriting from an abstract class with undefined function, but not sure how to do this in Julia.

May I ask what kind of OOP you’re referring to? If you’re thinking Java-style where you’re inheriting not only behavior but also struct fields, you’re going to have a bad time trying to replicate it in julia. Method level type assertions on arguments should in my opinion _only_ be used to distinguish different implementations in dispatch, not for limiting incoming arguments (there is _no_ performance difference between a typed and untyped argument in a method, except in [very, very rare cases](https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing) you’re unlikely to run into).
