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

Different behaviors of evaluator and compiler



    Date: Wed, 21 Aug 1991 06:27 EDT
    From: %nrb.be%mcsun.EU.net@Warbucks.AI.SRI.COM

    Date: Wed, 21 Aug 91 12:25+0100
    From: Vincent Keunen <keunen@milou.nrb.be>
    Subject: Different behaviors of evaluator and compiler
    To: SLUG@AI.SRI.COM
    Message-ID: <19910821112550.5.KEUNEN@milou.nrb.be>
    Character-Type-Mappings: (1 0 (NIL 0) (NIL :ROMAN NIL) "CPTFONT")
              (2 0 (NIL 0) (:FIX :BOLD :NORMAL) "CPTFONTCB")
    Fonts: CPTFONT, CPTFONT, CPTFONTCB
          
          
    I came across something I don't understand the reasons...  Can someone
    explain why this is so and how to solve this problem?  Thank you.
 
    What I want to do:
 
    I want to make a list of items.  There are lots of them, so I figured
    out that I might as well nconc instead of appending to limit the number
    of conses (I don't know the items in advance; they are produced by a
    loop).  Therefore, I accumulate everything in "result".  If I initialize
    result with the empty list ('() or nil), I get an error because I can't
    nconc that, which I understand.  So I initialize it with '(nil) because
    I don't mind having something at the start of the list (initializing it
    with '(anything) gives the same behaviour).
 
    This is a simple function to demonstrate the strange behaviour:
 
    (defun test ()
      (let ((result '(nil)))
        (loop for item in '(a b c)
              do (nconc result (list item)))
        result))
 
    (test) ;when the function definition is evaluated returns
 
    (NIL A B C) ;...which is what I want
 
Run TEST a few more times, without redefining it, and see what you get.
'(NIL) is a piece of the structure representing the code, and your
implementation of TEST is modifying itself.

    (test) ;when the function definition is compiled returns
 
Genera's compiler tries to prevent you from modifying program code by
putting constant data in an area that you cannot write into.

The correct version of this program is:

 (defun test ()
   (let ((result (list nil)))
     (loop for item in '(a b c)
	   do (nconc result (list item)))
     result))

although, if you are going to use LOOP, then using its COLLECT feature
is likely to be more efficient than this.

    Error: Attempt to RPLACD a list that is embedded in a structure and
           therefore cannot be RPLACD'ed.  The list is (NIL)
    While in the function SYS:RPLACD-ESCAPE  SYS:*NCONC  TEST
 
    SYS:RPLACD-ESCAPE
       Arg 0 (CONS): (NIL)
       Arg 1 (SI:X): (A)
    s-A, :    Editor Top Level
    s-B:           Restart process Zmacs Windows
    
 
   Can someone help me on this one?