If I omit the semicolon, this code doesn't compile.
def checkRadioButton(xml: DslBuilder): String => XmlTree = {
val inputs = top(xml).\\*(hasLocalNameX("input"));
{ (buttonValue: String) =>
// code omitted
}
}
My guess is that, without the semicolon, scalac thinks that the partial function is another argument to the \\*
method, instead of the return value. (It isn't actually a partial function, by the way, it's a total function.)
Can I do without the semicolon here? I've never had to use a semicolon at the end of a line before in Scala.
I’d write it like this instead:
def checkRadioButton(xml: DslBuilder): String => XmlTree = {
val inputs = top(xml).\\*(hasLocalNameX("input"));
(buttonValue: String) => { // <-- changed position of {
// code omitted
}
}
Just add a second newline, which apparently is equivalent to the semicolon.
Still, I'm not entirely happy with this, as it seems fragile.
Here is a simplification, explanation, and beautification.
Simplified,
scala> def f: String => String = {
| val i = 7
| { (x: String) =>
| "y"
| }
| }
<console>:9: error: Int(7) does not take parameters
{ (x: String) =>
^
<console>:12: error: type mismatch;
found : Unit
required: String => String
}
^
This fails because the newline after the 7
is not taken as a semicolon, for the reason that it might be a function application; you might want a DSL where the brace is on the next line. Here is the little nl
in the syntax of an arg with braces.
Newline handling is described in 1.2 of the spec; a few spots like this one, where a single nl
is accepted, are mentioned at the end of the section.
(Two newlines doesn't work, which is why that also fixes your problem.)
Notice that a nl
is not accepted in front of a paren, so the following works (though with only parens, you get only one expression for your function literal):
scala> def g: String => String = {
| val i = 7
| ( (x: String) =>
| "y"
| )
| }
g: String => String
In fact, the best edit for the problem code is not more braces but fewer:
scala> def f: String => String = {
| val i = 7
| x: String =>
| "y"
| }
f: String => String
The reason for this nice syntax is that your method body is already a block expression, and when the result expression of a block is a function literal, you can simplify.
The type of x
is also redundant.
scala> def f: String => String = {
| val i = 7
| x =>
| val a = "a"
| val b = "b"
| a + i + x + b
| }
f: String => String
And not surprisingly:
scala> def f: (String, Int) => String = {
| val i = 7
| (x, j) =>
| x + (i + j)
| }
f: (String, Int) => String
scala> f("bob",70)
res0: String = bob77