Re: Array and Hash-Table References



andrew.baine@xxxxxxxxx <andrew.baine@xxxxxxxxx> wrote:
+---------------
| On Sep 19, 5:46 pm, are <Propon...@xxxxxxx> wrote:
| > What are the pros and cons of a Lisp in which (AREF x 3) and (GETHASH
| > 'c y), for example, becomes (x 3) and (y 'c), respectively? The
| > latter are more concise; is there a down side?
|
| We've heard some cons, but on the pro side, functions and the data
| structures you mention alike are mappings. It'd be nice to abstract
| away whether that mapping is calculated by a function or stored in an
| object.
+---------------

O.k., o.k., have it your way:

> (defmacro define-funcallable-array (name dimensions
&rest array-init-args)
(let ((lex-name
(intern (concatenate 'string (symbol-name :*LEXVAR-FOR-)
(symbol-name name)
(symbol-name :*))
(symbol-package name)))
(setf-name
(intern (concatenate 'string (symbol-name :setf-)
(symbol-name name))
(symbol-package name))))
`(progn
(defparameter ,lex-name
(make-array ,dimensions ,@array-init-args))
(define-symbol-macro ,name ,lex-name)
(defun ,name (&rest indices)
(apply #'aref ,name indices))
;; Awkward, but the only alternative is reversal, like GETHASH.
(defun ,setf-name (index-list new-value)
(setf (apply #'aref ,name index-list) new-value)))))

DEFINE-FUNCALLABLE-ARRAY
> (loop for i below 3 collect
(loop for j below 5 collect
(+ 100 (* i 10) j)))

((100 101 102 103 104) (110 111 112 113 114) (120 121 122 123 124))
> (define-funcallable-array foo '(3 5) :initial-contents *)

SETF-FOO
> foo

#2A((100 101 102 103 104) (110 111 112 113 114) (120 121 122 123 124))
> (foo 1 2)

112
> (setf-foo (list 1 2) 3737)

3737
> (foo 1 2)

3737
> foo

#2A((100 101 102 103 104) (110 111 3737 113 114) (120 121 122 123 124))
>

Happy now?!?


-Rob

-----
Rob Warnock <rpw3@xxxxxxxx>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607

.