diff --git a/pages/functional-programming-emojis.tsx b/pages/functional-programming-emojis.tsx index 9b3360b94..9a56512ab 100644 --- a/pages/functional-programming-emojis.tsx +++ b/pages/functional-programming-emojis.tsx @@ -217,7 +217,7 @@ const InlineCode = ({ css={css` font-weight: 400; font-family: ${codeFontFamily}; - background-color: ${highlighted ? colors('yellow300') : colors('codeBg')}; + background-color: ${highlighted ? colors('yellow200') : colors('codeBg')}; display: inline-block; font-size: 0.85em; padding: 0.075em 0.2em; @@ -499,7 +499,7 @@ const guessTheResult = ( <> Guess what the result would be
- before pressing the button! + before pressing the button. ) @@ -639,8 +639,8 @@ export default () => { In the first half (steps 1 - 5): I’ll show you how simple JavaScript code can be represented visually using my - emoji puzzles. Even if you’re not familiar with JS, you should - still be able to understand it. + 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 @@ -668,7 +668,7 @@ export default () => { Identity function in JS

- First, take a look at the following code. It’s an{' '} + Take a look at the following code. It’s an{' '} identity function in JavaScript that returns the argument.

@@ -676,20 +676,20 @@ export default () => { sushi => sushi`}

If you apply the above function on a string{' '} - 'sandwich', then the result would be{' '} + 'sandwich', the result will be{' '} 'sandwich'.

- {`// The result would be 'sandwich' + {`// The result will be 'sandwich' (sushi => sushi)('sandwich')`}

- Now, here’s the interesting part: One day, I realized - that the above JS code can be{' '} - described visually using emojis. Check this out: + 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
- the JS code from the above + (sushi => sushi)('sandwich')

The above emoji puzzle is equivalent to the earlier JS code. @@ -702,8 +702,8 @@ sushi => sushi`} } >{`(sushi => sushi)('sandwich')`}

- …is represented by the bottom two items on the - puzzle, which are both . + …is represented by the bottom two items, which + are both .

@@ -722,8 +722,8 @@ sushi => sushi`}
} >{`(sushi => sushi)('sandwich')`}

- …is represented by the top item on the puzzle, - which is a . + …is represented by the top item, which is a{' '} + .

@@ -738,39 +738,50 @@ sushi => sushi`} it.

- Note: To keep things simple, this puzzle doesn’t - distinguish between variable names (e.g.{' '} - sushi) and strings (e.g.{' '} - 'sushi'). Therefore, both{' '} - sushi and{' '} - 'sushi' will be represented as{' '} - . +

+ 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. 😉 +

Running the function

I’ve added the button to the JS code - snippet so you can see the result.{' '} - - If you press , - {' '} - you’ll see that the result is 'sandwich'. + snippet below. If you press it, you’ll see + that the result is 'sandwich'.

{`(sushi => sushi)('sandwich')`}

- Now, we can also “run” the equivalent emoji puzzle and get the - same result.{' '} + We can also “run” the equivalent emoji puzzle and get the same + result.{' '} - Try pressing the button below the - puzzle. + Try pressing the button below.

- + + An emoji puzzle that’s equivalent to +
+ (sushi => sushi)('sandwich') +

The result is a , which is the same as @@ -780,15 +791,13 @@ sushi => sushi`} So, you can an emoji puzzle just as you can run a piece of JS code.{' '} - Basically, this is how I taught functional programming to - non-programmers in my course ( + This is how I taught functional programming to non-programmers + in my course ( Y Combinator for Non-programmers )—without showing any code. - {' '} - I could have used letters instead of emojis, but emojis are less - scary-looking for non-programers. +

Let’s take a look at another example. Here’s a piece @@ -811,7 +820,11 @@ sushi => 'pizza'`} this code can be represented using an emoji puzzle as follows.{' '}

- + + An emoji puzzle that’s equivalent to +
+ (sushi => 'pizza')('sandwich') +

Just like the JS code, the emoji puzzle ended up with a{' '} after running it. @@ -819,7 +832,7 @@ sushi => 'pizza'`}

What we have learned so far: Simple JS code like - below can be visually represented using emoji puzzles. + below can be represented using emoji puzzles.

'pizza'`} Visualizing evaluation rules

- Because 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'. If you see{' '} - (sushi => 'pizza')('sandwich'), you know - that the result would be 'pizza'. You - know what free variables and bound variables mean. + 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'. + + + If you see{' '} + (sushi => 'pizza')('sandwich'), you + know that the result would be 'pizza'. + + + You know what free variables and bound variables mean. + +

- On the other hand, non-programmers may not have a mental model of - how function evaluation works. To help them develop a mental model - without showing them any code, I created a{' '} - step-by-step visualization of function evaluation - rules using the emoji puzzle I mentioned earlier. + 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:

'pizza'`} try pressing the button - . This button is a bit different from the last time— - - it shows all the steps that happen in between the beginning and - the end - - . + . This button is a bit different from the last time—it shows{' '} + every step that happens in between.

@@ -944,11 +964,13 @@ sushi => 'pizza'`}

- The above steps visually represent how functions are - evaluated—they are equivalent to how JavaScript evaluates{' '} - (sushi => sushi)('sandwich'). By learning - these rules, non-programmers can evaluate functions intuitively, - without learning about how variable bindings work. + 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.

If there’s no match @@ -1008,17 +1030,16 @@ sushi => 'pizza'`}

- That’s how the emoji puzzle visualizes the evaluation of a - function when there’s no matching variable in the function - body—like{' '} - {`(sushi => 'pizza')('sandwich')`}. + So we’re left with a . 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 + press {' '} on each example to see the evaluation visualization.{' '} @@ -1042,8 +1063,10 @@ sushi => 'pizza'`}

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 + 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{' '} @@ -1056,7 +1079,7 @@ sushi => 'pizza'`} <> Guess what the result would be
- before pressing the button! + before pressing the button. } >{`(sushi => sandwich => sushi)( @@ -1064,13 +1087,23 @@ sushi => 'pizza'`} )('chicken')`}

The result was {`'hamburger'`}. It’s - because {'sushi'} is bound to{' '} - {`'hamburger'`},{' '} - {'sandwich'} is bound to{' '} - {`'chicken'`}, and it returns what’s in{' '} - {'sushi'}. + because:

-

And here’s the equivalent emoji puzzle:

+
    + + {'sushi'} is bound to{' '} + {`'hamburger'`}, + + + {'sandwich'} is bound to{' '} + {`'chicken'`}, + + + And it returns the value of {'sushi'}, + which is {`'hamburger'`}. + +
+

Now, here’s the equivalent emoji puzzle:

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

'pizza'`}

- Now, let’s talk about how we evaluate this function. In JS, we - first evaluate the function call with the argument{' '} + How do we evaluate this function? Well, in JS, we first evaluate + the function call with the argument{' '} 'hamburger'.

'pizza'`} )('chicken')`}

Equivalently, in an emoji puzzle,{' '} - we evaluate the bottom two rows first. We ignore - the top row initially, which is shaded in blue. + 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 @@ -1127,10 +1160,11 @@ sushi => 'pizza'`} Ignore the top row for now

- If you look at the left edge of the puzzle, the bottom two rows - correspond to the pair of{' '} + 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 the rule:{' '} + ’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. @@ -1157,15 +1191,18 @@ sushi => 'pizza'`}

Here’s the rule:{' '} - The middle items on the bottom row are labeled as{' '} - , - and you can ignore them. + The middle item on the bottom row is labeled as{' '} + {' '} + (for “Middle”), and you can ignore it. {' '} You can pretend that{' '} - ’s don’t exist and apply the other rules from before. + ’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:

-

Let’s take a look at the next few steps in this iteration:

@@ -1191,6 +1228,8 @@ sushi => 'pizza'`} …it becomes this, which is
equivalent to the above emoji puzzle +
+ (but it’s not done yet!) } >{`(sandwich => 'hamburger')('chicken')`} @@ -1203,14 +1242,13 @@ sushi => 'pizza'`} Let’s continue to the end!

We ended up with a , which is exactly - the same as what the JS code evaluated to. So we’ve shown that - complex functional JS expressions can be represented using an - emoji puzzle. + the same as what the JS code evaluated to.

What we have learned so far: Complex functional JS - expressions can be represented using an emoji puzzle. + expressions can be represented and evaluated using an emoji + puzzle.

'pizza'`} 1’s.
- The middle items on the bottom row are labeled as{' '} + The middle item on the bottom row is labeled as{' '} - , and you can ignore them. + , and you can ignore it. Equivalent emoji puzzle:

- Next, here’s slightly different JS code.{' '} + Next, here’s slightly different JS code. Compared to the last + time,{' '} - There’s an extra pair of parentheses around{' '} - (spaghetti => spaghetti)('salad'), so - this will be evaluated first + there’s an extra pair of parentheses around{' '} + (spaghetti => spaghetti)('salad'), + which changes the result. - , and the result will be different from the last time.

pizza`} caption={guessTheResult} - >{`(friedPotatoes => pizza => pizza)( + >{`// There’s an extra pair of parens around +// (spaghetti => spaghetti)("salad") +(friedPotatoes => pizza => pizza)( (spaghetti => spaghetti)("salad") )`}

@@ -1286,11 +1326,11 @@ sushi => 'pizza'`} the pair of 1’s is on the top two rows {' '} - instead.{' '} + instead. So we start with the top two rows this time.{' '} Try pressing {' '} - and see what happens! + and see what happens.

This time, the pair of{' '} @@ -1322,12 +1362,39 @@ sushi => 'pizza'`} 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. +

- Let’s apply what we’ve learned and solve more interesting - problems. First, here’s a function called{' '} - convert that takes a function as an - argument. It then applies (n => n + 1)(0){' '} - to it. + 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) @@ -1370,7 +1437,8 @@ convert(sushi => sandwich =>

- Now, what if the input changes as follows?{' '} + Next: What if the input to{' '} + convert changes as follows?{' '} Try pressing on each example. @@ -1431,13 +1499,17 @@ convert(a => b => a(a(a(b)))) // 3 // ...and so on...`}

- These functions that can be converted to numbers using{' '} - convert() have a{' '} - special name. They are called{' '} + 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. + . Each function represents a Church numeral, like this:

{`// Church numeral 0 a => b => b @@ -1454,8 +1526,11 @@ a => b => a(a(a(b)))) // ...and so on...`}

You might be wondering: “What’s the point of this?” - I’ll explain it shortly, but before I do so, let me explain how my - emoji puzzles can express Church numerals. + 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{' '} @@ -1472,22 +1547,21 @@ a => b => a(a(a(b))))

Here’s what’s new:{' '} - We now have a {' '} - button below the puzzle which converts it to the corresponding + We now have the “ + ” button below the puzzle which converts it to the corresponding Church number. {' '} - Try pressing it. + Try pressing it:

Other Church numeral functions can also be represented using emoji - puzzles, and they can be converted as well. Of course, the emojis - don’t need to be and{' '} - - —they can be other emojis, as long as they follow the same - pattern. + 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: @@ -1509,12 +1583,12 @@ a => b => a(a(a(b)))) next about why Church numerals are interesting.

- You can do maths with functions + Arithmetic with functions

Church numerals are interesting because{' '} - they let you do maths with functions. First, take - a look at this function: + they let you do arithmetic with functions. Take a + look at this function:

{`sushi => sandwich => pizza => sandwich( @@ -1526,19 +1600,19 @@ a => b => a(a(a(b))))

    - We apply the above function to the Church numeral zero ( has the + We apply the above function to the Church numeral zero (has the pattern a => b => b), and Run convert() (from earlier) on it. - What would the result be? + What would the result be?

Let’s take a look.{' '} Try to guess before pressing the {' '} - button! + button.

{`// Function from the above @@ -1555,18 +1629,31 @@ const zero = chicken => salad => salad convert(f(zero))`}

The result is 1, which is 1 greater than - the input Church numeral, which was 0. - Basically, 0 became{' '} + the input Church numeral, which was 0. In + other words, 0 became{' '} 1.

+ , + , + + ]} + description={ + <> + 0 became 1 + + } + />

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

{`// If we apply this function to a // Church numeral, it returns a new @@ -1588,20 +1675,40 @@ const two = chicken => salad => convert(f(two))`}

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

    - You can calculate someNumber + 1… + + By using a Church numeral function that can be converted to{' '} + someNumber… + - By using a Church numeral function that can be converted to{' '} - someNumber… + + …and the function f we saw earlier, + - And the function f we saw earlier. + + You can calculate someNumber + 1. +
+ , + , + + ]} + description={ + <> + You can calculate someNumber + 1 +
+ using just functions + + } + />

Now, let’s see if we can explain this to non-programmers using @@ -1611,7 +1718,7 @@ convert(f(two))`}

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. + by pressing the button below.

Represents: @@ -1665,8 +1772,7 @@ convert(f(two))`}
In other words:{' '} We can use an emoji puzzle to calculate{' '} - someNumber + 1, in a way that’s - equivalent to using Church numeral functions in JS. + someNumber + 1.

@@ -1698,7 +1804,7 @@ convert(f(two))`}

So, it successfully calculated{' '} - 1 + 1 = 2! Again, this is what just + 1 + 1 = 2. Again, this is what just happened:

@@ -1718,8 +1824,10 @@ const mul = sushi => sandwich => pizza => sushi(sandwich(pizza))`}

Let’s compute 2 x 3 using the above{' '} - mul function. Take a look at the code - below and{' '} + 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 @@ -1779,7 +1887,7 @@ const mul = sushi => sandwich => pizza => Press {' '} and see what happens. (Because it takes time, we’ll fast-forward - it at 4x the speed.) + it at 4x speed.)

@@ -1797,9 +1905,9 @@ const mul = sushi => sandwich => pizza => Conditionals

- In addition to math expressions, we can also represent{' '} + In addition to arithmetic, we can also implement{' '} conditionals such as if/else{' '} - statements using just functions/emoji puzzles. + statements using emoji puzzles.

Consider the following JS code. This is a simple{' '} @@ -1814,8 +1922,12 @@ const mul = sushi => sandwich => pizza =>

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: + 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 @@ -1843,7 +1955,7 @@ const mul = sushi => sandwich => pizza =>

- The bottom emoji puzzle (in the yellow background) + The bottom emoji puzzle (yellow background)
can be converted to
@@ -1861,7 +1973,7 @@ const mul = sushi => sandwich => pizza =>

- The bottom emoji puzzle (in the yellow background) + The bottom emoji puzzle (yellow background)
can be converted to
@@ -1874,8 +1986,7 @@ const mul = sushi => sandwich => pizza =>

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

@@ -1887,8 +1998,8 @@ const mul = sushi => sandwich => pizza => Wikipedia - ), created by a mathematician Alonzo Church. It only has two - features:{' '} + ), 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:

@@ -1925,7 +2036,7 @@ const mul = sushi => sandwich => pizza => noHighlight caption={<>Equivalent lambda calculus code} >{`λsushi.λsandwich.λpizza - sushi(sandwich pizza)`} + sushi (sandwich pizza)`}

So, here’s the secret:{' '} @@ -1968,14 +2079,22 @@ const mul = sushi => sandwich => pizza => Control flow and Y combinator - You’re almost done: This is the final step in this - article. +

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

- 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{' '} + 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 @@ -1991,10 +2110,10 @@ const mul = sushi => sandwich => pizza =>

Y combinator is complex, so if we go into detail we’ll need another article. In fact, I used two full pages ( - page 1,{' '} - page 2) in my course to - explain Y combinator using emoji puzzles. So here I’ll explain - what Y combinator is briefly. + 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{' '} @@ -2024,15 +2143,16 @@ const mul = sushi => sandwich => pizza => - 5 * 4 * 3 * 2 *1 + 5 * 4 * 3 * 2 * 1 } result="120" >{`fact(5)`}

- The above recursive function was a named{' '} - function. It had the name fact, which was - called from the function body to do recursion. + 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.

@@ -2059,7 +2179,9 @@ const mul = sushi => sandwich => pizza => if you use Y combinator, you can do recursion without using a named function. {' '} - First, here’s the Y combinator function{' '} +

+

+ Let me show you how. Here’s the Y combinator function{' '} yc:

sandwich => pizza => )`}

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. + 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.

sandwich => pizza => })(5) // ← run it on 5`}

The result was 120, so it successfully - calculated the factorial. + calculated the factorial{' '} + 5 * 4 * 3 * 2 * 1.

So:{' '} By using the yCombinator function, you - can create a recursive function using only anonymous functions. + can create a recursive function without using named functions. {' '} It allows you to implement control flow (loops) using anonymous functions. @@ -2154,8 +2281,8 @@ const mul = sushi => sandwich => pizza => the final lesson of my course - , I show how to use the above emoji puzzle to calculate factorials - (I won’t show it here because it’s pretty complex). + , 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,{' '} @@ -2165,7 +2292,7 @@ const mul = sushi => sandwich => pizza =>

- + Conclusion @@ -2184,8 +2311,9 @@ const mul = sushi => sandwich => pizza => I wanted to challenge myself to explain a{' '} difficult computer science concept (like Y - combinator) to non-programmers under the following constraints: - + combinator) to non-programmers + {' '} + while satisfying the following constraints:

    Don’t use any code @@ -2193,8 +2321,10 @@ const mul = sushi => sandwich => pizza => Must be doable on a smartphone in under 2-3 hours

- In the future, I plan to do something similar with other CS - topics. In the meantime, you can take a look at my course,{' '} + 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 diff --git a/src/contents/0.en.tsx b/src/contents/0.en.tsx index 77a9c5606..6d1a5ca76 100644 --- a/src/contents/0.en.tsx +++ b/src/contents/0.en.tsx @@ -21,11 +21,11 @@ import YoutubeEmbed from 'src/components/YoutubeEmbed' import { githubRepo } from 'src/lib/meta' import * as R from 'src/components/Runners' -export const JimsTalk = () => ( +export const JimsTalk = ({ onBlog }: { onBlog?: boolean }) => ( <>

- For programmers interested in learning about Y Combinator, I recommend - this video:{' '} + {onBlog ? <>If you are : <>For programmers} interested in learning + about Y Combinator, I recommend this video:{' '} “Y Not- Adventures in Functional Programming” diff --git a/src/lib/theme/colors.ts b/src/lib/theme/colors.ts index bfb40b4a4..fbca65426 100644 --- a/src/lib/theme/colors.ts +++ b/src/lib/theme/colors.ts @@ -64,6 +64,7 @@ export const allColors = { blue400: blue[400], blue600: blue[600], yellow100: yellow[100], + yellow200: yellow[200], yellow300: yellow[300], yellow400: yellow[400], yellow900: yellow[900],