2025 James B. Wilson
\(I(x) = x\)
\(K_c(x)=c\)
So
\(K_x(x)=x\)?
A motivated introduction to \(\lambda\)-calculus
A fable by James B. Wilson
Every day Haskell Curry and Robert Feys would go to lunch at Constants.
The menu was always the one posted item.
On Curry days, Haskell was happy.
...but Robert would be sad.
A fable by James B. Wilson
On Fry days, Robert was delighted...
...but Haskell was mad.
A fable by James B. Wilson
Then one day the two of them had and idea!
Replace the menu with a variable so they could both order what they wanted!
Constant functions are
Graph is a horizontal line (Slope 0).
(Thanks to Desmos.com)
\(c\) in \(K_c(x)=c\) is a place-holder for some future choice.
(Thanks to Desmos.com)
I'm going to choose \(c:=x\).
\(K_x(x)=x\)
Graph that ...
IT HAS SLOPE 1!
Constant functions DON'T have slope 1, so what's the mistake?
\(x\) from alphabet of variables
\(a\) from separate alphabet of constants
\(\sigma\) a string of variables, constants, and the \(\mapsto\) symbol.
3. \(\begin{aligned} x7|_{x:=35+y} & \rhd (x|_{x:=35+y})(7|_{x:=35+y})\\ & \rhd (35+y)7\end{aligned}\)
2. \(5|_{x:=35+y}\rhd 5\)
Technical point, the parentheses, \(|\), \(:=\), and \(\rhd\) are outside the language, they are "meta-language".
> x:=35+y
> x
35+y> x:=35+y
> 27
27> x:=35+y
> (x-5)(x+5)
(35+y-5)(35+y+5)\[\begin{aligned} (x\mapsto x^2)|_{x:=35+y} & \rhd (x\mapsto x^2)\end{aligned}\]
x := 35+y
def f(x):
return x*xNot the "same" x.
4. Local Variables are invisible from outside scope: \[(x\mapsto \tau)|_{x:=\sigma}\qquad \text{yields}\qquad x\mapsto \tau\]
Not the "same" \(x\).
(More confusing in math notation.)
def f(x):
return x*xx := 35+y
def f(y):
s := 0
for x in [1..10]
s := y*x
return sNot the "same" x.
5. Avoid Trapping variables!
def f(y):
s := 0
for x in [1..10]
s := y*x
return sx := 35+pi
def f(y):
return y + x
SAME x.
If \(x\) is in \(\tau\) but free, then avoid trapping variables!
def f(y):
return y + (35+pi)
No "visible" y.
x := 35+y
def f(y):
return y + x
SAME x.
def f(y)
return y + (35+y)
y is visible (free)!
x := 35+y
def f(z):
return z + (35+y)
Not the same y.
x := 35+pi
def f(y)
return y + x
SAME x.
No "visible" y,
so not trapped
x := 35+y
def f(y)
return y + x
SAME x.
y is visible (free)!
So it is trapped between same x's
SAME x=c.
No "visible" x,
so not trapped
\(c:=5\)
\(K_c(x)=c\)
SAME x=c.
"visible" x,
trapped;
rename!
\(c:=x\)
\(K_c(x)=c\)
\(c:=x\)
\(K_c(z)=c\);
So \(K_x(z)=x\)
(still slope 0, but in the zx-plane)
\(K_5(x)=5\)
Math uses "=" to mean both "assign" and "test/assert equals".
\(y=3x+9\) is an implicit assignment of the variable \(y\). We are naming the function \(x\mapsto 3x+9\) with the letter \(y\)
Meanwhile here the "=" is to assert equality, the letter \(y\) now equals two quantities \[\begin{aligned} y & = 3x+9\\ y & = 6x-2 \end{aligned}\]There may be consequences not such as \(3x+9=6x-2\) which do not occur for assignment.
The Walrus \(:=\) is a common way to make a distinction for assignment.
Technically variables cannot be assigned. They are in a separate alphabet.
Assignment is just a jargon place holder for a future planned substitution.
So the use of = for assignment is flawed.
What is \(f(5)\)?
Many will answer \(-2\), i.e.
\[f(5)=5-y=5-(5+2)=-2\]
Let us see if computers agree.
You will get an error, perhaps this one
>>> f(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
f(5)
~^^^
File "<stdin>", line 2, in f
return x - y
~~^~~
TypeError: unsupported operand type(s) for -: 'int' and 'function'Try it yourself at https://www.online-python.com/
def y(x):
return x+2
def f(x):
return x-y
f(5)In Python
Read strictly by rules \(y\) traps \(x\) (exercise, draw the trapping arrows to see it)
So Python is effectively renaming one or both of the \(x\)'s differently so \(x-y\neq x-(x+2)\). In fact it doesn't know what you mean by \(x-y\).
If you sense that the meaning really changed after renaming the variable then chances are there is some confussion between "equals" and "assigned".
should be mean the same as this
So \(f(5)=-2\) results from bad math habits.
If you are convinced that was the intent, then you can force your code do this by renaming \(y's\) use of \(x\) to make both \(x\)'s the same.
Python
def y(x):
return x+2
def f(x):
return x-y(x) # force's y's x to be the same as f's x
f(5) # returns -2| Python | Java | C++ |
|---|---|---|
| lambda x: x+2 | x -> x+2 | [](int x) { return x+2 } |