# Question on Racket Guide 5.2 statement

**URL:** <https://racket.discourse.group/t/question-on-racket-guide-5-2-statement/3903>\
**Category:** Questions & Answers\
**Created:** [August 16, 2025, 1:03am UTC](https://racket.discourse.group/t/question-on-racket-guide-5-2-statement/3903 "2025-08-16T01:03:46Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dashman](https://avatars.discourse-cdn.com/v4/letter/d/e19b73/32.png) [@Dashman](https://racket.discourse.group/u/Dashman)\
**Post date:** [August 16, 2025, 1:03am UTC](https://racket.discourse.group/t/question-on-racket-guide-5-2-statement/3903/1 "2025-08-16T01:03:46Z")

</div>

"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))

---

<div class="post-metadata">

**Author:** ![spdegabrielle](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/spdegabrielle/32/95_2.png) [@spdegabrielle](https://racket.discourse.group/u/spdegabrielle)\
**Post date:** [August 16, 2025, 4:57pm UTC](https://racket.discourse.group/t/question-on-racket-guide-5-2-statement/3903/2 "2025-08-16T16:57:48Z")

</div>

> [@Dashman](#):
>
> 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))

Hi @Dashman , Welcome!  
I believe the statement ["the name that cannot be used directly as an expression"](https://docs.racket-lang.org/guide/define-struct.html#(part._struct-copy):~:text=(i.e.%2C-,the%20name%20that%20cannot%20be%20used%20directly%20as%20an%20expression,-).%20The%20struct%2Dexpr) 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.

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [August 16, 2025, 8:24pm UTC](https://racket.discourse.group/t/question-on-racket-guide-5-2-statement/3903/3 "2025-08-16T20:24:08Z")

</div>

> [@Dashman](#):
>
> Is the statement about "cannot be directly used in an expression" out of date?

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.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [August 16, 2025, 10:34pm UTC](https://racket.discourse.group/t/question-on-racket-guide-5-2-statement/3903/4 "2025-08-16T22:34:06Z")

</div>

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.
