This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: setf.scm


Maciej Stachowiak <mstachow@mit.edu> writes:

> This differs most markedly from code I posted a while back (with a
> similar interface but rather different implementation) in that setter
> is a macro, and setf! attempts to determine the setter of the passed
> procedure at macro-expansion time, not run-time. I think this is a bad
> idea because it _appears_ to be dynamic, by being based on the
> procedure object rather than the symbol, unlike Common Lisp, but it
> actually isn't because of the macro-expansion property described
> above.

This mechanism wasn't based on your code, but was, what was supposed
to be, an improvement on the mechanism in STk which also is Common
Lispish.

> For instance, code like this:
> 
> (define (mutate-cons-cell accessor cell new-value)
>   (setf! (accessor cell) new-value))
> 
> (define my-cell (cons 3 4))
> (define my-cell (cons 3 4))
> 
> (mutate-cons-cell car my-cell 'x)
> 
> (mutate-cons-cell cdr my-cell 'y)
> 
> Will silently do the shockingly unexpected wrong thing and leave
> my-cell with a value of (y . 4), whereas a fully Common Lisp-like setf
> would have complained, and my code would have done the right thing. I
> think the current code is thus the worst of all possible worlds,
> semantics-wise. (I predicted this on reading the code, but testing
> confirms).

I agree.  I think it should complain.

I made a thought error (Christian's code was OK, but I added the
strange stuff) when implementing this.  I must have thought about
dynamic properties one second and static in the other.  Sorry.  :(

> I also don't think it is useful to allow getters and setters to be
> macros (and obviously that can't be done with the non-memoizing
> version where setter is a procedure since code written to use that
> with macros would be utterly uncompilable). Is there a particular
> purpose that was envisioned for?

It was supposed to be an implementation of Common Lisp's generalized
locations, where getters and setters can be special forms.

On the other hand I don't see a strong need to have dynamic
behaviour.  There is a reason why `set' wasn't included in RnRS.
E.g., in your example above I think it would be more natural to write

  (mutate-cons-cell set-car! my-cell 'x)

    or

  (mutate-cons-cell (setter car) my-cell 'x)

    and

  (define (mutate-cons-cell setter cell new-value)
    (setter cell new-value))

(I'm aware that you wrote the code above to demonstrate my bug, which
 it excellently did, not to show a typical usage of dynamic setf!.)

In fact, the point of doing a thing like

  (set! (car x) 3)

is to get better syntax.  It's supposed to be "syntactic sugar".
If you let the cadar be a variable, it seems to defeat the purpose to
yield clearer code.

I'll change the implementation to a purely static one.

/mdj