// TCLRS — COMMAND REFERENCE

tclrs v0.4.8 · generated from the compiler's own tables · MIT

Docs Report GitHub

>_LANGUAGE REFERENCE

Every name the current tclrs build knows — 81 commands, 169 ensemble subcommands, the expr ladder, the string is classes and the format conversions — each with the signature the compiler reports and a description written from what the code does. 339 entries in all. Jump via the chapter index, or Ctrl+F for a name.

Chapters

Commands

81 entries

Every command the current build compiles. A name absent from this chapter is invalid command name "…" at compile time, not a runtime lookup that fails — resolving the name while compiling is what turns a call into a Op::Call to a known entry. The list is the compiler's own: the names it matches itself, plus the list commands it forwards. Each signature is the wording of the wrong # args message at that command's compile site, so a reader who provokes the error sees this text.

81
Commands
140/169
Ensemble subcommands
27
expr binary operators
v0.4.8
Build

# after

after ms|cancel|idle|info ?arg ...?

Register a script to run after a delay or when nothing else is pending, cancel one, or list what is registered. See the module note in src/cmd_after.rs for which event sources a build has.

# append

append varName ?value ...?

Append every value to the variable's string; yields the new value.

# apply

apply lambdaExpr ?arg ...?

Run a lambda — a list of parameters, a body and an optional namespace — as what it is: a procedure body with a frame of its own. The lambda may be computed. A wrong argument count is reported against the lambda, which has no name to report.

# array

array subcommand ?arg ...?

The array ensemble, over a variable rather than a value: an array is never itself a value.

# binary

binary subcommand ?arg ...?

The binary ensemble: build a byte string from values (format), take values back out of one (scan), and convert between bytes and base64, hex or uuencode text (encode, decode). A byte string here is a string whose every character is below U+0100.

# break

break

Leave the innermost loop. The stack is unwound by a count the compiler knows statically.

# catch

catch script ?resultVarName?

Run the script and trap an error from it, including one raised inside a procedure it called; yields the completion code.

# cd

cd ?dirName?

Change the working directory; no argument means the home directory.

# clock

clock subcommand ?arg ...?

The time ensemble: read the clock, and convert between an instant and a calendar.

# close

close channel ?direction?

Drop a reference to a channel and close it once none is left; ?direction? half-closes a read-write channel.

# concat

concat ?arg ...?

Trim each argument of surrounding whitespace and join them with single spaces into one list.

# continue

continue

Begin the innermost loop's next iteration; in a for, its step still runs first.

# coroutine

coroutine name cmd ?arg ...?

Create a coroutine context — a second VM over the same chunk — running one of the script's procedures, and enter it.

# dict

dict subcommand ?arg ...?

The dict ensemble, over a value: a dict is a list of alternating keys and values, so it can be passed and printed like any string.

# encoding

encoding subcommand ?arg ...?

The transcoding ensemble: convert between a byte string and a string, and report which encodings and error profiles exist.

# eof

eof channel

Whether the channel's device reported end of file and nothing decoded is still buffered.

# error

error message ?errorInfo? ?errorCode?

Raise an error carrying the message. The two optional words are evaluated and then dropped: what they set is -errorinfo and -errorcode, the return options this frontend does not carry.

# eval

eval arg ?arg ...?

Concatenate the arguments and run the result as a script against the interpreter's own variables. The chunk is cached by source text.

# expr

expr arg ?arg ...?

Evaluate the arguments as an expression. A braced argument is compiled once, not re-parsed per evaluation.

# fconfigure

fconfigure channel ?-option value ...?

Read or set a channel's generic options: -translation, -encoding, -buffering, -buffersize, -blocking.

# file

file subcommand ?arg ...?

The path and filesystem ensemble; the path halves need nothing on disk.

# flush

flush channel

Hand everything buffered for the channel to its device.

# for

for start test next body

Run start, then the body while test holds, running next after each iteration. Emitted rotated, like every loop here.

# foreach

foreach varList list ?varList list ...? command

Iterate over one or more lists in parallel; the longest fixes the count and shorter ones supply empty values.

# format

format formatString ?arg ...?

Format the arguments the way sprintf does, with Tcl's conversion set.

# gets

gets channel ?varName?

The next line without its terminator; with a variable, the line goes there and the count is the result.

# glob

glob ?switches? ?pattern ...?

Every existing name a pattern matches, walked one path component at a time.

# global

global ?varName ...?

Address the named variables in the global table rather than the procedure's frame slots. Outside a procedure it does nothing.

# if

if test ?then? body ?elseif test ?then? body ...? ?else? ?body?

The first branch whose test is a true Tcl boolean; a test that is not a boolean is an error, not a false branch. The else keyword is optional: the word after the last body is the else script whatever it says.

# incr

incr varName ?increment?

Add the increment (1 by default) to the variable; yields the new value.

# info

info subcommand ?arg ...?

Interpreter introspection. Variables, procedure signatures and bodies, command names, the call frame's level and its locals, the math functions, whether text is a complete command, and the versions; the subcommands naming machinery this frontend has none of — frame, errorstack, cmdcount, cmdtype, the object-system queries, constant, loaded — are refused by name rather than mis-answered.

# join

join list ?joinString?

Concatenate the list's elements, separated by joinString (a space by default).

# lappend

lappend varName ?value ...?

Append each value to the list held in the variable; yields the new list.

# lassign

lassign list ?varName ...?

Assign the elements to the variables in order; yields the unassigned remainder.

# ledit

ledit listVar first last ?element ...?

Replace the range in the variable's list with the elements; yields the new list.

# lindex

lindex list ?index ...?

The element at an index path, or the list itself when no index is given.

# linsert

linsert list index ?element ...?

A copy of the list with the elements inserted before the index.

# list

list ?arg ...?

A list of the arguments, quoted by the reference algorithm so it reads back as the same elements.

# llength

llength list

How many elements the list has.

# lmap

lmap varList list ?varList list ...? command

foreach that collects each iteration's value into a list; continue contributes nothing.

# lpop

lpop listvar ?index ...?

Remove the element at an index path from the variable's list and yield it.

# lrange

lrange list first last

The sublist between two indices, inclusive.

# lremove

lremove list ?index ...?

A copy of the list without the indexed elements; an index outside it is ignored.

# lrepeat

lrepeat count ?value ...?

The values repeated count times, as one list.

# lreplace

lreplace list first last ?element ...?

A copy of the list with the range replaced by the elements.

# lreverse

lreverse list

The list, reversed.

# lsearch

lsearch ?-option value ...? list pattern

The index of the first matching element, or -1. Option parsing is the reference one, abbreviation included.

# lseq

lseq n ??op? n ??by? n??

An arithmetic sequence; a zero step yields one element and a step pointing away from the end yields none.

# lset

lset listVar ?index? ?index ...? value

Replace the element at an index path in the variable's list; the end grows by one element only.

# lsort

lsort ?-option value ...? list

The list sorted by the reference merge sort — the algorithm, not just the ordering, because -unique observes it.

# namespace

namespace subcommand ?arg ...?

The namespace ensemble. A namespace is resolved while compiling, so its variables and procedures take qualified names; the queries are answered from interpreter state.

# open

open fileName ?access? ?permissions?

Open a file and return the channel's name. The command-pipeline form is refused.

# package

package option ?arg ...?

The package ensemble: what a name is provided at, what would load it, and TIP 268's version arithmetic over both.

# proc

proc name args body

Define a procedure. Parameters and locals are frame slots; defaults and a trailing args are resolved at the call site.

# puts

puts ?-nonewline? ?channel? string

Write the string to a channel, or to stdout when none is named.

# pwd

pwd

The working directory, as the last cd was told it rather than as getcwd reports it.

# read

read channel ?numChars?

Read the whole channel, or that many characters; -nonewline drops the trailing newlines.

# regexp

regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?

Match a regular expression, setting the match variables; the count under -all, the text under -inline.

# regsub

regsub ?-option ...? exp string subSpec ?varName?

Substitute for a regular expression's matches; the new string, or the count when a variable is named. Under -command the subSpec is a command prefix called once per match with the match and its subexpressions, and its result is the replacement verbatim.

# rename

rename oldName newName

Rename a command, or delete it when the new name is empty. A call the same chunk compiled is guarded so a deleted command still refuses.

# return

return ?-code code? ?result?

Return from the enclosing procedure with the result. -code ok and -code error are the codes implemented.

# scan

scan string format ?varName ...?

Read the string the way sscanf does, with Tcl's conversion set. With variable names the result is how many conversions were assigned, and a variable whose conversion never ran is left untouched; with none, the converted values come back as a list.

# seek

seek channel offset ?origin?

Move the device's position, discarding what was buffered and clearing end of file.

# set

set varName ?newValue?

Read or write a variable; yields its value. A procedure's variables are slots, a script's are VM globals.

# source

source ?-encoding encoding? fileName

Read a file and evaluate it against this interpreter; yields the value of its last command.

# split

split string ?splitChars?

Split the string at any of the characters into a list.

# string

string subcommand ?arg ...?

The string ensemble. Subcommands, options and the string is class are resolved while compiling.

# subst

subst ?-nobackslashes? ?-nocommands? ?-novariables? string

Perform the substitutions of a double-quoted word on a value, against the calling frame: a $name in it is that frame's variable and a [cmd] in it runs there. Each option makes its introducer literal text rather than the start of a construct. A command substitution's failure is trapped the way the reference implementation traps it — an error propagates, a break ends the substitution keeping what it has, a continue drops that one substitution — while a plain variable read is not trapped, so a missing variable is an error.

# switch

switch ?-option ...? string ?pattern body ...? ?default body?

Run the body of the first pattern that matches, -exact, -glob or -regexp. With -regexp, -matchvar and -indexvar name variables the matched text and its index pairs are written to.

# tcl_findLibrary

tcl_findLibrary basename version patch initScript enVarName varName

Tcl's own library-directory search, ported from library/auto.tcl: find the initialisation script, set the library variable and source it.

# tell

tell channel

The device's position, less whatever was read ahead of the script.

# throw

throw type message

Raise message as an error, the type having been checked to be a list of at least one element. The -errorcode the type becomes is part of the return-options dictionary, whose error entries this frontend does not model.

# unset

unset ?-nocomplain? ?--? ?name ...?

Remove variables or array elements.

# update

update ?idletasks?

Service everything that is pending and return; idletasks services only the idle handlers.

# uplevel

uplevel ?level? arg ?arg ...?

Concatenate the arguments and run the result as a script in the frame of a caller: #0 is the global level, a bare number counts calls outwards from this one. Which word is the level is decided when the command runs, so uplevel $n works. Only a procedure call is a level, so uplevel 1 at a script's top level is a bad level.

# upvar

upvar ?level? otherVar localVar ?otherVar localVar ...?

Bind a local name to a variable at another level. The level and the target may both be computed, and an array element may be the target.

# variable

variable ?name value ...? name ?value?

Declare a namespace variable. In a procedure body it links the local name to the namespace's variable rather than creating one.

# vwait

vwait ?varName?

Service events until the named global is written. With no name it is update.

# while

while test command

Run the body while the test holds. Inside a procedure this is the loop that reaches a compiled trace.

# yield

yield ?value?

Suspend the running coroutine and hand the value to whoever resumed it.

# yieldto

yieldto command ?arg ...?

Suspend and donate the resumer to another coroutine of the script, which is what makes the transfer symmetric rather than a queue.

The string ensemble

23 subcommands recognised · 23 implemented · 0 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# string cat

string cat ?string ...?

Concatenate the arguments; no arguments yields the empty string.

# string compare

string compare ?-nocase? ?-length int? string1 string2

-1, 0 or 1 for the ordering of the two strings.

# string equal

string equal ?-nocase? ?-length int? string1 string2

1 when the two strings are the same, 0 otherwise.

# string first

string first needleString haystackString ?startIndex?

The index of the first occurrence of the needle, or -1.

# string index

string index string charIndex

The character at the index, or the empty string when out of range.

# string insert

string insert string index insertString

The string with insertString placed before the index.

# string is

string is class ?-strict? ?-failindex var? str

Whether the string belongs to a character class. The class is resolved while compiling.

# string last

string last needleString haystackString ?lastIndex?

The index of the last occurrence of the needle, or -1.

# string length

string length string

How many characters the string has.

# string map

string map ?-nocase? mapping string

Replace every key of the mapping list with its value, scanning left to right.

# string match

string match ?-nocase? pattern string

Whether the glob pattern matches the whole string.

# string range

string range string first last

The characters between two indices, inclusive.

# string repeat

string repeat string count

The string repeated count times.

# string replace

string replace string first last ?string?

The string with the range replaced by the fourth argument, or removed.

# string reverse

string reverse string

The string, reversed by character.

# string tolower

string tolower string ?first? ?last?

The string in lower case, or only the range given.

# string totitle

string totitle string ?first? ?last?

The string with its first character in title case and the rest lowered.

# string toupper

string toupper string ?first? ?last?

The string in upper case, or only the range given.

# string trim

string trim string ?chars?

The string without leading and trailing characters from the set (whitespace by default).

# string trimleft

string trimleft string ?chars?

The string without leading characters from the set.

# string trimright

string trimright string ?chars?

The string without trailing characters from the set.

# string wordend

string wordend string charIndex

The index just past the last character of the word containing charIndex — a word being a run of letters, digits and underscores, or a single other character. The index is clamped rather than refused: a negative one is read as 0 and one past the end as the length. Characters outside ASCII raise instead of answering, because the word classes rest on Unicode tables this build carries at a different revision than the reference interpreter's.

# string wordstart

string wordstart string charIndex

The index of the first character of the word containing charIndex, with the same clamping and the same refusal beyond ASCII as string wordend.

The array ensemble

13 subcommands recognised · 6 implemented · 7 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# array anymore

array anymore arrayName searchId

Whether a search opened by array startsearch has elements left to hand out — 1 or 0. The four search-token subcommands need a cursor held across commands and keyed by the token startsearch returned, which is state this frontend does not keep, so all four are refused together.

Refused at run time: array anymore is not supported yet

# array default

array default subcommand arrayName ?value?

Tcl 9's per-array default: array default set a 0 makes every unset element of a read as 0, and get, exists and unset inspect and clear that. It is a property of the variable rather than of a value, and nothing in this frontend's array storage carries one.

Refused at run time: array default is not supported yet

# array donesearch

array donesearch arrayName searchId

Close a search and release its token, returning the empty string. Refused with the rest of the search-token family.

Refused at run time: array donesearch is not supported yet

# array exists

array exists arrayName

Whether the variable exists and holds an array — 1 or 0. A peek, not a read: asking does not create the variable, which is what lets it be asked about an unset name without raising.

# array for

array for {keyVar valueVar} arrayName script

Run the script once per element with the two variables bound, the way dict for does, yielding the empty string. dict for is built here and this is not: iterating an array needs a snapshot of a variable's elements taken before the body can modify them, which is a different lowering from walking a value.

Refused at run time: array for is not supported yet

# array get

array get arrayName ?pattern?

The array as a flat list of alternating names and values, restricted to the names matching a glob pattern when one is given. The order is the storage's, not sorted.

# array names

array names arrayName ?mode? ?pattern?

The element names, filtered by a glob pattern by default. The mode may be -exact, -glob or -regexp; -regexp searches the name rather than anchoring to it, and never folds case.

# array nextelement

array nextelement arrayName searchId

The next element name a search has to give, or the empty string when it is exhausted. Refused with the rest of the search-token family.

Refused at run time: array nextelement is not supported yet

# array set

array set arrayName list

Set elements from a flat list of alternating names and values; an odd-length list is an error. Which name the error quotes follows the command's scope rather than the variable's — inside a procedure body tclsh names the variable, at the top level it names the first element it was about to write, and this reproduces that.

# array size

array size arrayName

How many elements the array has; 0 for a variable that is unset or is not an array.

# array startsearch

array startsearch arrayName

Open a traversal of the array and return a token naming it, such as s-1-a. The token identifies a cursor the interpreter holds until array donesearch, which is the state this frontend does not have.

Refused at run time: array startsearch is not supported yet

# array statistics

array statistics arrayName

A multi-line report on the hash table behind the array — entries, buckets, the bucket-occupancy histogram and the average search distance. Every number in it describes the reference interpreter's own Tcl_HashTable, which is not the structure this frontend stores an array in, so there is nothing truthful to answer.

Refused at run time: array statistics is not supported yet

# array unset

array unset arrayName ?pattern?

Remove the elements whose names match the glob pattern, or the whole array when no pattern is given.

The dict ensemble

22 subcommands recognised · 21 implemented · 1 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# dict append

dict append dictVarName key ?string ...?

Append the strings to the value already at the key in the dict the variable holds, creating the key when it is absent, and yield the new dict.

# dict create

dict create ?key value ...?

A dict of the given pairs; an odd number of arguments is an error. With no arguments it is the empty dict, which is the empty string.

# dict exists

dict exists dictionary key ?key ...?

Whether the whole key path resolves — 1 or 0. A path that runs into a value which is not itself a dict answers 0 rather than raising, which is what separates it from dict get.

# dict filter

dict filter dictionary filterType arg ?arg ...?

The pairs kept by one of three filters. key and value take glob patterns — any of several matching keeps the pair, and no pattern keeps nothing. script {k v} body runs the body per pair and keeps the pair its result calls true, and keeps what it has collected when a break ends the walk.

# dict for

dict for {keyVarName valueVarName} dictionary script

Run the script for each pair with the two variables bound, in insertion order, and yield the empty string. Lowered as a cursor over a flattened pair list, so the dict is snapshotted before the first iteration.

# dict get

dict get dictionary ?key ...?

The value at the key path; the whole dict when no key is given. A key that is absent raises, unlike dict exists.

# dict getdef

dict getdef dictionary ?key ...? key default

The value at the key path, or the trailing default argument when any step of the path is missing — the total-function form of dict get. A dict that does not parse is still an error, as it is for dict get.

# dict getwithdefault

dict getwithdefault dictionary ?key ...? key default

The long spelling of dict getdef, identical in behaviour. Both are listed because either one being present is what makes dict get an unambiguous abbreviation of nothing else.

# dict incr

dict incr dictVarName key ?increment?

Add the increment (1 by default) to the value at the key in the dict the variable holds, treating an absent key as 0, and yield the new dict. The variable may be a frame slot or a global; a variable naming an array element — dict incr a(k) … — is refused instead.

# dict info

dict info dictionary

A multi-line report on the hash table behind the dict: entries, buckets, the bucket-occupancy histogram and the average search distance. Refused here. Every number in it describes the reference interpreter's Tcl_HashTable, and it reports the table the object has rather than one the value implies — a dict grown and then shrunk keeps the buckets it grew, so two dicts with the same string answer differently. A dict here is its string, so there is no history to report.

Refused at run time: dict info is not supported yet

# dict keys

dict keys dictionary ?pattern?

The keys in insertion order, restricted to those matching a glob pattern when one is given.

# dict lappend

dict lappend dictVarName key ?value ...?

Append the values as list elements to the value at the key in the dict the variable holds, and yield the new dict.

# dict map

dict map {keyVarName valueVarName} dictionary script

dict for that collects each iteration's result as the new value for the key the key variable holds when the body ends. A break throws the whole accumulation away, which is where it parts from dict filter's script form.

# dict merge

dict merge ?dictionary ...?

One dict of all the arguments, a later occurrence of a key winning. With no arguments it is the empty dict.

# dict remove

dict remove dictionary ?key ...?

The dict without the named keys; a key that is not present is not an error. Only top-level keys — there is no path form.

# dict replace

dict replace dictionary ?key value ...?

The dict with the given pairs set, as a value rather than through a variable — dict set without the assignment.

# dict set

dict set dictVarName key ?key ...? value

Set the value at a key path in the dict the variable holds, creating the variable and any intermediate dicts, and yield the new dict. The read of the current value tolerates an unset variable where a bare $d would refuse it; a variable naming an array element is refused.

# dict size

dict size dictionary

How many pairs the dict has.

# dict unset

dict unset dictVarName key ?key ...?

Remove the key path from the dict the variable holds and yield the new dict. Removing the last key of the path is not an error when it is absent; a key the path has to walk through must exist.

# dict update

dict update dictVarName key varName ?key varName ...? script

Bind each named key's value to a variable, run the script, then write the variables back into the dict — and yield the script's own result. The write-back is a finally: it happens after an error, a break or a return too, and a variable the body unset takes its key out of the dict. The variable names have to be literal here.

# dict values

dict values dictionary ?pattern?

The values in insertion order, restricted to those whose string form matches a glob pattern when one is given.

# dict with

dict with dictVarName ?key ...? script

dict update over every key at once: each key becomes a variable of that name for the duration of the script, and the variables are written back after — after an error, a break or a return too. A leading key path opens out a sub-dictionary instead. The names come from the dictionary's keys, so each is resolved when the command runs: a global at a script's own level, a frame slot inside a procedure, and one element of an array for a key written a(i). Unsetting a bound variable is what removes its key; every other key goes back even if the body deleted it from the dictionary.

The info ensemble

29 subcommands recognised · 20 implemented · 9 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# info args

info args procname

The parameter names of a procedure, in order, as a list. Answered from the signature table the compiler already builds to check call arity, so a computed procedure name works as well as a literal one.

# info body

info body procname

The source text a procedure's body was written as, answered from the same table info args reads, so a computed procedure name works. A procedure whose body the script computed has no text and is reported as no procedure, which is what tclsh reports for a name that is none.

# info class

info class subcommand class ?arg ...?

Introspection on a TclOO class — its instances, methods, superclasses and mixins, selected by a second subcommand word. TclOO is not implemented here, so the whole family is refused by name.

Refused at run time: info class is not supported yet: TclOO is not implemented

# info cmdcount

info cmdcount

How many commands the interpreter has evaluated. Refused: nothing counts them. A compiled frontend does not execute commands one at a time — a loop body becomes bytecode and, above the first tier, native code — so there is no place the count could be kept without slowing down what it measures.

Refused at run time: info cmdcount is not supported yet: the interpreter does not keep it

# info cmdtype

info cmdtype commandName

What kind of command a name is — native, proc, alias, ensemble, import or object in the reference interpreter. Refused: commands are resolved while compiling and no per-name kind survives into the run.

Refused at run time: info cmdtype is not supported yet: the interpreter does not keep it

# info commands

info commands ?pattern?

The command names matching the glob pattern — every name the frontend answers to, the command modules' included, together with the script-defined procedures — sorted. With no pattern, every name.

# info complete

info complete command

1 when the text is a whole command, 0 when more input could finish it. Only genuinely unterminated input answers 0 — an open brace, bracket or quote. Text that is closed but malformed is complete: puts }extra, {a}x, set x "a"b and a trailing backslash are all 1, matching tclsh. This is what a REPL asks to decide whether to keep reading.

# info constant

info constant varName

Whether a variable was made read-only by Tcl 9's const. Refused: constant variables are not implemented, so no variable can answer 1 and answering 0 for all of them would be a claim rather than a report.

Refused at run time: info constant is not supported yet: constant variables are not implemented

# info consts

info consts ?pattern?

The constant variable names matching the pattern. Refused for the same reason as info constant.

Refused at run time: info consts is not supported yet: constant variables are not implemented

# info coroutine

info coroutine

The name of the coroutine whose context is running, or the empty string outside one. The one info subcommand answered from the coroutine machinery rather than from the interpreter's tables.

# info default

info default procname arg varname

1 when the named parameter has a default, writing the default into varname; 0 otherwise, writing the empty string. The third argument may itself be an array element, which is what a script reading a whole signature into an array writes.

# info errorstack

info errorstack ?interp?

The CALL/INNER trace of the most recent error, as a list. Refused: errors here carry a message and a line, not a captured call chain.

Refused at run time: info errorstack is not supported yet: the interpreter does not keep it

# info exists

info exists varName

1 when the variable or array element is set, 0 otherwise. A peek rather than a read — reaching the variable's place without growing storage — because an unset read raises here and asking whether a variable is set must not create it.

# info frame

info frame ?number?

The depth of the call stack, or a dictionary describing one frame — its type, the file and line it came from, and the command being run. Refused: this frontend does not expose the running call frame.

Refused at run time: info frame is not supported yet: it reports on the stack of *commands*, and only the stack of call frames is kept

# info functions

info functions ?pattern?

The expr math function names matching the pattern — abs, sin, pow and the rest — read from the same table that lowers a call to one, so the list cannot fall behind what expr accepts.

# info globals

info globals ?pattern?

The global variable names matching the glob pattern, sorted. Global here means the VM's own global table, which is where a script's top-level variables live.

# info hostname

info hostname

This host's name, from gethostname; the empty string when the call fails. Read at run time rather than compiled in, so an AOT-built binary reports the machine it runs on and not the one that built it.

# info level

info level ?number?

How deep the current procedure call is — 0 at a script's own level, one more per activation. Only a call is counted, not the frames the VM pushes for a scope or after a JIT side exit. The form taking a level number is refused: a call site pushes the actual arguments and nothing naming the command, so there is no record of what entered a level.

# info library

info library

The directory of Tcl's script library. Compiles and runs, then raises no library has been specified for Tcl — tclsh's own message for an interpreter whose tcl_library is gone, which is the state this frontend is permanently in because nothing here reads an init.tcl. A raise, not a refusal, so a catch around it behaves as it does under tclsh.

# info loaded

info loaded ?interp? ?prefix?

The binary extension packages loaded into an interpreter. Refused: load is not implemented, so the list would be empty by construction rather than by observation.

Refused at run time: info loaded is not supported yet: loadable extensions are not implemented

# info locals

info locals ?pattern?

The local variable names of the running procedure that are set, matching the pattern. A local is a frame slot addressed by index, so which names the frame has is settled while compiling and which of them hold anything is settled by the frame — the answer is the two halves met. A local whose only mention stands after the info locals is not listed.

# info nameofexecutable

info nameofexecutable

The full path of the running binary, from the operating system. For an AOT-compiled script this is the standalone executable, not the tclrs that built it.

# info object

info object subcommand object ?arg ...?

Introspection on a TclOO object — its class, methods, variables and mixins, selected by a second subcommand word. Refused with info class, because TclOO is not implemented.

Refused at run time: info object is not supported yet: TclOO is not implemented

# info patchlevel

info patchlevel

The full major.minor.patch version of the Tcl language this frontend implements — 9.0.4 — not the crate's own version, which tclrs --version reports. A script branching on it is asking about the language.

# info procs

info procs ?pattern?

The script-defined procedure names matching the glob pattern, sorted; builtins are excluded, which is the difference from info commands.

# info script

info script ?filename?

The file being evaluated, or the empty string when the script came from -c or stdin. With an argument it sets the name and returns that same new name — tclsh answers identically, so the one-line save-and-restore idiom does not work in either.

# info sharedlibextension

info sharedlibextension

The suffix a loadable library has on this platform — .dylib, .dll or .so. Decided by the build target, so it is the platform's answer and not a probe of the filesystem.

# info tclversion

info tclversion

The major.minor version of the Tcl language implemented — 9.0. As with info patchlevel, the language's version and not the crate's.

# info vars

info vars ?pattern?

The visible variable names matching the glob pattern, sorted. At a script's own level that is every variable the interpreter holds, including the argc, argv and argv0 it sets up; inside a procedure it is the frame's own — its set locals plus the names global, variable and upvar bound into it, which is what tclsh answers.

The namespace ensemble

19 subcommands recognised · 16 implemented · 3 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# namespace children

namespace children ?name? ?pattern?

The child namespaces of a namespace, fully qualified.

# namespace code

namespace code script

The script wrapped so that evaluating it later runs it in this namespace.

# namespace current

namespace current

The namespace the command was written in. Folded while compiling, since that is where a namespace is decided.

# namespace delete

namespace delete ?name name...?

Remove namespaces, their child namespaces and their commands.

# namespace ensemble

namespace ensemble subcommand ?arg ...?

exists, create and configure. Dispatching through an ensemble is not implemented: a call resolves its command while compiling.

# namespace eval

namespace eval name arg ?arg...?

Lower the body with this namespace current, which is what gives its proc, variable and $v the namespace's names. The name and the body have to be written out.

# namespace exists

namespace exists name

1 when the namespace exists.

# namespace export

namespace export ?-clear? ?pattern pattern...?

Add patterns to the namespace's export list, or report it when no pattern is given.

# namespace forget

namespace forget ?pattern pattern...?

Remove the imports of the commands a pattern names — not the commands themselves.

# namespace import

namespace import ?-force? ?pattern pattern...?

Bring exported commands into this namespace under their tail names. A pattern that matches nothing is not an error.

# namespace inscope

namespace inscope ns script ?arg...?

Evaluate the script in a namespace, with the extra arguments appended as list elements.

# namespace origin

namespace origin name

Where an imported command was originally defined; the command's own name when it was not imported.

# namespace parent

namespace parent ?name?

The namespace containing this one; empty for the root.

# namespace path

namespace path ?namespaceList?

Refused: it changes how a later name resolves, which this frontend resolved while compiling.

Refused at run time: "namespace path" is not supported yet: this frontend resolves namespaces while compiling, so the name has to be written out

# namespace qualifiers

namespace qualifiers string

Everything before the last ::, a port of NamespaceQualifiersCmd. Folded when the argument is written out.

# namespace tail

namespace tail string

Everything after the last ::, a port of NamespaceTailCmd.

# namespace unknown

namespace unknown ?script?

Refused, for the same reason namespace path is.

Refused at run time: "namespace unknown" is not supported yet: this frontend resolves namespaces while compiling, so the name has to be written out

# namespace upvar

namespace upvar ns ?otherVar myVar ...?

Refused, for the same reason namespace path is.

Refused at run time: "namespace upvar" is not supported yet: this frontend resolves namespaces while compiling, so the name has to be written out

# namespace which

namespace which ?-command? ?-variable? name

The qualified name a command or variable resolves to, or the empty string.

The package ensemble

12 subcommands recognised · 12 implemented · 0 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# package files

package files package

The files a package was loaded from. Always empty here: nothing records one, because this frontend has no package index.

# package forget

package forget ?package ...?

Drop everything known about each package — its version and every script that would load it. A name that is not known is not an error.

# package ifneeded

package ifneeded package version ?script?

Register the script that loads a version, or, with no script, report the one registered for exactly that version.

# package names

package names

Every package that is provided or has a loading script, in the order each was first mentioned.

# package prefer

package prefer ?latest|stable?

Whether an unqualified require takes the newest version or the newest stable one. Starts at stable and only ever moves to latest.

# package present

package present ?-exact? package ?requirement ...?

Like require for a package already provided, and an error rather than a load attempt for one that is not.

# package provide

package provide package ?version?

Declare this package present at a version, or report the version it was declared at. A second, different version is a conflict.

# package require

package require ?-exact? package ?requirement ...?

Make a package present, loading it if it is not, and yield the version that ended up provided.

# package unknown

package unknown ?command?

The script run when a required package is not known; the empty string clears it.

# package vcompare

package vcompare version1 version2

-1, 0 or 1 by TIP 268's ordering, in which 9.0 and 9.0.0 are equal and 1.2a3 sorts below 1.2.

# package versions

package versions package

The versions a loading script has been registered for.

# package vsatisfies

package vsatisfies version ?requirement ...?

Whether the version meets any of the requirements, each a version, a versionMin-versionMax range, or a versionMin- open range.

The clock ensemble

7 subcommands recognised · 7 implemented · 0 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# clock add

clock add clockval ?number units?... ?-option value?

Move an instant by calendar or fixed units; a day past the end of a month is clamped to it.

# clock clicks

clock clicks ?-switch?

A high-resolution counter, in microseconds unless -milliseconds is given.

# clock format

clock format clockval ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?

An instant as text, in the root locale's catalogue.

# clock microseconds

clock microseconds

The current time in microseconds since the epoch.

# clock milliseconds

clock milliseconds

The current time in milliseconds since the epoch.

# clock scan

clock scan string ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?

Text as an instant. The -format form only; the free-form parser is refused.

# clock seconds

clock seconds

The current time in seconds since the epoch.

The file ensemble

37 subcommands recognised · 28 implemented · 9 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# file atime

file atime name

The last access time, in seconds since the epoch.

# file attributes

file attributes name

Refused: the platform attribute set is not built.

Refused at run time: file attributes is not supported yet: it needs an interface this frontend has not built

# file channels

file channels

Refused: this frontend has no channels.

Refused at run time: file channels is not supported yet: it needs an interface this frontend has not built

# file copy

file copy ?-force? ?--? source ?source ...? target

Copy files or whole directories; an existing target is an error without -force.

# file delete

file delete ?-force? ?--? ?name ...?

Remove names; one that does not exist is not an error.

# file dirname

file dirname name

Everything but the last path component.

# file executable

file executable name

1 when the name can be executed by this process.

# file exists

file exists name

1 when the name resolves to something.

# file extension

file extension name

From the last dot at or after the last separator to the end.

# file home

file home ?user?

A home directory, this process's own when no user is named.

# file isdirectory

file isdirectory name

1 when the name resolves to a directory.

# file isfile

file isfile name

1 when the name resolves to an ordinary file.

# file join

file join name ?name ...?

Join path elements; an element that is itself absolute discards the ones before it.

# file link

file link ?-linktype? linkName ?target?

Refused: creating links is not built.

Refused at run time: file link is not supported yet: it needs an interface this frontend has not built

# file lstat

file lstat name varName

Refused: it writes an array this frontend does not build for it.

Refused at run time: file lstat is not supported yet: it needs an interface this frontend has not built

# file mkdir

file mkdir ?dir ...?

Create directories and every missing parent; an existing directory is not an error.

# file mtime

file mtime name

The last modification time, in seconds since the epoch.

# file nativename

file nativename name

The path in the platform's own form, which on unix drops duplicate separators.

# file normalize

file normalize name

The absolute path with links resolved, except in the last component.

# file owned

file owned name

1 when this process's effective user owns the name.

# file pathtype

file pathtype name

absolute or relative; unix has no volume-relative paths.

# file readable

file readable name

1 when the name can be read by this process.

# file readlink

file readlink name

What a symbolic link points at, as it was written.

# file rename

file rename ?-force? ?--? source ?source ...? target

Move names; an existing target is an error without -force.

# file rootname

file rootname name

The path with its extension cut off.

# file separator

file separator ?name?

The path separator, which on unix is always a slash.

# file size

file size name

The size in bytes.

# file split

file split name

The path's elements as a list; the root, when there is one, is a single element.

# file stat

file stat name varName

Refused: it writes an array this frontend does not build for it.

Refused at run time: file stat is not supported yet: it needs an interface this frontend has not built

# file system

file system name

Refused: there is one filesystem here and no way to name another.

Refused at run time: file system is not supported yet: it needs an interface this frontend has not built

# file tail

file tail name

The last path component.

# file tempdir

file tempdir ?template?

Refused: it is built on the channel layer.

Refused at run time: file tempdir is not supported yet: it needs an interface this frontend has not built

# file tempfile

file tempfile ?nameVar? ?template?

Refused: it returns an open channel.

Refused at run time: file tempfile is not supported yet: it needs an interface this frontend has not built

# file tildeexpand

file tildeexpand name

The one command in Tcl 9 that expands a leading ~ or ~user.

# file type

file type name

file, directory, link, fifo, socket, blockSpecial or characterSpecial.

# file volumes

file volumes

Refused: there is no volume table here.

Refused at run time: file volumes is not supported yet: it needs an interface this frontend has not built

# file writable

file writable name

1 when the name can be written by this process.

The encoding ensemble

7 subcommands recognised · 7 implemented · 0 refused

An ensemble resolves its subcommand the way Tcl_GetIndexFromObj does — an exact match, else a prefix that fits exactly one entry — so this chapter carries the names the frontend recognises, which is what decides whether an abbreviation is ambiguous. Recognising a name is not implementing it. Each entry says what the subcommand does in the language; an entry the runtime refused says so, in the frontend's own words, after the description. The refusal is deferred rather than raised while compiling, so an unexecuted one costs nothing and a catch can trap it.

# encoding convertfrom

encoding convertfrom ?-profile profile? ?-failindex var? encoding data

A byte string in some encoding, as a string. The profile decides what an invalid sequence becomes; strict is the default.

# encoding convertto

encoding convertto ?-profile profile? ?-failindex var? encoding data

A string as a byte string in some encoding. The profile decides what an unrepresentable character becomes.

# encoding dirs

encoding dirs ?dirList?

The encoding search path. Starts empty here: the tables are inside the binary, so there is no directory to search.

# encoding names

encoding names

Every encoding this frontend can convert with, sorted. What it lists, it converts.

# encoding profiles

encoding profiles

The error profiles: replace, strict and tcl8.

# encoding system

encoding system ?encoding?

The encoding used for system calls, utf-8 unless it is set to another.

# encoding user

encoding user

The encoding the user prefers, which off Windows is the system encoding.

The expr operators and operands

27 binary operators · 5 unary and ternary · 10 operand shapes

Precedence levels, loosest first, printed from the table the parser binds with. Unary + - ~ ! bind tighter than every level below, and the ternary ?: looser; ** is the one right-associative level. The string comparisons share a level with their numeric counterparts, as expr(n) specifies — so "a" eq "a" == 1 is 1. Tcl's integer arithmetic is its own rather than C's in most of these operators, and each entry says where.

leveloperatorsassociativity
11||left
10&&left
9|left
8^left
7&left
6== != eq ne in nileft
5<= >= < > lt gt le geleft
4<< >>left
3+ -left
2* / %left
1**right

# ||

a || b

Logical or over Tcl booleans, yielding 1 or 0. Short-circuits: a true left operand means the right is never evaluated, so 1 || [error x] is 1.

# &&

a && b

Logical and over Tcl booleans, yielding 1 or 0. Short-circuits the same way — 0 && [error x] is 0.

# |

a | b

Bitwise or. Integers are not a fixed width here: when either side has been promoted past 64 bits the operation is performed over an infinite two's-complement sign extension, so the sign of an arbitrarily large operand is respected rather than truncated.

# ^

a ^ b

Bitwise exclusive or, over the same infinite sign extension as |.

# &

a & b

Bitwise and, over the same infinite sign extension as |. -1 & 3 is 3, because -1 is all ones however far it is extended.

# ==

a == b

Equality that prefers a numeric reading and falls back to string comparison when either operand is not a number. 10 == "10.0" is 1 — both are numbers and both are ten — while "abc" == "abc" is 1 by string.

# !=

a != b

The negation of ==, with the same numeric-preferring rule. A NaN operand makes both false, so nan != nan is 1.

# eq

a eq b

String equality on the operands as written. No numeric reading is attempted, so 1.0 eq 1 is 0 where 1.0 == 1 is 1. A numeric literal carries its own spelling for exactly this comparison.

# ne

a ne b

String inequality — the negation of eq, and equally blind to numeric value.

# in

a in b

Whether the left operand equals one of the right operand's list elements, compared as strings. String equality is the whole rule, so 1 in {01} is 0.

# ni

a ni b

Whether the left operand is not one of the right's list elements — the negation of in, with the same string rule.

# <=

a <= b

Less-or-equal, preferring a numeric reading and falling back to string order, like ==.

# >=

a >= b

Greater-or-equal, with the same numeric-preferring rule.

# <

a < b

Less-than, with the same numeric-preferring rule.

# >

a > b

Greater-than, with the same numeric-preferring rule. "abc" > "abd" is 0 by string order; inf > 1 is 1, because inf is a floating-point literal here and not a word.

# lt

a lt b

String less-than, never numeric: "10" lt "9" is 1 because 1 sorts before 9.

# gt

a gt b

String greater-than, never numeric.

# le

a le b

String less-or-equal, never numeric.

# ge

a ge b

String greater-or-equal, never numeric.

# <<

a << b

Left shift that grows rather than dropping the bits that leave a word: 1 << 64 is 18446744073709551616, not 0. A negative shift count is an error.

# >>

a >> b

Arithmetic right shift, and saturating rather than wrapping: 1 >> 200 is 0 and -1 >> 200 is -1, because the sign bit is what is left after every value bit has been shifted out.

# +

a + b

Addition. Integer operands promote past 64 bits rather than wrapping, up to MAX_INT_BITS; a floating-point operand makes the result floating-point.

# -

a - b

Subtraction, with the same promotion rule as +.

# *

a * b

Multiplication, with the same promotion rule as +.

# /

a / b

Integer division flooring toward negative infinity, not truncating toward zero as C does: -57 / 10 is -6 and 7 / -2 is -4. Division by zero is an error.

# %

a % b

The remainder that pairs with Tcl's flooring division, so it takes the sign of the divisor: -57 % 10 is 3, 5 % -3 is -1 and -5 % 3 is 1.

# **

a ** b

Exponentiation — the one right-associative level, so 2 ** 3 ** 2 is 512. Integral for integral operands including a negative exponent, which floors: 2 ** -1 is 0. 0 ** -1 is exponentiation of zero by negative power.

# -

- a

Arithmetic negation. Unary operators bind tighter than every binary level and are parsed right to left, so - - 1 is 1.

# +

+ a

Unary plus. It asserts that the operand is a number — a non-numeric operand is an error — and otherwise changes nothing.

# ~

~ a

Bitwise complement over the infinite two's-complement sign extension, so ~5 is -6. A floating-point operand is an error.

# !

! a

Logical not over a Tcl boolean, yielding 1 or 0 — !yes is 0. Matched only when the next character is not =, so != is still the inequality operator.

# ?:

test ? a : b

The conditional. It binds looser than every binary operator, is right-associative, and evaluates only the arm it takes — the other arm's command substitutions never run.

# integer literal

123   0xff   0o17   0b101   0d19   1_000_000

An integer, in decimal or with a 0x, 0o, 0b or 0d radix prefix. _ may separate digits but must have one on each side, so 1_000_000 is a million while 0x_10 and 1_ are not numbers at all and are read as barewords.

# floating-point literal

1.5   1.5e3   .5

A double, in the usual C spellings. A literal carries the text the script wrote as well as its value, so expr {007.0} prints 007.0 rather than 7.0.

# inf / nan

inf   infinity   nan

Floating-point literals in any case, not function names — expr {inf > 1} is 1 and expr {nan == nan} is 0. Exactly these three words and no others, and each keeps its spelling, so inf eq "Inf" is 0.

# boolean word

true   false   yes   no   on   off

A unique, case-insensitive prefix of one of the six words. t, fals, y, n and of are booleans; o is not, because on and off both begin with it. The word is an operand carrying its own spelling — expr {ON} is ON — so eq compares text and arithmetic refuses it with tclsh's non-numeric wording.

# variable

$name   $arr(index)

The variable's value, or an array element's. The index is itself substituted, so $arr($i) works.

# command substitution

[script]

The result of running the script, as an operand. Inside a short-circuited &&, || or ?: arm it is never run.

# quoted string

"text"

A double-quoted operand with the usual substitutions performed inside it — variables, command substitutions and backslash escapes.

# braced string

{text}

A braced operand taken literally: nothing inside it is substituted. "a" eq {a} is 1 because both produce the one character.

# grouping

( expression )

Parentheses override precedence. Nesting is bounded by MAX_EXPR_DEPTH, past which the expression is refused rather than overflowing the stack.

# function call

name(arg, ...)

Parsed as a call and then refused: math function "sin" is not supported yet. The refusal is deferred, so an unevaluated call — in a short-circuited arm, or an untaken branch — costs nothing and a catch can trap it.

string is classes

22 entries

Resolved while compiling, in the interpreter's own listing order, and checked left to right so a decision reached early is still a decision. The classes that rest on Unicode general-category tables accept ASCII — where the two implementations were verified to agree exactly — and raise on the 4804 code points tclsh 9.0.4 categorises and Unicode 16.0 does not, rather than answering from a different Unicode revision than the reference interpreter's. Every class but list and dict answers 1 for the empty string unless -strict is given.

# alnum

string is alnum ?-strict? ?-failindex var? str

Every character is a letter or a decimal digit — the Unicode letter categories plus Nd.

# alpha

string is alpha ?-strict? ?-failindex var? str

Every character is a letter: Lu, Ll, Lt, Lm or Lo. This is the general category union Tcl uses, not Rust's char::is_alphabetic, which is the wider Alphabetic property.

# ascii

string is ascii ?-strict? ?-failindex var? str

Every character is below U+0080. Answered arithmetically, so it never needs the Unicode tables and never refuses.

# control

string is control ?-strict? ?-failindex var? str

Every character is in category Cc or Cf — the C0/C1 controls and the format characters.

# boolean

string is boolean ?-strict? ?-failindex var? str

The whole string is a Tcl boolean: a number in any radix, or a unique case-insensitive prefix of true/false/yes/no/on/off.

# dict

string is dict ?-strict? ?-failindex var? str

Structural rather than a character class: the string is a well-formed list with an even number of elements. {a 1 b} is 0 and {} is 1. -strict is ignored, as it is for list.

# digit

string is digit ?-strict? ?-failindex var? str

Every character is in category Nd. This is any Unicode decimal digit, not only 09.

# double

string is double ?-strict? ?-failindex var? str

The string, less surrounding ASCII whitespace, reads as a floating-point number — integers included, since every integer is a valid double.

# entier

string is entier ?-strict? ?-failindex var? str

The string reads as an integer of any size, with no upper bound: 99999999999999999999 is 1. Identical to integer here, which is also unbounded.

# false

string is false ?-strict? ?-failindex var? str

The string is a Tcl boolean and that boolean is false — 0, no, off, false and their prefixes.

# graph

string is graph ?-strict? ?-failindex var? str

Every character is printable and not a space: word characters, punctuation, marks, the non-decimal numbers and the symbol categories. string is graph "€" is 1 where string is punct "€" is 0, because the currency symbols are here and not there.

# integer

string is integer ?-strict? ?-failindex var? str

The string, less surrounding ASCII whitespace, reads as an integer in any radix — 0xff is 1. Unbounded, so it does not narrow to 32 bits the way the reference interpreter's documentation describes.

# list

string is list ?-strict? ?-failindex var? str

The string parses as a well-formed Tcl list — the test is whether the list splitter accepts it, so unbalanced braces are 0. -strict is ignored: the empty string is a well-formed list.

# lower

string is lower ?-strict? ?-failindex var? str

Every character is in category Ll. Title-case letters are not lower case.

# print

string is print ?-strict? ?-failindex var? str

graph plus the three Unicode separator categories — and not plus the ASCII control whitespace, so string is print \t is 0 while string is space \t is 1.

# punct

string is punct ?-strict? ?-failindex var? str

Every character is in one of the seven punctuation categories. The symbol categories are deliberately excluded; they belong to graph.

# space

string is space ?-strict? ?-failindex var? str

Every character is Tcl whitespace: the six ASCII space characters below U+0080, then the Unicode whitespace plus U+180E, U+200B, U+2060 and U+FEFF. Verified equal to the reference interpreter over every code point up to U+2FFFF, and answered without the general-category tables so it never refuses.

# true

string is true ?-strict? ?-failindex var? str

The string is a Tcl boolean and that boolean is true — 1, yes, on, true and their prefixes.

# upper

string is upper ?-strict? ?-failindex var? str

Every character is in category Lu. Title-case letters are not upper case.

# wideinteger

string is wideinteger ?-strict? ?-failindex var? str

The string reads as an integer and fits in 64 bits. This is the one integer class with a bound, so 99999999999999999999 is 0 here and 1 for integer and entier.

# wordchar

string is wordchar ?-strict? ?-failindex var? str

Every character is a letter, a decimal digit, or connector punctuation — which is what makes _ a word character.

# xdigit

string is xdigit ?-strict? ?-failindex var? str

Every character is an ASCII hexadecimal digit, either case. Answered without the general-category tables, so it never refuses.

format conversions

17 conversions · 17 implemented · 8 size modifiers

Each conversion below was established by running one of it through the runtime and reading the answer. A letter missing from this chapter is bad field specifier. Width and precision both accept *, consuming an argument; a negative width sets - and negates. Justification follows tclsh 9.0.4 rather than C99, which means - does not override 0 for an integer (%-08d 42 is 00000042) but does for everything else (%-08.2f 42 is 42.00   ).

# %s

format %s value

The argument as a string. A precision truncates it to that many characters, not bytes — format %.3s abcdef is abc.

# %c

format %c codepoint

The character with that code point — format %c 65 is A. A number that is not a code point yields U+FFFD rather than an error.

# %d

format %d integer

A signed decimal integer, truncated to the size modifier's width (32 bits by default). # prefixes 0d, which is Tcl's spelling and not C's.

# %i

format %i integer

Identical to %d in every respect; both are signed decimal.

# %u

format %u integer

An unsigned decimal integer. The value is reinterpreted at the size modifier's width, so format %u -1 is 4294967295 at the default 32 bits. An untruncated width (ll or L) is unsigned bignum format is invalid, because there is no width to reinterpret at.

# %o

format %o integer

Unsigned octal. # prefixes 0o — Tcl 9's spelling, where C writes a bare leading 0.

# %x

format %x integer

Unsigned hexadecimal in lower case. # prefixes 0x.

# %X

format %X integer

Unsigned hexadecimal in upper case. The # prefix stays lower-case 0x, matching the reference interpreter rather than C's 0X.

# %b

format %b integer

Unsigned binary. # prefixes 0b. Tcl has this conversion and C does not.

# %p

format %p integer

Hexadecimal over the whole 64-bit word, always prefixed: format %p -1 is 0xffffffffffffffff where %#x -1 is 0xffffffff, and format %p 0 is 0x0 where %#x 0 is 0. Those two differences are the whole of it.

# %e

format %e double

Scientific notation with a lower-case e and a two-digit exponent; six digits of precision by default.

# %E

format %E double

%e with an upper-case E in the exponent.

# %f

format %f double

Fixed-point notation, six digits after the point by default. %.f with no digits is precision 0.

# %g

format %g double

The shorter of %e and %f for the value, with trailing zeroes removed.

# %G

format %G double

%g with an upper-case E when it chooses the exponential form.

# %a

format %a double

C99's hexadecimal floating-point form. Recognised and refused — the "%a" conversion is not supported yet — rather than being reported as a bad field specifier, so the message distinguishes a conversion that exists from one that does not.

# %A

format %A double

The upper-case spelling of %a, refused with the same message.

Size modifiers

Consumed between the field and the conversion character. Only the integer conversions read the width; a modifier with nothing after it is format string ended in middle of field specifier.

# ll

format %lld integer

No truncation and no reinterpretation: even the unsigned conversions keep the value's sign, so format %llx -1 is -1 where %lx -1 is ffffffffffffffff. Tested before the single-letter modifiers, so ll never reads as two ls.

# h

format %hd integer

Truncate to 16 bits before converting.

# l

format %ld integer

Truncate to 64 bits before converting, and reinterpret rather than keep the sign for an unsigned conversion: format %lx -1 is ffffffffffffffff.

# j

format %jd integer

C's intmax_t width — 64 bits here, the same as l.

# q

format %qd integer

The BSD quad width — 64 bits, the same as l.

# z

format %zd integer

C's size_t width. 64 bits on every target this crate builds for.

# t

format %td integer

C's ptrdiff_t width. 64 bits, like z.

# L

format %Ld integer

No truncation, identical to ll. With %u it is an error — unsigned bignum format is invalid — because an unsigned conversion has no width to reinterpret at.