menu
663 tokens

Primitives

Number, int32, uint32, int64, float32, character too.

Primitives

  • number, yes, but int32, uint32, int64, float32, character too

  • no real symbol use case left, so no symbol or unique symbol

  • string and bigint are just regular classes (String, BigInt)

  • variable sized integers

  • isize / usize

  • (sequence collections default to isize instead of number)

  • keep null and undefined, no strong reason not to

  • keep freshness and widening

  • keep literal freshness

  • const / as const

  • integer overflow / underflow traps in all build models

  • explicit wrapping / saturating / checked arithmetic

  • only upcasts are allowed via as

src/primitives.ds.ds
1const enabled: boolean = true;2const count: uint32 = 42;3const ratio: float64 = 0.75;4const initial: char = 'D';5const name: string = "Destack";

Conversions

Conversions follow the same explicitness rule as the rest of Destack: as between numeric types is allowed only when every value of the source type is representable in the destination (lossless), and lossy conversions must pick their behavior explicitly:

1declare const wide: int32;2 3const a: int64 = wide as int64;   // OK: lossless widening4const b: uint8 = wide as uint8;   // ERROR: lossy conversion5const c = wide.truncate<uint8>(); // explicit: keep the low bits6const d = wide.saturate<uint8>(); // explicit: clamp into range

Intervals

Ranges in type position become an interval type over bounded sets like int, bigint, or char; basically, an interval type is a static subset of its scalar type (e.g., 1..4 in type position is equivalent to 1 | 2 | 3). Assignments to interval-typed places must already have an interval-compatible type - the compiler does not prove arithmetic expressions stay inside intervals and we do not insert implicit runtime checks for interval assignments.

1type Digit = 0..=9;2type LowerAscii = 'a'..='z';3type UserPort = 1024..=65535;4 5let digit: Digit = 7;6let letter: LowerAscii = 'm';7let port: UserPort = 8080;8 9digit satisfies int;10letter satisfies char;11port satisfies int;

String

Destack wants to be "TypeScript++", and thus we also follow JavaScript's string behavior: string length and positional access are defined in terms of UTF-16 code units, and - just like TS's own string iterator - iteration yields Unicode code points (mapping to char).

1const text = "héllo";2 3text.length satisfies isize; // UTF-16 code units, as in JS4 5for (const c of text) {6    c satisfies char; // iteration by code point, as in JS7}

Destack is stricter than TS for string indexing: text[i] gives a char, and indexing into a lone surrogate traps. On native targets, string is the library's String with owned UTF-16 code units; on JS/TS targets, strings use the host engine's representation.