Discussion of Common Lisp
-
gutzofter
- Posts: 10
- Joined: Thu Jul 03, 2008 12:53 pm
Post
by gutzofter » Tue Dec 16, 2008 9:40 am
As of right now I'm creating my own objects. I also use macros to automatically create those objects. The object is specifically a list composed of properties and their access functions:
Code: Select all
(defun make-obj ()
(let ((data :my-whatever))
(list
:get-data (lambda ()
data)
:set-data (lambda (d)
(setf data d)))))
(defun get-data (obj)
(funcall (getf obj :get-data)))
(defun set-data (obj d)
(funcall (getf obj :set-data) d))
I use this macro for each item in the property list to create access functions:
Code: Select all
(defmacro make-property (name&args)
(destructuring-bind (name args) name&args
(let ((g (gensym)))
`(progn
(defun ,(new-symbol (symbol-name name)) (obj ,@args)
(destructuring-bind ,args (rest ,g)
(apply (getf obj ,name) (WHAT-GOES-HERE?))))))))
WHAT-GOES-HERE? is the problem. Anybody have any suggestions?
-
S11001001
- Posts: 5
- Joined: Tue Sep 30, 2008 9:18 pm
- Location: Indiana, USA
-
Contact:
Post
by S11001001 » Wed Dec 17, 2008 4:20 am
I see a reference to ,g, but nothing that is binding it (g is bound in the compilation context, but the gensym created by g is not bound in the runtime context).
More broadly, I can't tell what you want make-property to define. Perhaps you have some usage examples?
-
Harleqin
- Posts: 71
- Joined: Wed Dec 17, 2008 5:18 am
- Location: Bonn, Germany
Post
by Harleqin » Wed Dec 17, 2008 9:12 am
This looks like you are trying to program Java with Lisp syntax. Have a look at defclass, and how accessors are defined in it.
-
gutzofter
- Posts: 10
- Joined: Thu Jul 03, 2008 12:53 pm
Post
by gutzofter » Wed Dec 17, 2008 12:27 pm
@S11001001
'destructoring-bind' handles lambda-lists (lists with keyword paramters?).
Code: Select all
(destructuring-bind (&key a) '(:a 1123) (print a))
The output:
The macroexpand-1:
Code: Select all
(LET ((#:WHOLE1043 '(:A 1123)))
(DECLARE (TYPE LIST #:WHOLE1043))
(LET* ((#:KEYWORDS-1045 #:WHOLE1043))
(DECLARE (SB-EXT:MUFFLE-CONDITIONS SB-EXT:CODE-DELETION-NOTE))
(DECLARE (IGNORABLE #:KEYWORDS-1045))
(MULTIPLE-VALUE-BIND
(#:KEY-PROBLEM-1046 #:INFO-1047)
(SB-KERNEL::VERIFY-KEYWORDS #:KEYWORDS-1045 '(:A) 'NIL)
(WHEN #:KEY-PROBLEM-1046
(ERROR 'SB-KERNEL::DEFMACRO-LAMBDA-LIST-BROKEN-KEY-LIST-ERROR
:KIND 'DESTRUCTURING-BIND :PROBLEM #:KEY-PROBLEM-1046 :INFO
#:INFO-1047)))
(LET* ((A
(IF (SB-KERNEL::KEYWORD-SUPPLIED-P :A #:KEYWORDS-1045)
(SB-KERNEL::LOOKUP-KEYWORD :A #:KEYWORDS-1045) NIL)))
(PRINT A))))
So when I do a d-bind on
I'm actually at run-time or the gensym should hold
The reason I think were using
instead of
is because I stole the example from OnLisp and it is part of creating macros. If you use a keyword parameter &whole it binds the entire form into whole, including the name and to do a rest means you get everything after the name.
-
gutzofter
- Posts: 10
- Joined: Thu Jul 03, 2008 12:53 pm
Post
by gutzofter » Wed Dec 17, 2008 12:27 pm
@Harleqin
Yes, I would say your right about Java and C#. If you look at my blog you can see some of my experiments with an object framework. I've learned a lot of Lisp because of this. Instead of doing book examples I thought I would get out there.
What I'm driving towards is framework that doesn't use inheritance. Instead of IS-A, drive towards HAS-A coupling and using events/closures for communicating between objects.
It looks like pretty soon I'll abandon my object framework. The underlying implementation is a hack-a-rama, but it is fun figuring out how to implement different functionality.
My Blog is:
http://uglylispcode.wordpress.com
-
gutzofter
- Posts: 10
- Joined: Thu Jul 03, 2008 12:53 pm
Post
by gutzofter » Thu Dec 18, 2008 1:01 am
WooHoo! I did it!
Code: Select all
(defmacro make-prop (name args)
(let ((g (gensym))
(r-args (flatten (remove-keywords args))))
`(progn
(defun ,name (obj &rest ,g)
(block ,name
(destructuring-bind ,args ,g
(declare (ignorable ,@r-args))
(apply (getf obj ',name) ,g)))))))
Note this is only REPL tested, not unit tested.
I was even able to silence the warning for the declared variables.
Here is the code to remove keywords from a tree.
Code: Select all
(defun replace-key-args (args)
(labels ((rka-aux (args is-key-arg?)
(if (atom args)
args
(progn
(if (equal '&key (first args))
(progn
(setf args (rest args))
(setf is-key-arg? t)))
(cond
(is-key-arg?
(if (consp (first args))
(cons (rka-aux (first args) nil)
(if (rest args)
(rka-aux (rest args) nil)))
(cons (rka-aux (make-keyword (first args)) nil)
(cons (rka-aux (first args) nil)
(if (rest args)
(rka-aux (rest args) t))))))
(t
(cons (rka-aux (first args) nil)
(if (rest args)
(rka-aux (rest args) nil)))))))))
(rka-aux args nil)))
If somebody wants to refactor it please show me the code.