Question

Reading back some of my Scala code, I noticed that it is either functional or object oriented.

Indeed, I have no idea on how to conciliate the no-side effects rule implied by immutable types and pure functions and the premise of OO, where methods modify instance state in-place, which is obviously side-effects.

One solution I am investigating is to make all methods return a clone of the current instance with the appropriate state modifications. Seems eager, but might help when I'll decide to paralelize the code, right ?

What are the best practices on mixing those 2 paradigms ? What is the balance ?

Thanks.

Was it helpful?

Solution

I think I actually take issue with the way you're framing this:

Indeed, I have no idea on how to conciliate the no-side effects rule implied by immutable types and pure functions and the premise of OO, where methods modify instance state in-place, which is obviously side-effects.

I wouldn't say that mutative operations on object fields is a core "premise of OO." Not at all (although conversely I do think that immutability is a core premise of FP). To me, OO is a way of thinking about program modularity more than anything else.

In my (perhaps twisted) mindset, even Haskell -- a language whose advocates often cringe at OO-style thinking -- nevertheless embodies some OO concepts, in the sense that it has a module system, various ways of encapsulating implementation details of datatypes, etc. And on the flip side, although it's exceptionally clumsy and aggravating, my Java code tends to make heavy use of basic functional concepts like currying.

In other words, I think the two approaches are complementary in a sense.

Now, at a less theoretical and more nuts-and-bolts level... Let's say you have something like:

class Foo(val a : A, val b : B, val c : C) {
  def setB(newb : B) : Foo = new Foo(a, newb, c)
}

... so you can say newFoo = foo.setB(b) as you suggested in the original post. I'd say this is totally fine style, and not cause for concern (about performance or readability or anything). You'll see plenty of this with the immutable collection classes in the Scala library.

OTHER TIPS

Immutable classes are a very good way to bridge OO and FP. Scala's Collection Library is a great example of blending OO, immutable objects and functional programming.

In your own code, Scala's case classes really help implementing immutable object, since they have a copy method which can be used as a replacement for the builder pattern.

// begin cheesy example
case class Circle(center: (Double, Double), radius: Double) {
  def move(c: (Double, Double)) = copy(center = c)
  def resize(r: Double) = copy(radius = r)
  def area = math.Pi * radius * radius
}

You may also benefit watching Rich Hickey's talks Persistent Data Structures and Managed References, and Are We There Yet? Both do an excellent job explaining the need for immutability, and how it helps us reason about state. He talks about everything with respect to Clojure, but his points apply equally well to Scala.

You might wanna check the Functional Programming chapter of Programming Scala (it's available free online) to get some hints.

FP it's not just about threading. High order functions can help you clean up and dry your code, making it look more elegant.

make all methods return a clone of the current instance

if you check how jQuery does it, it uses a technique called Method Chaining every method that would otherwise return void returns $this, so you can keep calling methods one over another. That's why jQuery objectness doesn't break traditional procedural user code in javascript.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top