On Lisp On Ruby

Vedi tutte le pagine e le modifiche recenti o scarica i sorgenti nella pagina


OnLispOnRuby

Ruby e’ stato spesso descritto come “un lisp con sintassi infissa”. Questo ha un senso in qualche modo, considerato che ruby fa un uso molto ampio di FormaLambda, che qualche funzione ha nomi simili (map, tanto per dire) e che alcune cose matz dice di averle prese dal CLOS.

Ma effettivamente, le similarita’ non sono tanto se si guarda meglio. Eppure, guardando meglio ancora, si trova una similarita’ anche piu’ profonda, cioe’; l’attenzione ad una tecnica di progrmmazione definita “bottom up” in cui le cose complesse vengono costruite su quelle semplici.

A questo riguardo, e’ obbligatorio pensare al libro OnLisp di Paul Graham, che e’ un po’ la massima espressione di questa idea.

Ovviamente il libro parla moltissimo di macro.. eppure per qualche motivo sento che alcune cose possono essere tradotte. Dunque, basandosi su URL:http://lib1.store.vip.sc5.yahoo.com/lib/paulgraham/onlisp.lisp?, io ci provo :)

(nota: scrivo senza possibilita’ di verificare il codice al momento, lo faro’ poi, senno fatelo voi :)

Sarebbe giusto implementare anche tutte le funzioni piu’ piccole, ma molte di esse sono built-in in ruby, e noi vogliamo sbrigarci ad arrivare a quelle piu’ interessanti :)

Ok, facile: (defun last1 (lst) (car (last lst)))

E’ una funzone predefinita: lst.last

questa: (defun single (lst) (and (consp lst) (not (cdr lst))))

sarebbe def single? (lst) lst0 and not lst1 end ma in ruby sarebbe meglio: class Array def single? size==1 end end

== Attenzione Array del Ruby != cons del Lisp —Matley

Anche in Lisp potresti fare (defmethod single? ((a list)) (eq (size a) 1))

append1/conc1 sono un poco inutili, data la presenza degli array literal. mklist e’ anch’essa un builtin, la funzione Kernel::Array(arg).

La funzione “longer” e’ piu’ interessante:

(defun longer (x y)
  (labels ((compare (x y)
             (and (consp x) 
                  (or (null y)
                      (compare (cdr x) (cdr y))))))
    (if (and (listp x) (listp y))
        (compare x y)
        (> (length x) (length y)))))

tradotto passo passo sarebbe un casino, ma in sostanza: def longer (x,y) x.is_a?(Array) and y.is_a?(Array) and (x.size > y.size) end

Non sono la stessa cosa, la longer di graham funziona con tutti gli oggetti che supportano l’operazione length, la tua solo con array. —Matley

La funzione filter è un builtin, dentro Enumerable.

Per le funzioni te la caveresti bene piu` o meno, ma per le macro? come fai a rendere una cosa del tipo (defmacro aif (test-form then-form &optional else-form) `(let ((it ,test-form)) (if it ,then-form ,else-form)))

Con cui puoi scrivere cose come: (aif (doesnt-work? object) (drop it) (use it))

Created on November 25, 2005 13:39 by il gruppo (256.256.256.256)