[plt-scheme] A macro for declaring class properties, a question

From: Jens Axel Soegaard (jensaxel at soegaard.net)
Date: Thu Oct 18 12:23:08 EDT 2007

Grant Rettke skrev:
> On 10/18/07, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
>> Hygiene means create names to avoid binding conflicts. So in this case,
>> imagine that each use of (property name) would actually introduce
>> super-secret-name1, super-secret-name2, etc. See macro stepper.
> In the case of Noel's code, then:
> (define-syntax property
>  (syntax-rules ()
>    [(_ name)
>     (begin (field super-secret-field-name)
>            (define/public name
>              (case-lambda
>                [() super-secret-field-name]
>                [(value) (set! super-secret-field-name value)])))]))
> Hygiene would avoid name clashes if all of the properties are
> generated within that macro: think (property x y z) versus (property
> x) (property y) (property z). Otherwise super-secret-field-name would
> get generated 3 times? I think this is the case as I just tried out
> the latter and got name clashes.

The above is the definition of property.

Different uses of property will introduce different identifiers.
One way to think of the expansion of the three uses of property:

   (property foo)
   (property bar)
   (property baz)

is that each use is marked with a unique number.

   (property_1 foo)
   (property_2 bar)
   (property_3 baz)

In the expansion of property_1 each newly introduced
identifier will automatically get _1 appended.

That is (property_1 foo) will expand to:

      (begin (field super-secret-field-name_1)
             (define/public foo
                 [() super-secret-field-name_1]
                 [(value) (set! super-secret-field-name_1 value)])))]))

In the same manner (property_2 bar) will expand to:

      (begin (field super-secret-field-name_2)
             (define/public bar
                 [() super-secret-field-name_2]
                 [(value) (set! super-secret-field-name_2 value)])))]))

The neat result is that you don't get any name conflicts.

The actual process is a more complicated, but as a first approximation
the above explanation is close enough to be useful.

(In the Macro Stepper, click on a name to see which identifiers
belong together.)

Jens Axel Søgaard

Posted on the users mailing list.