Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get a "missing parameter for expanded function" in one case and not the other?

Tags:

scala

Case this works:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (println(_))

Whereas this doesn't:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception(_.toString))

Compilation ends with this error:

error: missing parameter type for expanded function ((x$4) => x$4.toString)

Now if I write it this way it compiles again:

Seq(fromDir, toDir) find (!_.isDirectory) foreach (s => throw new Exception(s.toString))

I am sure there is a reasonable explanation ;)

like image 273
ebruchez Avatar asked Jan 15 '11 19:01

ebruchez


2 Answers

This has already been addressed in a related question. Underscores extend outwards to the closest closing Expr : top-level expressions or expressions in parentheses.

(_.toString) is an expression in parentheses. The argument you are passing to Exception in the error case is therefore, after expansion, the full anonymous function (x$1) => x$1.toString of type A <: Any => String, while Exception expects a String.

In the println case, _ by itself isn't of syntactic category Expr, but (println (_)) is, so you get the expected (x$0) => println(x$0).

like image 79
Francois G Avatar answered Nov 10 '22 05:11

Francois G


The difference is whether _ stands for the whole parameter, or is part of an expression. Depending on which, it falls into one of the two following categories:

Partially Applied Function

Seq(fromDir, toDir) find (!_.isDirectory) foreach (println(_))

translates into

Seq(fromDir, toDir) find (!_.isDirectory) foreach ((x$1) => println(x$1))

Anonymous Function Parameter

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception(_.toString))

translates into

Seq(fromDir, toDir) find (!_.isDirectory) foreach (throw new Exception((x$1) => x$1.toString))
like image 9
Daniel C. Sobral Avatar answered Nov 10 '22 04:11

Daniel C. Sobral