egervari, if EVERYTHING is immutable, changing the name of an object
that contains a complex set of data is still simple; just clone it
(shallow - if immutability is everywhere copying is trivial and cheap)
with a different name.

Nevertheless, trying to make everything immutable is failing the first
Rule of Programming Rules: They never apply in every single last
situation. If in doubt, go for immutability, but if its clear the
design would suck gigantic balls if you do that, then don't. For
example, in a game, making a character's Hitpoints, for example,
immutable, hence creating a copy every time these get affected, that
really isn't useful. Also, the state you are leaving behind (the
character with more hitpoints) really isn't useful by itself.

To illustrate, here's an example:

Let's say I have a City object which represents a city. This is its
complete definition:

public class City {
    private String name;
    private Location centralStation;
}

If that's all there is, it's obvious that centralStation should NOT be
immutable, and hence city won't be immutable. Every decade or so its
possible for a city's central station to undergo major renovations and
move a bit.

However, all the same, a location *SHOULD* be immutable. A certain
latitude/longitude cannot change, and it would be completely
ridiculous if code that's working with the current location of the
station all of a sudden sees its location move around. In practice, if
Location were mutable, the getCentralStationLocation() method would
have had to give a defensive copy anyway, so even the theoretic idea
that one gets a magically transforming Location object that 'tracks'
where-ever the central station is at this point in time isn't really
feasible without a lot more effort.

Sometimes these things become complicated though. Should 'name' be
immutable? Names tend to be used as keys and in display lists, so name
changing at a whim is somewhat disconcerting (that is: Code using the
"City" library needs to put in extra effort to work around the notion
that name can change over time), and cities don't usually change
names. Nevertheless, when Leningrad renamed itself back to St.
Petersburg, was it a different city? The answer "No, it's the same
city" seems more logical than "it's a new city", so I'd err on the
side of making name mutable here.

However, with a slight tweak to the City model it would make more
sense for City objects to be immutable:

public class City {
    private final String name;
    private final Location centralStation;
    private final Timestamp when;
}

we included a timestamp. It doesn't matter that St. Petersburg is
called St. Petersburg today, a city object with a timestamp of 0 (Jan
1st 1970) can only have one name: Leningrad. And this name can't ever
change, except in the face of wrong data.


This is in fact a common thread when trying to represent a state-
changes-over-time system with immutables, such as a game. You include
a timestamp. This can work (and if you program in Haskell you're
pretty much forced into it), but it's easy to see that this is
probably not the best use case for immutables: You'd have to write
code to integrate two diverging time-lines. If you don't, there's
absolutely no point in tracking any of it. However, with both
timestamp tracking and a merge algorithm you can massively scale your
game, by letting each thread do its own thing, merging only on an as
needed basis.


There are also questions about equality in either system: With
timestamped final cities, obviously the 1980 state of a city isn't
equal to the 1970 state of a city, but an .isSameCity() method would
be prudent. I don't see a way to write it without including an ID of
some sort. Same goes for when you're working with a mutable city. With
an ID you can even use the city as a key in a map, as the equality/
hashCode of it won't change even if you fiddle with it.


However, if a field can NOT reasonably change intrinsic meaning over
time it shouldn't be mutable just because the underlying system may
have a need for changing it. For example, java.awt.Point is mutable,
and that was a mistake. A mutable Location object would be a mistake.
Mutable strings would be bad. Mutable numbers are no good. Sometimes
you need a mutable *container*, and that's fine, but that should be
explicit (fortunately java has them; java.util.concurrent.Atomic*).

On Apr 29, 2:41 pm, egervari <[email protected]> wrote:
> How many of you are currently programming in a hybrid language such as
> Scala?
>
> I'm finding it difficult to make things immutable. While I am
> definitely using more immutability than I ever have in the past, I
> don't think it's practical for some applications.
>
> For example, I am making a game right now. While I can kind of see how
> to make it immutable... I'm not sure it's entirely desirable. There is
> a lot of state in a game, especially a complex one.
>
> Right now, classes that are immutable are things that don't have a lot
> of nested structures, or things that have case class semantics. For
> example, a Potion of healing that heals for 200 health is a good
> example of an immutable object. Once it's consumed, you can just throw
> it away.
>
> Also, various parts of the game will have use actors, so I make sure
> any of the objects that need to be passed from actor to actor in the
> messages are immutable. If they aren't going to be used as messages, I
> prefer mutability instead. This is backwards of what people have been
> saying to do... but I find it makes things much simpler.
>
> The hardest part of keeping everything immutable is large classes with
> collections. To make them fully immutable, you have to clone
> everything on every operation.
>
> Let's say you a character in an rpg game and you change their name.
> Bam, you gotta clone all fields and return a new character. This is a
> gigantic pain in the ass. It feels bloated to do it over and over, and
> it is a maintenance havoc.
>
> I'm thinking back to some systems I have done in the past, where I
> have 130-150 domain objects. How do we make those immutable? If you
> have a customer... and you change a line item on an invoice... you'd
> have to re-create the entire object graph if you were working with the
> root customer object.
>
> How have you been wrestling with immutability/mutability in your
> programs? What patterns/principles have you been using to decide? How
> far have you gone to the immutability end?
>
> --
> You received this message because you are subscribed to the Google Groups 
> "The Java Posse" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to 
> [email protected].
> For more options, visit this group 
> athttp://groups.google.com/group/javaposse?hl=en.

-- 
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en.

Reply via email to