{Begin Chapter Function Definition, Manipulation, and Evaluation}
{Title Function Definition, Manipulation, and Evaluation}
{Text


The Interlisp programming system is designed to help the user define and debug functions.  Developing an applications program in Interlisp involves defining a number of functions in terms of the system primitives and other user-defined functions.  Once defined, the user's functions may be referenced exactly like Interlisp primitive functions, so the programming process can be viewed as extending the Interlisp language to include the required functionality.


The user defines a function with a list expressions known as an {lisp EXPR}.  An {lisp EXPR} specifies if the function has a fixed or variable number of arguments, whether these arguments are evaluated or not, the function argument names, and a series of forms which define the behavior of the function.  For example:

{lispcode (LAMBDA (X Y) (PRINT X) (PRINT Y))}

A function defined with this {lisp EXPR} would have two evaluated arguments, {lisp X} and {lisp Y}, and it would execute {lisp (PRINT X)} and {lisp (PRINT Y)} when evaluated.  Other types of {lisp EXPR}s are described below.



A function is defined by putting an {lisp EXPR} in the function definition cell of a litatom.  There are a number of functions for accessing and setting function definition cells, but one usually defines a function with {fn DEFINEQ} ({PageRef Fn DEFINEQ}).  For example:

{lispcode
← (DEFINEQ (FOO (LAMBDA (X Y) (PRINT X) (PRINT Y))
(FOO)}

The expression above will define the function {lisp FOO} to have the {lisp EXPR} definition {lisp (LAMBDA (X Y) (PRINT X) (PRINT Y))}.  After being defined, this function may be evaluated just like any system function:

{lispcode
← (FOO 3 (IPLUS 3 4))
3
7
7
←}


All function definition cells do not contain {lisp EXPR}s.  The compiler ({PageRef Tag COMPILER}) translates {lisp EXPR} definitions into compiled code objects, which execute much faster.  In Interlisp-10, many primitive system functions are defined with machine code objects known as {lisp SUBR}s.  Interlisp provides a number of "function type functions" which determine how a given function is defined ({lisp EXPR}/compiled code/{lisp SUBR}), the number and names of function arguments, etc.  See {PageRef Fn FNTYP}.



Usually, functions are evaluated automatically when they appear within another function or when typed into Interlisp.  However, sometimes it is useful to envoke the Interlisp interpreter explicitly to apply a given "functional argument" to some data.  There are a number of functions which will apply a given function repeatedly.  For example, {fn MAPCAR} will apply a function (or an {lisp EXPR}) to all of the elements of a list, and return the values returned by the function:

{lispcode
← (MAPCAR '(1 2 3 4 5) '(LAMBDA (X) (ITIMES X X))
(1 4 9 16 25)}


When using functional arguments, there are a number of problems which can arise, related with accessing free variables from within a function argument.  Many times these problems can be solved using the function {fn FUNCTION} to create a {lisp FUNARG} object (see {PageRef Fn FUNCTION}).


The macro facility provides another way of specifying the behavior of a function (see {PageRef Tag Macros}).  Macros are very useful when developing code which should run very quickly, which should be compiled differently than it is interpreted, or which should run differently in different implementations of Interlisp.


{Include FnTypes}

{Include FnDef}

{Include FnEval}

{Include Macros}


}{End Chapter Function Definition, Manipulation, and Evaluation}