[plt-dev] `struct' and `define-struct'

From: Jakub Piotr Cłapa (jpc-ml at zenburn.net)
Date: Sun Apr 25 16:09:24 EDT 2010

On 25-04-10 20:15, Matthew Flatt wrote:
> Updating documentation has forced me to think a lot more about
> `struct', `define-struct', and the transition path for `scheme' to
> `racket', and so I've made some changes:
>   * `define-struct' (as provided by both `scheme/base' and
>     `racket/base') binds the type name as a constructor in addition to
>     the `make-'-prefixed name.
>        >  (define-struct a (x y))
>        >  (a 1 2)
>        #<a>
>     Furthermore, the name of the constructor as reported by
>     `object-name' is the type name, not the `make-'-prefixed name:
>        >  (define-struct a (x y))
>        >  make-a
>        #<procedure:a>
>     This makes our existing libraries `racket'-ready without having to
>     change all the `define-struct's to `struct'. And since the type name
>     bound by `define-struct' was previously disallowed as an expression,
>     the change is generally backward-compatible.
>   * The `struct' and `define-struct' forms accept `#:constructor-name'
>     and `#:extra-constructor-name' options.

I was writing some custom constructors which use optional and keyword 
arguments and I didn't like what I ended with:
1. Name the new constructor make-foo* and rename-out it. (I have to use 
the starred form in the current module).
2. set! the old constructor binding to the new lambda while using let to 
memorize the old binding. Ugly...

With the new syntax I could use #:constructor-name make-foo* and name my 
own make-foo but AFAIU it won't work for naming my constructor foo since 
this would shadow the type name binding.

Why not add a #:custom-contructor argument taking a procedure to install 
as a default constructor for both make-foo and foo. If used together 
with #:constructor-name it would allow access to the old constructor.

Jakub Piotr Cłapa

Posted on the dev mailing list.