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

Re: shiftf



> MCL's shiftf macro produces unneccesary complicated form in the simple
> cases.  The most frequent use of shift, is probably for simple pointer
> switching in list structures: Replacing a value while saving the old
> value.  (The two-argument (place, newvalue) special case of shiftf used
> to have its own name, swapf)
> 
> Here's what MCL's shiftf produces:
> ? (macroexpand '(shiftf (cddr liste) nil))
> (LET* ((#:G91 LISTE) 
>        (#:G89 (MULTIPLE-VALUE-LIST (CDDR #:G91)))) 
>   (DECLARE (DYNAMIC-EXTENT #:G89)) 
>   (MULTIPLE-VALUE-BIND (#:G90) NIL 
>     (PROGN (CCL::SET-CDDR #:G91 #:G90))) 
>   (VALUES-LIST #:G89))
> 
> Here's a simpler expansion suggestion (Allegro 4.1 produces something
> similar to this):
> (LET* ((#:G91 LISTE) 
>        (#:G89 (CDDR #:G91))
>        (#:G90 NIL))
>   (CCL::SET-CDDR #:G91 #:G90)
>   #:G89)

You didn't mention which version of MCL you are using.  SETF and related macros 
had a lot of work done on them not too long ago.  In MCL2.0p2 (and probably in 
MCL2.0, but p2 is what I've got in front of me right now) the expansion is

(LET* ((#:G30466 LISTE))
  (MULTIPLE-VALUE-PROG1 (CDDR #:G30466)
    (MULTIPLE-VALUE-BIND (#:G30465)
        NIL
      (PROGN (SET-CDDR #:G30466 #:G30465)))))

The MULTIPLE-VALUE-BIND with a single variable is trivially transformed into a 
LET.  If the compiler handling for MULTIPLE-VALUE-PROG! recognizes that CDDR 
always returns one value and makes the obvious transformation, then compiling 
this expansion should produce the same code as your simpler expansion, without 
requiring that the SHIFTF macro (and presumably lots of other similar macros) 
itself try to optimize the expansion.  The reason for all the 
multiple-value-mumbles in the expansion is to support multiple-valued place 
forms (see X3J13 issue SETF-MULTIPLE-STORE-VARIABLES).  Rather than try to make 
the macros optimize this stuff, its much better to make the compiler smart 
about some of these special cases where multiple value forms can be transformed 
into single value forms.  Unfortunately, the compiler doesn't currently seem to 
know about CDDR being single valued, so things could be a bit better.  But the 
"bug" is there, not in SHIFTF.