emacs.d/clones/scheme/docs.racket-lang.org/reference/struct-generics.html

103 lines
102 KiB
HTML
Raw Normal View History

2022-09-30 11:00:09 +02:00
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/><meta name="viewport" content="width=device-width, initial-scale=0.8"/><title>5.4&nbsp;Generic Interfaces</title><link rel="stylesheet" type="text/css" href="../scribble.css" title="default"/><link rel="stylesheet" type="text/css" href="extras.css" title="default"/><link rel="stylesheet" type="text/css" href="../racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-style.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../manual-racket.css" title="default"/><link rel="stylesheet" type="text/css" href="../doc-site.css" title="default"/><script type="text/javascript" src="../scribble-common.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../manual-racket.js"></script><script type="text/javascript" src="../doc-site.js"></script><script type="text/javascript" src="../local-redirect/local-redirect.js"></script><script type="text/javascript" src="../local-redirect/local-user-redirect.js"></script><!--[if IE 6]><style type="text/css">.SIEHidden { overflow: hidden; }</style><![endif]--></head><body id="doc-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist tocviewlisttopspace"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_0&quot;);">&#9658;</a></td><td></td><td><a href="index.html" class="tocviewlink" data-pltdoc="x">The Racket Reference</a></td></tr></table></div><div class="tocviewsublisttop" style="display: none;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1&nbsp;</td><td><a href="model.html" class="tocviewlink" data-pltdoc="x">Language Model</a></td></tr><tr><td align="right">2&nbsp;</td><td><a href="notation.html" class="tocviewlink" data-pltdoc="x">Notation for Documentation</a></td></tr><tr><td align="right">3&nbsp;</td><td><a href="syntax.html" class="tocviewlink" data-pltdoc="x">Syntactic Forms</a></td></tr><tr><td align="right">4&nbsp;</td><td><a href="data.html" class="tocviewlink" data-pltdoc="x">Datatypes</a></td></tr><tr><td align="right">5&nbsp;</td><td><a href="structures.html" class="tocviewselflink" data-pltdoc="x">Structures</a></td></tr><tr><td align="right">6&nbsp;</td><td><a href="mzlib_class.html" class="tocviewlink" data-pltdoc="x">Classes and Objects</a></td></tr><tr><td align="right">7&nbsp;</td><td><a href="mzlib_unit.html" class="tocviewlink" data-pltdoc="x">Units</a></td></tr><tr><td align="right">8&nbsp;</td><td><a href="contracts.html" class="tocviewlink" data-pltdoc="x">Contracts</a></td></tr><tr><td align="right">9&nbsp;</td><td><a href="match.html" class="tocviewlink" data-pltdoc="x">Pattern Matching</a></td></tr><tr><td align="right">10&nbsp;</td><td><a href="control.html" class="tocviewlink" data-pltdoc="x">Control Flow</a></td></tr><tr><td align="right">11&nbsp;</td><td><a href="concurrency.html" class="tocviewlink" data-pltdoc="x">Concurrency and Parallelism</a></td></tr><tr><td align="right">12&nbsp;</td><td><a href="Macros.html" class="tocviewlink" data-pltdoc="x">Macros</a></td></tr><tr><td align="right">13&nbsp;</td><td><a href="input-and-output.html" class="tocviewlink" data-pltdoc="x">Input and Output</a></td></tr><tr><td align="right">14&nbsp;</td><td><a href="security.html" class="tocviewlink" data-pltdoc="x">Reflection and Security</a></td></tr><tr><td align="right">15&nbsp;</td><td><a href="os.html" class="tocviewlink" data-pltdoc="x">Operating System</a></td></tr><tr><td align="right">16&nbsp;</td><td><a href="memory.html" class="tocviewlink" data-pltdoc="x">Memory Management</a></td></tr><tr><td align="right">17&nbsp;</td><td><a href="unsafe.html" class="tocviewlink" data-pltdoc="x">Unsafe Operations</a></td></tr><tr><td align="right">18&nbsp;</td><td><a href="running.html" class=
associated with generic functions. Generic functions are defined
using a <span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define-generics%29%29" class="RktStxLink" data-pltdoc="x">define-generics</a></span> form. Method implementations for
a structure type are defined using the <span class="RktPn">#:methods</span> keyword
(see <a href="define-struct.html" data-pltdoc="x">Defining Structure Types: <span class="RktSym"><span class="RktStxLink">struct</span></span></a>).</p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><table cellspacing="0" cellpadding="0" class="RktBlk RForeground"><tr><td><span class="RktPn">(</span><a name="(form._((lib._racket/generic..rkt)._define-generics))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define-generics%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">define-generics</a></span></span><span class="hspace">&nbsp;</span><span class="RktVar">id</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">generics-opt</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktVar">method-id</span><span class="hspace">&nbsp;</span><span class="RktPn">. </span><span class="RktVar">kw-formals*</span><span class="RktPn">]</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">generics-opt</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr><tr><td><span class="stt">&nbsp;</span></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="specgrammar"><tr><td align="right" valign="baseline"><span class="RktVar">generics-opt</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktPn">#:defaults</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktVar">default-pred?</span><span class="hspace">&nbsp;</span><span class="RktVar">default-impl</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span><span class="RktPn">]</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktPn">#:fast-defaults</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktVar">fast-pred?</span><span class="hspace">&nbsp;</span><span class="RktVar">fast-impl</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span><span class="RktPn">]</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktPn">#:fallbacks</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktVar">fallback-impl</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span><span class="RktPn">]</span></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktPn">#:defined-predicate</span><
the static information about a new generic interface;</p></li><li><p><span class="RktVar">id</span><span class="RktSym">?</span> as a predicate identifying
instances of structure types that implement this generic group; and</p></li><li><p>each <span class="RktVar">method-id</span> as a <a name="(tech._generic._method)"></a><span style="font-style: italic">generic method</span> that calls the
corresponding method on values where
<span class="RktVar">id</span><span class="RktSym">?</span> is true.
Each <span class="RktVar">method-id</span>&rsquo;s <span class="RktVar">kw-formals*</span> must include a required
by-position argument that is <span class="RktSym"><a href="stxcmp.html#%28def._%28%28quote._~23~25kernel%29._free-identifier~3d~3f%29%29" class="RktValLink" data-pltdoc="x">free-identifier=?</a></span> to
<span class="RktVar">id</span>. That argument is used in the generic definition to
locate the specialization.</p></li><li><p><span class="RktVar">id</span><span class="RktSym">/c</span> as a contract combinator that
recognizes instances of structure types which implement the
<span class="RktSym">gen:</span><span class="RktVar">id</span> generic interface. The combinator
takes pairs of <span class="RktVar">method-id</span>s and contracts. The contracts
will be applied to each of the corresponding method implementations.
The <span class="RktVar">id</span><span class="RktSym">/c</span> combinator is intended to be used to
contract the range of a constructor procedure for a struct type that
implements the generic interface.</p></li></ul><p>The <span class="RktPn">#:defaults</span> option may be provided at most once.
When it is provided, each generic function
uses <span class="RktVar">default-pred?</span>s to dispatch to the given
<a name="(tech._default._method)"></a><span style="font-style: italic">default method</span> implementations,
<span class="RktVar">default-impl</span>s, if dispatching to the generic method table fails.
The syntax of the <span class="RktVar">default-impl</span>s is the same as the methods
provided for the <span class="RktPn">#:methods</span> keyword for <span class="RktSym"><a href="define-struct.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._struct%29%29" class="RktStxLink" data-pltdoc="x">struct</a></span>.</p><p>The <span class="RktPn">#:fast-defaults</span> option may be provided at most once.
It works the same as <span class="RktPn">#:defaults</span>, except the <span class="RktVar">fast-pred?</span>s are
checked before dispatching to the generic method table. This option is
intended to provide a fast path for dispatching to built-in datatypes, such as
lists and vectors, that do not overlap with structures implementing
<span class="RktSym">gen:</span><span class="RktVar">id</span>.</p><p>The <span class="RktPn">#:fallbacks</span> option may be provided at most once.
When it is provided, the <span class="RktVar">fallback-impl</span>s define
<a name="(tech._fallback._method)"></a><span style="font-style: italic">fallback method</span> implementations
that are used for any instance of the generic interface that does not supply a
specific implementation. The syntax of the <span class="RktVar">fallback-impl</span>s is the same
as the methods provided for the <span class="RktPn">#:methods</span> keyword for <span class="RktSym"><a href="define-struct.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._struct%29%29" class="RktStxLink" data-pltdoc="x">struct</a></span>.</p><p>The <span class="RktPn">#:defined-predicate</span> option may be provided at most once.
When it is provided, <span class="RktVar">defined-pred-id</span> is defined as a
procedure that reports whether a specific instance of the generic interface
implements a given set of methods.
Specifically, <span class="RktPn">(</span><span class="RktVar">defined-pred-id</span><span class="stt"> </span><span class="RktSym">v</span><span class="stt"> </span><span class="RktVal">'</span><span class="RktVal">name</span><span class="stt"> </span><span class="RktMeta"><a href="stx-patterns.html#%28form._%28%28lib._racket%2Fprivate%2Fstxcase-scheme..rkt%29._......%29%29" class="RktStxLink" data-pltdoc="x">...</a></span><span class="RktPn">)</span> produces <span class="RktVal">#t</span> if
<span class="RktSym">v</span> has implementations for each method <span class="RktSym">name</span>, not counting
<span class="RktPn">#:fallbacks</span> implementations, and produces <span class="RktVal">#f</span> otherwise.
This procedure is intended for use by
higher-level APIs to adapt their behavior depending on method
availability.</p><p>The <span class="RktPn">#:defined-table</span> option may be provided at most once.
When it is provided, <span class="RktVar">defined-table-id</span> is defined as a
procedure that takes an instance of the generic interface and returns an
immutable <a href="hashtables.html#%28tech._hash._table%29" class="techoutside" data-pltdoc="x"><span class="techinside">hash table</span></a> that maps symbols corresponding to method
names to booleans representing whether or not that method is
implemented by the instance. This option is deprecated; use
<span class="RktPn">#:defined-predicate</span> instead.</p><p>The <span class="RktPn">#:derive-property</span> option may be provided any number of times.
Each time it is provided, it specifies a <a href="structprops.html#%28tech._structure._type._property%29" class="techoutside" data-pltdoc="x"><span class="techinside">structure type property</span></a> via
<span class="RktVar">prop-expr</span> and a value for the property via <span class="RktVar">prop-value-expr</span>.
All structures implementing the generic interface via <span class="RktPn">#:methods</span>
automatically implement this structure type property using the provided values.
When <span class="RktVar">prop-value-expr</span> is executed, each <span class="RktVar">method-id</span> is bound to
its specific implementation for the <a href="structures.html#%28tech._structure._type%29" class="techoutside" data-pltdoc="x"><span class="techinside">structure type</span></a>.</p><p>If a value <span class="RktSym">v</span> satisfies <span class="RktVar">id</span><span class="RktSym">?</span>, then <span class="RktSym">v</span> is
a <a name="(tech._generic._instance)"></a><span style="font-style: italic">generic instance</span> of <span class="RktSym">gen:</span><span class="RktVar">id</span>.</p><p>If a generic instance <span class="RktSym">v</span> has a corresponding implementation for some
<span class="RktVar">method-id</span> provided via <span class="RktPn">#:methods</span> in <span class="RktSym"><a href="define-struct.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._struct%29%29" class="RktStxLink" data-pltdoc="x">struct</a></span> or via
<span class="RktPn">#:defaults</span> or <span class="RktPn">#:fast-defaults</span> in <span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define-generics%29%29" class="RktStxLink" data-pltdoc="x">define-generics</a></span>,
then <span class="RktVar">method-id</span> is an <a name="(tech._implemented._generic._method)"></a><span style="font-style: italic">implemented generic method</span> of
<span class="RktSym">v</span>.</p><p>If <span class="RktVar">method-id</span> is not an implemented generic method of a generic
instance <span class="RktSym">v</span>, and <span class="RktVar">method-id</span> has a fallback implementation that
does not raise an <span class="RktSym"><a href="struct-generics.html#%28def._%28%28lib._racket%2Fgeneric..rkt%29._exn~3afail~3asupport%29%29" class="RktValLink" data-pltdoc="x">exn:fail:support</a></span> exception when given <span class="RktSym">v</span>,
then <span class="RktVar">method-id</span> is a <a name="(tech._supported._generic._method)"></a><span style="font-style: italic">supported generic method</span> of <span class="RktSym">v</span>.</p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>procedure</p></div></div><p class="RForeground"><span class="RktPn">(</span><a name="(def._((lib._racket/generic..rkt)._raise-support-error))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28def._%28%28lib._racket%2Fgeneric..rkt%29._raise-support-error%29%29" class="RktValDef RktValLink" data-pltdoc="x">raise-support-error</a></span></span><span class="hspace">&nbsp;</span><span class="RktVar">name</span><span class="hspace">&nbsp;</span><span class="RktVar">v</span><span class="RktPn">)</span><span class="hspace">&nbsp;</span>&rarr;<span class="hspace">&nbsp;</span><span class="RktSym"><a href="data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt%29._none%2Fc%29%29" class="RktValLink" data-pltdoc="x">none/c</a></span></p></blockquote></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">name</span><span class="hspace">&nbsp;</span>:<span class="hspace">&nbsp;</span><span class="RktSym"><a href="symbols.html#%28def._%28%28quote._~23~25kernel%29._symbol~3f%29%29" class="RktValLink" data-pltdoc="x">symbol?</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">v</span><span class="hspace">&nbsp;</span>:<span class="hspace">&nbsp;</span><span class="RktSym"><a href="data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt%29._any%2Fc%29%29" class="RktValLink" data-pltdoc="x">any/c</a></span></td></tr></table></blockquote></div><div class="SIntrapara">Raises an <span class="RktSym"><a href="struct-generics.html#%28def._%28%28lib._racket%2Fgeneric..rkt%29._exn~3afail~3asupport%29%29" class="RktValLink" data-pltdoc="x">exn:fail:support</a></span> exception for a <a href="struct-generics.html#%28tech._generic._method%29" data-pltdoc="x">generic
method</a> called <span class="RktVar">name</span> that does not support the <a href="struct-generics.html#%28tech._generic._instance%29" data-pltdoc="x">generic
instance</a> <span class="RktVar">v</span>.</div></p><p><div class="SIntrapara">Example:</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="struct-generics.html#%28def._%28%28lib._racket%2Fgeneric..rkt%29._raise-support-error%29%29" class="RktValLink" data-pltdoc="x">raise-support-error</a></span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">some-method-name</span><span class="hspace">&nbsp;</span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"arbitrary"</span><span class="hspace">&nbsp;</span><span class="RktVal">"instance"</span><span class="hspace">&nbsp;</span><span class="RktVal">"value"</span><span class="RktVal">)</span><span class="RktPn">)</span></td></tr><tr><td><p><span class="RktErr">some-method-name: not implemented for '("arbitrary"</span></p></td></tr><tr><td><p><span class="RktErr">"instance" "value")</span></p></td></tr></table></blockquote></div></p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>struct</p></div></div><table cellspacing="0" cellpadding="0" class="RForeground"><tr><td><span class="RktPn">(</span><span class="RktSym"><a href="define-struct.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._struct%29%29" class="RktStxLink" data-pltdoc="x">struct</a></span></td><td><span class="hspace">&nbsp;</span></td><td><a name="(def._((lib._racket/generic..rkt)._exn~3afail~3asupport~3f))"></a><a name="(def._((lib._racket/generic..rkt)._struct~3aexn~3afail~3asupport))"></a><a name="(def._((lib._racket/generic..rkt)._exn~3afail~3asupport))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28def._%28%28lib._racket%2Fgeneric..rkt%29._exn~3afail~3asupport%29%29" class="RktValDef RktValLink" data-pltdoc="x">exn:fail:support</a></span></span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="exns.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._exn~3afail%29%29" class="RktValLink" data-pltdoc="x">exn:fail</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">#:transparent</span><span class="RktPn">)</span></td></tr></table></blockquote></div><div class="SIntrapara">Raised for <a href="struct-generics.html#%28tech._generic._method%29" data-pltdoc="x">generic methods</a> that do not support the given
<a href="struct-generics.html#%28tech._generic._instance%29" data-pltdoc="x">generic instance</a>.</div></p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><p class="RForeground"><span class="RktPn">(</span><a name="(form._((lib._racket/generic..rkt)._define/generic))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define%2Fgeneric%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">define/generic</a></span></span><span class="hspace">&nbsp;</span><span class="RktVar">local-id</span><span class="hspace">&nbsp;</span><span class="RktVar">method-id</span><span class="RktPn">)</span></p></blockquote></td></tr></table></blockquote></div><div class="SIntrapara">When used inside the method definitions associated with the <span class="RktPn">#:methods</span>,
<span class="RktPn">#:fallbacks</span>, <span class="RktPn">#:defaults</span> or <span class="RktPn">#:fast-defaults</span> keywords,
binds <span class="RktVar">local-id</span> to the generic for <span class="RktVar">method-id</span>. This form is
useful for method specializations to use generic methods (as opposed to the
local specialization) on other values.</div></p><p><div class="SIntrapara">The <span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define%2Fgeneric%29%29" class="RktStxLink" data-pltdoc="x">define/generic</a></span> form is only allowed inside:
</div><div class="SIntrapara"><ul><li><p>a <span class="RktPn">#:methods</span> specification in <span class="RktSym"><a href="define-struct.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._struct%29%29" class="RktStxLink" data-pltdoc="x">struct</a></span> (or <span class="RktSym"><a href="define-struct.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define-struct%29%29" class="RktStxLink" data-pltdoc="x">define-struct</a></span>)</p></li><li><p>the specification of <span class="RktPn">#:fallbacks</span>, <span class="RktPn">#:defaults</span> or
<span class="RktPn">#:fast-defaults</span> in <span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define-generics%29%29" class="RktStxLink" data-pltdoc="x">define-generics</a></span></p></li></ul></div></p><p>Using <span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define%2Fgeneric%29%29" class="RktStxLink" data-pltdoc="x">define/generic</a></span> elsewhere is a syntax error.</p><p><div class="SIntrapara">Examples:</div><div class="SIntrapara"><blockquote class="SCodeFlow"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td><span class="stt">&gt; </span><span class="RktPn">(</span><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define-generics%29%29" class="RktStxLink" data-pltdoc="x">define-generics</a></span><span class="hspace">&nbsp;</span><span class="RktSym">printable</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">gen-print</span><span class="hspace">&nbsp;</span><span class="RktSym">printable</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">port</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">gen-port-print</span><span class="hspace">&nbsp;</span><span class="RktSym">port</span><span class="hspace">&nbsp;</span><span class="RktSym">printable</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym">gen-print*</span><span class="hspace">&nbsp;</span><span class="RktSym">printable</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">port</span><span class="RktPn">]</span><span class="hspace">&nbsp;</span><span class="RktPn">#:width</span><span class="hspace">&nbsp;</span><span class="RktSym">width</span><span class="hspace">&nbsp;</span><span class="RktPn">#:height</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">height</span><span class="RktPn">]</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">#:defaults</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktSym"><a href="strings.html#%28def._%28%28quote._~23~25kernel%29._string~3f%29%29" class="RktValLink" data-pltdoc="x">string?</a></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._define%2Fgeneric%29%29" class="RktStxLink" data-pltdoc="x">define/generic</a></span><span class="hspace">&nbsp;</span><span class="RktSym">super-print</span><span class="hspace">&nbsp;</span><span class="RktSym">gen-print</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="define.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._define%29%29" class="RktStxLink" data-pltdoc="x">define</a></span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym">gen-print</span><span class="hspace">&nbsp;</span><span class="RktSym">s</span><span class="hspace">&nbsp;</span><span class="RktPn">[</span><span class="RktSym">port</span><span class="hspace">&nbsp;</span><span class="RktPn">(</span><span class="RktSym"><a href="port-ops.html#%
interface</span></a> <span class="RktVar">gen-id</span>, and constrains their implementations of the
specified <span class="RktVar">method-id</span>s with the corresponding <span class="RktVar">method-ctc</span>s.</div></p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><table cellspacing="0" cellpadding="0" class="RktBlk RForeground"><tr><td><span class="RktPn">(</span><a name="(form._((lib._racket/generic..rkt)._impersonate-generics))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._impersonate-generics%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">impersonate-generics</a></span></span><span class="hspace">&nbsp;</span><span class="RktVar">gen-id</span><span class="hspace">&nbsp;</span><span class="RktVar">val-expr</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktVar">method-id</span><span class="hspace">&nbsp;</span><span class="RktVar">method-proc-expr</span><span class="RktPn">]</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">maybe-properties</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr><tr><td><span class="stt">&nbsp;</span></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="specgrammar"><tr><td align="right" valign="baseline"><span class="RktVar">maybe-properties</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktPn">#:properties</span><span class="hspace">&nbsp;</span><span class="RktVar">props-expr</span></td></tr></table></td></tr><tr><td><span class="stt">&nbsp;</span></td></tr><tr><td><blockquote class="SubFlow"><table cellspacing="0" cellpadding="0" class="argcontract"><tr><td><span class="hspace">&nbsp;&nbsp;</span></td><td><span class="RktVar">method-proc-expr</span></td><td><span class="hspace">&nbsp;</span></td><td>:</td><td><span class="hspace">&nbsp;</span></td><td><span class="RktPn">(</span><span class="RktSym"><a href="data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt%29._any%2Fc%29%29" class="RktValLink" data-pltdoc="x">any/c</a></span><span class="hspace">&nbsp;</span><span class="RktPn">. </span><span class="RktSym"><a href="function-contracts.html#%28form._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._-~3e%29%29" class="RktStxLink" data-pltdoc="x"><span class="nobreak">-&gt;</span></a></span><span class="RktPn"> .</span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fprivate%2Fmisc..rkt%29._any%2Fc%29%29" class="RktValLink" data-pltdoc="x">any/c</a></span><span class="RktPn">)</span></td></tr></table><table cellspacing="0" cellpadding="0" class="argcontract"><tr><td><span class="hspace">&nbsp;&nbsp;</span></td><td><span class="RktVar">props-expr</span></td><td><span class="hspace">&nbsp;</span></td><td>:</td><td><span class="hspace">&nbsp;</span></td><td><span class="RktPn">(</span><span class="RktSym"><a href="data-structure-contracts.html#%28def._%28%28lib._racket%2Fcontract%2Fbase..rkt%29._list%2Fc%29%29" class="RktValLink" data-pltdoc="x">list/c</a></span><span class="hspace">&nbsp;</span><span class="RktSym"><a href="chaperones.html#%28def._%28%28quote._~23~25kernel%29._imperso
that implements the <a href="struct-generics.html#%28tech._generic._interface%29" class="techoutside" data-pltdoc="x"><span class="techinside">generic interface</span></a> <span class="RktVar">gen-id</span>. The impersonator
applies the results of the <span class="RktVar">method-proc-expr</span>s to the structure&rsquo;s implementation
of the corresponding <span class="RktVar">method-id</span>s, and replaces the method
implementation with the result.</div></p><p>A <span class="RktVar">props-expr</span> can provide properties to attach to the
impersonator. The result of <span class="RktVar">props-expr</span> must be a list with
an even number of elements, where the first element of the list is an
impersonator property, the second element is its value, and so on.</p><p class="SHistory">Changed in version 6.1.1.8 of package <span class="stt">base</span>: Added <span class="RktPn">#:properties</span>.</p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><table cellspacing="0" cellpadding="0" class="RktBlk RForeground"><tr><td><span class="RktPn">(</span><a name="(form._((lib._racket/generic..rkt)._chaperone-generics))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._chaperone-generics%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">chaperone-generics</a></span></span><span class="hspace">&nbsp;</span><span class="RktVar">gen-id</span><span class="hspace">&nbsp;</span><span class="RktVar">val-expr</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktVar">method-id</span><span class="hspace">&nbsp;</span><span class="RktVar">method-proc-expr</span><span class="RktPn">]</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">maybe-properties</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr></table></blockquote></div><div class="SIntrapara">Like <span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._impersonate-generics%29%29" class="RktStxLink" data-pltdoc="x">impersonate-generics</a></span>, but
creates a <a href="chaperones.html#%28tech._chaperone%29" class="techoutside" data-pltdoc="x"><span class="techinside">chaperone</span></a> of <span class="RktVar">val-expr</span>, which must be a structure
that implements the <a href="struct-generics.html#%28tech._generic._interface%29" class="techoutside" data-pltdoc="x"><span class="techinside">generic interface</span></a> <span class="RktVar">gen-id</span>. The chaperone
applies the specified <span class="RktSym">method-proc</span>s to the structure&rsquo;s implementation
of the corresponding <span class="RktVar">method-id</span>s, and replaces the method
implementation with the result, which must be a chaperone of the original.</div></p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><table cellspacing="0" cellpadding="0" class="RktBlk RForeground"><tr><td><span class="RktPn">(</span><a name="(form._((lib._racket/generic..rkt)._redirect-generics))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._redirect-generics%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">redirect-generics</a></span></span><span class="hspace">&nbsp;</span><span class="RktVar">mode</span><span class="hspace">&nbsp;</span><span class="RktVar">gen-id</span><span class="hspace">&nbsp;</span><span class="RktVar">val-expr</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktPn">[</span><span class="RktVar">method-id</span><span class="hspace">&nbsp;</span><span class="RktVar">method-proc-expr</span><span class="RktPn">]</span><span class="hspace">&nbsp;</span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktVar">maybe-properties</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr></table></blockquote></div><div class="SIntrapara">Like <span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._impersonate-generics%29%29" class="RktStxLink" data-pltdoc="x">impersonate-generics</a></span>, but
creates an <a href="chaperones.html#%28tech._impersonator%29" class="techoutside" data-pltdoc="x"><span class="techinside">impersonator</span></a> of <span class="RktVar">val-expr</span>
if <span class="RktVar">mode</span> evaluates to <span class="RktVal">#f</span>, or creates
a <a href="chaperones.html#%28tech._chaperone%29" class="techoutside" data-pltdoc="x"><span class="techinside">chaperone</span></a> of <span class="RktVar">val-expr</span> otherwise.</div></p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><table cellspacing="0" cellpadding="0" class="RktBlk RForeground"><tr><td><span class="RktPn">(</span><a name="(form._((lib._racket/generic..rkt)._make-struct-type-property/generic))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._make-struct-type-property%2Fgeneric%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">make-struct-type-property/generic</a></span></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">name-expr</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">maybe-guard-expr</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">maybe-supers-expr</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">maybe-can-impersonate?-expr</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktVar">property-option</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;</span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr><tr><td><span class="stt">&nbsp;</span></td></tr><tr><td><table cellspacing="0" cellpadding="0" class="specgrammar"><tr><td align="right" valign="baseline"><span class="RktVar">maybe-guard-expr</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktVar">guard-expr</span></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td></tr><tr><td align="right" valign="baseline"><span class="RktVar">maybe-supers-expr</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><table cellspacing="0" cellpadding="0" class="RktBlk"><tr><td></td></tr></table></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="RktVar">supers-expr</span></td></tr><tr><td align="right" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="center" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td><td align="left" valign="baseline"><span class="stt">&nbsp;</span></td></tr><tr><td align="right" valign="baseline"><span class="RktVar">maybe-can-impersonate?-expr</span></td><td align="left" valign="baseline"><span class="stt">
values, just like <span class="RktSym"><a href="structprops.html#%28def._%28%28quote._~23~25kernel%29._make-struct-type-property%29%29" class="RktValLink" data-pltdoc="x">make-struct-type-property</a></span> would:</div></p><ul><li><p>a <a href="structprops.html#%28tech._structure._type._property._descriptor%29" class="techoutside" data-pltdoc="x"><span class="techinside">structure type property descriptor</span></a></p></li><li><p>a <a href="structprops.html#%28tech._property._predicate%29" class="techoutside" data-pltdoc="x"><span class="techinside">property predicate</span></a> procedure</p></li><li><p>a <a href="structprops.html#%28tech._property._accessor%29" class="techoutside" data-pltdoc="x"><span class="techinside">property accessor</span></a> procedure</p></li></ul><p>Any struct that implements this property will also implement
the properties and <a href="struct-generics.html#%28tech._generic._interface%29" class="techoutside" data-pltdoc="x"><span class="techinside">generic interfaces</span></a> given in the
<span class="RktPn">#:property</span> and <span class="RktPn">#:methods</span> declarations.
The property <span class="RktVar">val-expr</span>s and <span class="RktSym">method-def</span>s are
evaluated eagerly when the property is created, not when
it is attached to a structure type.</p><p><div class="SIntrapara"><blockquote class="SVInsetFlow"><table cellspacing="0" cellpadding="0" class="boxed RBoxed"><tr><td><blockquote class="SubFlow"><div class="RBackgroundLabel SIEHidden"><div class="RBackgroundLabelInner"><p>syntax</p></div></div><table cellspacing="0" cellpadding="0" class="RktBlk RForeground"><tr><td><span class="RktPn">(</span><a name="(form._((lib._racket/generic..rkt)._make-generic-struct-type-property))"></a><span title="Provided from: racket/generic | Package: base"><span class="RktSym"><a href="struct-generics.html#%28form._%28%28lib._racket%2Fgeneric..rkt%29._make-generic-struct-type-property%29%29" class="RktStxDef RktStxLink" data-pltdoc="x">make-generic-struct-type-property</a></span></span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktVar">gen:name-id</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktVar">method-def</span></td></tr><tr><td><span class="hspace">&nbsp;&nbsp;&nbsp;</span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr></table></blockquote></div><div class="SIntrapara">Creates a new structure type property and returns the
<a href="structprops.html#%28tech._structure._type._property._descriptor%29" class="techoutside" data-pltdoc="x"><span class="techinside">structure type property descriptor</span></a>.</div></p><p>Any struct that implements this property will also implement
the <a href="struct-generics.html#%28tech._generic._interface%29" class="techoutside" data-pltdoc="x"><span class="techinside">generic interface</span></a> given by <span class="RktVar">gen:name-id</span>
with the given <span class="RktVar">method-def</span>s. The <span class="RktVar">method-def</span>s
are evaluated eagerly when the property is created, not when
it is attached to a structure type.</p><div class="navsetbottom"><span class="navleft"><form class="searchform"><input class="searchbox" id="searchbox" type="text" tabindex="1" placeholder="...search manuals..." title="Enter a search string to search the manuals" onkeypress="return DoSearchKey(event, this, &quot;8.6&quot;, &quot;../&quot;);"/></form>&nbsp;&nbsp;<a href="https://docs.racket-lang.org/index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot(&quot;8.6&quot;);">top</a><span class="tocsettoggle">&nbsp;&nbsp;<a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright">&nbsp;&nbsp;<a href="structprops.html" title="backward to &quot;5.3 Structure Type Properties&quot;" data-pltdoc="x">&larr; prev</a>&nbsp;&nbsp;<a href="structures.html" title="up to &quot;5 Structures&quot;" data-pltdoc="x">up</a>&nbsp;&nbsp;<a href="struct-copy.html" title="forward to &quot;5.5 Copying and Updating Structures&quot;" data-pltdoc="x">next &rarr;</a></span>&nbsp;</div></div></div><div id="contextindicator">&nbsp;</div></body></html>