
Which Programming Languages Are Functional? - ingve
http://blog.jenkster.com/2015/12/which-programming-languages-are-functional.html
======
rdtsc
Erlang currently is probably the most practically used functional language. It
has been in production for decades. It manages probably 50% of world's
smartphone <-> internet traffic. There are many database built on it, message
processing backends, handles hundreds of millions of connected device
(WhatsApp).

Yet most people forget it about when talking about "functional", and end up
comparing Python to Haskell basically. Maybe with F# thrown in there for good
measure.

Erlang has solid closure support, tail call elimination, immutable data
structures and variables, encourages using recursion instead of for loops, in
practice folds/maps are common constructs instead of an oddity etc (like say
in Python).

It even has an optional success typing system:

[http://learnyousomeerlang.com/dialyzer](http://learnyousomeerlang.com/dialyzer)

EDIT: Elixir is using Erlang's VM as well and almost everything about language
features above apply to it. If you don't want to give Erlang a try, check out
Elixir. It also has one of the friendliest communities for new-comers.

~~~
tombert
It's weird, I always kind of wondered why Erlang gets left out of the FP
discussions. It's not as dogmatic as Haskell or something, but functional-ness
is kind of its bread and butter.

~~~
rdtsc
I think the answer is that Erlang's creators are not academics and they sort
of never went out of their way to tout functional properties of their
language. Functional properties fell out of their requirements for simplicity,
fault tolerance, concurrency and reliability. In other words the goal of
Erlang was never to be functional but to be useful for fault tolerant
distributed systems.

Someone down the line probably mentioned to them "Hey, btw, did you know you
have a functional language?" And they probably shrugged and said "Oh, cool!"

I would guess Joe, Robert or Mike never went about reading papers on type
theory, thinking about meta-circular evaluators, or y combinators etc and said
"We need that, let's implement it!". Instead, they started with stuff like
"let's minimize state" so made state explicitly passed in. "Let's minimize
mutable state", so make data immutable. So then need recursion instead of for
loops, so let's think about tail call elimination. They played with Prolog so
language inherited the base Prolog syntax which has a functional taste to it,
that helped as well.

The same thing kind of happened with the actor paradigm. They never started
with a goal of implemented an actor / message passing programming paradigm. It
just fell out of fault isolation property. Someone later told them "Oh btw,
did you know you have implemented the actor paradigm?" and they probably
shrugged and said "Oh, cool!" and went back to doing whatever they were doing.

~~~
jarcane
I've talked with Robert at some length and listened to his talk on LFE, and
that's more or less the way of it, plus Robert himself was an old Lisp buff
from way back (hence Lisp-flavored Erlang). It was basically a combination of
"this is what we need to do what we want" and occasionally bits of "well of
course you do it that way".

That was actually how he described tail call elimination in his LFE talk: "of
course you have TCE/O, why the hell wouldn't you?"

Which was a refreshing perspective to me, considering how many programmers
_still_ seem to have been heavily indoctrinated to the idea that recursion is
automatically bad.

------
mightybyte
I'm not sure if I like this definition of "functional". Don't get me wrong,
I'm a Haskell guy and think Haskell is fantastic for production use, but this
definition of "functional" almost seems to rule out everything except Haskell.
Even if I try to maximize my Haskell fanboyism I can't with a straight face
choose a definition for "functional programming language" that of the today's
production-viable languages only includes Haskell. A definition that narrow
just isn't very useful. I don't have super strong opinions about how it should
be defined, but I tend to be drawn towards a more fuzzy definition. One that
seems attractive is: "functional programming languages are languages that
focus on functions as the basic unit of abstraction".

~~~
jacquesm
> I'm a Haskell guy

Don't ever be a 'programming language 'x' guy or girl'. Be yourself, know some
tools and skills and be prepared to switch those out for whatever works best
in that particular application. If you limit yourself to a certain programming
language, no matter how great it seems to be today you've built in your own
obsolescence.

Better to be a guy or a girl with x years of Haskell experience and a whole
bunch of other stuff besides.

~~~
draw_down
On the one hand I think that's reading too much into the phrase "Haskell guy",
but on the other I disagree in the sense that being a dilettante is no good
either. I think people should be "T-shaped", deep on one to a few
languages/platforms and some experience with many others. Spending a long time
with one language/platform will teach you deeper lessons over time than
switching every 6 months.

------
chvid
But why would you want a "functional programming" language when you can have a
modern multiparadigm language (JavaScript 6, Swift, Java 8, C#)?

The author seems to believe that no side effects is the key property of a
functional language. But for me most problems I deal with (user interface,
various business domains, integration with other systems over network etc.)
are filled with state and procedures. Sure you can deal with that in a purely
functional way but to me it is a bit like doing object-orientated programming
in C with macros and a lot of conventions. Why not simply use a programming
language with suitable primitives? In particular now that multiparadigm
languages are the most widely used in our industry.

~~~
murbard2
The value of functional programming is not in what it brings, it's in what it
takes away.

It is easier to reason about functional programs because they maintain certain
properties. These could be types, an absence of side effect, etc. This is the
point of the entire article.

You get none of those benefits if your "multi paradigm" language allows you to
break those guarantees.

For a multi paradigm language to derive benefits from functional programming,
it should allow developers to explicitly write guarantees that can be enforced
at compile time. This is a promising direction but, to my knowledge, it's not
available in any of the languages you mentioned.

~~~
asonge
I think this is exactly it.

If you had a multi-paradigm language, you'd need not only just some way to
break the rules easily and have that bubble up, you'd also want this rule-
breaking behavior to be exposed up the chain from any libraries. You'd also
have to enforce the benefits of immutability and such through social pressure
in order for users to see large parts of the benefits of side-effect
isolation.

A lot of the choices FP languages make that are less about side-effects (like
strict typing systems) are also often an all-or-none proposition. Optional
typing systems have very limited benefits if libraries aren't well-typed. The
static analyzers can only do so much.

~~~
dozzie
Oh, they can do surprisingly much. See how Erlang works with its optional
typespecs and dialyzer.

------
konne88
Why not just call the post: "Which Programming Languages are Pure?". What's
the point of redefining Functional Programming in a way that is at best
controversial?

~~~
cygx
A language can be purely functional, purely object-oriented, purely garbage-
collected, ...

The sole specifier 'pure' is meaningless without context...

------
seanwilson
Maybe I'm missing something, but what does implicit "this" arguments have to
do with functional programming?

> public String getName() { return this.name; }

> How would we purify this call? Well, this is the hidden input, so all we
> have to do is lift it up to an argument:

> public String getName(Person this) { return this.name; }

> Now getName is a pure function.

Isn't that just syntactic sugar? I would say that a real functional
programming language enforces that functions cannot have side effects, not
just that you have the ability to write such functions.

~~~
typon
How is it syntactic sugar? In the second version the function is now accessing
an argument rather than something outside its scope. That's pretty much the
definition of a pure function (besides having no side effects).

~~~
seanwilson
I would agree if getName was accessing a global variable but I don't see how
getName(person) is any more functional than person.getName(). OCaml features
objects with similar syntax for example:
[http://caml.inria.fr/pub/docs/manual-
ocaml/objectexamples.ht...](http://caml.inria.fr/pub/docs/manual-
ocaml/objectexamples.html)

~~~
typon
Because you can write person.getName() like this:

def getName():

. . this.setName('foo')

. . return this.name

There's nothing in principle preventing you from doing that in the
"functional" approach but if your data is immutable then you can't do it.

~~~
Someone

      def getName(person):
        person.setName('foo')
        return person.name
    

The problem, from a functional viewpoint, isn't the implicit argument, it is
the fact that you can write _setName_.

~~~
typon
Really? I thought implicit arguments were a strict no-no in functional
programming.

~~~
Someone
Implicit arguments are still arguments. It is just syntactic sugar, and I
think syntax changes cannot change a functional language into a non-functional
one.

------
pluma
Friendly reminder that all programming languages are just tools and it's not
productive to get worked up about which one is better than others or which
arbitrary label makes them more valuable.

Except PHP. PHP still sucks.

~~~
actsasbuffoon
I half agree. A hammer and a screwdriver are both just tools, but they're good
at different things. It's good to know about the variety of available tools
and the sorts of tasks they're good at.

~~~
pluma
Sure, but in many situations the tool you already have and understand trumps
the theoretically better suited tool you have to pick up at the hardware shop
and train your team to use.

The logical extreme would otherwise be to switch to a new tool whenever one
comes out that is objectively better at a given task and retrain every team
member that was previously using the old tool and rewrite the code that relies
on the old tool to use the new tool.

This balance is called pragmatism and it's more important in the real world
than the objective quality of tools you don't already have in your toolbelt.

------
DanielBMarkham
Standard reminder: please remember OCaml and F#.

OCaml may be a little obscure in the mainstream programming community, but
there are a ton of folks using F# out there.

~~~
drchickensalad
There are a ton of folks using f# out there? Would be nice to hear about them.

~~~
DanielBMarkham
Some testimonials:
[http://fsharp.org/testimonials/](http://fsharp.org/testimonials/)

Don't have time to do the full internet report for you, but if you're
interested, the way to tell is simply google various programming problems with
F# instead of C#.

Five years ago you could mostly find C# code and convert in your head. Now
about 80% of the time you can find what you're looking for in F#. That's a ton
of people.

------
typon
Its worth mentioning Elm when talking about making Javascript functional. To
me Elm is like the fun sibling in the Haskell family.

Signals are way easier to understand (for me personally) than monads. I just
wish it had better Javascript interop. Making ports for everything to talk to
an existing API (like three.js) is a deal breaker.

~~~
innocentoldguy
I feel the same way about Elm. I am curious regarding your comment about ports
though. I will admit, I haven't used ports for connecting with three.js, but I
have used them to tie in with existing Javascript code during our conversion
process and I thought they were pretty nice. What makes the combination of
three.js and Elm ports a problem. Is it just the number of them you have to
write, or is there some other pain point?

~~~
typon
Yea essentially its a matter of scale. three.js is not a small library by any
means and I'm using a lot of the features. I tries to
use:[https://github.com/seliopou/elm-d3](https://github.com/seliopou/elm-d3)

as my guide. I think it just comes down to "I don't have time to rewrite
bindings for an entire API right now" because ports require you to really
understand what's going on. There's no shotgun method of converting an entire
API.

Another reason I gave up is that Purescript does have three.js bindings.

~~~
innocentoldguy
Yeah, that makes sense. Thank you for the information.

------
lmm
"Functional" is just a word, and I don't think it's particularly helpful to
declare "language X is not functional". map/reduce, lambda, types, and control
of effects are all valuable, and no single one absolutely characterizes
functional vs. not.

------
MichaelGG
Hmm I've always felt the true nature of FP is having higher order functions.
That's what starts to make things fun. If you need a long keyword to introduce
a lambda, or if partially applying and passing functions around is ugly then
you lose a lot of the benefits and cannot truly embrace HOFs. In a typed
language, no generics or other type limitations puts a major cramp on this
too.

Yeah this means C function pointers allow some FP. Except they're clunky and
have a hard time bundling info with them (no closures). This makes HOFs sort
of a pain.

Controlling state, or at least immutability, is just a generally good idea.
Even in rather non-FP code I wish I had easy immutability.

------
mark_l_watson
I take issue with the critique of Java not being functional. Old style Java
uses mutable objects and yes code is not functional. However, it is now (a
good) standard) practice to make immutable objects.

------
pklausler
IMO the essence of programming is the definition of abstract interfaces and
the composition of components within a context according to those interfaces.
The essence of _functional_ programming is the composition of components that
create their results without modifying their execution context in any way that
could be detected by a failure of referential transparency.

With that definition, functional programming is a style, not a class of
languages. An assembly routine that computes a cosine is a functional program.
I typically write C/C++ code in a functional style, constructing and returning
new data structures rather than modifying arguments in place, because it's so
much easier to test, use in parallel code, and reuse later.

So I don't think that strong typing, higher kinds, higher order functions,
algebraic types, pattern matching, anonymous closures, polymorphism, or
garbage collection, e.g., are necessary to functional programming (although
they're all wonderful and Haskell seems to have collected just the right mix
of features together into a language that I love using whenever I can). It's
about whether or not your components have interfaces that are like
mathematical functions.

------
tripa
> [Perl] has a magic argument, $_, which means something like, "the return
> value of the previous call".

What?!

~~~
Mithaldu
I don't know whether you recognize this as wrong, or are surprised at the
thought of such a thing (which doesn't actually exist like that).

In any case, i've suggested a correction here:
[http://blog.jenkster.com/2015/12/which-programming-
languages...](http://blog.jenkster.com/2015/12/which-programming-languages-
are-functional.html#comment-2432154798)

~~~
__david__
$_ isn't really global though:

    
    
        perl -e 'for (1,2,3,4) { for (5,6) { print "  $_\n" } print "$_\n" }'

~~~
Mithaldu
It may look like it is not in loop constructs, but it is. `for` and friends
just apply `local` scoping to `$_` internally.

------
Grue3
> Lisp is the oldest functional programming language, and the oldest dynamic
> language.

But Lisp is not a functional language! It's based on the concept of CONS which
is mutable and allows for shared structure. Lisp is #1 language that everyone
thinks is functional when it's actually not. I'm surprised this article out of
all made this mistake.

~~~
davexunit
Well, Lisp is based on the Lambda calculus, which is what we've come to know
as the basis for functional programming. Things are much more overtly
functional when you look at certain members of the Lisp family such as Scheme.

------
canjobear
Would Scheme count as a functional programming language by this definition?

On one hand, the idiomatic emphasis on tail calls (supported by tail call
optimization in the language) makes it easy to avoid stateful for and while
loops.

On the other hand, most nontrivial code has plenty of `set!`s.

~~~
davexunit
Scheme is a multi-paradigm programming language. Functional is one such
paradigm that it supports. It also supports imperative, object-oriented,
relational, and probably others that I don't even know about.

In Scheme, one can build functional systems on top of imperative building
blocks. For example, memoization can be implemented as a higher-order
procedure that uses a mutable hash table as the cache. A memoized function is
still pure, despite the use of local state, because it retains the crucial
property of referential transparency.

Anyway, I guess my point is that the use of 'set!' or 'hash-table-set!' or
whatever else doesn't mean that a program is no longer using the functional
paradigm. To quote from a Clojure web page[0], "if a pure function mutates
some local data in order to produce an immutable return value, is that ok?"

[0] [http://clojure.org/transients](http://clojure.org/transients)

------
chchrutuch
I can find points I disagree with on every language here, but this author
seems to have quite the bias against Java, so I'll make a few
counterarguments.

"If you write Java code that has no side-effects, that doesn't read or change
the local object's state, you'll be called a Bad Programmer."

No you won't.

"Java thinks that localised side-effects are cornerstone of good code"

Java doesn't think anything. It's a tool.

"Unfortunately, in practice Java doesn't just try to encapsulate side-effects;
it mandates them"

No, it doesn't.

I will say I've worked in Java shops and seen the language used in this way.
I've also worked in Java shops and seen people who have read and internalized
the messages in Effective Java, especially with regard to handling state, and
the codebase looked nothing like what is described in this article. I
recommend the author take some time to read that book and keep reminding
himself that Java is a generalized tool that can be used in many ways.

------
im_down_w_otp
All the ones that aren't dysfunctional.

~~~
AnimalMuppet
Argh. _One second_ after clicking downvote, I got the joke...

~~~
im_down_w_otp
Jerk :-p

