Polly Want a Message - Sandi Metz

The talk ultimately ends up here:

class Listing
  attr_reader :source, :subsetter, :justifier

  def initialize(source:, subsetter: justifier:)
    @source = source
    @subsetter = subsetter
    @justifier = justifier
  end

  def lines
    justifier.justify(subsetter.lines(source.lines))
  end
end

One observation right of the bat - this isn’t PLace-Oriented Programming (PLOP) but instead value-oriented programming. I guess I shouldn’t be too surprised as there is this paraphrasing [14:00]:

Easy is the enemy of simple

Now squinting at this code I can see:

defmodule Listing do

  def lines(source, subset, justify) do
    source.()
    |> subset.()
    |> justify.()
  end

end

revealing shades of the venerable master Qc Na and his student Anton (alt).

The other thing that is interesting is that Listing.lines/3 is only concerned (i.e. separation of concerns) with coordination of collaboration - i.e. computation has been entirely delegated to the passed dependencies (subset/1, justify/1).

Finally the “improved code” has a 60% larger LOC count than the original code. This increase is seen as a trade-off for the code being easier to reason about as any one class has no more than 18 LOC.

Personally I also suspect that some of the verbosity is due to many OO languages not being streamlined for this style of coding - I would even go further and suggest that in most cases the OO language constructs would not guide developers towards promoting (and adopting) this particular style.

Another interesting quote [37:16]:

Yet, it is true, when I show this example to people, examples like this to people, very often here’s what they say. They say, but now I don’t know how everything works. And my snarky self-- my snarky self never gets on stage. This Sandi doesn’t come out much. I’m like, yes, duh. Like that’s the whole point.

… OO gives you the opportunity to maximize the ignorance of every object. And if you take advantage of that opportunity, you can make your entire application smarter.

One unfortunate side effect of this talk is that Sandi uses the term Faux-O to mean poor execution of OO - i.e. with a heavy, negative connotation. The term FauxO was used in 2012 by Gary Bernhardt in a positive manner to refer to a desirable implementation of a Functional Core, Imperative shell style architecture (see also Boundaries).

So now FauxO needs to be qualified to avoid ambiguity. I suspect ultimately Sandi’s meaning of FauxO (or FauxOO) is going to prevail; unfortunately Gary Bernhardt’s version didn’t catch on over the preceding 6 years (so Functional Core, Imperative Shell had its chance).

8 Likes