[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FUNCTION-TYPE



    Date: 06 Jun 87  1630 PDT
    From: Dick Gabriel <RPG@SAIL.STANFORD.EDU>

    ... Changes that introduce or retain inconsistencies which confuse new
    users and which complicate the rules of the language are preferable to
    changes that cause old programs to stop working.

    I think Common Lisp is so messed up that the cleanest change to
    function types will not effect major improvements. Our position
    with respect to EuLisp will be more difficult. ...

I disagree with your claim that a change to the function types alone will
not make a major improvement in the language.

We can define any function to do anything we want. That in itself does
not make the language inconsistent. There is nothing inconsistent about
defining the functions FUNCALL and APPLY to take arguments which are
coercible to functions, especially if you also make it clear that you
can put things in function cells which are coercible to functions.
This is no more unreasonable than allowing any function to coerce its
argument. Consider STRING-DOWNCASE of a symbol, for example.

One of the great powers of types in a language is that you can tell when
you have one that is not quite suitable and define an interpretation for
it. If you require exactly one type as an argument to all functions, you
alienate the whole notion of generic functions and take us into a world
that more resembles CLU, where you need one function for every type.

If all we did was fix the types and not fix the business about what can go
in the cells or be given to APPLY or FUNCALL, we'd still have a lot.

Consider that if the EuLisp guys don't like our definition of the functions
and want to run EuLisp compatibility in our lisp, they can effectively do:

 (IN-PACKAGE "EULISP" :USE "CL")
 (SHADOW '(APPLY FUNCALL))
 ...
 (DEFUN APPLY (FUNCTION &REST SPREAD-ARGUMENTS)
   (CL:APPLY (THE FUNCTION #'CL:APPLY)
	     (THE FUNCTION FUNCTION) SPREAD-ARGUMENTS))
 (DEFUN FUNCALL (FUNCTION &REST ARGUMENTS)
   (CL:APPLY (THE FUNCTION FN) ARGUMENTS))

And as for us, we can do the following to win in theirs:

 (IN-PACKAGE "COMMONLISP" :USE "EU")
 (SHADOW '(APPLY FUNCALL))
 ...
 (PROCLAIM '(INLINE COERCE-TO-FUNCTION))
 (DEFUN COERCE-TO-FUNCTION (FN)
   (FLET ((FAIL () (ERROR "Not a function: ~S" FN)))
     (TYPECASE FN
       (FUNCTION FN)
       (SYMBOL (SYMBOL-FUNCTION FN))
       (LIST (IF (EQ (CAR LIST) 'LAMBDA)
		 (EVAL ,LIST)
		 (FAIL)))
       (OTHERWISE (FAIL)))))
 (DEFUN APPLY (FN &REST SPREAD-ARGUMENTS)
   (EU:APPLY #'EU:APPLY (COERCE-TO-FUNCTION FN) SPREAD-ARGUMENTS))
 (DEFUN FUNCALL (FN &REST ARGUMENTS)
   (EU:APPLY (COERCE-TO-FUNCTION FN) ARGUMENTS))

Not much code for either side.

The thing which makes this so easy going both directions is the agreement
on making the FUNCTION type something that you can get leverage out
of.

The issue of how you deal with that type in any given function is
interesting, but need not (and I think should not) be intimately tied
up with this much more important issue that we probably can and should
all agree upon.

You might say that this is so little code that we should go the extra
little bit and just agree to make the mechanisms the same, but I don't
think that would be wise. To go further for us would compromise large
bodies of existing code and built-in philosophies about Lisp and what
it can do for them. To go further for the Eulisp guys might compromise
their existing code and their philosophies. I think that either side
has a defensible reason for maintaining their ground and that it is
appropriate to agree not to agree on this issue.