From: almond@statsci.com (Russell G. Almond)
Subject: Re: Compiled function name in Allegro CL
Organization: Statistical Sciences, Inc., Seattle, WA USA
Date: Mon, 12 Oct 1992 22:30:31 GMT



> Is there a function in ACL 4.1 which extracts the function name
> from the function object? (similar to SI:COMPILED-FUNCTION-NAME on
> the Symbolics, or SYS:PROCEDURE-REF in Lucid)

I've tried to write a portable function to do that.  I've so far
tested it on ACL 4.1 and CMUCL-15e.  It uses
function-lambda-expression to do most of its work.  As the
specifications for that function (actaully, I haven't checked the
draft ANSI standard on this, just CLtL2) are rather loose, it has a
high potential for loosing.  However, this function might do something
close to what you want it to do.  


(defun write-function (function &optional (stream t))
  (declare (type Function function))
  "This will try its damnedist to write a function out to stream in
such a way that it can be read back by the lisp reader.  The first
choice is as a name and the second choice is as a lambda expression in
the null lexical environment.  If neither of those are possible, it
prints failure-result and generates a warning.

Unless your lisp is totally wimpy, this should work for named
functions both compiled and interpreted and lambda expression which
were closed in the null lexical environment.  

The following expression:
(let ((foo :bar)) (setq biz #'(lambda (x) (cons foo x))))
will produce a closure in a non-null lexical environment.  These
cannot be read and written portibably because they depend on the
lexical binding of foo which will not be available at read time.  
Write function tries to print this out as 
#<#'(lambda (x) (cons foo x))>  and issues a warning so that you can
try and tweak it by hand.

What it will do with generic functions is system dependent.  It
currently looses with CMU lisp 15e and wins with Allegro V4.1.

"
  (unless (fboundp 'function-lambda-expression)
    ;; this version of lisp doesn't conform to X3j13 standards yet, we
    ;; loose automatically.
    (warn "write-function:  Your lisp doesn't support function-lambda-expression
  We loose.~%")  
    (return-from write-function (prin1 function stream)))
  
  (multiple-value-bind (lambda-exp env name)
      (function-lambda-expression function)
    (cond ((and name (Symbolp name)
		#+cmu(not (eq (find-package :pcl) (symbol-package name)))
		)
	   ;; We win (usually).  Symbol is probably name of function, print it.
	   (format stream "#'~S" name))
	  ((and (null env) (listp lambda-exp) (eq 'lambda (car lambda-exp)))
	   ;; Lambda expression in null lexical environment.  We win.
	   (format stream "#'~S" lambda-exp))
	  (t ;; We loose.  Probably a lambda expression in a non-null
	   ;; enviornment, but could be something weird.
	   (warn "Write-function: Can't write function ~S (~S)
legibilly.  (This is probably because the function was closed in a
non-null lexical environment, or because the function is generic)
"
		 name function)
	   (format stream "#<#'~S>" (if lambda-exp lambda-exp
				      function)))
	  )))


BTW, if anybody has any patches for other LISP dialects, I would be
interested in getting them. 

Hope this helps.


			Russell Almond			   
Statistical Sciences, Inc.		
1700 Westlake Ave., N Suite 500		
Seattle, WA  98109			
(206) 283-8802				
almond@statsci.com			




Newsgroups: comp.lang.lisp