I am struggling to understand the basics of Scala, in particular this code:
trait RichIterator extends AbsIterator {
def foreach(f: T => Unit): Unit = while (hasNext) f(next())
}
to me, foreach looks like a method that returns unit. It takes a function, f as parameter:
f: T => Unit
which also returns unit. The method loops while hasNext is true and I have no idea what f(next()) does. Is this f the input parameter, and why use a function which seems to just return a Unit? Can someone please help explain this to me.
The foreach function is typically used to achieve side-effects. What I mean is that when I call List(1, 2, 3).foreach(println) I want to print (which is a side-effect) all elements from the list.
I have no idea what f(next()) does.
The f(next()) means call the function f - which is the argument of the foreach function - with the next element - which is retrieved by calling next().
Why use a function that just returns Unit?
Generally in Scala you will notice that methods which have side-effects return Unit. I actually extracted a piece of scaladoc here which is from the original definition of foreach found in TraversableLike.
/**
* #param f the function that is applied for its side-effect to every element. The result of function `f` is discarded.
* #tparam U the type parameter describing the result of function `f`. This result will always be ignored. Typically `U` is `Unit`, but this is not necessary.
*/
def foreach[U](f: A => U): Unit
Considering that the result of foreach will always be ignored, one could directly set it to Unit instead of enforcing another type parameter as the author of your example already did.
I hope this helps you :)
In this example, as you correctly noticed, the foreach-function loops over all the elements (with the while and hasNext).
f is the function you got as parameter.
You call this function with all the elements element (which you get by calling next() in the loop ).
So the function f is executed for every element.
Example:
You pass the function println.
Now you loop over every element of the Iterator. with next(), you get the next element. This is passed to your println-function (that you provided as parameter). Therefore, each element is printed.
Foreach is a loop that does some actions on each element wrapped in object. In this example this extends AbsIterator, so next() is next element of iterable sequence. You are using foreach by passing there argument function which will do some actions on each element, but won't change it unlike map, and unlike map it won't return new collection, that is why it's UNIT. Easy example would be if RichIterator would iterate on Strings.
Then you can have Iterable like this:
("1","2","3")
You could use foreach on this by passing f = (str => println(str))
Then it would go with
hasNext -> true
println("1")
hasNext -> true
println("2")
hasNext -> true
println("3")
hasNext -> false
And output would be simple
1
2
3
Related
I am bit new to scala curying and the call by name functions. I am facing difficulty in understanding the Syntax. What is the fllow of the function why there is need of returning the f(result) and what function is applied on it further.
def withScan[R](table: Table, scan: Scan)(f: (Seq[Result]) => R): R = {
var resultScanner: ResultScanner = null
try {
resultScanner = table.getScanner(scan)
val it: util.Iterator[Result] = resultScanner.iterator()
val results: mutable.ArrayBuffer[Result] = ArrayBuffer()
while (it.hasNext) {
results += it.next()
}
f(results)
} finally {
if (resultScanner != null)
resultScanner.close()
}
}
Let's look at just the function signature
def withScan[R](table: Table, scan: Scan)(f: (Seq[Result]) => R): R
Firstly, ignore the fancy currying syntax for now as you can always rewrite a curried function into a normal function by putting all the parameters in one parameter list i.e.
def withScan[R](table: Table, scan: Scan, f: Seq[Result] => R): R
Secondly, notice the last parameter is a function on its own and we don't know what it does yet. withScan will take a function somebody gives it and use that function on something. We might be interested in why someone needs such a function. Since we need to deal with a lot of resources that need to be opened and closed properly such as File, DatabaseConnection, Socket,... we will then repeat ourselves with the code that closes the resources or even worse, forget to close the resources. Hence we want to factor the boring common code out to give you a convenient function: if you use withScan to access the table, we will somehow give you the Result so that you can work on that and also we will make sure to close the resources properly for you so that you can just focus on the interesting operation. This is call the "loan pattern"
Now let's go back to the currying syntax. Although currying has other interesting use cases, I believe the reason it is written in this style is in Scala, you can use curly braces block to pass the parameter to the function i.e. one can use the function above like this
withScan(myTable, myScan) { results =>
//do whatever you want with the results
}
This looks just like a built in control flow like if-else or for loop!
As I understand that properly this is function which take some Table (probably db table) and try to scna this tabel using argument scan. After you collect data using relevant scanner this method just map collected sequence to object of type R.
For such mapping it is used f function.
You can use this function:
val list: List[Result] = withScan(table, scanner)(results => results.toList)
Or
val list: List[Result] = withScan(table, scanner)(results => ObjectWhichKeepAllData(results))
IMHO, it is not very well written code, and also I feel that the better would be to do mapping thing outside of this function. Let client do the mapping (which BTW should be for every single result) and leave scanning only for that function.
This is an example of a higher-order function: a function which takes another function as a parameter.
The function appears to do the following:
- opens the passed in table with the passed in scanner
- parses the table with an iterator, populating entries in a local ArrayBuffer
- calls a function, passed in by the caller, on the sequence of entries that have been parsed.
The function parameter allows this function to be used to carry out any operation on the scanned information, depending on the function passed in.
The function prototype could equally have been declared:
def withScan[R](table: Table, scan: Scan, f: (Seq[Result]) => R): R = {
The function has been declared with two argument lists; this is an example of currying. This is a benefit when calling the function, as it allows the method to be called with a clearer syntax.
Consider a function that might be passed into this function:
def getHighestValueEntry(results: Seq[Result]): R = {
Without currying, the function would be called like this:
withScan[R](table, scan, results => getHighestValueEntry(results))
With currying the function can be called in a manner that makes the function parameter stand out more clearly. This is helped by the ability in Scala to use curly braces instead of parentheses to surround the arguments to a function, if you are only passing in one argument:
withScan(table, scan) { results =>
getHighestValueEntry(results) }
Array("hi","there").map(println)
Array("hi","there").map(s => println(s))
Array("hi","there").map(println(_))
Each of the above statements yields the same output though in the first 2 argument to map is a function object whereas in the last one it is function invocations.
How is map able to handle both?
Signature of map in TraversableLike class is like this:
def map[B, That](f: scala.Function1[A, B])(implicit bf: scala.collection.generic.CanBuildFrom[Repr, B, That]) : That = { /* compiled code */ }
How is map able to handle both?
It is able to handle both because the compiler created a method value for map by performing eta-expansion on the println. There is a distinction in Scala between methods and functions, where the former doesn't hold any value, which makes the compiler need to go the extra mile to make it work.
The compiler after eta-expansion actually emits:
Array("hi","there").map(s => println(s))
Matching your second example. The actual code is more verbose, but means the same:
scala.this.Predef.refArrayOps[String](
scala.Array.apply[String]("hi", "there")(
(ClassTag.apply[String](classOf[java.lang.String]): scala.reflect.ClassTag[String])))
.map[Unit, Any]({((x: Any) => scala.this.Predef.println(x))
})(scala.this.Array.canBuildFrom[Unit]((ClassTag.Unit: scala.reflect.ClassTag[Unit])));
As #slouc said in the comments, the third example using the placeholder syntax is desugered into s => println(s), which makes it an equivalent to your second example.
As a complete not so important side note, since println returns Unit, Array.foreach would be more suitable here:
Array("hi","there").foreach(println)
Im a Scala newbie and I get that its a really rich language. One thing that is getting me caught out syntax-wise is on function creation. I understand that braces {} are interpreted by the compiler as being synonymous with parentheses () in many contexts, but the following I still do not quite understand.
The following is the output from Scala REPL:
scala> def index = List {}
index: List[Unit]
scala> def index = List ()
index: List[Nothing]
Q1.
If I understand the above correctly, I am creating a function called index that creates a new List (new is omitted because of implicit call to apply method right?).
I see that Unit (equivalent to null in Java?) is the Type of my List when braces {} are used. But Nothing is the type when using parens ().
Q2.
Can someone explain, in simple terms (if possible), the difference between the use of {} and () in creating functions and also what Nothing represents?
Edit - So the following are equivalent?
def index = List {val a = 1; a}
def index = List ({val a = 1; a})
Im also struggling a bit with where the terms function and method seem to be used interchangeably.
Is it correct to say that both the above can both be considered either a function or method?
Or does it depend on who you talk to?
If I understand the above correctly, I am creating a function called index that creates a new List (new is omitted because of implicit call to apply method right?).
(new is omitted because of implicit call to apply method right?)
Yes, kind of. List.apply constructs the List and returns it to your method.
def index = List {} creates a method called index that creates a new List by calling List.apply.
Can someone explain, in simple terms (if possible), the difference between the use of {} and () in creating functions and also what Nothing represents?
The empty curly braces {} represent an anonymous function, rather than a simple list of elements. For example I can do:
scala> def index = List {val a = 1; a}
index: List[Int]
Your method is equivalent to (where the parentheses are omitted):
def index = List({})
The result of the anonymous function is passed to apply. When the braces are empty, the return type of the anonymous function is Unit. So we get List[Unit].
def index = List () always returns an empty List. However, because you have no annotations, the compiler cannot infer a type from this, so it is inferred as Nothing, which is a sub-type of every other type. This allows us to combine a List[Nothing] with a List[Int] and still compile.
I see that Unit (equivalent to null in Java?) ...
Unit is the return type of a method that doesn't return anything. Similar to void in Java, not null.
I am new to Scala, and am learning it by going over some Play code. I have had a good read of the major concepts of Scala and am comfortable with functional programming having done some Haskell and ML.
I am really struggling to read this code, at the level of the syntax and the programming paradigms alone. I understand what the code is supposed to do, but not how it does it because I can't figure out the syntax.
// -- Home page
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref) { implicit request =>
for {
someDocuments <- ctx.api.forms("everything").ref(ctx.ref).submit()
} yield {
Ok(views.html.index(someDocuments))
}
}
(Prismic is an API separate to Play and is not really that relevant). How would I describe this function (or is it a method??) to another developer over the phone: in other words, using English. For example in this code:
def add(a: Int, b: Int): Int = a + b
I would say "add is a function which takes two integers, adds them together and returns the result as another integer".
In the Play code above I don't even know how to describe it after getting to "index is a function which takes an Option of a String and returns an Action of type AnyContent by ....."
The bit after the '=' and then the curly braces and the '=>' scare me! How do I read them? And is the functional or OO?
Thanks for your assistance
Let's reduce it to this:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)(function)
That's better, isn't it? index is a function from Option of String to Action of AnyContent (one word), which calls the action method of the object Prismic passing two curried parameters: ref, the parameter that index received, and a function (to be described).
So let's break down the anonymous function:
{ implicit request =>
for {
someDocuments <- ctx.api.forms("everything").ref(ctx.ref).submit()
} yield {
Ok(views.html.index(someDocuments))
}
}
First, it uses {} instead of () because Scala allows one to drop () as parameter delimiter if it's a single parameter (there are two parameter lists, but each has a single parameter), and that parameter is enclosed in {}.
So, what about {}? Well, it's an expression that contains declarations and statements, with semi-colon inference on new lines, whose value is that of the last statement. That is, the value of these two expressions is the same, 3:
{ 1; 2; 3 }
{
1
2
3
}
It's a syntactic convention to use {} when passing a function that extends for more than one line, even if, as in this case, that function could have been passed with just parenthesis.
The next thing confusing is the implicit request =>, Let's pick something simpler:
x => x * 2
That's pretty easy, right? It takes one parameter, x, and returns x * 2. In our case, it is the same thing: the function takes one parameter, request, and returns this:
for (someDocuments <- somethingSomething())
yield Ok(views.html.index(someDocuments))
That is, it calls some methods, iterate over the result, and map those results into a new value. This is a close equivalent to Haskell's do notation. You can rewrite it like below (I'm breaking it down into multiple lines for readability):
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
So, back to our method definition, we have this:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)(
implicit request =>
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
)
The only remaining question here is what that implicit is about. Basically, it makes that parameter implicitly available through the scope of the function. Presumably, at least one of these method calls require an implicit parameter which is properly fielded by request. I could drop the implicit there an pass request explicitly, if I knew which of these methods require it, but since I don't, I'm skipping that.
An alternate way of writing it would be:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)({
request =>
implicit val req = request
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
})
Here I added {} back because I added a declaration to the body of the function, though I decided not to drop the parenthesis, which I could have.
Something like this:
index is a function which takes an Option of a String and returns an Action of type AnyContent. It calls the method action that takes as a first argument an Option and as a second argument a method that assumes an implicit value request of type Request is in scope. This method uses a For-comprehension that calls the submit method which returns an Option or a Future and then in case its execution is successful, it yields the result Ok(...) that will be wrapped in the Action returned by the action method of Prismic.
Prismic.action is a method that takes 2 groups of arguments (a.k.a. currying).
The first is ref
The second is { implicit request => ...}, a function defined in a block of a code
more information on Action
Will the foreach method of a Scala immutable Queue always be processed in the order one expects for a queue or is there a method that guarantees the order? Or do I have to use a loop + dequeue?
scala.collection.immutable.Queue is scala.collection.Seq. See Seq documentation:
Sequences are special cases of iterable collections of class Iterable. Unlike iterables, sequences always have a defined order of elements.
So yes, you'll get the same elements order with foreach and with loop + dequeue.
If you don't trust documentation you could take a look at implementation:
Queue#foreach is inherited from IterableLike and implemented like this:
def foreach[U](f: A => U): Unit = iterator.foreach(f)
Queue#iterator is implemented like this:
override def iterator: Iterator[A] = (out ::: in.reverse).iterator
And Queue#dequeue returns the first element of out, if any, or the last element of in. So you'll get the same elements order.