Commit | Line | Data |
---|---|---|
2da09c3f MV |
1 | @c -*-texinfo-*- |
2 | @c This is part of the GNU Guile Reference Manual. | |
3 | @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004 | |
4 | @c Free Software Foundation, Inc. | |
5 | @c See the file guile.texi for copying conditions. | |
6 | ||
9401323e | 7 | @page |
226297eb NJ |
8 | @node Programming Overview |
9 | @chapter An Overview of Guile Programming | |
10 | ||
11 | Guile is designed as an extension language interpreter that is | |
12 | straightforward to integrate with applications written in C (and C++). | |
13 | The big win here for the application developer is that Guile | |
14 | integration, as the Guile web page says, ``lowers your project's | |
15 | hacktivation energy.'' Lowering the hacktivation energy means that you, | |
16 | as the application developer, @emph{and your users}, reap the benefits | |
17 | that flow from being able to extend the application in a high level | |
18 | extension language rather than in plain old C. | |
19 | ||
1982a56a NJ |
20 | In abstract terms, it's difficult to explain what this really means and |
21 | what the integration process involves, so instead let's begin by jumping | |
22 | straight into an example of how you might integrate Guile into an | |
23 | existing program, and what you could expect to gain by so doing. With | |
24 | that example under our belts, we'll then return to a more general | |
25 | analysis of the arguments involved and the range of programming options | |
26 | available. | |
27 | ||
28 | @menu | |
29 | * Extending Dia:: How one might extend Dia using Guile. | |
30 | * Scheme vs C:: Why Scheme is more hackable than C. | |
31 | * Testbed Example:: Example: using Guile in a testbed. | |
32 | * Programming Options:: Options for Guile programming. | |
33 | * User Programming:: How about application users? | |
34 | @end menu | |
35 | ||
36 | ||
37 | @node Extending Dia | |
38 | @section How One Might Extend Dia Using Guile | |
39 | ||
40 | Dia is a free software program for drawing schematic diagrams like flow | |
41 | charts and floor plans (REFFIXME). This section conducts the thought | |
42 | experiment of adding Guile to Dia. In so doing, it aims to illustrate | |
43 | several of the steps and considerations involved in adding Guile to | |
44 | applications in general. | |
45 | ||
46 | @menu | |
47 | * Dia Objective:: Deciding why you want to add Guile. | |
48 | * Dia Steps:: Four steps required to add Guile. | |
49 | * Dia Smobs:: How to represent Dia data in Scheme. | |
50 | * Dia Primitives:: Writing Guile primitives for Dia. | |
51 | * Dia Hook:: Providing a hook for Scheme evaluation. | |
52 | * Dia Structure:: Overall structure for adding Guile. | |
53 | * Dia Advanced:: Going further with Dia and Guile. | |
54 | @end menu | |
55 | ||
56 | ||
57 | @node Dia Objective | |
58 | @subsection Deciding Why You Want to Add Guile | |
59 | ||
60 | First off, you should understand why you want to add Guile to Dia at | |
61 | all, and that means forming a picture of what Dia does and how it does | |
62 | it. So, what are the constituents of the Dia application? | |
63 | ||
64 | @itemize @bullet | |
65 | @item | |
66 | Most importantly, the @dfn{application domain objects} --- in other | |
67 | words, the concepts that differentiate Dia from another application such | |
68 | as a word processor or spreadsheet: shapes, templates, connectors, | |
69 | pages, plus the properties of all these things. | |
70 | ||
71 | @item | |
72 | The code that manages the graphical face of the application, including | |
73 | the layout and display of the objects above. | |
74 | ||
75 | @item | |
76 | The code that handles input events, which indicate that the application | |
77 | user is wanting to do something. | |
78 | @end itemize | |
79 | ||
80 | @noindent | |
81 | (In other words, a textbook example of the @dfn{model - view - | |
82 | controller} paradigm.) | |
83 | ||
84 | Next question: how will Dia benefit once the Guile integration is | |
85 | complete? Several (positive!) answers are possible here, and the choice | |
86 | is obviously up to the application developers. Still, one answer is | |
87 | that the main benefit will be the ability to manipulate Dia's | |
88 | application domain objects from Scheme. | |
89 | ||
90 | Suppose that Dia made a set of procedures available in Scheme, | |
91 | representing the most basic operations on objects such as shapes, | |
92 | connectors, and so on. Using Scheme, the application user could then | |
93 | write code that builds upon these basic operations to create more | |
94 | complex procedures. For example, given basic procedures to enumerate | |
95 | the objects on a page, to determine whether an object is a square, and | |
96 | to change the fill pattern of a single shape, the user can write a | |
97 | Scheme procedure to change the fill pattern of all squares on the | |
98 | current page: | |
99 | ||
100 | @lisp | |
101 | (define (change-squares'-fill-pattern new-pattern) | |
102 | (for-each-shape current-page | |
103 | (lambda (shape) | |
104 | (if (square? shape) | |
105 | (change-fill-pattern shape new-pattern))))) | |
106 | @end lisp | |
107 | ||
108 | ||
109 | @node Dia Steps | |
110 | @subsection Four Steps Required to Add Guile | |
111 | ||
112 | Assuming this objective, four steps are needed to achieve it. | |
113 | ||
114 | First, you need a way of representing your application-specific objects | |
115 | --- such as @code{shape} in the previous example --- when they are | |
116 | passed into the Scheme world. Unless your objects are so simple that | |
117 | they map naturally into builtin Scheme data types like numbers and | |
118 | strings, you will probably want to use Guile's @dfn{SMOB} interface to | |
119 | create a new Scheme data type for your objects. | |
120 | ||
121 | Second, you need to write code for the basic operations like | |
122 | @code{for-each-shape} and @code{square?} such that they access and | |
123 | manipulate your existing data structures correctly, and then make these | |
124 | operations available as @dfn{primitives} on the Scheme level. | |
125 | ||
126 | Third, you need to provide some mechanism within the Dia application | |
127 | that a user can hook into to cause arbitrary Scheme code to be | |
128 | evaluated. | |
129 | ||
130 | Finally, you need to restructure your top-level application C code a | |
131 | little so that it initializes the Guile interpreter correctly and | |
132 | declares your @dfn{SMOBs} and @dfn{primitives} to the Scheme world. | |
133 | ||
134 | The following subsections expand on these four points in turn. | |
135 | ||
136 | ||
137 | @node Dia Smobs | |
138 | @subsection How to Represent Dia Data in Scheme | |
139 | ||
140 | For all but the most trivial applications, you will probably want to | |
141 | allow some representation of your domain objects to exist on the Scheme | |
142 | level. This is where the idea of SMOBs comes in, and with it issues of | |
143 | lifetime management and garbage collection. | |
144 | ||
145 | To get more concrete about this, let's look again at the example we gave | |
146 | earlier of how application users can use Guile to build higher-level | |
147 | functions from the primitives that Dia itself provides. | |
148 | ||
149 | @lisp | |
150 | (define (change-squares'-fill-pattern new-pattern) | |
151 | (for-each-shape current-page | |
152 | (lambda (shape) | |
153 | (if (square? shape) | |
154 | (change-fill-pattern shape new-pattern))))) | |
155 | @end lisp | |
156 | ||
157 | Consider what is stored here in the variable @code{shape}. For each | |
158 | shape on the current page, the @code{for-each-shape} primitive calls | |
159 | @code{(lambda (shape) @dots{})} with an argument representing that | |
160 | shape. Question is: how is that argument represented on the Scheme | |
161 | level? The issues are as follows. | |
162 | ||
163 | @itemize @bullet | |
164 | @item | |
165 | Whatever the representation, it has to be decodable again by the C code | |
166 | for the @code{square?} and @code{change-fill-pattern} primitives. In | |
167 | other words, a primitive like @code{square?} has somehow to be able to | |
168 | turn the value that it receives back into something that points to the | |
169 | underlying C structure describing a shape. | |
170 | ||
171 | @item | |
172 | The representation must also cope with Scheme code holding on to the | |
173 | value for later use. What happens if the Scheme code stores | |
174 | @code{shape} in a global variable, but then that shape is deleted (in a | |
175 | way that the Scheme code is not aware of), and later on some other | |
176 | Scheme code uses that global variable again in a call to, say, | |
177 | @code{square?}? | |
178 | ||
179 | @item | |
180 | The lifetime and memory allocation of objects that exist @emph{only} in | |
181 | the Scheme world is managed automatically by Guile's garbage collector | |
182 | using one simple rule: when there are no remaining references to an | |
183 | object, the object is considered dead and so its memory is freed. But | |
184 | for objects that exist in both C and Scheme, the picture is more | |
185 | complicated; in the case of Dia, where the @code{shape} argument passes | |
186 | transiently in and out of the Scheme world, it would be quite wrong the | |
187 | @strong{delete} the underlying C shape just because the Scheme code has | |
188 | finished evaluation. How do we avoid this happening? | |
189 | @end itemize | |
190 | ||
191 | One resolution of these issues is for the Scheme-level representation of | |
192 | a shape to be a new, Scheme-specific C structure wrapped up as a SMOB. | |
193 | The SMOB is what is passed into and out of Scheme code, and the | |
194 | Scheme-specific C structure inside the SMOB points to Dia's underlying C | |
195 | structure so that the code for primitives like @code{square?} can get at | |
196 | it. | |
197 | ||
198 | To cope with an underlying shape being deleted while Scheme code is | |
199 | still holding onto a Scheme shape value, the underlying C structure | |
200 | should have a new field that points to the Scheme-specific SMOB. When a | |
201 | shape is deleted, the relevant code chains through to the | |
202 | Scheme-specific structure and sets its pointer back to the underlying | |
203 | structure to NULL. Thus the SMOB value for the shape continues to | |
204 | exist, but any primitive code that tries to use it will detect that the | |
205 | underlying shape has been deleted because the underlying structure | |
206 | pointer is NULL. | |
207 | ||
208 | So, to summarize the steps involved in this resolution of the problem | |
209 | (and assuming that the underlying C structure for a shape is | |
210 | @code{struct dia_shape}): | |
211 | ||
212 | @itemize @bullet | |
213 | @item | |
214 | Define a new Scheme-specific structure that @emph{points} to the | |
215 | underlying C structure: | |
216 | ||
217 | @lisp | |
218 | struct dia_guile_shape | |
219 | @{ | |
220 | struct dia_shape * c_shape; /* NULL => deleted */ | |
221 | @} | |
222 | @end lisp | |
223 | ||
224 | @item | |
225 | Add a field to @code{struct dia_shape} that points to its @code{struct | |
226 | dia_guile_shape} if it has one --- | |
227 | ||
228 | @lisp | |
229 | struct dia_shape | |
230 | @{ | |
231 | @dots{} | |
232 | struct dia_guile_shape * guile_shape; | |
233 | @} | |
234 | @end lisp | |
235 | ||
236 | @noindent | |
237 | --- so that C code can set @code{guile_shape->c_shape} to NULL when the | |
238 | underlying shape is deleted. | |
239 | ||
240 | @item | |
241 | Wrap @code{struct dia_guile_shape} as a SMOB type. | |
242 | ||
243 | @item | |
244 | Whenever you need to represent a C shape onto the Scheme level, create a | |
245 | SMOB instance for it, and pass that. | |
246 | ||
247 | @item | |
248 | In primitive code that receives a shape SMOB instance, check the | |
249 | @code{c_shape} field when decoding it, to find out whether the | |
250 | underlying C shape is still there. | |
251 | @end itemize | |
252 | ||
253 | As far as memory management is concerned, the SMOB values and their | |
254 | Scheme-specific structures are under the control of the garbage | |
255 | collector, whereas the underlying C structures are explicitly managed in | |
256 | exactly the same way that Dia managed them before we thought of adding | |
257 | Guile. | |
258 | ||
259 | When the garbage collector decides to free a shape SMOB value, it calls | |
260 | the @dfn{SMOB free} function that was specified when defining the shape | |
261 | SMOB type. To maintain the correctness of the @code{guile_shape} field | |
262 | in the underlying C structure, this function should chain through to the | |
263 | underlying C structure (if it still exists) and set its | |
264 | @code{guile_shape} field to NULL. | |
265 | ||
266 | For full documentation on defining and using SMOB types, see | |
267 | @ref{Defining New Types (Smobs)}. | |
268 | ||
269 | ||
270 | @node Dia Primitives | |
271 | @subsection Writing Guile Primitives for Dia | |
272 | ||
273 | Once the details of object representation are decided, writing the | |
274 | primitive function code that you need is usually straightforward. | |
275 | ||
276 | A primitive is simply a C function whose arguments and return value are | |
277 | all of type @code{SCM}, and whose body does whatever you want it to do. | |
278 | As an example, here is a possible implementation of the @code{square?} | |
279 | primitive: | |
280 | ||
281 | @lisp | |
282 | #define FUNC_NAME "square?" | |
283 | static SCM square_p (SCM shape) | |
284 | @{ | |
285 | struct dia_guile_shape * guile_shape; | |
286 | ||
287 | /* Check that arg is really a shape SMOB. */ | |
288 | SCM_VALIDATE_SHAPE (SCM_ARG1, shape); | |
289 | ||
290 | /* Access Scheme-specific shape structure. */ | |
291 | guile_shape = SCM_SMOB_DATA (shape); | |
292 | ||
293 | /* Find out if underlying shape exists and is a | |
294 | square; return answer as a Scheme boolean. */ | |
295 | return SCM_BOOL (guile_shape->c_shape && | |
296 | (guile_shape->c_shape->type == DIA_SQUARE)); | |
297 | @} | |
298 | #undef FUNC_NAME | |
299 | @end lisp | |
300 | ||
301 | Notice how easy it is to chain through from the @code{SCM shape} | |
302 | parameter that @code{square_p} receives --- which is a SMOB --- to the | |
303 | Scheme-specific structure inside the SMOB, and thence to the underlying | |
304 | C structure for the shape. | |
305 | ||
306 | In this code, @code{SCM_SMOB_DATA} and @code{SCM_BOOL} are macros from | |
307 | the standard Guile API. @code{SCM_VALIDATE_SHAPE} is a macro that you | |
308 | should define as part of your SMOB definition: it checks that the passed | |
309 | parameter is of the expected type. This is needed to guard against | |
310 | Scheme code using the @code{square?} procedure incorrectly, as in | |
311 | @code{(square? "hello")}; Scheme's latent typing means that usage errors | |
312 | like this must be caught at run time. | |
313 | ||
314 | Having written the C code for your primitives, you need to make them | |
315 | available as Scheme procedures by calling the @code{scm_c_define_gsubr} | |
316 | function. @code{scm_c_define_gsubr} (REFFIXME) takes arguments that | |
317 | specify the Scheme-level name for the primitive and how many required, | |
318 | optional and rest arguments it can accept. The @code{square?} primitive | |
319 | always requires exactly one argument, so the call to make it available | |
320 | in Scheme reads like this: | |
321 | ||
322 | @lisp | |
323 | scm_c_define_gsubr ("square?", 1, 0, 0, square_p); | |
324 | @end lisp | |
325 | ||
326 | For where to put this call, see the subsection after next on the | |
327 | structure of Guile-enabled code (@pxref{Dia Structure}). | |
328 | ||
329 | ||
330 | @node Dia Hook | |
331 | @subsection Providing a Hook for the Evaluation of Scheme Code | |
332 | ||
333 | To make the Guile integration useful, you have to design some kind of | |
334 | hook into your application that application users can use to cause their | |
335 | Scheme code to be evaluated. | |
336 | ||
337 | Technically, this is straightforward; you just have to decide on a | |
338 | mechanism that is appropriate for your application. Think of Emacs, for | |
339 | example: when you type @kbd{@key{ESC} :}, you get a prompt where you can | |
340 | type in any Elisp code, which Emacs will then evaluate. Or, again like | |
341 | Emacs, you could provide a mechanism (such as an init file) to allow | |
342 | Scheme code to be associated with a particular key sequence, and | |
343 | evaluate the code when that key sequence is entered. | |
344 | ||
345 | In either case, once you have the Scheme code that you want to evaluate, | |
346 | as a null terminated string, you can tell Guile to evaluate it by | |
347 | calling the @code{scm_c_eval_string} function. | |
348 | ||
349 | ||
350 | @node Dia Structure | |
351 | @subsection Top-level Structure of Guile-enabled Dia | |
352 | ||
353 | Let's assume that the pre-Guile Dia code looks structurally like this: | |
354 | ||
355 | @itemize @bullet | |
356 | @item | |
357 | @code{main ()} | |
358 | ||
359 | @itemize @bullet | |
360 | @item | |
361 | do lots of initialization and setup stuff | |
362 | @item | |
363 | enter Gtk main loop | |
364 | @end itemize | |
365 | @end itemize | |
366 | ||
367 | When you add Guile to a program, one (rather technical) requirement is | |
368 | that Guile's garbage collector needs to know where the bottom of the C | |
369 | stack is. The easiest way to ensure this is to use | |
370 | @code{scm_boot_guile} like this: | |
371 | ||
372 | @itemize @bullet | |
373 | @item | |
374 | @code{main ()} | |
375 | ||
376 | @itemize @bullet | |
377 | @item | |
378 | do lots of initialization and setup stuff | |
379 | @item | |
380 | @code{scm_boot_guile (argc, argv, inner_main, NULL)} | |
381 | @end itemize | |
382 | ||
383 | @item | |
384 | @code{inner_main ()} | |
385 | ||
386 | @itemize @bullet | |
387 | @item | |
388 | define all SMOB types | |
389 | @item | |
390 | export primitives to Scheme using @code{scm_c_define_gsubr} | |
391 | @item | |
392 | enter Gtk main loop | |
393 | @end itemize | |
394 | @end itemize | |
395 | ||
396 | In other words, you move the guts of what was previously in your | |
397 | @code{main} function into a new function called @code{inner_main}, and | |
398 | then add a @code{scm_boot_guile} call, with @code{inner_main} as a | |
399 | parameter, to the end of @code{main}. | |
400 | ||
401 | Assuming that you are using SMOBs and have written primitive code as | |
402 | described in the preceding subsections, you also need to insert calls to | |
403 | declare your new SMOBs and export the primitives to Scheme. These | |
404 | declarations must happen @emph{inside} the dynamic scope of the | |
405 | @code{scm_boot_guile} call, but also @emph{before} any code is run that | |
406 | could possibly use them --- the beginning of @code{inner_main} is an | |
407 | ideal place for this. | |
408 | ||
409 | ||
410 | @node Dia Advanced | |
411 | @subsection Going Further with Dia and Guile | |
412 | ||
413 | The steps described so far implement an initial Guile integration that | |
414 | already gives a lot of additional power to Dia application users. But | |
415 | there are further steps that you could take, and it's interesting to | |
416 | consider a few of these. | |
417 | ||
418 | In general, you could progressively move more of Dia's source code from | |
419 | C into Scheme. This might make the code more maintainable and | |
420 | extensible, and it could open the door to new programming paradigms that | |
421 | are tricky to effect in C but straightforward in Scheme. | |
422 | ||
423 | A specific example of this is that you could use the guile-gtk package, | |
424 | which provides Scheme-level procedures for most of the Gtk+ library, to | |
425 | move the code that lays out and displays Dia objects from C to Scheme. | |
426 | ||
427 | As you follow this path, it naturally becomes less useful to maintain a | |
428 | distinction between Dia's original non-Guile-related source code, and | |
429 | its later code implementing SMOBs and primitives for the Scheme world. | |
430 | ||
431 | For example, suppose that the original source code had a | |
432 | @code{dia_change_fill_pattern} function: | |
433 | ||
434 | @lisp | |
435 | void dia_change_fill_pattern (struct dia_shape * shape, | |
436 | struct dia_pattern * pattern) | |
437 | @{ | |
438 | /* real pattern change work */ | |
439 | @} | |
440 | @end lisp | |
441 | ||
442 | During initial Guile integration, you add a @code{change_fill_pattern} | |
443 | primitive for Scheme purposes, which accesses the underlying structures | |
444 | from its SMOB values and uses @code{dia_change_fill_pattern} to do the | |
445 | real work: | |
446 | ||
447 | @lisp | |
448 | SCM change_fill_pattern (SCM shape, SCM pattern) | |
449 | @{ | |
450 | struct dia_shape * d_shape; | |
451 | struct dia_pattern * d_pattern; | |
452 | ||
453 | @dots{} | |
454 | ||
455 | dia_change_fill_pattern (d_shape, d_pattern); | |
456 | ||
457 | return SCM_UNSPECIFIED; | |
458 | @} | |
459 | @end lisp | |
460 | ||
461 | At this point, it makes sense to keep @code{dia_change_fill_pattern} and | |
462 | @code{change_fill_pattern} separate, because | |
463 | @code{dia_change_fill_pattern} can also be called without going through | |
464 | Scheme at all, say because the user clicks a button which causes a | |
465 | C-registered Gtk+ callback to be called. | |
466 | ||
467 | But, if the code for creating buttons and registering their callbacks is | |
468 | moved into Scheme (using guile-gtk), it may become true that | |
469 | @code{dia_change_fill_pattern} can no longer be called other than | |
470 | through Scheme. In which case, it makes sense to abolish it and move | |
471 | its contents directly into @code{change_fill_pattern}, like this: | |
472 | ||
473 | @lisp | |
474 | SCM change_fill_pattern (SCM shape, SCM pattern) | |
475 | @{ | |
476 | struct dia_shape * d_shape; | |
477 | struct dia_pattern * d_pattern; | |
478 | ||
479 | @dots{} | |
480 | ||
481 | /* real pattern change work */ | |
482 | ||
483 | return SCM_UNSPECIFIED; | |
484 | @} | |
485 | @end lisp | |
486 | ||
487 | So further Guile integration progressively @emph{reduces} the amount of | |
488 | functional C code that you have to maintain over the long term. | |
489 | ||
490 | A similar argument applies to data representation. In the discussion of | |
491 | SMOBs earlier, issues arose because of the different memory management | |
492 | and lifetime models that normally apply to data structures in C and in | |
493 | Scheme. However, with further Guile integration, you can resolve this | |
494 | issue in a more radical way by allowing all your data structures to be | |
495 | under the control of the garbage collector, and kept alive by references | |
496 | from the Scheme world. Instead of maintaining an array or linked list | |
497 | of shapes in C, you would instead maintain a list in Scheme. | |
498 | ||
499 | Rather like the coalescing of @code{dia_change_fill_pattern} and | |
500 | @code{change_fill_pattern}, the practical upshot of such a change is | |
501 | that you would no longer have to keep the @code{dia_shape} and | |
502 | @code{dia_guile_shape} structures separate, and so wouldn't need to | |
503 | worry about the pointers between them. Instead, you could change the | |
504 | SMOB definition to wrap the @code{dia_shape} structure directly, and | |
505 | send @code{dia_guile_shape} off to the scrap yard. Cut out the middle | |
506 | man! | |
507 | ||
508 | Finally, we come to the holy grail of Guile's free software / extension | |
509 | language approach. Once you have a Scheme representation for | |
510 | interesting Dia data types like shapes, and a handy bunch of primitives | |
511 | for manipulating them, it suddenly becomes clear that you have a bundle | |
512 | of functionality that could have far-ranging use beyond Dia itself. In | |
513 | other words, the data types and primitives could now become a library, | |
514 | and Dia becomes just one of the many possible applications using that | |
515 | library --- albeit, at this early stage, a rather important one! | |
516 | ||
517 | In this model, Guile becomes just the glue that binds everything | |
518 | together. Imagine an application that usefully combined functionality | |
519 | from Dia, Gnumeric and GnuCash --- it's tricky right now, because no | |
520 | such application yet exists; but it'll happen some day @dots{} | |
521 | ||
522 | ||
523 | @node Scheme vs C | |
524 | @section Why Scheme is More Hackable Than C | |
525 | ||
526 | Underlying Guile's value proposition is the assumption that programming | |
527 | in a high level language, specifically Guile's implementation of Scheme, | |
528 | is necessarily better in some way than programming in C. What do we | |
529 | mean by this claim, and how can we be so sure? | |
226297eb NJ |
530 | |
531 | One class of advantages applies not only to Scheme, but more generally | |
532 | to any interpretable, high level, scripting language, such as Emacs | |
533 | Lisp, Python, Ruby, or @TeX{}'s macro language. Common features of all | |
534 | such languages, when compared to C, are that: | |
9401323e NJ |
535 | |
536 | @itemize @bullet | |
537 | @item | |
226297eb NJ |
538 | They lend themselves to rapid and experimental development cycles, |
539 | owing usually to a combination of their interpretability and the | |
540 | integrated development environment in which they are used. | |
9401323e NJ |
541 | |
542 | @item | |
226297eb NJ |
543 | They free developers from some of the low level bookkeeping tasks |
544 | associated with C programming, notably memory management. | |
9401323e NJ |
545 | |
546 | @item | |
226297eb NJ |
547 | They provide high level features such as container objects and exception |
548 | handling that make common programming tasks easier. | |
9401323e NJ |
549 | @end itemize |
550 | ||
1982a56a NJ |
551 | In the case of Scheme, particular features that make programming easier |
552 | --- and more fun! --- are its powerful mechanisms for abstracting parts | |
553 | of programs (closures --- @pxref{About Closure}) and for iteration | |
226297eb NJ |
554 | (@pxref{while do}). |
555 | ||
556 | The evidence in support of this argument is empirical: the huge amount | |
557 | of code that has been written in extension languages for applications | |
558 | that support this mechanism. Most notable are extensions written in | |
559 | Emacs Lisp for GNU Emacs, in @TeX{}'s macro language for @TeX{}, and in | |
560 | Script-Fu for the Gimp, but there is increasingly now a significant code | |
561 | eco-system for Guile-based applications as well, such as Lilypond and | |
562 | GnuCash. It is close to inconceivable that similar amounts of | |
563 | functionality could have been added to these applications just by | |
564 | writing new code in their base implementation languages. | |
565 | ||
226297eb NJ |
566 | |
567 | @node Testbed Example | |
568 | @section Example: Using Guile for an Application Testbed | |
569 | ||
570 | As an example of what this means in practice, imagine writing a testbed | |
571 | for an application that is tested by submitting various requests (via a | |
572 | C interface) and validating the output received. Suppose further that | |
573 | the application keeps an idea of its current state, and that the | |
574 | ``correct'' output for a given request may depend on the current | |
575 | application state. A complete ``white box''@footnote{A @dfn{white box} | |
576 | test plan is one that incorporates knowledge of the internal design of | |
577 | the application under test.} test plan for this application would aim to | |
578 | submit all possible requests in each distinguishable state, and validate | |
579 | the output for all request/state combinations. | |
580 | ||
581 | To write all this test code in C would be very tedious. Suppose instead | |
582 | that the testbed code adds a single new C function, to submit an | |
583 | arbitrary request and return the response, and then uses Guile to export | |
584 | this function as a Scheme procedure. The rest of the testbed can then | |
585 | be written in Scheme, and so benefits from all the advantages of | |
586 | programming in Scheme that were described in the previous section. | |
587 | ||
588 | (In this particular example, there is an additional benefit of writing | |
589 | most of the testbed in Scheme. A common problem for white box testing | |
590 | is that mistakes and mistaken assumptions in the application under test | |
591 | can easily be reproduced in the testbed code. It is more difficult to | |
592 | copy mistakes like this when the testbed is written in a different | |
593 | language from the application.) | |
594 | ||
595 | ||
596 | @node Programming Options | |
597 | @section A Choice of Programming Options | |
598 | ||
599 | The preceding arguments and example point to a model of Guile | |
600 | programming that is applicable in many cases. According to this model, | |
601 | Guile programming involves a balance between C and Scheme programming, | |
602 | with the aim being to extract the greatest possible Scheme level benefit | |
603 | from the least amount of C level work. | |
604 | ||
605 | The C level work required in this model usually consists of packaging | |
606 | and exporting functions and application objects such that they can be | |
607 | seen and manipulated on the Scheme level. To help with this, Guile's C | |
608 | language interface includes utility features that aim to make this kind | |
609 | of integration very easy for the application developer. These features | |
610 | are documented later in this part of the manual: see REFFIXME. | |
611 | ||
612 | This model, though, is really just one of a range of possible | |
613 | programming options. If all of the functionality that you need is | |
614 | available from Scheme, you could choose instead to write your whole | |
615 | application in Scheme (or one of the other high level languages that | |
616 | Guile supports through translation), and simply use Guile as an | |
617 | interpreter for Scheme. (In the future, we hope that Guile will also be | |
618 | able to compile Scheme code, so lessening the performance gap between C | |
619 | and Scheme code.) Or, at the other end of the C--Scheme scale, you | |
620 | could write the majority of your application in C, and only call out to | |
621 | Guile occasionally for specific actions such as reading a configuration | |
622 | file or executing a user-specified extension. The choices boil down to | |
623 | two basic questions: | |
9401323e NJ |
624 | |
625 | @itemize @bullet | |
626 | @item | |
627 | Which parts of the application do you write in C, and which in Scheme | |
628 | (or another high level translated language)? | |
629 | ||
630 | @item | |
631 | How do you design the interface between the C and Scheme parts of your | |
632 | application? | |
633 | @end itemize | |
634 | ||
635 | These are of course design questions, and the right design for any given | |
636 | application will always depend upon the particular requirements that you | |
226297eb NJ |
637 | are trying to meet. In the context of Guile, however, there are some |
638 | generally applicable considerations that can help you when designing | |
639 | your answers. | |
9401323e NJ |
640 | |
641 | @menu | |
642 | * Available Functionality:: What functionality is already available? | |
643 | * Basic Constraints:: Functional and performance constraints. | |
644 | * Style Choices:: Your preferred programming style. | |
645 | * Program Control:: What controls program execution? | |
9401323e NJ |
646 | @end menu |
647 | ||
648 | ||
649 | @node Available Functionality | |
226297eb | 650 | @subsection What Functionality is Already Available? |
9401323e NJ |
651 | |
652 | Suppose, for the sake of argument, that you would prefer to write your | |
653 | whole application in Scheme. Then the API available to you consists of: | |
654 | ||
655 | @itemize @bullet | |
656 | @item | |
657 | standard Scheme | |
658 | ||
659 | @item | |
660 | plus the extensions to standard Scheme provided by | |
661 | Guile in its core distribution | |
662 | ||
663 | @item | |
664 | plus any additional functionality that you or others have packaged so | |
665 | that it can be loaded as a Guile Scheme module. | |
666 | @end itemize | |
667 | ||
668 | A module in the last category can either be a pure Scheme module --- in | |
669 | other words a collection of utility procedures coded in Scheme --- or a | |
670 | module that provides a Scheme interface to an extension library coded in | |
671 | C --- in other words a nice package where someone else has done the work | |
672 | of wrapping up some useful C code for you. The set of available modules | |
673 | is growing quickly and already includes such useful examples as | |
674 | @code{(gtk gtk)}, which makes Gtk+ drawing functions available in | |
675 | Scheme, and @code{(database postgres)}, which provides SQL access to a | |
676 | Postgres database. | |
677 | ||
a7a7bb95 NJ |
678 | Given the growing collection of pre-existing modules, it is quite |
679 | feasible that your application could be implemented by combining a | |
680 | selection of these modules together with new application code written in | |
681 | Scheme. | |
682 | ||
683 | If this approach is not enough, because the functionality that your | |
226297eb NJ |
684 | application needs is not already available in this form, and it is |
685 | impossible to write the new functionality in Scheme, you will need to | |
686 | write some C code. If the required function is already available in C | |
687 | (e.g. in a library), all you need is a little glue to connect it to the | |
688 | world of Guile. If not, you need both to write the basic code and to | |
689 | plumb it into Guile. | |
9401323e NJ |
690 | |
691 | In either case, two general considerations are important. Firstly, what | |
692 | is the interface by which the functionality is presented to the Scheme | |
693 | world? Does the interface consist only of function calls (for example, | |
694 | a simple drawing interface), or does it need to include @dfn{objects} of | |
695 | some kind that can be passed between C and Scheme and manipulated by | |
696 | both worlds. Secondly, how does the lifetime and memory management of | |
697 | objects in the C code relate to the garbage collection governed approach | |
698 | of Scheme objects? In the case where the basic C code is not already | |
699 | written, most of the difficulties of memory management can be avoided by | |
700 | using Guile's C interface features from the start. | |
701 | ||
226297eb NJ |
702 | For the full documentation on writing C code for Guile and connecting |
703 | existing C code to the Guile world, see REFFIXME. | |
9401323e NJ |
704 | |
705 | ||
706 | @node Basic Constraints | |
226297eb | 707 | @subsection Functional and Performance Constraints |
9401323e NJ |
708 | |
709 | ||
710 | @node Style Choices | |
226297eb | 711 | @subsection Your Preferred Programming Style |
9401323e NJ |
712 | |
713 | ||
714 | @node Program Control | |
226297eb | 715 | @subsection What Controls Program Execution? |
9401323e | 716 | |
9401323e NJ |
717 | |
718 | @node User Programming | |
719 | @section How About Application Users? | |
720 | ||
721 | So far we have considered what Guile programming means for an | |
722 | application developer. But what if you are instead @emph{using} an | |
723 | existing Guile-based application, and want to know what your | |
724 | options are for programming and extending this application? | |
725 | ||
726 | The answer to this question varies from one application to another, | |
727 | because the options available depend inevitably on whether the | |
728 | application developer has provided any hooks for you to hang your own | |
729 | code on and, if there are such hooks, what they allow you to | |
730 | do.@footnote{Of course, in the world of free software, you always have | |
731 | the freedom to modify the application's source code to your own | |
732 | requirements. Here we are concerned with the extension options that the | |
733 | application has provided for without your needing to modify its source | |
734 | code.} For example@dots{} | |
735 | ||
736 | @itemize @bullet | |
737 | @item | |
738 | If the application permits you to load and execute any Guile code, the | |
739 | world is your oyster. You can extend the application in any way that | |
740 | you choose. | |
741 | ||
742 | @item | |
743 | A more cautious application might allow you to load and execute Guile | |
744 | code, but only in a @dfn{safe} environment, where the interface | |
745 | available is restricted by the application from the standard Guile API. | |
746 | ||
747 | @item | |
748 | Or a really fearful application might not provide a hook to really | |
749 | execute user code at all, but just use Scheme syntax as a convenient way | |
750 | for users to specify application data or configuration options. | |
751 | @end itemize | |
752 | ||
753 | In the last two cases, what you can do is, by definition, restricted by | |
754 | the application, and you should refer to the application's own manual to | |
755 | find out your options. | |
756 | ||
757 | The most well known example of the first case is Emacs, with its | |
758 | extension language Emacs Lisp: as well as being a text editor, Emacs | |
759 | supports the loading and execution of arbitrary Emacs Lisp code. The | |
760 | result of such openness has been dramatic: Emacs now benefits from | |
761 | user-contributed Emacs Lisp libraries that extend the basic editing | |
762 | function to do everything from reading news to psychoanalysis and | |
763 | playing adventure games. The only limitation is that extensions are | |
764 | restricted to the functionality provided by Emacs's built-in set of | |
765 | primitive operations. For example, you can interact and display data by | |
85a9b4ed | 766 | manipulating the contents of an Emacs buffer, but you can't pop-up and |
9401323e NJ |
767 | draw a window with a layout that is totally different to the Emacs |
768 | standard. | |
769 | ||
770 | This situation with a Guile application that supports the loading of | |
771 | arbitrary user code is similar, except perhaps even more so, because | |
772 | Guile also supports the loading of extension libraries written in C. | |
773 | This last point enables user code to add new primitive operations to | |
774 | Guile, and so to bypass the limitation present in Emacs Lisp. | |
775 | ||
776 | At this point, the distinction between an application developer and an | |
777 | application user becomes rather blurred. Instead of seeing yourself as | |
778 | a user extending an application, you could equally well say that you are | |
779 | developing a new application of your own using some of the primitive | |
780 | functionality provided by the original application. As such, all the | |
781 | discussions of the preceding sections of this chapter are relevant to | |
782 | how you can proceed with developing your extension. |