Thursday, May 11, 2006

LISP Arrays

I found practically no "single source" tutorial on how to work with arrays in
(Common) LISP (although by browsing around, one can learn it -
like I did :-) ). Here I attempt to present a simple tutorial on the usage of
one-dimensional arrays. The higher dimensions can be used by imaginatively
extending the usage...

Creating Arrays

Array with 5 slots:

CL-USER>(setf foo (make-array 5))
#(NIL NIL NIL NIL NIL)
Array with 5 slots - each initialized to 0(zero):
CL-USER>(setf foo (make-array 5 :initial-element 0))
#(0 0 0 0 0)
Array with 5 slots - initialized to a custom list of values:
CL-USER> (setf foo (make-array 5 :initial-contents '(0 1 2 3 4)))
#(0 1 2 3 4)
Array with 5 slots - initialized to heterogeneous types of values:
CL-USER> (setf foo (make-array 5 :initial-contents
'(0 "one" 'two '("t" "h" "r" "e" "e") nil)))
#(0 "one" 'TWO '("t" "h" "r" "e" "e") NIL)
Number of slots in the form associated with initial contents must match the number of slots in then array.

Working with Arrays

LISP Arrays work with a zero based index Scheme (:-) ).
Accessing the value at an index:
CL-USER> (setf foo (make-array 5 :initial-contents '(0 1 2 3 4)))
#(0 1 2 3 4)
CL-USER> (aref foo 3)
3
Assigning to a value at an index:
CL-USER> (setf foo (make-array 5 :initial-contents '(0 1 2 3 4)))
#(0 1 2 3 4)
CL-USER> (setf (aref foo 3) "three")
"three"
CL-USER> foo
#(0 1 2 "three" 4)
(From the above it is clear that) Like many other "pointer" functions of LISP, aref returns something that is suited both as an lvalue and an rvalue. This is magic incanted by setf macro and define-setf-expander macro. See
  1. section on assignments
    and generalized assignments
    of peter siebel's book to learn more about setf
  2. hyperspec for setf and define-setf-expander.
fill pointers control the location at which vector functions such as vector-push and vector-pop.
CL-USER> (setf foo (make-array 5 :initial-contents '(0 1 2 3 4) :fill-pointer 3))
#(0 1 2)
CL-USER> (vector-push "three" foo)
3
CL-USER> foo
#(0 1 2 "three")
CL-USER> (vector-pop foo)
"three"
CL-USER> foo
#(0 1 2)
CL-USER> (setf (fill-pointer foo) 4)
4
CL-USER> foo
#(0 1 2 "three")
CL-USER> (fill-pointer foo)
4
Notice that "three" is still lurking there after the pop.

Resources

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home