List of Tcl commands by bytecode status

This page is driven mostly by the 8.6 manual build .

Note that some commands may be listed with a **** against them. That is because they are present in multiple categories; they are ensembles (and related) and have partial compilations.

Already bytecoded

On the trunk

append
array ****
    array exists
    array unset
    array set
break
catch
concat
continue
dict ****
    dict append
    dict create
    dict exists
    dict for
    dict get
    dict incr
    dict lappend
    dict map
    dict merge
    dict set
    dict unset
    dict update
    dict with
error
eval
expr
for
foreach
format
global
if
incr
info ****
    info commands
    info coroutine
    info exists
    info level
    info object ****
        info object class
        info object namespace
lappend
lassign
lindex
linsert
list
llength
lmap
lrange
lreplace
lset
namespace ****
    namespace code
    namespace current
    namespace origin
    namespace qualifiers
    namespace tail
    namespace upvar
    namespace which
next
nextto
regexp
regsub
return
self ****
    self namespace
    self object
set
string ****
    string compare
    string equal
    string first
    string index
    string is
        alnum
        alpha
        ascii
        boolean
        control
        digit
        double
        entier
        false
        graph
        integer
        list
        lower
        print
        punct
        space
        true
        upper
        wideinteger
        wordchar
        xdigit
    string last
    string length
    string map
    string match
    string range
    string replace
    string tolower
    string totitle
    string toupper
    string trim
    string trimleft
    string trimright
subst
switch
tailcall
tcl::mathop
    tcl::mathop::!
    tcl::mathop::!=
    tcl::mathop::%
    tcl::mathop::&
    tcl::mathop::*
    tcl::mathop::**
    tcl::mathop::+
    tcl::mathop::-
    tcl::mathop::/
    tcl::mathop::<
    tcl::mathop::<<
    tcl::mathop::<=
    tcl::mathop::==
    tcl::mathop::>
    tcl::mathop::>=
    tcl::mathop::>>
    tcl::mathop::^
    tcl::mathop::eq
    tcl::mathop::in
    tcl::mathop::ne
    tcl::mathop::ni
    tcl::mathop::|
    tcl::mathop::~
throw
try
unset
unsupported ****
    tcl::unsupported::assemble
upvar
variable
while
yield
yieldto

On a dev branch

These are only done on the dkf-compile-misc-info branch. (Currently none; branch was merged to trunk but remains as base for further work)

AMG: lmap?

DKF: Yes, indeed (and dict map too)! See TIP #405 for the details; the code was committed on Oct 18. More to the point, some commands (info coroutine, info level, namespace current and self object) aren't yet BCCed on the trunk.

I chose to do those four because they're things that are relatively accessible to the bytecode engine.

AMG: I'm glad to see [info coroutine], which is performance-critical to Wibble. You may have noticed SEH's contributions to the Wibble implementation, mostly driven by performance. One thing he did was try to cache [info coroutine] in a variable. It seems to me an optimized [info coroutine] ought to take less time than reading a variable.

DKF: Don't get your hopes up too much; reading a local variable whose name is known at compile time is exceptionally fast (assuming it is untraced).

Potential candidates for bytecoding

Note that there is no consideration of whether these should be bytecoded; with many of them, it might well be a very bad idea for other reasons (e.g., costly internal algorithms).

(Note also that anything marked with !!! is ultra-unlikely to be done, on the grounds that it is rare in real code.)

array ****
    array get
    array names
    array size
binary
    binary decode
    binary encode
    binary format
    binary scan
dict ****
    dict filter
    dict keys
    dict remove
    dict replace
    dict size
    dict values
info ****
    info args
    info body
    info class
        info class call
        info class constructor
        info class definition
        info class destructor
        info class filters
        info class forward
        info class instances
        info class methods
        info class methodtype
        info class mixins
        info class subclasses
        info class superclasses
        info class variables
    info complete
    info default
    info errorstack
    info frame
    info globals
    info locals
    info object ****
        info object call
        info object definition
        info object filters
        info object forward
        info object isa ****
            info object isa class
            info object isa metaclass
            info object isa mixin
            info object isa typeof
        info object methods
        info object methodtype
        info object mixins
        info object variables
        info object vars
    info patchlevel
    info procs
    info script
    info vars
join
lrepeat
lreverse
lsearch
lsort
mathfunc
namespace ****
    namespace children
    namespace delete
    namespace ensemble ****
        namespace ensemble configure
        namespace ensemble exists
    namespace eval
    namespace exists
    namespace export
    namespace forget
    namespace import
    namespace inscope
    namespace parent
    namespace path
    namespace unknown
scan
self ****
    self call
    self caller   !!!
    self class
    self filter   !!!
    self method   !!!
    self next     !!!
    self target   !!!
split
string ****
    string repeat
    string reverse
    string wordend      !!!
    string wordstart    !!!
tcl::prefix
    tcl::prefix all
    tcl::prefix longest
    tcl::prefix match
time
uplevel

DKF: I'm guessing that next, tailcall, yield and yieldto would be good candidates. Maybe also some variants of array unset (those that can be based on the existing unset machinery) and some more dict subcommands. We also ought to be able to do namespace code, though I'm not sure how much of a win that is. Maybe some cases of string is could be done too, though I'm not convinced that would be a net win. uplevel would be good, but I'm really uncertain about how to do it (except in the uplevel 0 case, which is rather low-value). Also, self namespace can probably be done, and if we were to do string map we might also be able to handle some regsub cases (which would definitely benefit some users' code). We can also probably handle some format cases (e.g., “all literals” and “only %s used in format string”).

DKF: Turns out to be impossible to do array unset; you get a difference in the trace behavior which you can't work around. Unless I was to add in a special instruction for doing just that particular thing (a “synch the array entries” trace)… Hmm…

DKF: It also seems that join is quicker if not bytecoded (with generic instructions). It gains more from being able to do low-level buffer access than from avoiding leaving TEBC, and we'd have to just wholly code it directly as new bytecodes to benefit.

AMG: I'd like to see [time] be optimized so I don't have to wrap everything I'm timing in a proc. That's probably not the same thing as bytecoding it, though. I imagine bytecoding [time] would entail adding opcodes to start and end timing, along with a stack mechanism to keep track of iteration counts and nested invocations of time. I'd be inclined to say that's too much of a hassle, but it would be nice to have an efficient fixed count loop mechanism. [for] is an awfully big, slow, and unwieldy, and [while] with [incr $count -1] is faster except for the need to either devise preincrement (while {"$count[incr count -1; list]"} {...}) or toss in an extra [incr count] before starting the loop (for {incr count} {[incr count -1]} {} {...}). How clumsy.

Filtered Candidates

dict keysMaybe; a trivial extension from dict for, which is done.
dict valuesMaybe; a trivial extension from dict for, which is done.

AMG: Regarding [uplevel 0]: I think the major use case for this command went away when we fixed/broke the nested array bug/feature. I recently used [uplevel 0] because I had a bunch of commands operating on a variable name that resulted from several substitutions I got tired of typing all the time, but I later redesigned the code to avoid it.

AMG: Update! Oops, I meant to say [upvar 0], which isn't relevant to your discussion anyway. Sorry!

Commands that will never be bytecoded

Low-level details/internals

These are commands that access information that is probably not best used in production systems, or do things that are largely obsolete.

DKF: I know my assertion that info tclversion is obsolete is somewhat controversial, but info patchlevel has been useful for much longer, and package's relationship to the Tcl package is probably more relevant anyway.

OS connectivity, script library

These are commands where the dominant performance factors are the OS, or they are deliberately kept as scripted commands. In either case, there's no real benefit to bytecoding (there are better choices of place to put effort).

after
    after <ms>
    after cancel
    after idle
    after info
auto_execok
auto_import
auto_load
auto_mkindex
auto_path
auto_qualify
auto_reset
bgerror
cd
chan
    chan blocked
    chan close
    chan configure
    chan copy
    chan create
    chan eof
    chan event
    chan flush
    chan gets
    chan names
    chan pending
    chan pipe
    chan pop
    chan postevent
    chan push
    chan puts
    chan read
    chan seek
    chan tell
    chan truncate
clock
    clock add
    clock clicks
    clock format
    clock microseconds
    clock milliseconds
    clock scan
    clock seconds
close
dde
    dde eval
    dde execute
    dde poke
    dde request
    dde servername
    dde services
encoding
    encoding convertfrom
    encoding convertto
    encoding dirs
    encoding names
eof
exec
exit
fblocked
fconfigure
fcopy
file
    file atime
    file attributes
    file channels
    file copy
    file delete
    file dirname
    file executable
    file exists
    file extension
    file isdirectory
    file isfile
    file join
    file link
    file lstat
    file mkdir
    file mtime
    file nativename
    file normalize
    file owned
    file pathtype
    file readable
    file readlink
    file rename
    file rootname
    file separator
    file size
    file split
    file stat
    file system
    file tail
    file tempfile
    file type
    file volumes
    file writable
fileevent
flush
gets
glob
history
    history add
    history change
    history clear
    history event
    history info
    history keep
    history nextid
    history redo
http
    http::cleanup
    http::code
    http::config
    http::data
    http::error
    http::formatQuery
    http::geturl
    http::meta
    http::ncode
    http::register
    http::reset
    http::size
    http::status
    http::unregister
    http::wait
info ****
    info hostname
    info library
    info loaded
    info nameofexecutable
    info sharedlibextension
interp ****
    interp aliases
    interp bgerror
    interp cancel
    interp debug
    interp eval
    interp exists
    interp hidden
    interp invokehidden
    interp issafe
    interp limit
    interp marktrusted
    interp recursionlimit
    interp share
    interp slaves
    interp target
    interp transfer
load
msgcat
    msgcat::mc
    msgcat::mcflmset
    msgcat::mcflset
    msgcat::mcload
    msgcat::mclocale
    msgcat::mcmax
    msgcat::mcmset
    msgcat::mcpreferences
    msgcat::mcset
    msgcat::mcunknown
open
package
    package forget
    package ifneeded
    package names
    package prefer
    package present
    package provide
    package require
    package require
    package unknown
    package vcompare
    package versions
    package vsatisfies
parray
pid
pkg::create
pkg_mkIndex
platform
    platform::generic
    platform::identify
    platform::patterns
platform::shell
    platform::shell::generic
    platform::shell::identify
    platform::shell::platform
puts
pwd
read
registry
    registry broadcast
    registry delete
    registry get
    registry keys
    registry set
    registry type
    registry values
safe ****
    safe::interpAddToAccessPath
    safe::interpConfigure
    safe::interpDelete
    safe::interpFindInAccessPath
    safe::interpInit
    safe::setLogCmd
seek
socket
source
tcl_endOfWord
tcl_findLibrary
tcl_startOfNextWord
tcl_startOfPreviousWord
tcl_wordBreakAfter
tcl_wordBreakBefore
tcltest
    tcltest::bytestring
    tcltest::cleanupTests
    tcltest::configure
    tcltest::customMatch
    tcltest::debug
    tcltest::errorChannel
    tcltest::errorFile
    tcltest::interpreter
    tcltest::limitConstraints
    tcltest::loadFile
    tcltest::loadScript
    tcltest::loadTestedCommands
    tcltest::makeDirectory
    tcltest::makeFile
    tcltest::match
    tcltest::matchDirectories
    tcltest::matchFiles
    tcltest::normalizeMsg
    tcltest::normalizePath
    tcltest::outputChannel
    tcltest::outputFile
    tcltest::preserveCore
    tcltest::removeDirectory
    tcltest::removeFile
    tcltest::runAllTests
    tcltest::singleProcess
    tcltest::skip
    tcltest::skipDirectories
    tcltest::skipFiles
    tcltest::temporaryDirectory
    tcltest::test
    tcltest::testConstraint
    tcltest::testsDirectory
    tcltest::verbose
    tcltest::viewFile
    tcltest::workingDirectory
tell
tm
    tcl::tm::path
    tcl::tm::roots
trace
    trace add
    trace info
    trace remove
    trace variable
    trace vdelete
    trace vinfo
unknown
unload
update
vwait
zlib
    zlib adler32
    zlib compress
    zlib crc32
    zlib decompress
    zlib deflate
    zlib gunzip
    zlib gzip
    zlib inflate
    zlib push
    zlib stream

Command creation and related

These create commands and do related tricks; they mostly benefit a lot from bytecoding, but there's little value in boosting them themselves. (Though rename is a special case in that it is possible to sensibly bytecode it, but it is much more likely to trigger a progressive recompile than nearly any other command.)

Not actually commands

These have manpage links, but aren't commands as such.

Tcl
argc
argv
argv0
env
errorCode
errorInfo
filename
re_syntax
refchan
tcl_interactive
tcl_library
tcl_nonwordchars
tcl_patchLevel
tcl_pkgPath
tcl_platform
tcl_precision
tcl_rcFileName
tcl_traceCompile
tcl_traceEval
tcl_version
tcl_wordchars
transchan