1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-06 15:40:29 +02:00
guile/doc/scheme-procedures.texi
2001-04-11 22:04:30 +00:00

337 lines
11 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
@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: