
Value-Oriented Programming (2018) - pcr910303
https://matt.diephouse.com/2018/08/value-oriented-programming/
======
kootling
I don't get this. Aren't protocols basically interfaces? So the argument is
"Start writing an interface, not a class?" Isn't this common knowledge? This
is stuff you learn in programming 101. (I'm not trying to come off as snarky;
I'm genuinely curious.)

~~~
mikekchar
There are 2 general approaches for design when doing something that is vaguely
object oriented. One is to decompose you data into structures, figure out the
entity-relationships (often with a diagram) and then finally decide which
operations should live on which object. When I first started out in the 80's
this was pretty much "the way". You would frequently write descriptions of the
domain, circle all of your nouns and underline your verbs. Then you would make
data structures with the nouns and make methods with the verbs.

A lot of this stuff came out of the Simula branch of OOP. It's the kind of
stuff that C++, Java, C#, etc was modelled around. Objects are an
encapsulation of data along with their operations.

The other way to go is more where the Smalltalk guys went. In this branch of
OOP, what's important are the messages. Data is abstracted out and your goal
is to refer to it as little as possible. Instead messages are passed around
between objects and the objects are responsible for dealing with the messy
business of handling the actual data. When you are designing you look for the
message flow and then build objects that handle the messages.

When one says "Start writing an interface, not a class", I think what is meant
is that you should concentrate on the messages that the objects need to react
to, not the data within the classes. So you are designing a protocol, not an
E-R diagram.

There are people who are adamant that only one of these two approaches will
result in "good code". Often there is a considerable amount of derision for
someone who believes in the opposite approach. The truth probably lies
somewhere in between IMHO. There are advantages and disadvantages. When doing
a data centric approach, it's very easy to understand the state that you are
capturing. But it's also very easy to let the details of the data dominate and
to create unnecessarily complex code dealing with that data. Often you end up
with god objects and poor decomposition of behaviour. On the other hand, if
you go for the protocol approach, often you get designs where the state is
almost impossible to figure out and where you have "big bags of functions"
because it is convenient. It is difficult to maintain the data abstractions
and often the data details leak out, pretty much destroying your design.

Design is super difficult and requires a lot of experience of doing it.
Different schools of thought and descriptions of approaches are helpful to a
certain degree, but the best is to write a lot of code and get feedback from
people with experience. My biggest piece of advice for people who are near the
beginning of their career (i.e. first 10 years or so) is to try to work on an
project (likely your own side project) for at least 5 to 10 years so that you
can see it implode under its own weight. The biggest mistake I see developers
make is assuming that things that appear to work for a year or two will
continue to work as the code base ages. Especially I find people who have
formulaic approaches to design often break the design badly in the long term
(there are some 3 letter abbreviations that I could splash out if I wanted to
pick a fight ;-) ) Unfortunately, these people rarely work on a project for
more than a year or two, so you get what I call "drive by designings" \-- just
shoot it to pieces and drive on.

~~~
hnick
Would a summary of the two approaches being whether you focus first on what
the object does vs what the object knows?

Drawing a Class Diagram of data fields was indeed the only way we learned ~20
years ago. But now that you mention it I find myself slipping into the other
model a lot more lately. It's an especially natural fit for APIs.

~~~
mikekchar
Ha ha! I've tried to answer this question a few times tonight, but alas I find
that I am not able to do so :-) It's a good question and I think the answer is
much more deep than it appears. Maybe one day I'll be able to answer it.

------
thelazydogsback
You've also now gone from an immediate-mode renderer to a retained-mode
renderer (allowing future transformations on rendered segments, etc.) "for
free". But you're also adding potentially millions of new GC objects on the
heap that weren't there before, so not so free.

~~~
ken
How do you figure? He's not using any reference types, and he's using a
language that doesn't even have a GC.

It's likely the Set<Path> will use heap allocation internally (there isn't
really a way around that), but it's only holding a small value type.

Besides, this wasn't a streaming interface before this change, either. In the
first version, all elements were held in an array already.

~~~
thelazydogsback
AFAIK Swift supports GC, though only simple ref-counting at the moment. Yes,
it's the Set<Path>s that I'm talking about.

------
kragen
I think this is usually called "functional programming". See for example
[https://prog21.dadgum.com/26.html](https://prog21.dadgum.com/26.html).

~~~
jnbiche
While most statically-typed functional programming offer some approach to
composition similar to Swift prototols, the concept goes above and beyond the
idea described in the article you posted, which relates more to the idea of
programming with immutable data.

So similar compositional techniques to Swift protocols would be typeclasses in
Haskell, traits in Scala, module interfaces in ML languages (which have to be
used at the module-level via functors instead of at the value-level like the
other examples), etc.

Edit: I should have read to the end. I stopped after reading a few paragraphs
of what looked like a basic interface vs inheritance discussion. Turns out, at
the mid-point, he introduces an "alternative" to that approach, which is
indeed more or less functional programming. As much as I like functional
programming, (his "Value-Oriented-Programming"), interfaces are often quite
useful when programming in the large.

~~~
kragen
The article doesn't seem to be promoting using the Swift protocol approach to
composition — at least, that's not what it uses the "Value-Oriented
Programming" name to refer to. Instead, it's saying that _instead_ of using
the Swift protocol approach to composition, you should return a complicated
_value_ of some concrete data type from your function.

~~~
jnbiche
Oh, my apologies. I read a few paragraphs and it looked like a basic tutorial
about Swift protocols and inheritance vs composite, so I stopped. I'll read
the whole thing.

Edit: Yeah, you're right. I read to the end and that's pretty much functional
programming as you suggested. I'm not convinced it's always better than using
interfaces. Like most things, I think it depends. For example, particularly
when programming "in-the-large", I think being able to package up different
contexts (like a TestRenderer) into different protocol implementations is
often an _advantage_ of that approach, not a weakness, as he seems to imply.

~~~
kragen
Yeah, I'm not sure he's right that one technique is clearly better than the
other. They're only separated by a transformation to explicit CPS and a
doesNotUnderstand: override, but that isn't in itself an argument that the
distinction is unimportant.

------
dang
Discussed at the time:
[https://news.ycombinator.com/item?id=17881197](https://news.ycombinator.com/item?id=17881197)

------
andrepd
So functional programming + type classes?

------
zvrba
Um, he "invented" a command design pattern
[https://en.wikipedia.org/wiki/Command_pattern](https://en.wikipedia.org/wiki/Command_pattern)

------
ken
He doesn't use the term, but this looks exactly like an embedded domain-
specific language. It's a nice improvement on the original sample program.

------
rnikander
I was trying to use more values and protocols but then they made SwiftUI where
your model has to be class (ObservableObject).

------
einpoklum
The article seems to be overly preoccupied with nouns.

------
stopachka
Love the simple demonstration of a pretty profound concept

