From: John Thingstad
Subject: checking a function type
Date: 
Message-ID: <op.tj3vmccapqzri1@pandora.upc.no>
Given that I have a function

(defun prompt-integer (prompt error-msg test)
   (check-type prompt string)
   (check-type error-msg string)
   (check-type test function)

   (write-string prompt)
   (let ((guess (ignore-errors (parse-integer (read-line nil)))))
     (cond
      ((and (integerp guess) (funcall test guess)) guess)
      (t (write-line error-msg)
         (prompt-integer "> " error-msg test)))))

I would like to make the check-type for test more spesific
I know I can write something like (check-type day (integer 1 31)).
Can I check for a function of one argument or even of one integer argument?
Tried to check the hyperspec but I can't find anything on this.

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

From: Juho Snellman
Subject: Re: checking a function type
Date: 
Message-ID: <slrnenbt1k.61q.jsnell@sbz-30.cs.Helsinki.FI>
John Thingstad <··············@chello.no> wrote:
> Given that I have a function
>
> (defun prompt-integer (prompt error-msg test)
>    (check-type prompt string)
>    (check-type error-msg string)
>    (check-type test function)
>
>    (write-string prompt)
>    (let ((guess (ignore-errors (parse-integer (read-line nil)))))
>      (cond
>       ((and (integerp guess) (funcall test guess)) guess)
>       (t (write-line error-msg)
>          (prompt-integer "> " error-msg test)))))
>
> I would like to make the check-type for test more spesific
> I know I can write something like (check-type day (integer 1 31)).
> Can I check for a function of one argument or even of one integer argument?

No. While it is possible to express e.g. a function of one required
parameter in the CL type system by using the list-form of the FUNCTION
type specifier, it can't be used for runtime type checks. See CLHS on
TYPEP:

: An error of type error is signaled if type-specifier is values, or a
: type specifier list whose first element is either function or values.

-- 
Juho Snellman
From: John Thingstad
Subject: Re: checking a function type
Date: 
Message-ID: <op.tj35y2zppqzri1@pandora.upc.no>
On Tue, 05 Dec 2006 23:35:32 +0100, Juho Snellman <······@iki.fi> wrote:

> John Thingstad <··············@chello.no> wrote:
>> Given that I have a function
>>
>> (defun prompt-integer (prompt error-msg test)
>>    (check-type prompt string)
>>    (check-type error-msg string)
>>    (check-type test function)
>>
>>    (write-string prompt)
>>    (let ((guess (ignore-errors (parse-integer (read-line nil)))))
>>      (cond
>>       ((and (integerp guess) (funcall test guess)) guess)
>>       (t (write-line error-msg)
>>          (prompt-integer "> " error-msg test)))))
>>
>> I would like to make the check-type for test more spesific
>> I know I can write something like (check-type day (integer 1 31)).
>> Can I check for a function of one argument or even of one integer  
>> argument?
>
> No. While it is possible to express e.g. a function of one required
> parameter in the CL type system by using the list-form of the FUNCTION
> type specifier, it can't be used for runtime type checks. See CLHS on
> TYPEP:
>
> : An error of type error is signaled if type-specifier is values, or a
> : type specifier list whose first element is either function or values.
>

Yes.. Were I instead to write

(defun prompt-integer (prompt error-msg test)
   (declare (optimize (speed 0) (safety 3) (debug 3))
            (ftype (function (integer) t) test)
            (type string prompt error-msg))

   (write-string prompt)
   (let ((number (ignore-errors (parse-integer (read-line nil)))))
     (cond
      ((and (integerp number) (funcall test number)) number)
      (t (write-line error-msg)
         (prompt-integer "> " error-msg test)))))

then prompt and error-msg are checked for type but test which is declared  
of ftype
is not.. With check-type I can at least check that it is a function.
Why is this?

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Juho Snellman
Subject: Re: checking a function type
Date: 
Message-ID: <slrnencqu4.bb8.jsnell@sbz-30.cs.Helsinki.FI>
John Thingstad <··············@chello.no> wrote:
> (defun prompt-integer (prompt error-msg test)
>    (declare (optimize (speed 0) (safety 3) (debug 3))
>             (ftype (function (integer) t) test)
>             (type string prompt error-msg))
>
>    (write-string prompt)
>    (let ((number (ignore-errors (parse-integer (read-line nil)))))
>      (cond
>       ((and (integerp number) (funcall test number)) number)
>       (t (write-line error-msg)
>          (prompt-integer "> " error-msg test)))))
>
> then prompt and error-msg are checked for type but test which is declared  
> of ftype is not.. With check-type I can at least check that it is a
> function. Why is this?

I'm not completely sure of what you're asking.

If it's why the FTYPE declaration isn't doing anything, that's because
FTYPE is for specifying types of things in the function namespace, not
in the variable namespace. So that declaration applies to the global
function TEST (which you're not calling in PROMPT-INTEGER, and
probably haven't even defined), rather than to the variable TEST.

-- 
Juho Snellman
From: John Thingstad
Subject: Re: checking a function type
Date: 
Message-ID: <op.tj4s75bbpqzri1@pandora.upc.no>
On Wed, 06 Dec 2006 08:05:40 +0100, Juho Snellman <······@iki.fi> wrote:

> John Thingstad <··············@chello.no> wrote:
>> (defun prompt-integer (prompt error-msg test)
>>    (declare (optimize (speed 0) (safety 3) (debug 3))
>>             (ftype (function (integer) t) test)
>>             (type string prompt error-msg))
>>
>>    (write-string prompt)
>>    (let ((number (ignore-errors (parse-integer (read-line nil)))))
>>      (cond
>>       ((and (integerp number) (funcall test number)) number)
>>       (t (write-line error-msg)
>>          (prompt-integer "> " error-msg test)))))
>>
>> then prompt and error-msg are checked for type but test which is  
>> declared
>> of ftype is not.. With check-type I can at least check that it is a
>> function. Why is this?
>
> I'm not completely sure of what you're asking.
>
> If it's why the FTYPE declaration isn't doing anything, that's because
> FTYPE is for specifying types of things in the function namespace, not
> in the variable namespace. So that declaration applies to the global
> function TEST (which you're not calling in PROMPT-INTEGER, and
> probably haven't even defined), rather than to the variable TEST.
>

Ah, I see. And with TYPE I can't make the declaration.
Still because the type is checked with TYPEP.
However I still fail to see why this restriction exists.
I assume I am missing something..

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/