Y combinator: Some functions do not have fixed points
Asked Answered
G

3

8

The Wikipedia article on the Y combinator provides the following JavaScript implementation of the Y combinator:

function Y(f) {
    return (
        (function (x) {
            return f(function (v) { return x(x)(v); }); })
        (function (x) {
            return f(function (v) { return x(x)(v); }); })
    );
}

The existence of a Y combinator in JavaScript should imply that every JavaScript function has a fixed point (since for every function g, Y(g) and g(Y(g)) should be equal).

However, it isn't hard to come up with functions without fixed points that violate Y(g) = g(Y(g)) (see here). Even certain functionals do not have fixed points (see here).

How does the proof that every function has a fixed point reconcile with the given counter-examples? Is JavaScript not an untyped lambda calculus in which the proof that Y(g) = g(Y(g)) applies?

Godchild answered 14/6, 2012 at 11:51 Comment(0)
R
3

The problem with lambda expressions is that they cannot be interpreted as functions in a mathematical sense, i.e. mappings from one set to another.

The reason is the cardinality of the set of functions from a set A on itself is always larger than the cardinality of A, so not all functions from A to A can be an element of A. That is, there is a function f: A -> A for which the expression f(f) does not make sense.

This is like the "set of all sets not containing itself", which does not make sense logically.

JavaScript is not a model of the lambda calculus.

The problem with your example is that

(lambda x.g(x x)) (lambda x.g(x x))

should be equivalent to

g((lambda x.g(x x)) (lambda x.g(x x)))

but it is not in your JavaScript program where g is the indicator function of 0.

x x is always undefined. Hence the first line evaluates to g (undefined) = 0. The second line evaluates to g (g (undefined)) = g (0) = 1. This means that your JavaScript model of the lambda calculus is, in fact, not really a model.

Since for each non-empty set D there is a function from D to D without a fixed point, obviously there can be no model of the lambda calculus. I think it should be even possible to prove that there cannot be an implementation of the Y-combinator in any Turing-complete language.

Rembert answered 22/6, 2012 at 15:40 Comment(1)
I would amend your last paragraph. Just because |D^D| > |D| in a set-theoretical sense does not mean lambda calculus has no models. See mathoverflow.net/questions/16752/…Anodyne
C
4

As far as I understand Wikipedia article, it doesn't imply anywhere that "that every JavaScript function has a fixed point" and this example simply shows how to implement Y combinator for functions that have it by their specification.

And no, according to definitions in that article and an article on fixed point, JavaScript can't be an untyped lambda calculus, because it can formulate functions that obviously fail "have a fixed point" check, like function f(x){ return x + 1 } or x ^ 1 if you want to include non-numbers and thus fail "every function has at least one fixed point" check too.

Corpse answered 14/6, 2012 at 14:50 Comment(3)
Now rewind just a sentence back: In certain mathematical formalizations of computation, such as the untyped lambda calculus and combinatory logic, <...> In these formalizations, the existence of a fixed-point combinator means that every function has at least one fixed point <...>Corpse
No, it isn't, because it fails to adhere to definitions in those articles. Updated answer.Corpse
BTW, I'm not that much of expert on calculus and fixed point definition, but does it really requires to be true to everything (strings, NaN, Inf), as opposed to just natural numbers? In that case x + 1 example from wiki would be wrong as well.Corpse
R
3

Fixed point theory comes in flavors. Those for programming languages are studied under the heading of denotational semantics. They depend on values forming a structured countable set with special properties. Latticesand Complete Partial Orders are two examples. All these sets have a "bottom" element, which turns out to be the fixed point that means "no useful result". In fact, the only fixed point operators you're interested in with computer programs are least fixed point operators: those that find the unique minimum fixed point that's lowest in the structured set of values. (Note all integers are on the same "level" in these structured sets. Only the bottom element lives beneath. The rest of the layers are composed of more complex types like function and tuple types, i.e. structures.) If you have some discrete math, this lays it out pretty nicely. Tarsky's fixed point theorem actually says that every function that is monotone (or alternately continuous) has a fixed point. See the reference above for definitions. In operational computer programs, the bottom element corresponds to a non-terminating computation: an infinite recursion.

The point of all this is that if you have a rigorous mathematical model of computation, you can start proving interesting things about type systems and program correctness. So it's not just an academic exercise.

Rhizoid answered 22/6, 2012 at 4:9 Comment(0)
R
3

The problem with lambda expressions is that they cannot be interpreted as functions in a mathematical sense, i.e. mappings from one set to another.

The reason is the cardinality of the set of functions from a set A on itself is always larger than the cardinality of A, so not all functions from A to A can be an element of A. That is, there is a function f: A -> A for which the expression f(f) does not make sense.

This is like the "set of all sets not containing itself", which does not make sense logically.

JavaScript is not a model of the lambda calculus.

The problem with your example is that

(lambda x.g(x x)) (lambda x.g(x x))

should be equivalent to

g((lambda x.g(x x)) (lambda x.g(x x)))

but it is not in your JavaScript program where g is the indicator function of 0.

x x is always undefined. Hence the first line evaluates to g (undefined) = 0. The second line evaluates to g (g (undefined)) = g (0) = 1. This means that your JavaScript model of the lambda calculus is, in fact, not really a model.

Since for each non-empty set D there is a function from D to D without a fixed point, obviously there can be no model of the lambda calculus. I think it should be even possible to prove that there cannot be an implementation of the Y-combinator in any Turing-complete language.

Rembert answered 22/6, 2012 at 15:40 Comment(1)
I would amend your last paragraph. Just because |D^D| > |D| in a set-theoretical sense does not mean lambda calculus has no models. See mathoverflow.net/questions/16752/…Anodyne

© 2022 - 2024 — McMap. All rights reserved.