Gilad Bracha explains how to distinguish FP hype from reality and to apply key ideas of FP in non-FP languages, separating the good parts of FP from its unnecessary cultural baggage.
Gilad Bracha is the creator of the Newspeak programming language and a software engineer at Google where he works on Dart. Previously, he was a VP at SAP Labs, a Distinguished Engineer at Cadence, and a Computational Theologist and Distinguished Engineer at Sun. He is co-author of the Java Language Specification, and a researcher in the area of object-oriented programming languages.
Software is Changing the World. QCon empowers software development by facilitating the spread of knowledge and innovation in the developer community. A practitioner-driven conference, QCon is designed for technical team leads, architects, engineering directors, and project managers who influence innovation in their teams.
excellent presentation !!!
Agree Smalltalk (as a hybrid functional-OO) language was ahead of its time. Also agree that FP sometimes is treated with religious fervor which is not helping its cause.
However as Gilad himself shows (via many examples) Monads from FP are indeed a useful concept. I personally think programmers should get familiar with them - regardless of the obtuse terminology; they just allow you to work at a higher level of abstraction.
You know after Smalltalk I was never really satisfied with either Java or C#. C# was OK but it was not until F# came along that I felt 'at home' again. IMHO F# is one of the most practical and versatile functional-OO languages on the market today.
Contrary to Gilad, Hindley-Milner type inference actually works very well in F# (which is part of the ML family). F# is statically typed but imparts the feel of a dynamically typed language because so few type annotations are needed.
It is true that when types don't align the error messages can be confusing with Hindley-Milner inference. In the beginning this was a hurdle for me. However with experience you develop a good sense of where the problem might be and can fix it quickly.
In both Visual Studio and Xamarin Studio you can 'discover' the type of any F# function / name in the source code editor just by hovering the mouse over it. I believe this is a must-have tooling feature for any language with type inference because the type information is not apparent from source code. Can't over emphasize the roll of tooling for any language!
Wonderful and entertaining
Functional Programming is about working with Values i.e. non-Mutable data
As per usual Gilad Bracha is more interested in controversy than facts
I would suggest that Gilad Bracha try to read a few Computer Science papers, especially the type theory behind OO and how it differs from the lambda calculus. And if Mr. Gilad finds the papers hard to read then I suggest he starts out with one of the many "Introduction to Computer Science" books out there.
2. Stating that Functional Programming is higher order functions + avoiding effects: Wrong.
Languages are about choosing what is easy and what is hard. It is easy in functional languages to work with immutable values and harder to work with mutable objects. OO languages are the opposite.
Gilad Bracha very carefully avoids talking about Haskell. Why? Because Haskell IS a pure functional language and would be a great example of showing what makes a truly functional language different from (say) Java. However he chose not to. My guess is that it would have made the talk less controversial?
F# is like being back home again after a long trip :-)
FP could be made easier
He is also right when he says many FP concepts were already usable (with different names though) in some old pure OOPL. What's new is that those concepts tend to be mandatory in some FPL instead of being just recommended.
Exactly like most OO concepts were usable in other older languages, but they have been made mandatory in OOL.
Re: Missing reference
which discusses Guy's blog entry.
There's also another story about William Cook's article:
with a link to a PDF. Don't know if it's exactly the same article Guy reference.
This was a waste of time
A functional language is one that has, as its core, the lambda calculus as a model of computation.
(With that in mind, you can define an imperative language as one that has the Turing machine as its core, and a logic language as one that has propositional logic as its core.)
(Also note that, with this definition, LISP is indeed the original functional programming language, as it was created as an executable self-described lambda calculus interpreter. In 1958.)
In practice, this means that the rules of evaluation of the language are mainly about substitutions, from which immutability and purity naturally follow; higher-order functions are of course implied directly by the underlying model, for the simple reason that you cannot do anything in lambda calculus without higher-order functions.
And, of course, functional programming languages are not "just" lambda calculus, just as imperative ones are not "just" Turing machines. Our programs do much more than computing.
With that word of context out of the way, here's my take on that talk: it's exactly what I do not want from a presentation. I did not learn anything useful watching it; it was vaguely amusing, especially the part about monads, but that was also very redundant with "Monads are Gonads" from Crockford a year ago and much less informative. The vast majority of his statements are "not even wrong". I mean, the guy did not even bother to look for a proper definition of what he was deconstructing.
Let me deconstruct this talk in a slightly less polite and benevolent way than the blog post above.
* The XKCD comic is funny. But using it to assert that functional programming is not practical? I can't even respond to that. This is clearly in the "not even wrong" category. I can assert that "people" do "nonsense" about anything, be it programming-related or not, especially if I do not feel compelled to provide any kind of evidence.
* As stated above, the guy can't even be bothered to find a proper definition of what he wants to deconstruct, all the while extolling the virtues of Object-Oriented Programming. Don't tempt me with "object-oriented" and "definition".
* HOFs are only a big deal because of Java. I do not know of any other programming language in which they are so *exotic*. You even get function pointers in C. Yes, they were fairly common in Smalltalk (which he claims predates FP languages, because it was in 72... LISP, 58? Can't he get a single fact right?), but so what?
* Effects are of course necessary, because our programs are not only about computing: they are about computing and then acting on the world based on these computations. As the saying goes, a purely functional program cannot even heat up your processor, as that would be a side-effect. (Also, xkcd.com/1312/, though he could not have used that one in his slides.) Even Haskell has effects, encapsulated into its IO monad. So the important distinction becomes how much the language pushes you to use them or not use them for the "computing" part of the program, as opposed to for the "affecting the world" part, which is inevitable.
* Scala is not a good example of the possible combination of OO and FP. Scala is not an FP language, period. Scala has higher-order functions and a decent type system, but only through Java-destroyed eyes can that even remotely resemble FP. (Now, don't get me wrong: Scala is a very nice language, a much needed replacement for Java, and it is possible to write in a functional style in Scala - but asserting that Scala is functional is akin to asserting that C++ is. Or Java 8.)
* His bit about user-defined control structures is cute, but has nothing to do with FP. It is about OO in a non-Java language. But how is that relevant? Yes, you can define custom control structures if you have literal lambda syntax and are not afraid to impose that on your users. Or if you have macros. Or if you have lazy evaluation in some way (either as a pervasive language feature like Haskell, or as an optional per-argument basis like Scala). *If*, as in this example, you do not care about forcing your users to create the lambdas themselves, I'm not sure there's any language but Java which does not let you "create your own control flow". (Of course, being able to do it without imposing extra syntax on the user is another story.)
* Tail calls. This one would be cute if it was not so embarrassing for the speaker. First and foremost, the need for tail call optimization is an accidental implementation detail due to the fact that our programs have to run on hardware realizations of Turing machines. It is basically the cost of an impedance mismatch. Granted, it is a quite necessary implementation detail to be able to work in practice, but it's still about the implementation of the language, not about its semantics. Ignoring that, the only argument he makes about tail calls is that they loose the stack trace. Now let's think about that for a second. (Yes, I do hope that my readership will need less than a second on average to reach the correct conclusion and see how absurd this is.) What are recursive tail calls in a functional program the equivalent of in an imperative program? Hint: it's on his slide. Recursive tail calls are typically used to represent *loops*. Every time I hear the "TCO looses stack traces" argument, I get my hopes up and then get disappointed when I see that, no, Java (Python/Ruby/Smalltalk/...) stack traces do not yet contain the successive values of the looping variables leading to the crash. (Actually, they usually do not contain any values, but that is another rant.)
* Hindley-Milner. Seriously? No value in not *having* to type types, but being able to, and getting the existing annotations checked, while the compiler can still use its (probably too general) inferred types to optimize code with no annotation? Gee, we must have completely different definitions of "value". (And of identity. And of FP.)
* Currying. Again, *SERIOUSLY??* I mean, what is he after exactly? This is again a "not even wrong" comment, and I really don't know how to respond to that. First of all, this is mostly just Haskell. Reducing all functional languages to Haskell is sort of short-sighted, especially when functional programming is the subject of the talk. This is, at best, a very lazy way to prepare for a talk. Besides, this completely misses the point that having automatic currying does not force you to actually pass arguments one at a time every time.
* Pattern matching is the only redeeming part of the talk, in that there is some grain of truth in what he's asserting: when pattern matching is used *only* to check the type of the argument, it is no better than an instanceof check. But 1°) pattern matching can do so much more, including destructuring and matching multiple cases of the same type, and 2°) some compilers at least (I'm pretty sure about ML, not quite sure about Haskell) actually do check that you cover all possible cases. So his argument is basically "I have found one language (Scala?) where pattern matching is not checked by the compiler, so if I reduce it to something barely useful (i.e. only checking for types), it's barely useful and not type checked".
* Making fun of monad tutorials is too easy, and should not take up a quarter of an hour, especially if it is to finally teach absolutely nothing to the audience.
* According to an interview of Eric Meijer, LINQ has actually been inspired by Haskell, not by Smalltalk ( channel9.msdn.com/Blogs/Charles/Simon-Peyton-Jo... ). There might have been something similar in the Smalltalk implementations, although the level of expertise the speaker demonstrated with each and every topic he mentioned makes me highly doubt that he understands any of these two subjects well enough to make a meaningful comparison.
* And finally, of course, the last point is as misguided as the rest of the talk: functional languages do not have a particular edge when it comes to live programming, as illustrated by the early Smalltalk environments (I'm not old enough - and I did not do the research - to know which came first between Squeak-style Smalltalk environment and Symbolics Lisp Machine ones, but I do know that that breed of Lisps was not geared towards limiting side effects). Dynamic languages do, but it's not even about typing: it's dynamic in terms of the runtime. Basically, you have an edge for interactive programming when you have an interpreter available at runtime as part of your core design. Duh!
So, yeah, all in all, a big waste of time, and the mastery demonstrated by the author makes me highly unlikely to ever watch another one of his talks. The only redeeming feature of this talk is this little gem around 35:06 : "The real issue I have is it has never been terribly clear to me that in programming, you know, once I have all of those valuable abstractions, the cases were I really want to treat them, except for the collections, treat them polymorphically, you know, they're not that obvious, and it's not clear, you know this is more a tool for language designers." OO for the win, indeed.
And I'll close with this quotation, from a few seconds after the previous one: "maybe if I took an hour and prepared it carefully".
Re: FP could be made easier
That said, it is true that much of the documentation about functional programming is obtuse and hard to read. But that is an accident: documentation of powerful static type systems is hard to read. It just so happens that, as of today, the most obtuse type systems are defined for functional languages. Static typing and functional programming are, however, mostly orthogonal.
If you want to taste functional programming without the strange vocabulary, try a dynamic language. I'd suggest either Erlang or Clojure; working with Ruby or Python and self-restricting to not ever mutate anything could also work, although it is easier to remain disciplined when the language does not tempt.
He wants us to know, for example, that electrons are not fermions because electrons were known before the term "fermion" was coined. Or, sorry, that lisp is not a functional language because it was known before the term "functional programming" was coined. Or something. The whole talk is fatuous nonsense of this sort.
His only compelling points are that 1) monads are perhaps too complex to be useful, and in any case have been very poorly explained, and 2) type inference systems give very poor error messages. These are both obvious, but I would not be at all surprised if, in ten years, industry looks back at this time with bewilderment that anyone was ever confused by monads. That's always the way when new ideas are popularized. It's also the case that early OOP languages generated unusable error messages, as anyone knows who lived through the early C++ compilers.
He complains that FP developers don't know what objects really are, however the paper he recommends to explain objects uses a definition that is only vaguely related to OOP as it is practiced: it's an entirely academic idea of objects based on (wait for it... wait for it....) lambda calculus. No, really. I'm not making that up. FP developers, of course, complain of OOP as it is practiced, and while implying that they are merely illiterate, Bracha is unable to challenge any of those complaints.
He notes that there's still no "killer app" for FP, which is a good point, but there are even fewer examples of the singular OOP that he advocates.
It almost sounds like he could give a good talk on this subject if he actually prepared for it, and was willing to use the terms OOP and FP they way the rest of the world understands them.
In defense of this talk
this great talk is about what is special about and meant by so called "functional progamming" in our days.
I think that some people should calm down and listen again with good intentions.
Many critics of this talk are embarrassingly far fetched or even lies.
Gilad seems to know some of the offended audience but makes no excuses (0:55) and even sais that his talk is to annoy the cultists of functional programming (5:35).
Gilad Bracha is not some random guy.
If he does not understood the theory than who does ?
Certainly not the average programmer like me to whom functional programming is advertised as well.
The main points of the talk, IMO:
The XKCD comic is not shown to be funny but to make a point (1:00).
Gilad thinks that the best criteria to recognize a language as functional is how recursion and tail calls are implemented (12:35).
HOF (higher order function) is not enough to qualify as functional language (3:20).
Java has them too but nobody would consider Java as a functional programming language.
His point is that OO languages have HOF since the 70s where the term "functional programming" was not yet invented.
Even today, the term "functional programming" has no clear meaning as Gilad tries to explain.
The absence of effects is not a trait of functional languages
if one considers Lisp, Scheme, Scala or F# as functional language (4:27).
HOF where not used by en.wikipedia.org/wiki/FP_%28programming_languag....
The functional programming people did not invent HOF (7:50).
They exist since Lisp.
HOF for user defined control structures (8:00).
I think that:
- macros are static compiler magic.
- Haskell is a very static programming language.
About debugging and stack traces (13:00).
Hindley-Milner and typesystems in general (16:30).
Typesystems do not prevent all errors.
Either not all kind of errors are covered by the typesystem or typing is so
complicated and cumbersome that debugging and testing are more realistic approaches.
And type errors can be cryptic.
According to Gilad:
- Names are important.
- Nominal typesystems are useful.
Gilad thinks that currying is useful but it can easily lead to a lack of program structure
to the point that types are required to introduce program structure again.
Pattern matching (20:55).
Patter matching means dynamic type tag checks like instanceof in Java.
Monads (24:00 and 42:00)
Gilad seems to make fun of replacing meaningful names and concepts by abstract and less meaningful concepts and names.
I like this: fsharpforfunandprofit.com/posts/why-i-wont-be-writing-a-monad-tutorial/,
I do not know the theory behind monads, but I have come to believe that some monad X is just some property or trait X that certain things or approaches have in common.
The formal monad interface (the abstraction of monads in formal languages) is used
to replace "concrete" names and things (objects, functions) by a monad with a "return" constructor and a "bind" operator.
Killer App for FP is live programming (42:20).
Because live programming with sample data is simpler with functions without side effects on the sample data.
Static typesystems do not replace live programming.
The time of confrontation is over...
Many new languages are multi-paradigm, capable of many things. (C#, F#, Java 8, Clojure)
It is a power of language, if things can be achieved with many ways.
The notable difference is however the design principles. Which kind of code is the default? The programming language will guide the developer to some direction.
C# and Java are object-oriented-first
F# and Clojure are functional-first
As analogy: which is better: float or int?
Usually both are supported. Even though the other ones would be just hard mathematical abstraction-constructs without real correspondence to the real world, they are still widely used.