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]