Context
No module in the standard library names a numeric limit. None of the 10 integer modules and
none of the 2 float modules declares MAX, MIN, EPSILON, BITS, PI, or INFINITY.
The compiler knows every one of these bounds, because the checked intrinsics test against
them. Silk source cannot name them.
Current behavior
A user who wants the largest i32 value must write the literal 2147483647 in the source.
A user who wants the smallest value must write -2147483648. Each literal is a place where
the user can make a mistake, and no reader can confirm the value without a calculation.
The float case is worse. A user cannot write an infinity literal at all, so a user must
reach for f64.fromBits and a hexadecimal bit pattern (f64.silk:102). A user cannot write
an epsilon value without the same trick.
Typed const already ships, so these declarations are expressible today. This ticket adds
declarations only.
Requirements
- Each integer module must declare
MAX and MIN with the type of that module.
- Each integer module must declare
BITS as a u32 value.
- Each float module must declare
MAX, MIN, EPSILON, INFINITY, and NAN.
- Each float module must declare
PI and E.
- Each constant must have an explicit type, so no constant may depend on literal defaults.
- The value of
MAX must equal the largest value that the checked intrinsics accept.
- The
usize and isize constants must match the pointer width of the target.
- The change must add no intrinsic and no compiler phase.
Example
// In i32.silk
pub const MAX: i32 = 2147483647
pub const MIN: i32 = -2147483648
pub const BITS: u32 = 32
// In f64.silk
pub const EPSILON: f64 = 0.0000000000000002220446049250313
pub const PI: f64 = 3.141592653589793
pub fn wouldOverflow(value: i32) -> bool {
return value > i32.MAX - 1
}
Out of scope
- A computed constant expression. The compiler rejects
const computed: i32 = 40 + 2
with SEM0086, and a test pins that behavior
(packages/compiler/test/TypedConstants.test.ts:108). Each constant must be one literal.
- A generic bound that gives
MAX for any integer type. That needs the bound form change
from ticket 30.
- A change to the checked arithmetic intrinsics.
- A conversion between a number and text. See ticket 36.
- The float math functions. See ticket 37.
Dependencies
- A decision on
usize and isize. These two types depend on the target pointer width, so
their constants cannot be one fixed literal for every target.
Acceptance criteria
Implementation note
A constant initializer must be one literal. Therefore each float constant must be written as
a decimal literal, and no constant may be written as an arithmetic expression over another
constant. An expression over a constant is legal inside a function body, so
i32.MAX - 1 compiles there. The restriction applies to the declaration only.
Context
No module in the standard library names a numeric limit. None of the 10 integer modules and
none of the 2 float modules declares
MAX,MIN,EPSILON,BITS,PI, orINFINITY.The compiler knows every one of these bounds, because the
checkedintrinsics test againstthem. Silk source cannot name them.
Current behavior
A user who wants the largest
i32value must write the literal2147483647in the source.A user who wants the smallest value must write
-2147483648. Each literal is a place wherethe user can make a mistake, and no reader can confirm the value without a calculation.
The float case is worse. A user cannot write an infinity literal at all, so a user must
reach for
f64.fromBitsand a hexadecimal bit pattern (f64.silk:102). A user cannot writean epsilon value without the same trick.
Typed
constalready ships, so these declarations are expressible today. This ticket addsdeclarations only.
Requirements
MAXandMINwith the type of that module.BITSas au32value.MAX,MIN,EPSILON,INFINITY, andNAN.PIandE.MAXmust equal the largest value that the checked intrinsics accept.usizeandisizeconstants must match the pointer width of the target.Example
Out of scope
const computed: i32 = 40 + 2with
SEM0086, and a test pins that behavior(
packages/compiler/test/TypedConstants.test.ts:108). Each constant must be one literal.MAXfor any integer type. That needs the bound form changefrom ticket 30.
Dependencies
usizeandisize. These two types depend on the target pointer width, sotheir constants cannot be one fixed literal for every target.
Acceptance criteria
i32.MAX + 1traps in the checked arithmetic path.MAXagainst the bound in the checked intrinsic.f64.INFINITYhas the same bits as the infinity bit pattern.f64.NANis not equal to itself.native LLVM backend.
usizeconstants match the target pointer width.SEM0086.Implementation note
A constant initializer must be one literal. Therefore each float constant must be written as
a decimal literal, and no constant may be written as an arithmetic expression over another
constant. An expression over a constant is legal inside a function body, so
i32.MAX - 1compiles there. The restriction applies to the declaration only.