@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: