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. The `#:constructor-name' option prevents the type name from working as a constructor (unless the supplied name matches the type name). Also, `#:constructor-name' makes the reflective name of the constructor (as reported by `object-name', for example) the symbolic form of the given constructor name, instead of the symbolic form of the type name. The `#:extra-constructor-name' option adds a constructor binding while keeping the type name as a constructor and preserving the symbolic type name as the reflective name of the constructor. The old `define-struct' form (and the form in the HtDP languages) corresponds to use `struct' with a `make-'-prefixed name as `#:constructor-name': > (define-struct a (x y) #:constructor-name make-a) > a a: identifier for static struct-type information cannot be used as an expression in: a > make-a #<procedure:make-a> The new `define-struct' form, in contrast, corresponds to use `struct' with a `make-'-prefixed name as `#:extra-constructor-name': > (define-struct a (x y) #:extra-constructor-name make-a) > a #<procedure:a> > make-a #<procedure:a> This use of `#:extra-constructor-name' above is different from > (define-struct a (x y)) > (define make-a a) in a subtle but crucial way: When you bind an extra constructor via `#:extra-constructor-name', the extra constructor is recorded as the constructor name in the expand-time binding of the type name, which means that `struct-out' exports the extra constructor. * In Scribble sources, `defstruct' corresponds to `define-struct', but it's rendered using `struct' and `#:extra-constructor-name'. A new `defstruct*' corresponds to `struct'. I don't like having the starred form be the preferred form while the unstarred one is is for backward compatibility, but I couldn't find a better name. I hope that a future `scheme/manual' replacement will clean this up (along with many other awkward names an inconsistencies in the Scribble libraries for writing manuals). * Not a change, but a detail to keep in mind: The `scheme' language provides `struct' for signatures via `scheme/unit', which is different from the `struct' in `racket' that is also recognized in signatures. The `mzlib/unit' library provides an even older and different `struct' for signatures. The `struct' from `scheme/unit' is like `define-struct', in that a `#:extra-constructor-name' option with ` make-' prefix is implicit. Whether you use `struct' from `scheme/unit' or from `racket' in a signature, the `#:constructor-name' and `#:extra-constructor-name' options are supported. _________________________________________________ For list-related administrative tasks: http://list.cs.brown.edu/mailman/listinfo/plt-dev