In lambda calculus, how would I write a function that returns true when its input is the identity function? - lambda-calculus

In lambda calculus, how would I write a function that returns true when its input is the identity function?
Assume true is some church encoded value of true.
It seems like this should be an easy function to write. But for every test I think of, a tricky input can outsmart it. Is it impossible?

I := λx.x
0 := λf.λx.x
1 := λf.λx.f x
TRUE := λx.λy.x
FALSE := λx.λy.y
PRED := λn.λf.λx.n (λg.λh.h (g f)) (λu.x) (λu.u)
ISZERO := λn.n (λx.FALSE) TRUE
The identity function λx.x is Eta equivalent to church numeral 1 λf.λx.f x. The Fn below will return FALSE for any function that does not evaluate to a church numeral zero (λf.λx.x) after being passed through the predicate function.
λx.(ISZERO (PRED x)) TRUE FALSE
There may exist a function BAD that behaves as such:
λx.(ISZERO (PRED x)) TRUE FALSE BAD := TRUE
BAD != I

Related

Return an integer literal from a Scheme function

I've been reading about Scheme functions and have not seen one that simply returns an integer literal; likely because it would not be a very useful function. However, I am interested in trying to write a simple function in Scheme that takes arguments and just returns an integer. My function is:
(define (f x y) 1)
When I call the function with:
(f 4 5)
The result is:
4
5
Why would the function return both of the arguments rather than simply returning 1?

Scheme Lambda? What is it?

What is it in scheme? How can we use it ?
scm> (define (x) 100)
x
scm> (x)
100
scm> x ; When we "called" x, it return (lambda () 100). what is it ?
(lambda () 100)
(define (x) 100) is the same as:
(define x ; define the variable named x
(lambda () ; as a anoymous function with zero arguments
100)) ; that returns 100
x ; ==> #<function> (some representation of the evaluated lambda object, there is no standard way)
(x) ; ==> 100 (The result of calling the function)
You might be more in to Algol languages so here is the same in JavaScript:
function x () { return 100; } is the same as:
var x = // define the variable named x
function () { // as the anonymous function with zero arguments
return 100; // that returns 100
};
x; // => function () { return 100; } (prints its source)
x(); // => 100 (the result of calling the function)
Beginners sometimes add parentheses around variables like ((x)) and it is equivalent to writing x()() in Algol languages. Thus x must be a function of zero arguments that will return a function of zero arguments in order to work.
(define (x) 100) is equivalent to (define x (lambda () 100)).
The first syntax is actually a syntactic sugar of the second. Both define a procedure.
When you use x, the Scheme interpreter will return you x itself. In this case, x is a lambda expression.
When you use (x), you are calling a procedure named x. The scheme interpreter will apply what's inside x, in this case, a lambda expression, and return you the return value.
To use lambda, consider lambda expression as an operator.
So ((lambda (<arg-list>) <body>) <parameter-list>)
Or, if you define a lambda expression to a variable, take the variable as the operator, for example, as what you do,
(define x
(lambda () 100))
(x)

How to interpret a lambda calculus expression?

say I am given the expression (i will refer to l as lambda):
lx.f1 f2 x
where f1 and f2 are functions and x suppose to some number.
how do you interpret this expression? is lx.(f1 f2) x the same as lx.f1 (f2 x)?
as an exemple, what will be the diffrence in the result of lx.(not eq0) x and lx.not (eq0 x)?
(eq0 is a function that return true if the parm equals 0 and not is the well known not function)
more formally T=lx.ly.x ,F=lx.ly.y ,not = lx.xFT and eq0 = lx.x(ly.F)T
f1 f2 x is the same as (f1 f2) x. Function application is left-associative.
is ln.(f1 f2) x the same as ln.f1 (f2 x)?
No, not at all. (f1 f2) x calls f1 with f2 as its argument and then calls the resulting function with x as its argument. f1 (f2 x) calls f2 with x as its argument and then calls f1 with the result of f2 x as its argument.
ln.(not eq0) x and ln.not (eq0 x)?
If we're talking about a typed lambda calculus and not expects a boolean as an argument, the former will simply cause a type error (because eq0 is a function and not a boolean). If we're talking about the untyped lambda calculus and true and false are represented as functions, it depends on how not is defined and how true and false are represented.
If true and false are Church booleans, i.e. true is a two-argument function that returns its first argument and false is a two-argument function that returns its second argument, then not is equivalent to the flip function, i.e. it takes a two-argument function and returns a two-argument function whose arguments have been reversed. So (not eq0) x will return a function that, when applied to two other arguments y and z, will evaluate to ((eq0 y) x) z. So if y is 0, it will return x, otherwise z.

SML| foldl with if

I'm having this exercise which asks to count how many values in a boolean list are true.
I typed this:
fun countt xs = foldl (fn (x,y) => if x=true then y=y+1) 0 xs;
which, apparently, is wrong. I'm getting the following error:
stdIn:54.21-54.24 Error: syntax error: deleting RPAREN INT0
Now, I've searched a bit and found out that RPAREN is a Syntax error. But i can't figure why there's a problem in the first place.
In a functional programming language, an if expression must have both then branch and an else branch (and they must both have the same type).
Your if expression only has a then branch.
Additionally, x=true always evaluates to the same value as x so you can just write if x then ... else ....
Finally, it looks like you're trying to write an assignment in the then branch. Remember that a foldl works by repeatedly passing the accumulator (y) to the function as it traverses the list with xs. So if you want to update the accumulator, all you have to do is return the updated value.
Just to complement the previous answer here are the suggested modifications:
fun countt xs = foldl (fn (x,acc) => if x then acc+1 else acc) 0 xs;
The term in parenthesis is the first argument to foldl, the value 0 is the seed value and the xs is the sequence that will be folded. The function takes a value and the current element of the sequence xs.
The function must return a value of the same type of 0, an integer.

Scheme function that returns function is returning unexpected value

I have a function in scheme
(define (m-m f)
(let ((count 0))
(define (h-m-c?) count)
(define (r-c) (begin (set! count 0) count))
(define (m-f m)
(cond ((eq? m 'h-m-c?) (h-m-c))
((eq? m 'r-c) (r-c))
(else (set! count (+ 1 count)) f)))
m-f))
where m-f is a function that is returned.
However, rather than returning a value, it returns
#<procedure:m-f>
It appears there is no error with the code, so why doesn't this return a usable value?
You told it to return m-f. That's the name of a procedure that you defined, so it's returning the procedure. To use this return value, you need to assign it to another variable.
(define thing1 (m-m 'unused))
(define thing2 (m-m 'who-cares))
(thing1 'h-m-c?)
(thing1 'increment)
(thing1 'h-m-c?)
(thing2 'h-m-c?)
Some other commentary:
Procedure names ending in ? are used for predicates that report true/false.
You don't need begin in (r-c). Procedure bodies allow multiple expressions, and execute them in order just like begin.
Why didn't you define a function for the case where count is incremented, like you did for the other cases?
Using the default for incrementing seems inappropriate, you should require a specific m parameter for this.
What's the purpose of the f parameter? The only thing it's used for is to be returned when incrementing? Wouldn't the new value of count be a more useful return value? It seems like it's intended to be a "name" for the instance; if so, perhaps you should add a new operation to return the name, rather than doing this when incrementing.
EDIT:
Based on the answer below, I suspect you're misusing the f parameter. It's probably supposed to be a function that you call when doing the increment. So you need to supply it as a lambda expression, and return (f) rather than just f.

Resources