when to stop reduction in lambda caculus - lambda-calculus

I am confused about how the lambda reduction terminates.For example,the number 2 is written as
\xy.xxy
Why shouldn't we continue to apply beta substitution rule and make it like
\xy.(x)xy
=>\ab.axy
=>\b.yx
=>y
This is clearly wrong.But i don't know why.Can anyone help me?thx a lot!

If you're having trouble making substitutions, I recommend you use fully expanded forms
\xy.xxy
is not
\xy.(x)xy
it is
λx. λy. (x x) y
which can be eta-reduced to
λx. λy. (x x) y
λx. (x x)
λx. x x
which is in head normal form and cannot be further reduced
beta substitution wasn't necessary in this particular problem

Related

Which is better in OCaml pattern matching, `when` or `if-then-else`?

Let's say we have a type called d:
type d = D of int * int
And we want to do some pattern matching over it, is it better to do it this way:
let dcmp = function
| D (x, y) when x > y -> 1
| D (x, y) when x < y -> -1
| _ -> 0
or
let dcmp = function
| D (x, y) ->
if x > y then 1 else if x < y then -1 else 0
Just in general is better to match patterns with many "when" cases or to match one pattern and the put an "if-then-else" in it?
And where can I get more information about such matters, like good practices in OCaml and syntactic sugars and such?
Both approaches have their cons and pros so they should be used accordingly to the context.
The when clause is easier to understand than if because it has only one branch, so you can digest a branch in a time. It comes with the price that when we analyze a clause in order to understand its path condition we have to analyze all branches before it (and negate them), e.g., compare your variant with the following definition, which is equivalent,
let dcmp = function
| D (x, y) when x > y -> 1
| D (x, y) when x = y -> 0
| _ -> -1
Of course, the same is true for if/then/else construct it is just harder to accidentally rearrange branches (e.g., during refactoring) in the if/then/else expression and completely change the logic of the expression.
In addition, the when guards may prevent the compiler from performing decision tree optimizations1 and confuse2 the refutation mechanism.
Given this, the only advantage to using when instead of if in this particular example is that when syntax looks more appealing as it perfectly lined up and it is easier for the human brain to find where are the conditions and their corresponding values, i.e., it looks more like a truth-table. However, if we will write
let dcmp (D (x,y)) =
if x = y then 0 else
if x > y then 1 else -1
we can achieve the same level of readability.
To summarize, it is better to use when when it is impossible or nearly impossible to express the same code with if/then/else. To improve readability it is better to factor your logic into helper functions with readable names. For example, with dcmp the best solution is to use neither if or when, e.g.,
let dcmp (D (x,y)) = compare x y
1)In this particular case the compiler will generate the same code for when and if/then/else. But in more general cases, guards may prevent the matching compiler from generating the efficient code, especially when branches are disjoint. In our case, the compiler just noticed that we're repeating the same branch and coalesced them into a single branch and turned it back into the if/then/else expression, e.g., here is the cmm output of the function with the when guards,
(if (> x y) 3 (if (< x y) -1 1))
which is exactly the same code as generated by the if/then/else version of the dcmp function.
2) Not to the state where it will not notice a missing branch, of course, but to the state where it will report missing branches less precisely or will ask you to add unnecessary branches.
Quoting the OCaml Towards Clarity and Grace style guide:
Code is more often read than written - make the life of the reader easy
and
Less code is better, cryptic code is worse
The first makes me think that the version with multiple when clauses is the better choice, as it makes it easy to predict or evaluate the result when reading the code depending on condition. The second goes further, against the if-then-else because, even if shorter, is cryptic when looking from afar.
Also, in the section Functions, we find out that "Pattern matching is the preferred way to define functions"
From a Haskell functional programmer's point of view.

Why is the x free in the lambda

I have following lambda expression:
x λ x. x
This is a function application, but why x is free variable?
x is not free in the lambda, but it is free outside of the lambda. Or, more simply, in
x (\y. y)
x is free but y is not. Variables are free just when there is no enclosing lambda that binds them; since there is no lambda enclosing the x at all, there is certainly no lambda enclosing the x that also binds x.

beta reduction: correct way to replace bound variables?

say I have the following example of a lambda expression with \x meant to represent lambda x
What would the beta reduction of the following be?
(\x.\x.(x x)) \z.z
My first instinct would have been for this to be
\x.(\z.z \z.z)
But someone I spoke with was of the opinion that the second \x would also be replaced with \z.z
which would mean it is really
\(\z.z).(\z.z \z.z)
Can someone please clarify what the correct approach would be. I can't say I really understand the second approach.
Actually, (\x.\x.(x x)) \z.z is alpha equivalent to (\x.\y.(y y)) \z.z because variables are always bound to the closest lambda abstraction.
This means (\x.\x.(x x)) \z.z is beta equivalent to \x.(x x).
Substitution is never done on lambda abstractions, the \x. part.

behavior of quote in racket

I'm used to (quote x) evaluating to x, (quote (x y z)) evaluating to (x y z), and (car (quote (x y z)) evaluating to x. The reasoning is simple: quote is a special form that does not evaluate its argument, but simply returns it as is.
I just started using Racket, and it thinks that (quote x) evaluates to (quote x), (quote (x y z)) evaluates to (quote (x y z)), and (car (quote (x y z)) evaluates to (quote x).
Well, actually, it prints these as 'x, '(x y z), and 'x, respectively, but that's the same thing.
Can someone explain the reasoning here? If, for some reason, (quote (x y z)) evaluates to (quote (x y z)), shouldn't the car of that then be quote? Where does (quote x) come from?
As far as I can tell, Racket, throughout the entire computation, internally behaves just as I'm used to, except that when it comes time to print the final result, it wraps it in a quote form. Is this correct in all cases? And if so, why would it want to do that?
Racket evaluates the expressions in the same way as any Scheme. Racket however has in a special writer in the teaching languages. In DrRacket you can change the way values are printed. In the language menu, click the advanced button, and then take a look at the printing options.
Racket (language) prints out the result of top level forms, not only when entered in the interaction window (REPL), but always. It's to ease developing I guess and in real world applications you don't have statements that doesn't amount to anything so a real application wouldn't have these lines displayed since you have define and an expression to start your program and you could return (void) from it to force no output..
If you were to change language to either #!r6rs or #!r5rs you quickly see that the only way to get the result of an evaluation in the definitions window would be if you explicitly used display on the result.
No matter the language used, display displays it correctly. For a REPL-print the language and setting control how it displays. Standard #!racket is to display in such way that putting it in a new expression wrapped with display would print exactly the same as if you would have wrapped the original expression with display.
(define test 'hello-world)
(display test) ;; displays hello-world and not 'hello-world
test ;; displays 'hello-world in #!racket, nothing in R6RS unless in interactions window

Finding if a number is the power of 2 in Scheme

I'm fairly new to Scheme and am attempting to learn it on my own from scratch. I'm stuck on the syntax of this problem. I know that if I want to find out if a number is a power of 2, in C for instance, I would simply do:
return (x & (x - 1)) == 0;
which would return true or false. How would I be able to convert this into a couple simple lines in Scheme?
I'll give you a hint since you're trying to learn the language.
Scheme has a function called (bitwise-and ...) which is equivalent to the & operator in C (there is also (bitwise-xor ...), (bitwise-not ..), etc., which do the expected thing).
(Here is the documentation of the (bitwise-and ...) function)
Given that, would you be able to translate what you've written in your question into Scheme code?
N.B: For a problem like this, you really don't need to resort to bitwise operations when using Scheme. Realistically, you should be writing a (possibly probably tail) recursive function that will compute this for you.
You can do this using a built in bitwise operator.
(define (pow2? x)
(= (bitwise-and x (- x 1))
0))
Scheme also has biwise operators.
But if you really want to develop your scheme skills, you should write a function that decides if an integer is a power of 2 by recursively dividing it by 2 until you are left with either 2 or with an odd number. This would be very inefficient, but really cool nonetheless.

Resources