Scala by name versus function parameters [duplicate] - scala

What is still unclear for is what's the advantage by-name parameters over anonymous functions in terms of lazy evaluation and other benefits if any:
def func1(a: => Int)
def func2(a: () => Int)
When should I use the first and when the second one?
This is not the copy of What's the difference between => , ()=>, and Unit=>

Laziness is the same in the both cases, but there are slight differences. Consider:
def generateInt(): Int = { ... }
def byFunc(a: () => Int) { ... }
def byName(a: => Int) { ... }
// you can pass method without
// generating additional anonymous function
byFunc(generateInt)
// but both of the below are the same
// i.e. additional anonymous function is generated
byName(generateInt)
byName(() => generateInt())
Functions with call-by-name however is useful for making DSLs. For instance:
def measured(block: ⇒ Unit): Long = {
val startTime = System.currentTimeMillis()
block
System.currentTimeMillis() - startTime
}
Long timeTaken = measured {
// any code here you like to measure
// written just as there were no "measured" around
}

def func1(a: => Int) {
val b = a // b is of type Int, and it`s value is the result of evaluation of a
}
def func2(a: () => Int) {
val b = a // b is of type Function0 (is a reference to function a)
}

An example might give a pretty thorough tour of the differences.
Consider that you wanted to write your own version of the veritable while loop in Scala. I know, I know... using while in Scala? But this isn't about functional programming, this is an example that demonstrates the topic well. So hang with me. We'll call our own version whyle. Furthermore, we want to implement it without using Scala's builtin while. To pull that off we can make our whyle construct recursive. Also, we'll add the #tailrec annotation to make sure that our implementation can be used as a real-world substitute for the built-in while. Here's a first go at it:
#scala.annotation.tailrec
def whyle(predicate: () => Boolean)(block: () => Unit): Unit = {
if (predicate()) {
block()
whyle(predicate)(block)
}
}
Let's see how this works. We can pass in parameterized code blocks to whyle. The first is the predicate parameterized function. The second is the block parameterized function. How would we use this?
What we want is for our end user to use the whyle just like you would the while control structure:
// Using the vanilla 'while'
var i = 0
while(i < args.length) {
println(args(i))
i += 1
}
But since our code blocks are parameterized, the end-user of our whyle loop must add some ugly syntactic sugar to get it to work:
// Ouch, our whyle is hideous
var i = 0
whyle( () => i < args.length) { () =>
println(args(i))
i += 1
}
So. It appears that if we want the end-user to be able to call our whyle loop in a more familiar, native looking style, we'll need to use parameterless functions. But then we have a really big problem. As soon as you use parameterless functions, you can no longer have your cake and eat it too. You can only eat your cake. Behold:
#scala.annotation.tailrec
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
if (predicate) {
block
whyle(predicate)(block) // !!! THIS DOESN'T WORK LIKE YOU THINK !!!
}
}
Wow. Now the user can call our whyle loop the way they expect... but our implementation doesn't make any sense. You have no way of both calling a parameterless function and passing the function itself around as a value. You can only call it. That's what I mean by only eating your cake. You can't have it, too. And therefore our recursive implementation now goes out the window. It only works with the parameterized functions which is unfortunately pretty ugly.
We might be tempted at this point to cheat. We could rewrite our whyle loop to use Scala's built-in while:
def whyle(pred: => Boolean)(block: => Unit): Unit = while(pred)(block)
Now we can use our whyle exactly like while, because we only needed to be able to eat our cake... we didn't need to have it, too.
var i = 0
whyle(i < args.length) {
println(args(i))
i += 1
}
But we cheated! Actually, here's a way to have our very own tail-optimized version of the while loop:
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
#tailrec
def whyle_internal(predicate2: () => Boolean)(block2: () => Unit): Unit = {
if (predicate2()) {
block2()
whyle_internal(predicate2)(block2)
}
}
whyle_internal(predicate _)(block _)
}
Can you figure out what we just did?? We have our original (but ugly) parameterized functions in the inner function here. We have it wrapped with a function that takes as arguments parameterless functions. It then calls the inner function and converts the parameterless functions into parameterized functions (by turning them into partially applied functions).
Let's try it out and see if it works:
var i = 0
whyle(i < args.length) {
println(args(i))
i += 1
}
And it does!
Thankfully, since in Scala we have closures we can clean this up big time:
def whyle(predicate: => Boolean)(block: => Unit): Unit = {
#tailrec
def whyle_internal: Unit = {
if (predicate) {
block
whyle_internal
}
}
whyle_internal
}
Cool. Anyways, those are some really big differences between parameterless and parameterized functions. I hope this gives you some ideas!

The two formats are used interchangeably, but there are some cases where we can use only one of theme.
let's explain by example, suppose that we need to define a case class with two parameters :
{
.
.
.
type Action = () => Unit;
case class WorkItem(time : Int, action : Action);
.
.
.
}
as we can see, the second parametre of the WorkItem class has a type Action.
if we try to replace this parameter with the other format =>,
case class WorkItem1(time : Int, s : => Unit) the compiler will show a message error :
Multiple markers at this line:
`val' parameters may not be call-by-name Call-by-name parameter
creation: () ⇒
so as we have see the format ()=> is more generic and we can use it to define Type, as class field or method parameter, in the other side => format can used as method parameter but not as class field.
A by-name type, in which the empty parameter list, (), is left out, is only
allowed for parameters. There is no such thing as a by-name variable or a
by-name field.

You should use the first function definition if you want to pass as the argument an Int by name.
Use the second definition if you want the argument to be a parameterless function returning an Int.

Related

Strange definition and call of a function with curly bracket in Scala (function as parameter of a function)

I'm totally new with Scala, I have to maintain an old code, so I have to understand what it does.
Now I am stuck on this piece of code, it is about defining and calling a method.
This is the definition of the method:
private def myMethod[I, O](price: Long, id: Int)(i: I)(f: (I, String) => O): O = {
..some code..
}
this is the method call
myMethod(price, id)(b) {
..some code.. //single line of code, just calling an other function
}
I understood the part of having type parameter also of having multiple parameter (currying).
But what I didn't understand, is :
first of all this part: (f: (I, String) => O) , this is completely strange for me
second, why in the method call, it contains code after the { symbol, is it overriding the original method? even it's the case, it make no sense to override it when making the call
also, myMethod is supposed to return a value of type O , but in my code it's never affected to any variable. (EDIT: this point is clear now, I just misunderstood the code, nvm mind about it)
Please can any one clarify this points (especially the first and second one which are making me so confused)
EDIT
private var x : classX
myMethod(price, id)(b) {
x.listX //calling method without parameters
}
def listX (param1: ListFaFBI, param2: String): ListX ={
//returning an Object of type ListX, not a function
}
as you can see that myMethod is calling listX. if I understood well, myMethod is returning the method listX itself which has two parameters ListFaFBI (or I) and String and returning ListX (or O) as defined in (f: (I, String) => O)
f is a function that takes in an I and a String and returns an O. f: (I, String) => O is syntactic sugar for f: Function2[I, String, O].
The braces act essentially the same as parentheses would, although there are some differences, as they can be treated as blocks (See this question). The code inside the braces is actually a function literal, and it will be passed as f. Also see this question. Here,
myMethod(price, id)(b) { (i, s) =>
..some code..
}
would be syntactic sugar for
myMethod(price, id)(b)({ (i, s) =>
..some code..
})
I'm not sure what you mean by "in my code it's never affected to any variable", but I assume that what is returned is either irrelevant or that there is an implied return (in case the call to myMethod is at the end of a block.
first of all this part: (f: (I, String) => O) , this is completely strange for me
It is a function, taking a tuple of two elements of type I and String, and returns an O
why in the method call, it contains code after the { symbol, is it overriding the original method?
Your method is using multiple parameter list, and the syntax of the last parameter group is a block definition that allows to define the function value ((I, String) => O)
For example, if we had a method which takes a function in the same parameter list:
def foo(s: String, f: String => String)
Our implementation would look like this:
foo("hello", {
s => s + "world"
}
)
However, if we used a separate parameter group:
def foo(s: String)(f: String => String)
Our implementation look like this:
foo("hello") {
s => s + "world"
}
Which is more eye pleasing and reads nicer.
myMethod is supposed to return a value of type O , but in my code it's never affected to any variable
If you add the implemention of the method we can better help show you where it is returning a value of type O

Is it possible in scala to have a generic method taking a method as an argument?

I would like to have:
def myMethod[T < ???](f: T): Unit = {
f()
}
The rest of the method is not really important but is it possible to replace ??? by somethind which would make sure T is a method
and if possible to go even further and make sure the return type of T is something defined ?
Like [T < (_*) => Int]
Thank you.
Would defining a type, like in the following trivial example, address your need?
type Fcn = String => Int
def myMethod(s: String, f: Fcn): Unit = {
println(f(s))
}
myMethod("hello", (s: String) => s.length)
// 5
You can use function literals:
def myMethod[A, T](f: A => T) {
f(someAValue)
}
or if you want functions that take no arguments:
def myMethod[T](f: () => T) {
f()
}
But judging by your comments, it seems like you specifically want to reference methods, and query the method for information about itself, which is not a feature of basic Scala. You may be able to do some of that with reflection, but reflection is an area best avoided.
Technically, you can't directly pass a method, since a method is not a value that you can instantiate and pass-around. What is usually passed around is a function instance. And when it appears that you're passing a method, the compiler is actually creating a function instance for you (method lifting or eta-expansion).
But that is not going to work if you're looking to inspect meta data about that method (name, deprecation). For that, you're probably looking for reflection. You can have your method take an instance of java.reflect.Method but that will require that you obtain that at call-site.

Passing function as block of code between curly braces

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.

Why do I need a curried function to be able to pass function literals with short placeholder syntax?

Given this definition:
class Foo(var x: String) {}
object Helper {
def model[T](get: ⇒ T, set: T ⇒ Unit) : Model[T] = new Model[T] {
override def getObject(): T = get
override def setObject(obj: T) { set(obj) }
}
}
I try to call model like this:
val f = new Foo("initial")
val stringModel = model(f.x, f.x = _)
But that doesn't work, the compiler gives me this, complaining about the underscore:
missing parameter type for expanded function ((x$1) => f.x = x$1)
If I change the definition of model to use two parameter lists like this:
def model[T](get: ⇒ T)(set: T ⇒ Unit) // rest is unchanged
Then I can call it like this:
model(f.x)(f.x = _)
Which I find nice and concise. I don't really mind doing it like this, though it makes method overloading harder. I would like to understand, however, why the second variant works and the first one doesn't?
The second variant works because Scala refines its types parameter-block by parameter-block. If you don't specify the type of your input parameter for the function, it's possible that it would change the type T that it has inferred based on the first parameter. If you push it to a separate parameter block, Scala's already decided what T must be by the time it hits that block, so it fills in the only possible value for the function argument type.

scala loan pattern, optional function param

I have a loan pattern that applies a function n times where 'i' is the incrementing variable. "Occasionally", I want the function passed in to have access to 'i'....but I don't want to require all functions passed in to require defining a param to accept 'i'. Example below...
def withLoaner = (n:Int) => (op:(Int) => String) => {
val result = for(i <- 1 to n) yield op(i)
result.mkString("\n")
}
def bob = (x:Int) => "bob" // don't need access to i. is there a way use () => "bob" instead?
def nums = (x:Int) => x.toString // needs access to i, define i as an input param
println(withLoaner(3)(bob))
println(withLoaner(3)(nums))
def withLoaner(n: Int) = new {
def apply(op: Int => String) : String = (1 to n).map(op).mkString("\n")
def apply(op: () => String) : String = apply{i: Int => op()}
}
(not sure how it is related to the loan pattern)
Edit Little explanation as requested in comment.
Not sure what you know and don't know of scala and what you don't undestand in that code. so sorry if what I just belabor the obvious.
First, a scala program consist of traits/classes (also singleton object) and methods. Everything that is done is done by methods (leaving constructor aside). Functions (as opposed to methods) are instances of (subtypes of) the various FunctionN traits (N the number of arguments). Each of them has as apply method that is the actual implemention.
If you write
val inc = {i: Int => i + 1}
it is desugared to
val inc = new Function1[Int, Int] {def apply(i: Int) = i + 1}
(defines an anonymous class extending Function1, with given apply method and creating an instance)
So writing a function has rather more weight than a simple method. Also you cannot have overloading (several methods with the same name, differing by the signature, just what I did above), nor use named arguments, or default value for arguments.
On the other hand, functions are first classes values (they can be passed as arguments, returned as result) while methods are not. They are automatically converted to functions when needed, however there may be some edges cases when doing that. If a method is intended solely to be used as a function value, rather than called as a method, it might be better to write a function.
A function f, with its apply method, is called with f(x) rather than f.apply(x) (which works too), because scala desugars function call notation on a value (value followed by parentheses and 0 or more args) to a call to method apply. f(x) is syntactic sugar for f.apply(x). This works whatever the type of f, it does not need to be one of the FunctionN.
What is done in withLoaner is returning an object (of an anonymous type, but one could have defined a class separately and returned an instance of it). The object has two apply methods, one accepting an Int => String, the other one an () => String. When you do withLoaner(n)(f) it means withLoaner(n).apply(f). The appropriate apply method is selected, if f has the proper type for one of them, otherwise, compile error.
Just in case you wonder withLoaner(n) does not mean withLoaner.apply(n) (or it would never stop, that could just as well mean withLoaner.apply.apply(n)), as withLoaner is a method, not a value.