6

Anyone care to elaborate on how val in scala is different from const in java?
What are the technical differences? I believe I understand what "const" is in c++ and java. I get the feeling that "val" is somehow different and better in some sense but I just can't put my finger on it. Thanks

Jim Balter
  • 16,163
  • 3
  • 43
  • 66
  • Don't forget `val`/`var` are also used to generically mark fields and local variables/values so that you don't have to declare a type. `val x` in Scala is really closer to `const auto x` in C++. – DaoWen Aug 21 '14 at 03:26

2 Answers2

11

const in Java has no function—it's reserved but you can't actually use it for anything. Declaring a Java variable as final is roughly equivalent.

Declaring a variable as a val in Scala has similar guarantees to Java final—but Scala vals are actually methods unless they're declared as private[this]. Here's an example:

class Test(val x: Int, private[this] val y: Int) {
  def z = y
}

Here's what the compiled classfile looks like:

$ javap -p Test
Compiled from "Test.scala"
public class Test {
  private final int x;
  private final int y;
  public int x();
  public int z();
  public Test(int, int);
}

So it's clear from this example that private[this] val is actually Scala's equivalent of Java's final in that it just creates a field (no getter method). However, it's a private field, so even that's not quite the same.

Another fun fact: Scala also has a final keyword! Scala's final behaves similarly to how final works for classes in Java—i.e. it prevents overriding. Here's another example:

final class Test(final val x: Int, final var y: Int) { }

And the resulting class:

$ javap -p Test
Compiled from "Test.scala"
public final class Test {
  private final int x;
  private int y;
  public final int x();
  public final int y();
  public final void y_$eq(int);
  public Test(int, int);
}

Notice that the final var definition makes the getter and setter methods final (i.e. you can't override them), but not the backing variable itself.

Community
  • 1
  • 1
DaoWen
  • 32,589
  • 6
  • 74
  • 101
0

A Scala val is equivalent to a final variable or field in Java. A Scala var is equivalent to a non-final variable or field in Java. (By the way, neither "var" nor "const" are Java terms.)

The aspect that's "better" about Scala's syntax choice to use val and var is that code using non-modifiable values is generally easier to understand. In Java, final is "syntactic vinegar", and style guides tend to argue over whether code should use final to encourage better coding or omit final to avoid the clutter. Scala doesn't have this conundrum because the var and val are exactly the same length, so you're a bit more free to just choose the one that makes the most sense.

Chris Martin
  • 30,334
  • 10
  • 78
  • 137
  • *"In Java, final is "syntactic vinegar", and style guides tend to argue over whether code should use final to encourage better coding or omit final to avoid the clutter."* Do you have a citation for either of those claims? IMO, `final` is only "syntactic sugar" insofar as *types* are syntactic sugar. Generic types are probably even more so since they actually get erased at compile-time, whereas the `final` specifier sticks around—but I've never heard anyone say that generics are just "syntactic sugar". I've also never heard anyone claim you should leave out `final` since it's just clutter! – DaoWen Aug 21 '14 at 03:21
  • Regarding the first part of your comment - you realize I wrote "vinegar", not "sugar"? – Chris Martin Aug 21 '14 at 03:29
  • I've got nothing in particular to cite, it's just a debate I've seen among coworkers and online over the years. One example: https://programmers.stackexchange.com/questions/48413/in-java-should-i-use-final-for-parameters-and-locals-even-when-i-dont-have-t – Chris Martin Aug 21 '14 at 03:37
  • No, I didn't notice you wrote *vinegar* rather than *sugar*—my bad. I've actually never seen that term before. However, I'd still disagree that `final` is syntactic vinegar since that definition seems to imply that the language designers purposely made something awkward to discourage it (like the cumbersome `asInstanceOf` in Scala). The point about eliding `final` on method parameters makes sense to me since all the `finals` would really make the signatures bulky. If you edit your question to specifically mention methods (and maybe emphasize "vinegar") then I can remove my downvote. – DaoWen Aug 21 '14 at 04:24
  • I don't believe it needs to be intentional to be vinegar. It's often just poor design (like the semicolons). It's definitely not just method signatures; it makes method bodies bulkier as well. Your downvote is your own, I don't need an explanation. – Chris Martin Aug 21 '14 at 04:28
  • I would say semicolons are *cruft*, not *vinegar*. I can see your point that anything that syntactically grosses you out could be "vinegar", but it looks like the people who coined the term specifically use it in the context of discouraging bad practices. – DaoWen Aug 21 '14 at 04:33