Quazi-quote, missing one evaluation

Discussion of Common Lisp

Quazi-quote, missing one evaluation

Postby wvxvw » Tue Oct 02, 2012 1:24 am

Hi. I'm trying to come up with a simple table to object mapping (a learning exercise for now, not a real thing). Below is my code, where I can achieve what I need, but in a clumsy way:

Code: Select all
(defclass db-object () ())

(defun slot-list-from-query (query)
  (format t "slot-list-from-query: ~s~&" query)
  (mapcar
   #'(lambda (pair)
       (format t "pair: ~s~&" pair)
       (let ((name (string-upcase (symbol-name (car pair)))))
         (list (intern name)
               :accessor
               (intern (concatenate 'string name "-OF"))
               :initarg (intern name "KEYWORD")))) query))

(defun make-class-with-slots (name slots)
  (format t "defining class: ~s, slots: ~s~&" name slots)
  `(defclass ,name (db-object) ,slots))

(defmacro table-to-class (name describe-table-query)
  `(let ((db-class (make-class-with-slots
                    ',name
                    (slot-list-from-query ,describe-table-query))))
     (eval db-class) ; this line particularly bothers me.
     (defmethod initialize-instance :after ((object ,name) &key raw-data)
                (mapcar
                 #'(lambda (pair)
                     (setf (slot-value object
                                       (find-symbol
                                        (string-upcase
                                         (symbol-name (car pair)))))
                           (cdr pair))) raw-data))
     db-class))


There are too many macros inside macrose, and I can't think of a way to make it work better. I need to evaluate a macro which is dynamically constructed inside another macro, and that just too many nesting levels then I can handle :cry:

I've also duplicated the code here http://pastebin.com/iXXMCDad for better readability.
wvxvw
 
Posts: 125
Joined: Sat Mar 26, 2011 6:23 am

Re: Quazi-quote, missing one evaluation

Postby pjstirling » Tue Oct 02, 2012 5:34 am

You've managed to avoid the double quasi-quote pit-trap with your helper, all you need do is use it :)

Code: Select all
(defclass db-object () ())
     
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defun slot-list-from-query (query)
    (format t "slot-list-from-query: ~s~&" query)
    (mapcar
     #'(lambda (pair)
    (format t "pair: ~s~&" pair)
    (let ((name (string-upcase (symbol-name (car pair)))))
      (list (intern name)
       :accessor
       (intern (concatenate 'string name "-OF"))
       :initarg (intern name "KEYWORD")))) query))

  (defun make-class-with-slots (name slots)
    (format t "defining class: ~s, slots: ~s~&" name slots)
    `(defclass ,name (db-object) ,slots)))

(defmacro table-to-class (name describe-table-query)
  `(progn
     ,(make-class-with-slots name
              (slot-list-from-query describe-table-query))
     (defmethod initialize-instance :after ((object ,name) &key raw-data)
       (mapcar
   #'(lambda (pair)
       (setf (slot-value object
               (find-symbol
                (string-upcase
            (symbol-name (car pair)))))
        (cdr pair))) raw-data))
     db-class))


pjstirling
 
Posts: 76
Joined: Sun Nov 28, 2010 4:21 pm

Re: Quazi-quote, missing one evaluation

Postby wvxvw » Thu Nov 01, 2012 1:41 pm

Oh, sorry, I've totally missed this reply! Although, too late, thanks!
wvxvw
 
Posts: 125
Joined: Sat Mar 26, 2011 6:23 am


Return to Common Lisp

Who is online

Users browsing this forum: Google [Bot] and 2 guests

cron