How to declare the type of a loop variable
Asked Answered
C

2

5

I want to do some integer arithmetic and was checking if SBCL could gain more speed if I provide explicit information about the type of values I use. While I easily could use declare in a defun or let directly to do so, I do not understand where to put the statement within a loop construct.

I came across the documentation of the iterate package which offers such possibilities but wanted to stick to loop for the moment.

A stub example could look like this:

(loop :for i from 1 upto 100 :collect
  (loop :for j from i upto 100
    :collect (* i j)))

How can I tell Lisp that i and j are e.g. of type fixnum?

Constable answered 21/3, 2017 at 21:1 Comment(0)
D
10

For simple types like fixnum, float, t and nil you can just write the type after the variable in the FOR clause. You can also add a type in a numeric-accumulation clause like a sum clause:

(loop for i fixnum below 10
      for j fixnum from 1 
      sum (* i j) fixnum)
Dibbrun answered 22/3, 2017 at 6:58 Comment(4)
Omitting of-type makes code concise, but, IMO, less readable.Latinist
@sds: I use that all the time. Since only FIXNUM and FLOAT make some sense for the short notation, I don't see any readability problem. The OF-TYPE notation is relatively rare in code I've seen.Dibbrun
I bow to you experience :-)Latinist
@sds: just looking at some applications, for fixnum declarations, with of-type is used a lot, but definitely less than declarations without of-type.Dibbrun
L
6

Use of-type:

(loop :for i of-type fixnum from 1 upto 100 :collect
  (loop :for j of-type fixnum from i upto 100
    :collect (* i j)))

Also, Examples of WITH clause are nice.

Like Rainer said, you can omit of-type for simple types, e.g., fixnum and float, but that violates the "rhythm" of loop whereby loop keywords alternate with user forms.

Note also that declaring i and j to be fixnums is not enough to ensure fixnum multiplication (the square of most-positive-fixnum is certainly not a fixnum). Thus to get the fastest possible multiplication you would need to declare i and j to be (unsigned-byte 1000) which does require of-type.

Of course, all this should not be necessary. The compiler should be smart enough. :-)

Latinist answered 21/3, 2017 at 21:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.