You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
\uXXXX and \UXXXXXXXX escapes in quoted text in Modern, with exactly four and eight
hexadecimal digits, as SWI-Prolog reads them. A surrogate escape is a syntax error rather than half
of a pair, and StrictIso rejects both forms, which ISO does not have.
In Modern, a symbol or punctuation character outside ASCII reads as a one-character atom, as
SWI-Prolog reads it: f(😀) is f('😀'), [€, ∀] is a list of two atoms, and writeq/1 writes
such an atom bare. Like SWI-Prolog 10.1, it never joins its neighbours, so 😀😀 is a syntax error
and - 😀 is the prefix operator applied to 😀. Brackets and quotation marks outside ASCII, such
as «, stay syntax errors. Unquoted names follow Unicode's identifier properties: any letter or
letter number that is not uppercase starts an atom, as in 中文 and Ⅰ, and combining marks and
superscript digits continue one, as in x́ and x².
Changed
In Modern, a character is a Unicode code point rather than a UTF-16 code unit, so a character
outside the Basic Multilingual Plane is one character with one code: atom_length('😀', N) gives
1, atom_codes('😀', L) gives [128512], char_code(C, 128512) succeeds, and "😀é" reads as a
two-element list. The atom and string predicates count, slice, and enumerate by code point — atom_length/2, sub_atom/5, atom_concat/3, atom_chars/2, atom_codes/2, char_code/2, number_codes/2, atom_number/2's 0'c, string_length/2, sub_string/5, string_code/3, split_string/4 — and char_type/2 and code_type/2 classify supplementary characters. A
surrogate code is not a character code; a host string's unpaired surrogate reads as U+FFFD. The
ISO predicates keep ISO's representation_error(character_code). StrictIso is unchanged: its
characters remain UTF-16 code units.
In Modern, the reader and writer work in code points too. 0'😀 is 128512, \x…\ escapes reach
U+10FFFF, and a supplementary letter reads and writes like any other letter — 𝑎bc is an atom, 𐐀x a variable, and writeq/1 leaves 𝑎bc unquoted. The layout linter's line-length limit
counts code points.
In Modern, streams and format work in code points as well. get_char/1,2, peek_char/1,2, get_code/1,2, and peek_code/1,2 read a supplementary character as one character, a peek
included, and put_char/1,2 and put_code/1,2 write one. format/2,3 counts columns in code
points, so ~t padding lines up around a supplementary character, and a supplementary fill
character works. char_conversion/2 maps any character.
In Modern, the standard order compares atoms, strings, and functor names by code point, as
SWI-Prolog does. UTF-16 order had put a supplementary character before U+E000–U+FFFF, so msort(['😀', '\xFFFD\'], L) now gives ['\xFFFD\', '😀']; text within the Basic Multilingual
Plane sorts as before. StrictIso keeps code-unit order.
CharacterConversionTable takes and returns character codes as int rather than char, so it
can hold a supplementary character: Convert(int), Set(int, int), and All() returning (int Input, int Output) pairs. Hosts that call it directly need recompiling.
char_type/2 and code_type/2 classify characters outside ASCII from the Unicode data, the way
SWI-Prolog does since 10.1, rather than by rules that put unassigned code points in graph, print, and punct. Now an unassigned code point has no type, a format character such as U+200B
is cntrl, and alpha, upper, and lower follow Unicode's Alphabetic, Uppercase, and Lowercase
properties, so ª is lower, Ⅰ is upper, and the Devanagari vowel signs are alpha. A number
such as ² is alnum rather than punct. ASCII characters keep their types.
writeq/1 leaves a Modern atom bare when it starts with any letter that is not uppercase, so 中文 and x́ are no longer quoted.
Fixed
format's ~c no longer truncates a code silently: a negative code raises format_argument_type(c, Code), and a code past Unicode or in the surrogate range raises representation_error(code_point), as SWI-Prolog does.
code_type/2's end_of_line holds for vertical tab and form feed, as in SWI-Prolog, and for
U+0085, U+2028, and U+2029.
A quoted atom or string holding a layout character other than the space, such as U+00A0 or U+2028,
is written with a \xHEX\ escape, because the reader rejects the raw character between quotes;
such an atom now reads back.