From: qikink
Subject: Extracting Function Names
Date: 
Message-ID: <1190448890.038205.302840@19g2000hsx.googlegroups.com>
Is there a way to extract a plaintext function name from the sharp-
quoted version? What I have is a function that I pass the function to
- i.e.

(find-nextx '(2 4 8)  # ' * # ' /)

(defun find-nextx (lst f1 f2) ...

Is there some function I can call on f1 and get the character * back -
alone, or am I stuck with all the <SYSTEM FUNCTION> stuff?

From: Chris Russell
Subject: Re: Extracting Function Names
Date: 
Message-ID: <1190467458.577244.201590@d55g2000hsg.googlegroups.com>
On 22 Sep, 09:14, qikink <······@gmail.com> wrote:
> Is there a way to extract a plaintext function name from the sharp-
> quoted version? What I have is a function that I pass the function to
> - i.e.
>
> (find-nextx '(2 4 8)  # ' * # ' /)
>
> (defun find-nextx (lst f1 f2) ...
>
> Is there some function I can call on f1 and get the character * back -
> alone, or am I stuck with all the <SYSTEM FUNCTION> stuff?

Part of the problem is that a function you pass may not be named, it
could also be an anonymous lambda,or a pointer to an old function that
has been replaced.

However if you know all of this and don't really care, you can output
the name of the function as a string using (format nil "~a") and then
chop it up into pieces.

For example:
((lambda(x)(subseq x 11 (1- (length x)))) (format nil "~a" #'list))

happens to return "LIST" in my version of sbcl. It may break in the
other cases and I expect on other implementations of CL.
See http://www.lisp.org/HyperSpec/Body/mac_print-unr_dable-object.html
for an explanation.

A more sane alternative might be to write find-next-x as a macro and
trap the symbols you are passed before they are transformed into
function references.
From: Rob Warnock
Subject: Re: Extracting Function Names
Date: 
Message-ID: <P_Kdnezm7739s2vbnZ2dnUVZ_gydnZ2d@speakeasy.net>
Chris Russell  <·····················@gmail.com> wrote:
+---------------
| On 22 Sep, 09:14, qikink <······@gmail.com> wrote:
| > Is there a way to extract a plaintext function name from
| > the sharp-quoted version?
+---------------

Certainly not portably, and perhaps not even consistently
within a single implementation.

+---------------
| For example:
| ((lambda(x)(subseq x 11 (1- (length x)))) (format nil "~a" #'list))
| 
| happens to return "LIST" in my version of sbcl. It may break
| in the other cases and I expect on other implementations of CL.
+---------------

Even in SBCL it will definitely break in other cases.
Consider these examples from CMUCL [which is probably
still close enough to SBCL for the results to be similar]:

    > (format nil "~a" #'list)

    "#<Function LIST {100C9A01}>"
    > (flet ((list (foo) (+ 3 foo)))
	(format nil "~a" #'list))
    "#<Interpreted Function (FLET LIST
			     )
      {48947A29}>"
    > (let ((list (lambda (foo) (+ 3 foo))))
	(format nil "~a" list))

    "#<Interpreted Function (LAMBDA (FOO) (+ 3 FOO)) {48995A49}>"
    > (let* ((*compile-print* nil)
             (*compile-verbose* nil)
	     (list (compile nil (lambda (foo) (+ 3 foo)))))
	(format nil "~a" list))

    "#<Function \"LAMBDA (FOO)\" {489CEC69}>"
    > 


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Chris Russell
Subject: Re: Extracting Function Names
Date: 
Message-ID: <1190552822.229665.48680@g4g2000hsf.googlegroups.com>
On 23 Sep, 10:14, ····@rpw3.org (Rob Warnock) wrote:
> Chris Russell  <·····················@gmail.com> wrote:
> +---------------
> | On 22 Sep, 09:14, qikink <······@gmail.com> wrote:
> | > Is there a way to extract a plaintext function name from
> | > the sharp-quoted version?
> +---------------
>
> Certainly not portably, and perhaps not even consistently
> within a single implementation.
>
> +---------------
> | For example:
> | ((lambda(x)(subseq x 11 (1- (length x)))) (format nil "~a" #'list))
> |
> | happens to return "LIST" in my version of sbcl. It may break
> | in the other cases and I expect on other implementations of CL.
> +---------------
>
> Even in SBCL it will definitely break in other cases.
> Consider these examples from CMUCL [which is probably
> still close enough to SBCL for the results to be similar]:
I did have a play to see if I could break it, and the all the
functional definitions I tried in SBCL return something of the form:
#<Function NAME &Optional UNIQUE_ID >
Where NAME is either just the name or of the form (BINDING-TYPE NAME)
like (FLET NAME), or of the form (LAMBDA(PARAMETERS)).

So the results are nice and consistent, which makes my dodgy little
hack surprisingly stable(at least if you want unique id in the
ambiguous cases).

I'd still feel nervous about actually using it though....
From: Juho Snellman
Subject: Re: Extracting Function Names
Date: 
Message-ID: <slrnffcrhk.a3u.jsnell@sbz-30.cs.Helsinki.FI>
Chris Russell <·····················@gmail.com> wrote:
> I did have a play to see if I could break it, and the all the
> functional definitions I tried in SBCL return something of the form:
> #<Function NAME &Optional UNIQUE_ID >
> Where NAME is either just the name or of the form (BINDING-TYPE NAME)
> like (FLET NAME), or of the form (LAMBDA(PARAMETERS)).

(defgeneric bar ())
(print #'bar) ;; => #<STANDARD-GENERIC-FUNCTION BAR (0)>

(let ((*evaluator-mode* :interpret))
  (eval '(defun foo () 1))
  (print #'foo)) ;;  => #<INTERPRETED-FUNCTION FOO>

-- 
Juho Snellman
From: Chris Russell
Subject: Re: Extracting Function Names
Date: 
Message-ID: <1190586925.268103.55510@d55g2000hsg.googlegroups.com>
On 23 Sep, 14:46, Juho Snellman <······@iki.fi> wrote:
> Chris Russell <·····················@gmail.com> wrote:
> > I did have a play to see if I could break it, and the all the
> > functional definitions I tried in SBCL return something of the form:
> > #<Function NAME &Optional UNIQUE_ID >
> > Where NAME is either just the name or of the form (BINDING-TYPE NAME)
> > like (FLET NAME), or of the form (LAMBDA(PARAMETERS)).
>
> (defgeneric bar ())
> (print #'bar) ;; => #<STANDARD-GENERIC-FUNCTION BAR (0)>
>
> (let ((*evaluator-mode* :interpret))
>   (eval '(defun foo () 1))
>   (print #'foo)) ;;  => #<INTERPRETED-FUNCTION FOO>
>
> --
> Juho Snellman

Thanks for that. The CLOS doesn't surprise me, but I wouldn't have
known how to do the second example.
From: Carl Taylor
Subject: Re: Extracting Function Names
Date: 
Message-ID: <ujcJi.584692$p47.40741@bgtnsc04-news.ops.worldnet.att.net>
"qikink" <······@gmail.com> wrote in message 
·····························@19g2000hsx.googlegroups.com...
> Is there a way to extract a plaintext function name from the sharp-
> quoted version? What I have is a function that I pass the function to
> - i.e.
>
> (find-nextx '(2 4 8)  # ' * # ' /)
>
> (defun find-nextx (lst f1 f2) ...
>
> Is there some function I can call on f1 and get the character * back -
> alone, or am I stuck with all the <SYSTEM FUNCTION> stuff?

You could use your Lisp's object address function to identify
the function passed as an argument.  In LispWorks this is
<sys:object-address>.

Carl Taylor


(defconstant +function-address-list+
   (list `(,(sys:object-address #'*) . *)
         `(,(sys:object-address #'/) . /)
         `(,(sys:object-address #'car) . car)
         `(,(sys:object-address #'+) . +)))


(defun get-function-name (f)
   (cdr (assoc (sys:object-address f)
                    +function-address-list+)))


(defun find-nextx (lst f1 f2)
   (car lst)
   (format t "~2%~6TFunction name is: ~A"
              (get-function-name f1))
   (format t "~2%~6TFunction name is: ~A~2%"
              (get-function-name f2)))



CL-USER 4 > (find-nextx '(2 4 8) #'* #'/)


      Function name is: *

      Function name is: /

NIL
From: Alex Mizrahi
Subject: Re: Extracting Function Names
Date: 
Message-ID: <46f576f7$0$90262$14726298@news.sunsite.dk>
(message (Hello 'qikink)
(you :wrote  :on '(Sat, 22 Sep 2007 08:14:50 -0000))
(

 q> Is there a way to extract a plaintext function name from the sharp-
 q> quoted version? What I have is a function that I pass the function to
 q> - i.e.

no, there's no good portable way to do that.
if you really need a name, pass a symbol rather than function itself.

you can funcall the symbol, since it's a function designator.

 q> (find-nextx '(2 4 8)  # ' * # ' /)
 q> (defun find-nextx (lst f1 f2) ...

quite likely your code won't need to change.

but you'll loose ability to pass a lambda, however if you want you can use 
weirdness like this:

(defmacro symbolic-lambda (sym (&rest args) &body body)
  `(let ((my-sym (make-symbol ,(symbol-name sym))))
    (setf (symbol-function my-sym) (lambda (,@args) ,@body))
       my-sym)

it creates a fresh symbol and assigns it a function each time it's called. 
now you funcall that symbol:

* (funcall (symbolic-lambda bugoga (x) (1+ x)) 1)

2

and you can see it's name:

CL-USER> (symbolic-lambda bugoga (x) (1+ x))
#:BUGOGA


however, function is not defined globally:

* (fboundp '#:bugoga)
NIL

* (fboundp 'bugoga)
NIL

kewl, ye? that's a symbolic computing ^oo^

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"Hanging In The Balance Of Deceit And Blasphemy")