You Can Explain Functional Programming Using Emojis

A visual representation of Lambda calculus, Church encoding, and Y combinator

Last month, I published a free online course called “Y Combinator for Non-programmers”. In this 17-page course, I explain functional programming concepts such as lambda calculus, Church encoding, and Y combinator in a way such that people who have zero programming knowledge can understand.

I didn’t use any code to explain these concepts. Instead, I created something called “emoji puzzles” that can visualize functional code. In this article, I’ll explain how my emoji puzzles can represent and execute functional code visually.

Quick Demo

First, here’s simple, functional JS code. Try pressing R un below to see the result:

Functional JS code: ( sushi => sushi ) ( 'sandwich' ) Run ← Press this button!

The above code can be expressed visually using my emoji puzzle below. Try pressing R un :

Equivalent emoji puzzle: R un ↑ Press this button!

I’ll explain how it works shortly. If you like to teach programming, or if you like functional programming, I think you’ll enjoy this article.

Overview

This article has 10 steps:

In the first half (steps 1 - 5): I’ll show you how simple JavaScript code can be represented visually using my emoji puzzles. You’ll be able to understand it even if you’re not familiar with JS.

I’ll show you how simple JavaScript code can be represented visually using my emoji puzzles. You’ll be able to understand it even if you’re not familiar with JS. In the second half (steps 6 - 10): I’ll talk about how I used my emoji puzzles to explain functional programming concepts such as lambda calculus, Church encoding, and Y combinator.

This article is for programmers. If you’re a non-programmer, check out my course instead: “ This article is for programmers. If you’re a non-programmer, check out my course instead: “ Y Combinator for Non-programmers ”.

1 / 10 · From my course’s Beginner 3 level Step/ 10

Identity function in JS

Take a look at the following code. It’s an identity function in JavaScript that returns the argument.

sushi => sushi

If you apply the above function on a string 'sandwich' , the result will be 'sandwich' .

( sushi => sushi ) ( 'sandwich' )

One day, I realized that the above JS code can be described visually using emojis like below. I called this an “emoji puzzle”.

An “ emoji puzzle ” that visually describes

(sushi => sushi)('sandwich')

The above emoji puzzle is equivalent to the earlier JS code. First, the identity function sushi => sushi …

( sushi => sushi ) ( 'sandwich' )

…is represented by the bottom two items, which are both sushi .

sushi => sushi is represented

by the bottom two items

Second, the argument 'sandwich' to the identity function…

( sushi => sushi ) ( 'sandwich' )

…is represented by the top item, which is a sandwich .

The argument 'sandwich' is represented

by the top item

That’s how my emoji puzzles can visually describe a simple JS expression. Next, let’s talk about how we can r un it.

Note: To keep things simple, emoji puzzles don’t distinguish between variable names (e.g. sushi ) and strings (e.g. 'sushi' ). Therefore, both sushi and 'sushi' will be represented as . Why emojis? I used emojis because they are not scary-looking for non-programers. I used food emojis because…I like food.

2 / 10 · From my course’s Beginner 4 level Step/ 10

Running the function

I’ve added the R un button to the JS code snippet below. If you press it, you’ll see that the result is 'sandwich' .

( sushi => sushi ) ( 'sandwich' ) Run ← Press this button!

We can also “run” the equivalent emoji puzzle and get the same result. Try pressing the R un button below.

An emoji puzzle that’s equivalent to

(sushi => sushi)('sandwich') R un ↑ Press this button!

The result is a sandwich , which is the same as what happens when you run the equivalent JS code.

So, you can r un an emoji puzzle just as you can run a piece of JS code. This is how I taught functional programming to non-programmers in my course (Y Combinator for Non-programmers)—without showing any code.

Let’s take a look at another example. Here’s a piece of JS code that’s slightly different from before. It’s a function that ignores the input and always returns 'pizza' .

sushi => 'pizza'

Let’s run the above code with 'sandwich' as the argument. Press R un :

( sushi => 'pizza' ) ( 'sandwich' ) Run

As expected, the result is 'pizza' . Now, this code can be represented using an emoji puzzle as follows. Press R un :

An emoji puzzle that’s equivalent to

(sushi => 'pizza')('sandwich') R un

Just like the JS code, the emoji puzzle ended up with a pizza after running it.

What we have learned so far: Simple JS code like below can be represented using emoji puzzles. Functional JS code: ( sushi => sushi ) ( 'sandwich' ) Result: 'sandwich' Equivalent emoji puzzle: Functional JS code: ( sushi => 'pizza' ) ( 'sandwich' ) Result: 'pizza' Equivalent emoji puzzle:

3 / 10 · From my course’s Beginner 4 level Step/ 10

Visualizing evaluation rules

If you know how to code, you have a mental model of how function evaluation works:

If you see (sushi => sushi)('sandwich') , you can quickly figure out that the result would be 'sandwich' .

, you can quickly figure out that the result would be . If you see (sushi => 'pizza')('sandwich') , you know that the result would be 'pizza' .

, you know that the result would be . You know what free variables and bound variables mean.

On the other hand, most non-programmers don’t have a mental model of how function evaluation works. To help them develop the mental model, I created a step-by-step visualization of function evaluation rules using emoji puzzles.

Let’s reuse the earlier example again:

Functional JS code: ( sushi => sushi ) ( 'sandwich' )

Equivalent emoji puzzle:

On the puzzle below, try pressing the R un button. This button is a bit different from the last time—it shows every step that happens in between.

Run (Show every step) ↑ Press this button!

Here are the four steps it displayed:

Step 1. Label: t l r

First, we label each emoji. The top item is labeled as t (for “Top”), the left item is labeled as l (for “Left”), and the right item is labeled as r (for “Right”).

Label: t l r t l r

Step 2. Match: l r

Second, w e check to see if some of l’s and r’s match. If they match, add the sign. In this case, both the bottom-left and the bottom-right are sushi , so there’s a match.

Match: l r t l r

Step 3. Copy: t r

Third, w e copy t’s to where the matched r’s are. In this case, we copy the sandwich on the top to the bottom-right.

Copy: t r t l r

Step 4. Remove: t l

Finally, w e remove t’s and l’s. We’re left with just the sandwich at the end.

Remove: t l t l

The above steps are a visual representation of how functions are evaluated. They are equivalent to how JavaScript evaluates (sushi => sushi)('sandwich') .

By learning these rules, non-programmers will be able to evaluate functions intuitively.

Note: The above steps would look very confusing to most programmers. As programmers, we already know how to evaluate functional expressions, and we instinctively try to map the above diagrams to code in our head. But in my testing, it seems to be less confusing to non-programmers who don’t already have a mental model of function evaluation. Furthermore, in the course itself, I slow down and spend a lot more time covering the above rules—the explanations are spread out in a full page (here). And I don’t show any code in my course—I only show emoji puzzles, so one less source of confusion compared to this article. One thing I learned is that the feedback on my course from programmers and non-programmers are complete opposites—generally negative from programmers but generally positive from non-programmers. I believe that’s because many programmers find that using code is simpler than using the above diagrams, but many non-programmers think the opposite. Some people have incredible difficulty understanding code or math symbols, and sometimes visual alternatives help them. I believe the more alternative teaching methods are offered in CS education, the better.

4 / 10 · From my course’s Beginner 4 level Step/ 10

If there’s no match

Let’s take a look at the other example from earlier:

Functional JS code: ( sushi => 'pizza' ) ( 'sandwich' )

Equivalent emoji puzzle:

Try pressing the R un button and see what happens:

Run (Show every step)

Here are the three steps it displayed:

Step 1. Label: t l r—this is the same as before.

Label: t l r t l r

Step 2. This time, there’s no match between l and r. The bottom-left is sushi , but the bottom-right is pizza .

No match: l r t l r

If there’s no match, we skip step 3 (Copy: t r) and go directly to step 4.

Step 4. Remove: t l

t l

So we’re left with a pizza . That’s how the emoji puzzle visualizes the evaluation of a function when there’s no matching variable in the function body.

More examples (optional read): Here are more examples that might be helpful for your understanding. You can press R un on each example to see the evaluation visualization. (Or press to step through manually.) Functional JS code: ( pizza => pizza ) ( spaghetti => 'bread' ) Result: (spaghetti => 'bread') Equivalent emoji puzzle: Run (Show every step) Functional JS code: ( salad => 'hotDog' ) ( curry => 'tacos' ) Result: 'hotDog' Equivalent emoji puzzle: Run (Show every step)

5 / 10 · From my course’s Beginner 5 level Step/ 10

More complicated expressions

Let’s take a look at more complicated functional JS expressions and see if they can be represented using an emoji puzzle.

Check out the following JS expression, and try to guess what the result would be before pressing the R un button.

Guess what the result would be

before pressing the R un button. ( sushi => sandwich => sushi ) ( 'hamburger' ) ( 'chicken' ) Run

The result was 'hamburger' . It’s because:

sushi is bound to 'hamburger' ,

is bound to , sandwich is bound to 'chicken' ,

is bound to , And it returns the value of sushi , which is 'hamburger' .

Now, here’s the equivalent emoji puzzle:

2 1 1 2

Let’s break it down. First, the function expression…

( sushi => sandwich => sushi ) ( 'hamburger' ) ( 'chicken' )

…is represented by the bottom row:

sushi => sandwich => sushi 2 1 1 2

And the two arguments…

( sushi => sandwich => sushi ) ( 'hamburger' ) ( 'chicken' )

…are represented by the top and the middle rows:

('hamburger')('chicken') 2 1 1 2

How do we evaluate this function? Well, in JS, we first evaluate the function call with the argument 'hamburger' .

In JS, we evaluate this part first ( sushi => sandwich => sushi ) ( 'hamburger' ) ( 'chicken' )

Equivalently, in an emoji puzzle, we evaluate the bottom two rows first. We ignore the top row initially, which is shaded in blue.

Focus on the bottom two rows , and

Ignore the top row for now 2 1 1 2

Also, if you look at the left edge of the puzzle above, the bottom two rows correspond to the pair of 1’s. That’s how you know that you must start with the bottom two rows. In an emoji puzzle with 3 rows, you start with the pair of 1’s.

Next, let’s label each item on the bottom two rows. This time, in addition to t l r, we now have a new label m for the sandwich .

There’s a new label m

for the sandwich 2 1 t l 1 2 m r

Here’s the rule: The middle item on the bottom row is labeled as m (for “Middle”), and you can ignore it. You can pretend that m’s don’t exist.

Let’s take a look at the next few steps in this iteration, which is just like what we saw earlier:

There’s a match among l ’s and r ’s 2 1 t l 1 2 m r

Copy t ’s to where the matched r ’s are 2 1 t l 1 2 m r

Remove t ’s and l ’s 2 1 t l 1 2

1 1

This is exactly like how the earlier JS code is evaluated.

After evaluating this part… ( sushi => sandwich => sushi ) ( 'hamburger' ) ( 'chicken' )

…it becomes this, which is

equivalent to the above emoji puzzle

(but it’s not done yet!) ( sandwich => 'hamburger' ) ( 'chicken' )

But we’re not done yet! Let’s continue to the end by pressing the R un button below:

Let’s continue to the end! 1 1 Run (Show every step)

We ended up with a hamburger , which is exactly the same as what the JS code evaluated to.

What we have learned so far: Complex functional JS expressions can be represented and evaluated using an emoji puzzle. Functional JS code: ( sushi => sandwich => sushi ) ( 'hamburger' ) ( 'chicken' ) Result: 'hamburger' Equivalent emoji puzzle:

(Start with the pair of 1 ’s) 2 1 1 2

More examples (optional read): Here’s another example that might be helpful for your understanding. Check out the following JS expression, and try to guess what the result would be before pressing the R un button. Guess what the result would be

before pressing the R un button. ( friedPotatoes => pizza => pizza ) ( spaghetti => spaghetti ) ( 'salad' ) Run The result was 'salad' . Now, here’s the equivalent emoji puzzle below. Try pressing R un . Again, remember that: We start with the pair of 1 ’s.

’s. The middle item on the bottom row is labeled as m , and you can ignore it . Equivalent emoji puzzle: 2 1 1 2 Run (Show every step) Next, here’s slightly different JS code. Compared to the last time, there’s an extra pair of parentheses around (spaghetti => spaghetti)('salad') , which changes the result. Guess what the result would be

before pressing the R un button. ( friedPotatoes => pizza => pizza ) ( ( spaghetti => spaghetti ) ( "salad" ) ) Run Let’s take a look at the equivalent emoji puzzle. This time, the pair of 1’s is on the top two rows instead. So we start with the top two rows this time. Try pressing R un and see what happens. This time, the pair of 1 ’s is

on the top two rows instead 1 2 1 2 Run (Show every step) Summary: In JavaScript , you can change the evaluation order of an expression by placing parentheses on different locations.

, you can change the evaluation order of an expression by placing parentheses on different locations. In emoji puzzles , you can change the evaluation order by placing the numbers (e.g. 1 ’s and 2 ’s) on different locations.

6 / 10 · From my course’s Intermediate 1 level Step/ 10

Church numerals

You’re halfway there: 5 steps down, 5 more to go! If you’re thinking of taking a break, I’d appreciate it if you could Share this article on Twitter before you close this page.

From now on, we’ll apply what we’ve learned so far to solve more interesting problems.

Here’s a function called convert that takes a function f as an argument. It then calls f with (n => n + 1)(0) .

function convert ( f ) { return f ( n => n + 1 ) ( 0 ) }

Now, suppose that we apply convert on this function: sushi => sandwich => sandwich . What would the result be? Try to guess before pressing the R un button.

Guess what the result would be

before pressing the R un button. function convert ( f ) { return f ( n => n + 1 ) ( 0 ) } convert ( sushi => sandwich => sandwich ) Run

The result is 0 because:

sushi is bound to n => n + 1

is bound to sandwich is bound to 0

is bound to And it returns sandwich , which is 0 .

Next: What if the input to convert changes as follows? Try pressing R un on each example.

convert ( sushi => sandwich => sushi ( sandwich ) ) Run

convert ( sushi => sandwich => sushi ( sushi ( sandwich ) ) ) Run

convert ( sushi => sandwich => sushi ( sushi ( sushi ( sandwich ) ) ) ) Run

The results are 1 , 2 , and 3 respectively because:

sushi is bound to n => n + 1

is bound to sandwich is bound to 0

is bound to So it applies n => n + 1 to 0 for the number of times sushi is used in the function body.

What we have learned so far: If we have a function that has one of the following patterns: a => b => b a => b => a ( b ) a => b => a ( a ( b ) ) a => b => a ( a ( a ( b ) ) ) Then, when the function is passed to convert() , it returns the number of times a is applied to b in the function body. convert ( a => b => b ) convert ( a => b => a ( b ) ) convert ( a => b => a ( a ( b ) ) ) convert ( a => b => a ( a ( a ( b ) ) ) )

Important: These functions that can be converted to a number using convert() have a special name. They are called Church numerals. Each function represents a Church numeral, like this:

a => b => b a => b => a ( b ) a => b => a ( a ( b ) ) ) a => b => a ( a ( a ( b ) ) ) )

You might be wondering: “What’s the point of this?” Don’t worry—I’ll tell you why Church numerals are interesting shortly. But before I do, let me explain how emoji puzzles can express Church numerals.

Here’s an emoji puzzle that represents sushi => sandwich => sandwich , which is Church numeral 0.

Represents:

sushi => sandwich => sandwich

(Church numeral 0 )

Here’s what’s new: We now have the “C onvert to a Number” button below the puzzle which converts it to the corresponding Church number. Try pressing it:

C onvert to a Number ↑ Press this button!

Other Church numeral functions can also be represented using emoji puzzles, and they can be converted to a number. And we can use emojis other than and —as long as they follow the same pattern.

Represents:

hamburger => chicken => hamburger(chicken)

(Church numeral 1 ) 1 1 C onvert to a Number

Church numeral 2 1 2 1 2 C onvert to a Number

Church numeral 3 1 2 3 1 2 3 C onvert to a Number

Now that we’ve covered the basics of Church numerals, we’ll talk next about why Church numerals are interesting.

7 / 10 · From my course’s Intermediate 3 level Step/ 10

Arithmetic with functions

Church numerals are interesting because they let you do arithmetic with functions. Take a look at this function:

sushi => sandwich => pizza => sandwich ( sushi ( sandwich ) ( pizza ) )

It looks pretty complicated, but don’t worry too much. Now, suppose that:

We apply the above function to the Church numeral zero (has the pattern a => b => b ), and

), and Run convert() (from earlier) on it.

(from earlier) on it. What would the result be?

Let’s take a look. Try to guess before pressing the R un button.

const f = sushi => sandwich => pizza => sandwich ( sushi ( sandwich ) ( pizza ) ) const zero = chicken => salad => salad convert ( f ( zero ) ) Run

The result is 1 , which is 1 greater than the input Church numeral, which was 0 . In other words, 0 became 1 .

0 became 1

Here’s the secret: This function f we used actually adds 1 to the input Church numeral. When you apply f to a Church numeral, it returns a new Church numeral that’s 1 greater than before.

const f = sushi => sandwich => pizza => sandwich ( sushi ( sandwich ) ( pizza ) )

You can try out more examples to verify this:

const one = chicken => salad => chicken ( salad ) convert ( f ( one ) ) Run

const two = chicken => salad => chicken ( chicken ( salad ) ) convert ( f ( two ) ) Run

This is what I mean by “doing arithmetic with functions”:

By using a Church numeral function that can be converted to someNumber …

… …and the function f we saw earlier,

we saw earlier, You can calculate someNumber + 1 .

You can calculate someNumber + 1

using just functions

Now, let’s see if we can explain this to non-programmers using emoji puzzles.

First, here’s an emoji puzzle representation of the Church numeral 0. You can confirm that it can be converted to by pressing the button below.

Represents:

chicken => salad => salad

(Church numeral 0 ) C onvert to a Number

And here’s the function f we saw earlier, represented as an emoji puzzle:

const f = sushi => sandwich => pizza => sandwich ( sushi ( sandwich ) ( pizza ) )

Equivalent emoji puzzle: 2 3 1 1 2 3

Let’s apply f to the Church numeral 0. To do that, we just combine the above two emoji puzzles and run it. Press R un :

Combined the above two emoji puzzles 1 1 2 3 1 1 2 3 Run (Show every step) Skip to the end →

The result is equivalent to sandwich => pizza => sandwich(pizza) , which is Church numeral 1.

Represents:

sandwich => pizza => sandwich(pizza)

(Church numeral 1 ) 1 1 C onvert to a Number

What just happened: An emoji puzzle that can be converted to became a puzzle that can be converted to . 1 Emoji puzzle that can be converted to 1 2 3 1 1 2 3 Emoji puzzle that can be converted to In other words: We can use an emoji puzzle to calculate someNumber + 1 .

More examples (optional read): Let’s see if we can calculate 1 + 1 = 2 using the same method. Here’s an emoji puzzle that can be converted to : Represents:

chicken => salad => chicken(salad)

(Church numeral 1 ) 1 1 C onvert to a Number And let’s combine it with the earlier emoji puzzle and run it. Press R un : 1 1 1 1 2 3 1 1 2 3 Run (Show every step) Skip to the end → The result is equivalent to Church numeral 2 and can be converted to . Church numeral 2 1 2 1 2 C onvert to a Number So, it successfully calculated 1 + 1 = 2 . Again, this is what just happened: 1 Emoji puzzle that can be converted to 1 2 3 1 1 2 3 Emoji puzzle that can be converted to

8 / 10 · From my course’s Advanced 5 level Step/ 10

Multiplications

You can do pretty much any computation with Church numerals. Consider multiplication. Here’s a JS function that multiplies two Church numerals:

const mul = sushi => sandwich => pizza => sushi ( sandwich ( pizza ) )

Let’s compute 2 x 3 using the above mul function. We use two Church numeral functions—one for 2 and the other for 3 , and feed them into mul . Take a look at the code below and press R un :

const two = chicken => salad => chicken ( chicken ( salad ) ) const three = curry => hamburger => curry ( curry ( curry ( hamburger ) ) ) const result = mul ( two ) ( three ) convert ( result ) Run

The result was 6 , so it successfully calculated 2 x 3 .

Now, let’s see if we can do the same using emoji puzzles. First, here’s an emoji puzzle that’s equivalent to the mul function.

const mul = sushi => sandwich => pizza => sushi ( sandwich ( pizza ) )

Equivalent emoji puzzle: 1 2 1 2

Let’s combine it with emoji puzzles that can be converted to and :

Converts to 1 2 1 2 Converts to 1 2 3 1 2 3

Here’s the combined puzzle. Press R un and see what happens. (Because it takes time, we’ll fast-forward it at 4x speed.)

2 1 2 1 2 1 1 2 3 1 2 3 1 2 1 2 1 2 Run (Show every step) Skip to the end →

The result is equivalent to Church numeral 6 and can be converted to .

Church numeral 6 1 2 3 4 5 6 1 2 3 4 5 6 C onvert to a Number

So emoji puzzles can calculate multiplications too. In my course, I also show how we can do subtractions using emoji puzzles. Divisions are very complicated but possible.

9 / 10 · From my course’s Advanced 2 level Step/ 10

Conditionals

In addition to arithmetic, we can also implement conditionals such as if/else statements using emoji puzzles.

Consider the following JS code. This is a simple if/else statement that does different things based on what x is.

if ( x === 0 ) { } else { }

It turns out that if/else statements like the above can also be expressed using Church numerals. To save time, I won’t show JS code this time and will only show the emoji puzzle. Check out the following:

An emoji puzzle that represents

if (x === 0) { ... } else { ... } 4 3 2 1 Emoji puzzle that can be converted to 1 2 3 4

The above emoji puzzle will become:

if you put an emoji puzzle that can be converted to on the bottom

if you put an emoji puzzle that can be converted to on the bottom otherwise

Let’s try it out. First, we’ll put an emoji puzzle that can be converted to on the bottom. Press R un :

The bottom emoji puzzle (yellow background)

can be converted to 4 3 2 1 1 2 3 4 Run (Show every step) Skip to the end →

What just happened: We started out with , and it ended up with .

Now, what if we started out with an emoji puzzle that can be converted to ? Press R un :

The bottom emoji puzzle (yellow background)

can be converted to 4 3 2 1 1 2 3 4 1 1 Run (Show every step) Skip to the end →

What just happened: We started out with , and it ended up with .

As you just saw, in addition to math expressions, we can also represent conditional statements using emoji puzzles.

Column: Lambda calculus and Church encoding: There’s a programming language called Lambda calculus (Wikipedia), created by a mathematician Alonzo Church in 1930s. It only has two features: variables and anonymous functions. Here’s a piece of lambda calculus code: λ is the greek alphabet “lambda” λsushi.sushi sandwich The above code is equivalent to the following JS code. There are no strings in lambda calculus—everything is either a variable or an anonymous function. ( sushi => sushi ) ( sandwich ) You might have realized that all the functional JS code we represented using emoji puzzles can be expressed in lambda calculus. For example, the emoji puzzle that multiplies two Church numerals… Emoji puzzle that multiplies

two Church numerals 1 2 1 2 …is equivalent to the following lambda calculus code: Equivalent lambda calculus code λsushi.λsandwich.λpizza sushi (sandwich pizza) So, here’s the secret: My emoji puzzles are actually a visual representation of lambda calculus. And by using emoji puzzles, lambda calculus can be explained visually to non-programmers! My emoji puzzles are actually

a visual representation of lambda calculus Finally: We saw that emoji puzzles, or lambda calculus, can express not only numbers and arithmetic but also conditionals. In fact, lambda calculus can express pretty much anything any programming language can do—it’s Turing complete. And this method of encoding data and operators using lambda calculus is called Church encoding (Wikipedia).

10 / 10 · From my course’s Advanced 4 level Step/ 10

Control flow and Y combinator

You’re almost done: This is the final step in this article.

Question: If we can express conditionals (e.g. if ) using functions/emoji puzzles, can we express control flow (e.g. loops) as well?

The answer is yes. We can express control flow using Y combinator.

Y combinator is a function that allows you to create a recursive function without using named functions.

Y combinator is complex, so if we go into detail we’ll need another article. In fact, I used two full pages (here and here) in my course to explain Y combinator using emoji puzzles. So here I’ll briefly explain what Y combinator is.

Take a look at this JS code. It calculates the factorial of a number using recursion.

Calculates the factorial of a number:

n * n-1 * ... * 1 function fact ( n ) { if ( n === 0 ) { return 1 } else { return n * fact ( n - 1 ) } }

If you run it on 5 , it calculates 5 * 4 * 3 * 2 * 1 . Press R un :

5 * 4 * 3 * 2 * 1 fact ( 5 ) Run

Note that the above recursive function was a named function. It had the name fact , which was called from the function body to do recursion.

This is a named function called fact function fact ( n ) { if ( n === 0 ) { return 1 } else { return n * fact ( n - 1 ) } }

You’d usually use a named function to do recursion. However, if you use Y combinator, you can do recursion without using a named function.

Let me show you how. Here’s the Y combinator function yc :

The Y combinator function const yCombinator = sushi => ( pizza => sushi ( sandwich => pizza ( pizza ) ( sandwich ) ) ) ( pizza => sushi ( sandwich => pizza ( pizza ) ( sandwich ) ) )

Now, we’ll apply yCombinator on another anonymous function. This time, fact is NOT a function name, but it’s a parameter name. We haven’t used any named function yet—we’ve only used anonymous functions.

fact is now a parameter yCombinator ( fact => n => { if ( n === 0 ) { return 1 } else { return n * fact ( n - 1 ) } } )

Finally, let’s run the above function on 5 and see what happens:

Run it on 5 yCombinator ( fact => n => { if ( n === 0 ) { return 1 } else { return n * fact ( n - 1 ) } } ) ( 5 ) Run

The result was 120 , so it successfully calculated the factorial 5 * 4 * 3 * 2 * 1 .

So: By using the yCombinator function, you can create a recursive function without using named functions. It allows you to implement control flow (loops) using anonymous functions.

Of course, Y combinator can be represented using an emoji puzzle:

The Y combinator function const yCombinator = sushi => ( pizza => sushi ( sandwich => pizza ( pizza ) ( sandwich ) ) ) ( pizza => sushi ( sandwich => pizza ( pizza ) ( sandwich ) ) )

Y combinator using emojis 1 1 2 1 1 2 1 1 1 2 1 1 2 1

In the final lesson of my course, I show how to use the Y combinator emoji puzzle to calculate factorials (I won’t show it here because it’s pretty complex).

In any case, you can teach Y combinator to non-programmers using emoji puzzles.

The Y Combinator I showed above is for applicative order languages like JavaScript. For normal order languages like Haskell, Y Combinator would look visually simpler, like this: Y Combinator for

normal order languages 1 1 2 2 1 1 1 2 2 1 The emoji puzzles on this page run in the applicative order because I tried to compare it with JavaScript. However, in my course, the emoji puzzles actually run in the normal order instead, simply because Y Combinator would be visually less complex. The bottom line is that my emoji puzzles support both applicative and normal orders of evaluation, which was nontrivial to implement.

If you are interested in learning about Y Combinator, I recommend this video: “Y Not- Adventures in Functional Programming”. This is a talk by Jim Weirich, a legendary Ruby programmer who passed away in 2014. He gave this talk at RubyConf 2012, and I was in the audience. It was an amazing talk.

Conclusion

One-line summary: By using emoji puzzles, you explain functional programming concepts such as lambda calculus, Church encoding, and Y combinator to non-programmers—without using any code.

Why did I make emoji puzzles? As someone who is passionate about teaching, I wanted to challenge myself to explain a difficult computer science concept (like Y combinator) to non-programmers while satisfying the following constraints:

Don’t use any code

Don’t sacrifice rigor

Must be doable on a smartphone in under 2-3 hours

That’s how I came up with emoji puzzles (they’re smartphone-friendly too). In the future, I plan to develop something similar with other CS topics. In the meantime, you can take a look at my course, Y Combinator for Non-programmers, here:

Thank you for reading!

I’d love it if you could share this on Twitter. Click here to Tweet this article.

Click here to Tweet this article. Also, the source code is available on GitHub:

Here’s my Twitter:

This article was published on Nov 8, 2019 .

About me: I’m Shu Uesugi, a full-stack developer based in San Francisco Bay Area, USA.