
Programming without objects - wkornewald
http://www.falkoriemenschneider.de/a__2014-09-17__Programming-without-objects.html
======
chton
What this article seems to miss is part of the raison d'être of Object
Oriented Programming. It's not just about how you encapsulate state and how
you act on that state. Forget the exact way the type system works, or what
extension methods are, or even what polymorphism is.

The big advantage of OO is that it acts as a distillation of how humans think.
We're accustomed to thinking in terms of 'things that do stuff'. What OO
provides is essentially a skeuomorphic element to your code, where your basic
units have some resemblance to real items and concepts. This makes it a lot
easier to reason about large codebases, and makes them easier to document (in
theory). It means the most important thing you need to understand how a piece
of business logic works is knowledge of the business. You don't need to know
anything about the data, or how the application is composed in order to comply
with the needed use case. If you know the concepts and their behaviour in the
problem domain, you will be able to make sense of how the code is written.

FP has its place, as does procedural code, but advocating either of them as a
complete replacement for OO is short-sighted. Claiming FP is a solution to
OO's shortcomings is too. Each has its place. If anything, we should be
working towards next-generation models, that combine the advantages of both
and mitigate the downsides of both.

~~~
dragonwriter
> The big advantage of OO is that it acts as a distillation of how humans
> think.

Honestly, while I think OO programming in the broadest sense does that, I
think class-oriented OOP (what the article mostly focusses on) languages,
particularly statically-typed class-oriented languages in the C++/Java lineage
--don't do a great job of either supporting that intuition or facilitating
applying it intuition to the construction of correct, maintainable computer
programs. They aren't _useless_ in that respect--there is a reason why they
flourished--but there's also a reason that after them an important programming
paradigm for several decades, and a dominant one since at least the late
1980s, there's a whole lot of moves away from traditional class-oriented OOP
in newer languages.

I think that we're seeing a model--which is mostly viewed as being within the
FP tradition but which has learned a lot from OOP languages and supports a lot
of OO thinking--emerge (and that this article points to a lot of its elements)
that provides a framework that better matches the intuition than class-
oriented OOP does, _while also_ better supporting building correct,
maintainable, easy-to-reason-about systems.

~~~
rockshassa
>don't do a great job of either supporting that intuition or facilitating
applying it intuition to the construction of correct, maintainable computer
programs

My first thought is that this is dependent on implementation. It is possible
to write classes in a way that aligns with intuition, but it is sometimes hard
to do that, and even if you're great at OOP it is hard to do consistently. I
think the Smalltalk message-sending way of thinking has huge value because it
is easy to reason with, and facilitates this intuition.

That said, I do see tremendous value in FP, and I'm encouraged by the elements
of FP that I've seen popping up in Swift. So I guess ultimately I do agree
with you. I'd like to see OOP continue to flourish, but borrow elements from
the Functional style that make it very difficult to write fragile code.

~~~
chton
I'm exactly in your camp. I would love to see more functional influence in OO,
and more careful thought about what to use at what time.

------
millstone
This article, like many that cheer functional programming, falls into a
certain cognitive bias, that prevents it from seeing what OO is good at.

Alan Kay wrote _" The key in making great and growable systems is much more to
design how its modules communicate rather than what their internal properties
and behaviors should be."_

To start to see what this means, consider the annoying String / Data.Text
split in Haskell. String is very much in the "leave data alone" mindset,
baring its guts as a [Char]. Now you're stuck: you can't change its
representation, you can't easily introduce Unicode, etc. This proved to be so
rigid that an entirely new string type had to be introduced, and we're still
dealing with the fallout.

Great and growable systems! The large scale structure of our software,
decomposed into modules, not just at a moment frozen in time, but in the
future as well. We are tasked with thinking about relationships and
communication.

So here is how "the better way" is introduced:

> Data is immutable, and any complex data structure...

There's that insidious FP bias: to immediately dive into data structures, to
view all programs as a self-contained data transformation. So reductionist!
It's completely focused on those "internal properties and behaviors" that we
were warned about above.

I would end here, but I just couldn't pass this up:

> To come up with a better solution [for dispatching], Haskell and Clojure
> take very different approaches, but both excel what any OO programmer is
> commonly used to.

"Any OO programmer?" No way! OO as realized in truly dynamic languages exposes
not just a fixed dispatch mechanism, but the machinery of dispatch itself,
i.e. a metaobject protocol:

 _"...there are not only classes for workaday tools, such as UI widgets, but
there are also classes that represent the metastructure of the system itself.
How are instances themselves made? What is a variable really? Can we easily
install a very different notion of inheritance? Can we decide that prototypes
are going to work better for us than classes, and move to a prototype-based
design?"_

This is far richer than the anemic switch-style dispatch that Haskell's guards
and pattern matching provide. For example, try modifying a Haskell program to
print a log every time a string is made. You can't!

I'm not familiar with Clojure but I'll bet its object model has its roots in
CLOS. Whether or not you call it "object oriented," CLOS is solidly in the
spirit of having a dynamic meta-structure.

~~~
colanderman
I think you and the author have posed a false dichotomy.

I avoid "traditional" OO in my own work for the some of the same reasons the
author points out; not least of which that traditional classes are a kitchen
sink.

But many of the _ideas_ of OO; notably extensionality (what the author
incorrectly calls intensionality), I could never do without. I agree with you,
that exposing the innards of my data structures is a crime: not only do I lose
control over their construction and use (including defining equality), but I'm
restricted from ever modifying the structure.

But nothing in FP prevents hiding structure. You can see it all the time in
OCaml: a module signature will declare an opaque, possibly parametric, type,
as well as a set of operators over that type. _The internal structure of that
type is never exposed._ All creation and use, and ideally comparisons (though
it is unfortunately not enforced in OCaml) must go through the module's API.

(Module signatures, it should be noted, may be shared by multiple
implementations, permitting compile-time dispatch.)

Yet while maintaining opacity, I am free to dispense with the excess baggage
an OO class entails: run-time dispatch; a single "self" (i.e. the "friend"
problem); that abomination known as inheritance; all these things I need no
longer worry about, and my code can be cleaner and more efficient.

~~~
millstone
The module system in OCaml sounds very nice (and we all know what the "O"
for!). But there's still a bias towards a sort of static-ness in FP. For
example, the use of abstract data types where a Java programmer may use a
class hierarchy. Clients cannot extend an ADT: I can't make my own List in
Haskell and pass it off to a function.

Regarding the OO "excess baggage," I would respond that what is "excess"
depends on the nature of the system. I can understand dismissing that stuff
when your program is self-contained. When the only code at play is your own,
when you can statically enumerate every type, function call site, etc, it may
be hard to see the value in those features.

My project is a shared library, and so is dynamically linked with code written
by other teams, perhaps years ago, or even yet-to-written. The system is thus
not my program in isolation, but an intimate collaboration between my
component and client components. Runtime dispatch, inheritance, reflection,
and even occasional mucking with meta-objects are the tools we use to
cooperate. This is a type of extensibility that Haskell doesn't even try to
support. I don't know about OCaml here.

(Alan Kay called this the "negotiation and strategy from the object’s point of
view.")

~~~
dragonwriter
In the same way that many recommend programming to interfaces rather than
concrete classes in static OO languages, programming to typeclasses rather
than concrete types (when you can't avoid that kind of dependency and write
completely generic code) is an important recommendation in Haskell.

------
nbevans
Every OOP developer is on a journey, they just don't know it. Some of them
will never make it. But some will reach a point of realisation where writing
well-designed software comes naturally to them because they've inadvertently
stumbled upon the core concepts of functional programming. It then requires
them to realise that what they've found is just FP and then requires a further
minor step to actually learn a more appropriate language. Once this developer
makes that jump he reaches a new plain of development happiness and a feeling
of power over OOP practicers because his level of productivity has magnified
by about 3x. Enabling themselves to allocate brain power to more important
issues. That's just called progress though.

Having said that, I dislike articles like this because they shout too loudly.
Just use a proper hybrid OO-FP (ala F# / Scala etc) language and be done with
it. These languages are designed for business productivity - not academic box
ticking. Everybody happy.

~~~
mpweiher
What arrogant hogwash.

I was exposed to functional programming my first year at university (it was
used in the introductory courses) and quickly noticed that contrary to the
hype (similar to yours), functional programs tended to be more bloated with
trying to work around limitations of the less expressive programming
model/language and not particularly more robust.

That doesn't mean certain aspects can't be nice to have ('let' is kinda nice),
but even that is mostly for programming-in-the-small.

Your unsubstantiated claim of 3x productivity increase is, er, "interesting".

~~~
nbevans
Don't worry, you haven't reached the right level of experience yet. You'll get
there, though you have some attitude problems to overcome first like most
young programmers.

~~~
frowaway001
I wonder why the parent comment is downvoted. He's dead on.

~~~
AnimalMuppet
nbevans made a post dripping with condescension and arrogance. mpweiher
pointed that out. nbevans replied with... more arrogance and condescension.
And you wonder why he got downvoted?

He's also (at least partly) wrong, and so are you. FP has it's place. But what
people like you and nbevans never seem to realize is that the rest of the
programming world is neither stupid nor ignorant. Yes, there are better ways
of working than the ways that we work. Yes, we don't know all of those ways,
even though some people do. But _that 's true for you, too._ There are people
who are ignorant about FP. There are also people who are both smarter than you
and more experienced than you, who do not use FP _for good reasons._ But you
and nbevans arrogantly tell us that once we learn enough, we'll see that
you're right. Your inexcusable assumption that everyone who disagrees with you
has to be both wrong and ignorant is why you're getting downvoted.

~~~
nbevans
OOP people are too sensitive!

I still use OOP just not as much as I have another tool in the box (FP) that
is sometimes (often?) more appropriate.

------
DEADB17
I think that contrasting OOP with FP brings too many implicit assumptions to
the discussion. The value of immutability, for example, seems to be orthogonal
to the technique used to structure a computation and is more closely related
to the problem to be solved.

In my opinion OO languages popularized the idea of having separate internal
and external representations by providing language constructs that made it
practical. But they also promoted the coupling of data with the methods to
manipulate it -- this is not a necessary characteristic of OO but it is common
in popular implementations. This association of data and methods turned out to
be a limiting factor in the face of changing (maybe unknown) requirements. The
flexibility of more dynamic run-times that allow to mutate this relationship
during execution (monkey patching) was not a satisfactory solution as it
inhibits static analysis. In my experience this is generally the main
motivation when looking into alternatives.

Modeling computations as dynamic data threaded through a series of statically
defined transformation seems like a sensible solution to the issue. It also
brings additional benefits (e.g.: easier unit testing) and makes some
constructs unnecessary (e.g.: implementation inheritance). This approach is
commonly used in FP languages and I think is the main reason why they are
contrasted as alternatives.

Since it's not always possible or desirable to re-write a project, sometimes
the technique is dismissed because it is confused with the languages that
favor it. The relative lack of resources explaining how to use FP techniques
in OO languages doesn't help either.

Separating the techniques from the implementations has practical value and it
allows evolving existing bodies of work.

------
programminggeek
One reason I think Objects and classes get a bad rap is the mutability and
lack of intentionality that comes from getters and setters.

When the innards basically are laid bare by setters, you lose a lot of control
of state and flow and object lifecycle that really hurts good design.

Looking at objects that need some kind of validation run on them, in many
cases the validations aren't run every mutation but rather on some kind of
save or persistence event, long after the validity of the object should have
been checked.

OO can lead to great design, and there are some great techniques in FP, but
average software written with either is probably terrible.

~~~
chvid
The point of getters and setters (rather than having public fields) have
always been to control how an object's users access the internals of the
object and how state is changed if at all. The idea that you should write them
as a ritual or a boilerplate is just bananas.

In this discussion of major programming paradigms it is important to realise a
couple of things: That this is very old discussion and that there are no clear
winner. The productivity and usefulness of a language is ultimately shown when
it is put to the test of big practical development projects. Currently
business is dominated by the object-orientated languages (C#, Java,
JavaScript, Objective-C, C++ etc.) and probably for good reason: The dominant
problems that software spends its line count on seems to be things like user
interface and interface to other "platforms/paradigms" such as relational
databases, web services or data files. Object-orientation have arguably shown
itself to solve these problems well.

------
zak_mc_kracken
That's a pretty underwhelming case against objects, and equally underwhelming
in favor of functional programming.

~~~
AnimalMuppet
Agreed. The problem is, what you're asking him to do is really hard.

Why was OOP considered a good idea? Before OOP, programs were just structs and
functions that operated on them. But as programs got larger, that approach
broke down. Someone on a team of programmers would create an instance of a
struct, but would initialize it in a way that some function (written by a
different programmer) would regard the struct as having an inconsistent state.
Or some function, which was meant to only be a helper function for other
functions that were the API, would be called directly by some ignorant and/or
lazy programmer. The result was increasing chaos as programs got larger.

OOP was viewed as the fix to that kind of problem. It was somewhat successful
as a fix, too.

So the problem with most of these pro-FP articles is that they show you small
examples. But the pre-OOP style worked fine on the small examples, too. In
fact, almost any style works on small examples.

And showing that I can write the same thing in fewer lines by using FP isn't
the answer, either. It's like saying that your algorithm has a smaller scaling
constant than mine does. That's fine, but _first_ let's talk about whether
your algorithm is O(n^2) and mine is O(n log n). That is, if your approach
scales worse than mine for large problems, then showing me that your way is
more efficient for small problems completely misses the point.

But to build a convincing case for that, you'd have to do something like
having a team of competent OOP programmers write a large-ish program (say, 10
person-years of work), and have a team of competent FP programmers write the
same thing, and report on the results. Oh, yeah, and have the teams maintain
the programs for five years. _That_ could be a convincing paper, because it
would address the actual issues.

~~~
DanielBMarkham
This is the argument I would use against FP. It's an open question -- to some
degree.

Couple of notes. First, have you seen what real-world large-scale OO looks
like? Dude, it ain't pretty. We're swimming in projects that are staffed at
10x or 20x the number of coders they probably really need, and a lot of time
is spent in support activities.

Second, maybe the real question here isn't one of scale, it's how the model
falls apart under strain. A good encapsulated system should offer you a bit
more defensive programming protection than an FP one. But if you're using
compsable executables, while testing at the O/S level? Meh.

I know why we went to OO. And let's not forget OOAD, a beautiful way of
joining analysis and design about the problem with the solution itself. I'm of
a mind that OOAD might live on even once the world moves to mostly FP.

I think maybe that OOP was a stopgap position; a place to try to build a
firewall against the encroaching overstaffing associated with Mythical Man-
Month management. Now that programming is a commodity, however, we're seeing
diminishing returns. Don't know.

I am much less convinced of the "We need OO for large scale projects" argument
now than I was two years ago. I expect this trend to continue. We might be
able to solve the scaling problem with things like cyclomatic complexity
limits on executables, or DSL standards. Not sure of the answer here, but I
think we're going to find out.

~~~
lifeisstillgood
Programming is a commodity? In a generation I hope so - now?

And to be fair I think that OoP and FP are the wrong paradigms for handling
bad management of a large project. Open source methodologies are eating into
that (I have just started at a major Fortune 500 with effectively a huge open
source project inside it's employees) and even without that a good focus on
risk management will help

In short, talking about your problems and taking early steps to resolve them
will do more to fix a project than moving from OoP to fp.

------
mmiliauskas
All this FP revolt kind of start to remind me Whitehead's and Russell's
attempt to invent a formal system which would be paradox free...

~~~
eli_gottlieb
Martin-Lof Type Theory doesn't actually have any paradoxes in it.

~~~
tel
Well, it does—Girard found one. It also has lots of troubles with equality.

------
jimmaswell
The Equality point focuses on Java's issue with string equality but doesn't
mention that other OO languages let you overload == in order to provide the
type of equality you want, such as C#.

------
djur
The OO being addressed here is the statically-typed variant made popular by
C++ and its followers. Many of the points made (classes being types,
interfaces, type variables, etc.) do not apply to dynamic OO languages in the
Smalltalk vein.

There's even a footnote referencing Kay-style message passing OOP, but it
suggests that message passing languages are not "available today in the
mainstream". There are several major OO languages today based on message
passing, so I don't know how that claim is justified.

~~~
jimbokun
Notably Ruby and Objective C.

~~~
tonysuper
Objective-C is probably the saddest story of any programming language.

Absolutely fantastic libraries, incredibly easy to write high-level
abstractions over very low-level C code, and completely useless outside of one
platform.

I wish projects like GNUStep would get more love.

------
DanielBMarkham
I've been taking a similar journey in my blog, where I talk about the
difference in _thinking_ in FP and OOP. ( [http://tiny-giant-
books.com/blog/real-world-f-programming-pa...](http://tiny-giant-
books.com/blog/real-world-f-programming-part-2-types/) ) I use C# and F#.

I was at a Code Camp a few years back where one of the speakers was
introducing F#. He was looking at a map function or some such on the screen
and muttered something like "Well, you know, you can see the C# this compiles
down to. It's all just a while statement. So there's really not much here."

At the time, I was concerned that he missed the point.

It's tough moving from 20 years or so in OOP over to FP. Whatever you do, you
don't want to give folks the impression that you're just a fanboy for some new
latest whizbang tech eye candy. Yet it's important to convey that there's
something different going on here too. Yes, it's all just ones and zeroes, but
while true, that observation is not important.

You reach a point where you say "You know, an object is just a function with
closures. A function is just an object. It's all the same"

Yeah, it's all the same. But it's not. Just like that C# guy, you understand
that at the end of the day all we have is state machines, but you missed the
part about how thinking about things in various ways is better or worse for
creating certain types of solutions.

This author tries to make the case for FP by taking apart the wild and wooly
world OOP has become, where you're not just coding a solution, you're creating
a extension to the type system for your very own stuff. Very cool stuff. But I
think once you go down that path, you're arguing the wrong thing.

Thinking about problems in pure FP leads to small, composable functions. These
group into small, composable executables. These can be scheduled and pipelined
across many different O/Ses, networks, and machines. This land of unix-like
coding has a multi-decade track record and solid tools that any administrator
can use and understand. Thinking in terms of object graphs almost inevitably
leads to very complex and nuanced solutions, with lots of hidden dependencies,
that only work under certain conditions, and where you may need an expert or
two around to help out when things go wrong.

FP is not nirvana. Nothing is. But it is very refreshing to have it solve the
same old problems in a much less complex way. I don't see any future except
for pure FP -- although my money says it might be 20-30 years until the
industry catches on. Now's a good time to get an early start!

~~~
millstone
I wonder how much of the "small, composable functions" nature of FP can be
attributed to the types of programs you write in functional languages, and the
types that you don't.

Unix-like tools such as grep (or ghc) are very much like pure functions:
programs that accept input, and produce an output data. It's not surprising
that they lend themselves well to FP techniques. But other programs, like the
web browser I'm using now, have lots of "inputs" and "outputs." There's many
knobs that can be turned, and output goes to screen, disk, network, other
programs...

I suspect these programs have a larger essential "hairiness." grep only has to
search text. But Find in a text editor has to show a progress bar, cancel
button, intermediate result count, etc. These features are intimately
intertwined with the algorithm itself, and that's often hard in FP. Try
writing a Haskell function that does text find/replace with live progress
reporting. It's not easy, and it ends up looking a bit like Java.

Note that the land of unix-like coding isn't very good at UIs either!

~~~
DanielBMarkham
Great question!

I'm finding that FP tends to shave the "hairiness" off things, many times in
ways I had not anticipated.

UIs are a completely different animal. I've done a lot of UI stuff in the OO
world in the past, and some in C/C++. The couple of apps I wrote in F#? I
ended up doing a kind of functional-reactive thing. I really like the FRP
paradigm for UI work, but I need a lot more experience to say anything useful
about it. One of the things I started doing was setting up derived types from
Win32 objects. Looking back, with that kind of attitude I was probably headed
down the wrong road.

A web browser, eh? that's very interesting. One of my projects does some
screen scraping. I found that scraping could be done in a pipeline -- get the
page, score the sections, run some rules, do some QA, etc. Each stage did some
work and left things for the next stage. But, of course, I was processing many
pages at the same time. Rendering one page for a user sitting in front of a
screen is a completely different scenario. I think.

Writing a pure FP browser would be a hoot.

------
zvrba
First I'll comment on footnote #1 in the text:

> "Here, I refer to OO concepts as available today in the mainstream.
> Initially, objects were planned to be more like autonomous cells that
> exchange messages, very similar to what the Actor model provides. [...] "

There is _absolutely nothing_ in modern OO languages (Java, C++, C#)
preventing you to design systems as if object instances were actor instances
with method invocation corresponding to message passing. His text criticizes
therefore the wide-spread (mis)understanding of OO, _including his own_.

Second, he equates "concurrency" with "shared memory, mutation-based
concurrency". Well, there's message-passing too, and it works perfectly fine
in OO programs.

\---

His problems with OO stem _exactly_ from the reductionist approach of
OO=encapsulation+polymorphism. If you make the object ~ actor conceptual jump,
you'll suddenly get a new perspective on how to use objects in program design.

(In the actor model, actors do _not_ share state and are conceptually
immutable. However, there's a "become" operation which the actor can use to
change its future behavior on incoming messages, in effect giving you means to
implement a memory cell -- not that you'd really want to do it.)

------
pjmlp
Another article that fails to see mainstream FP languages are actually multi-
paradigm.

First of all the article fails in a few points regarding OO programing.

Single dispatch is not a synonym for OOP, Common Lisp, Dylan, Julia are all
examples of languages with multiple dispatch.

Second, unless Erlang, Miranda, Caml Light, Standard ML, Scheme, pure Lisp are
being used as examples of FP, most certanly the language will have support for
some type of OOP.

The only difference is if the language is functional first or object first,
concerning which paradigm is usually the one to reach to first.

I guess we need to have a few blog posts with UML examples mapped to OCaml,
F#, Clojure, Common Lisp, Haskell.

At very least it would make these comparison posts focus pure FP languages, I
guess.

------
SoftwareMaven
It does not follow that a poor OO implementation in one language (Java) means
all OO is poor (and, in fact, the article agrees with this when it decides
Haskell is an ok way to do OO).

Yes, _every_ concept in OO can be accomplished without OO and, in many cases,
are reduced implementations of more general concepts, so polymorphism is a
simplified kind of type-based function dispatch. The power comes in the
consistency and in the simplification itself. Instead of having multiple
implementations of polymorphism that have to be developed and managed by
multiple teams, you have one that is developed and managed by the compiler and
understood by everybody who writes the language.

Java was very opinionated about certain aspects of OO, missing the mark of why
OO is valuable in some places. It also made some very poor decisions in the
implementation of its VM (int/Integer, ==/.equals) that made things worse.
Finally, living in the Kingdom of Nouns[1] just sucks. But this feels like a
lispers rant against Java more than a true critique of object oriented
programming.

1\. [http://steve-yegge.blogspot.com/2006/03/execution-in-
kingdom...](http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-
nouns.html)

------
zak_mc_kracken
One thing where I think OOP is particularly elegant compared to FP is
refinement.

Say I have a class with five methods on it. I realize I need to create a new
class that has almost the same behavior: I want to reuse four of these five
methods but the fifth one is different. This is a very common problem.

This is trivial to do in OOP: create a base class, override the method whose
behavior you need to change, done.

I've never found an FP language that makes this as elegant.

------
scscsc
It seems to me that everyone is missing the point behind object-orientation.

Object-orientation sucks for everything except user interfaces. If you don't
believe me, try writing a UI library without objects and see what happens. UI
is OOP's best (and only compelling) use case.

For all other algorithms classical data structures/ADTs are much better. If
you don't believe me, try writing an OOP compiler.

~~~
shangxiao
I write a lot of interactive SVG based user interfaces in JavaScript and
always default to using "classes" to represent composable elements in the UI.
I've recently been wondering about whether writing UI code with a functional
language would even be possible. When it comes to data manipulation though I
will _always_ use underscore.

~~~
scscsc
My thesis is that by trying to write functional/imperative UI code you will
create your own ad-hoc OOP system.

------
colanderman
I think you've confused "intensional" and "extensional".

("Intensional" means "identity determined by structure"; "extensional" means
"identity determined by behavior". You seem to use them in the exact opposite
sense.)

------
Kiro
I'm not a good programmer but I've never understood OOP. For me it feels much
more logical to work with pure functions with consistent output based on
input. At work I'm told to use more OO but it feels really enforced and not
intuitive at all. The only time it makes sense for me is in game development
where you have many entities of the same type that all have their own states.

I feel I should learn OO properly and maybe try Java or something where you
have to code OO. On the other hand I also feel I should go with my gut
feeling, forget about OO and just learn FP instead. It feels wrong though to
"skip" OOP seeing most serious programmers seem to have a background in it.
What do you think?

~~~
jimbokun
The secret about real world Java applications is they tend not to be very
object oriented at all, in the way OOP is taught in textbooks.

Interfaces are very heavily used, along with dependency injection (boy, do
Java programmers love their dependency injection).

Inheritance is now widely discouraged. "Java Beans" are everywhere, which are
glorified structs breaking every single rule of encapsulation.

Java runs fast, is garbage collected, has great support for multithreading,
great Unicode support, and many other advantages. But it's certainly not very
object oriented, especially in the Alan Kay sense.

------
jaunkst
What does large scale applications look like in Haskell or Cloujour? Why can't
both co-exist? Can we have a humanized OO language that compiles to something
immutable?

------
recursive
Pattern matching seems very limited compared to subclass-based method
dispatch. Using pattern matching requires you to know every case in advance.
But most "standard" OO languages allow subclasses to be created without
touching the original base class. This allows injecting new behavior into
existing systems. AFAIK, pattern matching alone can't do this.

~~~
rapala
That's because it is limited. It's not meant to be a way to provide
polymorphism. One of the things that it does provide is the knowledge of every
possible case and a reminder from the compiler if you missed one. This is not
possible in many OO language.

FP languages have different ways to inject new behavior. You could for example
define a function a -> (a -> Int) -> Int. This function now works for any type
for which you can also provide the "interface" a -> Int.

~~~
gizmo686
You could also define a typeclass Intable, and a function (Intable a) => a ->
Int, which will work on any type that implements Intable.

------
CmonDev
The whole OOP vs FP argument is like food vs drinks argument. I am empowered
and capable of using both. What is the problem?

