Lisp is simmetry, understanding the find function

It may seems quite obvious, but the Lisp’s “find” semantic gave me some headache.
First of all, let’s start with some code:

(defvar *food-list*
  '((mela (pera banana)) (melanzane zucchine peperoni) (carne pesce uova)))

The “find” function gives you the power to search in a list for an item, returning back the element (if found) within his sublist (if present). Unfortunately, if the list is not symmetric, there is no guarantee to get the expected behaviour:

(find 'pera *food-list*)
=> NIL ;;WTF??

With find the list is visited one element at time, applying “eq” to any single element:

(eq 'pera '(mela (pera banana)))
=> NIL
(eq 'pera '(melanzane zucchine peperoni))
=> NIL
(eq 'pera '(carne pesce uova))
=> NIL

But how can we reach our pera within the find function? The “key” is in the “:key” parameter!!
With :key we can specify a function to be executed for each element find visit. It’s an old lisp school technique to use the car & cdr family functions:

(find 'pera *my-list* :key #'caadr)
=> (MELA (PERA BANANA))

Wow, it works! This is what happened in background for each element:

(eq 'pera (caadr '(mela (pera banana))))
=> T
(eq 'pera (caadr '(melanzane zucchine peperoni)))
=> NIL
(eq 'pera (caadr '(carne pesce uova)))
=> NIL

Simple enough, isn’t it?

Low and behold: subsequence

But what about searching for a sublist? What about searching for ‘(pera banana)? The following doesn’t work:

(find '(pera banana) *food-list* :key #'cadr)
=>NIL ;;WTF!!! AGAIN!!! WHY??

In order to solve this, remember what I’ve said about the comparison element by element! Yes, it’s made with the “eq” function! But you should know that “eq” works with nothing but symbols! We need the equal function in order to archive the result, but how can we force “find” using “equal”? The answer is in “:test”:

(find '(pera banana) *food-list* :test #'equal :key #'cadr)
=> (MELA (PERA BANANA)

Yes!

Conclusions

At the beginning some Lisp’s functions can be puzzling even if you are not a newbie with the functional programming, but this post should be useful to properly understand even the “find” function: Now let’s the hack begin! (cit. from Slime)

Bye!

Alfredo

Enable AutoComplete.el for lisp-mode

I don’t know exactly why, but AutoComplete.el for Emacs doesn’t work by default for standard lisp-mode, so there is my tweak:

1) Copied the scheme-mode from .emacs.d/ac-dict to the same dir but renaming it lisp-mode
2) I’ve put the following into my .emacs:

(add-to-list 'load-path "~/.emacs.d")
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")
(add-to-list 'ac-modes 'lisp-mode)
(ac-config-default)

The magic is provided by the line

(add-to-list 'ac-modes 'lisp-mode)

Hope this help 🙂

Sorry!!

I apologies for the lack of new articles in my blog, but I’m very busy right now! (University, everyday living, u know :O )
I hope to come back writing soon 🙂

Good night (and good luck)

Alfredo