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

suggestion for language extension



    Date: Mon, 26 Oct 87 17:37 EST
    From: Brad Miller <miller@acorn.cs.rochester.edu>

    There is, in fact, something conceptually simple that could be added to the
    spec, is upward compatible with the current language, and would make me sleep
    a lot easier (though compiler writers may groan a bit):

	Allow overloading of functions.

    This would allow me to create my own first-class objects, since I could
    overload common operators to handle (special case) the new type.

What do you mean by this?  Do you mean overloading in the Ada sense,
where you specify the data types of the arguments that cause a
particular implementation of the function to be invoked?  I believe CLOS
will allow this, although there will probably be some restrictions on
the built-in functions that may be converted to generic functions (my
feeling is that only functions proclaimed INLINE should be restricted).

You mentioned that overloading could be implemented using an ADVISE
feature.  A simple-minded ADVISE can be implemented using existing CL
facilities, so there is no real need for extending the language:

(defmacro advise (function &body body)
  (let ((new-fun (gensym)))
    `(progn (setf (symbol-function ',new-fun)
		  (symbol-function ',function))
	    (defun ,function (&rest arglist)
	      (flet ((do-it ()
		      (apply ',new-fun arglist)))
		.,body)))))

This defines something like the lispm :AROUND advice, except that
(do-it) is used in place of :do-it.  It also doesn't support unadvise,
named advice, etc., but those merely require maintaining a database.  It
also doesn't support the lispm feature that an advised function can be
redefined without affecting the advice, which requires hooks in the
implementation; however, I don't think it is necessary for the
overloading feature that Brad wants.

Another question: what particular problem does overloading solve for
you?  If you want a function that is like READ-CHAR except that it does
something different when the stream argument is one of your structures,
you can do:

(defun my-read-char (stream)
  (if (my-struct-p stream)
      (read-char-from-my-struct stream)
      (read-char stream)))

and call my-read-char in place of read-char in your program.  If your
intent was to pass a my-struct to some other CL input function, such as
READ or READ-LINE, advising read-char wouldn't necessarily help (CL
gives no guarantee that READ, READ-LINE, etc. call READ-CHAR internally,
although particular CL implementations may do so).

                                                barmar