6

I am new to scala, but I have background in javascript.

While I see the need to separate between val and var (mutable and immutable), I can't see why the def statement should ever be needed.

If functions are truly first-class citizens, as in javascript, why should they be declared with def and not with val ?

Is that design decision based on JVM related constraints, or is there some underlying logic that I fail to comprehend ?

Tom Fenech
  • 72,334
  • 12
  • 107
  • 141
Uri Goren
  • 13,386
  • 6
  • 58
  • 110
  • 1
    @0__ not quite the dupe: op asks *why it was designed this way*, not *what is the difference* – om-nom-nom Oct 14 '14 at 20:57
  • 4
    @om-nom-nom: The OP asks why functions are declared with `def`, but functions aren't declared with `def`, they are declared with `=>`, and `def` doesn't declare functions, it declares methods, which are fundamentally different from functions. The whole premise of the question is that methods and functions are the same thing, which is simply wrong, and is nicely explained in the duplicate question. – Jörg W Mittag Oct 14 '14 at 21:05
  • 2
    @JörgWMittag *The whole premise of the question is that methods and functions are the same thing, which is simply wrong.* Again, this is *what is the difference* (in other words, they ARE different indeed), but it does not explains why such separation was made many years ago in a first place. – om-nom-nom Oct 14 '14 at 21:38

3 Answers3

9

One big limitation of functions is that they cannot be generic as a value. E.g.

def foo[A](bar: A): Unit

That cannot be expressed as a function value

val foo: A => Unit  // A is _not_ a type parameter

that requires a resolution of type parameter A. Other differences are: Methods carry a natural notion of this as the enclosing class; they can abort via return. They can have multiple parameter lists, most importantly an implicit parameter list. They have named and default arguments. (I'm trying to imagine how a function with named and default arguments would look, perhaps it could be designed)

It probably would not have been impossible to just have function values, but def seems like a better match for the OO aspects of Scala.

0__
  • 66,707
  • 21
  • 171
  • 266
  • 1
    You should first state the basic difference (`def` is used to declare *methods*, which is quite different from declaring functions). Besides that, this is actually a pretty good answer, and so I don't understand why it was downvoted. – rsenna Oct 14 '14 at 21:37
4

def differs from val and var in that every time the variable is referenced, its expression is reevaluated.

Timothy Shields
  • 75,459
  • 18
  • 120
  • 173
  • 2
    Exactly. That's the real reason. – rsenna Oct 14 '14 at 21:02
  • 2
    @rsenna Not true. `object Foo { var bar = 1234; val baz = (i: Int) => i + bar }; Foo.bar=5678; Foo.baz(1)`. Functions catch the closure scope just as methods. – 0__ Oct 14 '14 at 21:11
  • 2
    @0__ wat? Even if what you're saying is right (and it is), it does not have any necessary relation to what this answer says. – rsenna Oct 14 '14 at 21:14
  • 2
    @0__ I did not say that you cannot have a `val` which is a closure. That is allowed. – Timothy Shields Oct 14 '14 at 21:15
  • Both a function value and a method are reevaluated every time you call `apply` or the method. – 0__ Oct 14 '14 at 23:09
  • 2
    @0__ No, the function value _itself_ is not reevaluated; only its `apply` method is. You can see it by changing to `val baz = { println("baz is evaluated"); (i: Int) => i + bar }`. – Alexey Romanov Oct 15 '14 at 04:52
1

I think it's language decision made for easier migration from Java. It's quite a big shift in mind to watch on functions as on function-values.

Eugene Zhulenev
  • 9,714
  • 2
  • 30
  • 40