I have found that SBCL 'do-symbols' (and loop) return duplicate items.
Testing environment: SBCL 1.1.4 x86 on Windows
Firstly, We define some helper functions:
;; compress from Ansi-Common-Lisp
(defun compress (x)
(labels ((rec (e x n)
(if (null x)
(if (= 1 n)
(list e)
(list (list e n)))
(if (eq e (car x))
(rec e (cdr x) (1+ n))
(cons (if (= 1 n)
e
(list e n))
(rec (car x)
(cdr x)
1))))))
(rec (car x) (cdr x) 1)))
(compress '(a a b c d d d))
;;=> ((A 2) B C (D 3))
;; This one can make the duplicate items visible:
(defun duplicates (list)
(remove-if-not #'listp (compress (sort list #'string<))))
(duplicates '(a a b c d d d))
;;=> ((A 2) (D 3))
;; This one use 'do-symbols' iterate each symbol in package, and check the
;; result
(defun test-pack-do-symbols (package)
(let (r)
(do-symbols (s package (duplicates r))
(push s r))))
When call the 'test-pack-do-symbols' on package :SB-MOP, you can see the duplicate items
(test-pack-do-symbols :sb-mop)
;;=> ((ADD-METHOD 2) (ALLOCATE-INSTANCE 2) (BUILT-IN-CLASS 2) (CLASS 2)
;; (CLASS-NAME 2) (COMPUTE-APPLICABLE-METHODS 2) (ENSURE-GENERIC-FUNCTION 2) #'2
;; (GENERIC-FUNCTION 2) (MAKE-INSTANCE 2) (METHOD 2) (METHOD-COMBINATION 2)
;; (METHOD-QUALIFIERS 2) (REMOVE-METHOD 2) (STANDARD-CLASS 2)
;; (STANDARD-GENERIC-FUNCTION 2) (STANDARD-METHOD 2) (STANDARD-OBJECT 2) (T 2))
There is another method to iterate symbols in a package, using the mighty 'loop'.
;; Now I define `test-pack-loop'
(defun test-pack-loop (package)
(duplicates (loop for s being each symbol in package
collect s)))
When call the 'test-pack-loop', you will not see the duplicate items.
(test-pack-loop :sb-mop)
;;=> NIL
But, even loop may return duplicate items on some packages, you can use the following code to see the difference between 'test-pack-do-symbols' and 'test-pack-loop'
(let (r1 r2)
(dolist (p (list-all-packages))
(when (test-pack-do-symbols p)
(push (package-name p) r1))
(when (test-pack-loop p)
(push (package-name p) r2)))
(print r1)
(print r2)
nil)
So, is this a bug, or consistent with the Standard?
Affected symbols: sb-c::stack-allocate-dynamic-extent, sb-c::stack-allocate-vector, and sb-c::stack-allocate-value-cells. These compiler policies were never officially supported, and turned out the be a flawed design. Remedy For code that needs stack-allocation in legacy SBCLs, conditionalize using:
SBCL provides a recursive event loop (serve-event) for doing non-blocking IO on multiple streams without using threads. Timeouts and Deadlines SBCL allows restricting the execution time of individual operations or parts of a computation using :timeoutarguments to certain blocking operations, synchronous timeouts and asynchronous timeouts.
About Steel Bank Common Lisp (SBCL) is a high performance Common Lisp compiler. It is open source / free software, with a permissive license. In addition to the compiler and runtime system for ANSI Common Lisp, it provides an interactive environment including a debugger, a statistical profiler, a code coverage tool, and many other extensions.
This has an impact on keyboard interrupt handling: pressing your terminal’s intr key (typically Control-C) will interrupt all processes in the foreground process group, including Lisp threads that SBCL considers to be notionally ‘background’. This is undesirable, so background threads are set to ignore the SIGINT signal.
Please refer to the Common Lisp Hyperspec which states
do-symbols iterates over the symbols accessible in package. Statements may execute more than once for symbols that are inherited from multiple packages.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With