After googling for about an hour, I have to confess, that while I find a lot of documentation about functions operating on bit arrays, I cannot find a single reference on how to actually create a bit array.
Right now, it seems to me that either, some arrays with other element types can be handled as bit arrays OR that one could use (make-array :element-type (???)) where I could not find any explanation as to what to put where I wrote the "???".
So, while it is probably obvious to anyone else, I have no idea how to create a bit array. I know about how to write a literal bit array - but if I need a bit array with, say 2^16 bits - how would I do it?
You are right about using make-array, just use 'bit as the element type. Try
(make-array initial-size :element-type 'bit).
The symbol BIT names the bit type and could be replaced with any other type specifier to make an array holding objects of that type. In this example initial-size is just a variable holding a whole number.
Another way to create a bit vector:
> (make-sequence '(vector bit) 10)
#*0000000000
There's also a literal syntax using the #* reader macro, and notice that the concrete type may differ between using make-array and make-sequence, though I am not sure if performance may be different depending on that...
Tested with SBCL:
CL-USER> (defvar arr (make-array 10 :element-type 'bit :fill-pointer 0))
ARR
CL-USER> (type-of arr)
(VECTOR T 10)
CL-USER> (defvar arr3 (make-sequence '(vector bit) 10))
ARR3
CL-USER> (type-of arr3)
(SIMPLE-BIT-VECTOR 10)
CL-USER> (type-of #*0101010100)
(SIMPLE-BIT-VECTOR 10)
How about this:
(setq x 10)
10
(setq y (read-from-string (format nil "#*~7,'0b" x)))
#*0001010
The 7 is an arbitrary length, which could be set by
(setq z 8)
8
(setq y (read-from-string (format nil (concatenate 'string "#*~" (write-to-string z) ",'0b") x)))
#*00001010
A large bit array may be better handled as an unsigned integer.
Related
I'm Haruo. My pleasure is solving SPOJ in Common Lisp(CLISP). Today I solved Classical/Balk! but in SBCL not CLISP. My CLISP submit failed due to runtime error (NZEC).
I hope my code becomes more sophisticated. Today's problem is just a chance. Please the following my code and tell me your refactoring strategy. I trust you.
https://github.com/haruo-wakakusa/SPOJ-ClispAnswers/blob/0978813be14b536bc3402f8238f9336a54a04346/20040508_adrian_b.lisp
Haruo
Take for example get-x-depth-for-yz-grid.
(defun get-x-depth-for-yz-grid (planes//yz-plane grid)
(let ((planes (get-planes-including-yz-grid-in planes//yz-plane grid)))
(unless (evenp (length planes))
(error "error in get-x-depth-for-yz-grid"))
(sort planes (lambda (p1 p2) (< (caar p1) (caar p2))))
(do* ((rest planes (cddr rest)) (res 0))
((null rest) res)
(incf res (- (caar (second rest)) (caar (first rest)))))))
style -> ERROR can be replaced by ASSERT.
possible bug -> SORT is possibly destructive -> make sure you have a fresh list consed!. If it is already fresh allocated by get-planes-including-yz-grid-in, then we don't need that.
bug -> SORT returns a sorted list. The sorted list is possibly not a side-effect. -> use the returned value
style -> DO replaced with LOOP.
style -> meaning of CAAR unclear. Find better naming or use other data structures.
(defun get-x-depth-for-yz-grid (planes//yz-plane grid)
(let ((planes (get-planes-including-yz-grid-in planes//yz-plane grid)))
(assert (evenp (length planes)) (planes)
"error in get-x-depth-for-yz-grid")
(setf planes (sort (copy-list planes) #'< :key #'caar))
(loop for (p1 p2) on planes by #'cddr
sum (- (caar p2) (caar p1)))))
Some documentation makes a bigger improvement than refactoring.
Your -> macro will confuse sbcl’s type inference. You should have (-> x) expand into x, and (-> x y...) into (let (($ x)) (-> y...))
You should learn to use loop and use it in more places. dolist with extra mutation is not great
In a lot of places you should use destructuring-bind instead of eg (rest (rest )). You’re also inconsistent as sometimes you’d write (cddr...) for that instead.
Your block* suffers from many problems:
It uses (let (foo) (setf foo...)) which trips up sbcl type inference.
The name block* implies that the various bindings are scoped in a way that they may refer to those previously defined things but actually all initial value may refer to any variable or function name and if that variable has not been initialised then it evaluates to nil.
The style of defining lots of functions inside another function when they can be outside is more typical of scheme (which has syntax for it) than Common Lisp.
get-x-y-and-z-ranges really needs to use loop. I think it’s wrong too: the lists are different lengths.
You need to define some accessor functions instead of using first, etc. Maybe even a struct(!)
(sort foo) might destroy foo. You need to do (setf foo (sort foo)).
There’s basically no reason to use do. Use loop.
You should probably use :key in a few places.
You write defvar but I think you mean defparameter
*t* is a stupid name
Most names are bad and don’t seem to tell me what is going on.
I may be an idiot but I can’t tell at all what your program is doing. It could probably do with a lot of work
For 2D graphics I need to optimize my functions, but in SBCL I get lots of comments about SBCL not being able to inline arithmetic operations. I tried all sorts of declarations but it doesn't seem to make the compiler happy. Here is a simple example:
(defun test-floor (x div)
(declare (type single-float x)
(type (signed-byte 64) div)
(optimize (speed 3)))
(floor x div))
gives the following 4 notes below. I'm completely lost as #'floor is a builtin function. I tried to find information/tutorials on how to properly give the compiler hints in SBCL and didn't find the right information, so any info would be very appreciated! Unfortunately optimization in Common Lisp is quite unknown territory for me. I'm using SBCL 1.3.20 on a Linux machine.
; file: /tmp/file595dqU
; in: defun test-floor
; (FLOOR CL-FLOCKS::X CL-FLOCKS::DIV)
; --> MULTIPLE-VALUE-BIND MULTIPLE-VALUE-CALL TRUNCATE LET*
; ==>
; (SB-KERNEL:%UNARY-TRUNCATE/SINGLE-FLOAT (/ SB-C::X SB-C::F))
;
; note: forced to do full call
; unable to do inline float truncate (cost 5) because:
; The result is a (values integer &optional), not a (values
; (signed-byte 64) &rest
; t).
; --> MULTIPLE-VALUE-BIND MULTIPLE-VALUE-CALL TRUNCATE LET* VALUES - *
; ==>
; (SB-KERNEL:%SINGLE-FLOAT SB-C::RES)
;
; note: forced to do full call
; unable to do inline float coercion (cost 5) because:
; The first argument is a integer, not a (signed-byte 64).
; --> MULTIPLE-VALUE-BIND MULTIPLE-VALUE-CALL FUNCTION IF VALUES 1-
; ==>
; (- SB-C::TRU 1)
;
; note: forced to do generic-- (cost 10)
; unable to do inline fixnum arithmetic (cost 1) because:
; The first argument is a integer, not a fixnum.
; The result is a (values integer &optional), not a (values fixnum &rest t).
; unable to do inline fixnum arithmetic (cost 2) because:
; The first argument is a integer, not a fixnum.
; The result is a (values integer &optional), not a (values fixnum &rest t).
; etc.
; --> MULTIPLE-VALUE-BIND MULTIPLE-VALUE-CALL FUNCTION IF VALUES
; ==>
; (+ REM SB-C::DIVISOR)
;
; note: doing signed word to integer coercion (cost 20) from div, for:
; the second argument of generic-+
;
; compilation unit finished
; printed 4 notes
CL-USER>
When you call floor, you have to deal with different subtypes of numbers: the code divides a float by an integer (that may involve coercing the integer as a float), and then have to coerce the result back to an integer. This is the amount of work that must be done, correctly, and you are unlikely to bypass it if you don't restrict your input types.
If instead you use ffloor, then the primary result is a float (you can still round it to an integer later, when you really need it (e.g. convert to pixels coordinates)). The following code does not give compilation notes:
(defun test-floor (x div)
(declare (type single-float x)
(type fixnum div)
(optimize (speed 3)))
(ffloor x div))
You may even declare div as being a float, which would push the responsibility of providing appropriately typed values (and performing runtime checks) to the callers.
Note also that you should probably (declaim (inline test-floor)) before you define the function; that helps because then the compiler can put shortcuts in the code to avoid checking input parameter types and boxing results.
Edit:
The range of a float cover a large possible domain (due to the exponent): more densely packed near zero, more spaced towards infinity. Integer values are linearly spaced, but cover a smaller range with the same number of bits. So if you want to guarantee your output fits in a fixnum, you have to make sure the float in your inputs does not go outside the range of fixnum, too. I tried the following:
(defun test-round (x)
(declare (type (single-float #.(float most-negative-fixnum 0f0)
#.(float (/ most-positive-fixnum 2) 0f0)) x)
(optimize (speed 3)))
(round x))
I had to half the upper range of the floats because when you test:
(typep (round (coerce most-positive-fixnum 'single-float)) 'fixnum)
... it returns NIL. I don't have much time to see why this happens, but this depends on your implementation and architecture. Taking half the most positive fixnum ensures the value is low enough to be converted as a fixnum. Now, I have no more compilation notes.
(the same goes for (signed-byte 64)))
NB. Unlike in the above example, you should use deftype and avoid repeating the same declarations everywhere.
If you want to specify the return value of an expression you can use THE:
(the fixnum (1+ 3))
But you really want to make sure that the value is actually a fixnum. If you 'lie', then Lisp may believe you and you have unspecified runtime effects. SBCL may warn at compile time, but you really should take care of that. If you provide wrong types are return wrong types, data may get corrupted and/or Lisp may crash.
Another way to specify a return value is the FTYPE declaration:
For example a function ith may take an integer and a list as arguments. It returns an arbitrary type -> T or any subtype.
(declaim (ftype (function (integer list) t)
ith))
For example:
(the fixnum (+ (the fixnum a) (the fixnum b)))
There you need to be sure that:
a is an fixnum
b is an fixnum
the sum of a and b is also always a fixnum
Here this is easier, since the sum of a and b is definitely a fixnum:
CL-USER 3 > (let ((a 3) (b 12))
(the fixnum (+ (the (integer 0 10) a)
(the (integer 3 20) b))))
15
Lisp may check that at runtime and/or compile-time. The addition now can be a simple fixnum operation and does not need to deal with fixnum overflows and bignums. If you set the safety value to something low, then the runtime check may also be omitted. But: you should never call this code with the wrong types.
SBCL is claiming that it can’t optimise the call to floor because it isn’t sure the return value will be small enough to fit into a 64-bit integer.
CL-USER> (test-floor 1f25 1234)
8103727629894569426944 ;
0.0
CL-USER> (format nil “~b” *)
;; a long binary string
CL-USER> (length *)
73
A 73 bit Integer may be returned but does not fit into 64 bits.
Se also the SBCL manual:
4 Compiler
4.1.3 Understanding Compiler Diagnostics
6 Efficiency
Edit: after some searching I have found the transformation for floor. It is here. I reproduce it below:
(deftransform floor ((number divisor))
`(multiple-value-bind (tru rem) (truncate number divisor)
(if (and (not (zerop rem))
(if (minusp divisor)
(plusp number)
(minusp number)))
(values (1- tru) (+ rem divisor))
(values tru rem))))
So that explains what the compiler messages were talking about
I am pretty much of a newbie to common-lisp and only use it for fun. But I assume to know the difference between mapper and mapcan, as the documentation in the hyperspec and other places is pretty clear.
But what happens if the function mapcan calls on the list elements evaluates to an atom instead of a list? As mapcan uses nconc to append lists, I had expected that there would be an error if there is no list.
But if I try
(mapcan (lambda (x) (+ 2 x)) '(1 2 3 4))
it evaluates to '6' in sbcl and clisp. (There might not be a practical need for this example; I am just curious) I see the point that returning a value might be nicer than a simpler error but could find anything about mapcan returning the last value if there are no lists to nconc.
Is there a reason for this behavior?
According to the documentation for mapcan (mapcan (lambda (x) (+ 2 x)) '(1 2 3 4)) Should do the same as (apply #'nconc (mapcar (lambda (x) (+ 2 x)) '(1 2 3 4))) and it signals an error the error *** - NCONC: 5 is not a list in clisp.
The hyperspec only shows what nconc should be doing with proper lists and nil as the arguments before last. It does not have anything else described so what you are seeing is that sbcl and clisp perhaps share the algorithm from a lisp in public domain or that they have implemented it so similar they have the same implementation specific results.
You probably cannot assume other implementations will do the same so you should make sure the function passed to mapcan always return a fresh list or nil that can be nconc-ed within the specification.
Imagine I have a class:
(defclass person () ())
And then I make some instances:
(setf anna (make-instance 'person))
(setf lisa (make-instance 'person))
How can I get either the objects themselves or the symbol names they were assigned to?
I want to be able to say something like (find-instances 'person) and get something like (anna lisa) or at least (#<PERSON {100700E793}> #<PERSON {100700E793}>).
What I am search for is the equivalent of each_object in ruby.
I very much want to be able to do it without an external library.
There is nothing like that built-in in Common Lisp.
Recording instances
For finding all instances of a class, one would usually make it that the class records the instance upon instance creation. One can imagine various mechanisms for that. Sometimes one would still want instances to be garbage collected - then one needs some kind of non-standard weak datastructure to do so. I would expect, that there are some libraries which implement similar things for CLOS instances.
Iterating over symbols of a package
If you would like to know which symbols of some or all packages have CLOS instances as a value, you could iterate over them (DO-SYMBOLS, DO-ALL-SYMBOLS, ...) and check if the have a symbol value and if that symbol value is an instance of a certain class.
There is no portable solution for this, as far as I know. If you are working on CCL, then map-heap-objects may do, what you are looking for
(defclass foo () ())
(defvar *x* (make-instance 'foo))
(defvar *y* (list (make-instance 'foo)))
(defun find-instances (n class)
(let ((buffer (make-array n :fill-pointer 0 :initial-element nil)))
(ccl:map-heap-objects (lambda (x)
(when (and (typep x class) (< (fill-pointer buffer) n))
(setf (aref buffer (fill-pointer buffer)) x)
(incf (fill-pointer buffer)))))
buffer))
(find-instances 2 'foo)
==> (#<FOO #x30200126F40D> #<FOO #x30200126634D>)
Similar solutions may exist for other Common Lisp implementations. Note, that you have to have an initial hunch as to how many instances the traversal may find. The reason is, that (as Rainer Joswig noted), the callback function should avoid consing. In order to achieve that, this implementation allocates a buffer up-front, and collects at most that many instances.
Suppose I define a function globally:
(defun x (y) (1+ y)) ;; Edit: my first example was too complicated
Is it possible to "coerce" the function x into a list like:
(x (y) (1+ y))
Thanks in advance!
PS - #Danlei's example works in Clozure CL with a special flag, however does anyone know how to get FUNCTION-LAMBDA-EXPRESSION to work in SBCL?
You could try FUNCTION-LAMBDA-EXPRESSION:
(function-lambda-expression #'foo)
But it's not guaranteed to work ("… implementations are free to return ``nil, true, nil'' in all cases …").
For example in CCL:
CL-USER> (setq ccl:*save-definitions* t)
T
CL-USER> (defun x (x y) (+ x y))
X
CL-USER> (function-lambda-expression #'x)
(LAMBDA (X Y) (DECLARE (CCL::GLOBAL-FUNCTION-NAME X)) (BLOCK X (+ X Y)))
NIL
X
In SBCL, you might try (setq sb-ext:*evaluator-mode* :interpret) (untested). Maybe there are other ways to achieve this in SBCL (you might look for an analog of *save-definitions* or even try different OPTIMIZE settings), but I don't know about them. Beware that functions entered in the REPL won't be compiled after setting *evaluator-mode* to :interpret, so you will probably experience worse performance.
In Common Lisp, you might be able to recover the definition of a function using function-lambda-expression (see the HyperSpec) or in some implementations uncompile-function.
When I was spending time on a project to do significant function manipulation, it was easiest to do this sort of thing:
(defclass node ()
(list-form
compiled-obj))
First the list form consisting of '(lambda foo (x ) bar) would be assigned, then I would compile Foo and assign it to the compiled-ojb slot.