|
|
|
|
|
by dokyun
638 days ago
|
|
> you can't type cons-based lists/trees (arguably THE Lisp data structure) because deftype can't be recursive and you can't create parametric types (deftype list-of (type)
`(cons ,type (or null (list-of ,type))))
(typep '(1 2 3 4) '(list-of integer))
=> T
Most of the standard types from which derived types can be made are parametric types, which specialize on their arguments in different ways. They work the same way as macros. One upon a time I wrote a type specifier that allows you to specialize on a lambda expression, using the ordinary 'satisfies' type that only lets you provide named functions: (deftype satisfiesp (function)
(let (predicate)
(cond ((symbolp function)
(setq predicate function))
((functionp function)
(setq predicate (gensym))
(setf (symbol-function predicate) function))
((and (consp function) (eq (car function) 'lambda))
(setq predicate (gensym))
(compile predicate function))
(t (error "~S is neither a lambda expression, function or symbol." function)))
`(satisfies ,predicate)))
Now you can even type-check on lambda expressions, and quasiquotation can sidestep the issue of capturing variables. (defvar foo 'bar)
(typep 'bar `(satisfiesp (lambda (x) (eq x ',foo))))
=> T
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node44.html |
|
> Most of the standard types from which derived types can be made are parametric types
I meant "parametric with a type parameter", but yeah.
> satisfies
I was (obviously, I hope) talking about static, not runtime typing.