Documentation / Numbers

Numbers

Moth uses Int for signed whole numbers and Float for finite real-number values. It avoids the large family of integer widths and implicit numeric conversions found in many systems languages.

Arithmetic checks overflow, division errors and non-finite results. Literal spelling and operator spacing also follow one exact grammar on every backend.

Choose the explanation level: Numeric types

Numeric types

Moth uses Int for whole numbers and Float for decimal numbers.

lives Int = 3
progress Float = 0.75

An Int can be used where a Float is expected:

lives Int = 3
display_value Float = lives

A Float never silently becomes an Int. That conversion can lose information, so it needs an explicit cast.

Moth has two core numeric types.

Int

Int is a signed 32-bit integer.

Its range is:

-2147483648 through 2147483647

Float

Float is a finite f64.

NaN, positive infinity and negative infinity are not valid Moth Float values. Boundaries that can introduce a non-finite result must reject it.

Promotion

Int may promote to Float at a contextual numeric boundary.

count Int = 3
ratio Float = count

Mixed Int and Float arithmetic produces Float.

There is no implicit Float -> Int conversion. Use a fallible explicit cast at an Int target.

Bool and Char are not numeric types.

Choose the explanation level: Numeric literals

Numeric literals

Whole numbers are Int values:

score = 42

Numbers with a decimal point are Float values:

progress = 0.5

Large and tiny values can use lowercase e notation:

population = 1e6
tolerance = 1e-6

Keep a minus sign attached to the value:

temperature = -5
opposite = -count

1E6, +1 and - count are not valid numeric forms.

The source spelling of a number determines its natural type.

whole = 42
decimal = 0.5
large = 1e6
small = 1e-6
precise = 1.0e+21

Contract

  • A whole-number literal is naturally Int.
  • A decimal-point literal is naturally Float.
  • Exponents use lowercase e.
  • Uppercase E is rejected.
  • Unary + is rejected.
  • A leading - must be attached to the literal or expression it negates.
  • -1, -1e6 and -count are valid prefix forms.
  • - count is invalid.
  • Integer literals must fit the Int range.
  • Float literals must materialise to a finite Float.
valid_literal = -42
valid_expression = -count

invalid_exponent = 1E6
invalid_plus = +1
invalid_spacing = - count

The invalid lines above demonstrate rejected syntax. They are not valid program forms.

Choose the explanation level: Operators

Operators

Put spaces around symbolic operators.

total = left + right
count += 1

Moth uses words for equality and logic:

same = left is right
different = left is not right
ready = loaded and valid
retry = timed_out or disconnected
blocked = not ready

Division has two forms:

real_result = 5 / 2
whole_result = 5 // 2

/ produces a real Float result. // performs integer division and produces an Int.

Use templates to join text:

greeting = ["Hello, ", "Priya"]

Templates handle all string joining and interpolation. + is for numbers only.

Moth keeps equality and logical operators readable.

same = left is right
different = left is not right
ready = has_input and is_valid
should_retry = timed_out or disconnected
blocked = not ready
  • and and or require Bool operands.
  • not requires one Bool operand.
  • Symbolic equality and symbolic logical-not forms are not language operators.

Arithmetic results

  • Int, Int with +, -, *, %, ^, // produces Int
  • Int, Int with / produces Float
  • Float, Float with +, -, *, /, %, ^ produces Float
  • mixed Int and Float with +, -, *, /, %, ^ produces Float

// is integer division and is valid only for two Int operands.

Comparisons

  • Int and Float support equality and ordering, including mixed numeric comparisons.
  • Char supports equality and ordering.
  • Bool supports equality only.
  • String supports is and is not. It does not support ordering operators.
  • Choices and options have additional equality rules in their own references.

+ is a numeric operator only. Source string concatenation uses templates. See Strings and characters for the canonical concatenation form.

Precedence and associativity

From highest to lowest:

  • level 6: unary not, unary -
  • level 5: ^
  • level 4: *, /, //, %
  • level 3: +, -
  • level 2: is, is not, <, <=, >, >=
  • level 1: and
  • level 0: or

^ is right-associative. Other binary operators are left-associative.

Parentheses override normal precedence.

Spacing

Symbolic binary operators require spaces on both sides. Assignment = follows the same outer-spacing rule, but it is not a binary operator.

total = left + right
count = 1

These forms are invalid:

-- INVALID: missing required spacing
total=left+right
count=1

The compound forms +=, -=, *=, /=, //=, %= and ^= follow the same rule:

count += 1
count //= 2

count+=1, count +=1 and count+= 1 are invalid.

The mutable declaration spelling ~= stays adjacent. It needs whitespace before ~ and after =:

count ~= 1

count~= 1, count ~=1 and count ~ = 1 are invalid.

Operator overloading is outside Moth's language design. Operators remain compiler-owned and predictable.

Choose the explanation level: Checked arithmetic

Checked arithmetic

Moth checks arithmetic instead of quietly wrapping or producing invalid floating-point values.

These operations can fail:

  • overflowing an Int
  • dividing by zero
  • using an invalid integer exponent
  • producing NaN or infinity

A function with an Error! return can pass that failure through its normal error path:

divide |left Int, right Int| -> Float, Error!:
    return left / right
;

Outside that kind of function, an unexpected runtime numeric failure stops the current program path.

A failure the compiler can prove in advance is reported during compilation.

Runtime numeric operations are checked.

Failures include:

  • integer overflow
  • division or modulo by zero
  • invalid integer exponents
  • non-finite Float results

Failure mode

When the enclosing function has builtin Error! as its error return slot, checked numeric failures use that error channel.

divide |left Int, right Int| -> Float, Error!:
    return left / right
;

ratio = divide(10, 0) catch:
    then 0.0
;

Custom fallible channels, non-fallible functions and entry-selected top-level runtime code use trap mode for checked numeric failure.

Numeric operators remain ordinary source expressions. The compiler lowers their failure path. They are not source-visible Error! values that can be handled in the middle of an arbitrary expression.

Compile-time failures

A statically known numeric failure is a compile-time diagnostic.

This remains true inside a function with builtin Error!.

Related behaviour

Range-loop counter updates use the same checked numeric operations.

Conversions that may lose information, such as Float -> Int, belong to the Casts documentation rather than implicit arithmetic coercion.