⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 non-standard-macros-and-special-forms.html

📁 Scheme跨平台编译器
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<html><head><title>CHICKEN User's Manual - Non-standard macros and special forms</title></head><body><a name="non-standard-macros-and-special-forms"></a><h1>Non-standard macros and special forms</h1><a name="making-extra-libraries-and-extensions-available"></a><h2>Making extra libraries and extensions available</h2><a name="require-extension"></a><h3>require-extension</h3><pre>[syntax] (require-extension ID ...)[syntax] (use ID ...)</pre><p>This form does all the necessary steps to make the libraries or extensions given in <tt>ID ...</tt> available. It loads syntactic extensions, if needed and generates code for loading/linking with core library modules or separately installed extensions. <tt>use</tt> is just a shorter alias for <tt>require-extension</tt>. This implementation of <tt>require-extension</tt> is compliant with <a href="http://srfi.schemers.org/srfi-55/srfi-55.html" class="external">SRFI-55</a> (see the <a href="http://srfi.schemers.org/srfi-55/srfi-55.html" class="external">SRFI-55</a> document for more information).</p><p>During interpretation/evaluation <tt>require-extension</tt> performs one of the following:</p><ul><li>If <tt>ID</tt> names a built-in feature <tt>chicken srfi-0 srfi-2 srfi-6 srfi-8 srfi-9 srfi-10 srfi-17 srfi-23 srfi-30 srfi-39 srfi-55</tt>, then nothing is done.</li><li>If <tt>ID</tt> names one of the syntactic extensions <tt>chicken-more-macros chicken-ffi-macros</tt>, then this extension will be loaded.</li><li>If <tt>ID</tt> names one of the core library units shipped with CHICKEN, then a <tt>(load-library 'ID)</tt> will be performed.</li><li>If <tt>ID</tt> names an installed extension with the <tt>syntax</tt> or <tt>require-at-runtime</tt> attribute, then the equivalent of <tt>(require-for-syntax 'ID)</tt> is performed, probably followed by <tt>(require ...)</tt> for any run-time requirements.</li><li>Otherwise, <tt>(require-extension ID)</tt> is equivalent to <tt>(require 'ID)</tt>.</li></ul><p>During compilation, one of the following happens instead:</p><ul><li>If <tt>ID</tt> names a built-in feature <tt>chicken srfi-0 srfi-2 srfi-6 srfi-8 srfi-9 srfi-10 srfi-17 srfi-23 srfi-30 srfi-39 srfi-55</tt>, then nothing is done.</li><li>If <tt>ID</tt> names one of the syntactic extensions <tt>chicken-more-macros chicken-ffi-macros</tt>, then this extension will be loaded at compile-time, making the syntactic extensions available in compiled code.</li><li>If <tt>ID</tt> names one of the core library units shipped with CHICKEN, or if the option <tt>-uses ID</tt> has been passed to the compiler, then a <tt>(declare (uses ID))</tt> is generated.</li><li>If <tt>ID</tt> names an installed extension with the <tt>syntax</tt> or <tt>require-at-runtime</tt> attribute, then the equivalent of <tt>(require-for-syntax 'ID)</tt> is performed, and code is emitted to <tt>(require ...)</tt> any needed run-time requirements.</li><li>Otherwise <tt>(require-extension ID)</tt> is equivalent to <tt>(require 'ID)</tt>.</li></ul><p>To make long matters short - just use <tt>require-extension</tt> and it will normally figure everything out for dynamically loadable extensions and core library units.</p><p><tt>ID</tt> should be a pure extension name and should not contain any path prefixes (for example <tt>dir/lib...</tt>) is illegal).</p><p><tt>ID</tt> may also be a list that designates an extension-specifier. Currently the following extension specifiers are defined:</p><ul><li><tt>(srfi NUMBER ...)</tt> is required for SRFI-55 compatibility and is fully implemented</li><li><tt>(version ID NUMBER)</tt> is equivalent to <tt>ID</tt>, but checks at compile-time whether the extension named <tt>ID</tt> is installed and whether its version is equal or higher than <tt>NUMBER</tt>. <tt>NUMBER</tt> may be a string or a number, the comparison is done lexicographically (using <tt>string&gt;=?</tt>).</li></ul><p>See also: <tt>set-extension-specifier!</tt></p><p>When syntax extensions are loaded that redefine the global toplevel macro-expander (for example the <a href="http://www.call-with-current-continuation.org/eggs/syntax-case.html" class="external">syntax-case</a> extension), then all remaining expression <em>in the same toplevel form</em> are still expanded with the old toplevel macro-expander.</p><a name="define-extension"></a><h3>define-extension</h3><pre>[syntax] (define-extension NAME CLAUSE ...)</pre><p>This macro simplifies the task of writing extensions that can be linked both statically and dynamically. If encountered in interpreted code or code that is compiled into a shared object (specifically if compiled with the feature <tt>chicken-compile-shared</tt>, done automatically by <tt>csc</tt> when compiling with the <tt>-shared</tt> or <tt>-dynamic</tt> option) then the code given by clauses of the form</p><PRE>(dynamic EXPRESSION ...)</PRE><p>are inserted into the output as a <tt>begin</tt> form.</p><p>If compiled statically (specifically if the feature <tt>chicken-compile-shared</tt> has not been given), then this form expands into the following:</p><PRE>(declare (unit NAME))(provide 'NAME)</PRE><p>and all clauses of the form</p><PRE>(static EXPRESSION ...)</PRE><p>all additionally inserted into the expansion.</p><p>As a convenience, the clause</p><PRE>(export IDENTIFIER ...)</PRE><p>is also allowed and is identical to <tt>(declare (export IDENTIFIER ...))</tt> (unless the <tt>define-extension</tt> form occurs in interpreted code, in with it is simply ignored).</p><p>Note that the compiler option <tt>-extension NAME</tt> is equivalent to prefixing the compiled file with </p><PRE>(define-extension NAME)</PRE><a name="binding-forms-for-optional-arguments"></a><h2>Binding forms for optional arguments</h2><a name="optional"></a><h3>optional</h3><pre>[syntax] (optional ARGS DEFAULT)</pre><p>Use this form for procedures that take a single optional argument. If <tt>ARGS</tt> is the empty list <tt>DEFAULT</tt> is evaluated and returned, otherwise the first element of the list <tt>ARGS</tt>. It is an error if <tt>ARGS</tt> contains more than one value.</p><PRE>(<B><FONT COLOR="#A020F0">define</FONT></B> (<B><FONT COLOR="#0000FF">incr</FONT></B> x . i) (+ x (optional i 1)))(incr 10)                                   =<B><FONT COLOR="#A020F0">=&gt;</FONT></B> 11(incr 12 5)                                 =<B><FONT COLOR="#A020F0">=&gt;</FONT></B> 17</PRE><a name="case-lambda"></a><h3>case-lambda</h3><pre>[syntax] (case-lambda (LAMBDA-LIST1 EXP1 ...) ...)</pre><p>Expands into a lambda that invokes the body following the first matching lambda-list.</p><PRE>(<B><FONT COLOR="#A020F0">define</FONT></B> <B><FONT COLOR="#0000FF">plus</FONT></B>  (case-lambda     (() 0)    ((x) x)    ((x y) (+ x y))    ((x y z) (+ (+ x y) z))    (args (apply + args))))(plus)                      =<B><FONT COLOR="#A020F0">=&gt;</FONT></B> 0(plus 1)                    =<B><FONT COLOR="#A020F0">=&gt;</FONT></B> 1(plus 1 2 3)                =<B><FONT COLOR="#A020F0">=&gt;</FONT></B> 6</PRE><p>For more information see the documentation for <a href="http://srfi.schemers.org/srfi-16/srfi-16.html" class="external">SRFI-16</a></p><a name="let-optionals"></a><h3>let-optionals</h3><pre>[syntax]  (let-optionals ARGS ((VAR1 DEFAULT1) ...) BODY ...)</pre><p>Binding constructs for optional procedure arguments. <tt>ARGS</tt> should be a rest-parameter taken from a lambda-list. <tt>let-optionals</tt> binds <tt>VAR1 ...</tt> to available arguments in parallel, or to <tt>DEFAULT1 ...</tt> if not enough arguments were provided. <tt>let-optionals*</tt> binds <tt>VAR1 ...</tt> sequentially, so every variable sees the previous ones. it is an error if any excess arguments are provided.</p><PRE>(let-optionals '(one two) ((a 1) (b 2) (c 3))  (list a b c) )                               =<B><FONT COLOR="#A020F0">=&gt;</FONT></B> (one two 3)</PRE><a name="let-optionals"></a><h3>let-optionals*</h3><pre>[syntax]  (let-optionals* ARGS ((VAR1 DEFAULT1) ... [RESTVAR]) BODY ...)</pre><p>Binding constructs for optional procedure arguments. <tt>ARGS</tt> should be a rest-parameter taken from a lambda-list. <tt>let-optionals</tt> binds <tt>VAR1 ...</tt> to available arguments in parallel, or to <tt>DEFAULT1 ...</tt> if not enough arguments were provided. <tt>let-optionals*</tt> binds <tt>VAR1 ...</tt> sequentially, so every variable sees the previous ones. If a single variable <tt>RESTVAR</tt> is given, then it is bound to any remaining arguments, otherwise it is an error if any excess arguments are provided.</p><PRE>(let-optionals* '(one two) ((a 1) (b 2) (c a))  (list a b c) )                               =<B><FONT COLOR="#A020F0">=&gt;</FONT></B> (one two one)</PRE><a name="other-binding-forms"></a><h2>Other binding forms</h2><a name="and-let"></a><h3>and-let*</h3><pre>[syntax] (and-let* (BINDING ...) EXP1 EXP2 ...)</pre><p>SRFI-2. Bind sequentially and execute body. <tt>BINDING</tt> can be a list of a variable and an expression, a list with a single expression, or a single variable. If the value of an expression bound to a variable is <tt>#f</tt>, the <tt>and-let*</tt> form evaluates to <tt>#f</tt> (and the subsequent bindings and the body are not executed).  Otherwise the next binding is performed. If all bindings/expressions evaluate to a true result, the body is executed normally and the result of the last expression is the result of the <tt>and-let*</tt> form. See also the documentation for <a href="http://srfi.schemers.org/srfi-2/srfi-2.html" class="external">SRFI-2</a>.</p><a name="rec"></a><h3>rec</h3><pre>[syntax] (rec NAME EXPRESSION)[syntax] (rec (NAME VARIABLE ...) BODY ...)</pre><p>Allows simple definition of recursive definitions. <tt>(rec NAME EXPRESSION)</tt> is equivalent to <tt>(letrec ((NAME EXPRESSION)) NAME)</tt> and <tt>(rec (NAME VARIABLE ...) BODY ...)</tt> is the same as <tt>(letrec ((NAME (lambda (VARIABLE ...) BODY ...))) NAME)</tt>.</p><a name="cut"></a><h3>cut</h3><pre>[syntax] (cut SLOT ...)[syntax] (cute SLOT ...)</pre><p><a href="http://srfi.schemers.org/srfi-26/srfi-26.html" class="external">Syntactic sugar for specializing parameters</a>.</p><a name="define-values"></a><h3>define-values</h3><pre>[syntax] (define-values (NAME ...) EXP)</pre><p>Defines several variables at once, with the result values of expression <tt>EXP</tt>.</p><a name="fluid-let"></a><h3>fluid-let</h3><pre>[syntax] (fluid-let ((VAR1 X1) ...) BODY ...)</pre><p>Binds the variables <tt>VAR1 ...</tt> dynamically to the values <tt>X1 ...</tt>  during execution of <tt>BODY ...</tt>.</p><a name="let-values"></a><h3>let-values</h3><pre>[syntax] (let-values (((NAME ...) EXP) ...) BODY ...)</pre><p>Binds multiple variables to the result values of <tt>EXP ...</tt>. All variables are bound simultaneously.</p><a name="let-values"></a><h3>let*-values</h3><pre>[syntax] (let*-values (((NAME ...) EXP) ...) BODY ...)</pre><p>Binds multiple variables to the result values of <tt>EXP ...</tt>. The variables are bound sequentially.</p><PRE>(let*-values (((a b) (values 2 3))              ((p) (+ a b)) )  p)                               =<B><FONT COLOR="#A020F0">=&gt;</FONT></B> 5</PRE>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -