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

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

Re: [Gnu-arch-users] Round IV: xl and all that (looking ahead, mostly)


From: Tom Lord
Subject: Re: [Gnu-arch-users] Round IV: xl and all that (looking ahead, mostly)
Date: Mon, 26 Jul 2004 11:02:06 -0700 (PDT)


    > From: Peter Conrad <address@hidden>

    > sorry if this is a really dumb question... the days when I was forced to
    > "learn" LISP are long gone... (yes, I know xl1 is not LISP).

Right ... and xl1 is different from lisp in relation to your question.

    > On Fri, Jul 23, 2004 at 06:55:59PM -0700, Tom Lord wrote:
    > > 
    > >         (define main 
    > >           (exit (and (print "hello")
    > >                      (print " ")
    > >                      (print "world\(nl)"))))

    > To me it is not obvious when an expression in () is evaluated. Obviously,
    > in the example above, the (exit ...) is not evaluated as part of the
    > execution of the (define ...) expression (because that would mean the end

The general form of a program is:

        (define <name> <formula>)
        (define <name> <formula>)
        ...

Programs are run in N steps:

        1. Load the program into a VM
        2. "Operator" asks for the values of any subset of the <name>s defined
        3. VM evaluates the corresponding formulas, reducing them to
           constant-value results
        4. Goto step 2 indefinately

At each step 2, any "demanded" but not yet computed values are
computed.  In other words, the formulas are executed when the 
value is first asked for, but not again after that.

So in the example program above, if you load it and ask the
interpreter to compute the value of `main',  it will start evaluating 
that expression.   The order-of-evaluation rules imply that the three
`print' calls will be executed in that order (assume each succeds),
then that will return #t from `and', then `exit', asked to compute the
value for `#t', will instead exit with status 0.


    > However, (exit (print "hello")) *would* evaluate the argument when the
    > entire expression is evaluated. 

If the program says:

        (define x (exit (print "hello")))

then the print and exit will be executed the first time the value of
`x' is either directly demanded, or is needed in order to compute some
other value that is directly demanded.


    > And I assume that 
    > (and (print "hello") (print " ")) would evaluate its arguments in order 
until
    > one such argument evaluates to false.

Right.


    > So my question is: since there are no syntactic hints on the order of
    > evaluation, is there some general rule that I have missed, or does the
    > programmer have to "just know" how different expressions are evaluated?

Left to right in function calls.

Left to right but stopped by the first #false in `and'.

Left to right but stopped by the first non-#false in `or'.

Conditional tests before consequents.

If you don't care about error-status, it would be handy to define a 
function like `begin':

        (begin <exp0>
               <exp1>
               ...
               <expN>)

which just ignores all of its arguments but the last, which it
returns.  The rule "left to right evaluation of arguments to function
calls" means that such a `begin' will do what you expect.

Those are the basic ordering rules, but then we can add weird ones
like:

        (first <exp0>
               <exp1> 
               ...)

to evaluate all the subexpressions in parallel, but halt all of those
subthreads as soon as any one of them completes.   Or:

        (all <exp0>
             <exp1> 
              ...)

to run (to completion) all the subexpressions in parallel.   (Or
`and-parallel' or `or-parallel' etc.)

-t





reply via email to

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