Tuesday, October 14, 2008

Scala's Model of Functions

I was a little dismayed to learn that Scala models functions with different numbers of parameters as instances of distinct function trait definitions. A practical upshot of this is that you can't really work with functions that take more than 22 parameters.

def crazy(a:Int, b:Int, c:Int, d:Int, e:Int, f:Int, g:Int, h:Int, i:Int, j:Int, 
k:Int, l:Int, m:Int, n:Int, o:Int, p:Int, q:Int, r:Int, s:Int, t:Int,
u:Int, v:Int) = 0
(crazy _).curry : (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) =>
(Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) =>
(Int) => (Int) => Int = <function>

def crazier(a:Int, b:Int, c:Int, d:Int, e:Int, f:Int, g:Int, h:Int, i:Int, j:Int,
k:Int, l:Int, m:Int, n:Int, o:Int, p:Int, q:Int, r:Int, s:Int, t:Int,
u:Int, v:Int, w:Int) = 0
(crazier _).curry : <error>

The scala runtime apparently has traits Function0 through Function22 defined. I guess this is so that they can have call methods that take a statically known list of parameters (rather than, say, an array). That's all well and good, and probably necesary for proper Java interop, but it's still a little sad. Still, I don't expect to run into that limit any time soon. Oh wait, I have already worked on projects with functions that take more than 20 parameters. Maybe this was added just for me. Now I'm sad.

1 comment:

Ricky Clarkson said...

I think you'll find that if you provide the extra classes, say, scala.Function23 yourself, it will work. If you have a real case for increasing that number feel free to file a bug report. Those classes are automatically generated when the Scala distribution is built, so changing that 22 to a higher number would be straightforward.

It would be nicer if it used a HList-related model, but that would be slower on the JVM.