The vocabulary is imported
What the language hands over unasked stops at Console, System, File and its errors. The rest of the vocabulary is written in Archon, and is imported.
Since the very first section, everything the course has done with a text, it has done with
$"{…}": gluing values end to end. Never cutting one, never looking inside one. This is not a
gap in the language — that vocabulary is not handed over, it is asked for.
import { StrText } from "std/extensions/str-text.arc";
extend archetype str StrText;
@entry(start)
object MyProgram {
start() {
var incantation := "abracadabra";
Console.print(text: $"{incantation.length} letters");
Console.print(text: $"the first five: {incantation.substring(start: 0, end: 5)}");
Console.print(text: $"the first one is worth {incantation.charAt(index: 0)}");
}
}
What the language hands over unasked
The list is short, and you already know all of it: Console, System, File, and the error
archetypes 8.2 named. Plus .length, met in 6.1 on an array, which holds for a text too. That
is all.
Cutting a text, reading a letter from it, turning it into a number: none of that is in the language. It is written in Archon, in a standard library, with the same archetypes and the same methods as the ones you have been writing since section 7. Remove the first two lines of the program and the compiler is blunt:
error[N009]: 'str' has no method 'substring'
There is no hidden method that a magic word would reveal. There is none, until one is brought in.
import fetches, extend applies
The two lines at the head of the program do not do the same thing, and both are needed:
import { StrText } from "std/extensions/str-text.arc";
extend archetype str StrText;
import says where it comes from and what is taken out of it: from the file
std/extensions/str-text.arc, a bundle of methods called StrText. The path starts with
std/, and that library the compiler carries in its own memory — nothing to download, nothing
to install, no file to place next to yours.
extend archetype str StrText; applies it, here, in this file. The import alone is not
enough: the compiler answers the very same N009. That is deliberate — an extension never
imposes itself on a file that did not ask for it, and what you add to str at your place, you
do not add at your neighbour’s.
Notice, in passing, what has just happened: str is not a type of yours, you have not written a
line of it, and yet you have just given it methods — without inheriting from it, since there
is no inheritance in Archon. That is what extend is for.
substring cuts between two indexes
incantation.substring(start: 0, end: 5)
The indexes are those of 6.1, and they start at zero. start is taken, end is not: the
interval is half-open. Hence two conveniences — end - start is the length of the piece, and
substring(start: 0, end: incantation.length) returns the whole text without running one step
over.
Running over, as it happens, does not go unnoticed:
uncaught error — IndexOutOfRangeError : substring [0, 50) out of range for a string of length 11
It is the out-of-bounds array error of 6.1, on a text, and it is caught exactly as section 8 showed.
charAt returns a code, not a letter
incantation.charAt(index: 0) returns 97, not "a".
This is no oddity: Archon has no separate “character” type. A lone letter is a text of one
letter, and a character code is an integer — 97 is the one for a, 98 the one for b, and so
on. A charAt is therefore for comparing, not for displaying; to display a letter, call
substring.
Over to you
- Remove the
extendline, keep theimport, and read:N009is back. The import brings in, it does not apply. - Ask for
substring(start: 0, end: 50)on eleven letters: the error names the interval and the length, and you would already know how to catch it. - Print
incantation.charAt(index: 1):98. The codes follow one another as the alphabet does. - Take the last five letters —
substring(start: incantation.length - 5, end: incantation.length). It is the same arithmetic as in 6.1 for reaching the last index.