📄 faq.html
字号:
<p>Another symptom is that <tt>(require 'srfi-18)</tt> will silently fail.</p><p>This typically happens because the Chicken libraries have been installed in a non-standard location, such as your home directory. The workaround is to explicitly tell the dynamic linker where to look for your libraries:</p><pre>export DYLD_LIBRARY_PATH=~/scheme/chicken/lib:$DYLD_LIBRARY_PATH ;; Macexport LD_LIBRARY_PATH=~/scheme/chicken/lib:$LD_LIBRARY_PATH ;; Linux</pre><a name="how-can-i-increase-the-size-of-the-trace-shown-when-runtime-errors-are-detected"></a><h3>How can I increase the size of the trace shown when runtime errors are detected?</h3><p>When a runtime error is detected, Chicken will print the last entries from the trace of functions called (unless your executable was compiled with the <tt>-no-trace</tt> option. By default, only 16 entries will be shown. To increase this number pass the <tt>-:aN</tt> parameter to your executable.</p><a name="optimizations"></a><h2>Optimizations</h2><a name="how-can-i-obtain-smaller-executables"></a><h3>How can I obtain smaller executables?</h3><p>If you don't need <tt>eval</tt> or the stuff in the <tt>extras</tt> library unit, you can just use the <tt>library</tt> unit:</p><PRE> (declare (uses library)) (display <B><FONT COLOR="#BC8F8F">"Hello, world!\n"</FONT></B>)</PRE><p>(Don't forget to compile with the <tt>-explicit-use</tt> option) Compiled with Visual C++ this generates an executable of around 240 kilobytes. It is theoretically possible to compile something without the library, but a program would have to implement quite a lot of support code on its own.</p><a name="how-can-i-obtain-faster-executables"></a><h3>How can I obtain faster executables?</h3><p>There are a number of declaration specifiers that should be used to speed up compiled files: declaring <tt>(standard-bindings)</tt> is mandatory, since this enables most optimizations. Even if some standard procedures should be redefined, you can list untouched bindings in the declaration. Declaring <tt>(extended-bindings)</tt> lets the compiler choose faster versions of certain internal library functions. This might give another speedup. You can also use the the <tt>usual-integrations</tt> declaration, which is identical to declaring <tt>standard-bindings</tt> and <tt>extended-bindings</tt> (note that <tt>usual-integrations</tt> is set by default). Declaring <tt>(block)</tt> tells the compiler that global procedures are not changed outside the current compilation unit, this gives the compiler some more opportunities for optimization. If no floating point arithmetic is required, then declaring <tt>(number-type fixnum)</tt> can give a big performance improvement, because the compiler can now inline most arithmetic operations. Declaring <tt>(unsafe)</tt> will switch off most safety checks. If threads are not used, you can declare <tt>(disable-interrupts)</tt>. You should always use maximum optimizations settings for your C compiler. Good GCC compiler options on Pentium (and compatible) hardware are: <tt>-Os -fomit-frame-pointer -fno-strict-aliasing</tt> Some programs are very sensitive to the setting of the nursery (the first heap-generation). You should experiment with different nursery settings (either by compiling with the <tt>-nursery</tt> option or by using the <tt>-:s...</tt> runtime option).</p><a name="which-non-standard-procedures-are-treated-specially-when-the-extended-bindings-or-usual-integrations-declaration-or-compiler-option-is-used"></a><h3>Which non-standard procedures are treated specially when the <tt>extended-bindings</tt> or <tt>usual-integrations</tt> declaration or compiler option is used?</h3><p>The following standard bindings are handled specially, depending on optimization options and compiler settings:</p><pre><tt>+</tt> <tt>*</tt> <tt>-</tt> <tt>/</tt> <tt>quotient</tt> <tt>eq?</tt> <tt>eqv?</tt> <tt>equal?</tt> <tt>apply</tt> <tt>c...r</tt> <tt>values</tt> <tt>call-with-values</tt><tt>list-ref</tt> <tt>null?</tt> <tt>length</tt> <tt>not</tt> <tt>char?</tt> <tt>string?</tt> <tt>symbol?</tt> <tt>vector?</tt> <tt>pair?</tt> <tt>procedure?</tt><tt>boolean?</tt> <tt>number?</tt> <tt>complex?</tt> <tt>rational?</tt> <tt>real?</tt> <tt>exact?</tt> <tt>inexact?</tt> <tt>list?</tt> <tt>eof-object?</tt><tt>string-ref</tt> <tt>string-set!</tt> <tt>vector-ref</tt> <tt>vector-set!</tt> <tt>char=?</tt> <tt>char<?</tt> <tt>char>?</tt> <tt>char<=?</tt> <tt>char>=?</tt><tt>char-numeric?</tt> <tt>char-alphabetic?</tt> <tt>char-whitespace?</tt> <tt>char-upper-case?</tt><tt>char-lower-case?</tt> <tt>char-upcae</tt> <tt>char-downcase</tt> <tt>list-tail</tt> <tt>assv</tt> <tt>memv</tt> <tt>memq</tt> <tt>assoc</tt><tt>member</tt> <tt>set-car!</tt> <tt>set-cdr!</tt> <tt>abs</tt> <tt>exp</tt> <tt>sin</tt> <tt>cos</tt> <tt>tan</tt> <tt>log</tt> <tt>asin</tt> <tt>acos</tt> <tt>atan</tt> <tt>sqrt</tt><tt>zero?</tt> <tt>positive?</tt> <tt>negative?</tt> <tt>vector-length</tt> <tt>string-length</tt> <tt>char->integer</tt><tt>integer->char</tt> <tt>inexact->exact</tt> <tt>=</tt> <tt>></tt> <tt><</tt> <tt>>=</tt> <tt><=</tt> <tt>for-each</tt> <tt>map</tt> <tt>substring</tt><tt>string-append</tt> <tt>gcd</tt> <tt>lcm</tt> <tt>list</tt> <tt>exact->inexact</tt> <tt>string->number</tt> <tt>number->string</tt><tt>even?</tt> <tt>odd?</tt> <tt>remainder</tt> <tt>floor</tt> <tt>ceiling</tt> <tt>truncate</tt> <tt>round</tt> <tt>cons</tt> <tt>vector</tt> <tt>string</tt><tt>string=?</tt> <tt>string-ci=?</tt> <tt>make-vector</tt> <tt>call-with-current-continuation</tt><tt>write-char</tt> <tt>read-string</tt> </pre><p>The following extended bindings are handled specially: </p><p><tt>bitwise-and</tt> <tt>bitwise-ior</tt> <tt>bitwise-xor</tt> <tt>bitwise-not</tt> <tt>bit-set?</tt> <tt>add1</tt> <tt>sub1</tt> <tt>fx+</tt> <tt>fx-</tt> <tt>fx*</tt> <tt>fx/</tt> <tt>fxmod</tt> <tt>fx=</tt> <tt>fx></tt> <tt>fx>=</tt> <tt>fixnum?</tt> <tt>fxneg</tt> <tt>fxmax</tt> <tt>fxmin</tt> <tt>fxand</tt> <tt>fxior</tt> <tt>fxxor</tt> <tt>fxnot</tt> <tt>fxshl</tt> <tt>fxshr</tt> <tt>flonum?</tt> <tt>fp+</tt> <tt>fp-</tt> <tt>fp*</tt> <tt>fp/</tt> <tt>atom?</tt> <tt>fp=</tt> <tt>fp></tt> <tt>fp>=</tt> <tt>fpneg</tt> <tt>fpmax</tt> <tt>fpmin</tt> <tt>arithmetic-shift</tt> <tt>signum</tt> <tt>flush-output</tt> <tt>thread-specific</tt> <tt>thread-specific-set!</tt> <tt>not-pair?</tt> <tt>null-list?</tt> <tt>print</tt> <tt>print*</tt> <tt>u8vector->blob/shared</tt> <tt>s8vector->blob/shared</tt> <tt>u16vector->blob/shared</tt> <tt>s16vector->blob/shared</tt> <tt>u32vector->blob/shared</tt> <tt>s32vector->blob/shared</tt> <tt>f32vector->blob/shared</tt> <tt>f64vector->blob/shared</tt> <tt>block-ref</tt> <tt>blob-size</tt> <tt>u8vector-length</tt> <tt>s8vector-length</tt> <tt>u16vector-length</tt> <tt>s16vector-length</tt> <tt>u32vector-length</tt> <tt>s32vector-length</tt> <tt>f32vector-length</tt> <tt>f64vector-length</tt> <tt>u8vector-ref</tt> <tt>s8vector-ref</tt> <tt>u16vector-ref</tt> <tt>s16vector-ref</tt> <tt>u32vector-ref</tt> <tt>s32vector-ref</tt> <tt>f32vector-ref</tt> <tt>f64vector-ref</tt> <tt>u8vector-set!</tt> <tt>s8vector-set!</tt> <tt>u16vector-set!</tt> <tt>s16vector-set!</tt> <tt>u32vector-set!</tt> <tt>s32vector-set!</tt> <tt>hash-table-ref</tt> <tt>block-set!</tt> <tt>number-of-slots</tt> <tt>first</tt> <tt>second</tt> <tt>third</tt> <tt>fourth</tt> <tt>null-pointer?</tt> <tt>pointer->object</tt> <tt>make-record-instance</tt> <tt>locative-ref</tt> <tt>locative-set!</tt> <tt>locative?</tt> <tt>locative->object</tt> <tt>identity</tt> <tt>cpu-time</tt> <tt>error</tt> <tt>call/cc</tt> <tt>any?</tt> <tt>substring=?</tt> <tt>substring-ci=?</tt> <tt>substring-index</tt> <tt>substring-index-ci</tt></p><a name="can-i-load-compiled-code-at-runtime"></a><h3>Can I load compiled code at runtime?</h3><p>Yes. You can load compiled at code at runtime with <tt>load</tt> just as well as you can load Scheme source code. Compiled code will, of course, run faster.</p><p>To do this, pass to <tt>load</tt> a path for a shared object. Use a form such as <tt>(load "foo.so")</tt> and run <tt>csc -shared foo.scm</tt> to produce <tt>foo.so</tt> from <tt>foo.scm</tt> (at which point <tt>foo.scm</tt> will no longer be required).</p><a name="garbage-collection"></a><h2>Garbage collection</h2><a name="why-does-a-loop-that-doesn-t-cons-still-trigger-garbage-collections"></a><h3>Why does a loop that doesn't <tt>cons</tt> still trigger garbage collections?</h3><p>Under CHICKENs implementation policy, tail recursion is achieved simply by avoiding to return from a function call. Since the programs are CPS converted, a continuous sequence of nested procedure calls is performed. At some stage the stack-space has to run out and the current procedure and its parameters (including the current continuation) are stored somewhere in the runtime system. Now a minor garbage collection occurs and rescues all live data from the stack (the first heap generation) and moves it into the the second heap generation. Then the stack is cleared (using a <tt>longjmp</tt>) and execution can continue from the saved state. With this method arbitrary recursion (in tail- or non-tail position) can happen, provided the application doesn't run out of heap-space. (The difference between a tail- and a non-tail call is that the tail-call has no live data after it invokes its continuation - and so the amount of heap-space needed stays constant)</p><a name="why-do-finalizers-not-seem-to-work-in-simple-cases-in-the-interpeter"></a><h3>Why do finalizers not seem to work in simple cases in the interpeter?</h3><p>Consider the following interaction in CSI:</p><pre>#;1> (define x '(1 2 3))#;2> (define (yammer x) (print x " is dead"))#;3> (set-finalizer! x yammer)(1 2 3)#;4> (gc #t)157812#;5> (define x #f)#;6> (gc #t)157812#;7></pre><p>While you might expect objects to be reclaimed and "<em>(1 2 3) is dead</em>" printed, it won't happen: the literal list gets held in the interpreter history, because it is the result value of the set-finalizer! call. Running this in a normal program will work fine.</p><p>When testing finalizers from the interpreter, you might want to define a trivial macro such as</p><pre>(define-macro (v x) `(begin (print ,x) (void)))</pre><p>and wrap calls to <tt>set-finalizer!</tt> in it.</p><a name="interpreter"></a><h2>Interpreter</h2><a name="does-csi-support-history-and-autocompletion"></a><h3>Does CSI support history and autocompletion?</h3><p>CSI doesn't support it natively but it can be activated with the <a href="http://www.call-with-current-continuation.org/eggs/readline.html" class="external">http://www.call-with-current-continuation.org/eggs/readline.html</a> egg. After installing the egg, add the following to your <tt>~/.csirc</tt> or equivalent file:</p><PRE>(require-extension readline)(current-input-port (make-gnu-readline-port))(gnu-history-install-file-manager (string-append (<B><FONT COLOR="#A020F0">or</FONT></B> (getenv <B><FONT COLOR="#BC8F8F">"HOME"</FONT></B>) <B><FONT COLOR="#BC8F8F">"."</FONT></B>) <B><FONT COLOR="#BC8F8F">"/.csi.history"</FONT></B>))</PRE><p>Users of *nix-like systems (including Cygwin), may also want to check out <a href="http://utopia.knoware.nl/~hlub/rlwrap/" class="external">rlwrap</a>. This program lets you "wrap" another process (e.g. <tt>rlwrap csi</tt>) with the readline library, giving you history, autocompletion, and the ability to set the keystroke set. Vi fans can get vi keystrokes by adding "set editing-mode vi" to their <tt>.inputrc</tt> file.</p><a name="does-code-loaded-with-load-run-compiled-or-interpreted"></a><h3>Does code loaded with <tt>load</tt> run compiled or interpreted?</h3><p>If you compile a file with a call to <tt>load</tt>, the code will be loaded at runtime and, if the file loaded is a Scheme source code file (instead of a shared object), it will be interpreted (even if the caller program is compiled).</p><a name="extensions"></a><h2>Extensions</h2><a name="how-can-i-install-chicken-eggs-to-a-non-default-location"></a><h3>How can I install Chicken eggs to a non-default location?</h3><p>You can just set the <tt>CHICKEN_REPOSITORY</tt> environment variable. It should contain the path where you want eggs to be installed:</p><pre>$ export CHICKEN_REPOSITORY=~/chicken/$ chicken-setup extensionname</pre><p>In order to make programs (including csi) see these eggs, you should set this variable when you run them. Alternatively, you can call the <tt>repository-path</tt> Scheme procedure before loading the eggs, as in:</p><PRE>(repository-path <B><FONT COLOR="#BC8F8F">"/home/azul/chicken"</FONT></B>)(use format-modular)</PRE><p>Note, however, that using <tt>repository-path</tt> as above hard-codes the location of your eggs in your source files. While this might not be an issue in your case, it might be safe to keep this configuration outside of the source code (that is, specifying it as an environment variable) to make it easier to maintain.</p><a name="can-i-install-chicken-eggs-as-a-non-root-user"></a><h3>Can I install chicken eggs as a non-root user?</h3><p>Yes, just <a href="http://galinha.ucpel.tche.br/FAQ#Extensions#How can I install Chicken eggs to a non-default location?" class="external">install them in a directory you can write</a>.</p><hr/><p>Previous: <a href="bugs-and-limitations.html" class="internal">Bugs and limitations</a></p><p>Next: <a href="acknowledgements.html" class="internal">Acknowledgements</a></p></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -