{Begin SubSec Lambdatran}
{Title Lambdatran}
{Text

{index *BEGIN* lambdatran package}


{note The lambdatran package was written by R. M. Kaplan.}

{Tag Lambdatran}


{it
Note:  Lambdatran is a LispUsers package that is contained on the file {lisp LAMBDATRAN.DCOM}.
}



The purpose of this package is to facilitate defining new {lisp LAMBDA} words in such a way that a variety of other system packages will respond to them appropriately.  A {lisp LAMBDA} word is a word that can appear as {fn CAR} of a function definition, like {lisp LAMBDA} and {lisp NLAMBDA}.  New {lisp LAMBDA} words are useful because they enable the user to define his own conventions about such things as the interpretation of arguments, and to build in certain defaults about how values are returned.  For example, the DECL package ({PageRef Tag DECL}) defines {lisp DLAMBDA} as a new {lisp LAMBDA} word with unconventional arguments such as the following:

{lisp (DLAMBDA ((A FLOATP) (B FIXP) (RETURNS SMALLP)) (FOO A B))}


In order for such an expression to be executable and compilable, a mechanism must be provided for translating this expression to an ordinary {lisp LAMBDA} or {lisp NLAMBDA}, with the special behavior associated with the arguments built into the function body.  The lambdatran package accomplishes this via an appropriate entry on {index DWIMUSERFORMS Var}{var DWIMUSERFORMS} (see {PageRef Var DWIMUSERFORMS}) that computes the translation.


Besides executing and compiling, Interlisp applies a number of other operations to function definitions (e.g. breaking, advising), many of which depend on the system being able to determine certain properties of the function, such as the names of its arguments, their number, and the type of the function ({lisp EXPR}, {lisp FEXPR}, etc.).  The lambdatran package also provides new definitions for the functions {fn FNTYP}, {fn ARGLST}, {fn NARGS}, and {fn ARGTYPE} which can be told how to compute properties for the user's {lisp LAMBDA}-words.


A new {lisp LAMBDA}-word is defined in the following way:


1.  Add the {lisp LAMBDA}-word itself (e.g. the atom {lisp DLAMBDA}) to the list {var LAMBDASPLST}.{index LAMBDASPLST Var}  This suppresses attempts to correct the spelling of the {lisp LAMBDA}-word.


2.  Add an entry for the {lisp LAMBDA}-word to the association-list {var LAMBDATRANFNS},{index LAMBDATRANFNS Var} which is a list of elements of the form:
{lisp ({arg LAMBDA-WORD} {arg TRANFN} {arg FNTYP} {arg ARGLIST})}, where


{arg LAMBDA-WORD} is the name of the {lisp LAMBDA}-word (e.g. {lisp DLAMBDA}).


{arg TRANFN} is a function of one argument that will be called whenever a real definition is needed for the {lisp LAMBDA}-word definition.  Its argument is the {lisp LAMBDA}-word definition, and its value should be a conventional {lisp LAMBDA} or {lisp NLAMBDA} expression which will become the translation of the {lisp LAMBDA}-word form.  The free variable {var FAULTFN} is bound to the name of the function in which the {lisp LAMBDA}-word form appeared (or {lisp TYPE-IN} if the form was typed in).


{arg FNTYP} determines the function-type of a definition beginning with {arg LAMBDA-WORD}.  It is consulted if the definition does not already have a translation from which the function type may be deduced.  If {arg FNTYP} is one of the atoms {lisp EXPR}, {lisp FEXPR}, {lisp EXPR*}, {lisp FEXPR*}, then all definitions beginning with {lisp LAMBDA}-word are assumed to have that type.  Otherwise, {arg FNTYP} is a function of one argument that will be applied to the {lisp LAMBDA}-word definition.  Its value should be one of the above four function types.


{arg ARGLIST} determines the argument list of the definition if it has not already been translated (if it has, the {arg ARGLIST} is simply the {arg ARGLIST} of the translation).  It is also a function of one argument, the {lisp LAMBDA}-word definition, and its value should be the list of arguments for the function (e.g. {lisp (A B)} in the {lisp DLAMBDA} example above).  If the {lisp LAMBDA}-word definition is ill-formed and the argument list cannot be computed, the function should return {lisp T}.  If an {arg ARGLIST} entry is not provided in the {var LAMBDATRANFNS} element, then the argument list defaults to the second element of the definition.


As an example, the {var LAMBDATRANFNS} entry for {lisp DLAMBDA} is
{lisp (DLAMBDA DECL EXPR DLAMARGLIST)}, where {lisp DECL} and {lisp DLAMARGLIST} are functions of one argument.


Note:  if the {lisp LAMBDA}-word definition has an argument list with argument names appearing either as literal atoms or as the first element of a list, the user should also put the property {prop INFO}{index INFO Prop} with value {lisp BINDS} on the property list of the {lisp LAMBDA}-word in order to inform {fn DWIMIFY} ({PageRef Fn DWIMIFY}) to take notice of the names of the arguments when {fn DWIMIFY}ing.

{index *END* lambdatran package}

}{End SubSec Lambdatran}