What's the reasoning behind adding the "case" keyword to Scala? - scala

Apart from:
case class A
... case which is quite useful?
Why do we need to use case in match? Wouldn't:
x match {
y if y > 0 => y * 2
_ => -1
}
... be much prettier and concise?
Or why do we need to use case when a function takes a tuple? Say, we have:
val z = List((1, -1), (2, -2), (3, -3)).zipWithIndex
Now, isn't:
z map { case ((a, b), i) => a + b + i }
... way uglier than just:
z map (((a, b), i) => a + b + i)
...?

First, as we know, it is possible to put several statements for the same case scenario without needing some separation notation, just a line jump, like :
x match {
case y if y > 0 => y * 2
println("test")
println("test2") // these 3 statements belong to the same "case"
}
If case was not needed, compiler would have to find a way to know when a line is concerned by the next case scenario.
For example:
x match {
y if y > 0 => y * 2
_ => -1
}
How compiler would know whether _ => -1 belongs to the first case scenario or represents the next case?
Moreover, how compiler would know that the => sign doesn't represent a literal function but the actual code for the current case?
Compiler would certainly need a kind of code like this allowing cases isolation:
(using curly braces, or anything else)
x match {
{y if y > 0 => y * 2}
{_ => -1} // confusing with literal function notation
}
And surely, solution (provided currently by scala) using case keyword is a lot more readable and understandable than putting some way of separation like curly braces in my example.

Adding to #Mik378's answer:
When you write this: (a, b) => something, you are defining an anonymous Function2 - a function that takes two parameters.
When you write this: case (a, b) => something, you are defining an anonymous PartialFunction that takes one parameter and matches it against a pair.
So you need the case keyword to differentiate between these two.

The second issue, anonymous functions that avoid the case, is a matter of debate:
https://groups.google.com/d/msg/scala-debate/Q0CTZNOekWk/z1eg3dTkCXoJ
Also: http://www.scala-lang.org/old/node/1260
For the first issue, the choice is whether you allow a block or an expression on the RHS of the arrow.
In practice, I find that shorter case bodies are usually preferable, so I can certainly imagine your alternative syntax resulting in crisper code.
Consider one-line methods. You write:
def f(x: Int) = 2 * x
then you need to add a statement. I don't know if the IDE is able to auto-add parens.
def f(x: Int) = { val res = 2*x ; res }
That seems no worse than requiring the same syntax for case bodies.
To review, a case clause is case Pattern Guard => body.
Currently, body is a block, or a sequence of statements and a result expression.
If body were an expression, you'd need braces for multiple statements, like a function.
I don't think => results in ambiguities since function literals don't qualify as patterns, unlike literals like 1 or "foo".
One snag might be: { case foo => ??? } is a "pattern matching anonymous function" (SLS 8.5). Obviously, if the case is optional or eliminated, then { foo => ??? } is ambiguous. You'd have to distinguish case clauses for anon funs (where case is required) and case clauses in a match.
One counter-argument for the current syntax is that, in an intuition deriving from C, you always secretly hope that your match will compile to a switch table. In that metaphor, the cases are labels to jump to, and a label is just the address of a sequence of statements.
The alternative syntax might encourage a more inlined approach:
x match {
C => c(x)
D => d(x)
_ => ???
}
#inline def c(x: X) = ???
//etc
In this form, it looks more like a dispatch table, and the match body recalls the Map syntax, Map(a -> 1, b -> 2), that is, a tidy simplification of the association.

One of the key aspects of code readability is the words that grab your attention. For example,
return grabs your attention when you see it because you know that it is such a decisive action (breaking out of the function and possible sending a value back to the caller).
Another example is break--not that I like break, but it gets your attention.
I would agree with #Mik378 that case in Scala is more readable than the alternatives. Besides the compiler confusion he mentions, it gets your attention.
I am all for concise code, but there is a line between concise and illegible. I will gladly make the trade of 4n characters (where n is the number of cases) for the substantial readability that I get in return.

Related

How to model if-expressions with actor systems?

I'm trying to emulate a simple functional language using an actor based execution model where issues arose modelling if-expression.
Actor systems nowadays are used basically for speeding up all kind of stuff by avoiding OS locks and stalled threads or to make microservices less painful, but initially it was supposed to be an alternative model of computation in general [1][2], a contemporary take on it may be propagation networks. So this should be capable to cover any programming language construct and certainly an if, right?
While I'm aware that this is occasionally met with irritation, I saw one timid attempt to move towards recursive algorithms represented using akka actors (I've refurbished it and added further examples including the one given below). That attempt halted at function calls, but why not go further and also model operators and if conditions with actors? In fact the smalltalk language applies this model and yields a precursor of the actor concept, as has been pointed out in the accepted answers below.
Surprisingly recursive function calls aren't much of an issue, but if1 is, due to it's potentially stateful nature.
Given the clause C: if a then x else y, here's the problem:
My initial idea was, that C is an actor behaving like a function with 3 parameters (a,x,y) that returns either x or y depending on a. Being maximally parallel [2] a,x and y would be evaluated simultaneously and passed as messages to C. Now, this isn't really good, if C is the exit condition of a recursive function f, sending one branch of f in an infinite recursion. Also if x or y have side effects one can't just evaluate both of them. Let's take this recursive sum (which is not the usual factorial, stupid as such and could be made tail recursive, but that's not the point)
f(n) = if n <= 0
0
else
n + f(n -1)
Note, that I'd like to create an if-expression resembling the one of Scala, see the (spec, p. 88), or Haskell, for that matter, rather than an if-statement that relies on side-effects.
f(0) would cause 3 concurrent evaluations
n <= 0 (ok)
0 (ok)
n + f(n -1) (bad, introducing the weird behavior that the call to f(n) actually will return (yielding 0) but the evaluation of its branches continues infinitely)
I can see these options from here:
The whole computation becomes stateful and the evaluation of either x
or y only happens after a has been calculated (mandatory if x or y have side effects).
Some guarding mechanism gets introduced that renders x or y not
applicable for arguments outside a certain range upon the call of f. They might evaluate to some "not applicable" marker instead of a value, which will not be used in C anyway, since it comes from a branch which isn't relevant.
I'm not sure at this point, If I didn't miss out on the question at a fundamental level and there are obvious other approaches that I just don't see. Input appreciated :)
Btw. see this for an exhaustive list of conditional branching in different languages, without giving their semantics, and, not exhaustive, the wiki page on conditionals, with semantics, and this for a discussion how the question at hand is an issue till down to the level of hardware.
1 I'm aware that an if could be seen as a special case of pattern matching, but then the question is, how to model the different cases of a match expression using actors. But maybe that wasn't even intended in the first place, matching is just something that every actor can do without referring to other specialized "match-actors". On the other hand it has been stated that "everything is an actor", rather confusing[2]. Btw. does anybody have a clear notion what the [#message whatever] notation is meant to be in that paper? # is irritatingly undefined. Maybe smalltak gives a hint, there it indicates a symbol.
There is a little bit of a misconception in your question. In functional languages, if is not necessarily a function of three parameters. Rather, it is sometimes two functions of two parameters.
In particular, that is how the Church Encoding of Booleans works in λ-calculus: there are two functions, let's call them True and False. Both functions have two parameters. True simply returns the first argument, False simply returns the second argument.
First, let's define two functions called true and false. We could define them any way we want, they are completely arbitrary, but we will define them in a very special way which has some advantages as we will see later (I will use ECMAScript as a somewhat reasonable approximation of λ-calculus that is probably readable by a bigger portion of visitors to this site than λ-calculus itself):
const tru = (thn, _ ) => thn,
fls = (_ , els) => els;
tru is a function with two parameters which simply ignores its second argument and returns the first. fls is also a function with two parameters which simply ignores its first argument and returns the second.
Why did we encode tru and fls this way? Well, this way, the two functions not only represent the two concepts of true and false, no, at the same time, they also represent the concept of "choice", in other words, they are also an if/then/else expression! We evaluate the if condition and pass it the then block and the else block as arguments. If the condition evaluates to tru, it will return the then block, if it evaluates to fls, it will return the else block. Here's an example:
tru(23, 42);
// => 23
This returns 23, and this:
fls(23, 42);
// => 42
returns 42, just as you would expect.
There is a wrinkle, however:
tru(console.log("then branch"), console.log("else branch"));
// then branch
// else branch
This prints both then branch and else branch! Why?
Well, it returns the return value of the first argument, but it evaluates both arguments, since ECMAScript is strict and always evaluates all arguments to a function before calling the function. IOW: it evaluates the first argument which is console.log("then branch"), which simply returns undefined and has the side-effect of printing then branch to the console, and it evaluates the second argument, which also returns undefined and prints to the console as a side-effect. Then, it returns the first undefined.
In λ-calculus, where this encoding was invented, that's not a problem: λ-calculus is pure, which means it doesn't have any side-effects; therefore you would never notice that the second argument also gets evaluated. Plus, λ-calculus is lazy (or at least, it is often evaluated under normal order), meaning, it doesn't actually evaluate arguments which aren't needed. So, IOW: in λ-calculus the second argument would never be evaluated, and if it were, we wouldn't notice.
ECMAScript, however, is strict, i.e. it always evaluates all arguments. Well, actually, not always: the if/then/else, for example, only evaluates the then branch if the condition is true and only evaluates the else branch if the condition is false. And we want to replicate this behavior with our iff. Thankfully, even though ECMAScript isn't lazy, it has a way to delay the evaluation of a piece of code, the same way almost every other language does: wrap it in a function, and if you never call that function, the code will never get executed.
So, we wrap both blocks in a function, and at the end call the function that is returned:
tru(() => console.log("then branch"), () => console.log("else branch"))();
// then branch
prints then branch and
fls(() => console.log("then branch"), () => console.log("else branch"))();
// else branch
prints else branch.
We could implement the traditional if/then/else this way:
const iff = (cnd, thn, els) => cnd(thn, els);
iff(tru, 23, 42);
// => 23
iff(fls, 23, 42);
// => 42
Again, we need some extra function wrapping when calling the iff function and the extra function call parentheses in the definition of iff, for the same reason as above:
const iff = (cnd, thn, els) => cnd(thn, els)();
iff(tru, () => console.log("then branch"), () => console.log("else branch"));
// then branch
iff(fls, () => console.log("then branch"), () => console.log("else branch"));
// else branch
Now that we have those two definitions, we can implement or. First, we look at the truth table for or: if the first operand is truthy, then the result of the expression is the same as the first operand. Otherwise, the result of the expression is the result of the second operand. In short: if the first operand is true, we return the first operand, otherwise we return the second operand:
const orr = (a, b) => iff(a, () => a, () => b);
Let's check out that it works:
orr(tru,tru);
// => tru(thn, _) {}
orr(tru,fls);
// => tru(thn, _) {}
orr(fls,tru);
// => tru(thn, _) {}
orr(fls,fls);
// => fls(_, els) {}
Great! However, that definition looks a little ugly. Remember, tru and fls already act like a conditional all by themselves, so really there is no need for iff, and thus all of that function wrapping at all:
const orr = (a, b) => a(a, b);
There you have it: or (plus other boolean operators) defined with nothing but function definitions and function calls in just a handful of lines:
const tru = (thn, _ ) => thn,
fls = (_ , els) => els,
orr = (a , b ) => a(a, b),
nnd = (a , b ) => a(b, a),
ntt = a => a(fls, tru),
xor = (a , b ) => a(ntt(b), b),
iff = (cnd, thn, els) => cnd(thn, els)();
Unfortunately, this implementation is rather useless: there are no functions or operators in ECMAScript which return tru or fls, they all return true or false, so we can't use them with our functions. But there's still a lot we can do. For example, this is an implementation of a singly-linked list:
const cons = (hd, tl) => which => which(hd, tl),
car = l => l(tru),
cdr = l => l(fls);
You may have noticed something peculiar: tru and fls play a double role, they act both as the data values true and false, but at the same time, they also act as a conditional expression. They are data and behavior, bundled up into one … uhm … "thing" … or (dare I say) object! Does this idea of identifying data and behavior remind us of anything?
Indeed, tru and fls are objects. And, if you have ever used Smalltalk, Self, Newspeak or other pure object-oriented languages, you will have noticed that they implement booleans in exactly the same way: two objects true and false which have method named if that takes two blocks (functions, lambdas, whatever) as arguments and evaluates one of them.
Here's an example of what it might look like in Scala:
sealed abstract trait Buul {
def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): T
def &&&(other: ⇒ Buul): Buul
def |||(other: ⇒ Buul): Buul
def ntt: Buul
}
case object Tru extends Buul {
override def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): U = thn
override def &&&(other: ⇒ Buul) = other
override def |||(other: ⇒ Buul): this.type = this
override def ntt = Fls
}
case object Fls extends Buul {
override def apply[T, U <: T, V <: T](thn: ⇒ U)(els: ⇒ V): V = els
override def &&&(other: ⇒ Buul): this.type = this
override def |||(other: ⇒ Buul) = other
override def ntt = Tru
}
object BuulExtension {
import scala.language.implicitConversions
implicit def boolean2Buul(b: ⇒ Boolean) = if (b) Tru else Fls
}
import BuulExtension._
(2 < 3) { println("2 is less than 3") } { println("2 is greater than 3") }
// 2 is less than 3
Given the very close relationship between OO and actors (they are pretty much the same thing, actually), which is not historically surprising (Alan Kay based Smalltalk on Carl Hewitt's PLANNER; Carl Hewitt based Actors on Alan Kay's Smalltalk), I wouldn't be surprised if this turned out to be a step in the right direction to solve your problem.
Q : didn't ( I ) miss out on the question at a fundamental level?
Yes, you happened to have missed a cardinal point: even the functional-languages, that may otherwise enjoy the forms of AND- and/or OR-based fine-grain sorts of parallelism, do not grow as wild as not to respect the strictly [SERIAL] nature of the if ( expression1 ) expression2 [ else expression3 ]
You have spend many efforts on argumentation about recursion-case(s) whereas the principal property was left out of your view. State-fullness is the Mother Nature of the computing ( these toys are nothing but finite state automata, no matter how large the state-space might be, it is and always will principally remain finite ).
Even the cited Scala p.88 confirms this: "The conditional expression is evaluated by evaluating first e1. If this evaluates to true, the result of evaluating e2 is returned, otherwise the result of evaluating e3 is returned." - which is a pure-[SERIAL] process-recipe ( one step after another ).
One may remember, that even the evaluation of expression1 may have (and does have ) state-change effects ( not only "side-effects" ), but indeed state-change effects ( PRNG-steps into a new state whenever a random-number was asked to get generated and many similar situations )
Thus the if e1 then e2 else e3 has to obey a pure-[SERIAL] implementation, no matter what benefits may be brought into action from fine-grain {AND|OR}-based-parallelism ( may see many working examples thereof in languages that can use 'em right since late 70-ies early 80-ies )

() vs {} in foreach case [duplicate]

What is the formal difference between passing arguments to functions in parentheses () and in braces {}?
The feeling I got from the Programming in Scala book is that Scala's pretty flexible and I should use the one I like best, but I find that some cases compile while others don't.
For instance (just meant as an example; I would appreciate any response that discusses the general case, not this particular example only):
val tupleList = List[(String, String)]()
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )
=> error: illegal start of simple expression
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }
=> fine.
I tried once to write about this, but I gave up in the end, as the rules are somewhat diffuse. Basically, you’ll have to get the hang of it.
Perhaps it is best to concentrate on where curly braces and parentheses can be used interchangeably: when passing parameters to method calls. You may replace curly braces with parentheses if, and only if, the method expects a single parameter. For example:
List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
However, there’s more you need to know to better grasp these rules.
Increased compile checking with parens
The authors of Spray recommend round parens because they give increased compile checking. This is especially important for DSLs like Spray. By using parens you are telling the compiler that it should only be given a single line; therefore if you accidentally give it two or more, it will complain. Now this isn’t the case with curly braces – if for example you forget an operator somewhere, then your code will compile, and you get unexpected results and potentially a very hard bug to find. Below is contrived (since the expressions are pure and will at least give a warning), but makes the point:
method {
1 +
2
3
}
method(
1 +
2
3
)
The first compiles, the second gives error: ')' expected but integer literal found. The author wanted to write 1 + 2 + 3.
One could argue it’s similar for multi-parameter methods with default arguments; it’s impossible to accidentally forget a comma to separate parameters when using parens.
Verbosity
An important often overlooked note about verbosity. Using curly braces inevitably leads to verbose code since the Scala style guide clearly states that closing curly braces must be on their own line:
… the closing brace is on its own line immediately following the last
line of the function.
Many auto-reformatters, like in IntelliJ, will automatically perform this reformatting for you. So try to stick to using round parens when you can.
Infix Notation
When using infix notation, like List(1,2,3) indexOf (2) you can omit parentheses if there is only one parameter and write it as List(1, 2, 3) indexOf 2. This is not the case of dot-notation.
Note also that when you have a single parameter that is a multi-token expression, like x + 2 or a => a % 2 == 0, you have to use parentheses to indicate the boundaries of the expression.
Tuples
Because you can omit parentheses sometimes, sometimes a tuple needs extra parentheses like in ((1, 2)), and sometimes the outer parentheses can be omitted, like in (1, 2). This may cause confusion.
Function/Partial Function literals with case
Scala has a syntax for function and partial function literals. It looks like this:
{
case pattern if guard => statements
case pattern => statements
}
The only other places where you can use case statements are with the match and catch keywords:
object match {
case pattern if guard => statements
case pattern => statements
}
try {
block
} catch {
case pattern if guard => statements
case pattern => statements
} finally {
block
}
You cannot use case statements in any other context. So, if you want to use case, you need curly braces. In case you are wondering what makes the distinction between a function and partial function literal, the answer is: context. If Scala expects a function, a function you get. If it expects a partial function, you get a partial function. If both are expected, it gives an error about ambiguity.
Expressions and Blocks
Parentheses can be used to make subexpressions. Curly braces can be used to make blocks of code (this is not a function literal, so beware of trying to use it like one). A block of code consists of multiple statements, each of which can be an import statement, a declaration or an expression. It goes like this:
{
import stuff._
statement ; // ; optional at the end of the line
statement ; statement // not optional here
var x = 0 // declaration
while (x < 10) { x += 1 } // stuff
(x % 5) + 1 // expression
}
( expression )
So, if you need declarations, multiple statements, an import or anything like that, you need curly braces. And because an expression is a statement, parentheses may appear inside curly braces. But the interesting thing is that blocks of code are also expressions, so you can use them anywhere inside an expression:
( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
So, since expressions are statements, and blocks of codes are expressions, everything below is valid:
1 // literal
(1) // expression
{1} // block of code
({1}) // expression with a block of code
{(1)} // block of code with an expression
({(1)}) // you get the drift...
Where they are not interchangeable
Basically, you can’t replace {} with () or vice versa anywhere else. For example:
while (x < 10) { x += 1 }
This is not a method call, so you can’t write it in any other way. Well, you can put curly braces inside the parentheses for the condition, as well as use parentheses inside the curly braces for the block of code:
while ({x < 10}) { (x += 1) }
There are a couple of different rules and inferences going on here: first of all, Scala infers the braces when a parameter is a function, e.g. in list.map(_ * 2) the braces are inferred, it's just a shorter form of list.map({_ * 2}). Secondly, Scala allows you to skip the parentheses on the last parameter list, if that parameter list has one parameter and it is a function, so list.foldLeft(0)(_ + _) can be written as list.foldLeft(0) { _ + _ } (or list.foldLeft(0)({_ + _}) if you want to be extra explicit).
However, if you add case you get, as others have mentioned, a partial function instead of a function, and Scala will not infer the braces for partial functions, so list.map(case x => x * 2) won't work, but both list.map({case x => 2 * 2}) and list.map { case x => x * 2 } will.
There is an effort from the community to standardize the usage of braces and parentheses, see Scala Style Guide (page 21): http://www.codecommit.com/scala-style-guide.pdf
The recommended syntax for higher order methods calls is to always use braces, and to skip the dot:
val filtered = tupleList takeWhile { case (s1, s2) => s1 == s2 }
For "normal" metod calls you should use the dot and parentheses.
val result = myInstance.foo(5, "Hello")
I don't think there is anything particular or complex about curly braces in Scala. To master the seeming-complex usage of them in Scala, just keep a couple of simple things in mind:
curly braces form a block of code, which evaluates to the last line of code (almost all languages do this)
a function if desired can be generated with the block of code (follows rule 1)
curly braces can be omitted for one-line code except for a case clause (Scala choice)
parentheses can be omitted in function call with code block as a parameter (Scala choice)
Let's explain a couple of examples per the above three rules:
val tupleList = List[(String, String)]()
// doesn't compile, violates case clause requirement
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )
// block of code as a partial function and parentheses omission,
// i.e. tupleList.takeWhile({ case (s1, s2) => s1 == s2 })
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }
// curly braces omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft(_+_)
// parentheses omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft{_+_}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).reduceLeft _+_ // res1: String => String = <function1>
// curly braces omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0)(_ + _)
// parentheses omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0){_ + _}
// block of code and parentheses omission
List(1, 2, 3).foldLeft {0} {_ + _}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).foldLeft(0) _ + _
// error: ';' expected but integer literal found.
List(1, 2, 3).foldLeft 0 (_ + _)
def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
// block of code that just evaluates to a value of a function, and parentheses omission
// i.e. foo({ println("Hey"); x => println(x) })
foo { println("Hey"); x => println(x) }
// parentheses omission, i.e. f({x})
def f(x: Int): Int = f {x}
// error: missing arguments for method f
def f(x: Int): Int = f x
I think it is worth explaining their usage in function calls and why various things happen. As someone already said curly braces define a block of code, which is also an expression so can be put where expression is expected and it will be evaluated. When evaluated, its statements are executed and last's statement value is the result of whole block evaluation (somewhat like in Ruby).
Having that we can do things like:
2 + { 3 } // res: Int = 5
val x = { 4 } // res: x: Int = 4
List({1},{2},{3}) // res: List[Int] = List(1,2,3)
Last example is just a function call with three parameters, of which each is evaluated first.
Now to see how it works with function calls let's define simple function that take another function as a parameter.
def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
To call it, we need to pass function that takes one param of type Int, so we can use function literal and pass it to foo:
foo( x => println(x) )
Now as said before we can use block of code in place of an expression so let's use it
foo({ x => println(x) })
What happens here is that code inside {} is evaluated, and the function value is returned as a value of the block evaluation, this value is then passed to foo. This is semantically the same as previous call.
But we can add something more:
foo({ println("Hey"); x => println(x) })
Now our code block contains two statements, and because it is evaluated before foo is executed, what happens is that first "Hey" is printed, then our function is passed to foo, "Entering foo" is printed and lastly "4" is printed.
This looks a bit ugly though and Scala lets us to skip the parenthesis in this case, so we can write:
foo { println("Hey"); x => println(x) }
or
foo { x => println(x) }
That looks much nicer and is equivalent to the former ones. Here still block of code is evaluated first and the result of evaluation (which is x => println(x)) is passed as an argument to foo.
Because you are using case, you are defining a partial function and partial functions require curly braces.
Increased compile checking with parens
The authors of Spray, recommend that round parens give increased compile checking. This is especially important for DSLs like Spray. By using parens you are telling the compiler that it should only be given a single line, therefore if you accidentally gave it two or more, it will complain. Now this isn't the case with curly braces, if for example, you forget an operator somewhere your code will compile, you get unexpected results and potentially a very hard bug to find. Below is contrived (since the expressions are pure and will at least give a warning), but makes the point
method {
1 +
2
3
}
method(
1 +
2
3
)
The first compiles, the second gives error: ')' expected but integer literal found. the author wanted to write 1 + 2 + 3.
One could argue it's similar for multi-parameter methods with default arguments; it's impossible to accidentally forget a comma to separate parameters when using parens.
Verbosity
An important often overlooked note about verbosity. Using curly braces inevitably leads to verbose code since the scala style guide clearly states that closing curly braces must be on their own line: http://docs.scala-lang.org/style/declarations.html "... the closing brace is on its own line immediately following the last line of the function." Many auto-reformatters, like in Intellij, will automatically perform this reformatting for you. So try to stick to using round parens when you can. E.g. List(1, 2, 3).reduceLeft{_ + _} becomes:
List(1, 2, 3).reduceLeft {
_ + _
}
Parenthesis in an ideal coding style is basically used for single line code.
But if the particular piece of code is multiline then using braces is a better way.
With braces, you got semicolon induced for you and parentheses not. Consider takeWhile function, since it expects partial function, only {case xxx => ??? } is valid definition instead of parentheses around case expression.

Spark: Difference using map() and map{} [duplicate]

What is the formal difference between passing arguments to functions in parentheses () and in braces {}?
The feeling I got from the Programming in Scala book is that Scala's pretty flexible and I should use the one I like best, but I find that some cases compile while others don't.
For instance (just meant as an example; I would appreciate any response that discusses the general case, not this particular example only):
val tupleList = List[(String, String)]()
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )
=> error: illegal start of simple expression
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }
=> fine.
I tried once to write about this, but I gave up in the end, as the rules are somewhat diffuse. Basically, you’ll have to get the hang of it.
Perhaps it is best to concentrate on where curly braces and parentheses can be used interchangeably: when passing parameters to method calls. You may replace curly braces with parentheses if, and only if, the method expects a single parameter. For example:
List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
However, there’s more you need to know to better grasp these rules.
Increased compile checking with parens
The authors of Spray recommend round parens because they give increased compile checking. This is especially important for DSLs like Spray. By using parens you are telling the compiler that it should only be given a single line; therefore if you accidentally give it two or more, it will complain. Now this isn’t the case with curly braces – if for example you forget an operator somewhere, then your code will compile, and you get unexpected results and potentially a very hard bug to find. Below is contrived (since the expressions are pure and will at least give a warning), but makes the point:
method {
1 +
2
3
}
method(
1 +
2
3
)
The first compiles, the second gives error: ')' expected but integer literal found. The author wanted to write 1 + 2 + 3.
One could argue it’s similar for multi-parameter methods with default arguments; it’s impossible to accidentally forget a comma to separate parameters when using parens.
Verbosity
An important often overlooked note about verbosity. Using curly braces inevitably leads to verbose code since the Scala style guide clearly states that closing curly braces must be on their own line:
… the closing brace is on its own line immediately following the last
line of the function.
Many auto-reformatters, like in IntelliJ, will automatically perform this reformatting for you. So try to stick to using round parens when you can.
Infix Notation
When using infix notation, like List(1,2,3) indexOf (2) you can omit parentheses if there is only one parameter and write it as List(1, 2, 3) indexOf 2. This is not the case of dot-notation.
Note also that when you have a single parameter that is a multi-token expression, like x + 2 or a => a % 2 == 0, you have to use parentheses to indicate the boundaries of the expression.
Tuples
Because you can omit parentheses sometimes, sometimes a tuple needs extra parentheses like in ((1, 2)), and sometimes the outer parentheses can be omitted, like in (1, 2). This may cause confusion.
Function/Partial Function literals with case
Scala has a syntax for function and partial function literals. It looks like this:
{
case pattern if guard => statements
case pattern => statements
}
The only other places where you can use case statements are with the match and catch keywords:
object match {
case pattern if guard => statements
case pattern => statements
}
try {
block
} catch {
case pattern if guard => statements
case pattern => statements
} finally {
block
}
You cannot use case statements in any other context. So, if you want to use case, you need curly braces. In case you are wondering what makes the distinction between a function and partial function literal, the answer is: context. If Scala expects a function, a function you get. If it expects a partial function, you get a partial function. If both are expected, it gives an error about ambiguity.
Expressions and Blocks
Parentheses can be used to make subexpressions. Curly braces can be used to make blocks of code (this is not a function literal, so beware of trying to use it like one). A block of code consists of multiple statements, each of which can be an import statement, a declaration or an expression. It goes like this:
{
import stuff._
statement ; // ; optional at the end of the line
statement ; statement // not optional here
var x = 0 // declaration
while (x < 10) { x += 1 } // stuff
(x % 5) + 1 // expression
}
( expression )
So, if you need declarations, multiple statements, an import or anything like that, you need curly braces. And because an expression is a statement, parentheses may appear inside curly braces. But the interesting thing is that blocks of code are also expressions, so you can use them anywhere inside an expression:
( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
So, since expressions are statements, and blocks of codes are expressions, everything below is valid:
1 // literal
(1) // expression
{1} // block of code
({1}) // expression with a block of code
{(1)} // block of code with an expression
({(1)}) // you get the drift...
Where they are not interchangeable
Basically, you can’t replace {} with () or vice versa anywhere else. For example:
while (x < 10) { x += 1 }
This is not a method call, so you can’t write it in any other way. Well, you can put curly braces inside the parentheses for the condition, as well as use parentheses inside the curly braces for the block of code:
while ({x < 10}) { (x += 1) }
There are a couple of different rules and inferences going on here: first of all, Scala infers the braces when a parameter is a function, e.g. in list.map(_ * 2) the braces are inferred, it's just a shorter form of list.map({_ * 2}). Secondly, Scala allows you to skip the parentheses on the last parameter list, if that parameter list has one parameter and it is a function, so list.foldLeft(0)(_ + _) can be written as list.foldLeft(0) { _ + _ } (or list.foldLeft(0)({_ + _}) if you want to be extra explicit).
However, if you add case you get, as others have mentioned, a partial function instead of a function, and Scala will not infer the braces for partial functions, so list.map(case x => x * 2) won't work, but both list.map({case x => 2 * 2}) and list.map { case x => x * 2 } will.
There is an effort from the community to standardize the usage of braces and parentheses, see Scala Style Guide (page 21): http://www.codecommit.com/scala-style-guide.pdf
The recommended syntax for higher order methods calls is to always use braces, and to skip the dot:
val filtered = tupleList takeWhile { case (s1, s2) => s1 == s2 }
For "normal" metod calls you should use the dot and parentheses.
val result = myInstance.foo(5, "Hello")
I don't think there is anything particular or complex about curly braces in Scala. To master the seeming-complex usage of them in Scala, just keep a couple of simple things in mind:
curly braces form a block of code, which evaluates to the last line of code (almost all languages do this)
a function if desired can be generated with the block of code (follows rule 1)
curly braces can be omitted for one-line code except for a case clause (Scala choice)
parentheses can be omitted in function call with code block as a parameter (Scala choice)
Let's explain a couple of examples per the above three rules:
val tupleList = List[(String, String)]()
// doesn't compile, violates case clause requirement
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )
// block of code as a partial function and parentheses omission,
// i.e. tupleList.takeWhile({ case (s1, s2) => s1 == s2 })
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }
// curly braces omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft(_+_)
// parentheses omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft{_+_}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).reduceLeft _+_ // res1: String => String = <function1>
// curly braces omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0)(_ + _)
// parentheses omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0){_ + _}
// block of code and parentheses omission
List(1, 2, 3).foldLeft {0} {_ + _}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).foldLeft(0) _ + _
// error: ';' expected but integer literal found.
List(1, 2, 3).foldLeft 0 (_ + _)
def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
// block of code that just evaluates to a value of a function, and parentheses omission
// i.e. foo({ println("Hey"); x => println(x) })
foo { println("Hey"); x => println(x) }
// parentheses omission, i.e. f({x})
def f(x: Int): Int = f {x}
// error: missing arguments for method f
def f(x: Int): Int = f x
I think it is worth explaining their usage in function calls and why various things happen. As someone already said curly braces define a block of code, which is also an expression so can be put where expression is expected and it will be evaluated. When evaluated, its statements are executed and last's statement value is the result of whole block evaluation (somewhat like in Ruby).
Having that we can do things like:
2 + { 3 } // res: Int = 5
val x = { 4 } // res: x: Int = 4
List({1},{2},{3}) // res: List[Int] = List(1,2,3)
Last example is just a function call with three parameters, of which each is evaluated first.
Now to see how it works with function calls let's define simple function that take another function as a parameter.
def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
To call it, we need to pass function that takes one param of type Int, so we can use function literal and pass it to foo:
foo( x => println(x) )
Now as said before we can use block of code in place of an expression so let's use it
foo({ x => println(x) })
What happens here is that code inside {} is evaluated, and the function value is returned as a value of the block evaluation, this value is then passed to foo. This is semantically the same as previous call.
But we can add something more:
foo({ println("Hey"); x => println(x) })
Now our code block contains two statements, and because it is evaluated before foo is executed, what happens is that first "Hey" is printed, then our function is passed to foo, "Entering foo" is printed and lastly "4" is printed.
This looks a bit ugly though and Scala lets us to skip the parenthesis in this case, so we can write:
foo { println("Hey"); x => println(x) }
or
foo { x => println(x) }
That looks much nicer and is equivalent to the former ones. Here still block of code is evaluated first and the result of evaluation (which is x => println(x)) is passed as an argument to foo.
Because you are using case, you are defining a partial function and partial functions require curly braces.
Increased compile checking with parens
The authors of Spray, recommend that round parens give increased compile checking. This is especially important for DSLs like Spray. By using parens you are telling the compiler that it should only be given a single line, therefore if you accidentally gave it two or more, it will complain. Now this isn't the case with curly braces, if for example, you forget an operator somewhere your code will compile, you get unexpected results and potentially a very hard bug to find. Below is contrived (since the expressions are pure and will at least give a warning), but makes the point
method {
1 +
2
3
}
method(
1 +
2
3
)
The first compiles, the second gives error: ')' expected but integer literal found. the author wanted to write 1 + 2 + 3.
One could argue it's similar for multi-parameter methods with default arguments; it's impossible to accidentally forget a comma to separate parameters when using parens.
Verbosity
An important often overlooked note about verbosity. Using curly braces inevitably leads to verbose code since the scala style guide clearly states that closing curly braces must be on their own line: http://docs.scala-lang.org/style/declarations.html "... the closing brace is on its own line immediately following the last line of the function." Many auto-reformatters, like in Intellij, will automatically perform this reformatting for you. So try to stick to using round parens when you can. E.g. List(1, 2, 3).reduceLeft{_ + _} becomes:
List(1, 2, 3).reduceLeft {
_ + _
}
Parenthesis in an ideal coding style is basically used for single line code.
But if the particular piece of code is multiline then using braces is a better way.
With braces, you got semicolon induced for you and parentheses not. Consider takeWhile function, since it expects partial function, only {case xxx => ??? } is valid definition instead of parentheses around case expression.

Why does Scala require pattern variables to be linear?

Scala requires pattern variables to be linear, i.e. pattern
variable may not occur more than once in a pattern. Thus, this example does not compile:
def tupleTest(tuple: (Int, Int)) = tuple match {
case (a, a) => a
case _ => -1
}
But you can use two pattern variables and a guard to check equality instead:
def tupleTest(tuple: (Int, Int)) = tuple match {
case (a, b) if a == b => a
case _ => -1
}
So why does Scala require pattern variables to be linear? Are there any cases that can not be transformed like this?
Edit
It is easy to transform the first example into the second (Scala to Scala). Of all occurrences of a variable v in the pattern take the expressions that is evaluated first and assign it to the variable v. For each other occurrence introduce a new variable with a name that is not used in the current scope. For each of those variables v' add a guard v == v'. It is the same way a programmer would go (=> same efficiency). Is there any problem with this approach? I'd like to see an example that can not be transformed like this.
Because case (a, b) is basically assigning val a to _._1 and val b to _._2 (at least you can view it like that). In case of case (a, a), you cannot assign val a to both _._1 and _._2.
Actually the thing you want to do would have been looked like
case (a, `a`) => ???
as scala uses backtick to match an identifier. But unfortunately that still doesn't work as the visibility of a is given only after => (would have been fun though, I also hate writing case (a, b) if a = b =>). And the reason of this is probably just because it is harder to write a compiler that supports that

What is the formal difference in Scala between braces and parentheses, and when should they be used?

What is the formal difference between passing arguments to functions in parentheses () and in braces {}?
The feeling I got from the Programming in Scala book is that Scala's pretty flexible and I should use the one I like best, but I find that some cases compile while others don't.
For instance (just meant as an example; I would appreciate any response that discusses the general case, not this particular example only):
val tupleList = List[(String, String)]()
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )
=> error: illegal start of simple expression
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }
=> fine.
I tried once to write about this, but I gave up in the end, as the rules are somewhat diffuse. Basically, you’ll have to get the hang of it.
Perhaps it is best to concentrate on where curly braces and parentheses can be used interchangeably: when passing parameters to method calls. You may replace curly braces with parentheses if, and only if, the method expects a single parameter. For example:
List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
However, there’s more you need to know to better grasp these rules.
Increased compile checking with parens
The authors of Spray recommend round parens because they give increased compile checking. This is especially important for DSLs like Spray. By using parens you are telling the compiler that it should only be given a single line; therefore if you accidentally give it two or more, it will complain. Now this isn’t the case with curly braces – if for example you forget an operator somewhere, then your code will compile, and you get unexpected results and potentially a very hard bug to find. Below is contrived (since the expressions are pure and will at least give a warning), but makes the point:
method {
1 +
2
3
}
method(
1 +
2
3
)
The first compiles, the second gives error: ')' expected but integer literal found. The author wanted to write 1 + 2 + 3.
One could argue it’s similar for multi-parameter methods with default arguments; it’s impossible to accidentally forget a comma to separate parameters when using parens.
Verbosity
An important often overlooked note about verbosity. Using curly braces inevitably leads to verbose code since the Scala style guide clearly states that closing curly braces must be on their own line:
… the closing brace is on its own line immediately following the last
line of the function.
Many auto-reformatters, like in IntelliJ, will automatically perform this reformatting for you. So try to stick to using round parens when you can.
Infix Notation
When using infix notation, like List(1,2,3) indexOf (2) you can omit parentheses if there is only one parameter and write it as List(1, 2, 3) indexOf 2. This is not the case of dot-notation.
Note also that when you have a single parameter that is a multi-token expression, like x + 2 or a => a % 2 == 0, you have to use parentheses to indicate the boundaries of the expression.
Tuples
Because you can omit parentheses sometimes, sometimes a tuple needs extra parentheses like in ((1, 2)), and sometimes the outer parentheses can be omitted, like in (1, 2). This may cause confusion.
Function/Partial Function literals with case
Scala has a syntax for function and partial function literals. It looks like this:
{
case pattern if guard => statements
case pattern => statements
}
The only other places where you can use case statements are with the match and catch keywords:
object match {
case pattern if guard => statements
case pattern => statements
}
try {
block
} catch {
case pattern if guard => statements
case pattern => statements
} finally {
block
}
You cannot use case statements in any other context. So, if you want to use case, you need curly braces. In case you are wondering what makes the distinction between a function and partial function literal, the answer is: context. If Scala expects a function, a function you get. If it expects a partial function, you get a partial function. If both are expected, it gives an error about ambiguity.
Expressions and Blocks
Parentheses can be used to make subexpressions. Curly braces can be used to make blocks of code (this is not a function literal, so beware of trying to use it like one). A block of code consists of multiple statements, each of which can be an import statement, a declaration or an expression. It goes like this:
{
import stuff._
statement ; // ; optional at the end of the line
statement ; statement // not optional here
var x = 0 // declaration
while (x < 10) { x += 1 } // stuff
(x % 5) + 1 // expression
}
( expression )
So, if you need declarations, multiple statements, an import or anything like that, you need curly braces. And because an expression is a statement, parentheses may appear inside curly braces. But the interesting thing is that blocks of code are also expressions, so you can use them anywhere inside an expression:
( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
So, since expressions are statements, and blocks of codes are expressions, everything below is valid:
1 // literal
(1) // expression
{1} // block of code
({1}) // expression with a block of code
{(1)} // block of code with an expression
({(1)}) // you get the drift...
Where they are not interchangeable
Basically, you can’t replace {} with () or vice versa anywhere else. For example:
while (x < 10) { x += 1 }
This is not a method call, so you can’t write it in any other way. Well, you can put curly braces inside the parentheses for the condition, as well as use parentheses inside the curly braces for the block of code:
while ({x < 10}) { (x += 1) }
There are a couple of different rules and inferences going on here: first of all, Scala infers the braces when a parameter is a function, e.g. in list.map(_ * 2) the braces are inferred, it's just a shorter form of list.map({_ * 2}). Secondly, Scala allows you to skip the parentheses on the last parameter list, if that parameter list has one parameter and it is a function, so list.foldLeft(0)(_ + _) can be written as list.foldLeft(0) { _ + _ } (or list.foldLeft(0)({_ + _}) if you want to be extra explicit).
However, if you add case you get, as others have mentioned, a partial function instead of a function, and Scala will not infer the braces for partial functions, so list.map(case x => x * 2) won't work, but both list.map({case x => 2 * 2}) and list.map { case x => x * 2 } will.
There is an effort from the community to standardize the usage of braces and parentheses, see Scala Style Guide (page 21): http://www.codecommit.com/scala-style-guide.pdf
The recommended syntax for higher order methods calls is to always use braces, and to skip the dot:
val filtered = tupleList takeWhile { case (s1, s2) => s1 == s2 }
For "normal" metod calls you should use the dot and parentheses.
val result = myInstance.foo(5, "Hello")
I don't think there is anything particular or complex about curly braces in Scala. To master the seeming-complex usage of them in Scala, just keep a couple of simple things in mind:
curly braces form a block of code, which evaluates to the last line of code (almost all languages do this)
a function if desired can be generated with the block of code (follows rule 1)
curly braces can be omitted for one-line code except for a case clause (Scala choice)
parentheses can be omitted in function call with code block as a parameter (Scala choice)
Let's explain a couple of examples per the above three rules:
val tupleList = List[(String, String)]()
// doesn't compile, violates case clause requirement
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )
// block of code as a partial function and parentheses omission,
// i.e. tupleList.takeWhile({ case (s1, s2) => s1 == s2 })
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }
// curly braces omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft(_+_)
// parentheses omission, i.e. List(1, 2, 3).reduceLeft({_+_})
List(1, 2, 3).reduceLeft{_+_}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).reduceLeft _+_ // res1: String => String = <function1>
// curly braces omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0)(_ + _)
// parentheses omission, i.e. List(1, 2, 3).foldLeft(0)({_ + _})
List(1, 2, 3).foldLeft(0){_ + _}
// block of code and parentheses omission
List(1, 2, 3).foldLeft {0} {_ + _}
// not both though it compiles, because meaning totally changes due to precedence
List(1, 2, 3).foldLeft(0) _ + _
// error: ';' expected but integer literal found.
List(1, 2, 3).foldLeft 0 (_ + _)
def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
// block of code that just evaluates to a value of a function, and parentheses omission
// i.e. foo({ println("Hey"); x => println(x) })
foo { println("Hey"); x => println(x) }
// parentheses omission, i.e. f({x})
def f(x: Int): Int = f {x}
// error: missing arguments for method f
def f(x: Int): Int = f x
I think it is worth explaining their usage in function calls and why various things happen. As someone already said curly braces define a block of code, which is also an expression so can be put where expression is expected and it will be evaluated. When evaluated, its statements are executed and last's statement value is the result of whole block evaluation (somewhat like in Ruby).
Having that we can do things like:
2 + { 3 } // res: Int = 5
val x = { 4 } // res: x: Int = 4
List({1},{2},{3}) // res: List[Int] = List(1,2,3)
Last example is just a function call with three parameters, of which each is evaluated first.
Now to see how it works with function calls let's define simple function that take another function as a parameter.
def foo(f: Int => Unit) = { println("Entering foo"); f(4) }
To call it, we need to pass function that takes one param of type Int, so we can use function literal and pass it to foo:
foo( x => println(x) )
Now as said before we can use block of code in place of an expression so let's use it
foo({ x => println(x) })
What happens here is that code inside {} is evaluated, and the function value is returned as a value of the block evaluation, this value is then passed to foo. This is semantically the same as previous call.
But we can add something more:
foo({ println("Hey"); x => println(x) })
Now our code block contains two statements, and because it is evaluated before foo is executed, what happens is that first "Hey" is printed, then our function is passed to foo, "Entering foo" is printed and lastly "4" is printed.
This looks a bit ugly though and Scala lets us to skip the parenthesis in this case, so we can write:
foo { println("Hey"); x => println(x) }
or
foo { x => println(x) }
That looks much nicer and is equivalent to the former ones. Here still block of code is evaluated first and the result of evaluation (which is x => println(x)) is passed as an argument to foo.
Because you are using case, you are defining a partial function and partial functions require curly braces.
Increased compile checking with parens
The authors of Spray, recommend that round parens give increased compile checking. This is especially important for DSLs like Spray. By using parens you are telling the compiler that it should only be given a single line, therefore if you accidentally gave it two or more, it will complain. Now this isn't the case with curly braces, if for example, you forget an operator somewhere your code will compile, you get unexpected results and potentially a very hard bug to find. Below is contrived (since the expressions are pure and will at least give a warning), but makes the point
method {
1 +
2
3
}
method(
1 +
2
3
)
The first compiles, the second gives error: ')' expected but integer literal found. the author wanted to write 1 + 2 + 3.
One could argue it's similar for multi-parameter methods with default arguments; it's impossible to accidentally forget a comma to separate parameters when using parens.
Verbosity
An important often overlooked note about verbosity. Using curly braces inevitably leads to verbose code since the scala style guide clearly states that closing curly braces must be on their own line: http://docs.scala-lang.org/style/declarations.html "... the closing brace is on its own line immediately following the last line of the function." Many auto-reformatters, like in Intellij, will automatically perform this reformatting for you. So try to stick to using round parens when you can. E.g. List(1, 2, 3).reduceLeft{_ + _} becomes:
List(1, 2, 3).reduceLeft {
_ + _
}
Parenthesis in an ideal coding style is basically used for single line code.
But if the particular piece of code is multiline then using braces is a better way.
With braces, you got semicolon induced for you and parentheses not. Consider takeWhile function, since it expects partial function, only {case xxx => ??? } is valid definition instead of parentheses around case expression.