Section 9.1

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 extend line, keep the import, and read: N009 is 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.