Updates for The Tcl Programming Language, 2017 https://wiki.tcl-lang.org/page/BOOK+The+Tcl+Programming+Language Page 19, middle of page, C:\temp>ftype TclApp=C:\Tcl\bin\tclsh.exe should be C:\temp>ftype TclApp=C:\Tcl\bin\tclsh.exe "%1" %* Page 27, Table 3.1 Always use either \uHHHH, or \UHHHHHHHH notation. Avoid using \OOO and \xHH. Page 45, bottom of page, before the line set list_of_ints {-1 5 -5 10 -5 -1000 100} alias 'abs' should be defined as interp alias {} abs {} ::tcl::mathfunc::abs OR procedure 'abs' should be defined as proc abs {v} {::tcl::mathfunc::abs $v} Using alias is a better solution here. OR namespace path ::tcl::mathfunc Page 61, bottom of page, values proscribed by EIAS should be values prescribed by EIAS Page 76, top of page. The word 'the' is repeated. ... unless the the -nocase option is specified. should be ... unless the -nocase option is specified. Page 83, Table 4.7 5th row, This includes 1, false, no ... should be ... includes 0, false ... Page 91, before Table 4.11 \B - backslash character (advanced reqular expressions, Tcl 8.1 and later) Page 97, bottom of page. In the code example, regexp {(?ic)RE} STRING should be regexp {(?in)RE} STRING Page 135, middle of page, before the line set downloads_by_month ... procedure '+' should be defined as proc + {args} {expr [join $args " + "]} OR proc + {args} {expr [join $args +]} OR namespace path ::tcl::mathop Page 162, bottom of page. The syntax description of dict for should be dict for {KEYVAR VALUEVAR} DICTIONARY SCRIPT Page 165, bottom of page. Before 'array set student_array $students'. set students {A001 {Name Jean Grades {Physics A- Maths B} Clubs {Chess Photography Archery} Age 18} A002 {Name Pedro Grades {Maths A Spanish A History B} Clubs {Music Athletics} Age 16} A004 {Name Mark Grades {Physics A}}} Page 297, bottom of page. The condition if {$i >= 4} ... should be if {$i >= 3}.... Page 298, top of page. if {$i == 2}... should be if {$i == 1}.... Page 298, middle of page. return code value 1 / return should be return code value 2 / return. Page 300, top of page. ...discussed is 2 or error...' should be ...discussed is 1 or error...''. Page 308, top of page. close $chan should be close $result. Page 312, middle of page. -errorstack ERRORSTACK? should be ?-errorstack ERRORSTACK?. Page 320, bottom of page. namespace syntax ?NAMESPACE? should be namespace children ?NAMESPACE? Page 355, in script towards bottom of page, variable geom_term_geom should be geom_term Page 355, bottom of page, either seq_arith or seq_geom should be either seq::arith_term or seq::geom_term Page 355, contents of pkgIndex.tcl should be namespace eval seq { proc setup_autoload {dir} { global auto_index foreach cmd {arith_term geom_term} { set auto_index([namespace current]::$cmd) [ list source [file join $dir seq_arith.tcl] ] } package provide sequences 1.0 } } package ifneeded sequences 1.0 [list ::seq::setup_autoload $dir] OR better package ifneeded sequences 1.0 [ list ::apply { {dir} { foreach cmd {arith_term geom_term} { set ::auto_index(::seq::$cmd) [ list source [file join $dir seq_arith.tcl] ] } package provide sequences 1.0 } } $dir ] THEN 'sequences' directory should be added to '$auto_path' lappend auto_path [file normalize sequences] package require sequences ::seq::arith_term 22 33 44 ::seq::geom_term 2 3 4 namespace eval ::seq {info procs} Page 362, in the script at the top of the page, platform::identity should be platform::identify Page 362, in the script at the top of the page, package ifneeded binpkg... should be package ifneeded $package_name.... Page 365, middle of page. The experience gained from these system ... should be The experience gained from these systems ... Page 378, last line of page. The line 'This facility is available to all savings accounts but only to selected checking accounts.' should be This facility is available to all checking accounts but only to selected savings accounts. Page 393, top of page. ... the command self class command returns ... should be the self class command .... Page 416, top of page. The << redirection works... should be The >> redirection works.... Page 450, middle of page, the sentence While a TclOO based implementation ... looks somewhat incomplete. Perhaps it might be: In contrast to a TclOO based implementation ... or While a TclOO based implementation ... provides an implicit per-channel context, a namespace based one does not maintain ... Page 451, 1st, 2nd and 3rd procs might be more bureaucratic according to the previous namespace eval ::bureaucrat ..., i.e. proc ::bureacrat ... should be: proc ::bureaucrat ... Page 601, top of page. The syntax block for foreach should be: RESULTSET foreach ?-as lists|dicts? ?-columnsvariable COLVAR? ?--? VAR SCRIPT STATEMENT foreach ?-as lists|dicts? ?-columnsvariable COLVAR? ?--? VAR ?DICT? SCRIPT DBCONN foreach ?-as lists|dicts? ?-columnsvariable COLVAR? ?--? VAR SQL ?DICT? SCRIPT Page 601, 602, bottom of page. ACCOUNTS should be: Accounts **************************************************************************************************************************** About 'global' command: https://wiki.tcl-lang.org/page/global For older versions of Tcl (before Tcl 8.6): Globals are expensive if you call them only a few times in the proc - the cost of the initial linking to a local variable weighs heavily; they are quite fast if you use them a lot. The breakeven seems to be around 15 reads. For fewer calls, use fully qualified variable names instead. Example: proc gen_random {max} { set last [expr {($::last * $::IA + $::IC) % $::IM}] expr {$max * $::last / $::IM} } For newer versions of Tcl (Tcl 8.6 and later): 'variable' is slightly faster than 'global', 'global' has the same speed as 'namespace upvar', 'namespace upvar' is noticeably faster than referencing by fully qualified name, even if the variable is used only once in a procedure, because 'variable' and 'global' are now byte-compiled. Example: set foo 123; set bar 456; set baz 789 proc va {} {variable foo; variable bar; variable baz; return [string cat $foo $bar $baz]} proc gl {} {global foo bar baz; return [string cat $foo $bar $baz]} proc ns {} {namespace upvar :: foo foo bar bar baz baz; return [string cat $foo $bar $baz]} proc fq {} {return [string cat $::foo $::bar $::baz]} clear; puts variable:\t[timerate va 60000]; puts global:\t\t[timerate gl 60000]; puts namespace\ upvar:[timerate ns 60000]; puts fqn:\t\t[timerate fq 60000]