#TITLE#
#IC_REALNAME#
This CLRFI extends the SATISFIES Type Specifier to accept functions (including lambda expressions) in addition to symbols as argument.
It does not conflict with, relate to or replace any CLRFIs.
This CLRFI proposes as an extension to the specification of the Type Specifier SATISFIES, to allow functions and lambda expressions too as predicate.
The current practice is to allow only a predicate name, a symbol denoting a function. This complicates the interaction between DEFTYPE and SATISFIES; users need to write:
(defpackage "$$RESTRICTED-LIST-PREDICATES$$" (:USE)) (defun find-restricted-list-predicate (element-type) (let* ((name (with-standard-io-syntax (format nil "~S-P" element-type))) (predicate (FIND-SYMBOL name "$$RESTRICTED-LIST-PREDICATES$$"))) (unless predicate (setf predicate (intern name "$$RESTRICTED-LIST-PREDICATES$$")) (eval `(defun ,predicate (list) (every (lambda (item) (typep item ',element-type)) list)))) predicate)) (deftype restricted-list (element-type) `(and (satisfies proper-list-p) (satisfies ,(find-restricted-list-predicate element-type))))
instead of merely:
(deftype restricted-list (element-type) `(and (satisfies proper-list-p) (satisfies ,(lambda (list) (every (lambda (item) (typep item ',element-type)) list)))))
The cost would be:
(handler-case (typep .. '(satisfies (lambda (x) ...))) (error (err) ...))or:
(handler-case (typep .. '(satisfies #.(function ...))) (error (err) ...))would not work as expected anymore.
The interaction between DEFTYPE (which defines actually famillies of types) and SATISFIES is harder for the users.
Type Specifier SATISFIES
<Compound Type Specifier Kind:
Predicating.
Compound Type Specifier Syntax:
satisfies predicate
Compound Type Specifier Arguments:
predicate --- a function designator, or a lambda expression.
Compound Type Specifier Description:
This denotes the set of all objects that satisfy the predicate predicate, which must be either a symbol whose global function definition is a one-argument predicate, a one-argument predicate function, or a one-argument predicate lambda expression.
For example, the type specifier
(and integer (satisfies (lambda (x) (zerop (mod x 3)))))
denotes the
set of all integers multiple of 3.
The form (typep x '(satisfies p))
is equivalent to (if (p x) t nil)
.
The argument is required. The symbol * can be the argument, but it denotes itself (the symbol *), and does not represent an unspecified value.
NONE YET.
None.
Copyright (C) Pascal Bourguignon (2005). All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Common Lisp Request For Improvements process or editors, except as needed for the purpose of developing CLRFIs in which case the procedures for copyrights defined in the CLRFI process must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the authors or their successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and THE AUTHORS AND THE CLRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.