# Extending methods of pure function

**URL:** https://discourse.julialang.org/t/extending-methods-of-pure-function/18852
**Category:** General Usage
**Created:** [December 20, 2018, 2:33pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852 "2018-12-20T14:33:22Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)
#### Post date: [December 20, 2018, 2:33pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852/1 "2018-12-20T14:33:22Z")

</div>

AFAIU adding methods to `@pure` functions is not allowed. However I have a function `mysin` that I want to be able to add methods to later on and I also know that certain methods are pure. Is a purity fence like in the following snipped a sane solution to this?

```julia
using BenchmarkTools

Base.@pure mysin_pure(x::Float64) = sin(x)
mysin(x) = mysin_pure(x)
mysin(x::String) = some_cracy_method_added_later_on

function doit(f,n=100)
    ret = 0.
    for _ in 1:n
        ret += f(1)
    end
    ret
end

@btime doit(sin)
@btime doit(mysin)
  674.955 ns (0 allocations: 0 bytes)
  52.307 ns (0 allocations: 0 bytes)

```

If so is it also a sane idea to add a `@pure_method` macro that expands

```julia
@macroexpand @pure_method f(x) = body

```

into something like

```julia
Base.@pure f_pure(x) = body
f(x) = f_pure(x)

```

---

<div class="post-metadata">

### Author: ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)
#### Post date: [December 20, 2018, 4:11pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852/2 "2018-12-20T16:11:53Z")

</div>

In short, _disrecommended_.  
(because) You are asking “Is it reasonable to take a `@pure` function and then make it generic if it is done indirectly?”

> A pure function can only depend on immutable information. This also means a `@pure` function cannot use any global mutable state, including generic functions. Calls to generic functions depend on method tables which are mutable global state. Use with caution, incorrect `@pure` annotation of a function may introduce hard to identify bugs. Double check for calls to generic functions.

Doing what you explore would violate documented tenants of `@purity`.

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [December 20, 2018, 9:33pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852/3 "2018-12-20T21:33:22Z")

</div>

Actually, I think your proposal with `mysin` and `mysin_pure` looks totally fine. `mysin` is a regular generic function, and one of its methods happens to call an `@pure` function. That all sounds good to me.

I’m not as sure about your proposed macro–if you find yourself needing to use `@pure` that much, it might be a sign that there’s a better approach out there somewhere.

---

<div class="post-metadata">

### Author: ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)
#### Post date: [December 20, 2018, 9:54pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852/4 "2018-12-20T21:54:01Z")

</div>

Also, marking “pure” a function called “mysin” is theologically frowned upon.

(sorry)

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [December 20, 2018, 10:41pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852/5 "2018-12-20T22:41:23Z")

</div>

Maybe unsafe?, considering that `sin(Inf)` throws and this answer in [Can @pure functions throw an error? - #2 by jameson](https://discourse.julialang.org/t/can-pure-functions-throw-an-error/18459/2)

> [@Can @pure functions throw an error?](https://discourse.julialang.org/t/can-pure-functions-throw-an-error/18459/2):
>
> Probably a very bad idea, as `pure` means we can discard or duplicate side-effects, which then also means we can transform any program that might call this function into one that always throws this error at startup

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [December 20, 2018, 10:48pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852/6 "2018-12-20T22:48:32Z")

</div>

But I wonder if it is OK to wrap a generic function when all the arguments are concrete immutable and it’s “conceptually” pure (e.g., it doesn’t throw). I mean, is @jw3126’s example fine if `sin` doesn’t throw? Applying this point in the docstring literally probably indicates no:

> This also means a `@pure` function cannot use any global mutable state, including generic functions.

But I see this in `Base`:

> <https://github.com/JuliaLang/julia/blob/851ae465c45c9db88f0a854646f28eb0589883e5/base/set.jl#L536-L537>

---

<div class="post-metadata">

### Author: ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)
#### Post date: [December 20, 2018, 10:58pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852/7 "2018-12-20T22:58:25Z")

</div>

Ah thanks, I thought `sin(Inf)` was `NaN`, but you are right it throws.

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [December 20, 2018, 11:35pm UTC](https://discourse.julialang.org/t/extending-methods-of-pure-function/18852/8 "2018-12-20T23:35:29Z")

</div>

But then I found this example where a `@pure` function calls a generic function which includes a path to `throw` but actually is impossible to `throw` inside the context of the `@pure` function: [Rationale for the `@pure`ity of `Rational{T}(x)`](https://discourse.julialang.org/t/rationale-for-the-pure-ity-of-rational-t-x/18872). So maybe it’s fine to do this?

```julia
Base.@pure mysin_pure(x::Float64) = isfinite(x) ? sin(x) : NaN

```
