This question already has answers here:
Why use curly braces over parentheses?
(3 answers)
Closed 4 years ago.
In Scala, we can have:
println { "Hello, world!" }
And from the book 'Programming in Scala':
The purpose of this ability to substitute curly braces for parentheses for
passing in one argument is to enable client programmers to write function
literals between curly braces. This can make a method call feel more like a
control abstraction.
What does this statement mean?
This is syntactic sugar just for look and feel. When a function takes a function as argument like in
def doWith[A, B](todo: A => B): B = ???
You would normally have to call it like
doWith( input => ... )
// or even
doWith({ input => ... })
In scala it is allowed to replace parenthesis with with curlies, so
doWith { input =>
...
}
Has the look and feel of a control structure like
if (...) {
...
}
Imho, that makes calling higher order functions like 'map' or 'collect' much more readable:
someCollection.map { elem =>
...
...
}
which is essentially the same as
someCollection.map({ elem =>
...
...
})
with less chars.
"Control abstractions" are e.g. if, while, etc. So you can write a function
def myIf[A](cond: Boolean)(ifTrue: => A)(ifFalse: => A): A =
if (cond) ifTrue else ifFalse
(if you aren't familiar with : => Type syntax, search for "by-name parameters") you can call it as
val absX = myIf(x < 0) { -x } { x }
and it looks very similar to normal if calls. Of course, this is much more useful when the function you write is more different from the existing control structures.
In addition to (regular) functions and by-name arguments, braces also help with partial functions:
processList(l) {
case Nil => ...
case h :: t => ...
}
and sequences of expressions:
doSomething {
thing1;
thing2
}
Note that (thing1; thing2) is not a valid expression in Scala like it would be in, say, ML.
Actually what I have noticed the difference between the curly braces{} and parenthesis() is that you can write multiple lines in the curly braces. While in parenthesis() you can’t write more then one line for example.
val x :[List[Int]]=List(1,2,3,4,5,6,7,8)
x.map(y=> y*5) //it will work fine
x.map(y=>
case temp:Int=>println(temp)
case _ => println(“NOT Int”)) //it will not work
x.map{y=>
case temp:Int=>println(temp)
case _ => println(“NOT Int”)} //it willwork
So we can say it’s just the synthetic sugar to allow developer to write more then none line without ; that’s it it may have some other reason too.
Related
I have a Future of Tuple like this Future[(WriteResult, MyObject)] mytuplefuture, I'd like to map it and do something with MyObject so I am doing this:
mytuplefuture.map((wr,obj)=>{ //do sth});
but my eclipse scala IDE does not allow and recommend me to do:
mytuplefuture.map{ case(wr,obj) => { //do sth }}
what is the difference between those two?
I am used to doing the first one, I do not know about the second one until I try returning that tuple that wrapped in a future
myfuture.map((obj) => { // do sth with obj })
it was clear, I am mapping the content of the Future and do something with it, which will return another future because the original myfuture only contains something (obj) in the future..
Would anyone explain please?
The difference is this:
map is a higher-order function (HOF) that takes a function as its argument. This function - let's call it the mapping function for convenience - itself takes a single argument, which is the value of the completed Future. In this particular case, this value happens to be a tuple. Your first attempt assumed that the tuple could be broken open into two arguments, which would then be accepted by the mapping function - but that's not going to happen, hence the error.
It might seem that you could define the mapping function like this (note the extra parentheses around the arguments):
mytuplefuture.map(((wr,obj)) => /* do sth */)
however this is not currently supported by the Scala compiler. (That said, I think this might be a feature of a future Scala release.)
So, the alternative is to write the mapping function as a partial function using the case statement. The following:
mytuplefuture.map {
case (wr,obj) => //
}
is actually a kind of shorthand for:
mytuplefuture.map {
tuple: (WriteResult, MyObject) => tuple match {
case (wr,obj) => // do sth
}
}
In fact, this shorthand is generally useful for situations other than just breaking open tuples. For instance:
myList.filter {
case A => true
case _ => false
}
is short for:
myList.filter {
x => x match {
case A => true
case _ => false
}
}
So, let's say you wish to look at just the MyObject member of the tuple. You would define this as follows:
val myfuture = mytuplefuture.map {
case (_, obj) => obj
}
or, alternatively, being explicit with the tuple argument:
val myfuture = mytuplefuture.map(tuple => tuple._2)
which can in turn be simplified to just:
val myfuture = mytuplefuture.map(_._2)
where the first underscore is shorthand for the first argument to the mapping function. (The second underscore, as in _2, is part of the name for the second value in the tuple, and is not shorthand - this is where Scala can get a little confusing.)
All of the previous three examples return a Future[MyObject].
If you then apply map to this value, the single mapping function argument in this case will be your MyObject instance. Hence you can now write:
myfuture.map(obj => /* Do something with obj */)
As to the remainder of your question, the mapping function as applied to a Future's value does indeed apply to the result of the original future, since it can't be executed until the first future has completed. Therefore, map returns a future that completes (successfully or otherwise) when the first future completes.
UPDATED: Clarified what the argument to map actually is. Thanks to #AlexeyRomanov for putting me right, and to #RhysBradbury for pointing out my initial error. ;-)
The difference is, that case indicates decomposition (or extraction) of the object (invoking unapply, which you can implement yourself).
myfuture.map(obj => obj._2 ) in this case obj - is your tuple, so you can access its elements by ._1 and ._2
mytuplefuture.map{ case(wr,obj) => { //do sth }} this decompose tuple to its elements.
You can better feel the difference, by using this approach on case class which comes with a default unapply implementation
case class MyClass(int: Int)
List(MyClass(1)) map { myclass => myclass.int } // accesing the elements
List(MyClass(1)) map { case MyClass(i) => i + 1 } // decomposition
In your case I'd write
mytuplefuture.map(_.2).map( // do somthing )
P.S.
You can do the extraction for many other classes (Option for example).
It is also allowing you to write something like
val (a, b) = tuple
val MyClass(x) = myclass
Having the code below:
val prices = cars map (car => {
val price = car.getPrice
Logger.info(s"Car price is $price")
price
})
Is using parentheses fine in the above case or there is a strict imperial to use curly braces like below:
val prices = cars map { car => {
val price = car.getPrice
Logger.info(s"Car price is $price")
price
}}
I do not like two curly braces and prefer ({ ... }) style, but was warned by another developer that the inside function is side-effecting (logging message) and is 3 lines of code so it must be used with two curly braces and that the whole Scala community uses double curly braces in these cases.
I googled scala code and found this one:
def failed: Future[Throwable] =
transform({
case Failure(t) => Success(t)
case Success(v) => Failure(new NoSuchElementException("Future.failed not completed with a throwable."))
})(internalExecutor)
It has multiple lines but no side effects and my nice notation ({...}) is used here. Should it be changed when the code contains side-effects? Personally I do not like that even if the whole community says "Yes, use double curly braces!" :)
In your particular case I would actually only use curly braces and no parens:
val prices = cars map { car =>
val price = car.getPrice
Logger.info(s"Car price is $price")
price
}
The example you posted from the scala code is only using parentheses out of necessity, since transform is actually a function with multiple argument lists (i.e. transform(args1)(arg2)).
I have not heard of any convention relating side-effecting code to a particular choice of block delimiter (() vs {}), but I do find I prefer the look of {} when there are multiple lines in that block.
I have never heard about that you should curly braces when there is a side effect in a block of code. Use () for a single statement, and {} for multiple statements. What you call nice notation ({...}) is perfectly fine.
A few times I saw a Scala code like that:
object Doer{
def doStuff(op: => Unit) {
op
}
}
Invoked in this way:
Doer.doStuff{
println("Done")
}
What is strange for me is how a function is passed to another function as just a block of code between curly braces. And there is even no parentheses that normally mark the beginning and end of argument list.
What is the name of this Scala syntax/feature? In what cases I can use it? Where is it documented?
This is called either a nullary function or a thunk, and is an example of call-by-name evaluation: http://www.scala-lang.org/old/node/138
You can use nullaries pretty much anywhere you have a parameter list. They are basically just syntactic sugar around zero-argument functions that make them look like ordinary values, and are invoked whenever they are referenced.
So
def doSomething(op: => Unit) {
op
}
doSomething {
println("Hello!")
}
is exactly the same as:
def doSomething(op: () => Unit) {
op()
}
doSomething(() => println("Hello!"))
The one thing to keep in mind with nullaries is they are invoked every time they are referenced, so something like:
def foo(op: => Int) = op + op
foo {
println("foo")
5
}
will print "foo" twice.
Edit: To expand on Randall's comment, one of the big ways that a nullary function differs from a zero-arg function is that nullaries are not first-class values. For example, you can have a List[() => Int] but you cannot have a List[=> Int]. And if you had something like:
def foo(i: => Int) = List(i)
you are not adding the nullary function to the list, only its return value.
I am a scala newbie.
What is the difference between
invokeFunc(() => { "this is a string" } )
and
invokeFunc({ () => "this is a string" })
If you have a good resource for small scala nuances I would appreciate it.
TL;DR: those two code snippets are equivalent.
In () => { "this is a string" } the curly brackets introduce a block of code. As this block of code contains only one expression, it is essentially useless and you could just have written () => "this is a string".
Also, scala will almost always let you choose whether you use parentheses or curly brackets when calling a method. So println("hello") is the same as println{"hello"}. The reason scala allows curly bracket is so that you can define methods that you can use like it was a built-in part of the language. By example you can define:
def fromOneToTen( f: Int => Unit ) {
for ( i <- 1 to 10 ) f(i)
}
and then do:
fromOneToTen{ i => println(i) }
The curly braces here make it look more like a control structure such as scala's built-in while.
So invokeFunc(() => { "this is a string" } ) is the same as invokeFunc{() => { "this is a string" } }
As a last point, parentheses can always be used anywhere around a single expression, so (5) is the same as 5.
And curly braces can always be used to define a block containing a series of expressions, the block returning the last expression. A special case of this is a block of a single expression, in which case curly braces play the same role as parentheses.
All this means that you can always add superfluous parentheses or curly brackets around an expression. So the following are all equivalent: 123, {123}, (123), ({123})and so on.
Which also means that:
invokeFunc(() => "this is a string")
is the same as
invokeFunc({ () => "this is a string" })
which is the same as
invokeFunc({( () => "this is a string" )})
and so on.
To my understanding, the first has an anonymous function, while the second has a block. However, the last element of a block returns in Scala, and so the block returns the same anonymous function, which then becomes the parameter of the method.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Scala: short form of pattern matching that returns Boolean
In my scala code I'm finding myself often writing things like the following:
x match{
case Type(params) => doStuffWith(params)
case _ => /* do nothing*/
}
Is there already some predefined operator to do this? I think it would be much clearer if I could write things like:
if( x match Type(params)) {
doStuffWith(params)
}
essentially avoiding the weird otherwise case. I've also had other situations where being able to verify if something matches a pattern in an inline fashion would save me an extra pair of braces.
I know this sort of thing might only be more useful when writing more iterative code, but Scala seems to have so many hidden features I was wondering whether someone has a simple solution for this.
You could lifta partial function from Any to A into a function from Any to Option[A].
To make the syntax nice first define an helper function:
def lifted[A]( pf: PartialFunction[Any,A] ) = pf.lift
Then, make profit:
val f = lifted {
case Type(i) => doStuff(i)
}
scala> f(2)
res15: Option[Int] = None
scala> f(Type(4))
res16: Option[Int] = Some(8)
The doStuff method will be called only if the argument matches. And you can have several case clauses.
The shortest way I can think of is to wrap the value in an option and use the collect method:
Option(x).collect { case Type(params) => doStuffWith(params) }
Using the link that #phant0m gave, to spell it out:
import PartialFunction.condOpt
condOpt(x){ case Type(params) => doStuffWith(params) }
If this pattern appears often in your code, you should consider turning doSomeStuff into a method of Type. Case classes in Scala are normal classes, and you should use the object-oriented features when they make sense.
Otherwise, you could add a method at the top of your hierarchy, assuming all your case classes extend a common trait. For example:
class Base {
def whenType(f: (T1, T2) => Unit): Unit = this match {
case Type(t1, t2) => f(t1, t2)
case _ => ()
}
}
and then you can use x whenType doSomeStuff