{"size": 7395, "ext": "scrbl", "max_stars_repo_path": "pkgs/racket-doc/syntax/scribblings/struct.scrbl", "max_stars_repo_name": "lkh01/racket", "max_stars_repo_stars_event_min_datetime": "2018-07-05T21:18:24.000Z", "max_stars_repo_stars_event_max_datetime": "2021-06-04T14:48:37.000Z", "max_issues_repo_path": "pkgs/racket-doc/syntax/scribblings/struct.scrbl", "max_issues_repo_name": "lkh01/racket", "max_issues_repo_issues_event_min_datetime": "2017-05-10T07:33:20.000Z", "max_issues_repo_issues_event_max_datetime": "2018-07-19T15:49:46.000Z", "max_forks_repo_path": "pkgs/racket-doc/syntax/scribblings/struct.scrbl", "max_forks_repo_name": "lkh01/racket", "max_forks_repo_forks_event_min_datetime": "2016-04-25T11:47:57.000Z", "max_forks_repo_forks_event_max_datetime": "2017-05-09T14:52:48.000Z"}
{"max_stars_count": 4, "max_issues_count": 9, "max_forks_count": 3, "avg_line_length": 45.0914634146, "max_line_length": 103, "alphanum_fraction": 0.6325895876}
#lang scribble/doc
@(require "common.rkt" (for-label syntax/struct))

@title[#:tag "struct"]{Expanding @racket[define-struct]-like Forms}

@defmodule[syntax/struct]

@defproc[(parse-define-struct [stx syntax?] [orig-stx syntax?]) 
         (values identifier?
                 (or/c identifier? false/c)
                 (listof identifier?)
                 syntax?)]{

Parses @racket[stx] as a @racket[define-struct] form, but uses
@racket[orig-stx] to report syntax errors (under the assumption that
@racket[orig-stx] is the same as @racket[stx], or that they at least share
sub-forms). The result is four values: an identifier for the struct
type name, a identifier or #f for the super-name, a list of
identifiers for fields, and a syntax object for the inspector
expression.}

@defproc[(build-struct-names [name-id identifier?]
			     [field-ids (listof identifier?)]
                             [#:constructor-name ctr-name (or/c identifier? #f) #f]
			     [omit-sel? boolean?]
			     [omit-set? boolean?]
			     [src-stx (or/c syntax? false/c) #f])
          (listof identifier?)]{

Generates the names bound by @racket[define-struct] given an
identifier for the struct type name and a list of identifiers for the
field names. The result is a list of identifiers:

@itemize[
  @item{@racketidfont{struct:}@racket[name-id]}
  @item{@racket[ctr-name], or @racketidfont{make-}@racket[name-id] if @racket[ctr-name] is @racket[#f]}
  @item{@racket[name-id]@racketidfont{?}}
  @item{@racket[name-id]@racketidfont{-}@racket[_field], for each
        @racket[_field] in @racket[field-ids].}
  @item{@racketidfont{set-}@racket[name-id]@racketidfont{-}@racket[_field]@racketidfont{!}
        (getter and setter names alternate).}
  @item{....}]

If @racket[omit-sel?] is true, then the selector names are omitted from the
result list. If @racket[omit-set?] is true, then the setter names are omitted
from the result list.

The default @racket[src-stx] is @racket[#f]; it is used to provide a
source location to the generated identifiers.}

@defproc[(build-struct-generation [name-id identifier?]
                                  [field-ids (listof identifier?)]

                                  [#:constructor-name ctr-name (or/c identifier? #f) #f]
                                  [omit-sel? boolean?]
                                  [omit-set? boolean?]

                                  [super-type any/c #f]
                                  [prop-value-list list? '(list)]
                                  [immutable-k-list list? '(list)])
         (listof identifier?)]{

Takes the same arguments as @racket[build-struct-names] and generates
an S-expression for code using @racket[make-struct-type] to generate
the structure type and return values for the identifiers created by
@racket[build-struct-names].  The optional @racket[super-type],
@racket[prop-value-list], and @racket[immutable-k-list] parameters take
S-expressions that are used as the corresponding argument expressions to
@racket[make-struct-type].}


@defproc[(build-struct-generation* [all-name-ids (listof identifier?)]
				   [name-id identifier?]
				   [field-ids (listof identifier?)]
                                   [#:constructor-name ctr-name (or/c identifier? #f) #f]
				   [omit-sel? boolean?]
				   [omit-set? boolean?]
				   [super-type any/c #f]
				   [prop-value-list list? '(list)]
				   [immutable-k-list list? '(list)])
	 (listof identifier?)]{

Like @racket[build-struct-generation], but given the names produced by
@racket[build-struct-names], instead of re-generating them.}

@defproc[(build-struct-expand-info [name-id identifier?]
                                   [field-ids (listof identifier?)]
                                   [#:omit-constructor? no-ctr? any/c #f]
                                   [#:constructor-name ctr-name (or/c identifier? #f) #f]
                                   [#:omit-struct-type? no-type? any/c #f]
                                   [omit-sel? boolean?]
                                   [omit-set? boolean?]
                                   [base-name (or/c identifier? boolean?)]
                                   [base-getters (listof (or/c identifier? false/c))]
                                   [base-setters (listof (or/c identifier? false/c))])
	 any]{

Takes mostly the same arguments as @racket[build-struct-names], plus a parent
identifier/@racket[#t]/@racket[#f] and a list of accessor and mutator
identifiers (possibly ending in @racket[#f]) for a parent type, and
generates an S-expression for expansion-time code to be used in the
binding for the structure name. 

If @racket[no-ctr?] is true, then the constructor name is omitted from
the expansion-time information. Similarly, if @racket[no-type?] is
true, then the structure-type name is omitted.

A @racket[#t] for the @racket[base-name] means no super-type,
@racket[#f] means that the super-type (if any) is unknown, and an
identifier indicates the super-type identifier.}


@defproc[(struct-declaration-info? [v any/c]) boolean?]{

Returns @racket[#t] if @racket[x] has the shape of expansion-time
information for structure type declarations, @racket[#f] otherwise.
See @secref[#:doc refman]{structinfo}.}


@defproc[(generate-struct-declaration [orig-stx syntax?] 
                                      [name-id identifier?]
                                      [super-id-or-false (or/c identifier? false/c)]
                                      [field-id-list (listof identifier?)]
                                      [current-context any/c]
				      [make-make-struct-type procedure?]
				      [omit-sel? boolean? #f]
				      [omit-set? boolean? #f])
	 syntax?]{

This procedure implements the core of a @racket[define-struct]
expansion.

The @racket[generate-struct-declaration] procedure is called by a
macro expander to generate the expansion, where the @racket[name-id],
@racket[super-id-or-false], and @racket[field-id-list] arguments
provide the main parameters. The @racket[current-context] argument is
normally the result of @racket[syntax-local-context]. The
@racket[orig-stx] argument is used for syntax errors. The optional
@racket[omit-sel?] and @racket[omit-set?]  arguments default to
@racket[#f]; a @racket[#t] value suppresses definitions of field
selectors or mutators, respectively.

The @racket[make-struct-type] procedure is called to generate the
expression to actually create the struct type. Its arguments are
@racket[orig-stx], @racket[name-id-stx], @racket[defined-name-stxes],
and @racket[super-info].  The first two are as provided originally to
@racket[generate-struct-declaration], the third is the set of names
generated by @racket[build-struct-names], and the last is super-struct
info obtained by resolving @racket[super-id-or-false] when it is not
@racket[#f], @racket[#f] otherwise.

The result should be an expression whose values are the same as the
result of @racket[make-struct-type]. Thus, the following is a basic
@racket[make-make-struct-type]:

@RACKETBLOCK[
      (lambda (orig-stx name-stx defined-name-stxes super-info)
        #`(make-struct-type '#,name-stx
                             #,(and super-info (list-ref super-info 0))
                             #,(/ (- (length defined-name-stxes) 3) 2)
                             0 #f))]

but an actual @racket[make-make-struct-type] will likely do more.}
