Numbers: the full set of types, and real literals that take their type

The numeric types table lists bigint, int128, uint128, float and decimal.
A real literal without a suffix is a double, float or decimal as the
context says. A boolean prints as #t.

🤖 Generated with [ECA](https://eca.dev)

Co-Authored-By: eca-agent <git@eca.dev>
This commit is contained in:
Linus Björnstam 2026-10-21 13:05:45 +02:00
parent bd71102c19
commit 481538a1cb
2 changed files with 22 additions and 13 deletions

View file

@ -2315,22 +2315,25 @@ Nothing about @code{list-sort} knows about cards. It asks for @code{(Ord %a)}, a
@subsubsection{The types}
There are eight numeric types, each a .NET primitive:
The numeric types are the .NET ones:
@read-table{
| Type | Range | Type | Range |
|----------------+------------------------------+----------------+------------------------|
|----------------+------------------------------+----------------+---------------------------|
| @code{byte} | 0 … 255 | @code{uint} | 0 … 2^32−1 |
| @code{short} | −32 768 … 32 767 | @code{long} | −2^63 … 2^63−1 |
| @code{ushort} | 0 … 65 535 | @code{ulong} | 0 … 2^64−1 |
| @code{int} | about ±2.1 billion | @code{double} | 64-bit floating point |
| @code{bigint} | any integer | @code{float} | 32-bit floating point |
| @code{int128} | −2^127 … 2^127−1 | @code{decimal} | 28 digits, exact decimals |
| @code{uint128} | 0 … 2^128−1 | | |
}
There is no @code{float} and no @code{decimal}. A @code{char} is not a number: it can be compared and converted, but not added.
A @code{char} is not a number: it can be compared and converted, but not added.
@subsubsection{Writing numbers}
A number with a suffix is of that type. A decimal point or an exponent makes it a @code{double}:
A number with a suffix is of that type. A decimal point or an exponent makes it a real number, which is a @code{double}, a @code{float} or a @code{decimal}, and never an integer:
@read-table{
| Written | Type |
@ -2341,11 +2344,14 @@ A number with a suffix is of that type. A decimal point or an exponent makes it
| @code{21u} | @code{uint} |
| @code{21L} | @code{long} |
| @code{21UL} | @code{ulong} |
| @code{21d} @code{2.5} @code{1e3} | @code{double} |
| @code{21d} @code{2.5d} | @code{double} |
| @code{21M} @code{2.5M} | @code{decimal} |
| @code{21I} | @code{bigint} |
| @code{2.5} @code{1e3} | a real type, as the context says |
| @code{0x2A} @code{0b101010} | 42, of whatever type the context says |
}
A number without a suffix has no type of its own. It takes the type of wherever it is used, and is an @code{int} only when nothing says otherwise:
A number without a suffix has no type of its own. It takes the type of wherever it is used, and is an @code{int}, or a @code{double} if it is real, only when nothing says otherwise:
@codeblock[#:lang "bjolang"]|{
(: doubled (-> ushort ushort))
@ -2355,9 +2361,12 @@ A number without a suffix has no type of its own. It takes the type of wherever
(let ((start 5))
(+ start 3L)) ;; 8L: start was a long all along
(: tenth decimal)
(def tenth 0.1) ;; a decimal, so (+ tenth 0.2) is exactly 0.3
}|
A literal that does not fit the type it ends up with is a compile error. @code{(doubled 99999)} says that 99999 does not fit in a @code{ushort}.
A literal that does not fit the type it ends up with is a compile error. @code{(doubled 99999)} says that 99999 does not fit in a @code{ushort}, and @code{(doubled 2.5)} that 2.5 has a fraction.
@subsubsection{Arithmetic}

View file

@ -1718,7 +1718,7 @@ Literal prefixes like @code{#map(...)} are reader-level hash macros. You can reg
(defun (main)
(println #card(Q hearts)) ;; Q♥
(println #card[10 spades]) ;; 10♠, either bracket works
(println (court? #card(K clubs))) ;; True
(println (court? #card(K clubs))) ;; #t
(with-each-card (c [#card(A spades) #card(2 hearts)])
(println #"a card: ${c}"))
0)