var vs def

184 views
Skip to first unread message

scalanewbie

unread,
May 2, 2015, 6:57:51 AM5/2/15
to scala-l...@googlegroups.com
Hello All,

I am a newbie to scala and getting in grasp with val and def.

I noticed that I could write :

scala> var greatWorld2 = println("great world")

great world

greatWorld2: Unit = ()


AND


scala> def greatWorld() = println("great world")

greatWorld: ()Unit


Can someone please help me understand the difference?


I am aware that var is generally used to define variables and def is used to define functions. 


Now, keeping in mind that greatWorld2 is actually a variable and not a function, I am trying to print it, and I get:


scala> greatWorld2


OR, if I try calling it as a function, it throws an error e.g. below (which sounds ok as I did not declare this as a function, so was expecting this anyway).


scala> greatWorld2()

<console>:9: error: Unit does not take parameters

              greatWorld2()



 Long story short, difference between var and def , in terms of what the interpreter and or compiler is doing underneath will be very good to understand.


Thanks Guys,

S



Oliver Ruebenacker

unread,
May 2, 2015, 8:11:54 AM5/2/15
to scala-l...@googlegroups.com

     Hello,

  The right side of the = is evaluated once and the result is stored for a var, but for a def, it is evaluated again every time you call it.

  Also, vars don't take parameters (not even an empty ()), but defs can.

  A def is called a method and it is subject to overloading and overriding.

  A var is a field if it is in top-level of a trait/class/object, otherwise it is a local variable.

     Best, Oliver

--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-languag...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Oliver Ruebenacker
Solutions Architect at Altisource Labs
Be always grateful, but never satisfied.

martin odersky

unread,
May 2, 2015, 9:36:39 AM5/2/15
to scala-l...@googlegroups.com
On Sat, May 2, 2015 at 12:57 PM, scalanewbie <sudeep...@gmail.com> wrote:
> Hello All,
>
> I am a newbie to scala and getting in grasp with val and def.
>
> I noticed that I could write :
>
> scala> var greatWorld2 = println("great world")
>
> great world
>
> greatWorld2: Unit = ()
>
>
> AND
>
>
> scala> def greatWorld() = println("great world")
>
> greatWorld: ()Unit
>
>
> Can someone please help me understand the difference?
>
>
> I am aware that var is generally used to define variables and def is used to
> define functions.
>
>
> Now, keeping in mind that greatWorld2 is actually a variable and not a
> function, I am trying to print it, and I get:
>
>
> scala> greatWorld2
>
You are probably surprised that you see no output. That's because
greatWorld2 returns a unit value (after all, its type is Unit) and the
REPL does not print unit values. It could print () but it assumes that
you executed the expression for its side effects only.

Hope this helps

- Martin

>
> OR, if I try calling it as a function, it throws an error e.g. below (which
> sounds ok as I did not declare this as a function, so was expecting this
> anyway).
>
>
> scala> greatWorld2()
>
> <console>:9: error: Unit does not take parameters
>
> greatWorld2()
>
>
>
> Long story short, difference between var and def , in terms of what the
> interpreter and or compiler is doing underneath will be very good to
> understand.
>
>
> Thanks Guys,
>
> S
>
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "scala-language" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to scala-languag...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Martin Odersky
EPFL

scalanewbie

unread,
May 2, 2015, 12:26:06 PM5/2/15
to scala-l...@googlegroups.com
Thank you Martin and Oliver,

This is now clear to me (I think), correct me if am wrong below:

I created another small example, but this time with no variable in var declaration. Here is the example, and I start with initialising a variable i with 0

scala> var i = 0

i: Int = 0


scala> var greatWorld3:Boolean = if (i>10) true else { println("Print i:"+i)

     | i += 1

     | greatWorld3 }

Print i:0

greatWorld3: Boolean = false


scala> i

res44: Int = 1


scala> greatWorld3

res45: Boolean = false


Now, I start with a variable i set to 0; and declare a function (I think it is still a Function/Method; as when I did not provide :Boolean return type it complained as being recursive without any return type; do correct me if I am getting this wrong).


Given that the right side of '=' sign is only evaluated once, the statement is run once therefore the i ends up with 1 value at the end of it. And for the same reason, the greatWorld3 variable/function (ummm... I am still confused here if I defined a function or variable...) has the default for boolean, which is false.


And at end of the definition the interpreter prints:


greatWorld3: Boolean = false


which might have happened either because:

 a. the interpreter returns the type of the just created function/variable by default

OR

 b. Because there is a recursive call to greatWorld3, and the interpreter prints the vale of greatWorld3.


Not sure which one these above 2 is applied?


Next I go into function definition, with def


I then move on to define a new variable j with 0, and now replace the definition of greatWorld3 with a function def as below:


scala> var j = 0

j: Int = 0


scala> def greatWorld3:Boolean = if(j>10) true else {println("Print j:"+j)

     | j += 1

     | greatWorld3 }

greatWorld3: Boolean


scala> greatWorld3

Print j:0

Print j:1

Print j:2

Print j:3

Print j:4

Print j:5

Print j:6

Print j:7

Print j:8

Print j:9

Print j:10

res46: Boolean = true


scala> j

res47: Int = 11


Output for def block, is all ok.


Thanks for your help and time again.


Regard,

S


Som Snytt

unread,
May 2, 2015, 1:28:40 PM5/2/15
to scala-l...@googlegroups.com
Answering the question, it's "a", the REPL is just printing as usual.

You can google for discussions about recursive variable definitions. You're correct that it sees the default value on the RHS. That works because declarations in the REPL are class members, not locals.

You might also consider the scala-user group for questions because it has a bigger army of helpers.
 

Nick Stanchenko

unread,
May 2, 2015, 5:36:53 PM5/2/15
to scala-l...@googlegroups.com
Hi,

I think it’s easier to see the difference with simple examples.

Values are evaluated immediately (eagerly) and keep the result forever. That’s why the REPL doesn’t print “Evaluating...” for subsequent lines.

scala> val value = { println("Evaluating..."); 123 }
Evaluating...
value
: Int = 123

scala
> value
res0
: Int = 123

scala
> value
res1
: Int = 123

Methods, on the other hand, are evaluated every time you call them. That’s why the REPL does not print “Evaluating...” after the first line (we haven’t called the method yet), but does so for every subsequent line:

scala> def method = { println("Evaluating..."); 123 }
method
: Int

scala
> method
Evaluating...
res2
: Int = 123

scala
> method
Evaluating...
res3
: Int = 123

scala
> method
Evaluating...
res4
: Int = 123

There are also lazy values, which are evaluated only the first time they are accessed (but not during definition):

scala> lazy val lazyValue = { println("Evaluating..."); 123 }
lazyValue
: Int = <lazy>

scala
> lazyValue
Evaluating...
res5
: Int = 123

scala
> lazyValue
res6
: Int = 123

scala
> lazyValue
res7
: Int = 123

Variables (“var” keyword) behave more or less like values, but you can reassign them.
As already mentioned, in case of methods (“def”), you can also have arguments.

With that in mind, when you assign “println("Something")” to a “val”/“var”, it gets evaluated immediately, prints to the REPL and the “val”/“var” receives the result value, which is “()” of type “Unit”. When you assign it to a “def”, with parentheses or not, you get a method that will evaluate the statement (i.e. print to REPL) every time you call it.

Regarding functions, empty argument lists, etc, there are many great answers on StackOverflow:

Hope this helps,
Nick

Johannes Rudolph

unread,
May 3, 2015, 8:27:04 AM5/3/15
to scala-l...@googlegroups.com
Hi,

I think you may struggle on three points:

1.) expressions vs. statements and the Unit type and value: in Scala
each statement is also an expression. This means that statements will
return a value, the Unit value (), that can be put into a variable
(even if that's not particularly useful).

That's what happens in

var greatWorld2 = println("great world")

afterwards greatWorld2 contains the value ().

2.) the meaning of the syntax `var xyz = expression`. Actually, you
could see this as a short-form of

var xyz: Boolean = _
xyz = expression

The first line basically reserves a memory slot of type Boolean and
initializes it with the default value for that type. The second line
assigns the value of the expression to that memory slot.

Constrast this to

def xyz = expression

which is a line that isn't really executed at runtime i.e. when the
control flow reaches this line nothing happens. The expression is only
then evaluated when you "call the method". The repl sometimes makes
things harder to understand because it mixes up compile-time and
runtime, so I'd suggest also playing around writing real programs that
you first compile and then run.

3.) What the Scala compiler meant with "recursive without any return
type". The recursion that is meant here doesn't mean that there's
actually a recursive call happening at any point in time for your
`var` line, but it just means that in a var-definition you reference
the symbol which is currently being defined on the right-hand-side.
The Scala compiler won't be able to infer a type for these kind of
definitions so it complains.

The question remains what the semantics of the recursive occurrence of
the variable inside of its own definition is. If you make the
expansion I suggested at 2.) you will see why things are as they are:

var greatWorld3:Boolean =
if (i>10) true
else {
println("Print i:"+i)
i += 1
greatWorld3
}

is actually short for

var greatWorld3: Boolean = _
greatWorld3 =
if (i>10) true
else {
println("Print i:"+i)
i += 1
greatWorld3
}

So, first, the memory slot for greatWorld3 is reserved and initialized
with the default value of Boolean which is `false`, then the
expression of the right-hand-side of the assignment is executed (which
will access the current value of `greatWorld3` which is still the
default `false`, and then the result of this expression will be saved
to `greatWorld3`.

I hope this explains things a bit further :)
Johannes
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

scalanewbie

unread,
May 3, 2015, 8:49:08 AM5/3/15
to scala-l...@googlegroups.com
Thank you Johannes, Nick and som-snytt,

All your explanations are easy to understand.

@Johannes - Thanks for describing the inside view, that was really helpful and what I was kind of looking for. And I agree with your suggestion Johannes; I should give REPL a little rest and start coding a bit, surely that would help. :)


@Nick - Thanks for sharing the links at the end. I did not know that Functions and Methods are different in Scala; and the discussions you pointed out, has also revealed some new ways (new to me I mean) of using function literals along with var. 

Thank you.

Regards,
S

Andrew Phillips

unread,
May 3, 2015, 10:12:02 PM5/3/15
to scala-l...@googlegroups.com
> The question remains what the semantics of the recursive occurrence of 
the variable inside of its own definition is.

On this subject, see also: http://scalapuzzlers.com/#pzzlr-016.

Regards

ap
Reply all
Reply to author
Forward
0 new messages