Numbers
Compared to other Lisps, GameLisp's numbers are relatively simple. A number may only be an int
(a 32bit signed integer) or a flo
(a 32bit IEEE float). Rational fractions, arbitraryprecision
integers and complex numbers are not supported.
The API for manipulating numbers is mostly unsurprising  the full list of functions is available here. Some minor points:

Bit manipulation is supported for integers.

We provide a simple random number generator.

There is a distinction between
sign
(which returns0
,1
or1
for any number) andfloâ€‘sign
(which returns the sign of a float as1.0
,1.0
ornan.0
).
(prn (sign 0.0)) ; prints 0
(prn (flosign 0.0)) ; prints 1.0
Promotion to Float
Floats are "contagious". When a function such as +
receives both an integer and a
float among its arguments, the integer is promoted to a float before performing the operation, so
the return value is always a float.
(prn (+ 1 2 3 4)) ; prints 10
(prn (+ 1 2 3.0 4)) ; prints 10.0
(prn (/ 7 2)) ; prints 3
(prn (/ 7 2.0)) ; prints 3.5
(prn (% 5 1.5)) ; prints 0.5
Operations like min
and clamp
are the exception to the rule, because they return one of
their arguments unchanged.
(prn (max 1 2 3.0 4)) ; prints 4
(prn (clamp 1.0 3 5.0)) ; prints 3
Wrapping Arithmetic
Integer arithmetic is always unchecked (wrapping), even when your crate is compiled in debug mode.
(prn (+ 1 2147483647)) ; prints 2147483648
This helps to keep the language simple. If GameLisp were to take Rust's approach to integer overflow, it would need to provide distinct APIs for normal, wrapping and checked arithmetic. In Rust, this adds a large complexity burden when working with integers.
Out of those three options, wrapping arithmetic was chosen over checked arithmetic in order to make fatal errors less likely. In game development, overflowing an entity's coordinates and getting a nonsensical value will usually be a minor bug, but overflowing an entity's coordinates and crashing the game's executable would be catastrophic.