{begin subsec Validity of Definitions in Interlisp-10}
{title Validity of Definitions in Interlisp-10}
{Text

Although the function definition cell{index function definition cell} is intended for function definitions, {fn PUTD} and {fn GETD} do not make thorough checks on the validity of definitions that "look like" exprs, compiled code, or {lisp SUBR}s.  Thus if {fn PUTD} is given an array pointer, it treats it as compiled code, and simply stores the array pointer in the definition cell.  {fn GETD} will then return the array pointer.  Similarly, a call to that function will simply transfer to what would normally be the entry point for the function, and produce random results if the array were not compiled function.

Similarly, if {fn PUTD} is given a dotted pair of the form {lisp (number . address)} where {lisp number} and {lisp address} fall in the subr range, {index PUTD FN}{fn PUTD} assumes it is a subr and stores it away as described earlier.
{index GETD FN}{fn GETD} would then return a dotted pair {fn EQUAL}
(but not {fn EQ}) to the expression originally given {fn PUTD}.
Similarly, a call to this function would transfer to the corresponding address.

Finally, if {fn PUTD} is given any other list, it simply stores it away.  A call to this function would then go through the interpreter.

Note that {fn PUTD} does not actually check to see if the s-expression is valid definition, i.e., begins with {lisp LAMBDA} or {lisp NLAMBDA}.{index NLAMBDA Litatom}{index LAMBDA Litatom}  Similarly, {index EXPRP FN}{fn EXPRP} is true if a definition is a list and not of the form {lisp (number . address)}, {lisp number} = 0, 1, 2, or 3 and {lisp address} a subr address; {fn SUBRP}{index SUBRP FN} is true if it is of this form.  {index ARGLIST FN}{fn ARGLIST} and {index NARGS FN}{fn NARGS} work correspondingly.

Only {index FNTYP FN}{fn FNTYP} and {index ARGTYPE FN}{fn ARGTYPE} check function definitions further than that described above: both {fn ARGTYPE} and {fn FNTYP} return {lisp NIL} when {fn EXPRP} is true but {fn CAR} of the definition is not {lisp LAMBDA} or
{lisp NLAMBDA.}{foot These functions
have different values on {lisp LAMBDA}s and {lisp NLAMBDA}s and hence
must check.  The compiler and interpreter also take different actions for {lisp LAMBDA}s and {lisp NLAMBDA}s, and therefore generate errors if the definition is neither.
}{comment endfootnote}
In other words, if the user uses {index PUTD FN}{fn PUTD} to put {lisp (A B C)} in a function definition cell, {index GETD FN}{fn GETD}
will return this value, the editor and prettyprint will both treat it as a definition, {index EXPRP FN}{fn EXPRP} will return {lisp T}, {index CCODEP FN}{fn CCODEP} and {index SUBRP FN}{fn SUBRP} {lisp NIL}, {index ARGLIST FN}{fn ARGLIST} {lisp B}, and {index NARGS FN}{fn NARGS} 1.

}{End subsec Validity of Definitions in Interlisp-10}



{Begin SubSec SUBRs}
{Title SUBRs}
{Text
In Interlisp-10, basic built-in functions such as {fn CONS}, {fn CAR}, and {fn COND} are handcoded in machine language.  These functions are known as "{lisp SUBR}s."{index *PRIMARY* SUBRs}  Functions defined as {lisp SUBR}s can be lambda/nolambda or spread/nospread, the same four function types as {lisp EXPR} functions.

{lisp SUBR}s are called in a special way, so their definitions are stored differently than those of compiled or interpreted functions.  {fn GETD} of a {lisp SUBR} returns a dotted pair, {fn CAR} of which is an encoding of the {fn ARGTYPE} and number of arguments of the {lisp SUBR}, and {fn CDR} of which is the address of the first instruction.  Note that each {fn GETD} of a subr performs a {fn CONS}.  Similarly, {fn PUTD} of a definition of the form {lisp ({arg NUMBER} . {arg ADDRESS})}, where {arg NUMBER} and {arg ADDRESS} are in the appropriate ranges, stores the definition as a {lisp SUBR}.

{FnDef {FnName SUBRP} {FnArgs FN}
{Text
Returns {lisp T} if {lisp (FNTYP {arg FN})} is either {lisp SUBR}, {lisp FSUBR}, {lisp SUBR*}, or {lisp FSUBR*}, i.e., the third column of {fn FNTYP}s; {lisp NIL} otherwise.{index SUBR Litatom}{index FSUBR Litatom}{index SUBR* Litatom}{index FSUBR* Litatom}
}}


For {lisp SUBR}s, the function {fn ARGLIST} returns {lisp (U)}, {lisp (U V)}, {lisp (U V W)}, etc. depending on the number of arguments; if a nospread {lisp SUBR}, it returns {lisp U}.{index U (value of ARGLIST)}  This is merely a "feature" of {fn ARGLIST}; {lisp SUBR}s do not actually store the names of their arguments(s).


}{End SubSec SUBRs}