"The struct-copy form clones a structure and optionally updates specified fields in the clone. This process is sometimes called a functional update, because the result is a structure with updated field values. but the original structure is not modified.
struct-copy struct-id struct-expr [field-id expr] ...)
The struct-id that appears after struct-copy must be a structure type name bound by struct (i.e., the name that cannot be used directly as an expression). The struct-expr must produce an instance of the structure type. The result is a new instance of the structure type that is like the old one, except that the field indicated by each field-id gets the value of the corresponding expr.
Examples:
define p1 (posn 1 2))
define p2 (struct-copy posn p1 [x 3]))
Is the statement about "cannot be directly used in an expression" out of date? It appears it is being used in an expression: define p1 (posn 1 2))
1 Like
Hi @Dashman , Welcome!
I believe the statement "the name that cannot be used directly as an expression" means you can only use posn
as a constructor like your example (define p1 (posn 1 2))
, unlike posn-x
and posn-y
, which are used in expressions to get those components of the struct e.g. (list (posn-x p1) (posn-y p1))
Best regards,
Stephen
PS We are always looking to improve the documentation so if you feel you can make an improvement please don't hesitate to make a pull request with your proposed changes.
1 Like
Yes, I think so—good catch!
IIRC, historically, (define-struct posn (x y))
bound posn
in such a way that it could not be used as an expression, which is why it bound make-posn
to the constructor. After the invention of (struct posn (x y))
, where the same identifier is used for the name and the constructor by default, define-struct
was changed to do the same, easing compatibility and migration to the new style.
Whatever the historical details, posn
and, more explicitly, (#%expression posn)
are definitely valid expressions.
It is still possible to supply keyword options to struct
to specially arrange for posn
not to be directly usable as an expression. Whether or not the identifier can be directly used as an expression is irrelevant as long as it has the static info. I think this is just an outdated, and now wrong, attempt to clarify which identifier to use there.
3 Likes
I think the confusion is do the the double duty of the name posn
here.
In phase 0 it stands for the constructor - which can be used as an expression.
In phase 1 it stands for the structure descriptor.
But regardless, I too think the Guide should be reworded.
1 Like