Can a constant function have slope 1?

2025 James B. Wilson

Graph of a line of slope 1 and a constant slope 0 line through y=2.

\(I(x) = x\)

\(K_c(x)=c\)

So

\(K_x(x)=x\)?

A motivated introduction to \(\lambda\)-calculus

Curry and Feys go to lunch

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.

Curry and Feys go to lunch

A fable by James B. Wilson

On Fry days, Robert was delighted...

...but Haskell was mad.

Curry and Feys go to lunch

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!

How did Curry and Feys Hack Constants' Lunch?

Constant functions have slope 0

Constant functions are

  • \(y=2\) or
  • \(f(x)=3.14\) or
  • \(f(x)=\pi\) or just
  • \(K_c(x)=c\).

 

Graph is a horizontal line (Slope 0).

(Thanks to Desmos.com)

Do constant functions have slope 0?

\(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?

Substitution isn't just         "replace all symbols."

  • There are rules to substitution.  
  • When you make rules, you are choosing a logic.
  • The name?  "Lambda (\(\lambda\)) Calculus"

Substitution Refresh

  1. Identity Law:  \[x|_{x:=\sigma}\quad \text{yields}\quad \sigma\]
  2. Constant Law: \[a|_{x:=\sigma}\quad \text{yields}\quad a\]
  3. Composition Law: \[\rho\phi |_{x:=\sigma}\quad\text{yields}\quad \rho|_{x:=\sigma} \phi|_{x:=\sigma}\]

\(x\) from alphabet of variables

\(a\) from separate alphabet of constants

\(\sigma\) a string of variables, constants, and the \(\mapsto\) symbol.

  1. \(x|_{x:=35+y}\rhd 35+y\)

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)

Substitution Refresh

 \[\begin{aligned} (x\mapsto x^2)|_{x:=35+y} & \rhd (x\mapsto x^2)\end{aligned}\]

x := 35+y
def f(x):
	return x*x

Not 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*x

Substitution Refresh

x := 35+y
def f(y):
	s := 0
	for x in [1..10]
    	s := y*x 
	return s

Not the "same" x.

5. Avoid Trapping variables!

  • If \(x\) is local (or not even in) \(\tau\) then \[(y\mapsto \tau)|_{x:=\sigma}\quad\text{yields}\quad y\mapsto \tau\]
def f(y):
	s := 0
	for x in [1..10]
    	s := y*x 
	return s

Substitution Refresh

x := 35+pi
def f(y):
	return y + x

SAME  x.

If \(x\) is in \(\tau\) but free, then avoid trapping variables!

  • If \(y\) not visible in \(\sigma\) \[(y\mapsto \tau)|_{x:=\sigma}\quad \text{yields}\quad y\mapsto (\tau|_{x:=\sigma})\]
  • Else \[(y\mapsto \tau)|_{x:=\sigma}\quad \text{yields}\quad y\mapsto ((\tau|_{y:=z})|_{x:=\sigma})\]
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.

Trapped variable

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

Trapped variable

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\)

Warning about Math Convention

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.

\begin{aligned} y & = x +2\\ f(x) & = x-y \end{aligned}

Challenge Problem.

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'
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\).

Pro-Tip:  If you suspect a trapped variable just rename it.  

A renamed variable does not change the function even if it wasn't trapped.

If you sense that the meaning really changed after renaming the variable then chances are there is some confussion between "equals" and "assigned".

\begin{aligned} y & = x +2\\ f(x) & = x-y \end{aligned}

should be mean the same as this

\begin{aligned} y & = x +2\\ f(z) & = z-y \end{aligned}
\begin{aligned} y & = x +2\\ f(x) & = x-y \end{aligned}

How to fix the Problem.

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

Quick History

  • Rules are by Curry-Feys
  • \(x\mapsto \sigma\) was traditionally written \[\lambda x.\sigma\]
  • Hence the name "lambda calculus" (thanks A. Church!)
Python  Java C++
lambda x: x+2 x -> x+2 [](int x) { return x+2 }

Recap as two rules:

  • To spot a trapped variable try renaming the variable of the last function. If the meaning changed it's a trap!

  • Substitute like normal except if you trap a free variable.

Substitution

By James Wilson

Substitution

Substitution seems so obvious that we can be fooled by simple mistakes. Fixing them forces us into a logic and calculus to go with it. This is known as Lambda calculus and the rules we will use are by Curry-Feys. Come along for a playful tour of what goes wrong when we substitute.

  • 436