The Kawa Scheme Language

The Kawa Scheme Language

Quantities and Numbers

Kawa supports the full Scheme set of number operations with some extensions.

Kawa converts between Scheme number types and Java number types as appropriate.

Arithmetic operations

real-valued? obj

rational-valued? obj

integer-valued? obj

These numerical type predicates can be applied to any kind of argument. The real-valued? procedure returns #t if the object is a number object and is equal in the sense of = to some real number object, or if the object is a NaN, or a complex number object whose real part is a NaN and whose imaginary part is zero in the sense of zero?. The rational-valued? and integer-valued? procedures return #t if the object is a number object and is equal in the sense of = to some object of the named type, and otherwise they return #f.

(real-valued? +nan.0)                  ⇒ #t
(real-valued? +nan.0+0i)               ⇒ #t
(real-valued? -inf.0)                  ⇒ #t
(real-valued? 3)                       ⇒ #t
(real-valued? -2.5+0.0i)               ⇒ #t

(real-valued? -2.5+0i)                 ⇒ #t
(real-valued? -2.5)                    ⇒ #t
(real-valued? #e1e10)                  ⇒ #t

(rational-valued? +nan.0)              ⇒ #f
(rational-valued? -inf.0)              ⇒ #f
(rational-valued? 6/10)                ⇒ #t
(rational-valued? 6/10+0.0i)           ⇒ #t
(rational-valued? 6/10+0i)             ⇒ #t
(rational-valued? 6/3)                 ⇒ #t

(integer-valued? 3+0i)                 ⇒ #t
(integer-valued? 3+0.0i)               ⇒ #t
(integer-valued? 3.0)                  ⇒ #t
(integer-valued? 3.0+0.0i)             ⇒ #t
(integer-valued? 8/4)                  ⇒ #t

Note: These procedures test whether a given number object can be coerced to the specified type without loss of numerical accuracy. Specifically, the behavior of these predicates differs from the behavior of real?, rational?, and integer? on complex number objects whose imaginary part is inexact zero.

Note: The behavior of these type predicates on inexact number objects is unreliable, because any inaccuracy may affect the result.

exact-integer? z

Returns #t if z is both exact and an integer; otherwise returns #f.

(exact-integer? 32)                    ⇒ #t
(exact-integer? 32.0)                  ⇒ #t
(exact-integer? 32/5)                  ⇒ #f

finite? z

Returns #t if z is finite real number (i.e. an infinity and not a NaN), or if z is a complex number whose real and imaginary parts are both finite.

(finite? 3)             ⇒ #t
(finite? +inf.0)        ⇒ #f
(finite? 3.0+inf.0i)    ⇒ #f

infinite? z

Return #t if z is an infinite real number (+int.0 or -inf.0), or if z is a complex number where either real or imaginary parts or both are infinite.

(infinite? 5.0)         ⇒ #f
(infinite? +inf.0)      ⇒ #t
(infinite? +nan.0)      ⇒ #f
(infinite? 3.0+inf.0i)  ⇒ #t

nan? z

For a real numer returns whether its is a NaN; for a complex number if the real or imaginary parts or both is a NaN.

(nan? +nan.0)           ⇒ #t
(nan? 32)               ⇒ #f
(nan? +nan.0+5.0i)      ⇒ #t
(nan? 1+2i)             ⇒ #f

+ z

* z

These procedures return the sum or product of their arguments.

(+ 3 4)                          ⇒  7
(+ 3)                            ⇒  3
(+)                              ⇒  0
(+ +inf.0 +inf.0)                ⇒  +inf.0
(+ +inf.0 -inf.0)                ⇒  +nan.0

(* 4)                            ⇒  4
(*)                              ⇒  1
(* 5 +inf.0)                     ⇒  +inf.0
(* -5 +inf.0)                    ⇒  -inf.0
(* +inf.0 +inf.0)                ⇒  +inf.0
(* +inf.0 -inf.0)                ⇒  -inf.0
(* 0 +inf.0)                     ⇒  +nan.0
(* 0 +nan.0)                     ⇒  +nan.0
(* 1.0 0)                        ⇒  0.0

For any real number object x that is neither infinite nor NaN:

(+ +inf.0 x)                   ⇒  +inf.0
(+ -inf.0 x)                   ⇒  -inf.0

For any real number object x:

(+ +nan.0 x)                   ⇒  +nan.0

For any real number object x that is not an exact 0:

(* +nan.0 x)                   ⇒  +nan.0

The behavior of -0.0 is illustrated by the following examples:

(+  0.0 -0.0)  ⇒  0.0
(+ -0.0  0.0)  ⇒  0.0
(+  0.0  0.0)  ⇒  0.0
(+ -0.0 -0.0)  ⇒ -0.0

- z

- z_1 z_2 z_3

With two or more arguments, this procedures returns the difference of its arguments, associating to the left. With one argument, however, it returns the negation (additive inverse) of its argument.

(- 3 4)                               ⇒  -1
(- 3 4 5)                             ⇒  -6
(- 3)                                 ⇒  -3
(- +inf.0 +inf.0)                     ⇒  +nan.0

The behavior of -0.0 is illustrated by the following examples:

(-  0.0)       ⇒ -0.0
(- -0.0)       ⇒  0.0
(-  0.0 -0.0)  ⇒  0.0
(- -0.0  0.0)  ⇒ -0.0
(-  0.0  0.0)  ⇒  0.0
(- -0.0 -0.0)  ⇒  0.0

/ z

/ z_1 z_2 z_3

If all of the arguments are exact, then the divisors must all be nonzero. With two or more arguments, this procedure returns the quotient of its arguments, associating to the left. With one argument, however, it returns the multiplicative inverse of its argument.

(/ 3 4 5)                         ⇒  3/20
(/ 3)                             ⇒  1/3
(/ 0.0)                           ⇒  +inf.0
(/ 1.0 0)                         ⇒  +inf.0
(/ -1 0.0)                        ⇒  -inf.0
(/ +inf.0)                        ⇒  0.0
(/ 0 0)                           ⇒  exception &assertion
(/ 3 0)                           ⇒  exception &assertion
(/ 0 3.5)                         ⇒  0.0
(/ 0 0.0)                         ⇒  +nan.0
(/ 0.0 0)                         ⇒  +nan.0
(/ 0.0 0.0)                       ⇒  +nan.0

If this procedure is applied to mixed non–rational real and non–real complex arguments, it either raises an exception with condition type &implementation-restriction or returns an unspecified number object.

floor/ x y

truncate/ x y

div-and-mod x y

div0-and-mod0 x y

These procedures implement number–theoretic integer division. They accept two real numbers x and y as operands, where y must be nonzero. In all cases the result is two values q (an integer) and r (a real) that satisfy the equations:

x = q * y + r
q = rounding-op(x/y)

The result is inexact if either argument is inexact.

For floor/ the rounding-op is the floor function (below).

(floor/ 123 10)         ⇒  12 3
(floor/ 123 -10)        ⇒  -13 -7
(floor/ -123 10)        ⇒  -13 7
(floor/ -123 -10)       ⇒  12 -3

For truncate/ the rounding-op is the truncate function.

(truncate/ 123 10)      ⇒  12 3
(truncate/ 123 -10)     ⇒  -12 3
(truncate/ -123 10)     ⇒  -12 -3
(truncate/ -123 -10)    ⇒  12 -3

For div-and-mod the rounding-op is either floor (if y is positive) or ceiling (if y is negative). We have:

0  <= r < |y|
(div-and-mod 123 10)    ⇒  12 3
(div-and-mod 123 -10)   ⇒  -12 3
(div-and-mod -123 10)   ⇒  -13 7
(div-and-mod -123 -10)  ⇒  13 7

For div0-and-mod0 the rounding-op is the round function, and r lies within a half–open interval centered on zero.

-|y/2| <= r < |y/2|
(div0-and-mod0 123 10)   ⇒  12 3
(div0-and-mod0 123 -10)  ⇒  -12 3
(div0-and-mod0 -123 10)  ⇒  -12 -3
(div0-and-mod0 -123 -10) ⇒  12 -3
(div0-and-mod0 127 10)   ⇒  13 -3
(div0-and-mod0 127 -10)  ⇒  -13 -3
(div0-and-mod0 -127 10)  ⇒  -13 3
(div0-and-mod0 -127 -10) ⇒  13 3

The inconsistent naming is for historical reasons: div-and-mod and div0-and-mod0 are from R6RS, while floor/ and truncate/ are from R7RS.

floor-quotient x y

truncate-quotient x y

div x y

div0 x y

These procedures return the quotient part (first value) of respectively floor/, truncate/, div-and-mod, and div0-and-mod0.

floor-remainder x y

truncate-remainder x y

mod x y

mod0 x y

These procedures return the remainder part (second value) of respectively floor/, truncate/, div-and-mod, and div0-and-mod0.

As a Kawa extension y may be zero, in which case the result is x:

(mod 123 0)     ⇒  123 ;; Kawa extension

quotient x y

remainder x y

modulo x y

These are equivalent to truncate-quotient, truncate-remainder, and floor-remainder, respectively. These are provided for backward compatibility.

(remainder 13 4)     ⇒ 1
(remainder -13 4)    ⇒ -1
(remainder 13 -4)    ⇒ 1
(remainder -13 -4)   ⇒ -1
(remainder -13 -4.0) ⇒ -1.0
(modulo 13 4)   ⇒ 1
(modulo -13 4)  ⇒ 3
(modulo 13 -4)  ⇒ -4
(modulo -13 -4) ⇒ -1

abs x

Returns the absolute value of its argument.

(abs -7)                         ⇒  7
(abs -inf.0)                     ⇒  +inf.0

gcd n_1

lcm n_1

These procedures return the greatest common divisor or least common multiple of their arguments. The result is always non–negative. (R6RS allows inexact integer arguments; Kawa does not.)

(gcd 32 -36)                     ⇒  4
(gcd)                            ⇒  0
(lcm 32 -36)                     ⇒  288
(lcm 32.0 -36)                   ⇒  288.0
(lcm)                            ⇒  1

numerator q

denominator q

These procedures return the numerator or denominator of their argument; the result is computed as if the argument was represented as a fraction in lowest terms. The denominator is always positive. The denominator of 0 is defined to be 1. (R6RS allows inexact integer arguments; Kawa does not.)

(numerator   (/ 6 4))            ⇒  3
(denominator (/ 6 4))            ⇒  2

floor x

ceiling x

truncate x

round x

These procedures return inexact integer objects for inexact arguments that are not infinities or NaNs, and exact integer objects for exact rational arguments.

floor

Returns the largest integer object not larger than x.

ceiling

Returns the smallest integer object not smaller than x.

truncate

Returns the integer object closest to x whose absolute value is not larger than the absolute value of x.

round

Returns the closest integer object to x, rounding to even when x represents a number halfway between two integers.

If the argument to one of these procedures is inexact, then the result is also inexact. If an exact value is needed, the result should be passed to the exact procedure.

Although infinities and NaNs are not integer objects, these procedures return an infinity when given an infinity as an argument, and a NaN when given a NaN.

(floor -4.3)                     ⇒  -5.0
(ceiling -4.3)                   ⇒  -4.0
(truncate -4.3)                  ⇒  -4.0
(round -4.3)                     ⇒  -4.0

(floor 3.5)                      ⇒  3.0
(ceiling 3.5)                    ⇒  4.0
(truncate 3.5)                   ⇒  3.0
(round 3.5)                      ⇒  4.0

(round 7/2)                      ⇒  4
(round 7)                        ⇒  7

(floor +inf.0)                   ⇒  +inf.0
(ceiling -inf.0)                 ⇒  -inf.0
(round +nan.0)                   ⇒  +nan.0

rationalize x_1 x_2

The rationalize procedure returns a number object representing the simplest rational number differing from x_1 by no more than x_2.

A rational number r_1 is simpler than another rational number r_2 if r_1 = p_1/q_1 and r_2 = p_2/q_2 (in lowest terms) and |p_1| <= |p_2| and |q_1| <= |q_2|. Thus 3/5 is simpler than 4/7.

Although not all rationals are comparable in this ordering (consider 2/7 and 3/5) any interval contains a rational number that is simpler than every other rational number in that interval (the simpler 2/5 lies between 2/7 and 3/5).

Note that 0 = 0/1 is the simplest rational of all.

(rationalize (exact .3) 1/10)          ⇒ 1/3
(rationalize .3 1/10)                  ⇒ #i1/3  ; approximately

(rationalize +inf.0 3)                 ⇒  +inf.0
(rationalize +inf.0 +inf.0)            ⇒  +nan.0

The first two examples hold only in implementations whose inexact real number objects have sufficient precision.

exp z

log z

log z_1 z_2

sin z

cos z

tan z

asin z

acos z

atan z

atan x_1 x_2

These procedures compute the usual transcendental functions.

The exp procedure computes the base–e exponential of z. The log procedure with a single argument computes the natural logarithm of z (not the base–10 logarithm); (log z_1 z_2) computes the base–z_2 logarithm of z_1.

The asin, acos, and atan procedures compute arcsine, arccosine, and arctangent, respectively. The two–argument variant of atan computes:

(angle (make-rectangular x_2 x_1))

These procedures may return inexact results even when given exact arguments.

(exp +inf.0)    ⇒ +inf.0
(exp -inf.0)    ⇒ 0.0
(log +inf.0)    ⇒ +inf.0
(log 0.0)       ⇒ -inf.0
(log 0)         ⇒ exception &assertion
(log -inf.0)    ⇒ +inf.0+3.141592653589793i    ; approximately
(atan -inf.0)   ⇒ -1.5707963267948965          ; approximately
(atan +inf.0)   ⇒ 1.5707963267948965           ; approximately
(log -1.0+0.0i) ⇒ 0.0+3.141592653589793i       ; approximately
(log -1.0-0.0i) ⇒ 0.0-3.141592653589793i       ; approximately
                                                ; if -0.0 is distinguished

square z

Returns the square of z. This is equivalent to (* z z).

(square 42)    ⇒ 1764
(square 2.0)   ⇒ 4.0

sqrt z

Return the principal square root of z. For rational z, the result has either positive real part, or zero real part and non–negative imaginary part. The value of (sqrt z) could be expressed as:

e^((log z)/2)

The sqrt procedure may return an inexact result even when given an exact argument.

(sqrt -5)                   ⇒  0.0+2.23606797749979i ; approximately
(sqrt +inf.0)               ⇒  +inf.0
(sqrt -inf.0)               ⇒  +inf.0i

exact-integer-sqrt k

The exact-integer-sqrt procedure returns two non–negative exact integer objects s and r where k = s^2 + r and k < (s+1)^2.

(exact-integer-sqrt 4)  ⇒ 2 0 ; two return values
(exact-integer-sqrt 5)  ⇒ 2 1 ; two return values

Quantities and Units

As a super-class of numbers, Kawa also provides quantities. A quantity is a product of a unit and a pure number. The number part can be an arbitrary complex number. The unit is a product of integer powers of base units, such as meter or second.

Quantity literals have the following syntax:

quantity ::= optional-sign decimal unit-term [* unit-term]... [/ unit-term]
unit-term ::= unit-name [^ digit+]
unit-name ::= letter+

Some examples are 10pt (10 points), 5s (5 seconds), and 4cm^2 (4 square centimeters).

Note the quantity syntax is not recognized by the reader. Instead these are read as symbols. Assuming there is no lexical binding the for the symbol, it will be rewritten at compile-time into an expression. For example 4cm^2 is transformed into:

(* 4.0 (expt unit:cm 2))

quantity? object

True iff object is a quantity. Note that all numbers are quantities, but not the other way round. Currently, there are no quantities that re not numbers. To distinguish a plain unit-less number from a quantity, you can use complex?.

quantity->number q

Returns the pure number part of the quantity q, relative to primitive (base) units. If q is a number, returns q. If q is a unit, yields the magitude of q relative to base units.

quantity->unit q

Returns the unit of the quantity q. If q is a number, returns the empty unit.

make-quantity x unit

Returns the product of x (a pure number) and unit. You can specify a string instead of unit, such as "cm" or "s" (seconds).

define-base-unit unit-name dimension

Define unit-name as a base (primitive) unit, which is used to measure along the specified dimension.

(define-base-unit dollar "Money")

define-unit unit-name expression

Define unit-name as a unit (that can be used in literals) equal to the quantity expression.

(define-unit cent 0.01dollar)

The unit-name is declared in the unit namespace, so the above is equivalent to:

(define-constant unit:cent (* 0.01 unit:dollar))

Logical Number Operations

These functions operate on the 2's complement binary representation of an exact integer.

bitwise-not i

Returns the bit-wise logical inverse of the argument. More formally, returns the exact integer whose two's complement representation is the one's complement of the two's complement representation of i.

bitwise-and i ...

bitwise-ior i ...

bitwise-xor i ...

These procedures return the exact integer that is the bit-wise “and”, “inclusive or”, or “exclusive or” of the two's complement representations of their arguments. If they are passed only one argument, they return that argument. If they are passed no arguments, they return the integer that acts as identity for the operation: -1, 0, or 0, respectively.

bitwise-if i1 i2 i3

Returns the exact integer that is the bit-wise “if” of the twos complement representations of its arguments, i.e. for each bit, if it is 1 in i1, the corresponding bit in i2 becomes the value of the corresponding bit in the result, and if it is 0, the corresponding bit in i3 becomes the corresponding bit in the value of the result. This is equivaent to the following computation:

(bitwise-ior (bitwise-and i1 i2)
             (bitwise-and (bitwise-not i1) i3))

bitwise-bit-count i

If ei is non-negative, returns the number of 1 bits in the twos complement representation of i. Otherwise it returns the result of the following computation:

(bitwise-not (bitwise-bit-count (bitwise-not i)))

bitwise-length i

Returns the number of bits needed to represent i if it is positive, and the number of bits needed to represent (bitwise-not i) if it is negative, which is the exact integer that is the result of the following computation:

(do ((result 0 (+ result 1))
     (bits (if (negative? i)
               (bitwise-not i)
               ei)
           (bitwise-arithmetic-shift bits -1)))
    ((zero? bits)
     result))

This is the number of bits needed to represent i in an unsigned field.

bitwise-first-bit-set i

Returns the index of the least significant 1 bit in the twos complement representation of i. If ei is 0, then - 1 is returned.

(bitwise-first-bit-set 0) ⇒ -1
(bitwise-first-bit-set 1) ⇒ 0
(bitwise-first-bit-set -4) ⇒ 2

bitwise-bit-set? i1 i2

Returns #t if the i2'th bit (where i2 must be non-negative) is 1 in the two's complement representation of i1, and #f otherwise. This is the result of the following computation:

(not (zero?
       (bitwise-and
         (bitwise-arithmetic-shift-left 1 i2)
         i1)))

bitwise-copy-bit i bitno replacement-bit

Return the result of replacing the bitno'th bit of i by replacement-bit, where bitno must be non-negative, and replacement-bit must be either 0 or 1. This is the result of the following computation:

(let* ((mask (bitwise-arithmetic-shift-left 1 bitno)))
  (bitwise-if mask
            (bitwise-arithmetic-shift-left replacement-bit bitno)
            i))

bitwise-bit-field n start end

Return the integer formed from the (unsigned) bit-field starting at start and ending just before end. Same as:

(let ((mask
       (bitwise-not
        (bitwise-arithmetic-shift-left -1 end))))
  (bitwise-arithmetic-shift-right
    (bitwise-and n mask)
    start))

bitwise-copy-bit-field to start end from

Returns the result of replacing in to the bits at positions from start (inclusive) to end (exclusive) by the bits in from from position 0 (inclusive) to position end - start (exclusive). Both start and start must be non-negative, and start must be less than or equal to start.

This is the result of the following computation:

(let* ((mask1
         (bitwise-arithmetic-shift-left -1 start))
       (mask2
         (bitwise-not
           (bitwise-arithmetic-shift-left -1 end)))
       (mask (bitwise-and mask1 mask2)))
  (bitwise-if mask
              (bitwise-arithmetic-shift-left from
                                             start)
              to))

bitwise-arithmetic-shift i j

Shifts i by j. It is a “left” shift if j>0, and a “right” shift if j<0. The result is equal to (floor (* i (expt 2 j))).

Examples:

(bitwise-arithmetic-shift -6 -1) ⇒-3
(bitwise-arithmetic-shift -5 -1) ⇒ -3
(bitwise-arithmetic-shift -4 -1) ⇒ -2
(bitwise-arithmetic-shift -3 -1) ⇒ -2
(bitwise-arithmetic-shift -2 -1) ⇒ -1
(bitwise-arithmetic-shift -1 -1) ⇒ -1

bitwise-arithmetic-shift-left i amount

bitwise-arithmetic-shift-right i amount

The amount must be non-negative The bitwise-arithmetic-shift-left procedure returns the same result as bitwise-arithmetic-shift, and (bitwise-arithmetic-shift-right i amount) returns the same result as (bitwise-arithmetic-shift i (- amount));

bitwise-rotate-bit-field n start end count

Returns the result of cyclically permuting in n the bits at positions from start (inclusive) to end (exclusive) by count bits towards the more significant bits, start and end must be non-negative, and start must be less than or equal to end. This is the result of the following computation:

(let* ((n     ei1)
       (width (- end start)))
  (if (positive? width)
      (let* ((count (mod count width))
             (field0
               (bitwise-bit-field n start end))
             (field1 (bitwise-arithmetic-shift-left
                       field0 count))
             (field2 (bitwise-arithmetic-shift-right
                       field0
                       (- width count)))
             (field (bitwise-ior field1 field2)))
        (bitwise-copy-bit-field n start end field))
      n))

bitwise-reverse-bit-field i start end

Returns the result obtained from i by reversing the order of the bits at positions from start (inclusive) to end (exclusive), where start and end must be non-negative, and start must be less than or equal to end.

(bitwise-reverse-bit-field #b1010010 1 4) ⇒  88 ; #b1011000

logop op x y

Perform one of the 16 bitwise operations of x and y, depending on op.

logtest i j

Returns true if the arguments have any bits in common. Same as (not (zero? (bitwise-and i j))), but is more efficient.

SRFI-60 Logical Number Operations

Kawa supports SRFI-60 “Integers as Bits” as well, although we generally recommend using the R6RS-compatible functions instead when possible. Unless noted as being a builtin function, to use these you must first (require 'srfi-60) or (import (srfi :60)) (or (import (srfi :60 integer-bits))).

logand i ...

Equivalent to (bitwise-and i ...). Builtin.

logior i ...

Equivalent to (bitwise-ior i ...). Builtin.

logxor i ...

Equivalent to (bitwise-xor i ...). Builtin.

lognot i

Equivalent to (bitwise-not i). Builtin.

bitwise-merge mask i j

Equivalent to (bitwise-if mask i j).

any-bits-set? i j

Equivalent to (logtest i j).

logcount i

bit-count i

Count the number of 1-bits in i, if it is non-negative. If i is negative, count number of 0-bits. Same as (bitwise-bit-count i) if i is non-negative. Builtin as logcount.

integer-length i

Equivalent to (bitwise-length i). Builtin.

log2-binary-factors i

first-set-bit i

Equivalent to (bitwise-first-bit-set i).

logbit? pos i

bit-set? pos i

Equivalent to (bitwise-bit-set? i pos).

copy-bit bitno i bool

Equivalent to (bitwise-copy-bit i bitno (if bool 1 0)).

bit-field n start end

Equivalent to (bitwise-bit-field n start end).

copy-bit-field to from start end

Equivalent to (bitwise-copy-bit-field to start end from).

arithmetic-shift i j

Equivalent to (bitwise-arithmetic-shift i j). Builtin.

ash i j

Alias for arithmetic-shift. Builtin.

rotate-bit-field n count start end

Equivalent to (bitwise-rotate-bit-field n start end count).

reverse-bit-field i start end

Equivalent to (bitwise-reverse-bit-field i start end).

integer->list k [length]

list->integer list

The integer->list procedure returns a list of length booleans corresponding to the bits of the non-negative integer k, with #t for 1 and #f for 0. length defaults to (bitwise-length k). The list will be in order from MSB to LSB, with the value of (odd? k) in the last car.

The list->integer procedure returns the integer corresponding to the booleans in the list list. The integer->list and list->integer procedures are inverses so far as equal? is concerned.

booleans->integer bool1 ...

Returns the integer coded by the bool1 ... arguments. Equivalent to (list->integer (list bool1 ...)).

Deprecated Logical Number Operations

This older function is still available, but we recommend using the R6RS-compatible function.

bit-extract n start end

Equivalent to (bitwise-bit-field n start end).

Performance of numeric operations

Kawa can generally do a pretty good job of generating efficient code for numeric operations, at least when it knows or can figure out the types of the operands.

The basic operations +, -, and * are compiled to single-instruction bytecode if both operands are int or long. Likewise, if both operands are floating-point (or one is floating-point and the other is rational), then single-instruction double or float instructions are emitted.

A binary operation involing an infinite-precision integer and a fixed-size int or long is normally evaluated by expanding the latter to integer and using integer arithmetic. An exception is the integer argument is an integer literal whose value fits in a int or long - in that case the operation is done using int or long arithmetic.

In general, integer literals have amorphous type. When used to infer the type of a variable, they have integer type:

(let ((v1 0))
  ... v1 has type integer ... )

However, a literal whose value fits in the int or long range is implicitly viewed int or long in certain contexts, primarily method overload resolution and binary arithmethic (as mentioned above).

The comparison functions <, <=, =, >, and => are also optimized to single instriction operations if the operands have appropriate type. However, the functions zero?, positive?, and negative? have not yet been optimized. Instead of (positive? x) write (> x 0).

There are a number of integer division and modulo operations. If the operands are int or long, it is faster to use quotient and remainder rather than div and mod (or modulo). If you know the first operand is non-negative and the second is positive, then use quotient and remainder. (If an operand is an arbitrary-precision integer, then it dosn't really matter.)

The logical operations bitwise-and, bitwise-ior, bitwise-xor, bitwise-not, bitwise-arithmetic-shift-left, bitwise-arithmetic-shift-right are compiled to single bitcode instructions if the operands are int or long. Avoid bitwise-arithmetic-shift if the sign of the shift is known. If the operands are arbitrary-precision integer, a library call is needed, but run-time type dispatch is avoided.