100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Namespaces in Tcl

How Tcl's namespace command organizes procedures and variables into separate scopes to avoid naming collisions in larger programs.

Advanced TclIntermediate8 min readJul 10, 2026
Analogies

Organizing Code with Namespaces

As a Tcl program grows past a single script, procedure and variable names inevitably start to collide - two libraries both defining a proc called init or a variable called config. The namespace command solves this by creating a separate naming context, so namespace eval Db {proc init {} {...}} defines a procedure reachable as ::Db::init without touching any global init that might already exist. Namespaces can nest arbitrarily deep with :: as the separator, mirroring how a filesystem path separates directories, and every namespace has its own variable table distinct from the global scope.

🏏

Cricket analogy: Namespaces preventing name collisions are like two different domestic leagues both having a team called 'Strikers' - the full names 'Mumbai Strikers' and 'Melbourne Strikers' disambiguate them just as ::Db::init differs from ::Ui::init.

Defining and Accessing Namespace Contents

namespace eval Db { variable connCount 0; proc init {} { variable connCount; incr connCount } } creates both a namespace variable and a procedure inside it in one call; from outside, the procedure is invoked as Db::init (Tcl resolves the leading :: implicitly if the namespace already exists) and the variable is read with set ::Db::connCount or, from another proc inside the same namespace, with variable connCount to import it into local scope. namespace export and namespace import let one namespace selectively expose specific procedure names to another, avoiding the need to always type the fully qualified path.

🏏

Cricket analogy: namespace export selectively exposing procedure names is like a franchise releasing only its official injury-list update to the media while keeping internal training-ground notes private.

tcl
namespace eval ::Db {
    variable connCount 0
    namespace export connect init

    proc init {} {
        variable connCount
        set connCount 0
        puts "Db initialized"
    }

    proc connect {name} {
        variable connCount
        incr connCount
        puts "connected to $name (total: $connCount)"
    }
}

Db::init
Db::connect "primary"
Db::connect "replica"

# Selectively bring exported commands into the current namespace
namespace import ::Db::connect
connect "analytics"

Ensembles and namespace current

namespace ensemble create turns a namespace into a single dispatch command, so instead of calling Db::connect and Db::init separately, callers can write db connect ... and db init ... through one unified command name, similar to how the built-in string or dict commands dispatch to subcommands. Inside any procedure, namespace current returns the fully qualified name of the namespace it's executing in, which is useful for self-referential logic like registering a callback that must call back into the same namespace regardless of where it was originally invoked from.

🏏

Cricket analogy: namespace ensemble create unifying connect and init under one 'db' command is like a stadium's single help desk routing ticketing, catering, and parking queries instead of forcing fans to find three separate counters.

Because Tcl's variable command inside a proc only creates a local alias to a namespace variable - it doesn't copy its value - two procs in the same namespace that both call 'variable connCount' are reading and writing the exact same underlying storage, just like two global-scope references to the same variable.

namespace eval always executes its body in the target namespace's context, but a nested proc's own local variables still require an explicit 'variable' declaration to reach namespace-scoped variables - simply referencing $connCount inside a proc without declaring it first will resolve to an undefined local variable, not the namespace one, and raise an error.

  • namespace eval creates an isolated scope for procedures and variables, avoiding global name collisions.
  • :: separates nested namespace levels, similar to a filesystem path.
  • Fully qualified names like ::Db::init unambiguously reference a specific namespace's contents.
  • namespace export and namespace import selectively expose commands between namespaces.
  • The variable command inside a proc creates a local alias to the same underlying namespace storage.
  • namespace ensemble create groups related procedures under one dispatching command name.
  • namespace current returns the fully qualified name of the namespace currently executing.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#TclTkStudyNotes#NamespacesInTcl#Namespaces#Tcl#Organizing#Code#StudyNotes#SkillVeris#ExamPrep