4

Related to this thread

I am still unclear on the distinction between these 2 definitions:

val foo = (arg: Type) => {...}
def(arg:Type) = {...}

As I understand it:

1) the val version is bound once, at compile time
a single Function1 instance is created
can be passed as a method parameter

2) the def version is bound anew on each call
new method instance created per call.

If the above is true, then why would one ever choose the def version in cases where the operation(s) to perform are not dependent on runtime state?

For example, in a servlet environment you might want to get the ip address of the connecting client; in this case you need to use a def as, of course there is no connected client at compile time.

On the other hand you often know, at compile time, the operations to perform, and can go with immutable val foo = (i: Type) => {...}

As a rule of thumb then, should one only use defs when there is a runtime state dependency?

Thanks for clarifying

Community
  • 1
  • 1
virtualeyes
  • 11,147
  • 6
  • 56
  • 91
  • Syntax for the `def` is clearly incorrect. Please fix it so we know better what do you mean. – Daniel C. Sobral Jun 05 '12 at 22:11
  • @DanielC.Sobral eh? oh, you must have read the linked thread. This question is related to, but not exactly about, that thread. I mean as I wrote, val function vs. def method; specifically, cases where val should/can be used over def and vice-versa. I had assumed val, being immutable, to be more performant, but Oxbow Lakes' answer indicates otherwise; non-paramterization of val functions was a useful tidbit as well. A community wiki, definitive guide to val vs. def, performance characteristics, tradeoffs, and when to use, would be highly useful – virtualeyes Jun 06 '12 at 05:47

1 Answers1

4

I'm not entirely clear on what you mean by runtime state dependency. Both vals and defs can close over their lexical scope and are hence unlimited in this way. So what are the differences between methods (defs) and functions (as vals) in Scala (which has been asked and answered before)?

You can parameterize a def

For example:

object List {

  def empty[A]: List[A] = Nil     //type parameter alllowed here

  val Empty: List[Nothing] = Nil  //cannot create a type parameter
}

I can then call:

List.empty[Int]

But I would have to use:

List.Empty: List[Int]

But of course there are other reasons as well. Such as:

A def is a method at the JVM level

If I were to use the piece of code:

trades filter isEuropean

I could choose a declaration of isEuropean as either:

val isEuropean = (_ : Trade).country.region = Europe

Or

def isEuropean(t: Trade) = t.country.region = Europe

The latter avoids creating an object (for the function instance) at the point of declaration but not at the point of use. Scala is creating a function instance for the method declaration at the point of use. It is clearer if I had used the _ syntax.

However, in the following piece of code:

val b = isEuropean(t)

...if isEuropean is declared a def, no such object is being created and hence the code may be more performant (if used in very tight loops where every last nanosecond is of critical value)

Community
  • 1
  • 1
oxbow_lakes
  • 133,303
  • 56
  • 317
  • 449
  • Perhaps you should mention that every time method `isEuropean` is passed to another function/method, a new function object will be created. – missingfaktor Jun 05 '12 at 16:52
  • Good point; my original explanation was actually rather misleading in fact. I've edited it – oxbow_lakes Jun 05 '12 at 17:01
  • +1, @oxbow_lakes (thanks for the link, a veritable anthology of method vs. function) – virtualeyes Jun 05 '12 at 17:07
  • by runtime state dependency I mean as the example provided, "val foo = () => request.remoteAddress()" would generate a runtime error as at compile time there is no connected client. You could define a lazy val or perhaps a local def within the val anonymous method to workaround, but the point is just that, if the operation(s) to perform are not, let's say, externally dependent, then going with immutable val function, is an option. Just trying to develop some conventions for when to go with def method vs. val function – virtualeyes Jun 05 '12 at 17:19
  • "A def is a method at the JVM level" Are all `def`s methods at the JVM level? What about a `def` within the body of a function? – ebruchez Jun 06 '12 at 16:46