EVAL-DEFEATS-LINKERAPPLY, FUNCALL, or READ, which potentially call SYMBOL-FUNCTION or EVAL, which must be regarded as potential references to any standard or user-defined Common Lisp procedure. At a minimum, therefore, the entire Common Lisp library gets linked into the deliverable application.FUNCTIONP to be false of symbols and lists. Change the definitions of APPLY and FUNCALL so it is an error to pass them a symbol or a list as their first argument.
Functions such as MAPCAR that are defined by reference to the concept of function or by reference to APPLY and FUNCALL would be affected by these changes as well, but it would not be necessary to change their written specification.
Remove the #. and #, dispatching macro characters from the standard reader syntax. Require the interpreter, compiler, and interactive loader to use a reader syntax that has been extended by adding the #. and #, dispatching macro characters.
(DEFUN MAIN ()
(PRINT (EVAL (READ))))
A selective linker should, however, be able to link the following program into a relatively small executable file.
(DEFUN MAIN ()
(PRINT (APPLY (FOO) (READ))))
(DEFUN FOO ()
(LET ((BIAS (RANDOM 1000)))
#'(LAMBDA (&REST ARGS) (+ BIAS (APPLY #'+ ARGS)))))
Currently selective linkers have difficulty with the preceding program because they must also make programs like the following work, where FOO "computes" an arbitrary function. Under the proposal, the only ways to compute an arbitrary function would be through explicit use of EVAL or SYMBOL-FUNCTION et cetera.
(DEFUN MAIN ()
(PRINT (APPLY (FOO) (READ))))
(DEFUN FOO () (READ))
APPLY and FUNCALL, since they would not have to signal an error when passed a symbol or list. Implementations that rely on #. and #, in non-code data would suffer a conversion cost, but it seems unlikely that any implementations do this.APPLY and FUNCALL and by defining the #. and #, dispatching character macros. This will be referred to below as the trivial conversion.
Programs for which reliable selective linking is important, if any exist, are presumably written in a style that needs no conversion.
To convert an existing program into a style that can be linked selectively, it is necessary to examine all calls to APPLY, FUNCALL, MAPCAR, and other functions that take functions as arguments. Where the argument expression is of the form (FUNCTION f), no conversion is necessary. Where the first argument is of the form (QUOTE f), it should be changed to (FUNCTION f). Where the first argument is of neither of these two forms, human intervention will be necessary. It seems likely that most calls will have first arguments of the form (FUNCTION f) or (QUOTE f), so this conversion can be automated substantially but not completely.
As with all conversions, arguments to EVAL must be analyzed specially. Since uses of EVAL generally defeat selective linking, however, it is clear that programs that make extensive use of EVAL were not intended to be passed through a selective linker. Hence the trivial conversion should suffice for such programs.
If the program reads data from files, then it may be necessary to scan the files for occurrences of #. and #,. If any occurrences are found, they will have to be removed. It seems clear, however, that no program intended for selective linking will rely on #. and #, in data files.
While this proposal will make it possible to construct selective linkers, it will not make it trivial. In many implementations, for example, the data structure for each symbol contains among other things a pointer to the symbol's home package, a value cell, and a function cell. In such an implementation each symbol may represent a potential reference to the value cell of any symbol accessible from its home package. Implementations that care about selective linking may have to break such links.
Scheme proves that it is possible to design a Lisp that can be linked selectively. Reliable selective linkers have been written for T and for MacScheme, and possibly for other implementations as well.