103 lines
102 KiB
HTML
103 lines
102 KiB
HTML
|
<!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 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,"tocview_0");">►</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 </td><td><a href="model.html" class="tocviewlink" data-pltdoc="x">Language Model</a></td></tr><tr><td align="right">2 </td><td><a href="notation.html" class="tocviewlink" data-pltdoc="x">Notation for Documentation</a></td></tr><tr><td align="right">3 </td><td><a href="syntax.html" class="tocviewlink" data-pltdoc="x">Syntactic Forms</a></td></tr><tr><td align="right">4 </td><td><a href="data.html" class="tocviewlink" data-pltdoc="x">Datatypes</a></td></tr><tr><td align="right">5 </td><td><a href="structures.html" class="tocviewselflink" data-pltdoc="x">Structures</a></td></tr><tr><td align="right">6 </td><td><a href="mzlib_class.html" class="tocviewlink" data-pltdoc="x">Classes and Objects</a></td></tr><tr><td align="right">7 </td><td><a href="mzlib_unit.html" class="tocviewlink" data-pltdoc="x">Units</a></td></tr><tr><td align="right">8 </td><td><a href="contracts.html" class="tocviewlink" data-pltdoc="x">Contracts</a></td></tr><tr><td align="right">9 </td><td><a href="match.html" class="tocviewlink" data-pltdoc="x">Pattern Matching</a></td></tr><tr><td align="right">10 </td><td><a href="control.html" class="tocviewlink" data-pltdoc="x">Control Flow</a></td></tr><tr><td align="right">11 </td><td><a href="concurrency.html" class="tocviewlink" data-pltdoc="x">Concurrency and Parallelism</a></td></tr><tr><td align="right">12 </td><td><a href="Macros.html" class="tocviewlink" data-pltdoc="x">Macros</a></td></tr><tr><td align="right">13 </td><td><a href="input-and-output.html" class="tocviewlink" data-pltdoc="x">Input and Output</a></td></tr><tr><td align="right">14 </td><td><a href="security.html" class="tocviewlink" data-pltdoc="x">Reflection and Security</a></td></tr><tr><td align="right">15 </td><td><a href="os.html" class="tocviewlink" data-pltdoc="x">Operating System</a></td></tr><tr><td align="right">16 </td><td><a href="memory.html" class="tocviewlink" data-pltdoc="x">Memory Management</a></td></tr><tr><td align="right">17 </td><td><a href="unsafe.html" class="tocviewlink" data-pltdoc="x">Unsafe Operations</a></td></tr><tr><td align="right">18 </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"> </span><span class="RktVar">id</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">generics-opt</span><span class="hspace"> </span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVar">method-id</span><span class="hspace"> </span><span class="RktPn">. </span><span class="RktVar">kw-formals*</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">generics-opt</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr><tr><td><span class="stt"> </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"> </span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktPn">#:defaults</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktVar">default-pred?</span><span class="hspace"> </span><span class="RktVar">default-impl</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr><tr><td align="right" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktPn">#:fast-defaults</span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktPn">[</span><span class="RktVar">fast-pred?</span><span class="hspace"> </span><span class="RktVar">fast-impl</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr><tr><td align="right" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktPn">#:fallbacks</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVar">fallback-impl</span><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">]</span></td></tr><tr><td align="right" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt"> </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>’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"> </span><span class="RktVar">name</span><span class="hspace"> </span><span class="RktVar">v</span><span class="RktPn">)</span><span class="hspace"> </span>→<span class="hspace"> </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"> </span><span class="RktVar">name</span><span class="hspace"> </span>:<span class="hspace"> </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"> </span><span class="RktVar">v</span><span class="hspace"> </span>:<span class="hspace"> </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">> </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"> </span><span class="RktVal">'</span><span class="RktVal">some-method-name</span><span class="hspace"> </span><span class="RktVal">'</span><span class="RktVal">(</span><span class="RktVal">"arbitrary"</span><span class="hspace"> </span><span class="RktVal">"instance"</span><span class="hspace"> </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"> </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"> </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"> </span><span class="RktPn">(</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr><tr><td><span class="hspace"> </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"> </span><span class="RktVar">local-id</span><span class="hspace"> </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">> </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"> </span><span class="RktSym">printable</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">gen-print</span><span class="hspace"> </span><span class="RktSym">printable</span><span class="hspace"> </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"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">gen-port-print</span><span class="hspace"> </span><span class="RktSym">port</span><span class="hspace"> </span><span class="RktSym">printable</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </span><span class="RktPn">(</span><span class="RktSym">gen-print*</span><span class="hspace"> </span><span class="RktSym">printable</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">port</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktPn">#:width</span><span class="hspace"> </span><span class="RktSym">width</span><span class="hspace"> </span><span class="RktPn">#:height</span><span class="hspace"> </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"> </span><span class="hspace"> </span><span class="RktPn">#:defaults</span><span class="hspace"> </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"> </span><span class="hspace"> </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"> </span><span class="RktSym">super-print</span><span class="hspace"> </span><span class="RktSym">gen-print</span><span class="RktPn">)</span></td></tr><tr><td><span class="hspace"> </span><span class="hspace"> </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"> </span><span class="RktPn">(</span><span class="RktSym">gen-print</span><span class="hspace"> </span><span class="RktSym">s</span><span class="hspace"> </span><span class="RktPn">[</span><span class="RktSym">port</span><span class="hspace"> </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"> </span><span class="RktVar">gen-id</span><span class="hspace"> </span><span class="RktVar">val-expr</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVar">method-id</span><span class="hspace"> </span><span class="RktVar">method-proc-expr</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">maybe-properties</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr><tr><td><span class="stt"> </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"> </span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt"> </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"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktPn">#:properties</span><span class="hspace"> </span><span class="RktVar">props-expr</span></td></tr></table></td></tr><tr><td><span class="stt"> </span></td></tr><tr><td><blockquote class="SubFlow"><table cellspacing="0" cellpadding="0" class="argcontract"><tr><td><span class="hspace"> </span></td><td><span class="RktVar">method-proc-expr</span></td><td><span class="hspace"> </span></td><td>:</td><td><span class="hspace"> </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"> </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">-></span></a></span><span class="RktPn"> .</span><span class="hspace"> </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"> </span></td><td><span class="RktVar">props-expr</span></td><td><span class="hspace"> </span></td><td>:</td><td><span class="hspace"> </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"> </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’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"> </span><span class="RktVar">gen-id</span><span class="hspace"> </span><span class="RktVar">val-expr</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVar">method-id</span><span class="hspace"> </span><span class="RktVar">method-proc-expr</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace"> </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’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"> </span><span class="RktVar">mode</span><span class="hspace"> </span><span class="RktVar">gen-id</span><span class="hspace"> </span><span class="RktVar">val-expr</span></td></tr><tr><td><span class="hspace"> </span><span class="RktPn">[</span><span class="RktVar">method-id</span><span class="hspace"> </span><span class="RktVar">method-proc-expr</span><span class="RktPn">]</span><span class="hspace"> </span><span class="RktMeta">...</span></td></tr><tr><td><span class="hspace"> </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"> </span><span class="RktVar">name-expr</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">maybe-guard-expr</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">maybe-supers-expr</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">maybe-can-impersonate?-expr</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">property-option</span></td></tr><tr><td><span class="hspace"> </span><span class="RktMeta">...</span><span class="RktPn">)</span></td></tr></table></blockquote></td></tr><tr><td><span class="stt"> </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"> </span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt"> </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"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktVar">guard-expr</span></td></tr><tr><td align="right" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </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"> </span></td><td align="center" valign="baseline">=</td><td align="left" valign="baseline"><span class="stt"> </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"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline">|</td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="RktVar">supers-expr</span></td></tr><tr><td align="right" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="center" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </span></td><td align="left" valign="baseline"><span class="stt"> </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"> </span><span class="RktVar">gen:name-id</span></td></tr><tr><td><span class="hspace"> </span><span class="RktVar">method-def</span></td></tr><tr><td><span class="hspace"> </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, "8.6", "../");"/></form> <a href="https://docs.racket-lang.org/index.html" title="up to the documentation top" data-pltdoc="x" onclick="return GotoPLTRoot("8.6");">top</a><span class="tocsettoggle"> <a href="javascript:void(0);" title="show/hide table of contents" onclick="TocsetToggle();">contents</a></span></span><span class="navright"> <a href="structprops.html" title="backward to "5.3 Structure Type Properties"" data-pltdoc="x">← prev</a> <a href="structures.html" title="up to "5 Structures"" data-pltdoc="x">up</a> <a href="struct-copy.html" title="forward to "5.5 Copying and Updating Structures"" data-pltdoc="x">next →</a></span> </div></div></div><div id="contextindicator"> </div></body></html>
|