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.
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.
140/169
Ensemble subcommands
# 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 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 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.
| level | operators | associativity |
| 11 | || | left |
| 10 | && | left |
| 9 | | | left |
| 8 | ^ | left |
| 7 | & | left |
| 6 | == != eq ne in ni | left |
| 5 | <= >= < > lt gt le ge | left |
| 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 0–9.
# 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.