Commit | Line | Data |
---|---|---|
a0e07ba4 NJ |
1 | \input texinfo @c -*-texinfo-*- |
2 | @c %**start of header | |
3 | @setfilename guile-tut.info | |
4 | @settitle Guile Tutorial | |
5 | @set guile-tut | |
6 | ||
0aa7a7ce | 7 | @include version.texi |
a0e07ba4 NJ |
8 | |
9 | @dircategory The Algorithmic Language Scheme | |
10 | @direntry | |
11 | * Guile Tutorial: (guile-tut). The Guile tutorial. | |
12 | @end direntry | |
13 | ||
14 | @setchapternewpage off | |
15 | @c Choices for setchapternewpage are {on,off,odd}. | |
16 | @paragraphindent 2 | |
17 | @c %**end of header | |
18 | ||
19 | @iftex | |
20 | @finalout | |
21 | @c DL: lose the egregious vertical whitespace, esp. around examples | |
22 | @c but paras in @defun-like things don't have parindent | |
23 | @parskip 4pt plus 1pt | |
24 | @end iftex | |
25 | ||
26 | @titlepage | |
27 | @title Guile Tutorial | |
28 | @subtitle For use with Guile @value{VERSION} | |
29 | @subtitle Last updated @value{UPDATED} | |
b45898ca NJ |
30 | |
31 | @author Mark Galassi | |
32 | @author Cygnus Solutions and Los Alamos National Laboratory | |
33 | @author @email{rosalia@@nis.lanl.gov} | |
a0e07ba4 NJ |
34 | |
35 | @page | |
36 | @vskip 0pt plus 1filll | |
37 | Copyright @copyright{} 1997, 1998 Free Software Foundation | |
38 | ||
39 | Permission is granted to make and distribute verbatim copies of | |
40 | this manual provided the copyright notice and this permission notice | |
41 | are preserved on all copies. | |
42 | ||
43 | Permission is granted to copy and distribute modified versions of this | |
44 | manual under the conditions for verbatim copying, provided that the entire | |
45 | resulting derived work is distributed under the terms of a permission | |
46 | notice identical to this one. | |
47 | ||
48 | Permission is granted to copy and distribute translations of this manual | |
49 | into another language, under the above conditions for modified versions, | |
50 | except that this permission notice may be stated in a translation approved | |
51 | by the author. | |
52 | @end titlepage | |
53 | ||
54 | ||
55 | @ifinfo | |
56 | @node Top | |
57 | @top Guile Tutorial | |
58 | @end ifinfo | |
59 | ||
60 | @ifinfo | |
61 | This file gives a tutorial introductionto Guile. | |
62 | ||
63 | Copyright (C) 1997 Free Software Foundation | |
64 | ||
65 | Permission is granted to make and distribute verbatim copies of | |
66 | this manual provided the copyright notice and this permission notice | |
67 | are preserved on all copies. | |
68 | ||
69 | @ignore | |
70 | Permission is granted to process this file through TeX and print the | |
71 | results, provided the printed document carries copying permission | |
72 | notice identical to this one except for the removal of this paragraph | |
73 | (this paragraph not being relevant to the printed manual). | |
74 | ||
75 | @end ignore | |
76 | Permission is granted to copy and distribute modified versions of this | |
77 | manual under the conditions for verbatim copying, provided that the entire | |
78 | resulting derived work is distributed under the terms of a permission | |
79 | notice identical to this one. | |
80 | ||
81 | Permission is granted to copy and distribute translations of this manual | |
82 | into another language, under the above conditions for modified versions, | |
83 | except that this permission notice may be stated in a translation approved | |
84 | by the author. | |
85 | @end ifinfo | |
86 | ||
87 | ||
88 | @menu | |
fab8ab31 TTN |
89 | * Jump Start:: |
90 | * Introduction:: | |
91 | * Using Guile to program in Scheme:: | |
92 | * Guile in a Library:: | |
93 | * Regular Expression Support:: | |
94 | * UNIX System Programming:: | |
95 | * Where to find more Guile/Scheme resources:: | |
96 | * Concept Index:: | |
97 | * Procedure and Macro Index:: | |
98 | * Variable Index:: | |
99 | * Type Index:: | |
a0e07ba4 NJ |
100 | @end menu |
101 | ||
c5d13061 | 102 | |
a0e07ba4 NJ |
103 | @node Jump Start |
104 | @chapter Jump Start | |
105 | ||
106 | @noindent | |
107 | Before giving an overview of Guile, I present some simple commands and | |
108 | programs that you can type to get going immediately. | |
109 | ||
c5d13061 NJ |
110 | Start by invoking the Guile interpreter. Usually you do this by just |
111 | typing @code{guile}. Then type (or paste) the following expressions at | |
a0e07ba4 NJ |
112 | the prompt; the interpreter's response is preceded (in this manual) by |
113 | @result{}. | |
114 | ||
115 | @example | |
116 | <shell-prompt> guile | |
117 | @end example | |
118 | @lisp | |
119 | (+ 20 35) | |
120 | @result{} 55 | |
121 | (define (recursive-factorial n) | |
c5d13061 NJ |
122 | (if (zero? n) |
123 | 1 | |
124 | (* n (recursive-factorial (- n 1))))) | |
a0e07ba4 NJ |
125 | (recursive-factorial 5) |
126 | @result{} 120 | |
c5d13061 NJ |
127 | (quit) |
128 | @end lisp | |
129 | ||
130 | In this example we did some simple arithmetic @code{(+ 20 35)} and got | |
131 | the answer @code{55}. Then we coded the classic (and rather wasteful) | |
132 | factorial algorithm and computed the factorial of @code{55}. Finally we | |
133 | quit with @code{(quit)}. | |
134 | ||
135 | @cindex bignumbers | |
136 | We can find out about some of Scheme's nice features by asking for the | |
137 | factorial of some big number, say @code{500}. On some systems the | |
138 | correct answer will be returned (I do not indicate calling and leaving | |
139 | the guile session anymore). | |
140 | ||
141 | @lisp | |
a0e07ba4 NJ |
142 | (recursive-factorial 500) |
143 | @result{} 1220136825991110068701238785423046926253574342803192842192413588 | |
144 | 3858453731538819976054964475022032818630136164771482035841633787 | |
145 | 2207817720048078520515932928547790757193933060377296085908627042 | |
146 | 9174547882424912726344305670173270769461062802310452644218878789 | |
147 | 4657547771498634943677810376442740338273653974713864778784954384 | |
148 | 8959553753799042324106127132698432774571554630997720278101456108 | |
149 | 1188373709531016356324432987029563896628911658974769572087926928 | |
150 | 8712817800702651745077684107196243903943225364226052349458501299 | |
151 | 1857150124870696156814162535905669342381300885624924689156412677 | |
152 | 5654481886506593847951775360894005745238940335798476363944905313 | |
153 | 0623237490664450488246650759467358620746379251842004593696929810 | |
154 | 2226397195259719094521782333175693458150855233282076282002340262 | |
155 | 6907898342451712006207714640979456116127629145951237229913340169 | |
156 | 5523638509428855920187274337951730145863575708283557801587354327 | |
157 | 6888868012039988238470215146760544540766353598417443048012893831 | |
158 | 3896881639487469658817504506926365338175055478128640000000000000 | |
159 | 0000000000000000000000000000000000000000000000000000000000000000 | |
160 | 00000000000000000000000000000000000000000000000 | |
a0e07ba4 NJ |
161 | @end lisp |
162 | ||
c5d13061 NJ |
163 | The result is an example of Scheme's @emph{bignumbers}. However, there |
164 | are operating environments that provide (by default) too little stack | |
165 | space. They will instead produce an error message like this: | |
166 | ||
167 | @lisp | |
168 | (recursive-factorial 500) | |
169 | @print{} | |
170 | ERROR: Stack overflow | |
171 | ABORT: (stack-overflow) | |
172 | @end lisp | |
173 | ||
174 | Rather than enlarging the system's stack, we can implement the algorithm | |
175 | such that it does not consume increasing stack space. This is called a | |
176 | @emph{tail recursive} implementation. The following definition is tail | |
177 | recursive and so should work on all systems. | |
178 | ||
179 | @lisp | |
180 | (define (tail-recursive-factorial n) | |
181 | (define (loop k l) | |
182 | (if (zero? k) l | |
183 | (loop (- k 1) (* k l)))) | |
184 | (loop n 1)) | |
185 | ||
186 | (tail-recursive-factorial 500) | |
187 | @result{} 1220136825991110068701238785423046926253574342803192842192413588 | |
188 | ;; ... skipped | |
189 | @end lisp | |
a0e07ba4 NJ |
190 | |
191 | This is the most basic use of Guile: a simple Scheme interpreter. In | |
192 | the rest of this tutorial I will show you how Guile has many facets: it | |
193 | is also an @emph{extensible} interpreter (to which many features can be | |
194 | easilly added) and an @emph{embeddable} interpreter (which can be | |
195 | invoked from your C programs). | |
196 | ||
197 | ||
198 | @node Introduction | |
199 | @chapter Introduction | |
200 | ||
201 | @noindent | |
202 | @dfn{Guile} (which can stand for @emph{GNU Ubiquitous Intelligent | |
203 | Language Extension}) is the GNU extension language. It started out as | |
204 | an embeddable Scheme interpreter, and has rapidly evolved into a | |
205 | kitchen-sink package including a standalone Scheme interpreter, an | |
206 | embeddable Scheme interpreter, several graphics options, other languages | |
207 | that can be used along with Scheme (for now just @emph{ctax} and | |
208 | @emph{Tcl}), and hooks for much more. | |
209 | ||
210 | ||
211 | @menu | |
fab8ab31 TTN |
212 | * What are scripting and extension languages:: |
213 | * History of Guile and its motivations:: | |
214 | * How to characterize Guile:: | |
a0e07ba4 NJ |
215 | @end menu |
216 | ||
217 | @node What are scripting and extension languages | |
218 | @section What are scripting and extension languages | |
219 | @cindex scripting languages | |
220 | @cindex extension languages | |
221 | ||
222 | A @dfn{scripting language} is a programming language which serves as | |
223 | glue between other system programs. In the UNIX world, the traditional | |
224 | scripting language is the @emph{Bourne shell}, which allows many UNIX | |
225 | commands to be executed in sequence, or in a pipeline. Traditional UNIX | |
226 | commands are cleverly written to work well when put together in a | |
227 | script. | |
228 | ||
229 | Other examples of UNIX scripting languages are AWK, Perl, Scsh (the | |
230 | Scheme Shell: a Scheme interpreter enhanced to do good scripting), | |
231 | Python, Tcl, Java @dots{} | |
232 | @cindex scripting languages - examples | |
233 | ||
234 | UNIX programmers noticed, more than 25 years ago, that scripting | |
235 | languages can do serious work, so the Bourne shell was written to have | |
236 | variables, operators and control structures, just like a full-featured | |
237 | programming language. | |
238 | @cindex Bourne shell | |
239 | ||
240 | What scripting languages have, that traditional programming languages do | |
241 | not, is the ability to easily run an external program (or a pipeline of | |
242 | external programs) and use the returned values and output from that | |
243 | program in useful ways. | |
244 | ||
245 | An @dfn{extension language} is a programming language interpreter | |
246 | offered by an application program, so that users can write macros or | |
247 | even full-fledged programs to extend the original application. | |
248 | Extension languages have a C interface (it is usually C, but it could be | |
249 | any other compiled language), and can be given access to the C data | |
250 | structures. Likewise, there are C routines to access the extension | |
251 | language data structures. | |
252 | ||
253 | Extension languages abound in the software world, even though the name | |
254 | @emph{extension language} is seldom used. Examples are: | |
255 | @cindex extension languages - examples | |
256 | ||
257 | @itemize @bullet | |
258 | @item | |
259 | Emacs Lisp, the language used to program and customize GNU Emacs. | |
260 | @cindex Emacs Lisp | |
261 | ||
262 | @item | |
263 | Tcl, John Ousterhout's general-purpose scripting and extension language. | |
264 | @cindex Tcl | |
265 | ||
266 | @item | |
267 | The Lotus 1-2-3 macro language (any spreadsheet macro language, | |
268 | really). I mention this one first because it is a classic, even though | |
269 | it is seldom used any more. | |
270 | @cindex Lotus 1-2-3 | |
271 | ||
272 | @item | |
273 | Other spreadsheet and database macro languages. | |
274 | ||
275 | @item | |
276 | The Dominion empire-style game's @emph{exec} files. | |
277 | @cindex Dominion | |
278 | ||
279 | @item | |
280 | Any syntax for a ".*rc" file you might have used. Almost all programs | |
281 | end up parsing some kind of startup or configuration file. The syntax | |
282 | for those can get pretty involved, thus justifying calling them | |
283 | "extension languages". The @emph{fvwm} window manager, for example, | |
284 | parses a rather elaborate @file{.fvwmrc} file. | |
285 | ||
286 | @item | |
287 | Brent Benson's libscheme.a, an embeddable Scheme interpreter. | |
288 | @cindex Benson, Brent | |
289 | @cindex libscheme | |
290 | ||
291 | @item | |
292 | Guile, the GNU extension language, which is the subject of this | |
293 | tutorial. | |
294 | ||
295 | @end itemize | |
296 | ||
297 | One lesson we can learn from looking at classical large software | |
298 | applications is that "writers of large programs" always end up throwing | |
299 | in some kind of parser for configuration or scripting. | |
300 | ||
301 | Of the examples listed above, Emacs Lisp, Tcl, Libscheme and Guile have | |
302 | an important property: they are not added as an afterthought for a | |
303 | specific application. They are general-purpose languages which a user | |
304 | can learn (even in college courses) and then use to customize the | |
305 | application program. | |
306 | ||
307 | This is a recent and (in my opinion) very exciting direction in | |
308 | large-program software engineering: program designers can link in the | |
309 | Guile or Tcl library from the very beginning, and tell their users "You | |
310 | want to customize this program? Just use Scheme (or Tcl, or whatever | |
311 | language), which you already know!" | |
312 | @cindex large programs | |
313 | ||
314 | ||
315 | @node History of Guile and its motivations | |
316 | @section History of Guile and its motivations | |
317 | ||
318 | A few separate threads of events led to the development of Guile. | |
319 | ||
320 | In the fall of 1994, Richard Stallman, director of the GNU project, | |
321 | posted an article with the subject "Why you should not use Tcl", in | |
322 | which he argued that Tcl is inadequate as an extension language. This | |
323 | generated a flurry of flames (available in the hypermail archive | |
694a9bb3 | 324 | (@url{http://www.vanderburg.org/Tcl/war/}) @strong{The Tcl War}). |
a0e07ba4 NJ |
325 | @cindex Stallman, Richard |
326 | @cindex GNU project | |
327 | @cindex Tcl | |
328 | ||
329 | The result was that Stallman then proposed his design for the GNU | |
330 | Extension Language, first called GEL and then renamed Guile. The | |
331 | discussion triggered by that article is also available in a hypermail | |
694a9bb3 | 332 | archive, @url{http://www.vanderburg.org/Tcl/war2/}. |
a0e07ba4 NJ |
333 | |
334 | One interesting feature of this GNU Extension Language plan was that | |
335 | users should have a @emph{choice} of languages to use in extending their | |
336 | program. The basic language would be a slightly modified Scheme, and | |
337 | translators would be written to convert other languages (like Tcl, | |
338 | Python, Perl, C-like languages @dots{}) into Scheme. | |
339 | ||
340 | Tom Lord started working on this project immediately, taking Aubrey | |
341 | Jaffer's small and portable implementation of Scheme, SCM, and making it | |
342 | into an embeddable interpreter: callable from C and allowing new Scheme | |
343 | procedures to be written in C. | |
344 | @cindex Lord, Tom | |
345 | @cindex Jaffer, Aubrey | |
346 | ||
347 | In the spring of 1995, the guile-ii snapshot was released. This made it | |
348 | possible to start writing code in C and Scheme using the guile | |
349 | facilities. | |
350 | ||
351 | The guile-iii snapshot was released the summer of 1995, and it had fixed | |
352 | enough problems so that the access to Scheme data structures from C was | |
353 | almost complete. | |
354 | ||
355 | After this, Cygnus Support added many features to Guile and finished | |
356 | implementing others, so that Guile acquired thread support, a regular | |
357 | expression matcher, a Tk interface, an interface to the SGI OpenGL | |
358 | graphics system, an @emph{applet} formalism, and some other packages. | |
359 | This was all in the Cygnus Guile r0.3 and r0.4 releases. | |
360 | @cindex Cygnus Support | |
361 | ||
362 | Meanwhile, Tom Lord left the project after having produced a divergent | |
363 | version of Guile: 1.0b2. The Free Software Foundation hired Jim Blandy | |
364 | to coordinate Guile development. The FSF released its first version of | |
365 | Guile in January 1997. In the future, many of the Cygnus packages will | |
366 | be re-integrated into Guile. | |
367 | @cindex Blandy, Jim | |
368 | @cindex Free Software Foundation | |
369 | ||
370 | ||
371 | ||
372 | @node How to characterize Guile | |
373 | @section How to characterize Guile | |
374 | ||
375 | I have already mentioned that Guile has become a kitchen sink package; | |
376 | here you can see how Guile freely takes new commands and constructs from | |
377 | the portable Scheme library @emph{slib}, the @emph{Tk} widget set, a | |
378 | posix library (useful for UNIX systems programming), the regular | |
379 | expression library @emph{rx}, and many more @dots{} | |
380 | @cindex slib | |
381 | @cindex Tk | |
382 | @cindex POSIX | |
383 | @c @cindex OpenGL | |
384 | @cindex rx | |
385 | ||
386 | So Guile has many more primitive procedures available to it than those | |
387 | specified in @ref{Standard Procedures, Revised(5) Report on the | |
388 | Algorithmic Language Scheme, , r5rs, Revised(5) Report on the | |
389 | Algorithmic Language Scheme}. On top of that, Guile will interpret | |
390 | almost all standard Scheme programs. The only incompatible difference | |
391 | between the basic Guile language and R5RS Scheme is that Guile is case | |
392 | sensitive, whereas R5RS is case insensitive. We hope that few people | |
393 | have written Scheme programs that depend on case insensitivity. | |
394 | @cindex case sensitivity | |
395 | @cindex Revised(5) Report on the Algorithmic Language Scheme | |
396 | @cindex report on Scheme | |
397 | @cindex Scheme language - report | |
398 | @cindex Scheme language - definition | |
399 | ||
400 | Here is a possible view of the @emph{sum of the parts} in Guile: | |
401 | @cindex extensions to standard Scheme | |
402 | @cindex extensions to R5RS | |
403 | @cindex Scheme extensions | |
404 | @example | |
405 | guile = standard Scheme (R5RS) | |
406 | PLUS extensions to R5RS offered by SCM | |
407 | PLUS some extra primitives offered by Guile (catch/throw) | |
408 | PLUS portable Scheme library (SLIB) | |
409 | PLUS embeddable Scheme interpreter library (libguile) | |
410 | PLUS Tk toolkit | |
411 | PLUS threads | |
412 | PLUS Posix library | |
413 | @c PLUS OpenGL library (mesa) | |
414 | @c PLUS OpenGL toolkit (glut) | |
415 | PLUS Regular expression library (rx) | |
416 | @c PLUS Applet formalism | |
417 | PLUS Tcl library | |
418 | @end example | |
419 | ||
420 | ||
421 | @node Using Guile to program in Scheme | |
422 | @chapter Using Guile to program in Scheme | |
423 | @cindex Scheme programming tutorial | |
424 | @cindex tutorial on Scheme programming | |
425 | ||
426 | In this section I give a tutorial introduction to programming in Scheme, | |
427 | with a slant toward the interesting things that can be done in Guile. | |
428 | ||
429 | @c Applets are so @emph{chic} that they get their own section, but this | |
430 | This section will try to touch on many of the interesting and cool | |
431 | aspects of Guile, showing you how new types of problems can be solved | |
432 | with Guile. Note that using Guile as a library with @code{libguile.a} | |
433 | is described in its own chapter (@pxref{Guile in a Library}). Also note | |
434 | that some small examples are given in @ref{Jump Start}. | |
435 | ||
436 | To get started you need to know how to program in @dfn{Scheme} (a | |
437 | dialect of LISP). Fortunately Scheme is a small, clean language and is | |
438 | not hard to learn. It is also used in many undergraduate courses to | |
439 | introduce computer programming. | |
440 | @cindex lisp dialects | |
441 | ||
442 | I will not try to teach you Scheme here (although you might end up | |
443 | learning by example), since there are many good books on the subject, | |
444 | listed in @ref{Where to find more Guile/Scheme resources}. @footnote{To | |
445 | get started, look at the books @cite{Simply Scheme} and @cite{The Little | |
446 | Schemer} from that list.} | |
447 | ||
448 | ||
449 | @subsection Hello World | |
450 | @cindex hello world | |
451 | ||
452 | Our first program is the typical Scheme "hello world" program. Put the | |
453 | following code in a file called @code{hello.scm} (this can be find in | |
454 | @file{examples/scheme/hello.scm}). | |
455 | ||
456 | @smalllisp | |
457 | #!/usr/local/bin/guile -s | |
458 | !# | |
459 | ||
460 | (display "hello world") | |
461 | (newline) | |
462 | @end smalllisp | |
463 | ||
464 | Then run guile on it. One way to do so is to start up guile and load | |
465 | this file: | |
466 | ||
467 | @smallexample | |
468 | <shell-prompt> @kbd{guile} | |
469 | guile> @kbd{(load "hello")} | |
470 | @end smallexample | |
471 | ||
472 | Another way is to make the file executable and execute it directly. | |
473 | Notice how Guile recognizes a @code{-s} option which tells it to run a | |
474 | script and then exit. Guile also has a new type of block comment | |
475 | enclosed by @code{#!} and @code{!#}, so that you can make executable | |
476 | Scheme scripts with the standard UNIX @code{#!} mechanism. | |
477 | ||
478 | In the given example, the first line is used to invoke the Guile | |
479 | interpreter (make sure you correct the path if you installed Guile in | |
480 | something other than /usr/local/bin). Once Guile is invoked on this | |
481 | file, it will understand that the first line is a comment. The comment | |
482 | is then terminated with @code{!#} on the second line so as to not | |
483 | interfere with the execution mechanism. | |
484 | ||
485 | ||
486 | @subsection A bunch of operations in Scheme | |
487 | ||
488 | Here is some code you can type at the @code{guile>} prompt to see some | |
489 | of the Scheme data types at work (mostly lists and vectors). I have | |
490 | inserted brief comments @emph{before} each line of code explaining what | |
491 | happens. | |
492 | ||
493 | @smalllisp | |
494 | ;; @r{make a list and bind it to the symbol @code{ls}} | |
495 | guile> @kbd{(define ls (list 1 2 3 4 5 6 7))} | |
496 | @result{} | |
497 | ;; @r{display the list} | |
498 | guile> @kbd{ls} | |
fab8ab31 | 499 | @result{} (1 2 3 4 5 6 7) |
a0e07ba4 NJ |
500 | ;; @r{ask if @code{ls} is a vector; @code{#f} means it is not} |
501 | guile> @kbd{(vector? ls)} | |
fab8ab31 | 502 | @result{} #f |
a0e07ba4 NJ |
503 | ;; @r{ask if @code{ls} is a list; @code{#t} means it is} |
504 | guile> @kbd{(list? ls)} | |
fab8ab31 | 505 | @result{} #t |
a0e07ba4 NJ |
506 | ;; @r{ask for the length of @code{ls}} |
507 | guile> @kbd{(length ls)} | |
fab8ab31 | 508 | @result{} 7 |
a0e07ba4 NJ |
509 | ;; @r{pick out the first element of the list} |
510 | guile> @kbd{(car ls)} | |
fab8ab31 | 511 | @result{} 1 |
a0e07ba4 NJ |
512 | ;; @r{pick the rest of the list without the first element} |
513 | guile> @kbd{(cdr ls)} | |
fab8ab31 | 514 | @result{} (2 3 4 5 6 7) |
a0e07ba4 NJ |
515 | ;; @r{this should pick out the 3rd element of the list} |
516 | guile> @kbd{(car (cdr (cdr ls)))} | |
fab8ab31 | 517 | @result{} 3 |
a0e07ba4 NJ |
518 | ;; @r{a shorthand for doing the same thing} |
519 | guile> @kbd{(caddr ls)} | |
fab8ab31 | 520 | @result{} 3 |
a0e07ba4 NJ |
521 | ;; @r{append the given list onto @code{ls}, print the result} |
522 | ;; @r{@strong{NOTE:} the original list @code{ls} is @emph{not} modified} | |
523 | guile> @kbd{(append ls (list 8 9 10))} | |
fab8ab31 | 524 | @result{} (1 2 3 4 5 6 7 8 9 10) |
a0e07ba4 | 525 | guile> @kbd{(reverse ls)} |
5a825ad4 | 526 | @result{} (7 6 5 4 3 2 1) |
a0e07ba4 NJ |
527 | ;; @r{ask if 12 is in the list --- it obviously is not} |
528 | guile> @kbd{(memq 12 ls)} | |
fab8ab31 | 529 | @result{} #f |
a0e07ba4 NJ |
530 | ;; @r{ask if 4 is in the list --- returns the list from 4 on.} |
531 | ;; @r{Notice that the result will behave as true in conditionals} | |
532 | guile> @kbd{(memq 4 ls)} | |
fab8ab31 | 533 | @result{} (4 5 6 7) |
a0e07ba4 NJ |
534 | ;; @r{an @code{if} statement using the aforementioned result} |
535 | guile> @kbd{(if (memq 4 ls) | |
536 | (display "hey, it's true!\n") | |
537 | (display "dude, it's false\n"))} | |
538 | @print{hey, it's true!} | |
539 | @result{} | |
540 | guile> @kbd{(if (memq 12 ls) | |
541 | (display "hey, it's true!\n") | |
542 | (display "dude, it's false\n"))} | |
543 | @print{dude, it's false} | |
544 | @result{} | |
545 | guile> @kbd{(memq 4 (reverse ls))} | |
fab8ab31 | 546 | @result{} (4 3 2 1) |
a0e07ba4 NJ |
547 | ;; @r{make a smaller list @code{ls2} to work with} |
548 | guile> @kbd{(define ls2 (list 2 3 4))} | |
549 | ;; @r{make a list in which the function @code{sin} has been} | |
550 | ;; @r{applied to all elements of @code{ls2}} | |
551 | guile> @kbd{(map sin ls2)} | |
fab8ab31 | 552 | @result{} (0.909297426825682 0.141120008059867 -0.756802495307928) |
a0e07ba4 NJ |
553 | ;; @r{make a list in which the squaring function has been} |
554 | ;; @r{applied to all elements of @code{ls}} | |
5a825ad4 NJ |
555 | guile> @kbd{(map (lambda (n) (* n n)) ls)} |
556 | @result{} (1 4 9 16 25 36 49) | |
a0e07ba4 NJ |
557 | @end smalllisp |
558 | ||
559 | @smalllisp | |
560 | ;; @r{make a vector and bind it to the symbol @code{v}} | |
42ad901d | 561 | guile> @kbd{(define v '#(1 2 3 4 5 6 7))} |
a0e07ba4 | 562 | guile> @kbd{v} |
fab8ab31 | 563 | @result{} #(1 2 3 4 5 6 7) |
a0e07ba4 | 564 | guile> @kbd{(vector? v)} |
fab8ab31 | 565 | @result{} #t |
a0e07ba4 | 566 | guile> @kbd{(list? v)} |
fab8ab31 | 567 | @result{} #f |
a0e07ba4 | 568 | guile> @kbd{(vector-length v)} |
fab8ab31 | 569 | @result{} 7 |
a0e07ba4 NJ |
570 | ;; @r{vector-ref allows you to pick out elements by index} |
571 | guile> @kbd{(vector-ref v 2)} | |
fab8ab31 | 572 | @result{} 3 |
a0e07ba4 NJ |
573 | ;; @r{play around with the vector: make it into a list, reverse} |
574 | ;; @r{the list, go back to a vector and take the second element} | |
575 | guile> @kbd{(vector-ref (list->vector (reverse (vector->list v))) 2)} | |
fab8ab31 | 576 | @result{} 5 |
a0e07ba4 NJ |
577 | ;; @r{this demonstrates that the entries in a vector do not have} |
578 | ;; @r{to be of uniform type} | |
579 | guile> @kbd{(vector-set! v 4 "hi there")} | |
fab8ab31 | 580 | @result{} "hi there" |
a0e07ba4 | 581 | guile> @kbd{v} |
fab8ab31 | 582 | @result{} #(1 2 3 4 "hi there" 6 7) |
a0e07ba4 NJ |
583 | @end smalllisp |
584 | ||
585 | ||
586 | @subsection Using recursion to process lists | |
587 | @cindex recursion | |
588 | @cindex list processing | |
589 | ||
590 | Here are some typical examples of using recursion to process a list. | |
591 | ||
592 | @smalllisp | |
593 | ;; @r{this is a rather trivial way of reversing a list} | |
594 | (define (my-reverse l) | |
595 | (if (null? l) | |
596 | l | |
597 | (append (my-reverse (cdr l)) (list (car l))))) | |
598 | (my-reverse '(27 32 33 40)) | |
fab8ab31 | 599 | @result{} (40 33 32 27) |
a0e07ba4 NJ |
600 | @end smalllisp |
601 | ||
602 | ||
603 | @subsection Processing matrices | |
604 | ||
605 | Suppose you have a matrix represented as a list of lists: | |
606 | ||
607 | @smalllisp | |
608 | (define m | |
609 | (list | |
610 | (list 7 2 1 3 2 8 5 3 6) | |
611 | (list 4 1 1 1 3 8 9 8 1) | |
612 | (list 5 5 4 8 1 8 2 2 4))) | |
613 | @end smalllisp | |
614 | ||
615 | Then you could apply a certain function to each element of the matrix in | |
616 | the following manner: | |
617 | @smalllisp | |
618 | ;; @r{apply the function func to the matrix m element-by-element;} | |
619 | ;; @r{return a matrix with the result.} | |
620 | (define (process-matrix m func) | |
621 | (map (lambda (l) | |
622 | (map func l)) | |
623 | m)) | |
624 | @end smalllisp | |
625 | Notice that I have used the Scheme @code{map} procedure because I am | |
626 | interested in the matrix that results from the application of | |
627 | @code{func}, rather than in the side effects associated with applying | |
628 | @code{func}. | |
629 | ||
630 | This could be invoked with @code{(process-matrix m sin)} or | |
631 | @code{(process-matrix m (lambda (x) (* x x)))}; for example: | |
632 | ||
633 | @smalllisp | |
634 | (process-matrix m (lambda (x) (* x x))) | |
fab8ab31 | 635 | @result{} ((49 4 1 9 4 64 25 9 36) (16 1 1 1 9 64 81 64 1) (25 25 16 64 1 64 4 4 16)) |
a0e07ba4 NJ |
636 | @end smalllisp |
637 | ||
638 | To print a representation of the matrix, we could define a generalized | |
639 | routine: | |
640 | @smalllisp | |
641 | ;; @r{proc is a procedure to represent the single element,} | |
642 | ;; @r{row-proc is a procedure that is invoked after each row.} | |
643 | ;; @r{Example: proc could be (lambda (x) (begin (display x) (display " ")))} | |
644 | ;; @r{and row-proc could be (lambda (l) (display "\n"))} | |
645 | (define (represent-matrix m proc row-proc) | |
646 | (for-each (lambda (l) | |
647 | (begin | |
648 | (for-each proc l) | |
649 | (row-proc l))) | |
650 | m)) | |
651 | @end smalllisp | |
652 | @findex represent-matrix | |
653 | ||
654 | And then invoke it with | |
655 | @smalllisp | |
656 | (represent-matrix m | |
657 | (lambda (x) (begin (display x) (display " "))) | |
658 | (lambda (l) (begin (display "\n")))) | |
659 | @print{7 2 1 3 2 8 5 3 6} | |
660 | @print{4 1 1 1 3 8 9 8 1} | |
661 | @print{5 5 4 8 1 8 2 2 4} | |
662 | @end smalllisp | |
663 | ||
664 | @cindex objects | |
665 | ||
666 | Now we write a helper routine that uses Scheme @dfn{closures} to make | |
667 | objects with state that then receive messages to draw little squares. | |
668 | @cindex closures | |
669 | @cindex syntactic closures | |
670 | ||
671 | But let us take it one step at a time. I will start by showing you a | |
672 | simple example of object in Scheme. The object I make here represents a | |
673 | cell, which could be a cell in a matrix. The cell responds to commands | |
674 | to draw itself, to return the next cell, and so forth. @emph{Guile does | |
675 | not currently have a Tk interface, so I will leave the hooks for | |
676 | graphical rendering. In a future release of Guile I will add graphical | |
677 | rendering messages to the cell object.} | |
678 | ||
679 | @smallexample | |
680 | ;; @r{cell-object.scm: routines for creating and manipulating cell objects} | |
681 | ||
682 | ;; @r{(the-x, the-y) is the initial position of the cell.} | |
683 | ;; @r{the-color is a string representing a color; must be something Tk can grok.} | |
684 | ;; @r{square-size is the size of the square that gets drawn.} | |
685 | ;; @r{(sizex, sizey) is the size of the matrix.} | |
686 | (define (MAKE-CELL the-x the-y the-color square-size sizex sizey) | |
687 | (define (get-x) the-x) | |
688 | (define (get-y) the-y) | |
689 | ||
690 | (define (set-x! new-x) | |
691 | (set! the-x new-x) | |
692 | the-x) | |
693 | (define (set-y! new-y) | |
694 | (set! the-y new-y) | |
695 | the-y) | |
696 | (define (get-color) the-color) | |
697 | (define (set-color! new-color) | |
698 | (set! the-color new-color) | |
699 | the-color) | |
700 | (define (next!) | |
701 | (set! the-x (+ the-x 1)) | |
702 | (if (>= the-x sizex) | |
703 | (begin | |
704 | (set! the-x 0) | |
705 | (set! the-y (+ the-y 1)))) | |
706 | (if (>= the-y sizey) | |
707 | (begin | |
708 | (display "CELL next!: value of y is too big; not changing it\n") | |
709 | (set! the-y (- the-y 1)))) | |
710 | (cons the-x the-y)) | |
711 | (define (draw) | |
712 | (let* ((x0 (* the-x square-size)) | |
713 | (y0 (* the-y square-size)) | |
714 | (x1 (+ x0 square-size)) | |
715 | (y1 (+ y0 square-size))) | |
716 | (display "I should draw a ") | |
717 | (display the-color) | |
718 | (display " rectangle with corners at ") | |
719 | (display x0) (display y0) (display x1) (display y1) | |
720 | )) | |
721 | ||
722 | ;; self is the dispatch procedure | |
723 | (define (self message) | |
724 | (case message | |
725 | ((x) get-x) | |
726 | ((y) get-y) | |
727 | ((set-x!) set-x!) | |
728 | ((set-y!) set-y!) | |
729 | ((color) get-color) | |
730 | ((set-color!) set-color!) | |
731 | ((next!) next!) | |
732 | ((draw) draw) | |
733 | (else (error "CELL: Unknown message -> " message)))) | |
734 | ;; and now return the dispatch procedure | |
735 | self | |
736 | ) | |
737 | @end smallexample | |
738 | @cindex cell-object | |
739 | @findex MAKE-CELL | |
740 | ||
741 | What does this procedure do? It returns another procedure | |
742 | (@code{self}) which receives a message (x, y, set-x!, set-y!, @dots{}) | |
743 | and takes an action to return or modify its state. The state consists | |
744 | of the values of variables @code{the-x}, @code{the-y}, @code{the-color} | |
745 | and so forth. | |
746 | ||
747 | Here are some examples of how to use MAKE-CELL and the cell object it | |
748 | creates: | |
749 | @smallexample | |
750 | (define c (MAKE-CELL 0 0 "red" 10 7 9)) | |
751 | ||
752 | ;; @r{retrieve the x and y coordinates} | |
753 | ((c 'x)) | |
fab8ab31 | 754 | @result{} 0 |
a0e07ba4 | 755 | ((c 'y)) |
fab8ab31 | 756 | @result{} 0 |
a0e07ba4 NJ |
757 | ;; @r{change the x coordinate} |
758 | ((c 'set-x!) 5) | |
fab8ab31 | 759 | @result{} 5 |
a0e07ba4 | 760 | ((c 'x)) |
fab8ab31 | 761 | @result{} 5 |
a0e07ba4 NJ |
762 | ;; @r{change the color} |
763 | ((c 'color)) | |
fab8ab31 | 764 | @result{} "red" |
a0e07ba4 | 765 | ((c 'set-color!) "green") |
fab8ab31 | 766 | @result{} "green" |
a0e07ba4 | 767 | ((c 'color)) |
fab8ab31 | 768 | @result{} "green" |
a0e07ba4 NJ |
769 | ;; @r{now use the next! message to move to the next cell} |
770 | ((c 'next!)) | |
fab8ab31 | 771 | @result{} (6 . 0) |
a0e07ba4 | 772 | ((c 'x)) |
fab8ab31 | 773 | @result{} 6 |
a0e07ba4 | 774 | ((c 'y)) |
fab8ab31 | 775 | @result{} 0 |
a0e07ba4 NJ |
776 | ;; @r{now make things wrap around} |
777 | ((c 'next!)) | |
fab8ab31 | 778 | @result{} (0 . 1) |
a0e07ba4 | 779 | ((c 'next!)) |
fab8ab31 | 780 | @result{} (1 . 1) |
a0e07ba4 | 781 | ((c 'next!)) |
fab8ab31 | 782 | @result{} (2 . 1) |
a0e07ba4 | 783 | ((c 'x)) |
fab8ab31 | 784 | @result{} 2 |
a0e07ba4 | 785 | ((c 'y)) |
fab8ab31 | 786 | @result{} 1 |
a0e07ba4 NJ |
787 | @end smallexample |
788 | ||
789 | You will notice that expressions like @code{(c 'next)} return procedures | |
790 | that do the job, so we have to use extra parentheses to make the job | |
791 | happen. This syntax is rather awkward; one way around it is to define a | |
792 | @code{send} procedure: | |
793 | ||
794 | @smallexample | |
795 | ;; @r{send makes object syntax a bit easier; instead of saying} | |
796 | ;; @r{ ((my-cell 'set-x!) 4)} | |
797 | ;; @r{you can say} | |
798 | ;; @r{ (send my-cell 'set-x! 4)} | |
799 | (define (send obj . args) | |
800 | (let ((first-eval (apply obj (list (car args))))) | |
801 | (if (null? (cdr args)) | |
802 | (first-eval) | |
803 | (apply first-eval (cdr args))))) | |
804 | @end smallexample | |
805 | @findex send | |
806 | ||
807 | You can see that @code{send} passes the message to the object, making | |
808 | sure that things are evaluated the proper number of times. You can now | |
809 | type: | |
810 | ||
811 | @smallexample | |
812 | (define c2 (MAKE-CELL 0 0 "red" 10 7 9)) | |
813 | (send c2 'x) | |
fab8ab31 | 814 | @result{} 0 |
a0e07ba4 | 815 | (send c2 'set-x! 5) |
fab8ab31 | 816 | @result{} 5 |
a0e07ba4 | 817 | (send c2 'color) |
fab8ab31 | 818 | @result{} "red" |
a0e07ba4 | 819 | (send c2 'set-color! "green") |
fab8ab31 | 820 | @result{} "green" |
a0e07ba4 | 821 | (send c2 'next!) |
fab8ab31 | 822 | @result{} (1 . 0) |
a0e07ba4 | 823 | (send c2 'x) |
fab8ab31 | 824 | @result{} 1 |
a0e07ba4 | 825 | (send c2 'y) |
fab8ab31 | 826 | @result{} 0 |
a0e07ba4 NJ |
827 | @end smallexample |
828 | ||
829 | @cindex object-based programming | |
830 | @cindex object-oriented programming | |
831 | ||
832 | This is the simplest way of implementing objects in Scheme, but it does | |
833 | not really allow for full @emph{object-oriented programming} (for | |
834 | example, there is no inheritance). But it is useful for | |
835 | @emph{object-based programming}. | |
836 | ||
837 | Guile comes with a couple more complete object-oriented extensions to | |
838 | Scheme: these are part of slib (@pxref{Object, , , slib, SLIB: the | |
839 | portable Scheme library} and @pxref{Yasos, , , slib, SLIB: the portable | |
840 | Scheme library}). | |
841 | ||
842 | @node Guile in a Library | |
843 | @chapter Guile in a Library | |
844 | ||
845 | @iftex | |
846 | @nobreak | |
847 | @end iftex | |
848 | In the previous chapters Guile was used to write programs entirely in | |
849 | Scheme, and no C code was seen; but I have been claiming @emph{ad | |
850 | nauseam} that Guile is an @emph{extension} language. Here we see how | |
851 | that is done, and how that can be useful. | |
852 | @cindex libguile | |
853 | @cindex extending C programs | |
854 | ||
855 | ||
856 | @menu | |
fab8ab31 TTN |
857 | * Two world views:: |
858 | * What is libguile:: | |
859 | * How to get started with libguile:: | |
860 | * More interesting programming with libguile:: | |
861 | * Further examples:: | |
a0e07ba4 NJ |
862 | @end menu |
863 | ||
864 | @node Two world views | |
865 | @section Two world views | |
866 | @cindex master world | |
867 | ||
868 | In this manual, I usually jump into examples and explain them as you | |
869 | type in the code; here I will digress and ramble for a few paragraphs to | |
870 | set some concepts straight, and then let you type (or paste) in fun | |
871 | examples. | |
872 | ||
873 | In 1995, I implemented a large program, @dfn{Gnudl}, using Guile quite | |
874 | extensively. In the design phase of Gnudl, I found I had to make a | |
875 | choice: should the fundamental data structures be C or Scheme data | |
876 | structures? | |
877 | @cindex gnudl | |
878 | @cindex GNU Data Language | |
879 | @cindex Galassi, Mark | |
880 | ||
881 | Guile allows C to see its data structures (scalar types, lists, vectors, | |
882 | strings @dots{}). C also allows Guile to see its data structures. As a | |
883 | large program designer, you have to decide which of those capabilities | |
884 | to use. You have two main choices: | |
885 | ||
886 | @enumerate 1 | |
887 | @item | |
888 | You can write your software mostly in Scheme. In this case, your C | |
889 | software will mostly parse the Scheme code with Guile calls, and provide | |
890 | some new primitive procedures to be used by Scheme. This is what Gnudl | |
891 | does. | |
892 | ||
893 | @item | |
894 | You can write your software mostly in C, occasionally allowing Scheme | |
895 | code to be parsed by Guile, either to allow the user to modify data | |
896 | structures, or to parse a configuration file, @dots{} | |
897 | @end enumerate | |
898 | ||
899 | Mixing the two approaches seems unwise: the overall layout would be | |
900 | confusing. But who knows? There might be problems that are best solved | |
901 | by a hybrid approach. Please let me know if you think of such a | |
902 | problem. | |
903 | ||
904 | If you use the former approach, we will say that the @dfn{master world} | |
905 | is Scheme, and the C routines serve Scheme and access Scheme data | |
906 | structures. In the latter case, the master world is C, and Scheme | |
907 | routines serve the C code and access C data structures. | |
908 | ||
909 | In both approaches the @code{libguile.a} library is the same, but a | |
910 | predominantly different set of routines will be used. When we go | |
911 | through examples of libguile use, we will point out which is the master | |
912 | world in order to clarify these two approaches. | |
913 | ||
914 | ||
915 | @node What is libguile | |
916 | @section What is libguile | |
917 | @cindex libguile | |
918 | @cindex gh interface | |
919 | @cindex scm interface | |
920 | ||
921 | @dfn{Libguile} is the library which allows C programs to start a Scheme | |
922 | interpreter and execute Scheme code. There are also facilities in | |
923 | libguile to make C data structures available to Scheme, and vice versa. | |
924 | ||
925 | The interface provided by the libguile C library is somewhat specific to | |
926 | the implementation of the Scheme interpreter. This low-level libguile | |
927 | interface is usually referred to as the @code{scm_} interface, since its | |
928 | public calls (API) all have the @code{scm_} prefix. | |
929 | ||
930 | There is also a higher-level libguile interface, which is usually | |
931 | referred to as the @code{gh_} interface (libGuile High). Its public | |
932 | calls all have the @code{gh_} prefix. The @code{gh_} library interface | |
933 | is designed to hide the implementation details, thus making it easier to | |
934 | assimilate and portable to other underlying Scheme implementations. | |
935 | ||
936 | People extending Guile by adding bindings to C libraries (like OpenGL or | |
937 | Rx) are encouraged to use the @code{gh_} interface, so their work will | |
938 | be portable to other Scheme systems. The @code{gh_} interface should be | |
939 | more stable, because it is simpler. | |
940 | ||
941 | The @code{scm_} interface is necessary if you want to poke into the | |
942 | innards of Scheme data structures, or do anything else that is not | |
943 | offered by the @code{gh_} interface. It is not covered in this | |
944 | tutorial, but is covered extensively in @ref{Scheme data representation, | |
945 | Guile Reference Manual, guile-ref, Guile Reference Manual}. | |
946 | ||
947 | This chapter gives a gentle introduction to the @code{gh_} interface, | |
948 | presenting some @emph{hello world}-style programs which I wrote while | |
949 | teaching myself to use libguile. | |
950 | @cindex hello world | |
951 | ||
952 | The @cite{Guile Programmer's Manual} gives more examples of programs | |
953 | written using libguile, illustrating diverse applications. You can also | |
954 | consult my @emph{Gnudl} documentation at | |
955 | @url{http://nis-www.lanl.gov/~rosalia/mydocs/} to see a large scale | |
956 | project that uses C and Scheme code together. | |
957 | ||
958 | ||
959 | @node How to get started with libguile | |
960 | @section How to get started with libguile | |
961 | @cindex learn0 | |
962 | ||
963 | Here is an elementary first program, @code{learn0}, to get going with | |
964 | libguile. The program (which uses Scheme as a master world) is in a | |
965 | single source file, @code{learn0.c}: | |
966 | ||
967 | @smallexample | |
968 | /* @r{test the new libgh.a (Guile High-level library) with a trivial | |
969 | program} */ | |
970 | ||
971 | #include <stdio.h> | |
972 | ||
973 | #include <guile/gh.h> | |
974 | ||
975 | void main_prog(int argc, char *argv[]); | |
976 | ||
977 | main(int argc, char *argv[]) | |
978 | @{ | |
979 | gh_enter(argc, argv, main_prog); | |
980 | @} | |
981 | ||
982 | void main_prog(int argc, char *argv[]) | |
983 | @{ | |
984 | int done; | |
985 | char input_str[200]; | |
986 | ||
987 | gh_eval_str("(display \"hello Guile\")"); | |
988 | gh_eval_str("(newline)"); | |
989 | ||
990 | /* @r{for fun, evaluate some simple Scheme expressions here} */ | |
991 | gh_eval_str("(define (square x) (* x x))"); | |
992 | gh_eval_str("(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))"); | |
993 | gh_eval_str("(square 9)"); | |
994 | ||
995 | /* @r{now sit in a Scheme eval loop: I input the expressions, have | |
996 | Guile evaluate them, and then get another expression.} */ | |
997 | done = 0; | |
998 | fputs("learn0> ", stdout); | |
999 | while (fgets(input_str, 199, stdin) != NULL) @{ | |
1000 | gh_eval_str(input_str); | |
1001 | fputs("\nlearn0> ", stdout); | |
1002 | @} | |
1003 | ||
1004 | exit(0); | |
1005 | @} | |
1006 | @end smallexample | |
1007 | ||
1008 | If you name this program @code{learn0.c}, it can now be compiled with: | |
1009 | @smallexample | |
1010 | gcc -g -c learn0.c -o learn0.o | |
1011 | gcc -o learn0 learn0.o -lguile -lm | |
1012 | @end smallexample | |
1013 | ||
1014 | @c @emph{NOTE: If you are in the Guile development tree, you can simply do | |
1015 | @c ``cd doc/examples/c; make; ./learn0''.} | |
1016 | ||
1017 | The program is simple: it creates a Scheme interpreter, passes a couple | |
1018 | of strings to it that define new Scheme functions @code{square} and | |
1019 | @code{factorial}, and then a couple of strings that invoke those | |
1020 | functions. | |
1021 | ||
1022 | It then goes into a read-eval-print-loop (REPL), so you could type | |
1023 | one-line Scheme expressions to it and have them evaluated. For example: | |
1024 | @smallexample | |
1025 | <shell-prompt> ./learn0 | |
1026 | hello Guile | |
1027 | learn0> (display (sin 1.3)) | |
1028 | 963.558185417193e-3 | |
1029 | learn0> (display (fact 10)) | |
1030 | 3628800 | |
1031 | learn0> (quit) | |
1032 | <shell-prompt> | |
1033 | @end smallexample | |
1034 | ||
1035 | You should notice the key steps involved in this @code{learn0} program: | |
1036 | ||
1037 | @cartouche | |
1038 | @enumerate | |
1039 | @item | |
1040 | @code{#include <guile/gh.h>} | |
1041 | @item | |
1042 | You need to invoke the initialization routine @code{gh_enter()}. This | |
1043 | starts up a Scheme interpreter, handling many implementation-specific | |
1044 | details. | |
1045 | @item | |
1046 | Your main() function should be almost empty: the real main program goes | |
1047 | in a separate function main_prog() which is passed to gh_enter(). This | |
1048 | rather arcane convention is due to the way Guile's garbage collector | |
1049 | works: the whole program has to run in the dynamic context of | |
1050 | @code{gh_enter()}. | |
1051 | @item | |
1052 | You pass strings to the Scheme interpreter with the @code{gh_eval_str()} | |
1053 | routine. | |
1054 | @item | |
1055 | You link your program with @code{-lguile}. | |
1056 | @end enumerate | |
1057 | @end cartouche | |
1058 | ||
1059 | ||
1060 | @node More interesting programming with libguile | |
1061 | @section More interesting programming with libguile | |
1062 | @cindex learn1 | |
1063 | @cindex callback | |
1064 | @cindex builtin functions | |
1065 | ||
1066 | The @code{learn0} program shows how you can invoke Scheme commands from | |
1067 | a C program. This is not such a great achievement: the same could have | |
1068 | been done by opening a pipe to SCM or any other Scheme interpreter. | |
1069 | ||
1070 | A true extension language must allow @dfn{callbacks}. Callbacks allow | |
1071 | you to write C routines that can be invoked as Scheme procedures, thus | |
1072 | adding new primitive procedures to Scheme. This also means that a | |
1073 | Scheme procedure can modify a C data structure. | |
1074 | ||
1075 | Guile allows you to define new Scheme procedures in C, and provides a | |
1076 | mechanism to go back and forth between C and Scheme data types. | |
1077 | ||
1078 | Here is a second program, @code{learn1}, which demonstrates these | |
1079 | features. It is split into three source files: @code{learn1.c}, | |
1080 | @code{c_builtins.h} and @code{c_builtins.c}. I am including the code | |
1081 | here. | |
1082 | @c , but you might just want to look at the online source code and the | |
1083 | @c Makefile.am that come with Guile in the | |
1084 | @c @file{doc/examples/c} directory. | |
1085 | ||
1086 | Notice that @code{learn1} uses a Scheme master world, and the C routines | |
1087 | in @code{c_builtins.c} are simply adding new primitives to Scheme. | |
1088 | ||
1089 | @menu | |
fab8ab31 TTN |
1090 | * learn1.c:: |
1091 | * c_builtins.h:: | |
1092 | * c_builtins.c:: | |
1093 | * What learn1 is doing:: | |
1094 | * Compiling and running learn1:: | |
a0e07ba4 NJ |
1095 | @end menu |
1096 | ||
1097 | @node learn1.c | |
1098 | @subsection learn1.c | |
1099 | ||
1100 | Here is @file{learn1.c}: | |
1101 | @smallexample | |
1102 | #include <stdio.h> | |
1103 | ||
1104 | #include <guile/gh.h> | |
1105 | ||
1106 | #include "c_builtins.h" | |
1107 | ||
1108 | void main_prog(int argc, char *argv[]); | |
1109 | ||
1110 | main(int argc, char *argv[]) | |
1111 | @{ | |
1112 | gh_enter(argc, argv, main_prog); | |
1113 | @} | |
1114 | ||
1115 | void main_prog(int argc, char *argv[]) | |
1116 | @{ | |
1117 | char input_str[200]; /* @r{ugly hack: assume strlen(line) < 200} */ | |
1118 | int done; | |
1119 | ||
1120 | /* @r{for fun, evaluate some simple Scheme expressions here} */ | |
1121 | gh_eval_str("(define (square x) (* x x))"); | |
1122 | gh_eval_str("(define (fact n) (if (= n 1) 1 (* n (fact (- n 1)))))"); | |
1123 | gh_eval_str("(square 9)"); | |
1124 | gh_eval_str("(fact 100)"); | |
1125 | ||
1126 | /* @r{now try to define some new builtins, coded in C, so that they are | |
1127 | available in Scheme.} */ | |
1128 | gh_new_procedure1_0("c-factorial", c_factorial); | |
1129 | gh_new_procedure1_0("c-sin", c_sin); | |
1130 | gh_new_procedure1_0("v-t", vector_test); | |
1131 | ||
1132 | /* @r{now sit in a Scheme eval loop: I input the expressions, have | |
1133 | Guile evaluate them, and then get another expression.} */ | |
1134 | done = 0; | |
1135 | fputs("learn1> ", stdout); | |
1136 | while (!done) @{ | |
1137 | if (gets(input_str) == NULL) @{ | |
1138 | done = 1; | |
1139 | @} else @{ | |
1140 | gh_eval_str(input_str); | |
1141 | fputs("learn1> ", stdout); | |
1142 | @} | |
1143 | @} | |
1144 | ||
1145 | exit(0); | |
1146 | @} | |
1147 | @end smallexample | |
1148 | ||
1149 | @node c_builtins.h | |
1150 | @subsection c_builtins.h | |
1151 | ||
1152 | Here is @file{c_builtins.h}: | |
1153 | @smallexample | |
1154 | /* @r{builtin function prototypes} */ | |
1155 | ||
1156 | #include <guile/gh.h> | |
1157 | ||
1158 | SCM c_factorial(SCM n); | |
1159 | SCM c_sin(SCM n); | |
1160 | SCM vector_test(SCM s_length); | |
1161 | @end smallexample | |
1162 | ||
1163 | @node c_builtins.c | |
1164 | @subsection c_builtins.c | |
1165 | ||
1166 | Here is @file{c_builtins.c}: | |
1167 | @smallexample | |
1168 | #include <stdio.h> | |
1169 | #include <math.h> | |
1170 | ||
1171 | #include <guile/gh.h> | |
1172 | ||
1173 | #include "c_builtins.h" | |
1174 | ||
1175 | /* @r{this is a factorial routine in C, made to be callable by Scheme} */ | |
1176 | SCM c_factorial(SCM s_n) | |
1177 | @{ | |
1178 | int i; | |
1179 | unsigned long result = 1, n; | |
1180 | ||
1181 | n = gh_scm2ulong(s_n); | |
1182 | ||
1183 | gh_defer_ints(); | |
1184 | for (i = 1; i <= n; ++i) @{ | |
1185 | result = result*i; | |
1186 | @} | |
1187 | gh_allow_ints(); | |
1188 | return gh_ulong2scm(result); | |
1189 | @} | |
1190 | ||
1191 | /* @r{a sin routine in C, callable from Scheme. it is named c_sin() to | |
1192 | distinguish it from the default Scheme sin function} */ | |
1193 | SCM c_sin(SCM s_x) | |
1194 | @{ | |
1195 | double x = gh_scm2double(s_x); | |
1196 | ||
1197 | return gh_double2scm(sin(x)); | |
1198 | @} | |
1199 | ||
1200 | /* @r{play around with vectors in Guile: this routine creates a vector of | |
1201 | the given length, initializes it all to zero except element 2 which | |
1202 | is set to 1.9.} */ | |
1203 | SCM vector_test(SCM s_length) | |
1204 | @{ | |
1205 | SCM xvec; | |
1206 | ||
1207 | c_length = gh_scm2ulong(s_length); | |
1208 | printf("requested length for vector: %ld\n", gh_scm2ulong(s_length)); | |
1209 | ||
1210 | /* create a vector */ | |
1211 | xvec = gh_make_vector(s_length, gh_double2scm(0.0)); | |
1212 | /* set the second element in it */ | |
1213 | gh_vector_set_x(xvec, gh_int2scm(2), gh_double2scm(1.9)); | |
1214 | ||
1215 | return xvec; | |
1216 | @} | |
1217 | @end smallexample | |
1218 | ||
1219 | @node What learn1 is doing | |
1220 | @subsection What learn1 is doing | |
1221 | @cindex registering callbacks | |
1222 | @cindex registering C functions | |
1223 | @cindex primitive procedures | |
1224 | ||
1225 | If you compare learn1 to learn0, you will find that learn1 uses a new | |
1226 | Guile construct: the function @code{gh_new_procedure()}, and its | |
1227 | siblings: | |
1228 | ||
1229 | @smallexample | |
1230 | /* @r{now try to define some new builtins, coded in C, so that they are | |
1231 | available in Scheme.} */ | |
1232 | gh_new_procedure1_0("c-factorial", c_factorial); | |
1233 | gh_new_procedure1_0("c-sin", c_sin); | |
1234 | gh_new_procedure1_0("v-t", vector_test); | |
1235 | @end smallexample | |
1236 | ||
1237 | It is clear that @code{gh_new_procedure()} adds a new builtin | |
1238 | routine written in C which can be invoked from Scheme. We can now | |
1239 | revise our checklist for programming with libguile, so it includes | |
1240 | adding callbacks. | |
1241 | @cindex libguile - step by step | |
1242 | ||
1243 | @cartouche | |
1244 | @enumerate | |
1245 | @item | |
1246 | @code{#include <guile/gh.h>} | |
1247 | @item | |
1248 | You need to invoke the initialization routine @code{gh_enter()}. This | |
1249 | starts up a Scheme interpreter, handling many details. | |
1250 | @item | |
1251 | Your main() function should be almost empty: the real main program goes | |
1252 | in a separate function main_prog() which is passed to gh_enter(). This | |
1253 | rather arcane convention is due to the way Guile's garbage collector | |
1254 | works: the whole program has to run in the dynamic context of | |
1255 | @code{gh_enter()}. | |
1256 | @item | |
1257 | You pass strings to the Scheme interpreter with the @code{gh_eval_str()} | |
1258 | routine. | |
1259 | @item | |
1260 | @strong{[new]} You can now define new builtin Scheme functions; | |
1261 | i.e. define new builtin Scheme functions, with the | |
1262 | @code{gh_new_procedure()} routine. | |
1263 | @item | |
1264 | You pass strings to the Scheme interpreter with the | |
1265 | @code{gh_eval_str()} routine. | |
1266 | @item | |
1267 | You link your program with @code{-lguile}. | |
1268 | @end enumerate | |
1269 | @end cartouche | |
1270 | ||
1271 | I breezed by the issue of how to write your C routines that are | |
1272 | registered to be called from Scheme. This is non-trivial, and is | |
1273 | discussed at length in the @cite{Guile Programmer's Manual}. | |
1274 | ||
1275 | ||
1276 | @node Compiling and running learn1 | |
1277 | @subsection Compiling and running learn1 | |
1278 | ||
1279 | @smallexample | |
1280 | gcc -g -c learn1.c -o learn1.o | |
1281 | gcc -g -c c_builtins.c -o c_builtins.o | |
1282 | gcc -o learn1 learn1.o c_builtins.o -lguile -lm | |
1283 | @end smallexample | |
1284 | ||
1285 | If you run @code{learn1}, it will prompt you for a one-line Scheme | |
1286 | expression, just as @code{learn0} did. The difference is that you can | |
1287 | use the new C builtin procedures (@code{c-factorial}, @code{c-sin}, | |
1288 | @code{v-t}). | |
1289 | ||
1290 | @smallexample | |
1291 | <shell-prompt> ./learn1 | |
1292 | welcome to Guile | |
1293 | hello Guile | |
1294 | learn1> (display (c-factorial 6)) | |
1295 | 720 | |
1296 | learn1> (display (c-factorial 20)) | |
1297 | 2192834560 | |
1298 | learn1> (display (c-factorial 100)) | |
1299 | 0 | |
1300 | learn1> (display (c-sin 1.5)) | |
1301 | 0.997494986604054 | |
1302 | learn1> (display (v-t 10)) | |
1303 | requested length for vector: 10 | |
1304 | #(0.0 0.0 1.9 0.0 0.0 0.0 0.0 0.0 0.0 0.0) | |
1305 | learn1> (display (v-t 15)) | |
1306 | requested length for vector: 15 | |
1307 | #(0.0 0.0 1.9 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0) | |
1308 | learn1> (quit) | |
1309 | <shell-prompt> | |
1310 | @end smallexample | |
1311 | ||
1312 | As you see, taking @code{(c-factorial 100)} does not use bignumbers and | |
1313 | returns a bogus answer. | |
1314 | ||
1315 | @node Further examples | |
1316 | @section Further examples | |
1317 | ||
1318 | Further ``idealized'' examples are included in the @code{doc/examples/c} | |
1319 | distribution. They include programs to: | |
1320 | ||
1321 | @c [FIXME: still have to write some of these; then I will revise the list.] | |
1322 | ||
1323 | @itemize @bullet | |
1324 | @item | |
1325 | Parse a startup file (C is the master world). | |
1326 | @item | |
1327 | Set up initial conditions for an n-body simulation (C is the master | |
1328 | world). | |
1329 | @item | |
1330 | Implement a Scheme interpreter with all of Guile's goodies, @emph{plus} | |
1331 | the readline library @emph{and} a fast Fourier transform routine | |
1332 | provided in C (Scheme is the master world). | |
1333 | @end itemize | |
1334 | ||
1335 | @node Regular Expression Support | |
1336 | @chapter Regular Expression Support | |
1337 | ||
1338 | @node UNIX System Programming | |
1339 | @chapter UNIX System Programming | |
1340 | ||
1341 | @node Where to find more Guile/Scheme resources | |
1342 | @chapter Where to find more Guile/Scheme resources | |
1343 | ||
1344 | ||
1345 | @node Concept Index | |
1346 | @unnumbered Concept Index | |
1347 | ||
1348 | @printindex cp | |
1349 | ||
1350 | @node Procedure and Macro Index | |
1351 | @unnumbered Procedure and Macro Index | |
1352 | ||
1353 | This is an alphabetical list of all the procedures and macros in Dominion. | |
1354 | ||
1355 | @printindex fn | |
1356 | ||
1357 | @node Variable Index | |
1358 | @unnumbered Variable Index | |
1359 | ||
1360 | This is an alphabetical list of the major global variables in Dominion. | |
1361 | ||
1362 | @printindex vr | |
1363 | ||
1364 | @node Type Index | |
1365 | @unnumbered Type Index | |
1366 | ||
1367 | This is an alphabetical list of the major data structures in Dominion. | |
1368 | ||
1369 | @printindex tp | |
1370 | ||
1371 | @contents | |
1372 | ||
1373 | @bye |