-
Notifications
You must be signed in to change notification settings - Fork 0
/
Getting started
542 lines (430 loc) · 19.9 KB
/
Getting started
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
[[tags: manual]]
== Getting started
CHICKEN is a compiler that translates Scheme source files into
C, which in turn can be fed to a C compiler to generate a
standalone executable. An interpreter is also available and can be
used as a scripting environment or for testing programs before
compilation.
This chapter is designed to get you started with CHICKEN programming,
describing what it is and what it will do for you, and covering basic
use of the system. With almost everything discussed here, there is
more to the story, which the remainder of the manual reveals. Here, we
only cover enough to get you started. Nonetheless, someone who knows
Scheme already should be able to use this chapter as the basis for
writing and running small CHICKEN programs.
=== Scheme
Scheme is a member of the Lisp family of languages, of which Common
Lisp, Emacs Lisp and Clojure are other widely-known members. As with
Lisp dialects, Scheme features
* a wide variety of programming paradigms, including imperative, functional, and object-oriented
* a very simple syntax, based upon nested parenthesization
* the ability to extend the language in meaningful and useful ways
In contrast to Common Lisp, Scheme is very minimal, and tries to
include only those features absolutely necessary in programming. In
contrast to Emacs Lisp, Scheme is not anchored into a single program
(Emacs), and has a more modern and elegant language design. In contrast
to Clojure, Scheme provides only a very minimal set of concepts but allows
them to be used in very general ways with few restrictions.
Scheme is defined in a document called ''The Revised^5 Report on the
Algorithmic Language Scheme'', or ''R5RS'' for short. (Yes, it really
has been revised five times, so an expanded version of its name would
be ''The Revised Revised Revised Revised Revised Report''.) A newer
report, ''R6RS'', was
released in 2007, but this report has attracted considerable
controversy, and a number of Scheme implementations have chosen
not to be compliant
with it. Yet another report was released in 2013 ("R7RS"), that was
less ambitious than R6RS and more minimal.
CHICKEN fully complies with R5RS and, by using a separately available
extension also with the "R7RS small" language.
Even though Scheme is consciously minimalist, it is recognized that a
language must be more than a minimal core in order to be
useful. Accordingly, the Scheme community uses a process known as
`Scheme Requests For Implementation' (SRFI, pronounced `SUR-fee') to
define new language features. A typical Scheme system therefore
complies with one of the Scheme reports plus some or all of the
accepted SRFIs.
A good starting point for Scheme knowledge is
[[http://www.schemers.org]]. There you will find the defining reports,
FAQs, lists of useful books and other resources, and the SRFIs.
=== CHICKEN
CHICKEN Scheme combines an optimising compiler with a reasonably fast
interpreter. It supports almost all of R7RS and the important SRFIs.
The compiler generates portable C code that supports tail recursion,
first-class continuations and lightweight threads, and the interface to
and from C libraries is flexible, efficient, and easy to use. There are
hundreds of contributed CHICKEN libraries that make the programmer's
task easier. The interpreter allows interactive use, fast prototyping,
debugging, and scripting. The active and helpful CHICKEN community
fixes bugs and provides support. Extensive documentation is supplied.
CHICKEN was developed by Felix L. Winkelmann over the period from 2000
through 2007. In early 2008, Felix
asked the community to take over the responsibility of developing and
maintaining the system, though he still takes a strong interest in it,
and participates actively.
CHICKEN includes
* a Scheme interpreter that supports all of R5(7)RS Scheme, with
only a few relatively minor omissions, and with many extensions
* a compatible compiler whose target is C, thus making porting to new
machines and architectures relatively straightforward
* the C support allows Scheme code to include `embedded' C code,
thus making it easy to invoke host OS or library
functions
* a framework for language extensions, library modules that broaden
the functionality of the system
This package is distributed under the '''BSD license''' and as such is free
to use and modify as long as the original authors are acknowledged.
Scheme cognoscenti will appreciate the method of compilation and the
design of the runtime-system, which follow closely Henry Baker's
[[http://home.pipeline.com/~hbaker1/CheneyMTA.html|CONS Should Not
CONS Its Arguments, Part II: Cheney on the M.T.A.]] paper and expose a
number of interesting properties.
* Consing (creation of data on the heap) is inexpensive,
because a generational garbage collection scheme is used in combination
with allocating on the C stack, in which short-lived data structures are reclaimed
extremely quickly.
* Moreover, {{call-with-current-continuation}} involves only minimal
overhead and CHICKEN does not suffer under any performance penalties if
first-class continuations are used in complex ways.
The generated C code fully supports tail-call optimization (TCO).
Some of the features supported by CHICKEN:
* Lightweight threads based on first-class continuations
* Record structures
* Extended comment- and string-literal syntaxes
* Libraries for regular expressions, string handling
* UNIX system calls and extended data structures
* Compiled C files can be easily distributed
* Allows the creation of fully self-contained statically linked executables
* On systems that support it, compiled code can be loaded dynamically
* Built-in support for cross-compilation
CHICKEN has been used in many environments ranging from embedded
systems through desktop machines to large-scale server deployments.
The number of language extensions, or '''eggs''', is constantly growing:
* extended language features
* development tools, such as documentation generators, debugging, and
automated testing libraries
* interfaces to other languages such as Java, Python, and Objective-C
* interfaces to database systems, GUIs, and other libraries,
* network applications, such as servers and clients for ftp,
smtp/pop3, irc, and http
* web servers and related tools, including URL parsing, HTML
generation, AJAX, and HTTP session management
* data formats, including XML, JSON, and Unicode support
This chapter provides you with an overview of the entire system, with
enough information to get started writing and running small Scheme
programs.
=== CHICKEN repositories, websites and community
The master CHICKEN website is
[[http://www.call-cc.org]]. Here you can find
basic information about CHICKEN, downloads and pointers to other key
resources.
The CHICKEN wiki ([[http://wiki.call-cc.org]]) contains the most
current version of the User's manual, along with various tutorials and
other useful documents. The list of eggs is at
[[http://wiki.call-cc.org/egg-index|http://wiki.call-cc.org/egg-index]].
A very useful search facility for questions about procedures and syntax
available for CHICKEN can be found at
[[http://api.call-cc.org]]. The CHICKEN issue tracker is at
[[http://bugs.call-cc.org]].
The CHICKEN community has two major mailing lists. If you are a
CHICKEN user, {{chicken-users}}
([[http://lists.nongnu.org/mailman/listinfo/chicken-users]]) will be
of interest. The crew working on the CHICKEN system itself uses the
very low-volume {{chicken-hackers}} list
([[http://lists.nongnu.org/mailman/listinfo/chicken-hackers]]) for
communication. For other topic-specific mailing lists (e.g.,
announcements, security) and discussion groups, see
[[http://wiki.call-cc.org/discussion-groups|http://wiki.call-cc.org/discussion-groups]].
There is also an IRC channel ({{#chicken}}) on
[[http://freenode.net|Freenode]].
=== Installing CHICKEN
CHICKEN is available as C sources. Refer to the
{{README}} file in the distribution for instructions on installing it
on your system.
Because it compiles to C, CHICKEN requires that a C compiler be
installed on your system. (If you're not writing embedded C code, you
can pretty much ignore the C compiler once you have installed it.)
* On a Linux system, a C toolchain (e.g., GCC, clang) should be
installed as part of the basic operating system, or should be
available through the package management system (e.g., APT,
Synaptic, RPM, or Yum, depending upon your Linux distribution).
* On Macintosh OS X, you will need the XCode tools, which are
installable from the App Store.
* On Windows, you have three choices:
* Cygwin ([[http://sourceware.org/cygwin/]]) provides a relatively
full-featured Unix environment for Windows. CHICKEN works
substantially the same in Cygwin and Unix.
* The GNU Compiler Collection has been ported to Windows, in the
MinGW system ([[http://mingw.sourceforge.net]]). Unlike Cygwin,
executables produced with MinGW do not need the Cygwin DLLs in order
to run. MSYS is a companion package to MinGW; it provides a minimum
Unix-style development/build environment, again ported from free
software.
* You can build CHICKEN either with MinGW alone or with MinGW plus
MSYS. Both approaches produce a CHICKEN built against the mingw headers
and libraries.
The only difference is the environment where you actually run make.
{{Makefile.mingw}} can be used in {{cmd.exe}} with the version of make
that comes with mingw. {{Makefile.mingw-msys}}
uses unix commands such as {{cp}} and {{rm}}. The end product is the
same.
Refer to the {{README}} file for the version you're installing for
more information on the installation process.
Alternatively, third party packages in binary format are
available. See
[[http://wiki.call-cc.org/platforms|http://wiki.call-cc.org/platforms]]
for information about how to obtain them.
=== Development environments
The simplest development environment is a text editor and terminal
window (Windows: Command Prompt, OSX: Terminal, Linux/Unix: xterm) for
using the interpreter and/or invoking the compiler. If you install one
of the line editing extensions (e.g., [[/egg/breadline|breadline]],
[[/egg/parley|parley]], [[/egg/linenoise|linenoise]]), you have some
useful command line editing features in the interpreter (e.g., Emacs
or vi-compatible line editing, customization).
It will be helpful to use a text editor that knows Scheme; it can be painful
with editors that don't do parenthesis matching and automatic
indentation.
In the rest of this chapter, we'll assume that you are using an editor
of your choice and a regular terminal window for executing your
CHICKEN code.
=== The Read-Eval-Print loop
To invoke the CHICKEN interpreter, you use the {{csi}} command.
$ csi
CHICKEN
(c) 2008-2021, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 5.0.0 (rev 6653dce)
linux-unix-gnu-x86-64 [ 64bit dload ptables ]
Type ,? for help.
#;1>
This brings up a brief banner, and then the prompt. You can use this
pretty much like any other Scheme system, e.g.,
#;1> (define (twice f) (lambda (x) (f (f x))))
#;2> ((twice (lambda (n) (* n 10))) 3)
300
Suppose we have already created a file {{fact.scm}} containing a
function definition.
(define (fact n)
(if (= n 0)
1
(* n (fact (- n 1)))))
We can now load this file and try out the function.
#;3> (load "fact.scm")
; loading fact.scm ...
#;4> (fact 3)
6
The '''read-eval-print loop''' ('''REPL''') is the component of the
Scheme system that ''reads'' a Scheme expression, ''eval''uates it,
and ''prints'' out the result. The REPL's prompt can be customized
(see the [[Using the interpreter]])
but the default prompt, showing the number of the form, is quite
convenient.
The REPL also supports debugging commands:
input lines beginning with a {{,}} (comma) are treated as special
commands. (See the [[Using the interpreter#Toplevel commands|full list]].)
==== Scripts
You can use the interpreter to run a Scheme program from the command
line. For the following example we create a program that does a quick
search-and-replace on an input file; the arguments are a regular
expression and a replacement string. First create a file to hold the "data" called ''quickrep.dat'' with your favorite editor holding these lines:
xyzabcghi
abxawxcgh
foonly
Next create the scheme code in a file called ''quickrep.scm'' with the
following little program:
<enscript highlight=scheme>
;; irregex, the regular expression library, is one of the
;; libraries included with CHICKEN.
(import (chicken irregex)
(chicken io))
(define (process-line line re rplc)
(irregex-replace/all re line rplc))
(define (quickrep re rplc)
(let ((line (read-line)))
(if (not (eof-object? line))
(begin
(display (process-line line re rplc))
(newline)
(quickrep re rplc)))))
;;; Does a lousy job of error checking!
(define (main args)
(quickrep (irregex (car args)) (cadr args)))
</enscript>
To run it enter this in your shell:
$ csi -ss quickrep.scm <quickrep.dat 'a.*c' A
xyzAghi
Agh
foonly
The {{-ss}} option sets several options that work smoothly together to
execute a script. You can make the command directly executable from
the shell by inserting a [[Using the interpreter#Writing Scheme scripts|shebang line]]
at the beginning of the program.
The {{-ss}} option arranges to call a procedure named {{main}}, with
the command line arguments, packed in a list, as its arguments. (There
are a number of ways this program could be made more idiomatic CHICKEN
Scheme, see the rest of the manual for details.)
=== The compiler
There are several reasons you might want to compile your code.
* Compiled code executes substantially faster than interpreted
code.
* You might want to deploy an application onto machines where the
users aren't expected to have CHICKEN installed: compiled
applications can be self-contained.
* Compiled code can access external libraries written in lower-level
languages that follow the C calling convention.
The CHICKEN compiler is provided as the command {{chicken}}, but in
almost all cases, you will want to use the {{csc}} command
instead. {{csc}} is a convenient driver that automates compiling
Scheme programs into C, compiling C code into object code, and linking
the results into an executable file. (Note: in a Windows environment
with Visual Studio, you may find that {{csc}} refers to Microsoft's
C# compiler. There are a number of ways of sorting this out, of which
the simplest is to rename one of the two tools, and/or to
organize your {{PATH}} according to the task at hand.)
We can compile our factorial function, producing a file named
{{fact.so}} (''shared object'' in Linux-ese, the same file extension is
used in Windows, rather than {{dll}})
chicken$ csc -shared fact.scm
chicken$ csi -quiet
#;1> (load "fact.so")
; loading fact.so ...
#;2> (fact 6)
720
On any system, we can just compile a program directly into an
executable. Here's a program that tells you whether its argument is a
palindrome.
<enscript highlight=scheme>
(import (chicken process-context)) ; for "command-line-arguments"
(define (palindrome? x)
(define (check left right)
(if (>= left right)
#t
(and (char=? (string-ref x left) (string-ref x right))
(check (add1 left) (sub1 right)))))
(check 0 (sub1 (string-length x))))
(let ((arg (car (command-line-arguments))))
(display
(string-append arg
(if (palindrome? arg)
" is a palindrome\n"
" isn't a palindrome\n"))))
</enscript>
We can compile this program using {{csc}}, creating an executable
named {{palindrome}}.
$ csc -o palindrome palindrome.scm
$ ./palindrome level
level is a palindrome
$ ./palindrome liver
liver isn't a palindrome
CHICKEN supports separate compilation, using some extensions to
Scheme. Let's divide our palindrome program into a library module
({{pal-proc.scm}}) and a client module ({{pal-user.scm}}).
Here's the external library. We {{declare}} that {{pal-proc}} is a
''unit'', which is the basis of separately-compiled modules in
CHICKEN. (Units deal with separate compilation, but don't necessarily
involve separated namespaces; namespaces can be implemented by
[[/manual/Modules|modules]].)
<enscript highlight=scheme>
;;; Library pal-proc.scm
(declare (unit pal-proc))
(define (palindrome? x)
(define (check left right)
(if (>= left right)
#t
(and (char=? (string-ref x left) (string-ref x right))
(check (add1 left) (sub1 right)))))
(check 0 (sub1 (string-length x))))
</enscript>
Next we have some client code that ''uses'' this separately-compiled
module.
<enscript highlight=scheme>
;;; Client pal-user.scm
(declare (uses pal-proc))
(import (chicken process-context))
(let ((arg (car (command-line-arguments))))
(display
(string-append arg
(if (palindrome? arg)
" is a palindrome\n"
" isn't a palindrome\n"))))
</enscript>
Now we can compile and link everything together. (We show the compile
and link operations separately, but they can of course be combined
into one command.)
$ csc -c pal-proc.scm
$ csc -c pal-user.scm
$ csc -o pal-separate pal-proc.o pal-user.o
$ ./pal-separate level
level is a palindrome
The "unit" mechanism is relatively low-level and requires some
familiarity with underlying mechanism used to manage compilation
units. See [[Units and linking model]] for more information.
=== Installing an egg
Installing eggs is quite straightforward on systems that support
dynamic loading (that would include *BSD, Linux, Mac OS X,
Solaris, and Windows). The command {{chicken-install}} will fetch an
egg from the master CHICKEN repository, and install it on your local
system.
In this example, we install the {{uri-common}} egg, for parsing
Uniform Resource Identifiers.
$ chicken-install uri-common
{{chicken-install}} connects to a mirror of the egg repository and
retrieves the egg contents. If the egg has any uninstalled
dependencies, it recursively installs them. Then it builds the egg
code and installs the resulting extension into the
local CHICKEN repository.
Now we can use our new egg.
#;1> (import uri-common)
; loading /usr/lib/chicken/9/uri-common.import.so ...
; [... other loaded files omitted for clarity ...]
#;2> (uri-host (uri-reference "http://www.foobar.org/blah"))
"www.foobar.org"
=== Accessing C libraries
Because CHICKEN compiles to C, and because a foreign function
interface is built into the compiler, interfacing to a C library is
quite straightforward. This means that any facility available
on the host system is accessible from CHICKEN, with more or less
work.
Let's create a simple C library, to demonstrate how this
works. Here we have a function that will compute and return the '''n'''th
Fibonacci number. (This isn't a particularly good use of C here,
because we could write this function just as easily in Scheme, but a
real example would take far too much space here.)
/* fib.c */
int fib(int n) {
int prev = 0, curr = 1;
int next;
int i;
for (i = 0; i < n; i++) {
next = prev + curr;
prev = curr;
curr = next;
}
return curr;
}
Now we can call this function from CHICKEN.
;;; fib-user.scm
(import (chicken foreign) (chicken format))
#>
extern int fib(int n);
<#
(define xfib (foreign-lambda int "fib" int))
(do ((i 0 (+ i 1))) ((> i 10))
(printf "~A " (xfib i)))
(newline)
The syntax {{#>...<#}} allows you to include literal C (typically
external declarations) in your CHICKEN code. We access {{fib}} by
defining a {{foreign-lambda}} for it, in this case saying that the
function takes one integer argument (the {{int}} after the function
name), and that it returns an integer result (the {{int}} before.) Now we can invoke
{{xfib}} as though it were an ordinary Scheme function.
$ gcc -c fib.c
$ csc -o fib-user fib.o fib-user.scm
$ ./fib-user
0 1 1 2 3 5 8 13 21 34 55
Those who are interfacing to substantial C libraries should consider
using the [[/egg/bind|bind egg]].
---
Back to [[The User's Manual]]
Next: [[Using the interpreter]]