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