Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
What is a functional programming language? (enfranchisedmind.com)
50 points by bendmorris on Jan 14, 2011 | hide | past | favorite | 26 comments


I think we would be remiss to mention that fundamentally the Lambda Calculus and Turing Machines are mathematically equivalent, as proved in the Church-Turing Thesis (http://en.wikipedia.org/wiki/Church%E2%80%93Turing_thesis ).

And while it is true that there are functional features that are unsupported in the basic syntax of imperative languages, you can still do equivalent computation, and after all "Whoever does not understand LISP is doomed to reinvent it" :P


54. Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.

—Alan Perlis, Epigrams on Programming


ha, that's great.

I have to say learning about Lisp and the Lambda Calculus renewed my interest in computation and programming back in university. I really find Turing machines quite dull.

Perhaps i did not adequately disclaim my statements though. Having to hack a LISP into your imperative language is neither easy, maintainable or recommended. Just cause you can do it, doesn't mean you should ;)

The rest of the epigrams:

http://www-pu.informatik.uni-tuebingen.de/users/klaeren/epig...


The lambda calculus admits no notion of mutability, while the Turing machine is all about mutating locations on a tape. So I would argue that functional programming is really about immutability.

A language is a functional programming language if its standard library includes and is written specifically for immutable data structures. Mutable data structures, if they exist, are second class citizens.

Whether there is an object system is completely orthogonal. Whether there are first-class functions is also completely orthogonal.


This is a very odd definition; it would exclude many languages typically considered "functional", such as Haskell.


Haskell's core data structures are immutable (ADTs, tuples, records, etc.) -- what do you mean?


Let me clarify that a bit further -- I'm not excluding languages which offer mutable data structures, even in standard libraries. I'm simply excluding languages where the use of these data structures are de-emphasized.

This isn't a precise scientific definition of a functional language, but one that seems to quite cleanly differentiate languages like Haskell and ML from languages like Javascript and C#, all of which have first-class functions.


Your definition also clearly differentiate between "Common Lisp as is taught on universities" and "Common Lisp as it's actually used", which might or might not be a good sign.


I'm assuming anything in the "base" library counts as core; in it, you have pointer/buffer manipulation (Foreign.* ), synchronized mutable containers (Control.Concurrent.* ), ST (Control.Monad.ST), and various mutable containers (IORef, STRef, HashTable).

It's true that Haskell has many immutable types, but that's true of almost any language. Haskell is no more immutable than Java or C#, and certainly nothing like truly immutable languages such as Coq or Agda.


Stuff in the sinbin (or the 'IO monad') are definitely second-class citizens in the language and community. And not all of those examples are mutable - the whole point of ST is that it's safe for it to be implemented using mutation while still being treated as having immutable semantics, this doesn't mean the compiler or library actually use mutation in ST code.


> Stuff in the sinbin (or the 'IO monad') are definitely second-class citizens in the language and community.

[citation needed]

I've never noticed any particular dislike for IO in the language or community, excepting cases where it was obviously not appropriate. A general feeling that IO is best minimized is common throughout all languages and experienced communities.

> the whole point of ST is that it's safe for it to be implemented using mutation while still being treated as having immutable semantics, this doesn't mean the compiler or library actually use mutation in ST code.

I disagree; ST would be practically useless if it could not be relied upon to use mutation. Its purpose is to signal "this code uses safe mutation", not "this code is immutable * wink* * wink* "


> I've never noticed any particular dislike for IO in the language or community, excepting cases where it was obviously not appropriate.

And that isn't enough? 'Use IO only where you must' is not second-class? In any other context, I would definitely see that as second-classness - 'Oh, I only employ black workers when I simply can't get any white workers and must employ them'. IO is first-class only in the restricted and technical sense that yes, the type system will let you pass around IO values and functions.

> I disagree; ST would be practically useless if it could not be relied upon to use mutation.

But it still acts immutable and for all we know, is immutable. Just because some compilers and libraries use mutation doesn't prove your thesis that Haskell is as mutation happy as something like Java. As Isaac Asimov said, the man who thinks the Earth is a perfect sphere is wrong, like the man who thought it flat, but if you think he was just as wrong as the flat-Earther, you're more wrong than them both.


> And that isn't enough? 'Use IO only where you must' is not second-class? In any other context, I would definitely see that as second-classness

In that case, IO is second class in most languages, including Python, Ruby, C#, Java, C++, and C. I do not consider any of them to be functional.

> But it still acts immutable and for all we know, is immutable. Just because some compilers and libraries use mutation doesn't prove your thesis that Haskell is as mutation happy as something like Java.

No, it doesn't "act immutable"; an ST that acted immutable would be equivalent to State. The only advantage of ST over State is that compilers implement it as a special case of IO, and thus it can be used in place of IO for known-pure mutations.


OCaml has first class mutability and is usually considered a functional language (I am sure you can argue that of course).


I think there are about two classes roughly. The mathematically pure functions crowd with emphasis on correctness and the expressive power camp (which also helps with correctness indirectly).

I fall in the latter camp where functional programming is an approach, a style if you would. Where there are first order functions and the ability to easily manipulate them (C# fails here via verbosity), partial function application (often mislabelled currying), closures, recursion is forefront and immutability is the default. Terseness, algebraic types, tuples and pattern matching are optional but highly recommended (in my opinion Scala and Erlang are not terse relatively, Haskell/F#/Clojure are). I also find inference with static typing to be useful. [edit: by terse I don't mean by lines of code but vaguely, how busy each line is].

This combination leads to an extremely powerful and different way of thinking about and writing code that gives extensibility, composability and isolation for free. A style built around passing and assigning functions - treating functions the way most people treat variables. It also allows you to easily render abstractions of your problems without fussing with boiler plates. In terms of organizing and encapsulation it falls short but these new hybrids are shoring things up.


If we define a functional language as a language based on the lambda calculus, then whether it has first-class functions or not is not completely orthogonal since functions are values in the lambda calculus.


Functional means whatever the person saying it means by it.

Trying to give an all or nothing definition is doomed to failure and counter-examples.


“When I use a word,” Humpty Dumpty said, in a rather a scornful tone, “it means just what I choose it to mean—neither more nor less.”

“The question is,” said Alice, “whether you can make words mean so many different things.”

“The question is,” said Humpty Dumpty, “which is to be master that’s all.”

Alice was too much puzzled to say anything, so after a minute Humpty Dumpty began again. “They’ve a temper, some of them—particularly verbs, they’re the proudest—adjectives you can do anything with, but not verbs—however, I can manage the whole lot! Impenetrability! That’s what I say!”

and just for completenesses sake:

Alan Perlis — 48. The best book on programming for the layman is "Alice in Wonderland"; but that's because it's the best book on anything for the layman.


It, and "Through the Looking-glass", are very good books on programming for programmers, too. If you haven't read them since you were liddle, you're missing out.


FP means different to lispers, ML'ers and typeclassists (haskell, scala). Here's my attempt at a def

http://news.ycombinator.com/item?id=2075192


The author claims that Clojure tries to do OO. While Clojure does allow interaction with Java's object model, I think it's quite a stretch to say that it tries to do OO. Use of Java interop features for purposes other than interacting with a Java library or framework is generally discouraged.


The article is a year and a half old. Clojure doesn't "try" to do OO- multimethods always worked pretty well, and with 1.2.0 it does OO very well.

Clojure design philosophy is essentially "OOP: The Good Parts".


For there to be "Good Parts" of OOP, there would have to be a single kind of OOP.

P.S. Smalltalk.


That doesn't follow. If we define "OOP" to encompasses everything that anyone calls OOP then it's very possible for there to be "good parts" and "bad parts" in that set.

P.S. Smalltalk is a beautiful language with a great deal to offer anyone, but multimethods are superior. The fact that multimethods don't require multiple dispatch patterns demonstrates this.


i always miss interfaces in smalltalk. sometimes i really want a guarantee that the receiver will actually listen when i send a particular message. Even if you don't agree with that part, interfaces are really nice because the system will tell you, "hey, you forgot to add a method to respond to X. you got the other four, but spaced out this one. you should do something about that."


As someone new to clojure I gotta say that multimethods are pretty nice.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: