Re: [stack] Concatenative macros?

"iepos" <[email protected]>
Newsgroups gmane.comp.lang.concatenative
Message-ID <[email protected]>
Hi Billy & all,

It's been a while! Sorry this post is a little belated. I tried 
sending it last week, but something was wrong with my account (my 
concatenative membership had expired, apparently; or maybe the list 
was unmoderated back when I used to use it). In any case, Yahoo ate 
my post up, so I had to rewrite it ...

> A doubt begins to stir in my mind. Is the Fokker X combinator 
actually
> a pseudo-combinator? If so, is that a problem with the Fokker X
> combinator, or is it a problem with Kerby's ideas about
> pseudo-combinators? 

Yes. The Fokker X combinator would be a "pseudo-combinator". But 
that was a bad choice of terminology on my part. Under the standard 
definition, it is a combinator. The restricted objects I was calling 
combinators are what Curry called "proper combinators". So we ought 
to say that the Fokker X combinator is an improper combinator, but a 
combinator nonetheless. To recap, here are the standard definitions 
which I should have used:

Proper combinator: Any closed lambda-form in which all lambdas occur 
at the head (i.e., at the far left).

Combinator: Any closed lambda-form whatsoever (or, equivalently: any 
combination of proper combinators)

This applies to both applicative and concatenative systems (although 
the interpretation of "lambda" and "combination" of course depends 
on which system we're dealing with). Another way of putting it is 
that proper combinators are ones that can be expressed by a rewrite 
rule; i.e., in an applicative system, Z is a proper combinator if 
you can state a rule

  Zxyz == (some applicative combination of x, y, and z)

or the like, with as many variables as needed; the standard 
combinators S, K, I, B, C, W, T, etc. are all proper, while the 
Fokker X combinator and, for example, Y, the "paradoxical" or fixed-
point combinator, are not. 

Likewise, in a concatenative system, Z is a proper combinator if you 
can state a rule

  [z] [y] [x] Z == (some concatenative combination of x, y, and z)

or the like, with as many variables as needed. The standard 
combinators i, cons, dip, cat, swap, dup, zap, k, and cat are all 
proper.

Now, since the Fokker X combinator is improper, the question 
naturally arises: Is there a complete basis (in applicative 
combinatory logic) consisting of a single _proper_ combinator? The 
answer is no. The standard proof (due to William Craig) goes roughly 
like this: Every basis of proper combinators must contain a 
selector, i.e., a combinator like I or K, that takes some parameters 
(in a curried fashion, of course) and returns a certain one of them 
untouched, ignoring the rest. This is because selectors cannot be 
constructed out of other proper combinators; this can been seen by 
looking at the rewriting process: An expression Fxyz, for example, 
where F is written as some combination of proper combinators A, B, 
C, ..., none of which is a selector, can never reduce to just the 
the single variable 'x' by applying rewrite rules, because the 
rewrite rules for A, B, C, ... each have a right-hand-side 
consisting of something more than just a single variable. There is a 
combinator F (namely, the selector \xyz.x) for which Fxyz would 
reduce to x; but it is impossible to construct this F, or likewise, 
any selector, from a basis of non-selectors. Therefore, in a basis 
consisting of a single proper combinator, this combinator must be a 
selector. But selectors have no duplicative effect; therefore, it 
would be impossible to construct "W" or "S", for example. So a 
complete basis consisting of a single proper combinator does not 
exist.

So in a complete basis of proper combinators, we need at least two. 
And of course it turns out that two is enough, since {S, K} is a 
complete basis. But if you allow improper combinators, then one is 
enough, as the Fokker X combinator shows, for instance.

Now, what about in a concatenative system? Well, using an argument 
similar to the one above, we can show that a basis consisting of a 
single proper combinator is again impossible. This is because any 
basis of proper combinators must contain what I'll call a "total 
dequoter", i.e., a combinator whose right-hand-side contains no 
quotations; total dequoters simply execute some of their parameters 
(possibly multiple times, or none at all) in a certain order;  
examples would be i, k, zap, 'cat i', and

  X\ Y\ Z\ W\ Y X W X

A total dequoter is needed, because if every combinator in the basis 
had a quotation on the right-hand-side, then it would never be 
possible to get down to an empty stack, once a quotation was on it; 
specifically, the expression [] F, where F is written as some 
combination of proper combinators A, B, C, ..., none of which is a 
total dequoter, could never reduce to the empty program, which shows 
that 'i' could not be constructed, since 'i' would be an F that 
works. Therefore, in a basis consisting of a single proper 
combinator, this combinator must be a total dequoter. But from a 
total dequoter alone, it is clearly impossible to construct cons, or 
even swap, dup, dip, or cat. So a basis consisting of a single 
proper combinator again does not exist.

So the best we could hope for would be a two-combinator basis of 
proper combinators, or a one-combinator basis consisting of an 
improper combinator. We know that a basis of two proper combinators 
is possible; for example, {cake, k} works.

So what about a one-combinator basis? This is an interesting 
question. It will not work to simply take the concatenative version 
of the Fokker X combinator (or the Rosser, or any other applicative 
one-combinator complete basis).  This would be equivalent to the 
basis {s, k}, which is _not_ complete in a concatenative system. 
From {s, k}, we can construct all applicative combinators (i, b, c, 
etc.) and even many others (swap, cons, dup, zap), but it would be 
impossible to construct dip (or cat). You can see this by looking at 
the rewrite rules for 's' and 'k':

[Z] [Y] [X] s  ==  [[Z] Y] [Z] X
    [Y] [X] k  ==  X

Note that on the right-hand-side of both rules, there is nothing to 
the right of the only dequoted term X. In reducing the 
expression '[B] [A] F', where F is some (concatenative) combination 
of 's' and 'k', every step of the reduction preserves the property 
that no subexpression contains a (dequoted) A followed by anything 
containing B; therefore, it could never reduce to 'A [B]'. So it is 
impossible to construct dip from {s, k}.

But after some fiddling, I was able to find a one-combinator base 
that does work. The idea is to make a combinator with 'cake' and 'k' 
somehow embedded in it, built in such a way that, with a little 
manipulation, we can extract them back out. Let

z == X\ zap [cake] [k] X

or, in other words,

z == [zap [cake] [k]] dip i

Then

[] [] z z
== [] zap [cake] [k] z
== [cake] [k] z
== [cake] zap [cake] [k] k
== [cake] [k] k
== k

So we can construct k. And

[] [] [zap k] z 
== [] [] zap [cake] [k] zap k
== [] [cake] [k] zap k
== [] [cake] k
== cake

So we can construct cake. Explicitly, we can write them

k    == [] [] z z
cake == [] [] [[] [] [] z z [] [] z z] z

So this {z} forms a complete basis. Incidentally, this construction 
doesn't depend specifically on 'cake'; you could replace 'cake' with 
any combinator that, along with 'k', forms a complete basis.

- Brent
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.