Strings are UTF-8, and System.String is converted at a .NET call

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

Co-Authored-By: eca-agent <git@eca.dev>
This commit is contained in:
Linus Björnstam 2026-10-04 22:20:16 +02:00
parent ea96af593c
commit 1ef2489224
2 changed files with 9 additions and 5 deletions

View file

@ -1209,7 +1209,7 @@ Sets and the sorted collections are libraries, so they have to be imported. Thei
(orderedmap-min prices) ;; (Some ("apple" . 5))
}|
An ordered collection sorts its keys with their @code{Ord}, so a type that derives @code{Ord} can be a key in one. Strings are sorted by code unit, not by the rules of any language, so the order is the same on every machine.
An ordered collection sorts its keys with their @code{Ord}, so a type that derives @code{Ord} can be a key in one. Strings are sorted by code point, not by the rules of any language, so the order is the same on every machine.
@subsubsection{Building collections quickly}
@ -1709,15 +1709,15 @@ Dealing a deck to four players means giving player 0 the cards 0, 4, 8 and so on
@subsubsection{Strings and characters}
A @code{string} is a .NET string, which means it is stored as UTF-16. A @code{char} in bjolang is not a UTF-16 unit, though: it is a whole Unicode code point. An emoji is one @code{char}, even though it takes two units in the string. That leads to two different lengths:
A @code{string} is stored as UTF-8, and is always valid UTF-8. A @code{char} is not a byte, though: it is a whole Unicode code point. An emoji is one @code{char}, even though it takes four bytes in the string. That leads to two different lengths:
@codeblock[#:lang "bjolang"]|{
(def s "Björn 😀 åt")
(string-length s) ;; 11: storage units, O(1). Use it for sizing buffers.
(string-length s) ;; 15: storage units, which are bytes, O(1). Use it for sizing buffers.
(string-count s) ;; 10: characters, O(n). This is "how long is the text".
}|
For the same reason there is no @code{string-ref} that takes an index. Finding the n:th character of a UTF-16 string means walking it, so walking is what you do: with a @code{loop}, a fold, or a cursor.
For the same reason there is no @code{string-ref} that takes an index. Finding the n:th character of a UTF-8 string means walking it, so walking is what you do: with a @code{loop}, a fold, or a cursor.
@codeblock[#:lang "bjolang"]|{
(loop (:for c s) (:acc n (counting c)) => n) ;; 10: loops go by character
@ -1743,7 +1743,7 @@ Characters are written @code{#\a}, @code{#\space}, @code{#\newline}. They can be
(string-empty? "") ;; #t
}|
All of these compare strings ordinally, one storage unit at a time, and never according to the language settings of the machine. Upcasing and downcasing are the same everywhere too. To compare without caring about case, downcase both sides first.
All of these compare strings ordinally, byte by byte, which for UTF-8 is the order of the code points, and never according to the language settings of the machine. Upcasing and downcasing are the same everywhere too. To compare without caring about case, downcase both sides first.
@subsubsection{Cursors}