Hello all. I'm completely confused no matter what I look at on the
internet or in Paul Graham's Ansi Common Lisp. I just want to obtain a
list of all functions defined in a package. Can someone show me a
clear example of how this is done? For example, what code would list
all the functions defined in common-lisp? Also, I'm not interested in
inherited functions, only those defined in the package itself.
Thanks for any help.
- Jake
jakemiles wrote:
> Hello all. I'm completely confused no matter what I look at on the
> internet or in Paul Graham's Ansi Common Lisp. I just want to obtain a
> list of all functions defined in a package. Can someone show me a
> clear example of how this is done? For example, what code would list
> all the functions defined in common-lisp? Also, I'm not interested in
> inherited functions, only those defined in the package itself.
I'm sure wiser heads will post better solutions, but here's a piecewise
one that might help:
(defun symbol-function-p (sym)
"Is there a function associated with this symbol?"
(handler-case (symbol-function sym)
(undefined-function () nil)))
(defun defun-in-package-p (s p)
"Is this symbol interned in this package, and is there a
function asssociated with it?"
(and (symbol-function-p s)
(eq p (symbol-package s))))
(defun functions-in-package (pkg)
"Return a list of functions defined in the package PKG."
(loop for s being the symbols in pkg
when (defun-in-package-p s pkg)
collect s))
(defun document-package-functions (pkg)
"Print documentation of all functions defined in the package."
(loop for fnsym in (functions-in-package pkg)
do (princ (format nil "~a~%~a~%~%" fnsym
(or (documentation fnsym 'function) "")))))
;; then give it a try:
CL-USER> (document-package-functions (find-package :common-lisp))
DEFPARAMETER
Define a parameter that is not normally changed by the program,
but that may be changed without causing an error. Declare the
variable special and sets its value to VAL, overwriting any
previous value. The third argument is an optional documentation
string for the parameter.
SETF
Takes pairs of arguments like SETQ. The first is a place and the second
is the value that is supposed to go into that place. Returns the last
value. The place argument may be any of the access forms for which
SETF
knows a corresponding setting form.
CIS
Return cos(Theta) + i sin(Theta), i.e. exp(i Theta).
;;; etc
Graham
Graham Fawcett wrote:
> jakemiles wrote:
>
>>Hello all. I'm completely confused no matter what I look at on the
>>internet or in Paul Graham's Ansi Common Lisp. I just want to obtain a
>>list of all functions defined in a package. Can someone show me a
>>clear example of how this is done? For example, what code would list
>>all the functions defined in common-lisp? Also, I'm not interested in
>>inherited functions, only those defined in the package itself.
>
>
> I'm sure wiser heads will post better solutions, but here's a piecewise
> one that might help:
>
> (defun symbol-function-p (sym)
> "Is there a function associated with this symbol?"
> (handler-case (symbol-function sym)
> (undefined-function () nil)))
fboundp?
>
> (defun defun-in-package-p (s p)
> "Is this symbol interned in this package, and is there a
> function asssociated with it?"
> (and (symbol-function-p s)
> (eq p (symbol-package s))))
I would expect something named defun-xxxx to be a variant on defun. One
is not looking for defuns in a package, one is looking for functions.
One does not call a defun, once calls a function. etc etc.
>
> (defun functions-in-package (pkg)
> "Return a list of functions defined in the package PKG."
> (loop for s being the symbols in pkg
> when (defun-in-package-p s pkg)
fboundp?
You already know s is a symbol in pkg, so why does dipp have to check
the package of the symbol?
kt
> collect s))
>
> (defun document-package-functions (pkg)
> "Print documentation of all functions defined in the package."
> (loop for fnsym in (functions-in-package pkg)
> do (princ (format nil "~a~%~a~%~%" fnsym
> (or (documentation fnsym 'function) "")))))
>
> ;; then give it a try:
>
> CL-USER> (document-package-functions (find-package :common-lisp))
> DEFPARAMETER
> Define a parameter that is not normally changed by the program,
> but that may be changed without causing an error. Declare the
> variable special and sets its value to VAL, overwriting any
> previous value. The third argument is an optional documentation
> string for the parameter.
>
> SETF
> Takes pairs of arguments like SETQ. The first is a place and the second
> is the value that is supposed to go into that place. Returns the last
> value. The place argument may be any of the access forms for which
> SETF
> knows a corresponding setting form.
>
> CIS
> Return cos(Theta) + i sin(Theta), i.e. exp(i Theta).
>
> ;;; etc
>
> Graham
>
--
Cells: http://common-lisp.net/project/cells/
"I'll say I'm losing my grip, and it feels terrific."
-- Smiling husband to scowling wife, New Yorker cartoon
Ken Tilton wrote:
> Graham Fawcett wrote:
> > (defun symbol-function-p (sym)
> > "Is there a function associated with this symbol?"
> > (handler-case (symbol-function sym)
> > (undefined-function () nil)))
>
> fboundp?
Thanks. I knew I must be reinventing something, just didn't know what.
;-)
> > (defun defun-in-package-p (s p)
> > "Is this symbol interned in this package, and is there a
> > function asssociated with it?"
> > (and (symbol-function-p s)
> > (eq p (symbol-package s))))
>
> I would expect something named defun-xxxx to be a variant on defun. One
> is not looking for defuns in a package, one is looking for functions.
> One does not call a defun, once calls a function. etc etc.
Good point.
> > (defun functions-in-package (pkg)
> > "Return a list of functions defined in the package PKG."
> > (loop for s being the symbols in pkg
> > when (defun-in-package-p s pkg)
>
> fboundp?
> You already know s is a symbol in pkg, so why does dipp have to check
> the package of the symbol?
The OP wanted functions that were defined in-package, not imported into
it. Actually, I expected the "being the symbols" clause not to include
imported symbols, but it appears to; at least for me, over here in
SBCL. Check out SB-ALIEN, for example:
CL-USER> (loop with set = '()
for s being the symbols in (find-package :SB-ALIEN)
and p = (symbol-package s)
do (pushnew (package-name p) set)
finally (return set))
("SB-EXT" "SB-INT" "SB-ALIEN-INTERNALS" "SB-SYS" "SB-ALIEN"
"COMMON-LISP")
--g
"Graham Fawcett" <··············@gmail.com> writes:
> jakemiles wrote:
>> Hello all. I'm completely confused no matter what I look at on the
>> internet or in Paul Graham's Ansi Common Lisp. I just want to obtain a
>> list of all functions defined in a package. Can someone show me a
>> clear example of how this is done? For example, what code would list
>> all the functions defined in common-lisp? Also, I'm not interested in
>> inherited functions, only those defined in the package itself.
>
> I'm sure wiser heads will post better solutions, but here's a piecewise
> one that might help:
>
> (defun symbol-function-p (sym)
> "Is there a function associated with this symbol?"
> (handler-case (symbol-function sym)
> (undefined-function () nil)))
Macros also have a symbol-function.
> (defun defun-in-package-p (s p)
> "Is this symbol interned in this package, and is there a
> function asssociated with it?"
> (and (symbol-function-p s)
> (eq p (symbol-package s))))
Well implementations may export from COMMON-LISP symbols that are
actually defined somewhere else and imported into COMMON-LISP...
(length (remove (find-package "COMMON-LISP")
(com.informatimago.common-lisp.package:package-exports "COMMON-LISP")
:key (function symbol-package)))
--> 54
Better use com.informatimago.common-lisp.package:package-exports to get the symbols
exported from a package...
http://darcs.informatimago.com/lisp/common-lisp/package.lisp
So, to get the list of the functions that are _exported_ from a package:
(defun package-functions (package)
(remove-if-not (lambda (x) (and (fboundp x) (not (macro-function x))))
(com.informatimago.common-lisp.package:package-exports package)))
(length (package-functions "COMMON-LISP"))
--> 660
--
__Pascal Bourguignon__ http://www.informatimago.com/
HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.
Pascal Bourguignon wrote:
> "Graham Fawcett" <··············@gmail.com> writes:
> > (defun symbol-function-p (sym)
> > "Is there a function associated with this symbol?" ...)
> Macros also have a symbol-function.
I didn't know that. Thanks.
> So, to get the list of the functions that are _exported_ from a package:
>
> (defun package-functions (package)
> (remove-if-not (lambda (x) (and (fboundp x) (not (macro-function x))))
> (com.informatimago.common-lisp.package:package-exports package)))
LOOP has a "being the external-symbols" clause; I think this would do
the same thing, right?
(flet ((test (x) (and (fboundp x)
(not (macro-function x)))))
(loop for s being the external-symbols in (find-package :common-lisp)
when (test s) count s))
--> 661
You got 660; I wonder what my 661st function is...
--g
Pascal Bourguignon wrote:
> "Graham Fawcett" <··············@gmail.com> writes:
> > You got 660; I wonder what my 661st function is...
>
> Using: [snip] in these implementations: [snip] we get: [big-snip]
Must...resist...the...urge... to generate the Venn diagram... ;-)
--g
On 2006-11-23 07:15:43 +0000, Pascal Bourguignon <···@informatimago.com> said:
> Well implementations may export from COMMON-LISP symbols that are
> actually defined somewhere else and imported into COMMON-LISP...
However the test for the symbol-package of the symbol being the package
you're looking at tells you just that.
(message (Hello 'Graham)
(you :wrote :on '(22 Nov 2006 21:30:51 -0800))
(
GF> (defun symbol-function-p (sym)
GF> "Is there a function associated with this symbol?"
GF> (handler-case (symbol-function sym)
GF> (undefined-function () nil)))
why not just fboubdp?
)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity")
Alex Mizrahi wrote:
> (message (Hello 'Graham)
> (you :wrote :on '(22 Nov 2006 21:30:51 -0800))
> (
>
> GF> (defun symbol-function-p (sym)
> GF> "Is there a function associated with this symbol?"
> GF> (handler-case (symbol-function sym)
> GF> (undefined-function () nil)))
>
> why not just fboubdp [sic]?
Ignorance of its existence. ;-) Thank you.
Graham
On 2006-11-23 00:30:51 -0500, "Graham Fawcett" <··············@gmail.com> said:
> here's a piecewise
> one
The same, all at one hackish go thanks to relentless use of loop keywords ;^)
(defun doc-pkg-fns (pkg)
(loop with home-package = (find-package pkg)
for sym being each symbol of home-package
when (handler-case (symbol-function sym) (undefined-function () nil))
when (eq (symbol-package sym) home-package)
do (format t "~a~%~a~%~%" sym
(or (documentation sym 'function) ""))))
On 2006-11-23 12:19:37 -0500, Raffael Cavallaro
<················@pas-d'espam-s'il-vous-plait-mac.com> said:
> The same, all at one hackish go thanks to relentless use of loop keywords ;^)
Or with fboundp - duh!
(defun doc-pkg-fns (pkg)
(loop with home-package = (find-package pkg)
for sym being each symbol of home-package
when (fboundp sym)
when (eq (symbol-package sym) home-package)
do (format t "~a~%~a~%~%" sym
(or (documentation sym 'function) ""))))
Thanks everyone for all the input. This is what I came up with on my
own, though there are clearly more experienced lispers in the room.
This code works though, for any third parties interested. It also
doesn't use loop, which I personally don't like because I find it
complicated. I prefer plain old tail recursion. I know I'm weird this
way.
(defun package-symbols (package &key (external t) (internal t)
(inherited nil))
(mapcar #'car (package-symbol-access-pairs package
:external external
:internal internal
:inherited inherited)))
(defun package-symbol-access-pairs (package &key (external t) (internal
t) (inherited nil))
(remove-if-not (lambda (symbol-access-pair)
(let ((accessibility (cdr symbol-access-pair)))
(or (and external (eq accessibility :external))
(and internal (eq accessibility :internal))
(and inherited (eq accessibility :inherited)))))
(all-package-symbol-access-pairs package)))
(defun all-package-symbol-access-pairs (package)
(let ((all-symbols))
(do-symbols (x package)
(multiple-value-bind (symbol accessibility)
(find-symbol (symbol-name x) package)
(push (cons symbol accessibility) all-symbols)))
all-symbols))
- Jake
jakemiles wrote:
> Thanks everyone for all the input. This is what I came up with on my
> own, though there are clearly more experienced lispers in the room.
> This code works though, for any third parties interested. It also
> doesn't use loop, which I personally don't like because I find it
> complicated. I prefer plain old tail recursion. I know I'm weird this
> way.
Erm, no it doesn't use tail recursion. It does use a functional style
of programming. MAPCAR and REMOVE-IF-NOT are both higher-order
functions --- functions that take other functions as arguments --- and
are usual suspects in a functional program. I think this is what you
mean. Tail recursion is something else entirely, and it's not present
in your code.
Whether you use LOOP or a functional approach is a matter of personal
taste, and I doubt that you would be considered "weird" in any Lisp
circles for preferring the latter. Stand tall and be functional! ;-)
--g