117

In the last few years anonymous functions (AKA lambda functions) have become a very popular language construct and almost every major / mainstream programming language has introduced them or is planned to introduce them in an upcoming revision of the standard.

Yet, anonymous functions are a very old and very well-known concept in Mathematics and Computer Science (invented by the mathematician Alonzo Church around 1936, and used by the Lisp programming language since 1958, see e.g. here).

So why didn't today's mainstream programming languages (many of which originated 15 to 20 years ago) support lambda functions from the very beginning and only introduced them later?

And what triggered the massive adoption of anonymous functions in the last few years? Is there some specific event, new requirement or programming technique that started this phenomenon?

IMPORTANT NOTE

The focus of this question is the introduction of anonymous functions in modern, main-stream (and therefore, maybe with a few exceptions, non functional) languages. Also, note that anonymous functions (blocks) are present in Smalltalk, which is not a functional language, and that normal named functions have been present even in procedural languages like C and Pascal for a long time.

Please do not overgeneralize your answers by speaking about "the adoption of the functional paradigm and its benefits", because this is not the topic of the question.

26
  • 7
    15-20 years ago people were asking the same question about OO... it wasn't a new concept but it had an explosion of popularity.
    – MattDavey
    Commented Nov 3, 2012 at 9:49
  • 8
    @MattDavey Most would certainly disagree, but then I'd have to remind them that "most Smalltalk developers" isn't really that many people ;P
    – yannis
    Commented Nov 3, 2012 at 11:15
  • 34
    I think the more interesting question is what triggered their demise! After all, there was a time, when most modern languages did have lambdas, then languages like Java and C++ became popular. (Although I wouldn't exactly call Java a "modern" language. The most modern concept in Java is Generics, which dates back to the late 60s/early 70s. Even the combination of features Java provides, pointer safety, memory safety, type safety, GC, statically typed OO, Generics all existed in Eiffel in 1985 … and much better, IMHO.) Commented Nov 3, 2012 at 12:37
  • 33
    Even before Java 1.0 came out, while it was still in the early design stages, pretty much everybody pointed out that Java needs lambdas. Some of the designers that worked on Java include Guy Steele (Lisp proponent, co-designer of Scheme, co-author of Common Lisp, designer of Fortress), James Gosling (wrote the first Emacs Lisp interpreter for PCs), Gilad Bracha (Smalltalk proponent, co-designer of Animorphic Smalltalk, designer of Newspeak), Phil Wadler (co-designer of Haskell), Martin Odersky (designer of Scala). How Java ended up without lambdas is really beyond me. Commented Nov 3, 2012 at 12:41
  • 9
    "A tiny bit" often means 50% function, 50% noise. Commented Nov 4, 2012 at 2:45

14 Answers 14

87

There's certainly a noticeable trend towards functional programming, or at least certain aspects of it. Some of the popular languages that at some point adopted anonymous functions are C++ (C++11), PHP (PHP 5.3.0), C# (C# v2.0), Delphi (since 2009), Objective C (blocks) while Java 8 will bring support for lambdas to the language . And there are popular languages that are generally not considered functional but supported anonymous functions from the start, or at least early on, the shining example being JavaScript.

As with all trends, trying to look for a single event that sparked them is probably a waste of time, it's usually a combination of factors, most of which aren't quantifiable. Practical Common Lisp, published in 2005, may have played an important role in bringing new attention to Lisp as a practical language, as for quite some time Lisp was mostly a language you'd meet in an academic setting, or very specific niche markets. JavaScript's popularity may have also played an important role in bringing new attention to anonymous functions, as munificent explains in his answer.

Other than the adoption of functional concepts from multi-purpose languages, there's also a noticeable shift towards functional (or mostly functional) languages. Languages like Erlang (1986), Haskell (1990), OCaml (1996), Scala (2003), F# (2005), Clojure (2007), and even domain specific languages like R (1993) seem to have gained a strong following strongly after they were introduced. The general trend has brought new attention to older functional languages, like Scheme (1975), and obviously Common Lisp.

I think the single more important event is the adoption of functional programming in the industry. I have absolutely no idea why that didn't use to be the case, but it seems to me that at some point during the early and mid 90s functional programming started to find it's place in the industry, starting (perhaps) with Erlang's proliferation in telecommunications and Haskell's adoption in aerospace and hardware design.

Joel Spolsky has written a very interesting blog post, The Perils of JavaSchools, where he argues against the (then) trend of universities to favour Java over other, perhaps more difficult to learn languages. Although the blog post has little to do with functional programming, it identifies a key issue:

Therein lies the debate. Years of whinging by lazy CS undergrads like me, combined with complaints from industry about how few CS majors are graduating from American universities, have taken a toll, and in the last decade a large number of otherwise perfectly good schools have gone 100% Java. It's hip, the recruiters who use "grep" to evaluate resumes seem to like it, and, best of all, there's nothing hard enough about Java to really weed out the programmers without the part of the brain that does pointers or recursion, so the drop-out rates are lower, and the computer science departments have more students, and bigger budgets, and all is well.

I still remember how much I hated Lisp, when I first met her during my college years. It's definitely a harsh mistress, and it's not a language where you can be immediately productive (well, at least I couldn't). Compared to Lisp, Haskell (for example) is a lot friendlier, you can be productive without that much effort and without feeling like a complete idiot, and that might also be an important factor in the shift towards functional programming.

All in all, this is a good thing. Several multi-purpose languages are adopting concepts of paradigm that might have seemed arcane to most of their users before, and the gap between the main paradigms is narrowing.

Related questions:

Further reading:

5
  • Thanks for the answer (and lots of interesting ideas). +1 Yet, I would argue that introducing (only) lambdas into a programming language is a very small step towards FP, and it may even be confusing to many (what are lambdas doing all alone inside an imperative language?). After learning some Haskell, Scala, and SML, I do not have the feeling I can do real FP with an imperative language that only supports lambdas (what about currying, and pattern matching, immutability?).
    – Giorgio
    Commented Nov 3, 2012 at 10:22
  • let us continue this discussion in chat
    – Giorgio
    Commented Nov 3, 2012 at 10:52
  • 2
    @YannisRizos: Perl's had anonymous functions since the first release of 5 (1994), but they weren't completely "right" until 5.004 (1997).
    – Blrfl
    Commented Nov 3, 2012 at 11:01
  • 1
    @penartur That's what I thought too, but a friendly editor corrected me by pointing me here: msdn.microsoft.com/en-us/library/0yw3tz5k%28v=vs.80%29.aspx
    – yannis
    Commented Nov 4, 2012 at 14:46
  • I think that perhaps the main "event" that brought about the popularity of functional languages is the web. More specifically, the shift from desktop programs to server side. This gives the developer freedom to choose any programming language. Paul Graham and Lisp in the 90s is a notable example.
    – Gilad Naor
    Commented Nov 5, 2012 at 6:59
31

I think its interesting how much the popularity of functional programming has paralleled the growth and proliferation of Javascript. Javascript has a lot of radical features along the functional programming spectrum that at the time of its creation (1995) were not very popular among mainstream programming languages (C++/Java). It was injected suddenly into the mainstream as the only client-side web programming language. Suddenly a lot of programmers simply had to know Javascript and therefore you had to know something of functional programming language features.

I wonder how popular functional languages/features would be if it had not been for the sudden rise of Javascript.

5
  • 5
    Javascript is surely an important language, but I am not sure if the introduction of Javascript can account for the popularity of functional programming on its own: a lot of other functional programming languages have appeared over the last years, as Yannis has illustrated in his answer.
    – Giorgio
    Commented Nov 3, 2012 at 13:54
  • 8
    @Giorgio - there might've been a lot of other functional programming languages, but (relatively) nobody uses them. The use of JS and the increased view that the C++/Java way of making functors is painful and annoying are really the driving forces to the mainstream, even if the more academic languages firmed up how they should be implemented.
    – Telastyn
    Commented Nov 3, 2012 at 14:08
  • 1
    The popularity of dynamic languages in general is hinted at as one explanation for the popularity of Haskell: book.realworldhaskell.org/read/…
    – yannis
    Commented Nov 3, 2012 at 14:12
  • Also, the focus of the question is not the popularity of FP in general, but about the late introduction of anonymous functions in general-purpose, non functional languages. Even if the big public (most programmers) did not know them, language designers knew them very well. There must have been a reason for leaving them out at the beginning. Maybe they were considered non-intuitive for the developers of the early 90-ties.
    – Giorgio
    Commented Nov 3, 2012 at 14:16
  • @giorgio - They're far more troublesome to implement as opposed to Java style functors. Combine that with the lack of knowledge/adoption and it's a pretty clear design choice.
    – Telastyn
    Commented Nov 3, 2012 at 14:22
27

JavaScript and DOM event handlers meant that millions of programmers had to learn at least a little bit about first class functions in order to do any interactivity on the web.

From there, it's a relatively short step to anonymous functions. Because JavaScript doesn't close over this, it also strongly encourages you to learn about closures too. And then you're golden: you understand anonymous first class functions that close over enclosing lexical scopes.

Once you're comfortable with it, you want it in every language you use.

2
  • 7
    +1 it's not just about anonymous functions. Closures are a much broader concept than just defining a temporary function inline.
    – phkahler
    Commented Nov 5, 2012 at 0:16
  • @phkahler: You are right and, in this sense, Java already has closures (and even more powerful than what you get with a function literal) but it lacks a concise notation for the common case of a one-method anonymous class.
    – Giorgio
    Commented Dec 4, 2012 at 21:21
17

It certainly isn't the only factor, but I'll point out the popularity of Ruby. Not saying this is more important than any of the six answers already on the board, but I think that many things happened at once and that it's useful to enumerate them all.

Ruby is not a functional language and its lambdas, prods, and blocks seem clunky when you've used something like ML, but the fact is, it popularized the notion of mapping and reducing to a generation of young programmers fleeing Java and PHP for hipper pastures. Lambdas in several languages seem to be defensive moves more than anything else ("Stick around! We've got those too!!)

But the block syntax and the way it integrated with .each, .map, .reduce and so forth popluarized the idea of an anonymous function even if it's really a syntactic construct that behaves like a coroutine. And the easy conversion to a proc via & makes it a gateway drug for functional programming.

I argue that Ruby on Rails programmers writing JavaScript were already turned on to doing things in a lightweight functional style. Couple that with programmer blogging, the invention of Reddit, hacker News, and Stack Overflow around the same time, and the ideas spread faster over the Internet than they did in the days of Newsgroups.

TL;DR: Ruby, Rails, JavaScript, blogging, and Reddit/Hacker News/Stack Overflow pushed functional ideas to a mass market, so everyone wanted them in existing languages to prevent further defections.

3
  • 2
    +1 For a good answer and (if I could, because I only have one upvote) +1 for pointing out that "Lambdas in several languages seem to be defensive moves more than anything else ("Stick around! We've got those too!!)". I think this is a factor too. For some languages lambdas are a nice-to-have feature which, even though it adds very little expressive power to the language as a whole, it gives the language some popularity (a number of programmers seem to think that support for anonymous functions is equivalent to fully supporting functional programming).
    – Giorgio
    Commented Nov 4, 2012 at 19:03
  • 2
    I really think this is the reason why most languages have implemented block syntax in the recent years. But the only way to make sure is to ask he language developers what their motives were. We can only speculate imo.
    – SpoBo
    Commented Nov 5, 2012 at 7:41
  • for me, Ruby is the language that first made blocks rock and very appealing, so +1. Haskell might have had an effect as well.
    – rogerdpack
    Commented Nov 9, 2012 at 17:42
14

As Yannis pointed out, there are a number of factors that have influenced the adoption of high-order functions in languages that were previously without. One of the important items he only touched lightly on is the proliferation of multi-core processors and, with that, the desire for more parallel and concurrent processing.

The map/filter/reduce style of functional programming is very friendly to parallelization, allowing the programmer to easily make use of multiple cores, without writing any explicit threading code.

As Giorgio notes, there is more to functional programming than just high-order functions. Functions, plus a map/filter/reduce programming pattern, and immutability are the core of functional programming. Together these things make for powerful tools of parallel and concurrent programming. Thankfully, many languages already support some notion of immutability, and, even if they don't, programmers can treat things as immutable allowing the libraries and compiler to create and manage asynchronous or parallel operations.

Adding high-order functions to a language is an important step to simplifying concurrent programming.

Update

I'll add a couple more detailed examples in order to address the concerns Loki noted.

Consider the following C# code which traverses a collection of widgets, creating a new list of widget prices.

List<float> widgetPrices;
    float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
    widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}

For a large collection of widgets, or a computationally intensive CalculateWidgetPrice(Widget) method, this loop would not make good use of any available cores. To do the price calculations on different cores would require the programmer to explicitly create and manage threads, passing work around, and collecting the results together.

Consider a solution once high-order functions have been added to C#:

var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );

The foreach loop has been moved into the Select method, hiding its implementation details. All that remains to the programmer is to tell Select what function to apply to each element. This would allow the Select implementation to run the calculations in parellel, handling all the synchronization and thread management concerns without the programmer's involvement.

But, of course, Select does not do it's work in parallel. That's where immutability comes in. The implementation of Select does not know that the provided function (CalculateWidgets above) does not have side effects. The function could change the state of the program outside the view of Select and its synchronization, breaking everything. For example, in this case the value of salesTax could be changed in error. Pure functional languages provide immutability, so the Select (map) function can know for sure that no state is changing.

C# addresses this by providing PLINQ as an alternative to Linq. That would look like:

var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );

Which makes full use of all the cores of your system without explicit management of those cores.

6
  • I do point to the desire for more parallel and concurrent processing, it's discussed in the "A history of Erlang" ACM article I'm linking to in the fourth paragraph. But it's a very good point, and I should have probably expanded on it a bit more. +1 because now I don't have to ;P
    – yannis
    Commented Nov 3, 2012 at 10:49
  • You're right, I didn't look carefully enough. I edited my remark.
    – Ben
    Commented Nov 3, 2012 at 10:52
  • Oh, you didn't really have to do that, I wasn't complaining ;)
    – yannis
    Commented Nov 3, 2012 at 10:53
  • 4
    None of what you describe above requires lambdas. The same functionality is achieved just as easily with named functions. Here you are simply documenting a cause and a perceived affect without explaining the correlation. The last line IMO is what the question is about; but you did not answer it. Why does it simplify concurrent programming. Commented Nov 3, 2012 at 13:38
  • @Ben: Be careful that your example concerns higher-order functions which do not need anonymous functions to be used. Your answer contains interesting ideas (for another question) but is going off topic right now.
    – Giorgio
    Commented Nov 3, 2012 at 14:21
9

I agree with many of the answers here, but what's interesting is that when I learned about lambdas and jumped on them, it wasn't for any of the reasons others have mentioned.

In many cases, lambda functions simply improve readability of your code. Before lambdas when you call a method that accepted a function pointer (or function, or delegate), you had to define the body of that function somewhere else, so when you had "foreach" construct, your reader would have to jump to a different part of the code to see just what exactly you were planning to do with each element.

If the body of the function that processes elements is only few lines of, I would use an anonymous function because now when you are reading code, functionality remains unchanged, but the reader doesn't have to jump back and forth, the entire implementation is right there in front of him.

Many of the functional programming techniques and parallelization could be achieved without anonymous functions; just declare a regular one and pass a reference to that whenever you need to. But with lambdas ease of writing code and ease of reading code is greatly improved.

4
  • 1
    Very good explanation (+1). Lisp programmers have been aware of all this since 1958. ;-)
    – Giorgio
    Commented Nov 4, 2012 at 19:05
  • 4
    @Giorgio: Sure, but lisp programmers also had to buy special keyboards with reinforced open/close parenthesis keys :)
    – DXM
    Commented Nov 4, 2012 at 22:28
  • @DXM: not keyboards, they get additional input device that is kind of like piano pedals for opening and closing parenthesis ;-)
    – vartec
    Commented Feb 11, 2013 at 13:55
  • @DXM, vartec: Been doing some Scheme lately and I find the parentheses OK. Some C++ code can be much more cryptic (and I have much more experience with C++ than with Scheme). :-)
    – Giorgio
    Commented Mar 28, 2013 at 12:25
9

Having been involved in the recent history here a bit, I believe that one factor was the addition of generics to Java and .NET. That naturally leads to Func<,> and other strongly typed computational abstractions (Task<>, Async<> etc.)

In the .NET world we added these features precisely to support FP. That triggered a cascading set of language work related to functional programming, especially C# 3.0, LINQ, Rx and F#. That progression influenced other ecosystems too and still continues today in C#, F# and TypeScript.

It helps to have Haskell work at MSR too, of course :)

Of course there were many other influences too (JS certainly) and these steps were in turn influenced by many other things - but adding generics to these languages helped break the rigid OO orthodoxy of the late 90s in large parts of the software world and helped open the door for FP.

Don Syme

p.s. F# was 2003, not 2005 - though we would say it did not reach 1.0 until 2005. We also did a Haskell.NET prototype in 2001-02.

1
  • Welcome! I used 2005 for F#, as that's the year reported in the F#'s Wikipedia article as the year of the first stable release. Would you like me to change it to 2003?
    – yannis
    Commented Nov 4, 2012 at 17:16
4

This isn't meant to be a serious answer, but the question reminded me of a cool humorous post by James Iry - A Brief, Incomplete, and Mostly Wrong History of Programming Languages which includes the following phrase:

"Lambdas are relegated to relative obscurity until Java makes them popular by not having them."

1
  • golden phrase :)
    – pistache
    Commented Feb 11, 2013 at 13:25
4

From what I see most answers concentrate on explaining why functional programming in general made it's comeback and made it's way into mainstream. I felt this however doesn't really answer the question about anonymous functions in particular, and why they suddenly got so popular.

What has really gained the popularity, are closures. Since in most cases closures are throw-away functions passed variable, it obviously makes sense to use anonymous function syntax for these. And in fact in some languages it's the only way to create closure.

Why have closures gained popularity? Because they are useful in event-driven programming, when creating callback functions. It's currently the way of writing JavaScript client code (in fact it's the way of writing any GUI code). It's currently also the way of writing highly efficient back-end code as well as system code, as code written in event-driven paradigm is usually asynchronous and non-blocking. For back-end this became popular as solution to C10K problem.

3
  • Thanks for stressing that this question is not about functional programming (+1) because (1) the idea of a block of code that is passed around as an argument is also used in non-functional languages like Smalltalk, and (2) mutating state captured from the lexical context of a closure (as possible in many lambda implementations) is definitely non-functional. And yes, having closures, the step to anonymous closures is short. The interesting thing is that closures have also been well-known for a long time, and event-driven programming has been used (as far as I know) since the eighties.
    – Giorgio
    Commented Feb 11, 2013 at 13:18
  • But maybe it was only in the last few years that it became clear that closures can be used much more often than previously thought.
    – Giorgio
    Commented Feb 11, 2013 at 13:27
  • @Giorgio: yes, most of concepts that are currently used have been around for very, very long. Yet they haven't been used the way, they are used now.
    – vartec
    Commented Feb 11, 2013 at 13:36
1

I think the reason is the increasing prevalence of concurrent and distributed programming, where the core of object oriented programming (encapsulating changing state with objects) no longer applies. In the case of a distributed system, because there is no shared state (and software abstractions of that concept are leaky) and in the case of a concurrent system, because properly synchronizing access to shared state has been proven cumbersome and error-prone. That is, one of the key benefits of object oriented programming no longer applies for many programs, making the object oriented paradigm far less helpful that it used to be.

In contrast, the functional paradigm does not use mutable state. Any experience we gained with functional paradigms and pattern is therefore more immediately transferrable to concurrent and distributed computation. And rather than reinvent the wheel, the industry now borrows those patterns and language features to address its need.

3
  • 4
    Anonymous functions in some main-stream languages (e.g. C++11) do allow mutable state (they can even capture variables from the defining environment and change them during their execution). So I think that speaking about the functional paradigm in general and about immutability in particular is a bit out of the scope of the question being asked.
    – Giorgio
    Commented Nov 3, 2012 at 14:37
  • Having just read some of the feature notes for Java 8, one of the main goals of project lambda is to support concurrency. And THAT immediately takes us to the mutability clusterbomb that all of these wonderful javabeans are going to run into. Once Java gets lambdas (assuming it really does in the final release of version 8), they then need to address the immutable-by-default issue, somehow (it kind of destroys the language, thinking in Lisp - side effect free functions - instead of in COBOL - whack on DATA DIVISION / COPYBOOK)
    – Roboprog
    Commented Dec 3, 2013 at 2:49
  • Well said. The move away from mutable state make concurrency easier and technologies like cascalog and spark easily distribute functional programming across a cluster of computers. See glennengstrand.info/analytics/distributed/functional/… for more detail as to how and why.
    – Glenn
    Commented Dec 14, 2014 at 0:56
1

If may add my €0.02, although I would agree with the importance of JavaScript introducing the concept, I think more than concurrent programming I would blame the current fashion of asynchronous programming. When doing async calls (necessary with the webpages), simple anonymous functions are so obviously useful, that every web programmer (i.e., every programmer) had to get very familiar with the concept.

1

Another really old example of something akin to anonymous functions / lambdas is call-by-name in Algol 60. Note however that call-by-name is closer to passing macros as parameters than passing true functions, and it is more fragile / harder to understand as a result.

0

Here the ancestry to the best of my knowledge.

  • 2005: Javascript has most recently brought higher-order programming with lambdas back into mainstream. In particular libraries like underscore.js and jquery. One of the first of these libraries was prototype.js which predates jquery by about year. Prototype is based on the Enumerable module of Ruby, which leads us to…
  • 1996: Ruby's Enumerable module very obviously took inspiration from Smalltalk's collection framework. As has been mentioned by Matz in many interviews, which leads us to…
  • 1980: Smalltalk uses a lot of higher-order programming and provides a collection API that makes heavy use of higher-order programming (eg, GNU Smalltalk's Iterable class). In idiomatic Smalltalk code you won't find any for loops but only high-order enumerations. Unfortunately when Java when Smalltalk's collection framework was ported to Java in 1998 the higher-order enumerations were left out. That is how higher-order programming was phased out of the mainstream for the next ten years to come! Smalltalk has many ancestries, but relevant to OP's question is LISP, which leads us to…
  • 1958: LISP, obviously, has higher-order programming at its core.
1
  • Amiss, of course, is the whole ML ancestry. ML, SML, OCaml, Haskell, F#. That got to count for something.. Commented Feb 11, 2013 at 13:40
-1

Anonymous functions are nice because naming things is hard, and if you only use a function in once place, it doesn't need a name.

Lambda functions have only recently become mainstream because until recently, most languages didn't support closures.

I would suggest that Javascript has pushed this mainstream. It's a universal language that has no way to express parallelism, and anonymous functions ease the use of callback models. Additionally popular languages like Ruby and Haskell have contributed.

2
  • 1
    "Lambda functions have only recently become mainstream because until recently, most languages didn't support closures.": This reasoning sounds a bit circular to me: being mainstream means that most languages support it. One could immediately ask "What triggered the popularity of closures in modern programming languages."
    – Giorgio
    Commented Nov 6, 2012 at 14:45
  • I know that Python does not have the best implementation of lambdas. But in terms of popularity, it probably contributed more than Haskell. Commented Feb 11, 2013 at 13:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.