# Chars
`chars/*` is the character-classification namespace: predicates that
answer how a character is classified, plus two explicit
character-granular string verbs. The predicates cover the ASCII
conventions the language uses for identifiers and word-like tokens,
while `chars/count` and `chars/slice` are self-documenting spellings of
the codepoint-based `len` and `slice` — a reminder that string indexing
is character-based, not byte-based (see Strings). Every
`chars/*` function is registered in all hosts and needs no import; the
identifier predicates mirror the lexical rules in
Syntax and Style.
## Functions
| Function | Purpose |
|---|---|
| `chars/word? ch` | Word character: alphanumeric or `_ - ? ! /` |
| `chars/digit? ch` | Digit (`0`-`9`) |
| `chars/alpha? ch` | Letter (`a`-`z`, `A`-`Z`) |
| `chars/upper? ch` | Uppercase letter (`A`-`Z`) |
| `chars/lower? ch` | Lowercase letter (`a`-`z`) |
| `chars/space? ch` | Whitespace: space, tab, newline, carriage return |
| `chars/ident-start? ch` | Identifier start: letter or `_` |
| `chars/ident-cont? ch` | Identifier continuation: alphanumeric or `_ - ? ! /` |
| `chars/count s` | Number of codepoints (same as `len`) |
| `chars/slice s a b` | Codepoint range `[a, b)` (same as `slice`) |
Notes:
- The eight predicates take a single-character string and return a
boolean. Empty strings are `false`. When given a longer string they
classify its first character (`[chars/digit? "42"]` is `true`), so
pass one character at a time.
- Classification is ASCII-only — `[chars/upper? "É"]` is `false`, and
non-ASCII letters are never word characters.
- `chars/word?` and `chars/ident-cont?` accept the same set: letters,
digits, `_`, `-`, `?`, `!`, and `/`. `chars/ident-start?` is
stricter: letters and `_` only.
- `chars/count` is identical to `len` on a string; `bytes/len` is the
UTF-8 byte size. `chars/slice` clamps: `b` to the string end, `a` to
0, and `a >= b` yields `""`.
## Examples
### Classifying characters
echo [chars/digit? "7"] # true echo [chars/alpha? "x"] # true echo [chars/space? "\t"] # true echo [chars/upper? "É"] # false — ASCII only echo [chars/word? "/"] # true — namespace separators are word chars
### Identifier rules
echo [chars/ident-start? "_"] # true echo [chars/ident-start? "-"] # false echo [chars/ident-cont? "?"] # true echo [chars/ident-cont? " "] # false set code "x9" echo [chars/ident-start? [char-at $code 0]] # true echo [chars/ident-cont? [char-at $code 1]] # true
### Codepoints vs bytes
set s "a中c" echo [chars/count $s] # 3 codepoints echo [bytes/len $s] # 5 UTF-8 bytes echo [chars/slice $s 1 2] # 中 echo [chars/slice $s 2 99] # c — b clamps to the end
## See Also
- Strings — `len`, `slice`, `split ""`, and byte-level access
- Syntax and Style — identifier rules and call forms
- Regex — pattern matching over whole strings