- Typo in the non-recursive version

6 years 44 weeks ago - Guido's comments

6 years 50 weeks ago - Performance implication of using this idiom

7 years 6 days ago - this uses dynamic invocation

7 years 46 weeks ago

7 January 2010 - 5:36pm — Eamonn

If you learned about recursion you probably were given the factorial function as a simple example. Here it is in Scala:

def factorial(n:Int):Int = if(n==0) 1 else n * factorial(n-1)

Very nice. Now you can do `factorial(6)`

to get the answer `720`

.

But would it not be nicer if you could use standard mathematical notation and do `6!`

Well you can. Simply add this simple pimping implicit somewhere in scope:

implicit def pimp(i:Int) = new { def ! = factorial(i) }

Now you can use the `!`

operator after any integer. To avoid confusing the compiler, however, you may have to add some extra parentheses:

(3!) + (3!)

(3+3)!

Can we do better? Well if we avoid using recursion we can do it all in one line:

implicit def pimp(n:Int) = new { def ! = ((1 to n) :\ 1) ( _ * _ ) }

Here we are generating the integers 1,2,3,...,n and using the `:/`

fold operator to multiply them all together.

- Printer-friendly version
- Login or register to post comments

## Comments

## Typo in the non-recursive version

Since foldRight actually uses recursion underneath the covers I think you meant for your non-recursive version to be:

implicit def pimp(n:Int) = new { def ! = (1 /: (1 to n)) ( _ * _ ) }

Otherwise you will still be using recursion and will probably end up running out of heap space.

Also it might make more sense to use BigInt for the return value since even small factorials will easily overflow both Int and Long.