<br><br><div class="gmail_quote">On Wed, Aug 18, 2010 at 16:52, Matthias Felleisen <span dir="ltr"><<a href="mailto:matthias@ccs.neu.edu">matthias@ccs.neu.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<br>
Eduardo is providing a macro that helps you abbreviate complex<br>
selector and mutator chains. The BENFIT you get is that instead<br>
of writing<br>
<br>
(posn-x (bird-posn (sky-bird (world-sky some-world))))<br>
<br>
you can write -- in Racket --<br>
<br>
some-world.sky.bird.posn.x<br>
<br>
and make Racket programs look as short as C program selectors<br>
or Java dots or Javascript dots etc.<br>
<br>
The PRICE you pay is that you annotate variables and fields<br>
with struct information. That is, you have to say somewhere that<br>
some-world is a variable that always stands for a world struct.<br>
And the sky field in world has to come with information that it<br>
always is a sky-struct. And so on.<br></blockquote></div><br>As describe in the HelpDesk about `prop:procedure' it is <br>also possible to use the struct id as a procedure, so that it can be <br>used as an accessor/mutator.<br>
<br>This is an intermediate solution, as it is nearly (but not quite) as<br>short as the dot notation without introducing global names.<br><br>Just a quick example that needs more error-checking and needs <br>to be abstracted (and, as Matthias and Shriram are pointing out, <br>
this example has a f["baz"] flavor... I don't know if it is possible<br>to fix that if the procedure is not a macro) :<br>
<br>#lang racket<br><br>(struct foo (bar baz)<br> #:mutable<br> #:property prop:procedure <br> (case-lambda<br> [(self attr)<br> (case attr<br> [(bar) (foo-bar self)]<br> [(baz) (foo-baz self)]<br> [else (error "foo: No field named" attr)])]<br>
[(self attr val)<br> (case attr<br> [(bar) (set-foo-bar! self val)]<br> [(baz) (set-foo-baz! self val)]<br> [else (error "foo: No field named" attr)])]))<br><br>(let ([f (foo 1 2)])<br>
(f 'baz 3)<br> (list (f 'bar) (f 'baz)))<br><br><br>Laurent<br>