Type of predicates by type

I want to improve the quality and quantity of compiler warnings that I get - is there a way in Common Lisp to include type predicates over declared types, as well as over instances - the concrete answers are all right, I am interested to see how this is done if someone does this will do.

Compilation in CCL as follows:

(defun non-list (o) (not (listp o))) (deftype non-list () '(satisfies non-list)) (defun example (a) (list a)) (declaim (ftype (function (non-list) list) example)) (defun hmm () (declare (optimize (debug 3) (safety 3))) (let ((a '(abc)) (b '(def))) (declare (type list a)) (example '(ghi)) (example a) (example b))) 

I will get a warning about the compiler when I first call example - one that provides an instance of which can be checked with satisfies . This is good, and with the debug settings I get a runtime error which is good. I am wondering if I can write something like the following:

 (defun non-list-typep (type) (not (subtypep type 'list))) 

and somehow integrate it so that at least the second call - (example a) gives a warning at compile time, because its declared list type crashes the non-list-typep

Hooray!

+2
source share
2 answers

A bit of background :

There are two different things: the standard Common Lisp language and the widespread languages ​​that implement and extend Common Lisp.

General Lisp as a language does not require warnings / errors of the type similar at compile time. An implementation can basically ignore type declarations. The language also does not actually describe what should be done when the compiler does not ignore type declarations and how it should use them for static type checking.

Actual general Lisp compilers fall into the following groups when it comes to statically declared types:

  • ignore them mostly. For example, the Symbolics Lisp Machine compiler falls into this group.

  • uses declared types mainly for optimization purposes. I would say that CCL falls into this group. I do not think that he does many types of inference or dissemination of type information. I would suggest that also the reason the compiler is faster than SBCL is because it does less.

  • uses declared types mainly for optimization purposes, but can draw type inference and can provide type information (for optimization). For example, LispWorks falls into this group.

  • uses declared types for optimization purposes, draws type inference, can provide type information and considers type declarations as statements of type at compile time. The CMUCL and SBCL compilers are the main members of this group.

So, for an implementation of type 2. you are best off declaring everything if you want the compiler to recognize it. Note that Common Lisp provides THE and LOCALLY for recording declarations.

If you want to have type declarations as statements of a static type and check their compiler, it is better to use a compiler like SBCL .

Some information on his approach to type declarations can be found in the SBCL manual: Type Handling and Enter Errors at Compile Time . Read more here: Python compiler for CMU Common Lisp . Note that the CMU Common Lisp compiler (and later SBCL) is called Python - it has nothing to do with the Python programming language. The compiler already had its own name (early 1980s) before the Python language (1991) existed.

+6
source

Another way is to implement a type checking language on top of Common Lisp, such as Qi . I think it started with a couple of smart macros around defun to solve the problem you are facing.

+1
source

Source: https://habr.com/ru/post/951278/


All Articles