values cannot be volatile

328 views
Skip to first unread message

Jonathan Willis

unread,
Oct 6, 2015, 1:08:36 PM10/6/15
to scala-user
I asked this question in scala-language, but maybe this is a better forum for asking it:

I notice there is a ticket for the compiler not properly handling volatile fields in case classes: https://issues.scala-lang.org/browse/SI-8873. What version of scala will address this problem? My scala version is 2.11.7 and here is my case class:

case class Player(@volatile var hand: Hand,

                  var deck: Deck,

                  var discards: Discards,

                  var actions: Int,

                  var score: Int,

                  var money: Int) {

}

Russ P.

unread,
Oct 7, 2015, 12:32:21 AM10/7/15
to scala-user
I am wondering why you would declare a case class with all vars. That can be risky, depending on what you do with it. Why not just make it a regular class? Or use vals and the copy method to change them. I have no idea whether that would solve your problem, but it might be worth a try at least.


On Tuesday, October 6, 2015 at 10:08:36 AM UTC-7, Jonathan Willis wrote:
I asked this question in scala-language, but maybe this is a better forum for asking it:
Home > My Account
Participant Statement: Civilian

Print this page
Text size:
Quarterly StatementsAnnual Statements
You can view or download your past or current quarterly participant statements. As quarterly statement information becomes available (generally around mid-month in January, April, July, and at

Jonathan Willis

unread,
Oct 9, 2015, 12:18:25 AM10/9/15
to scala-user
I'm definitely a novice when it comes to scala. My thoughts were when reading the documentation on case classes was that case classes should be the default unless you need to inherit from them. Why would you need a regular class if you didn't inherit from it?

What risks would there be from using a case class with vars?
Why would i want to use vals instead of vars? I guess this could be beneficial so that all state changes occur in the GameState object and not in the player object. But then i would want my GameState to be a case class and vars, which I would potentially want to be volatile, which leads back to my original question
What exactly is the copy method to change vals?

Timothy Kim

unread,
Oct 9, 2015, 1:17:50 PM10/9/15
to scala-user
If you make your Object mutable this can happen

val player = Player( ... )

val result
= GameLibrary.calculateSomethingAboutPlayer(player)

// has player changed???

The method name suggests that it's going to calculate some value from player object. And it "feels" like it shouldn't change the player object. But there's nothing in the code guaranteeing that player hasn't been changed. Now, if the player class doesn't use var, then I'm guaranteed that the method doesn't (and cannot) change my player object.

But what if you need to modify a player?

You make a copy, instead of changing the object.

val player = Player( ... )  // Here, Player is a case class without vars

val richPlayer
= player.copy(money = 1000000)

Hope this helps.

Jonathan Willis

unread,
Oct 12, 2015, 2:14:47 PM10/12/15
to scala-user
Right, but don't you still have to change the player object somewhere? Yeah, you copied it but that doesn't do any good if that player isn't part of the game.

If I am able to do what I originally planned:


case class Player(@volatile var hand: Hand,

                  @volatile var deck: Deck,

                  @volatile var discards: Discards,

                  @volatile var actions: Int,

                  @volatile var score: Int,

                  @volatile var money: Int) {

}


Then this will be thread safe. To encapsulate better I intend to make these variables private and add some logic methods to the Player object. What could be improved with this design as compared to what you are suggestign?

Richard Bradley

unread,
Oct 13, 2015, 1:20:45 PM10/13/15
to scala-user
> Then this will be thread safe

Not for any interesting operations. Adding "volatile" all over the place doesn't magically make code thread safe.

Even comparatively simple operations like "player.actions -= 1" won't be thread-safe. You still need locks for any composite operations (or Actors or some other approach).

> don't you still have to change the player object somewhere?

In the functional style, you don't change the player object; you replace it with a new modified object.
The "case class" helper in Scala with its "copy" method is designed for that style.

It can be very difficult to understand how anything gets done without mutable state if you're very used to imperative programming, but it can work and it can work very well.
Try searching for "imperative v.s. functional" and read a few introductory texts.

These two touch on avoiding mutable state in functional programming, but they don't sell it very well:
There is more discussion in this link:

The "case class" helper constructs don't really work if you make the public fields "var" instead of val. 
It would be better to use a normal class and avoid case classes if you don't want immutable objects. 



> What could be improved with this design as compared to what you are suggestign?

The two styles are just different. There's no way to settle which is "better" in a thread like this. :-)

The specific problem with your proposal here is that the contract of a Case Class is that it is immutable. Your code will be surprising if you use both Case Classes and mutability. 

HTH


Rich

Clint Gilbert

unread,
Oct 13, 2015, 1:33:28 PM10/13/15
to scala...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 10/13/2015 01:20 PM, Richard Bradley wrote:
> The specific problem with your proposal here is that the contract
> of a Case Class is that it is immutable.

A serious question: where is this spelled out? My understanding is
that case classes just cause the compiler to generate some
boilerplate; the 'case' modifier doesn't imply anything about member
access or mutability.


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJWHUBhAAoJEBnktRkJHUgscUUP/07jbaWqpjzrMICZYggJtSjT
RR4ZMejcO7ZooCdM6Pbhxttr7a6qLqvtSgabK9yqh0WCjfaafMvfGtUmhIL7yPrE
FEZK/7a9uT6xVmlL6mHlDDT4mrf0eejduMfl5B28xN6gC3A7Kx5TRw4azuk4r6+D
TU6bsQjbCRBBep5XLZWoJAFiU+/CuOwvY5gZasng2Nz0y3ohAFf323JxMMTpL/st
agy4YMgC9664M8uI8q9aLCE5j1I2aPyOTZcnIFWiEWp+YONeh42DM96+QdnqZwKq
cxL18wLxv2GrhJaVBmLG99eaG0opbAdKvYB0MrJeBqY0i/ji+H8cgTCX7d76c++x
luYGsl1SYeyuXP2SRHTFXClQqF1vyl8yNitX8YycXc0OndMV9HfarwEqCM2Yc3En
ZUQqxceHpGLT6yfs6bAMLgfLAdxysmlbOozxjicrbqrapuIESHRjBcPsWlopdj87
Q+Wqvw212gOsKf+Sb7nnNSu+eWLpjraRfngQWrXXIepkRPXMy0IdqmEPOjXNWe9r
M4TRA7qBLBj2qGetxNeRmj1RC+ooAm6eA4gtBObVFbLzypUq7wyG38PKqRQOefat
j/ehWAPLH36PALa7HzL/3z8J/JZ/vIscAKi99PHC99oBqtXdN7uT3Vw0nLqPgc1i
avTvWrxzakSidSEEWdJY
=3TPA
-----END PGP SIGNATURE-----

Oliver Ruebenacker

unread,
Oct 13, 2015, 1:43:31 PM10/13/15
to Clint Gilbert, scala-user

     Hello,

On Tue, Oct 13, 2015 at 1:33 PM, Clint Gilbert <clint_...@hms.harvard.edu> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 10/13/2015 01:20 PM, Richard Bradley wrote:
> The specific problem with your proposal here is that the contract
> of a Case Class is that it is immutable.

A serious question: where is this spelled out?  My understanding is
that case classes just cause the compiler to generate some
boilerplate; the 'case' modifier doesn't imply anything about member
access or mutability.

  According to the specs for equals and hashCode, if two objects are equal, they must have the same hashCode, and the hashCode of an object must not change during the object's lifetime. Combine this with the auto-generated equals and hashCode methods of case classes.

  If you violate these, you might add an object to a hash-based collection and never find it again.

     Best, Oliver




-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJWHUBhAAoJEBnktRkJHUgscUUP/07jbaWqpjzrMICZYggJtSjT
RR4ZMejcO7ZooCdM6Pbhxttr7a6qLqvtSgabK9yqh0WCjfaafMvfGtUmhIL7yPrE
FEZK/7a9uT6xVmlL6mHlDDT4mrf0eejduMfl5B28xN6gC3A7Kx5TRw4azuk4r6+D
TU6bsQjbCRBBep5XLZWoJAFiU+/CuOwvY5gZasng2Nz0y3ohAFf323JxMMTpL/st
agy4YMgC9664M8uI8q9aLCE5j1I2aPyOTZcnIFWiEWp+YONeh42DM96+QdnqZwKq
cxL18wLxv2GrhJaVBmLG99eaG0opbAdKvYB0MrJeBqY0i/ji+H8cgTCX7d76c++x
luYGsl1SYeyuXP2SRHTFXClQqF1vyl8yNitX8YycXc0OndMV9HfarwEqCM2Yc3En
ZUQqxceHpGLT6yfs6bAMLgfLAdxysmlbOozxjicrbqrapuIESHRjBcPsWlopdj87
Q+Wqvw212gOsKf+Sb7nnNSu+eWLpjraRfngQWrXXIepkRPXMy0IdqmEPOjXNWe9r
M4TRA7qBLBj2qGetxNeRmj1RC+ooAm6eA4gtBObVFbLzypUq7wyG38PKqRQOefat
j/ehWAPLH36PALa7HzL/3z8J/JZ/vIscAKi99PHC99oBqtXdN7uT3Vw0nLqPgc1i
avTvWrxzakSidSEEWdJY
=3TPA
-----END PGP SIGNATURE-----

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



--
Oliver Ruebenacker
Senior Software Engineer, Diabetes Portal, Broad Institute

Richard Bradley

unread,
Oct 13, 2015, 1:51:32 PM10/13/15
to scala-user
> A serious question: where is this spelled out?

I agree; the documentation is lacking in this regard.

The most obvious official documentation about case classes is this page:

One of the comments on there links to this SO answer, which explains things very well and mentions immutability:

Clint Gilbert

unread,
Oct 13, 2015, 2:21:57 PM10/13/15
to Oliver Ruebenacker, scala-user
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 10/13/2015 01:43 PM, Oliver Ruebenacker wrote:
>> According to the specs for equals
>> <http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equal
s%28java.lang.Object%29>
>>
>>
and hashCode
>> <http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashC
ode%28%29>,
>>
>>
if two objects are equal, they must have the same hashCode, and the
>> hashCode of an object must not change during the object's
>> lifetime. Combine this with the auto-generated equals and
>> hashCode methods of case classes.
>
>> If you violate these, you might add an object to a hash-based
>> collection and never find it again.

I know how equals and hashcode work. But from the link you quoted:

docs.oracle.com wrote:
> Whenever it is invoked on the same object more than once during an
> execution of a Java application, the hashCode method must
> consistently return the same integer, **provided no information
> used in equals comparisons on the object is modified**.

(emphasis mine)

That says to me that if the fields of an object stay the same,
hashCode() should return the same value no matter how many times you
call it. The Java docs specifically set out an exception if the
fields used to compute the hash code are modified.

If there was a rule like you described, 95+% of Java classes that
implement hashCode() would violate it.

You made an argument for immutable keys in hash maps - which I
completely agree with! I was just asking where the "contract" is that
says that case classes have to be immutable. This comes up every once
in a while and causes confusion every time.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJWHUuiAAoJEBnktRkJHUgsUmcQAJj1E2PcZFfmA4TfFYtSnTb4
UB6LatPfZq+v6lXLpEAbl86ZIo9oOIVXqQ3YsovZ4ipBakZb8oodLLCaLyzQ24N7
q744NaWori797yxmsBk3dO1covgpQDlCV7FejRgyMlQu4U7EKV3j9e7HOdqjQW0Q
oe2gJzh75WmeA05EOXABgJ7X7ZyGsiGAuAZKgR9U3Hk6JlKv7zM2hBwVob7pJT9+
ImxzteT7cap2ntDwbBjjdG1JyJgHUlqX+1zkbhL2XV9TrJk7GPeErFsDTmb4+Jk/
OLJRuu35YDudFEO8+sncTejOHQfYsy6TmgZuEtEkICEQJJ0TR9nCcbKJamuQkJpN
7Fb6+CsqqkOGhlQmqhbuAKR6RepeGET0nqOEv3+Q9OvEr5Fpk9py6rOM4YC2H6uH
uUPPRptHN2pR9kxu26rXg4+jnNcVMz5C7C9SmfDvkhBKACeBAKOqOPMLKKEM0bj9
NU7mu4WBo67FW7rbDiF3IPIFCPU4cVeabm5VOdnEUwjQlhl5shyb2Xu8f4e33pwq
3dHV9haCj/BQUh0reRiRnleK9XCpAnRn+tzTEl6v+JTarKk+L4YvUW94rLjx2Yo7
d2pZPJNK92Si7MLV9iQB66MdK13Cpmny7q0YQrbd9PmY3T5/pnvoRXRB4J87Muq4
cPdD3DpvIFfbfy/zMcBY
=bZ7G
-----END PGP SIGNATURE-----

Rex Kerr

unread,
Oct 13, 2015, 2:24:05 PM10/13/15
to Oliver Ruebenacker, Clint Gilbert, scala-user
You forgot the


  provided no information used in equals comparisons on the object is modified

part of the hashCode docs.

When you mutate an object such that its equality changes, its hashCode may change also.

  --Rex

Clint Gilbert

unread,
Oct 13, 2015, 2:29:40 PM10/13/15
to scala...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

That SO thread just lays out common ways people use and think of case
classes - conventions, in other words. I was wondering if there was
an official statement, spec, or rule on this issue.

The scala-lang.org link doesn't really mention that case classes must
be immutable. (Searching for 'mutab' only finds one comment that's a
copy of one of the SO answers.) The compiler (and language spec?)
specifically allows case classes with mutable and non-public fields.
That, combined with statements from Typesafe devs on this list, has
always made me lean toward the "case classes are just for boilerplate"
interpretation, even though the case classes and regular classes I
write are nearly always immutable.

On 10/13/2015 01:51 PM, Richard Bradley wrote:
>> A serious question: where is this spelled out?
>
> I agree; the documentation is lacking in this regard.
>
> The most obvious official documentation about case classes is this
> page: http://docs.scala-lang.org/tutorials/tour/case-classes.html
>
> One of the comments on there links to this SO answer, which
> explains things very well and mentions immutability:
> http://stackoverflow.com/questions/2312881/what-is-the-difference-betw
een-scalas-case-class-and-class
>
>
>
>
>
> On Tuesday, October 13, 2015 at 6:33:28 PM UTC+1, Clint Gilbert
> wrote:
>
> On 10/13/2015 01:20 PM, Richard Bradley wrote:
>> The specific problem with your proposal here is that the
>> contract of a Case Class is that it is immutable.
>
> A serious question: where is this spelled out? My understanding
> is that case classes just cause the compiler to generate some
> boilerplate; the 'case' modifier doesn't imply anything about
> member access or mutability.
>
>
>
> -- You received this message because you are subscribed to the
> Google Groups "scala-user" group. To unsubscribe from this group
> and stop receiving emails from it, send an email to
> scala-user+...@googlegroups.com
> <mailto:scala-user+...@googlegroups.com>. For more options,
> visit https://groups.google.com/d/optout.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJWHU2PAAoJEBnktRkJHUgsNUYP/30r2ovjKzsNwdJexcF6It0x
tVFLBFfcq0CGLveg4MQM/eN9TsFJ9uaacPKaD3XX8jyQ7TZcu+hJqhmorgI6frIb
LximafP1QyNYlO0lADL1STbjdwa8ptunQFeSjpyVnKDtAJSr0Ma44AQb5Jtl99oP
dCBqeXa9fdsvbU2ihDbYGEXkwgeTyTkXEs/REvQqBgV6Zv2s4o8pHDSTlEMlPZwq
zml5VoW86Pr5/Qwuc7yCxMlHqTSGauA/ER+WXWdePsAu2VXtvi/CNpehB0SK5ps8
nGfgK1tAKjl3Hv2GkB23HXit+e4qL3f2LZqcAWx01AuoEsc8iP5TrXeOViwebsj5
F9/Bi0lgGyzwL8spkzW1UMy4OM7P+NQgXC0B8S/sY80bAV3elDLPf2qZrDu5gNgb
uhrGMXW0qZmeiRsDxKSccar6LytuBhKZgk6/sS7IiOeTe3wHtsS09fe2OS9ygEkU
W6o4/qnghMjVgl5gdeTOuKMEEofursvP2/7jqOR+/MPKYGnbd0dpbMTzQXasr2o+
HUl/0yCrSmUADEmVoy9AgJbucn1ak2HA4Pw0/rP16F8TFJaCTtTU/A38EnA0Hm4K
31kCe+htTah5vfZPlOluCGBfnuC5T8+PcSXx90fhYdfaQqa1c/lro45Z3y6jTqe4
qSjlGkw9ozvMbpQDZM3I
=7XsP
-----END PGP SIGNATURE-----

Richard Bradley

unread,
Oct 13, 2015, 5:22:31 PM10/13/15
to scala-user
> That SO thread just lays out common ways people use and think of case 
> classes - conventions, in other words.  I was wondering if there was 
> an official statement, spec, or rule on this issue. 

Not that I know of.

> That, combined with statements from Typesafe devs on this list,

Can you cite any such comments? It might go some way towards "an official statement, spec, or rule on this issue".

> has always made me lean toward the "case classes are just for boilerplate" 
> interpretation, even though the case classes and regular classes I 
> write are nearly always immutable. 

The boilerplate added by case classes works well if they are immutable and works poorly if they are mutable.
Specifically, "copy" is strange on a mutable class, and "equals" defined on all fields is rarely what you want on a mutable object.

I think you're right that there's no explicit immutable "contract", just a convention.

> <mailto:scala-user+unsub...@googlegroups.com>. For more options,

Clint Gilbert

unread,
Oct 13, 2015, 5:39:16 PM10/13/15
to scala...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jason Zaugg and Viktor Klang weigh in here:

https://groups.google.com/forum/#!topic/scala-user/buGv-DNNvWs

On 10/13/2015 05:22 PM, Richard Bradley wrote:
>> That SO thread just lays out common ways people use and think of
>> case classes - conventions, in other words. I was wondering if
>> there was an official statement, spec, or rule on this issue.
>
> Not that I know of.
>
>> That, combined with statements from Typesafe devs on this list,
>
> Can you cite any such comments? It might go some way towards "an
> official statement, spec, or rule on this issue".
>
>> has always made me lean toward the "case classes are just for
> boilerplate"
>> interpretation, even though the case classes and regular classes
>> I write are nearly always immutable.
>
> The boilerplate added by case classes works well if they are
> immutable and works poorly if they are mutable. Specifically,
> "copy" is strange on a mutable class, and "equals" defined on all
> fields is rarely what you want on a mutable object.
>
> I think you're right that there's no explicit immutable "contract",
> just a convention.
>
>
>
> On Tuesday, October 13, 2015 at 7:29:40 PM UTC+1, Clint Gilbert
> wrote:
>
> That SO thread just lays out common ways people use and think of
> case classes - conventions, in other words. I was wondering if
> there was an official statement, spec, or rule on this issue.
>
> The scala-lang.org <http://scala-lang.org> link doesn't really
>> scala-user+...@googlegroups.com <javascript:>
>> <mailto:scala-user+...@googlegroups.com <javascript:>>.
> For more options,
>> visit https://groups.google.com/d/optout
> <https://groups.google.com/d/optout>.
>
> -- You received this message because you are subscribed to the
> Google Groups "scala-user" group. To unsubscribe from this group
> and stop receiving emails from it, send an email to
> scala-user+...@googlegroups.com
> <mailto:scala-user+...@googlegroups.com>. For more options,
> visit https://groups.google.com/d/optout.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)

iQIcBAEBAgAGBQJWHXn8AAoJEBnktRkJHUgsOGgP/iipyJ5pAG1M2kOuCz86XlfG
WQn3CqP4p6Zsgd6W3oTgf83ACuJUbdrgreui2h9CMdn+Xm7fyr3t2rrYft3Ti8GA
ydTEN4F5GylNQL/xLXzgArnAZAG6V+EJRh/5K0nbcDqxJ6lhLK6+n7w8U52ZhDpn
iI76nFd70nk69FVImk3vLF1jKO5oCn+XM3xwD7dSCeazeGmvzKqQJUStRxmkfV1e
MZvzXG5PwsMgyO2VjhrjyD6e1hClu+5zGvuzYIF6V/tKMsxKO0Y1r8r+qNVfAfxs
417c8xfEddevXQ/Thtoz4svRlccmcST7Lf3p+QwtxDDur2FoCbTvq/ns9bkGgRHk
jkKsDgvZE8rBDUNXfJLTAeo3dIrK58jsyndpNURAAeXDQb99Fo+1EVTK8OuuSRRY
yqhqEk2ssmFky3wV+eJJs4UeXTvIRl2jGNcJ83JY5PIRQohkjDZcl1LVRau+sQ01
tN0RWHH0a1e5YEzz2MbI6y5odGPx3u+PpcwEVQ08e2O4Ta84CYx8kFgeLIs2mFEc
CCPKjo0iog4jAIUE7DnOd5WSM4B9PrgtJj+JB14vxx3fDMN6zoZWZuMBiy7P5kCL
EHZTZT7XqGnWkVV7PAyvyRNc8WKZhUn9jqU57fPtPty0WAbYcebdnemdh2uR31tj
ADCybRbEE/vbguk7e/nA
=3pc9
-----END PGP SIGNATURE-----
Reply all
Reply to author
Forward
0 new messages