Google 網路論壇不再支援新的 Usenet 貼文或訂閱項目,但過往內容仍可供查看。

the `the' thingy

瀏覽次數:8 次
跳到第一則未讀訊息

David Bakhash

未讀,
1998年5月20日 凌晨3:00:001998/5/20
收件者:

hey,

I'm a bit puzzled about declarations. I understand how to declare the
types of bound variables, e.g.:

(defun f (x)
(declare (type integer x))
(* x x))

But how do I just declare the return type of `f' to be of type
integer? I guess I can do something like:

(defun f (x)
(declare (type integer x))
(the integer (* x x)))

But I was looking for a much nicer solution (i.e. one that could go in
the declaration line).

thanks,

dave

Barry Margolin

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

In article <cxjpvh8...@hawk.bu.edu>, David Bakhash <ca...@bu.edu> wrote:
>But how do I just declare the return type of `f' to be of type
>integer? I guess I can do something like:
>
>(defun f (x)
> (declare (type integer x))
> (the integer (* x x)))
>
>But I was looking for a much nicer solution (i.e. one that could go in
>the declaration line).

You can't do it in the declaration line, you have to do it in a declaration
external to the function:

(declaim (ftype (function (integer) integer)
f))

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.

Erik Naggum

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

* David Bakhash

| But how do I just declare the return type of `f' to be of type integer?

the declaration (ftype (function (integer) integer) f) would declare the
type of the functional value of the symbol F (as opposed to the "normal"
value you would declare with TYPE) to be a FUNCTION that takes and yields
an INTEGER. it is most useful as a top-level "declaration":

(declaim (ftype (function (integer) integer) f))

the compiler is now free to assume a one-argument, one-valued function
whenever F is invoked as a function, but it probably won't do it much
good to know it takes and yields INTEGER objects, since the major savings
are in not having to cons bignums.

I have not seen much actual effect of these declarations on the compiled
code, but they can often help document a system.

#:Erik
--
"Where do you want to go to jail today?"
-- U.S. Department of Justice Windows 98 slogan

Marco Antoniotti

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

Barry Margolin <bar...@bbnplanet.com> writes:

> In article <cxjpvh8...@hawk.bu.edu>, David Bakhash <ca...@bu.edu> wrote:

> You can't do it in the declaration line, you have to do it in a declaration
> external to the function:
>

> (declaim (ftype (function (integer) integer)
> f))
>

How about using the '(values <typespec>*)' declaration?

In CMUCL I get

* (defun f (x)
(declare (type (mod 10) x)
(values fixnum))
(+ x x 2))
F
* (compile 'f)
F
NIL
NIL
* (f 4)
10
* (f 3)
8
* (type-of #'f)
(FUNCTION ((MOD 10)) (INTEGER 2 20))

Which is quite a type inference. However

* (defun m (x)
(declare (type (mod 10) x)
(values (integer 2 17)))
(+ x x 2))
M
* (compile 'm)
M
NIL
NIL
* (type-of #'m)
(FUNCTION ((MOD 10)) (INTEGER 2 17))
* (m 9)
Invoking debugger...
Starting server:

>> Error: 20 is not of type (INTEGER 2 17)

Leaving debugger.
*

--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 80 79 23, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it

Erik Naggum

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

* Marco Antoniotti

| How about using the '(values <typespec>*)' declaration?

although that is quite elegant, it is unfortunately not ANSI Common Lisp:

This type specifier [values] can be used only as the value-type in a
FUNCTION type specifier or a THE special form. It is used to specify
individual types when multiple values are involved.

I think the usage that CMUCL made of this type specifier and declaration
should be actively considered for the review of ANSI Common Lisp.

Rainer Joswig

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

In article <31047282...@naggum.no>, Erik Naggum <c...@naggum.no> wrote:

> * David Bakhash
> | But how do I just declare the return type of `f' to be of type integer?
>
> the declaration (ftype (function (integer) integer) f) would declare the
> type of the functional value of the symbol F (as opposed to the "normal"
> value you would declare with TYPE) to be a FUNCTION that takes and yields
> an INTEGER. it is most useful as a top-level "declaration":
>

> (declaim (ftype (function (integer) integer) f))
>

> the compiler is now free to assume a one-argument, one-valued function
> whenever F is invoked as a function, but it probably won't do it much
> good to know it takes and yields INTEGER objects, since the major savings
> are in not having to cons bignums.
>
> I have not seen much actual effect of these declarations on the compiled
> code, but they can often help document a system.

Actually I would like to see compiler warnings/erros when such
type declarations are violated in the code like
in (f (make-array 'foo)).

--
http://www.lavielle.com/~joswig/


Raymond Toy

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

Erik Naggum <c...@naggum.no> writes:

>
> (declaim (ftype (function (integer) integer) f))
>
> the compiler is now free to assume a one-argument, one-valued function
> whenever F is invoked as a function, but it probably won't do it much
> good to know it takes and yields INTEGER objects, since the major savings
> are in not having to cons bignums.
>
> I have not seen much actual effect of these declarations on the compiled
> code, but they can often help document a system.
>

With CMUCL, such declarations can be put to very good effect. If the
return type were single-float, then CMUCL can put that knowledge to
good use whenever f is called. I believe knowing the parameter types
also helps, but not nearly as much.

Correct documentation is always good, but, with CMUCL, I avoid using
such declarations because the compiler is often smart enough to
determine the return type itself; you just need to declare the
argument types. You have to be careful not to lie to the compiler.

Ray

Barry Margolin

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

In article <joswig-2105...@194.163.195.66>,

Rainer Joswig <jos...@lavielle.com> wrote:
>Actually I would like to see compiler warnings/erros when such
>type declarations are violated in the code like
>in (f (make-array 'foo)).

A good implementation should do so. I wouldn't be surprised if CMUCL does,
since it does lots of optimization and type-inferencing based on
declarations.

Rainer Joswig

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

In article <1S_81.83$152.8...@cam-news-reader1.bbnplanet.com>, Barry
Margolin <bar...@bbnplanet.com> wrote:

> In article <joswig-2105...@194.163.195.66>,
> Rainer Joswig <jos...@lavielle.com> wrote:
> >Actually I would like to see compiler warnings/erros when such
> >type declarations are violated in the code like
> >in (f (make-array 'foo)).
>
> A good implementation should do so. I wouldn't be surprised if CMUCL does,
> since it does lots of optimization and type-inferencing based on
> declarations.

I guess there aren't that many "good" implementations. Any reasons
for this?

--
http://www.lavielle.com/~joswig/


David Bakhash

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

Erik Naggum <c...@naggum.no> writes:

> (declaim (ftype (function (integer) integer) f))
>
> the compiler is now free to assume a one-argument, one-valued function
> whenever F is invoked as a function, but it probably won't do it much
> good to know it takes and yields INTEGER objects, since the major savings
> are in not having to cons bignums.

Now I'm utterly confused between all the different ways of doing the
same thing in CL. Since every function returns its last form,
wouldn't it be sufficient, in general, to wrap the last form in a
`the' statement:

(defun some-big-calculation (x y z)
(do-this x)
(then-this-on y)
(the bignum (+ x y z)))

???

Also, the declaim thing above seems to require that you know the
arglist too. i.e. I asked for a way to specify the RETURN type with a
declaration, and now it seems as though, with the declaim above, you
need to also specify the function args as well. In addition, this is
redundant, if you've already put that stuff in as `declare' statements
in the function itself:

(defun f (x)
(declare (type integer x))
(...))

So, between `the', and then the `declaim', and the `declare', I'm
thoroughly confounded.

dave

Marco Antoniotti

未讀,
1998年5月21日 凌晨3:00:001998/5/21
收件者:

Erik Naggum <c...@naggum.no> writes:

> * Marco Antoniotti
> | How about using the '(values <typespec>*)' declaration?
>
> although that is quite elegant, it is unfortunately not ANSI Common Lisp:
>
> This type specifier [values] can be used only as the value-type in a
> FUNCTION type specifier or a THE special form. It is used to specify
> individual types when multiple values are involved.
>
> I think the usage that CMUCL made of this type specifier and declaration
> should be actively considered for the review of ANSI Common Lisp.
>

Yep! I reviewed the HyperSpec and was quite disappointed.

Of course a "simple" solution would be to convince Franz and Harlequin
(and Bruno Haible :) ) to implement this extension to ANSI.

Since we are at it, we could also implement something like

(declaim (declaration signals))

(defun sometimes-I-err (x)
(declare (type integer x)
(values real)
(signals division-by-zero))
(if (zerop x)
(error 'division-by-zero)
(/ 1 x)))


Ain't Java Lispish? :)

Barry Margolin

未讀,
1998年5月22日 凌晨3:00:001998/5/22
收件者:

In article <joswig-2105...@194.163.195.66>,
Rainer Joswig <jos...@lavielle.com> wrote:
>In article <1S_81.83$152.8...@cam-news-reader1.bbnplanet.com>, Barry
>Margolin <bar...@bbnplanet.com> wrote:
>
>> In article <joswig-2105...@194.163.195.66>,
>> Rainer Joswig <jos...@lavielle.com> wrote:
>> >Actually I would like to see compiler warnings/erros when such
>> >type declarations are violated in the code like
>> >in (f (make-array 'foo)).
>>
>> A good implementation should do so. I wouldn't be surprised if CMUCL does,
>> since it does lots of optimization and type-inferencing based on
>> declarations.
>
>I guess there aren't that many "good" implementations. Any reasons
>for this?

Because the tradition in Common Lisp has been to use declarations primarily
for optimization, and most implementations don't do heavy optimization.
They'll optimize simple integer and floating point expressions, and
recognize those declarations. Type checking has generally been relegated
to runtime, with facilities like CHECK-TYPE.

Barry Margolin

未讀,
1998年5月22日 凌晨3:00:001998/5/22
收件者:

In article <cxjg1i3...@hawk.bu.edu>, David Bakhash <ca...@bu.edu> wrote:
>Also, the declaim thing above seems to require that you know the
>arglist too. i.e. I asked for a way to specify the RETURN type with a

Why wouldn't you know the arglist of a function you're using?

>declaration, and now it seems as though, with the declaim above, you
>need to also specify the function args as well. In addition, this is
>redundant, if you've already put that stuff in as `declare' statements
>in the function itself:
>
>(defun f (x)
> (declare (type integer x))
> (...))

Sometimes external declarations can be useful to specify local behavior.
E.g.

(locally (declare (ftype (function (fixnum) fixnum) f))
...)

indicates that within this form you promise only to pass fixnums to F, and
expect that it will always return a FIXNUM. Conceivably, if F looks like:

(declaim (inline f))


(defun f (x)
(declare (type integer x))

(if (typep x 'fixnum)
(f-fixnum x)
(f-general x)))

then any forms inside that scope that look like (f z) can be transformed
directly into (f-fixnum z).

I don't know if any existing compilers can do this (I'm sure someone will
chime in if they know of one), but the design of the CL declaration
mechanism was intended to support it. Also, designers of type inferencing
systems will probably say that the local declaration is unnecessary, as
their systems can usually determine that Z is must be a fixnum all by
themselves.

>So, between `the', and then the `declaim', and the `declare', I'm
>thoroughly confounded.

Common Lisp frequently provides multiple ways to say the same thing. There
are at least 3 simple ways to iterate over a list (MAPC, DOLIST, and LOOP).

Raymond Toy

未讀,
1998年5月22日 凌晨3:00:001998/5/22
收件者:

Barry Margolin <bar...@bbnplanet.com> writes:

> indicates that within this form you promise only to pass fixnums to F, and
> expect that it will always return a FIXNUM. Conceivably, if F looks like:
>
> (declaim (inline f))
> (defun f (x)
> (declare (type integer x))
> (if (typep x 'fixnum)
> (f-fixnum x)
> (f-general x)))
>
> then any forms inside that scope that look like (f z) can be transformed
> directly into (f-fixnum z).
>
> I don't know if any existing compilers can do this (I'm sure someone will
> chime in if they know of one), but the design of the CL declaration

With the definition of f above, CMUCL will transform (f z) into
(f-fixnum z) if CMUCL can prove that z really is a fixnum.

I'm not sure what CMUCL will do with the locally form you mentioned.

Ray

0 則新訊息