gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnu-arch-users] Re: Tla spork


From: Tobias C. Rittweiler
Subject: Re: [Gnu-arch-users] Re: Tla spork
Date: Fri, 27 Aug 2004 16:40:37 +0200

On Friday, August 27, 2004 at 7:10:47 AM, 
    Zenaan Harkness <address@hidden> wrote:

> It would be a great thing if someone were to figure out how to write a
> two hour tutorial that allowed people to "click into" the right thinking
> mode for lisp-like languages.

I'll teach you in 10 minutes! (the syntax, that's it)

Let's start with a procedural language like C, but for sake of
simplicity let's remove types alltogether in our mental model (their
(non-)existence will not matter in any way other than possible
distraction for our so strong concentration we need in order to
grok that mystical Lisp syntax!)

So we have a language of canonical syntax with infix operatos, lots of
keywords and all that stuff. Let's write a small fibonacci program in
it, and let's afterwards morph that incrimentally into the corresponding
fibonnaci program in lisp syntax.

fib(n)
{
  if ((n = 0) || (n = 1))) {
    return 1;
  } else {
    return fib(n-1) + fib(n-2);
  }
}

Ok, now let's say we're sick of those special operators, let's make them
all to functions, so that the whole programm constists entirely of
functions only. The ordinary naming scheme of functions is kept so a
function call still looks like

  function_name(arg1, arg2, arg3);

Hmm, making things like `return' or `+' or `-' to functions is no
problem, but what's about conditional operators like `if' and `||'?
Right, we need some special kind of functions for them which will not
apply the arguments before they're passed over, because Foo(Bar());
would usually cause Bar() executed at first and its return value passed
to Foo() -- not something we like for `if'!

Let's assume we have solved this problem and conditional operators will
work as expected. [We will not need the Želse' operator anylonger,
because `if' as a function can just take the condition as first
parameter and the two execute-blocks as next parameters.]

Another thing, because everything is a function, we need a way to
explicitly tell that we're going to define a new function; let's say
that's the `define' primitive for which will simply take a function
prototype and a function body.

So let's just write the above program to this new style (I'll change
`||' to `or', because ||(...) would look obnoxious):

define(fib(n), 
  { 
    if( or(=(n, 0), =(n, 1)), /* condition */
        {                      /* block if condition yields true */
          return(1);
        },
        {                      /* block if condition yields false */
          return( +(fib(-(n, 1)), 
                    fib(-(n, 2))));
        });
  });

Fine. Now let's take a look at this again... Notice that a semicolon
only appears after a closing parenthesis, so we can easily get rid of
those semicola, because we already got rid of the difference between
statements and expressions while we changed everything to functions,
which naturally yield some value!

Also notice that we don't really need those curly braces, and if only
for the reason that they do not fit particularly well to the much
prettiert parentheses! (Ok, this is a peculiarity of the example I
happen to use, still if we really need several functions to be
executed, we can easily define a new `block' function which takes
an arbitrary number of parameters and applies them in a row.)

Let's rewrite, let's rewrite...

define(fib(n), 
  if(or(=(n, 0), =(n, 1)),
     return(1),
     return( +(fib(-(n, 1)), 
               fib(-(n, 2))))))

Lot of Irrating Superfluous Parentheses! God, this is pretty close to
this horrible Lisp Syntax already... but let's try to get still further
rid of other useless keywords so that we shall have only parentheses
remain! Yes, right, let's throw all those commata away!

And notice that `return's aren't quite useful in our language, because
these functions just return what they get passed, huh? Let's kill 'em!

define(fib(n)
  if(or(=(n 0) =(n 1))
     1
     +(fib(-(n 1)) 
       fib(-(n 2)))))


Ok, now let's pause for a while and let's recall some datatyp we haven't
mentioned so far at all: Arrays. An array looks similiar to this
[1, 2, 3, 4, 5] or ["I", "am", "so", "evil"].

Oh, how utterly nice! Let's replace those beastly brackets with true
parentheses, and honor what we get: (1, 2, 3, 4, 5). Gosh, that looks
pretty much like a function application above -- the first element isn't
just moved out of the list.

Alright, let's change our function scheme to accomodate.. so that a
function isn't much else than a list. So we go from

  function_name(arg1 arg2 ... argn)

to 
  
  (function_name arg1 arg2 ... argn).


Ok, let's rewrite the example for the last time and wonder what we got:

(define (fib n)
  (if (or (= n 0) (= n 1))
     1
     (+ (fib (- n 1)) 
        (fib (- n 2)))))

Damn, that's just LISt Processing!


-- tcr (address@hidden)  ``Ho chresim'eidos uch ho poll'eidos sophos''





reply via email to

[Prev in Thread] Current Thread [Next in Thread]