mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-02 04:40:29 +02:00
multiple values, added docs for `receive'. (begin): Documented `begin'. (if cond case): Documented `if', `cond' and `case'. (and or): Documented `and' and `or'. (while do): Documented `do' and `while'. * scheme-procedures.texi (Optional Arguments): Split the node, added introductory text, added menu for subsections. (let-optional Reference, let-keywords Reference), (lambda* Reference, define* Reference): Added syntax documentation for all exported procedures from (ice-9 optargs).
579 lines
20 KiB
Text
579 lines
20 KiB
Text
@page
|
|
@node Procedures and Macros
|
|
@chapter Procedures and Macros
|
|
|
|
@menu
|
|
* Lambda:: Basic procedure creation using lambda.
|
|
* Optional Arguments:: Handling keyword, optional and rest arguments.
|
|
* Procedure Properties:: Procedure properties and metainformation.
|
|
* Procedures with Setters:: Procedures with setters.
|
|
* Macros:: Macros.
|
|
@end menu
|
|
|
|
|
|
@node Lambda
|
|
@section Lambda: Basic Procedure Creation
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
A @code{lambda} expression evaluates to a procedure. The environment
|
|
which is in effect when a @code{lambda} expression is evaluated is
|
|
enclosed in the newly created procedure, this is referred to as a
|
|
@dfn{closure} (@pxref{About Closure}).
|
|
|
|
When a procedure created by @code{lambda} is called with some actual
|
|
arguments, the environment enclosed in the procedure is extended by
|
|
binding the variables named in the formal argument list to new locations
|
|
and storing the actual arguments into these locations. Then the body of
|
|
the @code{lambda} expression is evaluation sequentially. The result of
|
|
the last expression in the procedure body is then the result of the
|
|
procedure invocation.
|
|
|
|
The following examples will show how procedures can be created using
|
|
@code{lambda}, and what you can do with these procedures.
|
|
|
|
@lisp
|
|
(lambda (x) (+ x x)) @result{} @r{a procedure}
|
|
((lambda (x) (+ x x)) 4) @result{} 8
|
|
@end lisp
|
|
|
|
The fact that the environment in effect when creating a procedure is
|
|
enclosed in the procedure is shown with this example:
|
|
|
|
@lisp
|
|
(define add4
|
|
(let ((x 4))
|
|
(lambda (y) (+ x y))))
|
|
(add4 6) @result{} 10
|
|
@end lisp
|
|
|
|
|
|
@deffn syntax lambda formals body
|
|
@var{formals} should be a formal argument list as described in the
|
|
following table.
|
|
|
|
@table @code
|
|
@item (@var{variable1} @dots{})
|
|
The procedure takes a fixed number of arguments; when the procedure is
|
|
called, the arguments will be stored into the newly created location for
|
|
the formal variables.
|
|
@item @var{variable}
|
|
The procedure takes any number of arguments; when the procedure is
|
|
called, the sequence of actual arguments will converted into a list and
|
|
stored into the newly created location for the formal variable.
|
|
@item (@var{variable1} @dots{} @var{variablen} . @var{variablen+1})
|
|
If a space--delimited period precedes the last variable, then the
|
|
procedure takes @var{n} or more variablesm where @var{n} is the number
|
|
of formal arguments before the period. There must be at least one
|
|
argument before the period. The first @var{n} actual arguments will be
|
|
stored into the newly allocated locations for the first @var{n} formal
|
|
arguments and the sequence of the remaining actual arguments is
|
|
converted into a list and the stored into the location for the last
|
|
formal argument. If there are exactly @var{n} actual arguments, the
|
|
empty list is stored into the location of the last formal argument.
|
|
@end table
|
|
|
|
@var{body} is a sequence of Scheme expressions which are evaluated in
|
|
order when the procedure is invoked.
|
|
@end deffn
|
|
|
|
|
|
@node Optional Arguments
|
|
@section Optional Arguments
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
Scheme procedures, as defined in R5RS, can wither handle a fixed number
|
|
of actual arguments, or a fixed number of actual arguments followed by
|
|
arbitrarily many additional arguments. Writing procedures of variable
|
|
arity can be useful, but unfortunately, the syntactic means for handling
|
|
argument lists of varying length is a bit inconvenient. It is possible
|
|
to give names to the fixed number of argument, but the remaining
|
|
(optional) arguments can be only referenced as a list of values
|
|
(@pxref{Lambda}).
|
|
|
|
Guile comes with the module @code{(ice-9 optargs)}, which makes using
|
|
optional arguments much more convenient. In addition, this module
|
|
provides syntax for handling keywords in argument lists
|
|
(@pxref{Keywords}).
|
|
|
|
Before using any of the procedures or macros defined in this section,
|
|
you have to load the module @code{(ice-9 optargs)} with the statement:
|
|
|
|
@lisp
|
|
(use-modules (ice-9 optargs))
|
|
@end lisp
|
|
|
|
@menu
|
|
* let-optional Reference:: Locally binding optional arguments.
|
|
* let-keywords Reference:: Locally binding keywords arguments.
|
|
* lambda* Reference:: Creating advanced argument handling procedures.
|
|
* define* Reference:: Defining procedures and macros.
|
|
@end menu
|
|
|
|
|
|
@node let-optional Reference
|
|
@subsection let-optional Reference
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
The syntax @code{let-optional} and @code{let-optional*} are for
|
|
destructuring rest argument lists and giving names to the various list
|
|
elements. @code{let-optional} binds all variables simultaneously, while
|
|
@code{let-optional*} binds them sequentially, consistent with @code{let}
|
|
and @code{let*} (REFFIXME).
|
|
|
|
@deffn {libary syntax} let-optional rest-arg (binding @dots{}) expr @dots{}
|
|
@deffnx {library syntax} let-optional* rest-arg (binding @dots{}) expr @dots{}
|
|
These two macros give you an optional argument interface that is very
|
|
@dfn{Schemey} and introduces no fancy syntax. They are compatible with
|
|
the scsh macros of the same name, but are slightly extended. Each of
|
|
@var{binding} may be of one of the forms @var{var} or @code{(@var{var}
|
|
@var{default-value})}. @var{rest-arg} should be the rest-argument of the
|
|
procedures these are used from. The items in @var{rest-arg} are
|
|
sequentially bound to the variable names are given. When @var{rest-arg}
|
|
runs out, the remaining vars are bound either to the default values or
|
|
left unbound if no default value was specified. @var{rest-arg} remains
|
|
bound to whatever may have been left of @var{rest-arg}.
|
|
|
|
After binding the variables, the expressions @var{expr} @dots{} are
|
|
evaluated in order.
|
|
@end deffn
|
|
|
|
|
|
@node let-keywords Reference
|
|
@subsection let-keywords Reference
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
@code{let-keywords} and @code{let-keywords*} are used for extracting
|
|
values from argument lists which use keywords instead of argument
|
|
position for binding local variables to argument values.
|
|
|
|
@code{let-keywords} binds all variables simultaneously, while
|
|
@code{let-keywords*} binds them sequentially, consistent with @code{let}
|
|
and @code{let*} (REFFIXME).
|
|
|
|
@deffn {library syntax} let-keywords rest-arg allow-other-keys? (binding @dots{}) expr @dots{}
|
|
@deffnx {library syntax} let-keywords rest-arg allow-other-keys? (binding @dots{}) expr @dots{}
|
|
These macros pick out keyword arguments from @var{rest-arg}, but do not
|
|
modify it. This is consistent at least with Common Lisp, which
|
|
duplicates keyword arguments in the rest argument. More explanation of what
|
|
keyword arguments in a lambda list look like can be found below in
|
|
the documentation for @code{lambda*}
|
|
(@pxref{lambda* Reference}). @var{binding}s can have the same form as
|
|
for @code{let-optional}. If @var{allow-other-keys?} is false, an error
|
|
will be thrown if anything that looks like a keyword argument but does
|
|
not match a known keyword parameter will result in an error.
|
|
|
|
After binding the variables, the expressions @var{expr} @dots{} are
|
|
evaluated in order.
|
|
@end deffn
|
|
|
|
|
|
@node lambda* Reference
|
|
@subsection lambda* Reference
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
When using optional and keyword argument lists, using @code{lambda} for
|
|
creating procedures and using @code{let-optional} or @code{let-keywords}
|
|
is a bit lengthy. Therefore, @code{lambda*} is provided, which combines
|
|
the features of those macros into a single convenient syntax.
|
|
|
|
For quick reference, here is the syntax of the formal argument list for
|
|
@code{lambda*} (brackets are used to indicate grouping only):
|
|
|
|
@example
|
|
ext-param-list ::= [identifier]* [#:optional [ext-var-decl]+]?
|
|
[#:key [ext-var-decl]+ [#:allow-other-keys]?]?
|
|
[[#:rest identifier]|[. identifier]]?
|
|
|
|
ext-var-decl ::= identifier | ( identifier expression )
|
|
@end example
|
|
|
|
The characters `*', `+' and `?' are not to be taken literally; they mean
|
|
respectively, zero or more occurences, one or more occurences, and one
|
|
or zero occurences.
|
|
|
|
@deffn {library syntax} lambda* formals body
|
|
@code{lambda*} creates a procedure that takes optional arguments. These
|
|
are specified by putting them inside brackets at the end of the
|
|
paramater list, but before any dotted rest argument. For example,
|
|
|
|
@lisp
|
|
(lambda* (a b #:optional c d . e) '())
|
|
@end lisp
|
|
|
|
creates a procedure with fixed arguments @var{a} and @var{b}, optional
|
|
arguments @var{c} and @var{d}, and rest argument @var{e}. If the
|
|
optional arguments are omitted in a call, the variables for them are
|
|
unbound in the procedure. This can be checked with the @code{bound?}
|
|
macro (documented below).
|
|
|
|
@code{lambda*} can also take keyword arguments. For example, a procedure
|
|
defined like this:
|
|
|
|
@lisp
|
|
(lambda* (#:key xyzzy larch) '())
|
|
@end lisp
|
|
|
|
can be called with any of the argument lists @code{(#:xyzzy 11)}
|
|
@code{(#:larch 13)} @code{(#:larch 42 #:xyzzy 19)} @code{()}. Whichever
|
|
arguments are given as keywords are bound to values.
|
|
|
|
Optional and keyword arguments can also be given default values
|
|
which they take on when they are not present in a call, by giving a
|
|
two-item list in place of an optional argument, for example in:
|
|
|
|
@lisp
|
|
(lambda* (foo #:optional (bar 42) #:key (baz 73))
|
|
(list foo bar baz))
|
|
@end lisp
|
|
|
|
@var{foo} is a fixed argument, @var{bar} is an optional argument with
|
|
default value 42, and baz is a keyword argument with default value 73.
|
|
Default value expressions are not evaluated unless they are needed and
|
|
until the procedure is called.
|
|
|
|
@code{lambda*} also supports two more special parameter list keywords.
|
|
|
|
@code{lambda*}-defined procedures now throw an error by default if a
|
|
keyword other than one of those specified is found in the actual
|
|
passed arguments. However, specifying @code{#:allow-other-keys}
|
|
immediately after the keyword argument declarations restores the
|
|
previous behavior of ignoring unknown keywords. @code{lambda*} also now
|
|
guarantees that if the same keyword is passed more than once, the
|
|
last one passed is the one that takes effect. For example,
|
|
|
|
@lisp
|
|
((lambda* (#:key (heads 0) (tails 0)) (display (list heads tails)))
|
|
#:heads 37 #:tails 42 #:heads 99)
|
|
@end lisp
|
|
|
|
would result in (99 47) being displayed.
|
|
|
|
@code{#:rest} is also now provided as a synonym for the dotted syntax
|
|
rest argument. The argument lists @code{(a . b)} and @code{(a #:rest b)}
|
|
are equivalent in all respects to @code{lambda*}. This is provided for
|
|
more similarity to DSSSL, MIT-Scheme and Kawa among others, as well as
|
|
for refugees from other Lisp dialects.
|
|
@end deffn
|
|
|
|
@deffn {library syntax} bound? variable
|
|
Check if a variable is bound in the current environment.
|
|
|
|
The procedure @code{defined?} doesn't quite cut it as it stands, since
|
|
it only checks bindings in the top-level environment, not those in local
|
|
scope only.
|
|
@end deffn
|
|
|
|
|
|
@node define* Reference
|
|
@subsection define* Reference
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
Just like @code{define} has a shorthand notation for defining procedures
|
|
(@pxref{Lambda Alternatives}), @code{define*} is provided as an
|
|
abbreviation of the combination of @code{define} and @code{lambda*}.
|
|
|
|
@code{define*-public} is the @code{lambda*} version of
|
|
@code{define-public}; @code{defmacro*} and @code{defmacro*-public} exist
|
|
for defining macros with the improved argument list handling
|
|
possibilities. The @code{-public} versions not only define the
|
|
procedures/macros, but also export them from the current module.
|
|
|
|
@deffn {library syntax} define* formals body
|
|
@deffnx {library syntax} define*-public formals body
|
|
@code{define*} and @code{define*-public} support optional arguments with
|
|
a similar syntax to @code{lambda*}. They also support arbitrary-depth
|
|
currying, just like Guile's define. Some examples:
|
|
|
|
@lisp
|
|
(define* (x y #:optional a (z 3) #:key w . u)
|
|
(display (list y z u)))
|
|
@end lisp
|
|
defines a procedure @code{x} with a fixed argument @var{y}, an optional
|
|
agument @var{a}, another optional argument @var{z} with default value 3,
|
|
a keyword argument @var{w}, and a rest argument @var{u}.
|
|
|
|
@lisp
|
|
(define-public* ((foo #:optional bar) #:optional baz) '())
|
|
@end lisp
|
|
|
|
This illustrates currying. A procedure @code{foo} is defined, which,
|
|
when called with an optional argument @var{bar}, returns a procedure
|
|
that takes an optional argument @var{baz}.
|
|
|
|
Of course, @code{define*[-public]} also supports @code{#:rest} and
|
|
@code{#:allow-other-keys} in the same way as @code{lambda*}.
|
|
@end deffn
|
|
|
|
@deffn {library syntax} defmacro* name formals body
|
|
@deffnx {library syntax} defmacro*-public name formals body
|
|
These are just like @code{defmacro} and @code{defmacro-public} except that they
|
|
take @code{lambda*}-style extended paramter lists, where @code{#:optional},
|
|
@code{#:key}, @code{#:allow-other-keys} and @code{#:rest} are allowed with the usual
|
|
semantics. Here is an example of a macro with an optional argument:
|
|
|
|
@lisp
|
|
(defmacro* transmorgify (a #:optional b)
|
|
(a 1))
|
|
@end lisp
|
|
@end deffn
|
|
|
|
|
|
@node Procedure Properties
|
|
@section Procedure Properties and Metainformation
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
Procedures always have attached the environment in which they were
|
|
created and information about how to apply them to actual arguments. In
|
|
addition to that, properties and metainformation can be stored with
|
|
procedures. The procedures in this section can be used to test whether
|
|
a given procedure satisfies a condition; and to access and set a
|
|
procedure's property.
|
|
|
|
The first group of procedures are predicates to test whether a Scheme
|
|
object is a procedure, or a special procedure, respectively.
|
|
@code{procedure?} is the most general predicates, it returns @code{#t}
|
|
for any kind of procedure. @code{closure?} does not return @code{#t}
|
|
for primitive procedures, and @code{thunk?} only returns @code{#t} for
|
|
procedures which do not accept any arguments.
|
|
@c FIXME::martin: thunk? returns true for `id'. What's wrong here?
|
|
|
|
@rnindex procedure?
|
|
@deffn primitive procedure? obj
|
|
Return @code{#t} if @var{obj} is a procedure.
|
|
@end deffn
|
|
|
|
@deffn primitive closure? obj
|
|
Return @code{#t} if @var{obj} is a closure.
|
|
@end deffn
|
|
|
|
@deffn primitive thunk? obj
|
|
Return @code{#t} if @var{obj} is a thunk.
|
|
@end deffn
|
|
|
|
@c FIXME::martin: Is that true?
|
|
@cindex procedure properties
|
|
Procedure properties are general properties to be attached to
|
|
procedures. These can be the name of a procedure or other relevant
|
|
information, such as debug hints.
|
|
|
|
@deffn primitive procedure-properties proc
|
|
Return @var{obj}'s property list.
|
|
@end deffn
|
|
|
|
@deffn primitive procedure-property p k
|
|
Return the property of @var{obj} with name @var{key}.
|
|
@end deffn
|
|
|
|
@deffn primitive set-procedure-properties! proc new_val
|
|
Set @var{obj}'s property list to @var{alist}.
|
|
@end deffn
|
|
|
|
@deffn primitive set-procedure-property! p k v
|
|
In @var{obj}'s property list, set the property named @var{key} to
|
|
@var{value}.
|
|
@end deffn
|
|
|
|
@cindex procedure documentation
|
|
Documentation for a procedure can be accessed with the procedure
|
|
@code{procedure-documentation}.
|
|
|
|
@deffn primitive procedure-documentation proc
|
|
Return the documentation string associated with @code{proc}. By
|
|
convention, if a procedure contains more than one expression and the
|
|
first expression is a string constant, that string is assumed to contain
|
|
documentation for that procedure.
|
|
@end deffn
|
|
|
|
@cindex source properties
|
|
@c FIXME::martin: Is the following true?
|
|
Source properties are properties which are related to the source code of
|
|
a procedure, such as the line and column numbers, the file name etc.
|
|
|
|
@deffn primitive set-source-properties! obj plist
|
|
Install the association list @var{plist} as the source property
|
|
list for @var{obj}.
|
|
@end deffn
|
|
|
|
@deffn primitive set-source-property! obj key datum
|
|
Set the source property of object @var{obj}, which is specified by
|
|
@var{key} to @var{datum}. Normally, the key will be a symbol.
|
|
@end deffn
|
|
|
|
@deffn primitive source-properties obj
|
|
Return the source property association list of @var{obj}.
|
|
@end deffn
|
|
|
|
|
|
@deffn primitive source-property obj key
|
|
Return the source property specified by @var{key} from
|
|
@var{obj}'s source property list.
|
|
@end deffn
|
|
|
|
|
|
@node Procedures with Setters
|
|
@section Procedures with Setters
|
|
|
|
@c FIXME::martin: Review me!
|
|
|
|
@c FIXME::martin: Document `operator struct'.
|
|
|
|
@cindex procedure with setter
|
|
@cindex setter
|
|
A @dfn{procedure with setter} is a special kind of procedure which
|
|
normally behaves like any accesor procedure, that is a procedure which
|
|
accesses a data structure. The difference is that this kind of
|
|
procedure has a so--called @dfn{setter} attached, which is a procedure
|
|
for storing something into a data structure.
|
|
|
|
Procedures with setters are treated specially when the procedure appears
|
|
in the special form @code{set!} (REFFIXME). How it works is best shown
|
|
by example.
|
|
|
|
Suppose we have a procedure called @code{foo-ref}, which accepts two
|
|
arguments, a value of type @code{foo} and an integer. The procedure
|
|
returns the value stored at the given index in the @code{foo} object.
|
|
Let @code{f} be a variable containing such a @code{foo} data
|
|
structure.@footnote{Working definitions would be:
|
|
@lisp
|
|
(define foo-ref vector-ref)
|
|
(define foo-set! vector-set!)
|
|
(define f (make-vector 2 #f))
|
|
@end lisp
|
|
}
|
|
|
|
@lisp
|
|
(foo-ref f 0) @result{} bar
|
|
(foo-ref f 1) @result{} braz
|
|
@end lisp
|
|
|
|
Also suppose that a corresponding setter procedure called
|
|
@code{foo-set!} does exist.
|
|
|
|
@lisp
|
|
(foo-set! f 0 'bla)
|
|
(foo-ref f 0) @result{} bla
|
|
@end lisp
|
|
|
|
Now we could create a new procedure called @code{foo}, which is a
|
|
procedure with setter, by calling @code{make-procedure-with-setter} with
|
|
the accessor and setter procedures @code{foo-ref} and @code{foo-set!}.
|
|
Let us call this new procedure @code{foo}.
|
|
|
|
@lisp
|
|
(define foo (make-procedure-with-setter foo-ref foo-set!))
|
|
@end lisp
|
|
|
|
@code{foo} can from now an be used to either read from the data
|
|
structure stored in @code{f}, or to write into the structure.
|
|
|
|
@lisp
|
|
(set! (foo f 0) 'dum)
|
|
(foo f 0) @result{} dum
|
|
@end lisp
|
|
|
|
@deffn primitive make-procedure-with-setter procedure setter
|
|
Create a new procedure which behaves like @var{procedure}, but
|
|
with the associated setter @var{setter}.
|
|
@end deffn
|
|
|
|
@deffn primitive procedure-with-setter? obj
|
|
Return @code{#t} if @var{obj} is a procedure with an
|
|
associated setter procedure.
|
|
@end deffn
|
|
|
|
@deffn primitive procedure proc
|
|
Return the procedure of @var{proc}, which must be either a
|
|
procedure with setter, or an operator struct.
|
|
@end deffn
|
|
|
|
@deffn primitive setter proc
|
|
Return the setter of @var{proc}, which must be either a procedure with
|
|
setter or an operator struct.
|
|
@end deffn
|
|
|
|
|
|
@node Macros
|
|
@section Macros
|
|
|
|
[FIXME: This needs some more text on the difference between procedures,
|
|
macros and memoizing macros. Also, any definitions listed here should
|
|
be double-checked by someone who knows what's going on. Ask Mikael, Jim
|
|
or Aubrey for help. -twp]
|
|
|
|
@deffn primitive procedure->syntax code
|
|
Return a @dfn{macro} which, when a symbol defined to this value
|
|
appears as the first symbol in an expression, returns the
|
|
result of applying @var{code} to the expression and the
|
|
environment.
|
|
@end deffn
|
|
|
|
@deffn primitive procedure->macro code
|
|
Return a @dfn{macro} which, when a symbol defined to this value
|
|
appears as the first symbol in an expression, evaluates the
|
|
result of applying @var{code} to the expression and the
|
|
environment. The value returned from @var{code} which has been
|
|
passed to @code{procedure->memoizing-macro} replaces the form
|
|
passed to @var{code}. For example:
|
|
@lisp
|
|
(define trace
|
|
(procedure->macro
|
|
(lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))
|
|
|
|
(trace @i{foo}) @equiv{} (set! @i{foo} (tracef @i{foo} '@i{foo})).
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn primitive procedure->memoizing-macro code
|
|
Return a @dfn{macro} which, when a symbol defined to this value
|
|
appears as the first symbol in an expression, evaluates the
|
|
result of applying @var{proc} to the expression and the
|
|
environment. The value returned from @var{proc} which has been
|
|
passed to @code{procedure->memoizing-macro} replaces the form
|
|
passed to @var{proc}. For example:
|
|
@lisp
|
|
(define trace
|
|
(procedure->macro
|
|
(lambda (x env) `(set! ,(cadr x) (tracef ,(cadr x) ',(cadr x))))))
|
|
|
|
(trace @i{foo}) @equiv{} (set! @i{foo} (tracef @i{foo} '@i{foo})).
|
|
@end lisp
|
|
@end deffn
|
|
|
|
@deffn primitive macro? obj
|
|
Return @code{#t} if @var{obj} is a regular macro, a memoizing macro or a
|
|
syntax transformer.
|
|
@end deffn
|
|
|
|
@deffn primitive macro-type m
|
|
Return one of the symbols @code{syntax}, @code{macro} or
|
|
@code{macro!}, depending on whether @var{m} is a syntax
|
|
tranformer, a regular macro, or a memoizing macro,
|
|
respectively. If @var{m} is not a macro, @code{#f} is
|
|
returned.
|
|
@end deffn
|
|
|
|
@deffn primitive macro-name m
|
|
Return the name of the macro @var{m}.
|
|
@end deffn
|
|
|
|
@deffn primitive macro-transformer m
|
|
Return the transformer of the macro @var{m}.
|
|
@end deffn
|
|
|
|
@deffn primitive cons-source xorig x y
|
|
Create and return a new pair whose car and cdr are @var{x} and @var{y}.
|
|
Any source properties associated with @var{xorig} are also associated
|
|
with the new pair.
|
|
@end deffn
|
|
|
|
|
|
@c Local Variables:
|
|
@c TeX-master: "guile.texi"
|
|
@c End:
|