/trunk/Doc/Manual/Chicken.html
HTML | 597 lines | 471 code | 123 blank | 3 comment | 0 complexity | e86d7317c9f852946d16a3186712d8e1 MD5 | raw file
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2<!-- Hand-written HTML --> 3<html> 4<head> 5<title>SWIG and Chicken</title> 6<link rel="stylesheet" type="text/css" href="style.css"> 7</head> 8 9<body bgcolor="#ffffff"> 10 11<H1><a name="Chicken"></a>20 SWIG and Chicken</H1> 12<!-- INDEX --> 13<div class="sectiontoc"> 14<ul> 15<li><a href="#Chicken_nn2">Preliminaries</a> 16<ul> 17<li><a href="#Chicken_nn3">Running SWIG in C mode</a> 18<li><a href="#Chicken_nn4">Running SWIG in C++ mode</a> 19</ul> 20<li><a href="#Chicken_nn5">Code Generation</a> 21<ul> 22<li><a href="#Chicken_nn6">Naming Conventions</a> 23<li><a href="#Chicken_nn7">Modules</a> 24<li><a href="#Chicken_nn8">Constants and Variables</a> 25<li><a href="#Chicken_nn9">Functions</a> 26<li><a href="#Chicken_nn10">Exceptions</a> 27</ul> 28<li><a href="#Chicken_nn11">TinyCLOS</a> 29<li><a href="#Chicken_nn12">Linkage</a> 30<ul> 31<li><a href="#Chicken_nn13">Static binary or shared library linked at compile time</a> 32<li><a href="#Chicken_nn14">Building chicken extension libraries</a> 33<li><a href="#Chicken_nn15">Linking multiple SWIG modules with TinyCLOS</a> 34</ul> 35<li><a href="#Chicken_nn16">Typemaps</a> 36<li><a href="#Chicken_nn17">Pointers</a> 37<ul> 38<li><a href="#Chicken_collection">Garbage collection</a> 39</ul> 40<li><a href="#Chicken_nn18">Unsupported features and known problems</a> 41<ul> 42<li><a href="#Chicken_nn19">TinyCLOS problems with Chicken version <= 1.92</a> 43</ul> 44</ul> 45</div> 46<!-- INDEX --> 47 48 49 50 <p> 51 This chapter describes SWIG's support of CHICKEN. CHICKEN is a 52 Scheme-to-C compiler supporting most of the language features as 53 defined in the <i>Revised^5 Report on Scheme</i>. Its main 54 attributes are that it 55 </p> 56 57 <ol> 58 <li>generates portable C code</li> 59 <li>includes a customizable interpreter</li> 60 <li>links to C libraries with a simple Foreign Function Interface</li> 61 <li>supports full tail-recursion and first-class continuations</li> 62 </ol> 63 64 <p> 65 When confronted with a large C library, CHICKEN users can use 66 SWIG to generate CHICKEN wrappers for the C library. However, 67 the real advantages of using SWIG with CHICKEN are its 68 <strong>support for C++</strong> -- object-oriented code is 69 difficult to wrap by hand in CHICKEN -- and its <strong>typed 70 pointer representation</strong>, essential for C and C++ 71 libraries involving structures or classes. 72 73 </p> 74 75<H2><a name="Chicken_nn2"></a>20.1 Preliminaries</H2> 76 77 78 <p> 79 CHICKEN support was introduced to SWIG in version 1.3.18. SWIG 80 relies on some recent additions to CHICKEN, which are only 81 present in releases of CHICKEN with version number 82 <strong>greater than or equal to 1.89</strong>. 83 To use a chicken version between 1.40 and 1.89, see the <a href="#Chicken_collection">Garbage collection</a> 84 section below. 85 </p> 86 87 <p> 88 You may want to look at any of the examples in Examples/chicken/ 89 directory for the basic steps to run SWIG CHICKEN. 90 </p> 91 92<H3><a name="Chicken_nn3"></a>20.1.1 Running SWIG in C mode</H3> 93 94 95 <p> 96 To run SWIG CHICKEN in C mode, use 97 the -chicken option. 98 </p> 99 100 <div class="shell"> 101 <pre>% swig -chicken example.i</pre> 102 </div> 103 104 <p> 105 To allow the wrapper to take advantage of future CHICKEN code 106 generation improvements, part of the wrapper is direct CHICKEN 107 function calls (<tt>example_wrap.c</tt>) and part is CHICKEN 108 Scheme (<tt>example.scm</tt>). The basic Scheme code must 109 be compiled to C using your system's CHICKEN compiler or 110 both files can be compiled directly using the much simpler <tt>csc</tt>. 111 </p> 112 113 <div class="shell"> 114<pre> 115% chicken example.scm -output-file oexample.c 116</pre> 117 </div> 118 119 <p> 120 So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and 121 <tt>oexample.c</tt> are the files that must be compiled to 122 object files and linked into your project. 123 </p> 124 125<H3><a name="Chicken_nn4"></a>20.1.2 Running SWIG in C++ mode</H3> 126 127 128 <p> 129 To run SWIG CHICKEN in C++ mode, use 130 the -chicken -c++ option. 131 </p> 132 133 <div class="shell"> 134 <pre>% swig -chicken -c++ example.i</pre> 135 </div> 136 137 <p> 138 This will generate <tt>example_wrap.cxx</tt> and 139 <tt>example.scm</tt>. The basic Scheme code must be 140 compiled to C using your system's CHICKEN compiler or 141 both files can be compiled directly using the much simpler <tt>csc</tt>. 142 </p> 143 144 <div class="shell"> 145 <pre>% chicken example.scm -output-file oexample.c</pre> 146 </div> 147 148 <p> 149 So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt> 150 and <tt>oexample.c</tt> are the files that must be compiled to 151 object files and linked into your project. 152 </p> 153 154<H2><a name="Chicken_nn5"></a>20.2 Code Generation</H2> 155 156 157<H3><a name="Chicken_nn6"></a>20.2.1 Naming Conventions</H3> 158 159 160 <p> 161 Given a C variable, function or constant declaration named 162 <tt>Foo_Bar</tt>, the declaration will be available 163 in CHICKEN as an identifier ending with 164 <tt>Foo-Bar</tt>. That is, an underscore is converted 165 to a dash. 166 </p> 167 168 <p> 169 You may control what the CHICKEN identifier will be by using the 170 <tt>%rename</tt> SWIG directive in the SWIG interface file. 171 </p> 172 173<H3><a name="Chicken_nn7"></a>20.2.2 Modules</H3> 174 175 176 <p> 177 The name of the module must be declared one of two ways: 178 <ul> 179 <li>Placing <tt>%module example</tt> in the SWIG interface 180 file.</li> 181 <li>Using <tt>-module example</tt> on the SWIG command 182 line.</li> 183 </ul> 184 185 <p> 186 The generated example.scm file then exports <code>(declare (unit modulename))</code>. 187 If you do not want SWIG to export the <code>(declare (unit modulename))</code>, pass 188 the -nounit option to SWIG. 189 190 <p> 191 CHICKEN will be able to access the module using the <code>(declare 192 (uses <i>modulename</i>))</code> CHICKEN Scheme form. 193 </p> 194 195<H3><a name="Chicken_nn8"></a>20.2.3 Constants and Variables</H3> 196 197 198 <p> 199 Constants may be created using any of the four constructs in 200 the interface file: 201 </p> 202 <ol> 203 <li><code>#define MYCONSTANT1 ...</code></li> 204 <li><code>%constant int MYCONSTANT2 = ...</code></li> 205 <li><code>const int MYCONSTANT3 = ...</code></li> 206 <li><code>enum { MYCONSTANT4 = ... };</code></li> 207 </ol> 208 209 <p> 210 In all cases, the constants may be accessed from within CHICKEN 211 using the form <tt>(MYCONSTANT1)</tt>; that is, the constants 212 may be accessed using the read-only parameter form. 213 </p> 214 215 <p> 216 Variables are accessed using the full parameter form. 217 For example, to set the C variable "int my_variable;", use the 218 Scheme form <tt>(my-variable 2345)</tt>. To get the C variable, 219 use <tt>(my-variable)</tt>. 220 </p> 221 222 <p> 223 The <tt>%feature("constasvar")</tt> can be applied to any constant 224 or immutable variable. Instead of exporting the constant as 225 a function that must be called, the constant will appear as a 226 scheme variable. This causes the generated .scm file to just contain the code 227 <tt>(set! MYCONSTANT1 (MYCONSTANT1))</tt>. See 228 <a href="Customization.html#Customization_features">Features and the %feature directive</a> 229 for info on how to apply the %feature. 230 </p> 231 232<H3><a name="Chicken_nn9"></a>20.2.4 Functions</H3> 233 234 235 <p> 236 C functions declared in the SWIG interface file will have 237 corresponding CHICKEN Scheme procedures. For example, the C 238 function "int sqrt(double x);" will be available using the 239 Scheme form <tt>(sqrt 2345.0)</tt>. A <code>void</code> return 240 value will give C_SCHEME_UNDEFINED as a result. 241 </p> 242 <p> 243 A function may return more than one value by using the 244 <code>OUTPUT</code> specifier (see Lib/chicken/typemaps.i). 245 They will be returned as multiple values using <code>(values)</code> if there is more than one 246 result (that is, a non-void return value and at least one argout 247 parameter, or a void return value and at least two argout 248 parameters). The return values can then be accessed with <code>(call-with-values)</code>. 249 </p> 250 251<H3><a name="Chicken_nn10"></a>20.2.5 Exceptions</H3> 252 253 254 <p>The SWIG chicken module has support for exceptions thrown from 255 C or C++ code to be caught in scheme. 256 See <a href="Customization.html#Customization_exception">Exception handling with %exception</a> 257 for more information about declaring exceptions in the interface file. 258 </p> 259 260 <p>Chicken supports both the <code>SWIG_exception(int code, const char *msg)</code> interface 261 as well as a <code>SWIG_ThrowException(C_word val)</code> function for throwing exceptions from 262 inside the %exception blocks. <code>SWIG_exception</code> will throw a list consisting of the code 263 (as an integer) and the message. Both of these will throw an exception using <code>(abort)</code>, 264 which can be handled by <code>(handle-exceptions)</code>. See 265 the Chicken manual on Exceptions 266 and <a href="http://srfi.schemers.org/srfi-12/srfi-12.html">SFRI-12</a>. Since the exception values are thrown 267 directly, if <code>(condition-case)</code> is used to catch an exception the exception will come through in the <code>val ()</code> case. 268 </p> 269 270 <p>The following simple module</p> 271 272<div class="code"><pre> 273%module exception_test 274 275%inline %{ 276 void test_throw(int i) throws (int) { 277 if (i == 1) throw 15; 278 } 279%} 280</pre></div> 281 282 <p>could be run with</p> 283 284<div class="targetlang"><pre> 285(handle-exceptions exvar 286 (if (= exvar 15) 287 (print "Correct!") 288 (print "Threw something else " exvar)) 289 (test-throw 1)) 290</pre></div> 291 292 293<H2><a name="Chicken_nn11"></a>20.3 TinyCLOS</H2> 294 295 296 <p> 297 The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as: 298 "Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a 299 metaobject protocol. The implementation is even simpler than 300 the simple CLOS found in `The Art of the Metaobject Protocol,' 301 weighing in at around 850 lines of code, including (some) 302 comments and documentation." 303 </p> 304 305 <p> 306 Almost all good Scheme books describe how to use metaobjects and 307 generic procedures to implement an object-oriented Scheme 308 system. Please consult a Scheme book if you are unfamiliar 309 with the concept. 310 </p> 311 312 <p> 313 314 CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN 315 uses if the -proxy argument is given. If -proxy is passed, then 316 the generated example.scm file will contain TinyCLOS class definitions. 317 A class named Foo is declared as <Foo>, and each member variable 318 is allocated a slot. Member functions are exported as generic functions. 319 320 <p> 321 322 Primitive symbols and functions (the interface that would be presented if 323 -proxy was not passed) are hidden and no longer accessible. If the -unhideprimitive 324 command line argument is passed to SWIG, then the primitive symbols will be 325 available, but each will be prefixed by the string "primitive:" 326 327 <p> 328 329 The exported symbol names can be controlled with the -closprefix and -useclassprefix arguments. 330 If -useclassprefix is passed to SWIG, every member function will be generated with the class name 331 as a prefix. If the -closprefix mymod: argument is passed to SWIG, then the exported functions will 332 be prefixed by the string "mymod:". If -useclassprefix is passed, -closprefix is ignored. 333 334 </p> 335 336<H2><a name="Chicken_nn12"></a>20.4 Linkage</H2> 337 338 339 <p> 340 Please refer to <em>CHICKEN - A practical and portable Scheme 341 system - User's manual</em> for detailed help on how to link 342 object files to create a CHICKEN Scheme program. Briefly, to 343 link object files, be sure to add <tt>`chicken-config 344 -extra-libs -libs`</tt> or <tt>`chicken-config -shared 345 -extra-libs -libs`</tt>to your linker options. Use the 346 <tt>-shared</tt> option if you want to create a dynamically 347 loadable module. You might also want to use the much simpler 348 <tt>csc</tt> or <tt>csc.bat</tt>. 349 </p> 350 351 <p>Each scheme file that is generated 352 by SWIG contains <code>(declare (uses <i>modname</i>))</code>. This means that to load the 353 module from scheme code, the code must include <code>(declare (uses <i>modname</i>))</code>. 354 </p> 355 356 357<H3><a name="Chicken_nn13"></a>20.4.1 Static binary or shared library linked at compile time</H3> 358 359 360 <p>We can easily use csc to build a static binary.</p> 361 362<div class="shell"> 363<pre> 364$ swig -chicken example.i 365$ csc -v example.scm example_impl.c example_wrap.c test_script.scm -o example 366$ ./example 367</pre> 368</div> 369 370<p>Similar to the above, any number of <tt>module.scm</tt> files could be compiled 371into a shared library, and then that shared library linked when compiling the 372main application.</p> 373 374<div class="shell"> 375<pre> 376$ swig -chicken example.i 377$ csc -sv example.scm example_wrap.c example_impl.c -o example.so 378</pre> 379</div> 380 381<p>The <tt>example.so</tt> file can then linked with <tt>test_script.scm</tt> when it 382is compiled, in which case <tt>test_script.scm</tt> must have <code>(declare (uses example))</code>. 383Multiple SWIG modules could have been linked into <tt>example.so</tt> and each 384one accessed with a <code>(declare (uses ... ))</code>. 385</p> 386 387<div class="shell"> 388<pre> 389$ csc -v test_script.scm -lexample 390</pre> 391</div> 392 393<p>An alternative is that the test_script.scm can have the code <code>(load-library 'example "example.so")</code>, 394in which case the test script does not need to be linked with example.so. The test_script.scm file can then 395be run with <tt>csi</tt>. 396</p> 397 398<H3><a name="Chicken_nn14"></a>20.4.2 Building chicken extension libraries</H3> 399 400 401<p>Building a shared library like in the above section only works if the library 402is linked at compile time with a script containing <code>(declare (uses ...))</code> or is 403loaded explicitly with <code>(load-library 'example "example.so")</code>. It is 404not the format that CHICKEN expects for extension libraries and eggs. The problem is the 405<code>(declare (unit <i>modname</i>))</code> inside the <tt>modname.scm</tt> file. There are 406two possible solutions to this.</p> 407 408<p>First, SWIG accepts a <tt>-nounit</tt> argument, in which case the <code>(declare (unit <i>modname</i>))</code> 409is not generated. Then, the <tt>modname.scm</tt> and <tt>modname_wrap.c</tt> files <b>must</b> be compiled into 410their own shared library.</p> 411 412<div class="shell"> 413<pre> 414$ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so 415</pre> 416</div> 417 418<p>This library can then be loaded by scheme code with the <code>(require 'modname)</code> function. 419See the 420Loading-extension-libraries in the eval unit inside the CHICKEN manual for more information.</p> 421 422<p>Another alternative is to run SWIG normally and create a scheme file that contains <code>(declare (uses <i>modname</i>))</code> 423and then compile that file into the shared library as well. For example, inside the <tt>mod_load.scm</tt> file,</p> 424 425<div class="targetlang"> 426<pre> 427(declare (uses mod1)) 428(declare (uses mod2)) 429</pre> 430</div> 431 432<p>Which would then be compiled with</p> 433 434<div class="shell"> 435<pre> 436$ swig -chicken mod1.i 437$ swig -chicken mod2.i 438$ csc -sv mod_load.scm mod1.scm mod2.scm mod1_wrap.c mod2_wrap.c mod1_impl.c mod2_impl.c -o mod.so 439</pre> 440</div> 441 442<p>Then the extension library can be loaded with <code>(require 'mod)</code>. As we can see here, 443<tt>mod_load.scm</tt> contains the code that gets executed when the module is loaded. All this code 444does is load both mod1 and mod2. As we can see, this technique is more useful when you want to 445combine a few SWIG modules into one chicken extension library, especially if modules are related by 446<code>%import</code></p> 447 448<p>In either method, the files that are compiled into the shared library could also be 449packaged into an egg. The <tt>mod1_wrap.c</tt> and <tt>mod2_wrap.c</tt> files that are created by SWIG 450are stand alone and do not need SWIG to be installed to be compiled. Thus the egg could be 451distributed and used by anyone, even if SWIG is not installed.</p> 452 453<p>See the <tt>Examples/chicken/egg</tt> directory in the SWIG source for an example that builds 454two eggs, one using the first method and one using the second method.</p> 455 456<H3><a name="Chicken_nn15"></a>20.4.3 Linking multiple SWIG modules with TinyCLOS</H3> 457 458 459<p>Linking together multiple modules that share type information using the <code>%import</code> 460directive while also using <tt>-proxy</tt> is more complicated. For example, if <tt>mod2.i</tt> imports <tt>mod1.i</tt>, then the 461<tt>mod2.scm</tt> file contains references to symbols declared in <tt>mod1.scm</tt>, 462and thus a <code>(declare (uses <i>mod1</i>))</code> or <code>(require '<i>mod1</i>)</code> must be exported 463to the top of <tt>mod2.scm</tt>. By default, when SWIG encounters an <code>%import "modname.i"</code> directive, 464it exports <code>(declare (uses <i>modname</i>))</code> into the scm file. This works fine unless mod1 was compiled with 465the <tt>-nounit</tt> argument or was compiled into an extension library with other modules under a different name.</p> 466 467<p>One option is to override the automatic generation of <code>(declare (uses mod1))</code> 468by passing the <tt>-noclosuses</tt> option to SWIG when compiling <tt>mod2.i</tt>. 469SWIG then provides the <code>%insert(closprefix) %{ %}</code> directive. Any scheme code inside that directive is inserted into the 470generated .scm file, and if <tt>mod1</tt> was compiled with <tt>-nounit</tt>, the directive should contain <code>(require 'mod1)</code>. 471This option allows for mixed loading as well, where some modules are imported with <code>(declare (uses <i>modname</i>))</code> 472(which means they were compiled without -nounit) and some are imported with <code>(require 'modname)</code>.</p> 473 474<p>The other option is to use the second idea in the above section. Compile all the modules normally, without any 475<code>%insert(closprefix)</code>, <tt>-nounit</tt>, or <tt>-noclosuses</tt>. Then the modules will import each other correctly 476with <code>(declare (uses ...))</code>. 477To create an extension library or an egg, just create a <tt>module_load.scm</tt> file that <code>(declare (uses ...))</code> 478all the modules.</p> 479 480<H2><a name="Chicken_nn16"></a>20.5 Typemaps</H2> 481 482 483 <p> 484 The Chicken module handles all types via typemaps. This information is 485 read from <code>Lib/chicken/typemaps.i</code> and 486 <code>Lib/chicken/chicken.swg</code>. 487 </p> 488 489<H2><a name="Chicken_nn17"></a>20.6 Pointers</H2> 490 491 492 <p> 493 For pointer types, SWIG uses CHICKEN tagged pointers. 494 495 A tagged pointer is an ordinary CHICKEN pointer with an 496 extra slot for a void *. With SWIG 497 CHICKEN, this void * is a pointer to a type-info 498 structure. So each pointer used as input or output from 499 the SWIG-generated CHICKEN wrappers will have type 500 information attached to it. This will let the wrappers 501 correctly determine which method should be called 502 according to the object type hierarchy exposed in the SWIG 503 interface files. 504 </p> 505 <p> 506 To construct a Scheme object from a C pointer, the wrapper code 507 calls the function 508 <code>SWIG_NewPointerObj(void *ptr, swig_type_info *type, int owner)</code>, 509 The function that calls <code>SWIG_NewPointerObj</code> must have a variable declared 510 <code>C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);</code> 511 It is ok to call <code>SWIG_NewPointerObj</code> more than once, 512 just make sure known_space has enough space for all the created pointers. 513 </p> 514 <p> 515 To get the pointer represented by a CHICKEN tagged pointer, the 516 wrapper code calls the function 517 <code>SWIG_ConvertPtr(C_word s, void **result, swig_type_info *type, int flags)</code>, 518 passing a pointer to a struct representing the expected pointer 519 type. flags is either zero or SWIG_POINTER_DISOWN (see below). 520 </p> 521 522<H3><a name="Chicken_collection"></a>20.6.1 Garbage collection</H3> 523 524 525 <p>If the owner flag passed to <code>SWIG_NewPointerObj</code> is 1, <code>NewPointerObj</code> will add a 526 finalizer to the type which will call the destructor or delete method of 527 that type. The destructor and delete functions are no longer exported for 528 use in scheme code, instead SWIG and chicken manage pointers. 529 In situations where SWIG knows that a function is returning a type that should 530 be garbage collected, SWIG will automatically set the owner flag to 1. For other functions, 531 the <code>%newobject</code> directive must be specified for functions whose return values 532 should be garbage collected. See 533 <a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for more information. 534 </p> 535 536 <p>In situations where a C or C++ function will assume ownership of a pointer, and thus 537 chicken should no longer garbage collect it, SWIG provides the <code>DISOWN</code> input typemap. 538 After applying this typemap (see the <a href="Typemaps.html#Typemaps">Typemaps chapter</a> for more information on how to apply typemaps), 539 any pointer that gets passed in will no longer be garbage collected. 540 An object is disowned by passing the <code>SWIG_POINTER_DISOWN</code> flag to <code>SWIG_ConvertPtr</code>. 541 <b>Warning:</b> Since the lifetime of the object is now controlled by the underlying code, the object might 542 get deleted while the scheme code still holds a pointer to it. Further use of this pointer 543 can lead to a crash. 544 </p> 545 546 <p>Adding a finalizer function from C code was added to chicken in the 1.89 release, so garbage collection 547 does not work for chicken versions below 1.89. If you would like the SWIG generated code to work with 548 chicken 1.40 to 1.89, pass the <code>-nocollection</code> argument to SWIG. This will not export code 549 inside the _wrap.c file to register finalizers, and will then export destructor functions which 550 must be called manually. 551 </p> 552 553<H2><a name="Chicken_nn18"></a>20.7 Unsupported features and known problems</H2> 554 555 556 <ul> 557 <li>No director support.</li> 558 <li>No support for c++ standard types like std::vector.</li> 559 <li>The TinyCLOS wrappers for overloaded functions will not work correctly when using 560 <a href="SWIGPlus.html#SWIGPlus_default_args">%feature(compactdefaultargs)</a>.</li> 561 </ul> 562 563<H3><a name="Chicken_nn19"></a>20.7.1 TinyCLOS problems with Chicken version <= 1.92</H3> 564 565 566 <p>In Chicken versions equal to or below 1.92, TinyCLOS has a limitation such that generic methods do not properly work on methods 567 with different number of specializers: TinyCLOS assumes that every method added to a generic function 568 will have the same number of specializers. SWIG generates functions with different lengths of specializers 569 when C/C++ functions are overloaded. For example, the code</p> 570 571<div class="code"> 572<pre> 573class Foo {}; 574int foo(int a, Foo *b); 575int foo(int a); 576</pre></div> 577 578<p>will produce scheme code</p> 579 580<div class="targetlang"> 581<pre> 582(define-method (foo (arg0 <top>) (arg1 <Foo>)) (<i>call primitive function</i>)) 583(define-method (foo (arg0 <top>)) (<i>call primitive function</i>)) 584</pre></div> 585 586<p>Using unpatched TinyCLOS, the second <code>(define-method)</code> will replace the first one, 587so calling <code>(foo 3 f)</code> will produce an error.</p> 588 589<p>There are three solutions to this. The easist is to upgrade to the latest Chicken version. Otherwise, the 590file <tt>Lib/chicken/tinyclos-multi-generic.patch</tt> in the SWIG source contains a patch against 591tinyclos.scm inside the 1.92 chicken source to add support into TinyCLOS for multi-argument generics. (This patch was accepted into Chicken) 592This requires chicken to be rebuilt and custom install of chicken. An alternative is the <tt>Lib/chicken/multi-generic.scm</tt> 593file in the SWIG source. This file can be loaded after TinyCLOS is loaded, and it will override some functions 594inside TinyCLOS to correctly support multi-argument generics. Please see the comments at the top of both files for more information.</p> 595 596 </body> 597</html>