@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009, 2010, 2012
+@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2009, 2010, 2012, 2013
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@deffn {Scheme Procedure} thread? obj
@deffnx {C Function} scm_thread_p (obj)
-Return @code{#t} iff @var{obj} is a thread; otherwise, return
+Return @code{#t} ff @var{obj} is a thread; otherwise, return
@code{#f}.
@end deffn
@deffn {Scheme Procedure} thread-exited? thread
@deffnx {C Function} scm_thread_exited_p (thread)
-Return @code{#t} iff @var{thread} has exited.
+Return @code{#t} if @var{thread} has exited, or @code{#f} otherwise.
@end deffn
@c begin (texi-doc-string "guile" "yield")
@deffn {Scheme Procedure} mutex? obj
@deffnx {C Function} scm_mutex_p (obj)
-Return @code{#t} iff @var{obj} is a mutex; otherwise, return
+Return @code{#t} if @var{obj} is a mutex; otherwise, return
@code{#f}.
@end deffn
@code{wait-condition-variable}, except that the mutex is left in an
unlocked state when the function returns.)
-When @var{timeout} is also given, it specifies a point in time where
-the waiting should be aborted. It can be either an integer as
-returned by @code{current-time} or a pair as returned by
+When @var{timeout} is also given and not false, it specifies a point in
+time where the waiting should be aborted. It can be either an integer
+as returned by @code{current-time} or a pair as returned by
@code{gettimeofday}. When the waiting is aborted, @code{#f} is
returned. Otherwise the function returns @code{#t}.
@end deffn
@deffn {Scheme Procedure} condition-variable? obj
@deffnx {C Function} scm_condition_variable_p (obj)
-Return @code{#t} iff @var{obj} is a condition variable; otherwise,
+Return @code{#t} if @var{obj} is a condition variable; otherwise,
return @code{#f}.
@end deffn
@deffn {Scheme Procedure} fluid? obj
@deffnx {C Function} scm_fluid_p (obj)
-Return @code{#t} iff @var{obj} is a fluid; otherwise, return
+Return @code{#t} if @var{obj} is a fluid; otherwise, return
@code{#f}.
@end deffn
@deffn {Scheme Procedure} fluid-bound? fluid
@deffnx {C Function} scm_fluid_bound_p (fluid)
-Returns @code{#t} iff the given fluid is bound to a value, otherwise
+Returns @code{#t} if the given fluid is bound to a value, otherwise
@code{#f}.
@end deffn
affect. And introducing a new setting to existing code is often easier
with a parameter object than adding arguments.
-@defun make-parameter init [converter]
+@deffn {Scheme Procedure} make-parameter init [converter]
Return a new parameter object, with initial value @var{init}.
If a @var{converter} is given, then a call @code{(@var{converter}
(my-param 0.75)
(my-param) @result{} 3/4
@end example
-@end defun
+@end deffn
@deffn {library syntax} parameterize ((param value) @dots{}) body1 body2 @dots{}
Establish a new dynamic scope with the given @var{param}s bound to new
separate initial location in each dynamic state, all initialized to the
given @var{init} value.
+New code should probably just use parameters instead of fluids, because
+the interface is better. But for migrating old code or otherwise
+providing interoperability, Guile provides the @code{fluid->parameter}
+procedure:
+
+@deffn {Scheme Procedure} fluid->parameter fluid [conv]
+Make a parameter that wraps a fluid.
+
+The value of the parameter will be the same as the value of the fluid.
+If the parameter is rebound in some dynamic extent, perhaps via
+@code{parameterize}, the new value will be run through the optional
+@var{conv} procedure, as with any parameter. Note that unlike
+@code{make-parameter}, @var{conv} is not applied to the initial value.
+@end deffn
+
As alluded to above, because each thread usually has a separate dynamic
state, each thread has its own locations behind parameter objects, and
changes in one thread are not visible to any other. When a new dynamic
done in parallel with that of the other @code{find} call, which can
reduce the execution time of @code{find-prime}.
+Futures may be nested: a future can itself spawn and then @code{touch}
+other futures, leading to a directed acyclic graph of futures. Using
+this facility, a parallel @code{map} procedure can be defined along
+these lines:
+
+@lisp
+(use-modules (ice-9 futures) (ice-9 match))
+
+(define (par-map proc lst)
+ (match lst
+ (()
+ '())
+ ((head tail ...)
+ (let ((tail (future (par-map proc tail)))
+ (head (proc head)))
+ (cons head (touch tail))))))
+@end lisp
+
Note that futures are intended for the evaluation of purely functional
expressions. Expressions that have side-effects or rely on I/O may
require additional care, such as explicit synchronization
for the main thread. The number of available CPU cores is determined
using @code{current-processor-count} (@pxref{Processes}).
+When a thread touches a future that has not completed yet, it processes
+any pending future while waiting for it to complete, or just waits if
+there are no pending futures. When @code{touch} is called from within a
+future, the execution of the calling future is suspended, allowing its
+host thread to process other futures, and resumed when the touched
+future has completed. This suspend/resume is achieved by capturing the
+calling future's continuation, and later reinstating it (@pxref{Prompts,
+delimited continuations}).
+
+Note that @code{par-map} above is not tail-recursive. This could lead
+to stack overflows when @var{lst} is large compared to
+@code{(current-processor-count)}. To address that, @code{touch} uses
+the suspend mechanism described above to limit the number of nested
+futures executing on the same stack. Thus, the above code should never
+run into stack overflows.
+
@deffn {Scheme Syntax} future exp
Return a future for expression @var{exp}. This is equivalent to:
If the result was already computed in parallel, @code{touch} returns
instantaneously. Otherwise, it waits for the computation to complete,
-if it already started, or initiates it.
+if it already started, or initiates it. In the former case, the calling
+thread may process other futures in the meantime.
@end deffn