
Why Class? - hhariri
http://hadihariri.com/2013/11/24/refactoring-to-functionalwhy-class/
======
btilly
There is a fundamental point here that really bears thinking about.

Software design has as a fundamental problem being able to express yourself in
a way that is clear and remains clear as things change. Basic principles of
good software design, like reducing cohesion, remain good principles no matter
what "paradigm" you think you're using. When you change paradigms, be aware
that the basic principles remain the same no matter what label you give them.
And since design is all about tradeoffs, if you are going to have to violate a
principle, you might as well do it in the clearest and most straightforward
way possible.

Let me give an example. A singleton is bad for all of the reasons that a
global variable is bad. If you need one, I prefer to make it a global variable
simply because that is honest about what design principle has been broken.
(Unless I want to make it lazy - then it is easier to write with a singleton!)

So learn the principles. Figure out what they look like and are called in your
paradigm. Get on with life and solve real problems.

Let me give a concrete example. I learned more about good OO design from the
first edition of _Code Complete_ than any other book that I ever read. Even
though it was entirely about procedural programming. Because the principles
that it discussed, from how to name functions to the value of abstract data
types to information hiding, all apply directly to OO. And to functional
programming. And to aspect oriented programming. They are truly universal.
Learn the principles, they are more important than the labels.

~~~
lists
As someone self-teaching their way into software engineering, would you be
able to suggest any resources aside from Code Complete for these principles?

~~~
morkbot
Try "Clean Code" by Robert C. Martin.

But also remember that there's no one proper way of doing these things, it's
all heuristics, not laws written in stone.

------
sklivvz1971
I really like Hadi's criticism of OO, and in fact I would like to hijack it
and take it a few steps further, to paint what in my mind is a more realistic
picture. Functional programming is only _an alternative choice of paradigm_.
Expert programmers will use the best tool for the job and eschew the pointless
search for the _absolute best_.

Why OO? Classes exist to decouple behaviors from data. In fact, their purpose
is to think in terms of cohesive sets of behaviors instead of data-driven
functions.

Does this apply to any possible case? No, it's a leaky abstraction.

Why FP? Functions exist to decouple behavior from other behavior. In fact,
their purpose is to think in terms of completely decoupled sets of behaviors
instead of cohesive functions.

Does this apply to any possible case? No, it's a leaky abstraction.

Why AOP? Aspects exist to decouple behaviors that apply across classes. In
fact, their purpose is to think in terms of orthogonal sets of behaviors
instead of hierarchical sets of behaviors.

Does this apply to any possible case? No, it's a leaky abstraction.

Why Procedural Programming? To separate the functionality of the application
in separate behaviors. In fact, the purpose of procedures is to think in terms
of behaviors instead of sequences of operations.

Does this apply to any possible case? No, it's a leaky abstraction.

Why Declarative Programming? To express solutions in terms of goals instead of
behaviors. In fact, its purpose is to think in terms of desired state, not
sequences or compositions of behaviors.

Does this apply to any possible case? No, it's a leaky abstraction.

Why Logic Programming? To explore the logical consequences of given facts,
instead of focusing on behaviors or desired outcomes. In fact, its purpose is
to find new truths starting from given truths.

Does this apply to any possible case? No, it's a leaky abstraction.

Why spaghetti code? Wait, no that's just crap ;-)

~~~
chc
> _Why OO? Classes exist to decouple behaviors from data._

This seems like the opposite of how it generally works. Classes tie behaviors
to data. This is what people generally seem to mean when they talk about
_encapsulation_ in OO — the behavior and the data are bound together very
well.

~~~
sklivvz1971
If you have a datetime object you can stop thinking about the fact that it's
internally implemented with e.g. ticks since the epoch. In fact, you don't
care anymore what _data_ it depends on, because you only depend on
_behaviors_.

~~~
weavejester
That's more polymorphism than encapsulation.

~~~
sklivvz1971
I was thinking more in terms of different versions of the same library, which
is clearly one of the reasons why we have encapsulation :-)

~~~
weavejester
I can see encapsulation being useful in that case, though I'm of the opinion
the use-cases for encapsulation don't outweigh the disadvantages it brings.

------
strictfp
I think that the article uses a bad example. OO is actually really bad in db
apps (DTO apps). OO shines when you are in one big continuous memory space,
and don't have to worry about the data behind the objects. I see OO as a good
way of abstracting the data away from the logic of your program.

This abstraction works well with classical desktop apps (lots of code, one big
heap, pointers are always valid), but breaks down badly when your program is
about communicating data and you start to cross memory address barriers.

A lot of modern apps are about data. You see a lot of networked apps, db apps
and layered apps with different technologies in every layer, communicating
with each other only through shared data formats. Such an app is primarily
concerned with shuffling data around, and oo breaks down into a horrible mess.
Each transition to a data representation requires a complete serialization of
the object graph to a reasonable data representation and back again at the
other side. This means that you essentially have twice the amount of work than
if you would operate on the data directly as you would do with FP.

Once the amount of "internal juggling" with the data exceeds a certain limit,
OO might be beneficial. But for data-centric apps, forget it.

~~~
weavejester
> I see OO as a good way of abstracting the data away from the logic of your
> program.

Why would you want to do this?

~~~
jbooth
"Bad programmers worry about the code. Good programmers worry about data
structures and their relationships." \-- Linus

If your data structures don't exist outside of your functional code acting on
them, it's hard to reason about the data structures themselves in a vacuum.

~~~
weavejester
Isn't this an argument against hiding your data structures behind an opaque
object structure?

~~~
jbooth
To my mind, it's an argument for explicit definition of data structures (from
me, not Linus).

It seems to me that structs and/or objects do that pretty well. I'm not sure
what you're talking about with 'opaque object structure'. class MyClass {
member1, member2 } seems pretty transparent to me.

Anyways, I was just explaining why many people prefer to have struct/object
definitions separated from the code that operates on them. YMMV, you don't
have to agree.

~~~
weavejester
If you're just treating a object as a map of keys to values, then it can be
fairly transparent, but unless you're using a language like Javascript, where
maps and objects are synonymous, objects are much more difficult to work with.
It's hard to transverse them, or to merge them, or often even to look up a
list of keys.

I'd suggest that a better solution would be to just use maps, at least in
languages with good support for raw data structures.

~~~
jbooth
"It's hard to transverse them, or to merge them, or often even to look up a
list of keys."

That's exactly what I'm arguing against in my comment on making your important
structs/objects and their relationships explicit. Randomly mutating them
together all over your program might seem more flexible but at a cost of
making you worry about your code rather than your data definitions. And that's
without even getting into performance implications.

If you actually need a Map, of course, that's a different situation than the
ones I'm thinking.

~~~
weavejester
Using a map doesn't necessarily mean random mutation, or giving up on your
type system. In languages with immutable data structures and a sophisticated
type system, you can type-check the keys and values in a map.

------
RyanZAG
If you think of classes as namespaces and not objects (which is what they are
half the time), it becomes a bit saner. Pragmatism makes the world work.

You can still write functional code in OO. Heck if it makes you feel better,
you can just make a macro to rename 'namespace' to 'class' and then you can
write code like

    
    
      namespace Utils {
       function thingy() {...}
      }
    

Namespaces are generally an improvement over globally defined functions as it
lets you mix and match libraries without having to worry that you included the
right header files, etc. Again, pragmatism.

~~~
dsego
Agreed. I think the problem with OOP (at least in most common implementations)
is that objects (and/or classes) just do too much. They serve as complex data
types, records, code modules, contracts, callback containers, etc. It's hard
to grasp disparate concepts when you keep calling them the same name. Even
harder to construct and explain more advanced stuff layered on top, such as
various design patterns that actually make those objects useful.

~~~
pointernil
Agree. I find it quite interesting how the concept of classes resp. objects
has been adapted and moved away from what they really were let's say in
Smalltalk (message processing entities) ... and I think this "progress" was
not for better regarding the clarity of the concept.

I think this progress has to do with "type systems" and additionally with the
very powerful tools c++ f.e. added to the tool box. The more powerful the
toolbox the harder it is to truly grasp it, it seams which steepens the
learning curve considerably unless only the very rudimentary "features" of oop
are used, as it happens mostly in commercial 9-5 software development.

~~~
tezka
Have you programmed in Smalltalk? Classes tend to do a lot more (well
everything that can be done) compared to C++. Smalltalk has a clean design for
the core parts so these hang together pretty well. Nonetheless, inheritance
hierarchies are deep and there are many fat classes. So small size in itself
is usually not a virtue, clarity in role is on the other hand.

------
Jormundir
I think of learning OOP much like learning Chess. In Chess it's very easy to
learn how the pieces move and start playing, but becoming a master is
incredibly difficult, requiring years and years of deliberate practice. When I
see people complaining about OOP, it makes me think of two beginners playing
Chess, thinking victory is a random outcome.

The dialogue of the article is entirely about coupling, and in OOP figuring
out how to make a loosely coupled system is what separates the grand masters
from the beginners. Designing a loosely coupled system is incredibly hard and
requires years of deliberate practice to master. So when someone who's a
beginner or not very good at OO design claims OO isn't a valuable paradigm, I
don't listen. Bad OO can be less valuable than no OO, just like anything else,
and just like anything else, that doesn't make the whole paradigm bad.

I've explored functional programming in a couple of college courses now, and
find it very intriguing. When it's time to go a make a system, however, I find
it difficult to boil down functional principles into the system I want. This
is a complaint in the same vein as the OO complaints. Functional programming
is incredibly impressive when designing a behavior, but what separates the
masters from the beginners seems to be when it's time to model an entire
system. This is the current separation in my mind: OO is designed and really
good for modeling a complex system that involves lots of mutation, and
functional programming is really good for modeling and separating behavior
within a system.

I don't think we have grounds to say one is better than the other yet. Both OO
and Functional have their niches where they're amazingly effective, and both
have a giant gray area where it's difficult to mold the pure paradigm onto a
solution.

I think the best solution so far is a mixture of the two, such as we see in
Scala. Though, a mixture too has its own set of drawbacks. Mainly what seems
to be an explosion of language complexity and a giant need for design
conventions and limitations when there are so many possible routes to a
solution.

The best of the current climate is a mixture of the two, with a framework that
clearly defines and separates where and when to use one paradigm over the
other, so you aren't bogged down with the additional complexity.

~~~
weavejester
> OO is designed and really good for modeling a complex system that involves
> lots of mutation

I'd argue that this is where OOP struggles the most. Because mutation in OOP
is implicit and unconstrained, it's more difficult to manage than in FP
languages, which typically have more sophisticated controls and constraints
for handling state.

~~~
dbaupp
Isn't that more a problem with the mainstream implementations of OOP, since
one could concievably have an OOP language with fine-grained mutability?

~~~
weavejester
Yes, I suppose it would be possible. It might work better with Smalltalk-like
languages that revolve around message-passing.

------
gress
Not to get into the oo vs functional debate, but generic advice about how big
a class should be and how it should relate to other classes is guaranteed to
be inappropriate some of the time.

Classes are a tool you can use to design a solution to your particular
programming problem. Sometimes the problem with call for a few large classes.
Sometimes it will call for an evenly balanced network of small classes.
Sometimes there will be a lot of DTOs, and sometime none. Sometimes large
classes will cause maintenance problems because there is a lot of complexity
confusingly jammed in one place, and other times they will be a boon because
you don't have to look in lots of confusingly named files to discover what you
are looking for.

Criticizing a design by how well it conforms to abstract rules, rather than
criticizing its fit to the actual problem will often lead to confusion.

These rules of thumb are useful, but only as a way to question whether your
design is a good fit - I.e. "Would it be better if this class had more
behavior or less behavior? Would it be better to split this class into smaller
components, or should this group of similar classes be coalesced into a single
entity?"

------
dj-wonk
This is a nice narrative. Some people have misconceptions about what OO gives
you in comparison to other paradigms. OO provides specific abstractions, which
may be useful in many cases, but also may be too much. In some cases, simpler
abstractions may be preferable. Less complected (baked together and
inseparable) abstractions can often be found in other paradigms. For example,
in Java, a person might use a class even though all they need is a namespace.
In many functional languages, you can just create a namespace without the
other trappings of OO. Sometimes that is just what you want.

I've seen some nice slides from Clojure talks that talk about how many OO
abstractions are complected (combined) versions of simpler abstractions. If
anyone has seen the slides I'm talking about, please share. For example, a
class is combination of a namespace and ___. Possible answers include mutable
state, shared data, and so on.

~~~
Totient
I think that was Rich Hickey's "Simple Made Easy" talk:
[http://www.infoq.com/presentations/Simple-Made-
Easy](http://www.infoq.com/presentations/Simple-Made-Easy)

I think one of his most important points is that objects _are_ good for
representing, well, actual objects. As in, you have a mouse, or screen or some
little robot that you are controlling through code. And that's _all_ they are
good for.

Need a way to define a bunch of static methods and avoid name collisions? -
you want a namespace.

Need a place to store a bunch of data about something? - you want a
associative array.

Need a way to call the same function on different types? - you want an
interface.

I'm not sure about this, but I suspect part of the problem stems from the fact
that object-oriented languages (usually Java these days) are the first
language that students are exposed to. Once you start thinking in OO
abstractions, it takes some effort to break out of the mindset.

------
huhtenberg
> _Why Class?_

To enforce an invariant but of course. Just ask Bjarne.

[1]
[http://www.artima.com/intv/goldilocks3.html](http://www.artima.com/intv/goldilocks3.html)

~~~
ufo
You can have Abstract Data Types without classes and object orientation.

~~~
huhtenberg
Sure.

------
davidkhess
I've found the most critical difference between OO and FP to be state. Objects
are stateful from the moment they are created until they are destroyed. FP is
remarkable for its general lack of side-effects - i.e. computations do not
normally affect shared state.

I believe this distinction is a critical one because an application with a lot
of shared state is more difficult to scale than one without. As another poster
pointed out, in a shared addressed space such as a desktop app, this isn't a
concern. But if you want to scale an application across multiple address
spaces, communicating and synchronizing the state of objects between these
spaces tends to be difficult.

So, my tendency is:

Small and shared address space? Tend to use OO patterns and implementations.

Big and distributed address space? Tend to use FP patterns and
implementations.

Note, I don't consider OO vs. FP a language choice – I consider it a
programming paradigm choice.

~~~
fauigerzigerk
The problem is that whether or not we have shared mutable state on a logical
level is not for us to choose. It's ultimately a property of the task at hand.
Pushing shared state onto the database doesn't make it go away. Workarounds
like MapReduce or monads only help us defer the moment of truth. If shared
mutable state is what users ultimately expect to see, these approaches are
merely simulations of shared mutable state that exploit a time gap in users'
perception.

That gap is very brittle. Nightly batch windows become too short. Users expect
real time updates leading to major redesigns of entire systems, like Google
dropping MapReduce for their search index.

But I think your point about state being the major difference between OO and
FP is absolutely true. In OO systems, statefulness is the default everywhere.
Nothing is formally known about state in OO system and that is a bad thing. We
need state to be explicit and formally specified.

------
lightblade
I think OO and FP can coexist peacefully. You just need to pick out their good
parts and discard the rest, and use a programming language that allows this.

Do put your object in classes, but don't put behaviors there. Use classes to
allow static type checking so that functions taking them can guarantee certain
field exist.

Separate behaviors out into its own module. I'd avoid calling them classes
here because there will be confusion. Interactions between objects can be
implemented in FP style. This is where you get to use map and reduce.

I've been learning about DCI (data context interaction) recently. I can't say
I've fully grasped it yet, but it did opened my mind on how to do design
differently.

~~~
hernan604
OO and FP coexist peacefully. FP is all about passing functions as parameters
into other functions.

Its exists on decent languages. Which in case allow OO also.

ie. perl, allows all that, and has Moose which allows Class and Roles and
Types. So you can build classes like lego, literally.

~~~
nbouscal
> FP is all about passing functions as parameters into other functions.

That's a common misconception. First-class functions and higher-order
functions are definitely commonly used in functional programming, but they are
not what makes it functional programming. As with any paradigm, there is no
universally agreed-upon definition, but most functional programmers will
likely agree that lack of mutable state and lack of side effects are much more
central to functional programming than first-class and higher-order functions.
The latter are really just useful and elegant tools to help accomplish the
former.

~~~
Sssnake
Without side effects you couldn't do anything. Pure functional languages make
side effects explicit, but it isn't about them being missing.

~~~
nbouscal
> Without side effects you couldn't do anything.

Not true.

> Pure functional languages make side effects explicit, but it isn't about
> them being missing.

True. I should have been more clear about that.

~~~
Sssnake
Yes true. Running a program with no side effects is a no-op. All side effect
free programs are identical, and do nothing. This is one of the most common
misconceptions people afraid to learn haskell bring up, because people keep
saying "functional programming is having no side effects".

~~~
nbouscal
So you're saying that a library that has no side effects but performs a
complicated data transformation "doesn't do anything"?

~~~
Sssnake
A library is not a program.

~~~
nbouscal
Your claim was "Without side effects you couldn't do anything." I was
rebutting that claim. Again, unless you want to claim that libraries "don't do
anything."

The more specific claim that you need side effects for a program to do
anything is also false. You can prove mathematical theorems with programs that
have no side effects. Of course now you'll say that that only works because of
the compiler, which does have side effects, but that's really just moving the
target so you can be "right" (as you did with this post).

Even if theorem proving isn't good enough, since the entire purpose for having
the term "side effects" is to be able to usefully discuss referential
transparency, the other poster who noted that IO can be an effect and not
necessarily a side effect was correct. If IO is isolated, it is not a side
effect, it is just an effect. A good example of this is the execution of the
main action in a Haskell program.

~~~
Sssnake
You are not rebutting that claim, you are being obtuse.

>You can prove mathematical theorems with programs that have no side effects

No, of course you can not. How do you see the result? That requires a side
effect of some kind.

>A good example of this is the execution of the main action in a Haskell
program.

That is a terrible example, as executing main precisely _is_ a side effect.

~~~
nbouscal
> No, of course you can not. How do you see the result? That requires a side
> effect of some kind.

The result is whether or not the program type-checks.

Your original claim was, again, that "without side effects you can't do
anything". So, again, unless you are claiming that functions and libraries
"don't do anything", your original claim was incorrect. Your new claim, that
_programs_ must have side effects to do anything, is still wrong but more
debatable.

You can call me obtuse if you want to, or you can learn how to communicate
clearly and say what you actually mean. Doesn't much matter to me either way.

~~~
Sssnake
>The result is whether or not the program type-checks.

Ok, you are very confused. Type checking has nothing to do with program
execution. Type checking is done at compile time. Any program with no side
effects, the compile can safely optimize into nothing, since it does nothing.
The compiler does the type checking, not the program.

>Your new claim, that programs must have side effects to do anything, is still
wrong but more debatable.

It is the claim I made and you replied to. If you want to be pedantic and
obtuse you can't expect people to not call you out on it.

~~~
nbouscal
Seriously? I'm directly quoting you in a post that is still visible, and
you're denying it? Again, the quote that I originally replied to: "Without
side effects you couldn't do anything."

> Ok, you are very confused.

You are both very arrogant and wrong. Not a pretty combination. Thank you oh
so much for telling me that type checking is done at compile time, as though
there were the slightest possibility I didn't know that given what I've been
saying.

If you took some time to learn how to have a conversation on the internet
_without_ being an asshole, you might actually learn something. Until then,
I'll stop wasting my time trying to have a discussion with you. Cheers.

------
jakejake
This is a great piece and probably mirrors the process that a lot of us have
gone through over the years. I know it definitely rang true for me.

I would hazard to guess that functional programming or any other solution will
go through the same type of evolution and we will be looking back in 10 years
at how immaturely we used the technology. Then we will circle back to yet some
other technology that was previously used and went out of style, with some new
insights added.

It seems to me that we go in a great big circle over and over again, picking
up a little bit of new info each time around.

~~~
VLM
Also applies to the eternal wheel of centralization / decentralization. Or the
peculiar 3-phase of interpreted / tokenized / compiled.

On a larger scale paradigms usually pick a spot along the verbosity continuum.
Concise and information dense or verbose and information free? This is another
eternal cycle. Some modern java looks about the same as 1960s COBOL to me.

------
taybin
Object-oriented in the large, functional in the small. Makes sense to me.

~~~
straws
Gary Bernhardt has a nice talk about that:

[https://www.destroyallsoftware.com/talks/boundaries](https://www.destroyallsoftware.com/talks/boundaries)

A lot of people I know consider object-oriented design orthogonal to the
programming style — that the real improvement is moving from a procedural to
functional approach. Any system that grows large enough to clearly define an
architecture technically _is_ object oriented, so long as it's passing
messages among stable interfaces.

You want to have that functional core and imperative shell. Tell above, ask
below.

It's just unfortunate that a lot of "object-oriented programming" that you
learn in school is really just imperative programming with interfaces ;)

~~~
dj-wonk
Re: "Any system that grows large enough to clearly define an architecture
technically is object oriented, so long as it's passing messages among stable
interfaces."

@straws: I'm curious, why do you think that the situation you mention above
implies that such a system is 'technically' object oriented?

If I'm understanding your claim, I disagree. All you need are mechanisms for:

(1) function-calling or message-passing (I don't think you were trying to
emphasize an extremely rigourous definition of 'message passing' were you?)

(2) namespacing

(3) validating a 'stable interface'

There are many definitions of OO, but this is one is good enough for my point:
"Objects, which are usually instances of classes, are used to interact with
one another to design applications and computer programs" (from
[http://en.wikipedia.org/wiki/Object-
oriented_programming](http://en.wikipedia.org/wiki/Object-
oriented_programming))

You _don 't_ need object-based inheritance (e.g. Java) or prototype-based
inheritance (e.g. Javascript) to build large systems in this way.

For example, you can build very large systems in Erlang (passing messages
too!) without any kind of OO.

There are lots of examples of how functional languages can enforce interfaces
without classes, including Haskell.

~~~
gnaritas
Erlang processes are basically objects passing messages to each other. They
have state and behavior and communicate via message passing, they are objects.

~~~
straws
I think we're mostly in agreement, @dj-wonk. Objects are about bundling that
state and behavior, nothing more. _How_ they're created or instantiated is
secondary.

It's unnecessary to create classes for functionality when it's unnecessary to
create _objects_ for functionality. Here's an eloquent article on that
subject:

[http://me.veekun.com/blog/2013/03/03/the-controller-
pattern-...](http://me.veekun.com/blog/2013/03/03/the-controller-pattern-is-
awful-and-other-oo-heresy/)

------
hernan604
Use a better OO meta object system, ie. Moose.

And then you can build a class like LEGO, literally.

Because, it has Class and Roles, a class can extend another class. And a Role
can be built with multiple roles. And a class can be built with multiples
Roles.

Your OO is outdated if it doesnt implement classes, roles, types and at least
method modifiers.

And your language should allow first function class to allow functional
programming if you desire.

Perl has all that and comes installed in any unix/linux/mac.. try in your
terminal: $ perl -v

Every linux/unix/mac system runs perl. So your company is probably using perl
and they dont even know.

------
rcirka
I do agree the "noun" vs "verb" analogy when classes are taught are
horrible..actually the way classes are taught in general are just confusing.

Ultimately, classes are about code organization and reuse. Done properly, it
leads to a well maintained program. Functional programming...it still needs to
be organized somehow, whether you put them in classes or namespaces, the last
thing you want is spaghetti code. Now depending in the type of programming,
you may need to preserve state, which can be quite challenging in a purely
functional environment.

~~~
DanWaterworth
_Now depending in the type of programming, you may need to preserve state,
which can be quite challenging in a purely functional environment._

What makes you say that?

------
anaphor
[http://c2.com/cgi/wiki?ExpressionProblem](http://c2.com/cgi/wiki?ExpressionProblem)

~~~
3rd3
[http://mitpress.mit.edu/sicp/full-text/book/book-
Z-H-18.html...](http://mitpress.mit.edu/sicp/full-text/book/book-
Z-H-18.html#%_sec_2.5.2)

------
naiquevin
I can somewhat relate to the conversations in the article. While I admit that
I don't think I used OOP correctly, since I started using more functions
instead of classes (in Python, my primary language), I observed that it has
been more convenient to reuse and refactor existing code.

Another observation is that it's far easier to read someone else's code if
there is no mutation. For eg. I have enrolled for the proglang course[1] on
coursera and only yesterday I completed this weeks homework which involves
enhancing an already written game of Tetris in Ruby. Major part of the
assignment was about reading and understanding the provided code that uses OOP
and makes heavy use of mutation. It was quite difficult to understand what one
method does without having a picture of the current state of the object,
specially with side effecting methods that call other side effecting methods.
A few times I had to add print statements here and there to actually
understand which one is being when and how many times. While I could score
full marks in the end, I am still not confident about completely understanding
the code and have a feeling that if I ever need to work with it again, the
amount of time it will take to load up everything again into my mind's memory
will be equal to what it took for the first time.

Of course, one could only make a true comparison by studying an implementation
of Tetris written in FP style. But from my experience with reading and writing
code in Erlang (for production) and Racket, Clojure (as hobby) I find it
relatively easier to study functional code written by others.

[1]:
[https://www.coursera.org/course/proglang](https://www.coursera.org/course/proglang)

------
abalone
It's not like one paradigm is perfect for everything. But there's one thing
that the author wrote that stood out for me: writing a "utils" class for stuff
he doesn't "know where it really belongs."

That's one of the benefits of OOP: it forces you to think harder about where
things belong, and this really helps as codebases grow. A "utils" class is
often a sign that things could be better organized.

~~~
sagarm
I couldn't disagree more that thinking harder about where things belong is a
benefit of OOP: it's an entirely unnecessary tax caused by the requirement to
wrap every symbol in a class.

Another aspect of this is unnecessary effort expended on deciding if
A.operateson(B) or B.operateson(A). Sometimes, you want to Operate(A, B). If
your language doesn't allow that, you end up with operator.Operate(A, B).

Classes are not always the best organizational tool.

------
hawkharris
Will someone give me a few concrete, practical examples of using functional
programming in JavaScript?

I'm interested in this concept, but I'm not sure how to go about applying it
to my own work as a front-end web developer. Most of the resources online are
theoretical.

~~~
straws
Everyone using jQuery is benefitting from functional programming. Querying,
traversing, and filtering are based on `each` and `map`. It turns what was
formerly looping and saving values as temporary/instance variables into
declarative, collection-based compositions of functions.

Beyond that, Michael Fogus — big in the Clojure + Clojurescript community —
has Functional Javascript which explores functional concepts using Underscore:
[http://www.amazon.com/Functional-JavaScript-Introducing-
Prog...](http://www.amazon.com/Functional-JavaScript-Introducing-Programming-
Underscore-js/dp/1449360726/)

Marijn Haverbeke — a big Lisp hacker and the creator of Codemirror — has a
nice chapter in (the free!) Eloquent Javascript as well:
[http://eloquentjavascript.net/chapter6.html](http://eloquentjavascript.net/chapter6.html)

You should also check out how Javascript supports functional programming in
languages that compile to Javascript such as LiveScript or Elm.

[http://livescript.net/](http://livescript.net/) [http://elm-
lang.org/](http://elm-lang.org/)

------
Quarrelsome
:D. Why is anyone even considering FP vs OO programming a choice? I've used
functional patterns within OO before and I'm sure the opposite is possible.

Both have merit depending on the skill-set and staff available to you, scale
of project and existing infrastructure.

I was however very disappointed when the author bundled interfaces into the
mix as if it was the same as the rest of it. The interface enables you to
support many different types of behaviour and enables you to structure your
libraries in different ways. It's a different aspect from just classes
themselves.

Genuinely I don't think shit like this is healthy. Smacks of religion.

------
sholanozie
I might be a little late, but does anyone have any examples of simple CRUD web
applications written in a functional language? There seems to be a lot of meta
discussion about the suitability of functional programming for the web, but
not very many concrete examples. Thanks!

------
kul_
'Don’t be silly Jake. Where else are you going to put functions if you don’t
have classes?'

The core argument is more of philosophical in nature in terms of paradigms,
because from functional programming view a function just acts on a data
transforming it to other form. But in pure OO world (like Java) one can not
dare to think beyond objects so for them it has to be in a object.

------
neebz
In one of the initial posts of the series, OP mentions that functional
programming doesn't have app state. Can anyone point out more details on this?

I don't know if I am understanding it correctly but one of the reasons I
absolutely loved Backbone.js was that it kept state of our DOM. Is this
relevant to above discussion? because state surely looks pretty beneficial.

------
yeukhon
One can argue that Javascript's prototype is probably the future, not the
traditional class-based OOP.

~~~
dasil003
After nearly 20 years of Javascript there still is no consensus on how to
structure object-oriented systems. This is somewhat reminiscent of lisp's
failure to succeed in the marketplace because it's so flexible that no one can
agree and get behind enough core ideas to build a large ecosystem. Javascript
had the weight of the web behind it to force adoption, but that clearly has
been in spite of the OO model not because of it.

I'm not trying to hate on JS either, I think it was a bit of a small miracle
what Brendan Eich pulled off under the constraints he had and I'm thankful for
JS every day. However I think it's fair to say that something like Ruby's
metaclass and mixin system gives you 99% of the modeling power of advanced
prototypal modeling with 99% less confusion. Obviously there are ways it could
be done better and more explicitly than in Javascript's typeless object world,
but even then I don't see where the win is. We need better ways to manage
state and mutation in mainstream languages, not more ways to compose objects.

------
zamalek
> Don’t be silly Jake. Where else are you going to put functions if you don’t
> have classes?

I'm seeing where this is going: GoLang.

------
afshinmeh
+1, Nice to see your post man, keep it up! :)

------
mortyseinfeld
Ever since I started playing around with Java (or even earlier with C++)
having data co-mingled with functions has never felt right to me. It just
never seemed very extensible to me, especially in a language like Java. Even
in C# where you have extension methods, they are second class citizens.

But also the old question of where to put a method seems like unecessary
mental overhead for solving a problem. Use modules and just pass things in.
You could probably even put some syntactic sugar in the language so that you
could use the "object".method notation on the first argument passed in if you
really wanted to.

So someone give me clojure with optional typing, a Python-like syntax, and get
off my lawn!

~~~
jamii
> clojure with optional typing, a Python-like syntax

[http://julialang.org/](http://julialang.org/)

------
goggles99
IMO, most critics of FP or OOP do so because they lack a full understanding of
one or the other. Either paradigm can be applied incorrectly and cause plenty
of problems. Both have their merits and strong points. Each fits a different
type of project better than the other. Also different people tend to grasp or
appreciate one or the other better naturally depending on how their brains are
wired. More logical, abstract thinkers tend toward OOP while more right
brained people tend toward FP. There is nothing wrong with this. There is also
nothing wrong with learning the benefits of the "other side". If fact it is
quite beneficial.

some language designers see and fully appreciate the benefits of both. They
start putting class synonymous structures in FP languages or FP functionality
in OOP languages. This is the future of the mainstream (Ex: EcmaScript 6 has
classes/types, C# has Linq, closures, lambdas ETC).

~~~
callmecosmas
Haskell seems pretty left brained to me!

