Question

I'm having a hard time understanding the scala compiler here. I'm passing three higher order functions to a superclass like this:

... extends Arithmetic(Math.pow(-_,_), Math.log(_)/Math.log(_), Math.pow(_,_))

The first function doesn't compile, the last function compiles, the only difference being the minus sign. The compiler gives the following warning:

error: wrong number of parameters; expected = 2

which is confusing, as there are two underscores. I will probably have to ditch the underscore syntax, but I want to understand why this happens. I have also tried

Math.pow(0-(_),_)    Math.pow(0.-(_),_)    Math.pow(0.0.-(_),_)

which all give the same error. Finally

Math.pow(-(_:Double),_:Double)

gives a new error

error: type mismatch;
  found   : Double => Double
  required: Double

which looks more like an actual error instead of me violating syntax. Now my next thought was, "apparently the underscore syntax doesn't work if there are functions within others". But looking at the second function Math.log(_) / Math.log(_), which to my knowledge is converted to Math.log(_)./(Math.log(_)), and compiles, this makes no sense, as here the partially applied log function is passed into ./(...)

Also, the expected type of the function, defined in the superclass Arithmetic is (Double,Double) => Double, so why does the type problem only surface after I explicitely declared the types?

Color me confused.

Was it helpful?

Solution

Math.pow(_,_) means (x,y) => Math.pow(x,y) whereas Math.pow(-_,_) means y => Math.pow(x => -x,y). Math.log(_)/Math.log(_) is an infix method call, it means the same as Math.log(_)./(Math.log(_)) and therefore (x,y) => Math.log(x)./(Math.log(y)).

See the StackOverflow Scala Tutorial in Chapter 21 "Functions/Function literals" and the subpoints "Placeholder syntax" to find more detailed explanations about how the underscores are parsed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top