Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

def or val for defining Function in Scala

I'm learning Programming Paradigms in my University and reading this course material provided by the lecturer that defined a function this way:

val double = (x: Int) => 2 * x
double: Int => Int = <function1>

But from my own studies I found and got used to defining the same function like this:

def d (x: Int) = 2 * x
d: (x: Int)Int

I'm new to Scala. And both definitions give a result of:

res21: Int = 8

Upon passing 4 as the parameter. Now my main question is why would the lecturer prefer to use val to define a function? I see it as longer and not really necessary unless using val gives some added advantages that I don't know of. Besides I understand using val makes some name a placeholder so later in the program, I could mistakenly write val double = 5 and the function would be gone! At this stage I'm quite convinced I learned a better way of defining a function unless someone would tell me otherwise.

like image 464
emi Avatar asked Oct 26 '13 13:10

emi


People also ask

What is the difference between DEF and Val in Scala?

val evaluates when defined. def evaluates on every call, so performance could be worse than val for multiple calls. You'll get the same performance with a single call.

How do you define a function in Scala?

In scala, functions are first class values. You can store function value, pass function as an argument and return function as a value from other function. You can create function by using def keyword. You must mention return type of parameters while defining function and return type of a function is optional.

Why is Val preferred in Scala?

In Scala the general rule is that you should always use a val field unless there's a good reason not to. This simple rule (a) makes your code more like algebra and (b) helps get you started down the path to functional programming, where all fields are immutable.

What does Val mean in Scala?

On the other hand, the val keyword represents a value. It's an immutable reference, meaning that its value never changes. Once assigned it will always keep the same value. Scala's val is similar to a final variable in Java or constants in other languages.


2 Answers

Strictly speaking def d (x: Int) = 2 * x is a method, not a Function, however scala can transparently convert (lift) methods into Functions for us. So that means you can use the d method anywhere that requires a Int => Int Function.

There is a small overhead of performing this conversion, as a new Function instance is created every time. We can see this happening here:

val double = (x: Int) => 2 * x
def d (x: Int) = 2 * x

def printFunc(f: Int => Int) = println(f.hashCode())

printFunc(double)
printFunc(double)
printFunc(d)
printFunc(d)

Which results in output like so:

1477986427
1477986427
574533740
1102091268

You can see when explicitly defining a Function using a val, our program only creates a single Function and reuses it when we pass as an argument to printFunc (we see the same hash code). When we use a def, the conversion to a Function happens every time we pass it to printFunc and we create several instances of the Function with different hash codes. Try it

That said, the performance overhead is small and often doesn't make any real difference to our program, so defs are often used to define Functions as many people find them more concise and easier to read.

like image 154
theon Avatar answered Sep 29 '22 14:09

theon


In Scala, function values are monomorphic (i.e. they can not have type parameters, aka "generics"). If you want a polymorphic function, you have to work around this, for example by defining it using a method:

def headOption[A]: List[A] => Option[A] = {
  case Nil   => None
  case x::xs => Some(x)
}

It would not be valid syntax to write val headOption[A]. Note that this didn't make a polymorphic function value, it is just a polymorphic method, returning a monomorphic function value of the appropriate type.

like image 37
Ben James Avatar answered Sep 29 '22 15:09

Ben James