Subject: Re: What kind of Lisp should I learn if I want to start programing with Lisp?
From: rpw3@rpw3.org (Rob Warnock)
Date: Sat, 07 Feb 2009 22:53:23 -0600
Newsgroups: comp.lang.lisp
Message-ID: <IcudnXg_46De-BPUnZ2dnUVZ_sjinZ2d@speakeasy.net>
Rainer Joswig  <joswig@lisp.de> wrote:
+---------------
| rpw3@rpw3.org (Rob Warnock) wrote:
| > Well, there's always Lisp500 <http://www.modeemi.fi/~chery/lisp500/>.  ;-}
| > 88 initial defined symbols, float-only arithmetic, 500 LOC of *very*
| > dense C!  Then loading "init500.lisp" adds another 761 symbols,
| > fleshing out the CL compatibility a *lot*.
| 
| ... How readable is the C part of Lisp500?
+---------------

Almost totally *unreadable*, actually!  ;-}  It's full of
"obfuscated C"-style compressions to keep the LOC small, e.g.:

    ...
    typedef int lval;
    lval *o2c(lval o) { return (lval*)(o - 1); }
    ...
    #define TRUE symi[1].sym
    #define T g[-2]
    #define U g[-3]
    #define V g[-4]
    #define W g[-5]
    #define NF(n) lval *g; g=f+n+3; f[1]=0; g[-1]=(n<<5)|16; *g=*f;
    #define E *f
    #define NE *g
    lval car(lval c) { return (c & 3) == 1 ? o2c(c)[0] : 0; }
    lval cdr(lval c) { return (c & 3) == 1 ? o2c(c)[1] : 0; }
    ...
    lval eval_if(lval *f, lval ex) { return evca(f, evca(f,ex)?cdr(ex):cddr(ex)); }
    ...
    lval eval_unwind_protect(lval *f, lval ex) { NF(1) T=0;
     T=ma(g,2,52,E,cdr(ex)); dyns = cons(g, T, dyns); T = evca(g, ex);
     T = rvalues(g, T); unwind(g, cdr(dyns)); return mvalues(T); }
    lval eval_if(lval *f, lval ex) {
     return evca(f, evca(f,ex)?cdr(ex):cddr(ex)); }
    lval eval_multiple_value_call(lval *f, lval ex) { lval *g=f+3; lval l;
     f[1]=evca(f, ex); for (ex=cdr(ex); ex; ex=cdr(ex)) { *g=*f;
     g[-1]=((g-f-3)<<5)|16; for (l = rvalues(g, evca(g, ex)); l; l = cdr(l)) {
       g[-1] = car(l); g++; }} xvalues = 8; return call(f, f[1], g-f-3); }
    lval eval_multiple_value_prog1(lval *f, lval ex) { NF(1) T=0;
     T = evca(g, ex); T = rvalues(g, T); eval_body(g, cdr(ex));
     return mvalues(T); }
    ...

+---------------
| I think it would be more useful to have a small, but readable
| implementation, than having a very small but difficult to read
| implementation. 
+---------------

I agree. Which is why even though my QDL is (currently) *much* less
featureful than Lisp500, there might be some point in making it available,
since IMHO it's much more readable. E.g., compare the above "one-liner"
"eval_if()" with the version in QDL-0.4:

    lispobj
    eval_if(lispobj rest, lispobj env)
    {
	lispobj bool;
	GC_PROTECT_BUF(2);

	GC_PROTECT_2(rest, env);
	bool = eval(car(rest), env);
	GC_UNPROTECT;
	if (bool != NIL)
	  return eval(cadr(rest), env);
	else
	  return eval(caddr(rest), env);
    }


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607