Wednesday, January 28, 2009

Lisp macros, eval and packages

Today I spent about an hour trying to find out the source of a bug in the code for my PhD prototype. To make the context short, I need to have a class definition to be stored, and loaded afterwards. And I was using Gary King's time-saver metatilities:defclass* to reduce the required coding. The problem was when I wanted to load such a definition in a generic method, I was evaluating the definition expression - one of the acceptable uses of `eval', correct me if I'm wrong, is to interpret something that was just read (in this case, from a serialized string, from other servers). The code in question was something like this:

(defmacro load-data (name attributes)
  "Defines a domain concept, using metatilities:defclass* syntax."
  `(progn
     (metatilities:defclass* ,name (data-item)
       (,@attributes)
       (:metaclass profiled-metaclass)
       (:name-prefix  ,(format nil "~(~A~)" name)))
     (info "Data type loaded: ~A" ',name)))

(defmethod load-definition ((def data-item-definition))
  (eval (macroexpand `(load-data ,(definition-name def)
                                                     ,(data-item-definition-attributes def)))))

What I was getting as a result is that the auxiliary methods created as accessors by defclass* weren't being imported in my packaged, but in CL-USER. Hence, lots and lots of compiler warnings and subsequent errors when trying to use those accessors. I fiddled around, tried to see if I could remove the eval, but the solution, so obvious as I know can see, is quite simple. Just place your evaluated expression after setting the package. The fixed method is the following:

(defmethod load-definition ((def data-item-definition))
  (eval `(progn (in-package :dshow)
                ,(macroexpand `(load-data ,(definition-name def)
                                          ,(data-item-definition-attributes def))))))

Hope you can see this before spending too much time on a similar bug!

Monday, January 26, 2009

Quick Emacs nicity

I can’t remember from whose configuration I got this piece of code. But it makes my lispy screen a little bit cuter, by turning all “(lambda” into the greek character. I tested on aquamacs, and on the Windows GNU Emacs, and it works. If anyone knows the original author of the idea, send him/her my thanks :)


;; Make lambdas appear as the character » (saves space!!)
(defun pretty-lambdas ()
  (interactive)
  (font-lock-add-keywords
   nil `(("(\\(lambda\\>\\)"
          (0 (progn (compose-region (match-beginning 1) (match-end 1)
                                    ,(make-char 'greek-iso8859-7 107))
                    nil))))))
(add-hook 'lisp-mode-hook 'pretty-lambdas)
(add-hook 'emacs-lisp-mode-hook 'pretty-lambdas)

Friday, January 02, 2009

On iPhone SDK and its pretty icons on tab bar items

After having made some experimentation around the iPhone SDK, I have now a simple - but useful - native application. I focused on the functionality, and up until now, I had a tab-bar with no icons. But that's not the Apple-way to present things. iPhone apps are pretty, and have simple but elegant icons with a gray tone that turn blue when selected. So i looked upon a library/bundle for some of those standard buttons, and found... none! Ok, no worries, let's find out how to make them. Wait. There isn't a specification for them! Yes, it's a shame, but Apple's iPhone SDK documentation is still a bit unfinished. The good news is that what is done, is easy to read and helpful. I ended up looking at other apps resources, found out they were 32x32 png images, and figured they had to have at least an alpha channel outside the image itself. So I fired Gimp, made a plain brush doodle and removed the background white, saved and tested. And it simply works! All colors are turned into the desired gray tone, and automatically swap to a smooth blue with a top glare when selected. Conclusion: the trick is to experiment. Chances are that what you want to do is *that* simple!