You are looking at historical revision 1063 of this page. It may differ significantly from its current revision.

FAQ

General

  Since Scheme is a relatively simple language, a large number of implementations exist and
  each has its specific advantages and disadvantages. Some are fast, some provide a rich
  programming environment. Some are free, others are tailored to specific domains, and so on. The reasons
  for the existance of CHICKEN are:
  CHICKEN is portable because it generates C code that runs on a large number of platforms.
  CHICKEN is extendable, since its code generation scheme and runtime system/garbage collector fits
  neatly into a C environment.
  CHICKEN is free and can be freely distributed, including its source code.
  CHICKEN offers better performance than nearly all interpreter based implementations, but still
  provides full Scheme semantics.
  As far as I know, CHICKEN is the first implementation of Scheme that uses Henry Baker's
    ''Cheney on the M.T.A'' concept.
  Send e-mail to {{felix@@call-with-current-continuation.org}}
  with some hints about the problem, like
  version/build of the compiler, platform, system configuration, code that
  causes the bug, etc.
 Accesses to foreign variables are translated directly into C constructs that access the variable,
 so the Scheme name given to that variable does only exist during compile-time.
 The same goes for constant- and inline-definitions: The name is only there to tell the compiler
 that this reference is to be replaced with the actual value.
  Each unit used via {{(declare (uses ...))}} is registered as a feature and
  so a symbol with the unit-name can be tested by {{cond-expand}} during macro-expansion-time.
  Features registered using the {{register-feature!}} procedure are only
  available during run-time of the compiled file. You can use the {{eval-when}} form
  to register features at compile time.
  If you don't need {{eval}} or the stuff in the {{extras}} library unit, 
  you can just use the {{library}} unit:
	(declare (uses library))
	(display "Hello, world!\n")
  (Don't forget to compile with the {{-explicit-use}} option)
  Compiled with Visual C++ this generates an excutable 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.
  Under CHICKENs implementation policy, tail recursion is achieved simply by avoiding to
  return from a function call. Since the programs is 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. Than the stack is cleared (using
  a {{longjmp}}) 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)
  There are a number of declaration specifiers that should be used to speed up
  compiled files: declaring {{(standard-bindings)}} is mandatory, since this enables
  most optimizations. Even if some standard procedures should be redefined, you can
  list untouched bindings in the declaration.
  Declaring {{(extended-bindings)}} lets the compiler choose faster versions of certain
  internal library functions. This might give another speedup. You can also use the
  the {{usual-integrations}} declaration, which is identical to declaring
  {{standard-bindings}} and {{extended-bindings}}
  (note that {{usual-integrations}} is set by default).
  Declaring {{(block)}} 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 {{(number-type fixnum)}}
  can give a big performance improvement, because the compiler can now inline
  most arithmetic operations. 
  Declaring {{(unsafe)}} will switch off most safety checks.
  If threads are not used, you can declare {{(disable-interrupts)}}.
  You should always use maximum optimizations settings for your C compiler.
  Good GCC compiler options on Pentium (and compatible) hardware are:
  {{-Os -fomit-frame-pointer -fno-strict-aliasing}}
  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 {{-nursery}}
  option or by using the {{-:s...}} runtime option).
  This message indicates that your program uses a library-unit, but that the
  object-file or library was not supplied to the linker. If you have the unit
  {{foo}}, which is contained in {{foo.o}} than you have to supply it to the
  linker like this (assuming a GCC environment):
  {{% csc program.scm foo.o -o program}}
  This means you have compiled a library unit as an application. When a unit-declaration (as in {{(declare (unit ...))}})
  is given, then this file has a specially named toplevel entry procedure. Just remove the declaration,
  or compile this file to an object-module and link it to your application code.
  {{case}} expands into a cascaded {{if}} expression, where the first item in each arm
  is treated as a quoted list. So the {{case}} macro can not infer wether
  a symbol is to be treated as a constant-name (defined via {{define-constant}}) or
  a literal symbol.
  The compiler option {{-unsafe}} or the declaration {{(declare (unsafe))}} disable
  certain safety-checks to improve performance, so code that would normally
  trigger an error will work unexpectedly or even crash the running application.
  It is advisable to develop and debug a program in safe mode (without unsafe
  declarations) and use this feature only if the application works properly.
 The following extended bindings are handled specially: 

bitwise-and bitwise-ior bitwise-xor bitwise-not add1 sub1

{{fx+}}

fx- fx* fx/ fxmod

 {{fx=}} {{fx>}} {{fx>=}} {{fixnum?}} {{fxneg}} {{fxmax}} {{fxmin}}

fxand fxior fxxor fxnot fxshl fxshr fp+ fp- fp* fp/ atom?

 {{fp=}} {{fp>}} {{fp>=}} {{fpneg}} {{fpmax}} {{fpmin}}
 {{arithmetic-shift}} {{signum}} {{flush-output}} {{thread-specific}} {{thread-specific-set!}}
 {{not-pair?}} {{null-list?}} {{print}} {{print*}} {{u8vector->bytevector}}
 {{s8vector->bytevector}} {{u16vector->bytevector}} {{s16vector->bytevector}}
 {{u32vector->bytevector}}
 {{s32vector->bytevector}} {{f32vector->bytevector}} {{f64vector->bytevector}} {{block-ref}}
 {{byte-vector-length}}
 {{u8vector-length}}
 {{s8vector-length}}
 {{u16vector-length}}
 {{s16vector-length}}
 {{u32vector-length}}
 {{s32vector-length}}
 {{f32vector-length}}
 {{f64vector-length}}
 {{u8vector-ref}}
 {{s8vector-ref}}
 {{u16vector-ref}}
 {{s16vector-ref}}
 {{u32vector-ref}}
 {{s32vector-ref}}
 {{f32vector-ref}}
 {{f64vector-ref}}
 {{u8vector-set!}}
 {{s8vector-set!}}
 {{u16vector-set!}}
 {{s16vector-set!}}
 {{u32vector-set!}}
 {{s32vector-set!}}
 {{hash-table-ref}}
  {{block-set!}} {{number-of-slots}}
   {{first}} {{second}} {{third}} {{fourth}} {{null-pointer?}} {{pointer->object}}
   {{make-record-instance}}
  {{locative-ref}} {{locative-set!}} {{locative?}} {{locative->object}} {{identity}}
   {{cpu-time}} {{error}} {{call/cc}}
 The following piece of code does not work as expected:
(eval-when (compile)
  (define-reader-ctor 'integer->char integer->char) )
(print #,(integer->char 33))
 The problem is that the compiler reads the complete source-file before doing any processing on it,
 so the sharp-comma form is encountered before the reader-ctor is defined. A possible solution is to include
 the file containing the sharp-comma form, like this:
(eval-when (compile)
  (define-reader-ctor 'integer->char integer->char) )

(include "other-file")
;;; other-file.scm:
(print #,(integer->char 33))
 Even when the {{match}} unit is not used, the macros from that package are visible in the compiler.
 The reason for this is that macros can not be accessed from library units (only when explicitly evaluated in running
 code). To speed up macro-expansion time, the compiler and the interpreter both already provide the compiled 
 {{match-...}} macro definitions. Macros shadowed lexically are no problem, but global definitions
 of variables named identically to (global) macros are useless - the macro definition shadows the global
 variable.
 This problem can be solved in one of three ways:
 
 - Use a different name
 
 - Undefine the macro, like this:
(eval-when (compile eval) (undefine-macro! 'match))
 
 To enable the {{read}} procedure to read symbols and identifiers case sensitive, you can set the
 parameter {{case-sensitivity}} to {{#t}}.
 There are two reasons why code involving callbacks can crash out of know apparent reason. The first is that it is
 important to use {{foreign-safe-lambda/foreign-safe-lambda*}} for the C code that is
 to call back into Scheme. If this is not done than sooner or later the available stack space will be exhausted.
 The second reason is that if the C code uses a large amount of stack storage, or if Scheme-to-C-to-Scheme calls are
 nested deeply, then the available nursery space on the stack will run low. To avoid this it might be advisable
 to run the compiled code with a larger nursery setting, i.e. run the code with {{-:s...}} and a larger
 value than the default (for example {{-:s300k}}), or use the {{-nursery}} compiler option.
 Note that this can decrease runtime performance on some platforms.
 Use {{eval-when}}, like this:
 <enscript highlight=scheme>
 (eval-when (compile)
   (match-error-control #:unspecified) )
 </enscript>
 The short answer:
 <enscript highlight=scheme>
 % chicken-setup numbers
 % csi -q
 #;1> (use numbers)
 </enscript>
 The long answer:
 There are a number of reasons for this:
 
 - For most applications of Scheme fixnums (exact word-sized integers) and flonums (64-bit floating-point
  numbers) are more than sufficient;
 
 - Interfacing to C is simpler;
 
 - Dispatching of arithmetic operations is more efficient.
 There is an extension based on the GNU Multiprecision Package that implements most of the full
 numeric tower, see http://www.call-with-current-continuation.org/eggs/numbers.html.
 
 Consider the following piece of code:
  
  (define k (call-with-current-continuation (lambda (k) k)))
  (k k)
 When compiled, this will loop endlessly. But when interpreted, {{(k k)}} will return
 to the read-eval-print loop! This happens because the continuation captured will eventually read the
 next toplevel expression from the standard-input (or an input-file if loading from a file). At the moment
 {{k}} was defined, the next expression was {{(k k)}}. But when {{k}}
 is invoked, the next expression will be whatever follows after {{(k k)}}.
 In other words, invoking a captured continuation will not rewind the file-position of the input source.
 A solution is to wrap the whole code into a {{(begin ...)}} expression, so all toplevel
 expressions will be loaded together.
 Specializing a method on {{<object>}} doesn't work on primitive data objects like
 numbers, strings, etc. so for example
  (define-method (foo (x <my-class>)) ...)
  (define-method (foo (x <object>)) ...)
  (foo 123)
 will signal an error, because to applicable method can be found. To specialize a method for primitive
 objects, use {{<top>}}:
  (define-method (foo (x <top>)) ...)
 Currently native threads are not supported. The runtime system is not reentrant, and the garbage-collection
 algorithm would be made much more complicated, since the location of every object (whether it is allocated
 on the stack or on the heap or completely outside the GC-able data space) has to be checked - this would
 be rather complex and inefficient in a situation where multiple threads are involved.

Platform specific

  Use {{csc}} in combination with the {{-dll}} option:
  {{C:\> csc foo.scm -dll}}
  Invoke {{csc}} with the {{-windows}} option. Or pass the {{-DC_WINDOWS_GUI}}
  option to the C compiler and link with the GUI version of the runtime system (that's {{libchicken-gui[-static].lib}}.
  The GUI runtime displays error messages in a message box and does some rudimentary command-line
  parsing.
 It seems that the Microsoft C compiler can only handle files up to a certain size, and it doesn't utilize virtual memory as
 well as the GNU C compiler, for example. Try closing running applications. If that fails, try to break up the Scheme code
 into several library units.
 Invoke {{csi}} with the {{-:c}} runtime option. Under Windows the interpreter thinks it
 is not running under control of a terminal and doesn't print the prompt and does not flush the output stream properly.
 Code compiled into a DLL to be loaded dynamically must be linked with the same runtime system as the loading
 application. That means that all dynamically loaded entities (including extensions built and installed with
 {{chicken-setup}}) must be compiled with the {{-windows}} {{csc}} option.
 The Windows development tools include a C# compiler with the same name. Either invoke {{csc.exe}} with a full
 pathname, or put the directory where you installed CHICKEN in front of the MS development tool path in the {{PATH}}
 environment variable.

Customization

  When you invoke the C compiler for your translated Scheme source program, add the C compiler option
  {{-DC_EMBEDDED}}, or pass {{-embedded}} to the {{csc}}
  driver program, so no entry-point function will be generated ({{main()}}).
  When your are finished with your startup processing, invoke:
   CHICKEN_main(argc, argv, C_toplevel);
 where {{C_toplevel}} is the entry-point into the compiled Scheme code. You
 should add the following  declarations at the head of your code:
  #include "chicken.h"
  extern void C_toplevel(C_word,C_word,C_word) C_noret;
 To add a compiled user pass instead of an interpreted one, create a library unit and recompile
 the main unit of the compiler (in the file {{chicken.scm}}) with an additional {{uses}}
 declaration. Then link all compiler modules and your (compiled) extension to create a new version of
 the compiler, like this (assuming all sources are in the
 current directory):
  % cat userpass.scm
  ;;;; userpass.scm - My very own compiler pass

  (declare (unit userpass))

  ;; Perhaps more user passes/extensions are added:
  (let ([old (user-pass)])
    (user-pass
      (lambda (x)
        (let ([x2 (do-something-with x)])
	  (if old
	      (old x2)
	      x2) ) ) ) )

{{

 % csc -c -x userpass.scm
 % csc chicken.scm -c -o chicken-extended.o -uses userpass
 % gcc chicken-extended.o support.o easyffi.o compiler.o optimizer.o batch-driver.o c-platform.o \
   c-backend.o userpass.o `csc -ldflags -libs` -o chicken-extended

}}

 On platforms that support it (Linux ELF, Solaris, Windows + VC++), compiled code can be loaded via {{-extend}}
 just like source files (see {{load}} in the User's Manual).

Macros

  Macro bodies that are defined and used in a compiled source-file are
  evaluated during compilation and so have no access to definitions in the
  compiled file. Note also that during compile-time macros are only available in
  the same source file in which they are defined. Files included via {{include}}
  are considered part of the containing file.
  Macros are defined during compile time, so when a file has been compiled, the definitions are gone. An exception
  to this rule are macros defined with {{define-macro}}, which are also visible at run-time, i.e.
  in {{eval}}. To use macros defined in other files, use the {{include}} special
  form.