# Base.factorial: Extending and overwriting functions in SpecialFunctions

**URL:** https://discourse.julialang.org/t/base-factorial-extending-and-overwriting-functions-in-specialfunctions/53486
**Category:** General Usage
**Tags:** base
**Created:** [January 17, 2021, 2:31pm UTC](https://discourse.julialang.org/t/base-factorial-extending-and-overwriting-functions-in-specialfunctions/53486 "2021-01-17T14:31:45Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![mr.red](https://avatars.discourse-cdn.com/v4/letter/m/35a633/32.png) [@mr.red](https://discourse.julialang.org/u/mr.red)
#### Post date: [January 17, 2021, 2:31pm UTC](https://discourse.julialang.org/t/base-factorial-extending-and-overwriting-functions-in-specialfunctions/53486/1 "2021-01-17T14:31:45Z")

</div>

The `Base.factorial` function supplies the following methods

```julia
julia> methods(factorial)
# 7 methods for generic function "factorial":
[1] factorial(n::UInt128) in Base at combinatorics.jl:26
[2] factorial(n::Int128) in Base at combinatorics.jl:25
[3] factorial(x::BigFloat) in Base.MPFR at mpfr.jl:639
[4] factorial(x::BigInt) in Base.GMP at gmp.jl:639
[5] factorial(n::Union{Int64, UInt64}) in Base at combinatorics.jl:27
[6] factorial(n::Union{Int16, Int32, Int8, UInt16, UInt32, UInt8}) in Base at combinatorics.jl:33
[7] factorial(n::Integer) in Base at intfuncs.jl:889

```

Currently that function is extended to `x::Number` using the `gamma` function within the `SpecialFunctions` module as such

```julia
# this trickery is needed while the deprecated method in Base exists
@static if !hasmethod(Base.factorial, Tuple{Number})
    import Base: factorial
end
factorial(x) = Base.factorial(x) # to make SpecialFunctions.factorial work unconditionally
factorial(x::Number) = gamma(x + 1) # fallback for x not Integer

```

It seems like that `Base.factorial` is deprecated according to the comments?

The problem arises now because the implementation `Base.factorial(x::BigFloat)` is checking that `isinteger(x)` which does not really make any sense. I’d like to extend it to any `BigFloat` by calling the `gamma` function.

Is it possible to extend `Base.factorial` in the following way:

- for `x::Integer` call `Base.factorial`
- else call `SpecialFunctions.gamma`
  - especially, overwrite `Base.factorial(x::BigFloat)`

I tried a straight forward implementation like such

```julia
# this trickery is needed while the deprecated method in Base exists
@static if !hasmethod(Base.factorial, Tuple{Number})
    import Base: factorial
end
factorial(x::Integer) = Base.factorial(x) # to make SpecialFunctions.factorial work unconditionally
factorial(x::Number) = gamma(x + 1) # fallback for x not Integer

```

This approach throws the following error

```julia
julia> using SpecialFunctions
[Info: Precompiling SpecialFunctions [276daf66-3868-5448-9aa4-cd146d93841b]
WARNING: Method definition factorial(Integer) in module Base at intfuncs.jl:889 overwritten in module SpecialFunctions at <HOME>/.julia/environments/SpecialFunctions-dev/dev/SpecialFunctions/src/gamma.jl:891.
  **incremental compilation may be fatally broken for this module**

```

* * *

This in relation to issue [#233](https://github.com/JuliaMath/SpecialFunctions.jl/issues/232).

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [January 19, 2021, 11:46am UTC](https://discourse.julialang.org/t/base-factorial-extending-and-overwriting-functions-in-specialfunctions/53486/2 "2021-01-19T11:46:14Z")

</div>

> [@mr.red](#):
>
> that function is extended to `x::Number`

That is technically type piracy and should not be part of a solution. IMO in the long run, it would be best to move all methods either into or out of `Base` — piling hacks on hacks will continue to backfire.
