An Introduction to the Y Combinator

Recursive Procedures Without letrec!

The Why of Y

Some of you have expressed interest in the more advanced uses of Racket and functional programming. If you are one of those people, read on. If not, feel free to return from whence you came.

In a reading about local recursive functions, I asked if you could give a translational semantics for letrec using lambda, and I hinted that you would have to do something we have never done before in Racket. That something is to change an existing variable binding — that is, to use a assignment statement!

Actually, there is a way to implement recursive procedures without using letrec or any language primitives beyond what we already know. This technique relies only on the ability to pass a function as an argument to another function. It creates a special kind of combinator, which is a lambda expression without any free variables. We encountered the idea of a combinator briefly in Session 12.

The Y combinator is one of the cool theoretical achievements in programming language theory. It shows that it is possible to create even a recursive function without a name. But how can a function call itself if it doesn't have a name? The trick: by passing itself to itself. This technique works even in a language that does not support recursive functions directly, as long as it support higher-order functions.

What is the Y combinator? How can it work? Here are two options for you:

Be forewarned: In order to derive Y, both authors have to work through several layers of higher-order functions, repeatedly abstracting lambda expressions out of lambda expressions. The process makes my head spin! It may do the same to you.

Even so, do not think that the Y combinator works only in Racket or a Lisp-like language. Any language with higher-order functions will do. You can check out versions of the Y combinator in:

I think some of these implementations are quite beautiful, perhaps most surprisingly the Perl version!

This zip file contains code files for these four implementations of Y, along with the Racket version mentioned above.

Acknowledgments

My copy of Gabriel's paper mirrors his original, which can be found on his web site, www.dreamsongs.com . Richard is not only an expert in several areas of computer science, including object-oriented programming, programming languages, and AI. He is also a working poet.