how to specify type for a constant?

Viewed 111

I have a bunch of constants, which I want to be of type (unsigned-byte 8).

(declaim (type '(unsigned-byte 8) +c0+ +c1+))
(defconstant +c0+ #x0)
(defconstant +c1+ #x10)

But the declaim does not seem to do the trick, given when I type (type-of +c0+) it returns BIT (or integer, depending on the value), which is clearly not what I want.

So, how can I specify the type for constants?

Update As it turns out, the question - while still a question - was not the root cause for my problems. In the (make-array '(2) ... part which caused the errors about "incompatible types", I entered for the initial-contents a quoted list where I should have put a "listed" list. WRONG: '(+c0+ +c1+), RIGHT: (list +c0+ +c1+).

Given I still associate variables instead of values with types in my mind, I could not interpret the meaning of the error messages coming from this.

So, basically I would delete the question if the system let me.

2 Answers

Types in Common Lisp are really just sets of values. Any value can be of an infinite number of types.

For example, the number 1 is of the type bit (which is an alias for (integer 0 1)). It is also of type (integer 0 2), or (integer -47 234). It is even of the type (or string null (integer 0 277)). So, when you ask (type-of 1), what should be the answer?

Lisp implementations know about some types that are built in. They will usually return the most restricted of those types that they know contains the value. If your Lisp implementation had special handling of numbers in base 5, it might return (integer 0 5) (or an alias of that) for 2.

So that's why the CLHS says that it returns a type specifier, not the type. It also specifies that it has to return something sensible (take a look there).

Your declamation is about the constant named +c0+, but the type-of call doesn't see that constant, it sees only the value coming out of it (think about the evaluation steps). So that declamation cannot have an effect here.

If you want to restrict the type of a value on the fly, you could use the or check-type.

(type-of +c0+) does not return a declared type of the variable or constant. It returns the dynamic type of the object which is the value of +c0+.

With your type declaration you declared the type of a constant identifier. Actually the effects of that is implementation specific. SBCL will use that type declaration.

But you need to understand the difference between static type declarations using DECLAIM, DECLARE, etc and dynamic types like the types used in TYPE-OF, TYPE-P, the element type option of MAKE-ARRAY, ...

Related