One day it occured to me that I should create a macro that would turn
tracing on for the functions of an entire package, after having done it
manually for the nth time that day. Being new to lisp I went through
the hyperspec and then the implementation docs for clisp to see if it
had already been done and see how I would do it if it wasn't. After a
little bit I whipped up the following macro. As far as I can tell it
should work but I keep getting a SIMPLE-PACKAGE-ERROR everytime I use
it. Would some kind soul clue me in as to why it doesn't work?
(defmacro trace-defuns-for-package ()
"Cause trace to be called on all functions in current package."
(let ((all-funs nil))
(do-symbols (sym)
(when (fboundp sym)
(push sym all-funs)))
`(ignore-errors (trace ,@all-funs))))
Stormcoder wrote:
> One day it occured to me that I should create a macro that would turn
> tracing on for the functions of an entire package, after having done it
> manually for the nth time that day. Being new to lisp I went through
> the hyperspec and then the implementation docs for clisp to see if it
> had already been done and see how I would do it if it wasn't. After a
> little bit I whipped up the following macro. As far as I can tell it
> should work but I keep getting a SIMPLE-PACKAGE-ERROR everytime I use
> it. Would some kind soul clue me in as to why it doesn't work?
>
> (defmacro trace-defuns-for-package ()
> "Cause trace to be called on all functions in current package."
> (let ((all-funs nil))
> (do-symbols (sym)
> (when (fboundp sym)
> (push sym all-funs)))
> `(ignore-errors (trace ,@all-funs))))
Am I right in saying this could be done with a function? If so, I'd
avoid the macro.
Brad
"bradb" <··············@gmail.com> writes:
> Stormcoder wrote:
>> One day it occured to me that I should create a macro that would turn
>> tracing on for the functions of an entire package, after having done it
>> manually for the nth time that day. Being new to lisp I went through
>> the hyperspec and then the implementation docs for clisp to see if it
>> had already been done and see how I would do it if it wasn't. After a
>> little bit I whipped up the following macro. As far as I can tell it
>> should work but I keep getting a SIMPLE-PACKAGE-ERROR everytime I use
>> it. Would some kind soul clue me in as to why it doesn't work?
>>
>> (defmacro trace-defuns-for-package ()
>> "Cause trace to be called on all functions in current package."
>> (let ((all-funs nil))
>> (do-symbols (sym)
>> (when (fboundp sym)
>> (push sym all-funs)))
>> `(ignore-errors (trace ,@all-funs))))
>
> Am I right in saying this could be done with a function? If so, I'd
> avoid the macro.
(defmacro trace-all-functions-in-package (&optional (package *package*))
`(trace
,@(loop for symbol being each present-symbol in package
when (and (fboundp symbol)
(not (or (special-operator-p symbol)
(macro-function symbol)))
(null (search "TRACED-" (symbol-name symbol)
:test #'char=)))
collect symbol)))
doesn't cause any errors for me in CLISP. I'm not sure why you were
getting errors, but TRACE (in CLISP at least) creates a function
TRACED-FOO for each function FOO that you trace. You probably don't
want to trace the trace functions. ;)
It seems like the only way to do this with a function is to call EVAL
(since TRACE is a macro), but I agree with Brad that a function would
be nicer.
--
You fool! You fell victim to one of the classic blunders! The most
famous is, "Never get involved in a land war in Asia", but only
slightly less well-known is this: "Never go in against a Sicilian when
death is on the line"!
Bill Atkins <············@rpi.edu> writes:
> "bradb" <··············@gmail.com> writes:
>
>> Stormcoder wrote:
>>> One day it occured to me that I should create a macro that would turn
>>> tracing on for the functions of an entire package, after having done it
>>> manually for the nth time that day. Being new to lisp I went through
>>> the hyperspec and then the implementation docs for clisp to see if it
>>> had already been done and see how I would do it if it wasn't. After a
>>> little bit I whipped up the following macro. As far as I can tell it
>>> should work but I keep getting a SIMPLE-PACKAGE-ERROR everytime I use
>>> it. Would some kind soul clue me in as to why it doesn't work?
>>>
>>> (defmacro trace-defuns-for-package ()
>>> "Cause trace to be called on all functions in current package."
>>> (let ((all-funs nil))
>>> (do-symbols (sym)
>>> (when (fboundp sym)
>>> (push sym all-funs)))
>>> `(ignore-errors (trace ,@all-funs))))
>>
>> Am I right in saying this could be done with a function? If so, I'd
>> avoid the macro.
>
> (defmacro trace-all-functions-in-package (&optional (package *package*))
> `(trace
> ,@(loop for symbol being each present-symbol in package
> when (and (fboundp symbol)
> (not (or (special-operator-p symbol)
> (macro-function symbol)))
> (null (search "TRACED-" (symbol-name symbol)
> :test #'char=)))
> collect symbol)))
>
> doesn't cause any errors for me in CLISP. I'm not sure why you were
> getting errors, but TRACE (in CLISP at least) creates a function
Peter's post just answered this question for me. :) The present-symbol
clause makes sure that imported symbols are ignored.
--
You fool! You fell victim to one of the classic blunders! The most
famous is, "Never get involved in a land war in Asia", but only
slightly less well-known is this: "Never go in against a Sicilian when
death is on the line"!
Yours works just fine. The output from mine is the following:
;; Tracing function STREAM-READ-CHAR-SEQUENCE.
NIL ;
#<SYSTEM::SIMPLE-PACKAGE-ERROR #x204C0B9E>
This is just a convenience macro that I am going to put in my rc so it
doesn't really matter if it is a macro or function. I'm still learning
lisp and I am trying to figure out why my version doesn't work for my
own edification.
"Stormcoder" <·········@gmail.com> writes:
> One day it occured to me that I should create a macro that would turn
> tracing on for the functions of an entire package, after having done it
> manually for the nth time that day. Being new to lisp I went through
> the hyperspec and then the implementation docs for clisp to see if it
> had already been done and see how I would do it if it wasn't. After a
> little bit I whipped up the following macro. As far as I can tell it
> should work but I keep getting a SIMPLE-PACKAGE-ERROR everytime I use
> it. Would some kind soul clue me in as to why it doesn't work?
>
> (defmacro trace-defuns-for-package ()
> "Cause trace to be called on all functions in current package."
> (let ((all-funs nil))
> (do-symbols (sym)
> (when (fboundp sym)
> (push sym all-funs)))
> `(ignore-errors (trace ,@all-funs))))
Two things to note:
1) DO-SYMBOLS iterates over all the symbols accessible in the
package. Which includes symbols from COMMON-LISP, if your package
uses COMMON-LISP as it almost certainly does.
2) Per 11.1.2.1.2 Constraints on the COMMON-LISP Package for
Conforming Programs, the consequences are undefined if you try to
trace a function named by an external symbol of the COMMON-LISP
package.
What you probably want is something more like:
(do-symbols (sym)
(when (and (eql (symbol-package sym) *package*) (fboundp sym))
(push sym to-trace)))
-Peter
--
Peter Seibel * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/
That fixed my problem. I do get warning like this:
WARNING: TRACE: redefining function COPY-LOCALE-CONV in top-level, was
defined
in /build/buildd/clisp-2.38/debian/build/i18n/i18n.fas
There's a bunch like this. Bill's version doesn't produce these
warnings. Given that this macro is only ever going to be used for
debugging, do you think that these warnings are a problem?
I enjoyed your book.