Pf. Too convoluted. You have to define stuff in M expressions and then map them
to S expressions. And what is it that you're defining? A set of primitive
functions, some of them operating on specialised data structures. Why? Here's
Prolog in Prolog:
This is just a straight-forward implementatio of SLDNF Resolution [1]. No
"primitives", no data types, no specialised data structures and no translation
from Prolog to something else before looping back to Prolog.
Also, rather fewer LOCs. LISP people are always bragging about their LOCs. I
don't know why.
__________
[1] "SLDNF" Resolution is Selective Linear Definite Resolution with Negation as
Failure, officially; or, Straight-up Logical Derivations with No Fuckups
Resolution, as I prefer to think of it.
I feel a little sick every time I see this regurgitated; McCarthy's interpreter is not remotely in the same class as Maxwell's equations (and the Church-Turing thesis). It's neither axiomatic, universal, nor minimal. Good ol' lambda calculus does a much better job. For example, here's the lambda calculus self-interpreter [1]
Basically, it does beta normal form reduction. In these kinds of situations, I sometimes feel like it's just as valuable to know how to get the darn thing to run, and then the rest explains itself. So for the purposes of this explanation, I'll share a Hello World example for this interpreter, that should hopefully get you going. This won't cover beta reduction or any of that jazz. Just the simplest possible usage that you can type into the web page at https://crypto.stanford.edu/~blynn/lambda/ and see something happen.
Why did this happen? It's because Y(λab.b(λc.c)(λcd.ac(ad))(λcd.a(cd))) is the reducer a.k.a. E and λabc.c(λdefg.ed) is the argument. What is λabc.c(λdefg.ed)? It's an encoded version of the identity function λd.d. So in other words, all it did was output exactly what was inputted. Except the input had to be encoded. Why is it encoded? Normally in LISP, if we wanted to pass a program to a self-interpreter, we've wrap the argument in (QUOTE), e.g.
(EVAL (QUOTE (LAMBDA (X) X)))
However the lambda calculus doesn't have a QUOTE builtin. Because the lambda calculus is a programming language that has only has a single keyword (can you guess what it is?) What they had to do instead was design a system of quoting that only uses lambdas:
Var=\m.\a b c.a m
App=\m n.\a b c.b m n
Lam=\f.\a b c.c f
So if you want to derive the argument yourself, you can type the following into the Stanford web page.
Lam (\y.Var y)
=> λa b c.c(λy a b c.a y)
You can even use the self-interpreter with SectorLambda. https://justine.lol/lambda/ For instance, the behavior of the reduced output will be the same as if you just typed in the normal identity function:
Another fun exercise, if you want to see all the steps that take place in reducing the self-interpreter, would be to download the lambda.com and lam2bin.com programs, and run the following command:
Sorry, I know this will come across as a little rude but, a "fun exercise"? My eyes hurt! Can't you do all this in a simpler notation? This looks like someone sneezed over a Scrabble set.
Edit: I guess that's more than a little rude. I apologise in advance, but really, this is so hard to read and I reckon it must be very hard to write correctly, let alone check the correctness off. There must be a better way!
Also, rather fewer LOCs. LISP people are always bragging about their LOCs. I don't know why.
__________
[1] "SLDNF" Resolution is Selective Linear Definite Resolution with Negation as Failure, officially; or, Straight-up Logical Derivations with No Fuckups Resolution, as I prefer to think of it.