5
votes

I'm just learning to program in scala. I have some experience in functional programming, as I have in object oriented programming. My question is kind of simple, yet tricky:

Which structures should be used in Scala? Should we only stick to immutables, eg. modifing lists by iterating through it and stick a new one together, or go for mutables? What is your opinion on that, what are the performance aspects, memory related aspects, ...

I'm likely to program in a functional style, but it often expands to an insane amount of effort to do things which are easily done by using mutables. Is it situation dependent, what to use?

3
This question is very general. I highly recommend identifying those problems that you think require "insane" effort to solve functionally, and asking questions about them. You might learn new functional techniques which make the effort seem reasonable - or even easier than using mutable data!Ben James
There are other questions that address this, and this question is too vague or broad to admit a good answer, but in brief: do what works best overall. As a rule of thumb, use an immutable solution if there are no severe drawbacks; after that, favor a mutable one where the mutable state doesn't escape the local context (i.e. the method you're using), followed by one where the mutable state is at least hidden in the class (so no need to worry about it except when using multiple threads--and document the lack of thread safety). Use immutability because it helps you, not when it hurts!Rex Kerr
On the easy/insane ratio: mutability is often easier to program and debug when dealing with a single thread and becomes insanely difficult to program and debug when using multiple threads.Bruno Grieder
Once you do much functional/immutable programming, you'll see (arguably more elegant) solutions to problems without wanting to use mutability. That said, you'll also know when to use mutability! (e.g. operating on a list element which is affected by other elements - such as finding the unique elements in a list.)Grogs

3 Answers

3
votes

(I thought this must be a duplicate but couldn't easily find an earlier similar one, so I venture to answer...)

There is no general answer to this question. The rule of thumb suggested by the creators of Scala is to start with immutable vals and structures and stick to them as long as it makes sense. You can almost always create a workable solution to your problem this way. But if not, of course be pragmatic and use mutability.

Once you have a solution, you can tweak it, test it, measure its performance etc. If you find that e.g. it is too slow or overly complex, identify the critical part of it, understand what makes it problematic and - if needed - reimplement it using mutable variables, ideally keeping it isolated from the rest of the program. Note though that in many cases, a better solution can be found from within the immutable realm as well, so try looking there first. Especially for a beginner like myself, it still happens regularly that the best solution I could come up with looked contorted and complex with no apparent way to improve it - until seeing a simple and elegant solution to the same problem in a few lines of code, created by an experienced Scala developer who controls more of the power of the language and its libraries.

3
votes

I usually obey the following rules:

  • Never use static mutable vars

  • Keep all user defined data types (typically case classes) immutable unless they are very expensive to copy. This will simplify a lot of the application logic.

  • If a data structure/collection is inherently mutable (i.e. it's designed to change over time), using a mutable data structure/collection might be appropriate. An example might be a large game world that is updated when players move. Remember to (almost) never share these data structures between threads though.

  • It's fine to use mutable local vars in methods

  • Use immutable collections for function results. These can be strictly or lazily evaluated depending on what gives best performance in the used context. Be careful if you use a lazily evaluated result which depends on a mutable collection though.

3
votes

Prefer immutable to mutable state. Use mutable state only where it is absolutely necessary. Some notable reasons include:

  • Performance. The standard libraries make wide use of vars and while loops, even though this is not idiomatic Scala. This should not be emulated, however, except for cases where you have profiled to determine that modifying the code to be more imperative will bring a significant performance gain.

  • I/O. I/O, or interacting with the outside world is inherently state dependent, and thus must be dealt with in a mutable manner.

This is no different than the recommended coding style found in all major languages, imperative or functional. For example, in Java it is preferable to use data objects with only private final fields. Code written in an immutable (and functional) way is inherently easier to understand because when one sees a val, they know it will never change, reducing the possible number of states any particular object or function can be in.

In many cases, it also allows automatic parallel execution, for example, collection classes in Scala all have a par function, which will return a parallel collection that automatically run the calls to functions like map or reduce in parallel.