Subject: Re: Array and Hash-Table References
From: rpw3@rpw3.org (Rob Warnock)
Date: Thu, 20 Sep 2007 23:38:13 -0500
Newsgroups: comp.lang.lisp
Message-ID: <JbidnXlzmMMo127bnZ2dnUVZ_o2vnZ2d@speakeasy.net>
andrew.baine@gmail.com <andrew.baine@gmail.com> wrote:
+---------------
| On Sep 19, 5:46 pm, are <Propon...@gmx.net> 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@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607