libguile-concepts.texi 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  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, 2005
  4. @c Free Software Foundation, Inc.
  5. @c See the file guile.texi for copying conditions.
  6. @page
  7. @node General Libguile Concepts
  8. @section General concepts for using libguile
  9. When you want to embed the Guile Scheme interpreter into your program or
  10. library, you need to link it against the @file{libguile} library
  11. (@pxref{Linking Programs With Guile}). Once you have done this, your C
  12. code has access to a number of data types and functions that can be used
  13. to invoke the interpreter, or make new functions that you have written
  14. in C available to be called from Scheme code, among other things.
  15. Scheme is different from C in a number of significant ways, and Guile
  16. tries to make the advantages of Scheme available to C as well. Thus, in
  17. addition to a Scheme interpreter, libguile also offers dynamic types,
  18. garbage collection, continuations, arithmetic on arbitrary sized
  19. numbers, and other things.
  20. The two fundamental concepts are dynamic types and garbage collection.
  21. You need to understand how libguile offers them to C programs in order
  22. to use the rest of libguile. Also, the more general control flow of
  23. Scheme caused by continuations needs to be dealt with.
  24. Running asynchronous signal handlers and multi-threading is known to C
  25. code already, but there are of course a few additional rules when using
  26. them together with libguile.
  27. @menu
  28. * Dynamic Types:: Dynamic Types.
  29. * Garbage Collection:: Garbage Collection.
  30. * Control Flow:: Control Flow.
  31. * Asynchronous Signals:: Asynchronous Signals
  32. * Multi-Threading:: Multi-Threading
  33. @end menu
  34. @node Dynamic Types
  35. @subsection Dynamic Types
  36. Scheme is a dynamically-typed language; this means that the system
  37. cannot, in general, determine the type of a given expression at compile
  38. time. Types only become apparent at run time. Variables do not have
  39. fixed types; a variable may hold a pair at one point, an integer at the
  40. next, and a thousand-element vector later. Instead, values, not
  41. variables, have fixed types.
  42. In order to implement standard Scheme functions like @code{pair?} and
  43. @code{string?} and provide garbage collection, the representation of
  44. every value must contain enough information to accurately determine its
  45. type at run time. Often, Scheme systems also use this information to
  46. determine whether a program has attempted to apply an operation to an
  47. inappropriately typed value (such as taking the @code{car} of a string).
  48. Because variables, pairs, and vectors may hold values of any type,
  49. Scheme implementations use a uniform representation for values --- a
  50. single type large enough to hold either a complete value or a pointer
  51. to a complete value, along with the necessary typing information.
  52. In Guile, this uniform representation of all Scheme values is the C type
  53. @code{SCM}. This is an opaque type and its size is typically equivalent
  54. to that of a pointer to @code{void}. Thus, @code{SCM} values can be
  55. passed around efficiently and they take up reasonably little storage on
  56. their own.
  57. The most important rule is: You never access a @code{SCM} value
  58. directly; you only pass it to functions or macros defined in libguile.
  59. As an obvious example, although a @code{SCM} variable can contain
  60. integers, you can of course not compute the sum of two @code{SCM} values
  61. by adding them with the C @code{+} operator. You must use the libguile
  62. function @code{scm_sum}.
  63. Less obvious and therefore more important to keep in mind is that you
  64. also cannot directly test @code{SCM} values for trueness. In Scheme,
  65. the value @code{#f} is considered false and of course a @code{SCM}
  66. variable can represent that value. But there is no guarantee that the
  67. @code{SCM} representation of @code{#f} looks false to C code as well.
  68. You need to use @code{scm_is_true} or @code{scm_is_false} to test a
  69. @code{SCM} value for trueness or falseness, respectively.
  70. You also can not directly compare two @code{SCM} values to find out
  71. whether they are identical (that is, whether they are @code{eq?} in
  72. Scheme terms). You need to use @code{scm_is_eq} for this.
  73. The one exception is that you can directly assign a @code{SCM} value to
  74. a @code{SCM} variable by using the C @code{=} operator.
  75. The following (contrived) example shows how to do it right. It
  76. implements a function of two arguments (@var{a} and @var{flag}) that
  77. returns @var{a}+1 if @var{flag} is true, else it returns @var{a}
  78. unchanged.
  79. @example
  80. SCM
  81. my_incrementing_function (SCM a, SCM flag)
  82. @{
  83. SCM result;
  84. if (scm_is_true (flag))
  85. result = scm_sum (a, scm_from_int (1));
  86. else
  87. result = a;
  88. return result;
  89. @}
  90. @end example
  91. Often, you need to convert between @code{SCM} values and approriate C
  92. values. For example, we needed to convert the integer @code{1} to its
  93. @code{SCM} representation in order to add it to @var{a}. Libguile
  94. provides many function to do these conversions, both from C to
  95. @code{SCM} and from @code{SCM} to C.
  96. The conversion functions follow a common naming pattern: those that make
  97. a @code{SCM} value from a C value have names of the form
  98. @code{scm_from_@var{type} (@dots{})} and those that convert a @code{SCM}
  99. value to a C value use the form @code{scm_to_@var{type} (@dots{})}.
  100. However, it is best to avoid converting values when you can. When you
  101. must combine C values and @code{SCM} values in a computation, it is
  102. often better to convert the C values to @code{SCM} values and do the
  103. computation by using libguile functions than to the other way around
  104. (converting @code{SCM} to C and doing the computation some other way).
  105. As a simple example, consider this version of
  106. @code{my_incrementing_function} from above:
  107. @example
  108. SCM
  109. my_other_incrementing_function (SCM a, SCM flag)
  110. @{
  111. int result;
  112. if (scm_is_true (flag))
  113. result = scm_to_int (a) + 1;
  114. else
  115. result = scm_to_int (a);
  116. return scm_from_int (result);
  117. @}
  118. @end example
  119. This version is much less general than the original one: it will only
  120. work for values @var{A} that can fit into a @code{int}. The original
  121. function will work for all values that Guile can represent and that
  122. @code{scm_sum} can understand, including integers bigger than @code{long
  123. long}, floating point numbers, complex numbers, and new numerical types
  124. that have been added to Guile by third-party libraries.
  125. Also, computing with @code{SCM} is not necessarily inefficient. Small
  126. integers will be encoded directly in the @code{SCM} value, for example,
  127. and do not need any additional memory on the heap. See @ref{Data
  128. Representation} to find out the details.
  129. Some special @code{SCM} values are available to C code without needing
  130. to convert them from C values:
  131. @multitable {Scheme value} {C representation}
  132. @item Scheme value @tab C representation
  133. @item @nicode{#f} @tab @nicode{SCM_BOOL_F}
  134. @item @nicode{#t} @tab @nicode{SCM_BOOL_T}
  135. @item @nicode{()} @tab @nicode{SCM_EOL}
  136. @end multitable
  137. In addition to @code{SCM}, Guile also defines the related type
  138. @code{scm_t_bits}. This is an unsigned integral type of sufficient
  139. size to hold all information that is directly contained in a
  140. @code{SCM} value. The @code{scm_t_bits} type is used internally by
  141. Guile to do all the bit twiddling explained in @ref{Data
  142. Representation}, but you will encounter it occasionally in low-level
  143. user code as well.
  144. @node Garbage Collection
  145. @subsection Garbage Collection
  146. As explained above, the @code{SCM} type can represent all Scheme values.
  147. Some values fit entirely into a @code{SCM} value (such as small
  148. integers), but other values require additional storage in the heap (such
  149. as strings and vectors). This additional storage is managed
  150. automatically by Guile. You don't need to explicitely deallocate it
  151. when a @code{SCM} value is no longer used.
  152. Two things must be guaranteed so that Guile is able to manage the
  153. storage automatically: it must know about all blocks of memory that have
  154. ever been allocated for Scheme values, and it must know about all Scheme
  155. values that are still being used. Given this knowledge, Guile can
  156. periodically free all blocks that have been allocated but are not used
  157. by any active Scheme values. This activity is called @dfn{garbage
  158. collection}.
  159. It is easy for Guile to remember all blocks of memory that it has
  160. allocated for use by Scheme values, but you need to help it with finding
  161. all Scheme values that are in use by C code.
  162. You do this when writing a SMOB mark function, for example
  163. (@pxref{Garbage Collecting Smobs}). By calling this function, the
  164. garbage collector learns about all references that your SMOB has to
  165. other @code{SCM} values.
  166. Other references to @code{SCM} objects, such as global variables of type
  167. @code{SCM} or other random data structures in the heap that contain
  168. fields of type @code{SCM}, can be made visible to the garbage collector
  169. by calling the functions @code{scm_gc_protect} or
  170. @code{scm_permanent_object}. You normally use these funtions for long
  171. lived objects such as a hash table that is stored in a global variable.
  172. For temporary references in local variables or function arguments, using
  173. these functions would be too expensive.
  174. These references are handled differently: Local variables (and function
  175. arguments) of type @code{SCM} are automatically visible to the garbage
  176. collector. This works because the collector scans the stack for
  177. potential references to @code{SCM} objects and considers all referenced
  178. objects to be alive. The scanning considers each and every word of the
  179. stack, regardless of what it is actually used for, and then decides
  180. whether it could possibly be a reference to a @code{SCM} object. Thus,
  181. the scanning is guaranteed to find all actual references, but it might
  182. also find words that only accidentally look like references. These
  183. `false positives' might keep @code{SCM} objects alive that would
  184. otherwise be considered dead. While this might waste memory, keeping an
  185. object around longer than it strictly needs to is harmless. This is why
  186. this technique is called ``conservative garbage collection''. In
  187. practice, the wasted memory seems to be no problem.
  188. The stack of every thread is scanned in this way and the registers of
  189. the CPU and all other memory locations where local variables or function
  190. parameters might show up are included in this scan as well.
  191. The consequence of the conservative scanning is that you can just
  192. declare local variables and function parameters of type @code{SCM} and
  193. be sure that the garbage collector will not free the corresponding
  194. objects.
  195. However, a local variable or function parameter is only protected as
  196. long as it is really on the stack (or in some register). As an
  197. optimization, the C compiler might reuse its location for some other
  198. value and the @code{SCM} object would no longer be protected. Normally,
  199. this leads to exactly the right behabvior: the compiler will only
  200. overwrite a reference when it is no longer needed and thus the object
  201. becomes unprotected precisely when the reference disappears, just as
  202. wanted.
  203. There are situations, however, where a @code{SCM} object needs to be
  204. around longer than its reference from a local variable or function
  205. parameter. This happens, for example, when you retrieve some pointer
  206. from a smob and work with that pointer directly. The reference to the
  207. @code{SCM} smob object might be dead after the pointer has been
  208. retrieved, but the pointer itself (and the memory pointed to) is still
  209. in use and thus the smob object must be protected. The compiler does
  210. not know about this connection and might overwrite the @code{SCM}
  211. reference too early.
  212. To get around this problem, you can use @code{scm_remember_upto_here_1}
  213. and its cousins. It will keep the compiler from overwriting the
  214. reference. For a typical example of its use, see @ref{Remembering
  215. During Operations}.
  216. @node Control Flow
  217. @subsection Control Flow
  218. Scheme has a more general view of program flow than C, both locally and
  219. non-locally.
  220. Controlling the local flow of control involves things like gotos, loops,
  221. calling functions and returning from them. Non-local control flow
  222. refers to situations where the program jumps across one or more levels
  223. of function activations without using the normal call or return
  224. operations.
  225. The primitive means of C for local control flow is the @code{goto}
  226. statement, together with @code{if}. Loops done with @code{for},
  227. @code{while} or @code{do} could in principle be rewritten with just
  228. @code{goto} and @code{if}. In Scheme, the primitive means for local
  229. control flow is the @emph{function call} (together with @code{if}).
  230. Thus, the repetition of some computation in a loop is ultimately
  231. implemented by a function that calls itself, that is, by recursion.
  232. This approach is theoretically very powerful since it is easier to
  233. reason formally about recursion than about gotos. In C, using
  234. recursion exclusively would not be practical, though, since it would eat
  235. up the stack very quickly. In Scheme, however, it is practical:
  236. function calls that appear in a @dfn{tail position} do not use any
  237. additional stack space (@pxref{Tail Calls}).
  238. A function call is in a tail position when it is the last thing the
  239. calling function does. The value returned by the called function is
  240. immediately returned from the calling function. In the following
  241. example, the call to @code{bar-1} is in a tail position, while the
  242. call to @code{bar-2} is not. (The call to @code{1-} in @code{foo-2}
  243. is in a tail position, though.)
  244. @lisp
  245. (define (foo-1 x)
  246. (bar-1 (1- x)))
  247. (define (foo-2 x)
  248. (1- (bar-2 x)))
  249. @end lisp
  250. Thus, when you take care to recurse only in tail positions, the
  251. recursion will only use constant stack space and will be as good as a
  252. loop constructed from gotos.
  253. Scheme offers a few syntactic abstractions (@code{do} and @dfn{named}
  254. @code{let}) that make writing loops slightly easier.
  255. But only Scheme functions can call other functions in a tail position:
  256. C functions can not. This matters when you have, say, two functions
  257. that call each other recursively to form a common loop. The following
  258. (unrealistic) example shows how one might go about determing whether a
  259. non-negative integer @var{n} is even or odd.
  260. @lisp
  261. (define (my-even? n)
  262. (cond ((zero? n) #t)
  263. (else (my-odd? (1- n)))))
  264. (define (my-odd? n)
  265. (cond ((zero? n) #f)
  266. (else (my-even? (1- n)))))
  267. @end lisp
  268. Because the calls to @code{my-even?} and @code{my-odd?} are in tail
  269. positions, these two procedures can be applied to arbitrary large
  270. integers without overflowing the stack. (They will still take a lot
  271. of time, of course.)
  272. However, when one or both of the two procedures would be rewritten in
  273. C, it could no longer call its companion in a tail position (since C
  274. does not have this concept). You might need to take this
  275. consideration into account when deciding which parts of your program
  276. to write in Scheme and which in C.
  277. In addition to calling functions and returning from them, a Scheme
  278. program can also exit non-locally from a function so that the control
  279. flow returns directly to an outer level. This means that some functions
  280. might not return at all.
  281. Even more, it is not only possible to jump to some outer level of
  282. control, a Scheme program can also jump back into the middle of a
  283. function that has already exited. This might cause some functions to
  284. return more than once.
  285. In general, these non-local jumps are done by invoking
  286. @dfn{continuations} that have previously been captured using
  287. @code{call-with-current-continuation}. Guile also offers a slightly
  288. restricted set of functions, @code{catch} and @code{throw}, that can
  289. only be used for non-local exits. This restriction makes them more
  290. efficient. Error reporting (with the function @code{error}) is
  291. implemented by invoking @code{throw}, for example. The functions
  292. @code{catch} and @code{throw} belong to the topic of @dfn{exceptions}.
  293. Since Scheme functions can call C functions and vice versa, C code can
  294. experience the more general control flow of Scheme as well. It is
  295. possible that a C function will not return at all, or will return more
  296. than once. While C does offer @code{setjmp} and @code{longjmp} for
  297. non-local exits, it is still an unusual thing for C code. In
  298. contrast, non-local exits are very common in Scheme, mostly to report
  299. errors.
  300. You need to be prepared for the non-local jumps in the control flow
  301. whenever you use a function from @code{libguile}: it is best to assume
  302. that any @code{libguile} function might signal an error or run a pending
  303. signal handler (which in turn can do arbitrary things).
  304. It is often necessary to take cleanup actions when the control leaves a
  305. function non-locally. Also, when the control returns non-locally, some
  306. setup actions might be called for. For example, the Scheme function
  307. @code{with-output-to-port} needs to modify the global state so that
  308. @code{current-output-port} returns the port passed to
  309. @code{with-output-to-port}. The global output port needs to be reset to
  310. its previous value when @code{with-output-to-port} returns normally or
  311. when it is exited non-locally. Likewise, the port needs to be set again
  312. when control enters non-locally.
  313. Scheme code can use the @code{dynamic-wind} function to arrange for
  314. the setting and resetting of the global state. C code can use the
  315. corresponding @code{scm_internal_dynamic_wind} function, or a
  316. @code{scm_dynwind_begin}/@code{scm_dynwind_end} pair together with
  317. suitable 'dynwind actions' (@pxref{Dynamic Wind}).
  318. Instead of coping with non-local control flow, you can also prevent it
  319. by erecting a @emph{continuation barrier}, @xref{Continuation
  320. Barriers}. The function @code{scm_c_with_continuation_barrier}, for
  321. example, is guaranteed to return exactly once.
  322. @node Asynchronous Signals
  323. @subsection Asynchronous Signals
  324. You can not call libguile functions from handlers for POSIX signals, but
  325. you can register Scheme handlers for POSIX signals such as
  326. @code{SIGINT}. These handlers do not run during the actual signal
  327. delivery. Instead, they are run when the program (more precisely, the
  328. thread that the handler has been registered for) reaches the next
  329. @emph{safe point}.
  330. The libguile functions themselves have many such safe points.
  331. Consequently, you must be prepared for arbitrary actions anytime you
  332. call a libguile function. For example, even @code{scm_cons} can contain
  333. a safe point and when a signal handler is pending for your thread,
  334. calling @code{scm_cons} will run this handler and anything might happen,
  335. including a non-local exit although @code{scm_cons} would not ordinarily
  336. do such a thing on its own.
  337. If you do not want to allow the running of asynchronous signal handlers,
  338. you can block them temporarily with @code{scm_dynwind_block_asyncs}, for
  339. example. See @xref{System asyncs}.
  340. Since signal handling in Guile relies on safe points, you need to make
  341. sure that your functions do offer enough of them. Normally, calling
  342. libguile functions in the normal course of action is all that is needed.
  343. But when a thread might spent a long time in a code section that calls
  344. no libguile function, it is good to include explicit safe points. This
  345. can allow the user to interrupt your code with @key{C-c}, for example.
  346. You can do this with the macro @code{SCM_TICK}. This macro is
  347. syntactically a statement. That is, you could use it like this:
  348. @example
  349. while (1)
  350. @{
  351. SCM_TICK;
  352. do_some_work ();
  353. @}
  354. @end example
  355. Frequent execution of a safe point is even more important in multi
  356. threaded programs, @xref{Multi-Threading}.
  357. @node Multi-Threading
  358. @subsection Multi-Threading
  359. Guile can be used in multi-threaded programs just as well as in
  360. single-threaded ones.
  361. Each thread that wants to use functions from libguile must put itself
  362. into @emph{guile mode} and must then follow a few rules. If it doesn't
  363. want to honor these rules in certain situations, a thread can
  364. temporarily leave guile mode (but can no longer use libguile functions
  365. during that time, of course).
  366. Threads enter guile mode by calling @code{scm_with_guile},
  367. @code{scm_boot_guile}, or @code{scm_init_guile}. As explained in the
  368. reference documentation for these functions, Guile will then learn about
  369. the stack bounds of the thread and can protect the @code{SCM} values
  370. that are stored in local variables. When a thread puts itself into
  371. guile mode for the first time, it gets a Scheme representation and is
  372. listed by @code{all-threads}, for example.
  373. While in guile mode, a thread promises to reach a safe point
  374. reasonably frequently (@pxref{Asynchronous Signals}). In addition to
  375. running signal handlers, these points are also potential rendezvous
  376. points of all guile mode threads where Guile can orchestrate global
  377. things like garbage collection. Consequently, when a thread in guile
  378. mode blocks and does no longer frequent safe points, it might cause
  379. all other guile mode threads to block as well. To prevent this from
  380. happening, a guile mode thread should either only block in libguile
  381. functions (who know how to do it right), or should temporarily leave
  382. guile mode with @code{scm_without_guile}.
  383. For some common blocking operations, Guile provides convenience
  384. functions. For example, if you want to lock a pthread mutex while in
  385. guile mode, you might want to use @code{scm_pthread_mutex_lock} which is
  386. just like @code{pthread_mutex_lock} except that it leaves guile mode
  387. while blocking.
  388. All libguile functions are (intended to be) robust in the face of
  389. multiple threads using them concurrently. This means that there is no
  390. risk of the internal data structures of libguile becoming corrupted in
  391. such a way that the process crashes.
  392. A program might still produce non-sensical results, though. Taking
  393. hashtables as an example, Guile guarantees that you can use them from
  394. multiple threads concurrently and a hashtable will always remain a valid
  395. hashtable and Guile will not crash when you access it. It does not
  396. guarantee, however, that inserting into it concurrently from two threads
  397. will give useful results: only one insertion might actually happen, none
  398. might happen, or the table might in general be modified in a totally
  399. arbitrary manner. (It will still be a valid hashtable, but not the one
  400. that you might have expected.) Guile might also signal an error when it
  401. detects a harmful race condition.
  402. Thus, you need to put in additional synchronizations when multiple
  403. threads want to use a single hashtable, or any other mutable Scheme
  404. object.
  405. When writing C code for use with libguile, you should try to make it
  406. robust as well. An example that converts a list into a vector will help
  407. to illustrate. Here is a correct version:
  408. @example
  409. SCM
  410. my_list_to_vector (SCM list)
  411. @{
  412. SCM vector = scm_make_vector (scm_length (list), SCM_UNDEFINED);
  413. size_t len, i;
  414. len = SCM_SIMPLE_VECTOR_LENGTH (vector);
  415. i = 0;
  416. while (i < len && scm_is_pair (list))
  417. @{
  418. SCM_SIMPLE_VECTOR_SET (vector, i, SCM_CAR (list));
  419. list = SCM_CDR (list);
  420. i++;
  421. @}
  422. return vector;
  423. @}
  424. @end example
  425. The first thing to note is that storing into a @code{SCM} location
  426. concurrently from multiple threads is guaranteed to be robust: you don't
  427. know which value wins but it will in any case be a valid @code{SCM}
  428. value.
  429. But there is no guarantee that the list referenced by @var{list} is not
  430. modified in another thread while the loop iterates over it. Thus, while
  431. copying its elements into the vector, the list might get longer or
  432. shorter. For this reason, the loop must check both that it doesn't
  433. overrun the vector (@code{SCM_SIMPLE_VECTOR_SET} does no range-checking)
  434. and that it doesn't overrung the list (@code{SCM_CAR} and @code{SCM_CDR}
  435. likewise do no type checking).
  436. It is safe to use @code{SCM_CAR} and @code{SCM_CDR} on the local
  437. variable @var{list} once it is known that the variable contains a pair.
  438. The contents of the pair might change spontaneously, but it will always
  439. stay a valid pair (and a local variable will of course not spontaneously
  440. point to a different Scheme object).
  441. Likewise, a simple vector such as the one returned by
  442. @code{scm_make_vector} is guaranteed to always stay the same length so
  443. that it is safe to only use SCM_SIMPLE_VECTOR_LENGTH once and store the
  444. result. (In the example, @var{vector} is safe anyway since it is a
  445. fresh object that no other thread can possibly know about until it is
  446. returned from @code{my_list_to_vector}.)
  447. Of course the behavior of @code{my_list_to_vector} is suboptimal when
  448. @var{list} does indeed get asynchronously lengthened or shortened in
  449. another thread. But it is robust: it will always return a valid vector.
  450. That vector might be shorter than expected, or its last elements might
  451. be unspecified, but it is a valid vector and if a program wants to rule
  452. out these cases, it must avoid modifying the list asynchronously.
  453. Here is another version that is also correct:
  454. @example
  455. SCM
  456. my_pedantic_list_to_vector (SCM list)
  457. @{
  458. SCM vector = scm_make_vector (scm_length (list), SCM_UNDEFINED);
  459. size_t len, i;
  460. len = SCM_SIMPLE_VECTOR_LENGTH (vector);
  461. i = 0;
  462. while (i < len)
  463. @{
  464. SCM_SIMPLE_VECTOR_SET (vector, i, scm_car (list));
  465. list = scm_cdr (list);
  466. i++;
  467. @}
  468. return vector;
  469. @}
  470. @end example
  471. This version uses the type-checking and thread-robust functions
  472. @code{scm_car} and @code{scm_cdr} instead of the faster, but less robust
  473. macros @code{SCM_CAR} and @code{SCM_CDR}. When the list is shortened
  474. (that is, when @var{list} holds a non-pair), @code{scm_car} will throw
  475. an error. This might be preferable to just returning a half-initialized
  476. vector.
  477. The API for accessing vectors and arrays of various kinds from C takes a
  478. slightly different approach to thread-robustness. In order to get at
  479. the raw memory that stores the elements of an array, you need to
  480. @emph{reserve} that array as long as you need the raw memory. During
  481. the time an array is reserved, its elements can still spontaneously
  482. change their values, but the memory itself and other things like the
  483. size of the array are guaranteed to stay fixed. Any operation that
  484. would change these parameters of an array that is currently reserved
  485. will signal an error. In order to avoid these errors, a program should
  486. of course put suitable synchronization mechanisms in place. As you can
  487. see, Guile itself is again only concerned about robustness, not about
  488. correctness: without proper synchronization, your program will likely
  489. not be correct, but the worst consequence is an error message.
  490. Real thread-safeness often requires that a critical section of code is
  491. executed in a certain restricted manner. A common requirement is that
  492. the code section is not entered a second time when it is already being
  493. executed. Locking a mutex while in that section ensures that no other
  494. thread will start executing it, blocking asyncs ensures that no
  495. asynchronous code enters the section again from the current thread,
  496. and the error checking of Guile mutexes guarantees that an error is
  497. signalled when the current thread accidentally reenters the critical
  498. section via recursive function calls.
  499. Guile provides two mechanisms to support critical sections as outlined
  500. above. You can either use the macros
  501. @code{SCM_CRITICAL_SECTION_START} and @code{SCM_CRITICAL_SECTION_END}
  502. for very simple sections; or use a dynwind context together with a
  503. call to @code{scm_dynwind_critical_section}.
  504. The macros only work reliably for critical sections that are
  505. guaranteed to not cause a non-local exit. They also do not detect an
  506. accidental reentry by the current thread. Thus, you should probably
  507. only use them to delimit critical sections that do not contain calls
  508. to libguile functions or to other external functions that might do
  509. complicated things.
  510. The function @code{scm_dynwind_critical_section}, on the other hand,
  511. will correctly deal with non-local exits because it requires a dynwind
  512. context. Also, by using a separate mutex for each critical section,
  513. it can detect accidental reentries.