How about to simplify the factorial function name?

Recently I found it quite complicated to call the function factorial(). I feel it too long for such a function that is so frequently used in some situations. Can we make it simpler? Like !(n) (I found that the operator ! does not have a method for ::Integer), for example.

I’ve never found the argument about length of functions/commands compelling, in any language. If you get tired of typing it’s probably a sign you need better tooling (for example some more help from your IDE), but bending a language because you don’t want to type to more is never a good idea.

If you have some factorial-heavy code you can introduce an alias yourself.

julia> const ! = factorial
factorial (generic function with 7 methods)

julia> !(5)
120

For performance reasons it’s important to use const.

Does this hide ! as negation? If so, everywhere?

Just in your code. :slight_smile:

Well, I guess that’s a little heavy-handed. In your own code it’s probably a better idea to commit some type piracy with

Base.:!(x::Int) = factorial(x)

but on the whole it would be advisable to alias it to something truly private.

And then again it is debatable whether !(5) is truly more readable than factorial(5), especially in a language where ! usually means boolean negation

If you have a high factorial density in your code I think it’s an arguable improvement but since it definitely means something different from negation it will never be considered for Base.

If you really want to commit a crime, with this

julia> Base.:(*)(n::Int, ::typeof(Base.:(!))) = factorial(n)

julia> 5(!)
120

at least you get the order right (although you need too many parentheses) :stuck_out_tongue_winking_eye: But again, don’t do it!

Thanks. It wouldn’t ever happen in my code. I was just curious how much potential damage it would cause.

You can just do

julia> !5
120

:smiley:

[I think actually `5!` could be made to do this, as in with Unitful.jl, but I’m not sure.]

You can get this with one letter, and readable in a way, i.e. using the correct functional form with the related gamma function:

julia> Ī“(6)  # Yes, you still have to type \Gamma<TAB>
120

after defining:

julia> const Ī“(x::Integer) = factorial(x-1)
Ī“ (generic function with 2 methods)

The gamma function is there:

I’m not going to propose adding const Ī“(x::Number) = gamma(x) there (which gives Float64), I suppose the Greek letters were considered too valuable to also claim one of them.

Hm. Maybe:

julia> struct Factorial end

julia> const _! = Factorial()
Factorial()

julia> Base.:*(n::Integer, ::Factorial) = factorial(n)

julia> 5_!
120

?

It doesn’t parse:

julia> 5!
ERROR: syntax: extra token "!" after end of expression
Stacktrace:
 [1] top-level scope
   @ none:1

I like it.

julia> struct Factorial end
julia> const ā¢ = Factorial()
julia> Base.:*(n::Integer, ::Factorial) = factorial(n)
julia> 5ā¢
120

:slight_smile:

That’s very clever but isn’t Base.* supposed to be for a function that behaves like multiplication?

Not really much danger in abusing it here for nice juxtaposition notation

Or const ā— = Factorial(), which can be typed by \:exclamation:<tab>. :wink:

Honestly, though, I’m a bit curious about what kind of code makes such heavy use of factorial that a shortcut is worth it.

(A common mistake is calling factorial when evaluating series formulas. See also this tutorial.)

Mine’s the ā€˜fat-torial’… :grinning:

Sometimes you want to optimize for performance and or numerical accuracy. Other times you know that doesn’t matter in your case and you just want to write pretty code