This is the list of Frequently Asked Questions about Chicken Scheme. If you have a question not answered here, feel free to post to the chicken-users mailing list; if you consider your question general enough, feel free to add it to this list.

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 existence 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 we know, CHICKEN is the first implementation of Scheme that uses Henry Baker's Cheney on the M.T.A concept.

> Well, it's pretty boring, really: when I started the project and needed some > name, the first thing that met my eyes was the "chicken" (actually a disguised penguin) > from the Wallace + Gromit movie... > And then there is of course the ever occurring chicken-and-egg problem > with bootstrapped compilers.

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.

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 whether a symbol is to be treated as a constant-name (defined via define-constant) or a literal symbol.

Native threads are not supported for two reasons. One, the runtime system is not reentrant. Two, concurrency implemented properly would require mandatory locking of every object that could be potentially shared between two threads. The garbage-collection algorithm would then become much more complex and inefficient, since the location of every object has to be accessed via a thread synchronization protocol. Such a design would make native threads in Chicken essentially equivalent to Unix processes and shared memory.

By default all string and character functions operate bytewise, so that characters with an integer value greater than 255 don't make much sense and multibyte UTF-8 characters are seen and manipulated as separate bytes, analogous to what a C program would see.

You can enable UTF-8 support by placing the following two lines at the beginning of your source file (or in your ~/.csirc for interactive sessions) before any other code, including other use directives:

(use iset syntax-case utf8)(import utf8)

This will replace all builtin string operators with UTF-8-aware versions, that will treat strings as sequences of multibyte UTF-8 characters, thus enabling you to represent and manipulate Unicode characters while remaining compatible with most C libraries and system interfaces.

Most eggs should work correctly in utf8 mode, including the regex extension, but you still have the option of working around incompatibilities of specific eggs by loading them before the (import utf8) directive. Keep in mind that some operations, such as string-length, are much more expensive in utf8 (multibyte) mode, and should be used with care. See the utf8 egg documentation for details.

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.

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 -windowscsc 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.

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:

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):

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.

There are two reasons why code involving callbacks can crash out of no apparent reason:

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.

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.

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):

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.

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.

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 using a different name or undefining the macro, like this:

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.

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:

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:

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 -no-trace option. By default, only 16 entries will be shown. To increase this number pass the -:aN parameter to your executable.

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 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.

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).

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 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)

While you might expect objects to be reclaimed and "(1 2 3) is dead" 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.

When testing finalizers from the interpreter, you might want to define a trivial macro such as

Users of *nix-like systems (including Cygwin), may also want to check out rlwrap. This program lets you "wrap" another process (e.g. rlwrap csi) 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 .inputrc file.

If you compile a file with a call to load, 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).

You can just set the CHICKEN_REPOSITORY environment variable. It should contain the path where you want eggs to be installed:

$ export CHICKEN_REPOSITORY=~/chicken/
$ chicken-setup extensionname

In order to make programs (including csi) see these eggs, you should set this variable when you run them. Alternatively, you can call the repository-path Scheme procedure before loading the eggs, as in:

(repository-path "/home/azul/chicken")(use format-modular)

Note, however, that using repository-path 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.