More work in the ‘typed-language’ branch of Vicare, for both the expander and the built–in types infrastructure. Some more type propagation stuff is implemented for built–in syntaxes.
Everything I discuss here is relative to code in the head of the ‘typed-language’ branch.
I have ported the multimethods library from the Nausicaa language to the typed
language implemented by (vicare)
. The main library is (vicare
language-extensions multimethods)
, the documentation is in the node
multimethods
of the documentation file vicare-libs. I got pissed with
myself while reviewing the documentation: there were still errors in there, even
after the multiple reviews I did in the past. Life is hard without proofreaders.
So, what about multimethods? Every Lisper should know about them, and (s)he should know that they are dog slow. Here I will show only a simple program that makes use of multimethods and labels:
#!vicare (program (demo) (options typed-language) (import (vicare) (vicare language-extensions multimethods) (vicare language-extensions labels)) (define-label <list-coords> (nongenerative user:<list-coords>) (parent (list <flonum> <flonum> <flonum>)) (method (x {O <list-coords>}) (list-ref O 0)) (method (y {O <list-coords>}) (list-ref O 1)) (method (z {O <list-coords>}) (list-ref O 2))) (define-label <vector-coords> (nongenerative user:<vector-coords>) (parent (vector <flonum> <flonum> <flonum>)) (method (x {O <vector-coords>}) (vector-ref O 0)) (method (y {O <vector-coords>}) (vector-ref O 1)) (method (z {O <vector-coords>}) (vector-ref O 2))) (define-record-type <coords> (fields {x <flonum>} {y <flonum>} {z <flonum>})) (module (add) (define-generic-definer definer (operand-type-inspector (lambda (obj) (cond ((is-a? obj <list-coords>) (type-unique-identifiers <list-coords>)) ((is-a? obj <vector-coords>) (type-unique-identifiers <vector-coords>)) (else (type-unique-identifiers-of obj)))))) (definer add (A B))) (define-method (add {A <list-coords>} {B <list-coords>}) (list (fl+ (.x A) (.x B)) (fl+ (.y A) (.y B)) (fl+ (.z A) (.z B)))) (define-method (add {A <vector-coords>} {B <vector-coords>}) (vector (fl+ (.x A) (.x B)) (fl+ (.y A) (.y B)) (fl+ (.z A) (.z B)))) (define-method (add {A <coords>} {B <coords>}) (new <coords> (fl+ (.x A) (.x B)) (fl+ (.y A) (.y B)) (fl+ (.z A) (.z B)))) (display (add '(1. 2. 3.) '(10. 20. 30.))) (newline) (display (add '#(1. 2. 3.) '#(10. 20. 30.))) (newline) (display (add (new <coords> 1. 2. 3.) (new <coords> 10. 20. 30.))) (newline) (flush-output-port (current-output-port)) #| end of program |# )
after compiling it we run it:
$ vicare --verbose --compile-program demo.sps --output demo vicare: expander warning: enabling typed language support for program vicare: serialising program demo ... vicare: done $ ./demo (11.0 22.0 33.0) #(11.0 22.0 33.0) #[record <coords> x=11.0 y=22.0 z=33.0]