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 | ||
c393de66 MV |
7 | @node Programming Overview |
8 | @section An Overview of Guile Programming | |
9 | ||
10 | Guile is designed as an extension language interpreter that is | |
11 | straightforward to integrate with applications written in C (and C++). | |
12 | The big win here for the application developer is that Guile | |
13 | integration, as the Guile web page says, ``lowers your project's | |
14 | hacktivation energy.'' Lowering the hacktivation energy means that you, | |
15 | as the application developer, @emph{and your users}, reap the benefits | |
16 | that flow from being able to extend the application in a high level | |
17 | extension language rather than in plain old C. | |
18 | ||
19 | In abstract terms, it's difficult to explain what this really means and | |
20 | what the integration process involves, so instead let's begin by jumping | |
21 | straight into an example of how you might integrate Guile into an | |
22 | existing program, and what you could expect to gain by so doing. With | |
23 | that example under our belts, we'll then return to a more general | |
24 | analysis of the arguments involved and the range of programming options | |
25 | available. | |
26 | ||
27 | @menu | |
28 | * Extending Dia:: How one might extend Dia using Guile. | |
29 | * Scheme vs C:: Why Scheme is more hackable than C. | |
30 | * Testbed Example:: Example: using Guile in a testbed. | |
31 | * Programming Options:: Options for Guile programming. | |
32 | * User Programming:: How about application users? | |
33 | @end menu | |
34 | ||
35 | ||
36 | @node Extending Dia | |
37 | @subsection How One Might Extend Dia Using Guile | |
38 | ||
39 | Dia is a free software program for drawing schematic diagrams like flow | |
4906d8bd KR |
40 | charts and floor plans (@uref{http://www.gnome.org/projects/dia/}). |
41 | This section conducts the thought | |
c393de66 MV |
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 | @subsubsection 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 | @subsubsection 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 | @subsubsection 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 | @subsubsection 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 | |
c393de66 MV |
282 | static SCM square_p (SCM shape) |
283 | @{ | |
284 | struct dia_guile_shape * guile_shape; | |
285 | ||
286 | /* Check that arg is really a shape SMOB. */ | |
e0a8221d | 287 | scm_assert_smob_type (shape_tag, shape); |
c393de66 MV |
288 | |
289 | /* Access Scheme-specific shape structure. */ | |
290 | guile_shape = SCM_SMOB_DATA (shape); | |
291 | ||
292 | /* Find out if underlying shape exists and is a | |
293 | square; return answer as a Scheme boolean. */ | |
294 | return scm_from_bool (guile_shape->c_shape && | |
295 | (guile_shape->c_shape->type == DIA_SQUARE)); | |
296 | @} | |
c393de66 MV |
297 | @end lisp |
298 | ||
299 | Notice how easy it is to chain through from the @code{SCM shape} | |
300 | parameter that @code{square_p} receives --- which is a SMOB --- to the | |
301 | Scheme-specific structure inside the SMOB, and thence to the underlying | |
302 | C structure for the shape. | |
303 | ||
e0a8221d AW |
304 | In this code, @code{scm_assert_smob_type}, @code{SCM_SMOB_DATA}, and |
305 | @code{scm_from_bool} are from the standard Guile API. We assume that | |
306 | @code{shape_tag} was given to us when we made the shape SMOB type, using | |
307 | @code{scm_make_smob_type}. The call to @code{scm_assert_smob_type} | |
308 | ensures that @var{shape} is indeed a shape. This is needed to guard | |
c393de66 MV |
309 | against Scheme code using the @code{square?} procedure incorrectly, as |
310 | in @code{(square? "hello")}; Scheme's latent typing means that usage | |
311 | errors like this must be caught at run time. | |
312 | ||
313 | Having written the C code for your primitives, you need to make them | |
314 | available as Scheme procedures by calling the @code{scm_c_define_gsubr} | |
e0e75ddf | 315 | function. @code{scm_c_define_gsubr} (@pxref{Primitive Procedures}) takes arguments that |
c393de66 MV |
316 | specify the Scheme-level name for the primitive and how many required, |
317 | optional and rest arguments it can accept. The @code{square?} primitive | |
318 | always requires exactly one argument, so the call to make it available | |
319 | in Scheme reads like this: | |
320 | ||
321 | @lisp | |
322 | scm_c_define_gsubr ("square?", 1, 0, 0, square_p); | |
323 | @end lisp | |
324 | ||
325 | For where to put this call, see the subsection after next on the | |
326 | structure of Guile-enabled code (@pxref{Dia Structure}). | |
327 | ||
328 | ||
329 | @node Dia Hook | |
330 | @subsubsection Providing a Hook for the Evaluation of Scheme Code | |
331 | ||
332 | To make the Guile integration useful, you have to design some kind of | |
333 | hook into your application that application users can use to cause their | |
334 | Scheme code to be evaluated. | |
335 | ||
336 | Technically, this is straightforward; you just have to decide on a | |
337 | mechanism that is appropriate for your application. Think of Emacs, for | |
338 | example: when you type @kbd{@key{ESC} :}, you get a prompt where you can | |
339 | type in any Elisp code, which Emacs will then evaluate. Or, again like | |
340 | Emacs, you could provide a mechanism (such as an init file) to allow | |
341 | Scheme code to be associated with a particular key sequence, and | |
342 | evaluate the code when that key sequence is entered. | |
343 | ||
344 | In either case, once you have the Scheme code that you want to evaluate, | |
345 | as a null terminated string, you can tell Guile to evaluate it by | |
346 | calling the @code{scm_c_eval_string} function. | |
347 | ||
348 | ||
349 | @node Dia Structure | |
350 | @subsubsection Top-level Structure of Guile-enabled Dia | |
351 | ||
352 | Let's assume that the pre-Guile Dia code looks structurally like this: | |
353 | ||
354 | @itemize @bullet | |
355 | @item | |
356 | @code{main ()} | |
357 | ||
358 | @itemize @bullet | |
359 | @item | |
360 | do lots of initialization and setup stuff | |
361 | @item | |
362 | enter Gtk main loop | |
363 | @end itemize | |
364 | @end itemize | |
365 | ||
366 | When you add Guile to a program, one (rather technical) requirement is | |
367 | that Guile's garbage collector needs to know where the bottom of the C | |
368 | stack is. The easiest way to ensure this is to use | |
369 | @code{scm_boot_guile} like this: | |
370 | ||
371 | @itemize @bullet | |
372 | @item | |
373 | @code{main ()} | |
374 | ||
375 | @itemize @bullet | |
376 | @item | |
377 | do lots of initialization and setup stuff | |
378 | @item | |
379 | @code{scm_boot_guile (argc, argv, inner_main, NULL)} | |
380 | @end itemize | |
381 | ||
382 | @item | |
383 | @code{inner_main ()} | |
384 | ||
385 | @itemize @bullet | |
386 | @item | |
387 | define all SMOB types | |
388 | @item | |
389 | export primitives to Scheme using @code{scm_c_define_gsubr} | |
390 | @item | |
391 | enter Gtk main loop | |
392 | @end itemize | |
393 | @end itemize | |
394 | ||
395 | In other words, you move the guts of what was previously in your | |
396 | @code{main} function into a new function called @code{inner_main}, and | |
397 | then add a @code{scm_boot_guile} call, with @code{inner_main} as a | |
398 | parameter, to the end of @code{main}. | |
399 | ||
400 | Assuming that you are using SMOBs and have written primitive code as | |
401 | described in the preceding subsections, you also need to insert calls to | |
402 | declare your new SMOBs and export the primitives to Scheme. These | |
403 | declarations must happen @emph{inside} the dynamic scope of the | |
404 | @code{scm_boot_guile} call, but also @emph{before} any code is run that | |
405 | could possibly use them --- the beginning of @code{inner_main} is an | |
406 | ideal place for this. | |
407 | ||
408 | ||
409 | @node Dia Advanced | |
410 | @subsubsection Going Further with Dia and Guile | |
411 | ||
412 | The steps described so far implement an initial Guile integration that | |
413 | already gives a lot of additional power to Dia application users. But | |
414 | there are further steps that you could take, and it's interesting to | |
415 | consider a few of these. | |
416 | ||
417 | In general, you could progressively move more of Dia's source code from | |
418 | C into Scheme. This might make the code more maintainable and | |
419 | extensible, and it could open the door to new programming paradigms that | |
420 | are tricky to effect in C but straightforward in Scheme. | |
421 | ||
422 | A specific example of this is that you could use the guile-gtk package, | |
423 | which provides Scheme-level procedures for most of the Gtk+ library, to | |
424 | move the code that lays out and displays Dia objects from C to Scheme. | |
425 | ||
426 | As you follow this path, it naturally becomes less useful to maintain a | |
427 | distinction between Dia's original non-Guile-related source code, and | |
428 | its later code implementing SMOBs and primitives for the Scheme world. | |
429 | ||
430 | For example, suppose that the original source code had a | |
431 | @code{dia_change_fill_pattern} function: | |
432 | ||
433 | @lisp | |
434 | void dia_change_fill_pattern (struct dia_shape * shape, | |
435 | struct dia_pattern * pattern) | |
436 | @{ | |
437 | /* real pattern change work */ | |
438 | @} | |
439 | @end lisp | |
440 | ||
441 | During initial Guile integration, you add a @code{change_fill_pattern} | |
442 | primitive for Scheme purposes, which accesses the underlying structures | |
443 | from its SMOB values and uses @code{dia_change_fill_pattern} to do the | |
444 | real work: | |
445 | ||
446 | @lisp | |
447 | SCM change_fill_pattern (SCM shape, SCM pattern) | |
448 | @{ | |
449 | struct dia_shape * d_shape; | |
450 | struct dia_pattern * d_pattern; | |
451 | ||
452 | @dots{} | |
453 | ||
454 | dia_change_fill_pattern (d_shape, d_pattern); | |
455 | ||
456 | return SCM_UNSPECIFIED; | |
457 | @} | |
458 | @end lisp | |
459 | ||
460 | At this point, it makes sense to keep @code{dia_change_fill_pattern} and | |
461 | @code{change_fill_pattern} separate, because | |
462 | @code{dia_change_fill_pattern} can also be called without going through | |
463 | Scheme at all, say because the user clicks a button which causes a | |
464 | C-registered Gtk+ callback to be called. | |
465 | ||
466 | But, if the code for creating buttons and registering their callbacks is | |
467 | moved into Scheme (using guile-gtk), it may become true that | |
468 | @code{dia_change_fill_pattern} can no longer be called other than | |
469 | through Scheme. In which case, it makes sense to abolish it and move | |
470 | its contents directly into @code{change_fill_pattern}, like this: | |
471 | ||
472 | @lisp | |
473 | SCM change_fill_pattern (SCM shape, SCM pattern) | |
474 | @{ | |
475 | struct dia_shape * d_shape; | |
476 | struct dia_pattern * d_pattern; | |
477 | ||
478 | @dots{} | |
479 | ||
480 | /* real pattern change work */ | |
481 | ||
482 | return SCM_UNSPECIFIED; | |
483 | @} | |
484 | @end lisp | |
485 | ||
486 | So further Guile integration progressively @emph{reduces} the amount of | |
487 | functional C code that you have to maintain over the long term. | |
488 | ||
489 | A similar argument applies to data representation. In the discussion of | |
490 | SMOBs earlier, issues arose because of the different memory management | |
491 | and lifetime models that normally apply to data structures in C and in | |
492 | Scheme. However, with further Guile integration, you can resolve this | |
493 | issue in a more radical way by allowing all your data structures to be | |
494 | under the control of the garbage collector, and kept alive by references | |
495 | from the Scheme world. Instead of maintaining an array or linked list | |
496 | of shapes in C, you would instead maintain a list in Scheme. | |
497 | ||
498 | Rather like the coalescing of @code{dia_change_fill_pattern} and | |
499 | @code{change_fill_pattern}, the practical upshot of such a change is | |
500 | that you would no longer have to keep the @code{dia_shape} and | |
501 | @code{dia_guile_shape} structures separate, and so wouldn't need to | |
502 | worry about the pointers between them. Instead, you could change the | |
503 | SMOB definition to wrap the @code{dia_shape} structure directly, and | |
504 | send @code{dia_guile_shape} off to the scrap yard. Cut out the middle | |
505 | man! | |
506 | ||
507 | Finally, we come to the holy grail of Guile's free software / extension | |
508 | language approach. Once you have a Scheme representation for | |
509 | interesting Dia data types like shapes, and a handy bunch of primitives | |
510 | for manipulating them, it suddenly becomes clear that you have a bundle | |
511 | of functionality that could have far-ranging use beyond Dia itself. In | |
512 | other words, the data types and primitives could now become a library, | |
513 | and Dia becomes just one of the many possible applications using that | |
514 | library --- albeit, at this early stage, a rather important one! | |
515 | ||
516 | In this model, Guile becomes just the glue that binds everything | |
517 | together. Imagine an application that usefully combined functionality | |
518 | from Dia, Gnumeric and GnuCash --- it's tricky right now, because no | |
519 | such application yet exists; but it'll happen some day @dots{} | |
520 | ||
521 | ||
522 | @node Scheme vs C | |
523 | @subsection Why Scheme is More Hackable Than C | |
524 | ||
525 | Underlying Guile's value proposition is the assumption that programming | |
526 | in a high level language, specifically Guile's implementation of Scheme, | |
527 | is necessarily better in some way than programming in C. What do we | |
528 | mean by this claim, and how can we be so sure? | |
529 | ||
530 | One class of advantages applies not only to Scheme, but more generally | |
531 | to any interpretable, high level, scripting language, such as Emacs | |
532 | Lisp, Python, Ruby, or @TeX{}'s macro language. Common features of all | |
533 | such languages, when compared to C, are that: | |
534 | ||
535 | @itemize @bullet | |
536 | @item | |
537 | They lend themselves to rapid and experimental development cycles, | |
538 | owing usually to a combination of their interpretability and the | |
539 | integrated development environment in which they are used. | |
540 | ||
541 | @item | |
542 | They free developers from some of the low level bookkeeping tasks | |
543 | associated with C programming, notably memory management. | |
544 | ||
545 | @item | |
546 | They provide high level features such as container objects and exception | |
547 | handling that make common programming tasks easier. | |
548 | @end itemize | |
549 | ||
550 | In the case of Scheme, particular features that make programming easier | |
551 | --- and more fun! --- are its powerful mechanisms for abstracting parts | |
552 | of programs (closures --- @pxref{About Closure}) and for iteration | |
553 | (@pxref{while do}). | |
554 | ||
555 | The evidence in support of this argument is empirical: the huge amount | |
556 | of code that has been written in extension languages for applications | |
557 | that support this mechanism. Most notable are extensions written in | |
558 | Emacs Lisp for GNU Emacs, in @TeX{}'s macro language for @TeX{}, and in | |
559 | Script-Fu for the Gimp, but there is increasingly now a significant code | |
560 | eco-system for Guile-based applications as well, such as Lilypond and | |
561 | GnuCash. It is close to inconceivable that similar amounts of | |
562 | functionality could have been added to these applications just by | |
563 | writing new code in their base implementation languages. | |
564 | ||
565 | ||
566 | @node Testbed Example | |
567 | @subsection Example: Using Guile for an Application Testbed | |
568 | ||
569 | As an example of what this means in practice, imagine writing a testbed | |
570 | for an application that is tested by submitting various requests (via a | |
571 | C interface) and validating the output received. Suppose further that | |
572 | the application keeps an idea of its current state, and that the | |
573 | ``correct'' output for a given request may depend on the current | |
574 | application state. A complete ``white box''@footnote{A @dfn{white box} | |
575 | test plan is one that incorporates knowledge of the internal design of | |
576 | the application under test.} test plan for this application would aim to | |
577 | submit all possible requests in each distinguishable state, and validate | |
578 | the output for all request/state combinations. | |
579 | ||
580 | To write all this test code in C would be very tedious. Suppose instead | |
581 | that the testbed code adds a single new C function, to submit an | |
582 | arbitrary request and return the response, and then uses Guile to export | |
583 | this function as a Scheme procedure. The rest of the testbed can then | |
584 | be written in Scheme, and so benefits from all the advantages of | |
585 | programming in Scheme that were described in the previous section. | |
586 | ||
587 | (In this particular example, there is an additional benefit of writing | |
588 | most of the testbed in Scheme. A common problem for white box testing | |
589 | is that mistakes and mistaken assumptions in the application under test | |
590 | can easily be reproduced in the testbed code. It is more difficult to | |
591 | copy mistakes like this when the testbed is written in a different | |
592 | language from the application.) | |
593 | ||
594 | ||
595 | @node Programming Options | |
596 | @subsection A Choice of Programming Options | |
597 | ||
598 | The preceding arguments and example point to a model of Guile | |
599 | programming that is applicable in many cases. According to this model, | |
600 | Guile programming involves a balance between C and Scheme programming, | |
601 | with the aim being to extract the greatest possible Scheme level benefit | |
602 | from the least amount of C level work. | |
603 | ||
604 | The C level work required in this model usually consists of packaging | |
605 | and exporting functions and application objects such that they can be | |
606 | seen and manipulated on the Scheme level. To help with this, Guile's C | |
607 | language interface includes utility features that aim to make this kind | |
608 | of integration very easy for the application developer. These features | |
609 | are documented later in this part of the manual: see REFFIXME. | |
610 | ||
611 | This model, though, is really just one of a range of possible | |
612 | programming options. If all of the functionality that you need is | |
613 | available from Scheme, you could choose instead to write your whole | |
614 | application in Scheme (or one of the other high level languages that | |
615 | Guile supports through translation), and simply use Guile as an | |
616 | interpreter for Scheme. (In the future, we hope that Guile will also be | |
617 | able to compile Scheme code, so lessening the performance gap between C | |
618 | and Scheme code.) Or, at the other end of the C--Scheme scale, you | |
619 | could write the majority of your application in C, and only call out to | |
620 | Guile occasionally for specific actions such as reading a configuration | |
621 | file or executing a user-specified extension. The choices boil down to | |
622 | two basic questions: | |
623 | ||
624 | @itemize @bullet | |
625 | @item | |
626 | Which parts of the application do you write in C, and which in Scheme | |
627 | (or another high level translated language)? | |
628 | ||
629 | @item | |
630 | How do you design the interface between the C and Scheme parts of your | |
631 | application? | |
632 | @end itemize | |
633 | ||
634 | These are of course design questions, and the right design for any given | |
635 | application will always depend upon the particular requirements that you | |
636 | are trying to meet. In the context of Guile, however, there are some | |
637 | generally applicable considerations that can help you when designing | |
638 | your answers. | |
639 | ||
640 | @menu | |
641 | * Available Functionality:: What functionality is already available? | |
642 | * Basic Constraints:: Functional and performance constraints. | |
643 | * Style Choices:: Your preferred programming style. | |
644 | * Program Control:: What controls program execution? | |
645 | @end menu | |
646 | ||
647 | ||
648 | @node Available Functionality | |
649 | @subsubsection What Functionality is Already Available? | |
650 | ||
651 | Suppose, for the sake of argument, that you would prefer to write your | |
652 | whole application in Scheme. Then the API available to you consists of: | |
653 | ||
654 | @itemize @bullet | |
655 | @item | |
656 | standard Scheme | |
657 | ||
658 | @item | |
659 | plus the extensions to standard Scheme provided by | |
660 | Guile in its core distribution | |
661 | ||
662 | @item | |
663 | plus any additional functionality that you or others have packaged so | |
664 | that it can be loaded as a Guile Scheme module. | |
665 | @end itemize | |
666 | ||
667 | A module in the last category can either be a pure Scheme module --- in | |
668 | other words a collection of utility procedures coded in Scheme --- or a | |
669 | module that provides a Scheme interface to an extension library coded in | |
670 | C --- in other words a nice package where someone else has done the work | |
671 | of wrapping up some useful C code for you. The set of available modules | |
672 | is growing quickly and already includes such useful examples as | |
673 | @code{(gtk gtk)}, which makes Gtk+ drawing functions available in | |
674 | Scheme, and @code{(database postgres)}, which provides SQL access to a | |
675 | Postgres database. | |
676 | ||
677 | Given the growing collection of pre-existing modules, it is quite | |
678 | feasible that your application could be implemented by combining a | |
679 | selection of these modules together with new application code written in | |
680 | Scheme. | |
681 | ||
682 | If this approach is not enough, because the functionality that your | |
683 | application needs is not already available in this form, and it is | |
684 | impossible to write the new functionality in Scheme, you will need to | |
685 | write some C code. If the required function is already available in C | |
679cceed | 686 | (e.g.@: in a library), all you need is a little glue to connect it to the |
c393de66 MV |
687 | world of Guile. If not, you need both to write the basic code and to |
688 | plumb it into Guile. | |
689 | ||
690 | In either case, two general considerations are important. Firstly, what | |
691 | is the interface by which the functionality is presented to the Scheme | |
692 | world? Does the interface consist only of function calls (for example, | |
693 | a simple drawing interface), or does it need to include @dfn{objects} of | |
694 | some kind that can be passed between C and Scheme and manipulated by | |
695 | both worlds. Secondly, how does the lifetime and memory management of | |
696 | objects in the C code relate to the garbage collection governed approach | |
697 | of Scheme objects? In the case where the basic C code is not already | |
698 | written, most of the difficulties of memory management can be avoided by | |
699 | using Guile's C interface features from the start. | |
700 | ||
701 | For the full documentation on writing C code for Guile and connecting | |
702 | existing C code to the Guile world, see REFFIXME. | |
703 | ||
704 | ||
705 | @node Basic Constraints | |
706 | @subsubsection Functional and Performance Constraints | |
707 | ||
708 | ||
709 | @node Style Choices | |
710 | @subsubsection Your Preferred Programming Style | |
711 | ||
712 | ||
713 | @node Program Control | |
714 | @subsubsection What Controls Program Execution? | |
715 | ||
716 | ||
717 | @node User Programming | |
718 | @subsection How About Application Users? | |
719 | ||
720 | So far we have considered what Guile programming means for an | |
721 | application developer. But what if you are instead @emph{using} an | |
722 | existing Guile-based application, and want to know what your | |
723 | options are for programming and extending this application? | |
724 | ||
725 | The answer to this question varies from one application to another, | |
726 | because the options available depend inevitably on whether the | |
727 | application developer has provided any hooks for you to hang your own | |
728 | code on and, if there are such hooks, what they allow you to | |
729 | do.@footnote{Of course, in the world of free software, you always have | |
730 | the freedom to modify the application's source code to your own | |
731 | requirements. Here we are concerned with the extension options that the | |
732 | application has provided for without your needing to modify its source | |
733 | code.} For example@dots{} | |
734 | ||
735 | @itemize @bullet | |
736 | @item | |
737 | If the application permits you to load and execute any Guile code, the | |
738 | world is your oyster. You can extend the application in any way that | |
739 | you choose. | |
740 | ||
741 | @item | |
742 | A more cautious application might allow you to load and execute Guile | |
743 | code, but only in a @dfn{safe} environment, where the interface | |
744 | available is restricted by the application from the standard Guile API. | |
745 | ||
746 | @item | |
747 | Or a really fearful application might not provide a hook to really | |
748 | execute user code at all, but just use Scheme syntax as a convenient way | |
749 | for users to specify application data or configuration options. | |
750 | @end itemize | |
751 | ||
752 | In the last two cases, what you can do is, by definition, restricted by | |
753 | the application, and you should refer to the application's own manual to | |
754 | find out your options. | |
755 | ||
756 | The most well known example of the first case is Emacs, with its | |
757 | extension language Emacs Lisp: as well as being a text editor, Emacs | |
758 | supports the loading and execution of arbitrary Emacs Lisp code. The | |
759 | result of such openness has been dramatic: Emacs now benefits from | |
760 | user-contributed Emacs Lisp libraries that extend the basic editing | |
761 | function to do everything from reading news to psychoanalysis and | |
762 | playing adventure games. The only limitation is that extensions are | |
763 | restricted to the functionality provided by Emacs's built-in set of | |
764 | primitive operations. For example, you can interact and display data by | |
765 | manipulating the contents of an Emacs buffer, but you can't pop-up and | |
766 | draw a window with a layout that is totally different to the Emacs | |
767 | standard. | |
768 | ||
769 | This situation with a Guile application that supports the loading of | |
770 | arbitrary user code is similar, except perhaps even more so, because | |
771 | Guile also supports the loading of extension libraries written in C. | |
772 | This last point enables user code to add new primitive operations to | |
773 | Guile, and so to bypass the limitation present in Emacs Lisp. | |
774 | ||
775 | At this point, the distinction between an application developer and an | |
776 | application user becomes rather blurred. Instead of seeing yourself as | |
777 | a user extending an application, you could equally well say that you are | |
778 | developing a new application of your own using some of the primitive | |
779 | functionality provided by the original application. As such, all the | |
780 | discussions of the preceding sections of this chapter are relevant to | |
781 | how you can proceed with developing your extension. | |
4906d8bd KR |
782 | |
783 | ||
784 | @c Local Variables: | |
785 | @c TeX-master: "guile.texi" | |
786 | @c End: |