gcl-devel
[Top][All Lists]
Advanced

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

[Gcl-devel] Re: Still lost


From: Camm Maguire
Subject: [Gcl-devel] Re: Still lost
Date: 10 Apr 2006 19:19:45 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Greetings!

Robert Boyer <address@hidden> writes:

> Sorry, I'm still very, probably hopelessly lost.  Can we be
> even more concrete and simple than ELT?  Let's look at
> SECOND.
> 
> What are the 8 official, long term, GCL plans for the
> behavior of the ANSI function SECOND under all 8
> "processing" circumstances, (a) compiled or (b) interpreted,
> SAFETY = 0, 1, 2, 3?  Or are there more than 8 different

OK, AFAICT, safety only pertains to compiled.  All interpreted code is
equivalent to compiled safety 3, AFAICT.

The long term goal is to have all system code check all needed data
once and only once.  System code (i.e. the 'second function one gets
by typeing '(second x) at the repl) will be compiled at only one safety
level in such a way as to achieve this.  Compiled user code containing
'second will do:

1) at safety 0/1, an unchecked inlined 'cadr.
2) at safety 2, a checked 'cadr C function call (i.e. item and cdr must be 
'cons)
3) at safety 3, proceed through the 'second system function via the
        lisp stack.

If one compiles (defun foo (x) (second x)), safety one only adds an
error when the wrong number of args are passed to 'foo.

Here is what I have now locally to fix the nth et. al. errors you
reported in the second system function.

(defun nth (n x)
  (declare (optimize (safety 2)));prevent unsafe inline of nthcdr
  (car (nthcdr n x)))            ; this is in keeping with gcl
                                 ; tradition of doing a blind cdr at
                                 ; safety 0/1

(let ((i -1))
  (dolist (l '(first second third fourth fifth sixth seventh eighth ninth 
tenth))
    (eval `(defun ,l (x) (declare (optimize (safety 1))) (nth ,(incf i) x)))))

nthcdr explicitly checks arguments only where needed (hopefully).

Currently there is (at least) one exception to this general rule of
safety: endp when inlined at or above safety 1 makes sure its argument
is a list.  Arguably this should only be at safety 2 and above.

In sum, this is how I see the existing traditional GCL safety
definitions:

0: You know what you are doing, execute at wire speed
1: Check for program/control errors, i.e. function arg number passing
2: Check types in all subsidiary function calls
3: Make all calls to system functions via the lisp stack, i.e. no
    inlining.

> situations?  You'll recall that according to ANSI, for a
> "safe call", one must be sure that three different things
> are "safe code or system code", according to ANSI, to wit:
> 
>   * the call
>   * the definition of the function being called
>   * the point of functional evaluation
> 
> So perhaps in ANSI Common Lisp I need to understand about
> 3x8=24 policies?  Presumably, some of these policies will be
> the same.  Maybe GCL will only have two or three distinct
> policies, but they will have to cover all 24 situations, no?
> 

I must confess that this is not at all clear in my mind, and that in
going forward thus far, I am merely trying to preserve the definitions
of the three safety levels as traditionally exhibited in gcl compiled
code.  I am assuming that someone knew what they were doing in this
regard at some point (i.e. in defining the behavior of the safety
levels) so that it makes for a solid platform on which to build :-).

> Does long term GCL plan include all of these these three
> things:
> 
> 1.  Redefine SECOND in lsp/gcl_listlib.lsp as
>          (defun second (x) 
>            (declare (optimize (safety 1)))
>            (cond ((null x) nil)
>                  ((atom x) (error "..."))
>                  (t (let ((d (cdr x)))
>                        (cond ((null d) nil)
>                              ((atom d) (error "..."))
>                              (t (car d)))))))
> 

Essentially, yes, but much more succintly via a do loop over endp in
nthcdr, where endp is compiled with sufficient safety as to do the
above on each cdr.

> 2.  Make SECOND a compiler macro so that, at least when
> compiling with SAFETY=0 or =1, the compiler macroexpansion
> of (SECOND x) is (CAR (CDR x)), which, at least when
> compiling with SAFETY=0 or 1, always turns into exactly two
> idealized machine code instructions?  (Relying on that hack
> that doing these single machine instructions on NIL happens
> to return NIL, by previous memory layout) and finally
> 

Yes.

> 3.  When running interpreted code with EVAL, and
> encountering a CONSp form to evaluate whose CAR is 'SECOND,
> EVAL will do nothing but do a fetch and c function call of
> the compiled C code for the function defined in 1 above, as
> compiled in the ordinary way by GCL and GCC, checking
> nothing except to rely upon that fact that the compiled code
> (because of the safety 1?) will check that precisely one arg
> was passed on the value stack?  How can that code possibly
> check that?  Doesn't the code for EVAL have to so some
> checking, to see what's in the CDR of the form in such a
> case, while pushing it on the value stack, before calling
> the code in 1?
> 

Essentially yes.  Eval'ed code goes through the system function, which
needs to have all the benefits of being compiled at safety 2
(i.e. checking argument number passing *and* types), but hopefully can
do the type checking intelligently only once and proceed to optimized
inlining thereafter in the function body.  All argument passing to and
from the repl must go through the lisp stack at the point of the repl,
which is the localized point at which number checking is achieved.
Calls between compiled C functions have the same checking except when
the functions are proclaimed before compilation, the safety is less
that 3 at the time of compilation, and fast links are on.  

> Too many questions!

Not at all. Really, I think unfortunate situation is that lisp
supports too many different possibilities here.

> 
> Please take all the time in the world you please to answer
> this, if ever.  No hurry at all.  I've been writing Lisp
> code now for 40 years, understanding less and less of what I
> am doing.  As Mark Twain put it, "It ain't what you don't
> know that gets you into trouble.  It's what you know for
> sure that just ain't so."

:-).

Please feel free to continue if anything remains unclear.  I am
learning too of course, and am quite behind yoursefl in this
regard!!!. 

BTW, have an nconc, nreconc, last, map, and list-function commit just
about ready.  Only need to provide compiler macros for remove and
delete AFAICS, and then clean up the ansi failures.

Take care,


> 
> Lost,
> 
> Bob
> 
> 
> 

-- 
Camm Maguire                                            address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

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