help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Writing a function/macro in Elisp that generates a function at runti


From: Ted Zlatanov
Subject: Re: Writing a function/macro in Elisp that generates a function at runtime
Date: Tue, 28 Oct 2008 11:47:46 -0500
User-agent: Gnus/5.110011 (No Gnus v0.11) Emacs/23.0.60 (gnu/linux)

On Tue, 28 Oct 2008 13:42:57 +0100 Toby Cubitt <tsc25@cantab.net> wrote: 

TC> I have a higher-level data structure built on top of a lower-level one.
TC> Internally, the higher-level structure stores data "cells" in the
TC> lower-level structure. The lower-level structure of course knows nothing
TC> about this. It just stores any kind of data, without knowing anything
TC> about its structure. And users of the higher-level structure also know
TC> nothing about the data cells, which are part of the internal
TC> implementation. As far as users are concerned, they can just store data
TC> of whatever kind they like in the higher-level structure.

TC> For the lower-level structure, I have defined exactly this kind of
TC> insert-with-function, called say `low-level-insert-with-function'. What
TC> I'm trying to do is to define a `high-level-insert-with-function' for
TC> the higher-level data structure. Clearly, it has to call
TC> `low-level-insert-with-function' to insert the data into the lower-level
TC> structure on which it is build, something like:

TC> (defun high-level-insert-with-function (higher-structure data insfun)
TC>   (low-level-insert-with-function
TC>    (higher-structure--get-lower-structure higher-structure)
TC>    data ??insfun??))

TC> Now insfun knows nothing about the data cells, since it was passed in by
TC> the user. And `low-level-insert-with-function' knows nothing about data
TC> cells, since it acts on the lower-level data structure.

TC> So it would seem I need to wrap insfun on the fly in the above function,
TC> to make it aware that the data is actually stored within "cells". And
TC> we're back to the problem from my previous mail: how to generate a
TC> wrapped insfun on the fly, in such a way that the setf macro required to
TC> enter data into a "cell" is expanded into the cell-data accessor
TC> function at compile-time.

I don't understand why you're trying to cross between the storage and
the logic (essentially, that's what your "low level" and "high level"
layers are).  The logic layer should know how to convert its data to and
from a neutral data format (in Lisp, that's usually a list).  The
storage layer should just store and retrieve the neutral data format.

Your approach makes sense, IMO, in an OOP environment where every object
knows how to serialize itself.  I got the following from
http://dorophone.blogspot.com/ and it may help you to sort-of-do
serializable objects if that's your goal...  You just print the value of
each object you create, and later you can eval them back in.

HTH
Ted

;;; from J.V. Toups http://dorophone.blogspot.com/
(defun toups-bang (sym)
  (intern (format "%s!" sym)))
(defun toups-s-cat (sym1 sym2)
  (intern (format "%s-%s" sym1 sym2)))
(defun toups-ques (sym)
  (intern (format "%s?" sym)))

(defmacro defstruquine (name &rest slots)
  (let* ((n-fields (length slots))
   (i 1)
   (out `(progn
     (defun ,(toups-bang name) ,slots
       (list ',(toups-bang name) ,@slots)) 
     (defun ,(toups-ques name) (item)
       (eq (car item) ',(toups-bang name))))))
 (loop for slot in slots do
    (setf out 
    (append out
      (list `(defun ,(toups-s-cat name slot) (item) (elt item ,i)))))
    (setf i (+ i 1)))
 (append out (list nil))))

;; Which can be used thusly:

;; (defstruquine person first-name last-name age)

;; (let ((p (person! "Edward" "Olmos" 61)))
;;   (person-first-name p) ;; is "Edward"
;;   (person-age p) ;; is 62
;;   p) ;; returns (person! "Edward" "Olmos" 61)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]