Python is that kind of cool one behaves when visiting parents of your would be spouse for the first time. Tcl on the other hand is like playing one's secret exclusive and somewhat dangerous games with kid school bestie.
Tcl/Tk pioneered the notion of a scripting language as a library. It got threading right. You can run multiple independent Tcl interpreters in the address space of your process and they can exchange messages. Entirety of interpreter state is encapsulated inside the interpreter object, no globals. To a user an it is just a pointer to an object.
No need for GIL, no need for serialization/deserialization (pickle/unpickle) ... just within process memory copy (or no copies in case data is immutable).
Tcl itself was quite clever as what I'd actually call a string-based scripting language (contrast with Bourne/C-shell/etc. that preceded it on Unix).
Originally, Tcl was among the handful of off-the-shelf extension languages. You write your big application in C or C++, and then you embed an interpreter for a higher-level extension language, for users or the original developer to add on functionality. The options at the time were usually a small Lisp/Scheme, Tcl, Python, or something entirely bespoke and probably quirky and half-butted.
During early dotcoms, there was considerable interest in Tcl for backend work, and it also wouldn't have been the worst choice to put into the browser. Like Python, Tcl would've been more accessible and democratizing-the-Web than JavaScript, and there were already solid off-the-shelf designs and implementations. (Scheme would've appeared slightly more intimidating than Python or Tcl, and was more powerful, which I think was why Tim Berners-Lee preferred Python over Scheme as the people's programming language for various Web purpose. The semantics of the JavaScript we got was more a hurried toy Scheme, plus the simplest object model, and a more intimidating syntax that came from systems programming.)
Didn't Cisco use Tcl in one of their IOSes? Found it: https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ios_tcl/co...
From D. Richard Hipp [1]:
"SQLite is a TCL extension that has escaped into the wild.
"The design of SQLite was inspired by the design of TCL, both in the way it handles datatypes and in the formatting of its source code. The index use case for SQLite was in a Tcl/Tk application for an industrial company. From its inception, SQLite has always depended heavily on TCL. These days, SQLite no longer uses TCL internally and can be run separately from any TCL interpreter, and yet the SQLite development process still depends heavily on TCL."
[1] https://www.tcl-lang.org/community/tcl2017/assets/talk93/Pap...
Good to see it's getting some modern support.
https://blog.gbacon.com/publications/2000-perl-journal-tktk/
Kudo’s to Mr Osterhout’s long lived legacy
Tcl and Tk are fantastic, and if this is where it ended, John Ousterhout would have secured his place in history - this is only 1 piece of his contributions, though - see too:
* Log structured file system[0]
* parallel Make[1] (Adam de Boor from Sprite project, not JO hisself)
* RAFT consensus protocol[2]
* Various notable teachings [3][4][5]
[0] https://en.wikipedia.org/wiki/Log-structured_file_system[1] https://man.freebsd.org/cgi/man.cgi?query=bmake&sektion=1
[2] https://en.wikipedia.org/wiki/Raft_(algorithm)
[3] https://en.wikipedia.org/wiki/Ousterhout's_dichotomy
[4] https://web.stanford.edu/~ouster/cgi-bin/papers/threads.pdf
But I think the Sprite kernel and the Sprite-specific libraries (Pfs, Pdev, Fs_Select, Td_), as well as the Sprite-specific userspace, were pretty incredibly pieces of software given the limited resources they were created with.
For that matter, John Ousterhout's text editor and terminal emulator, mx and tx, were the substratum that Tcl was built on. There's a single library on Sprite, libmx, which mx and tx are based on. Tcl basically grew as the command language of libmx, originally two separate entities, then by mx 2.4 it was fully incorporated:
eery@cherimoya [1] > cd /sprite/src/lib/mx
eery@cherimoya [4] > grep Tcl *.c
mxCmdAM.c: Tcl_Interp *interp;
mxCmdAM.c: Tcl_Return(interp, Cmd_BindingGet(mxwPtr->cmdTable, argv[1]),
mxCmdAM.c: interp->result = Tcl_Merge(bindingCount, bindings);
mxCmdAM.c: Tcl_Interp *interp;
[...]
eery@cherimoya [10] > grep LIBS ../../cmds/mx/local.mk
LIBS = -lc -lmx -lsx -lcmd -ltcl -lX11
Of course, even by 1992, there were multiple versions of Tcl coexisting... :-) eery@cherimoya [11] > ls /sprite/lib/sun4.md | grep tcl
libtcl.a
libtcl5.a
libtcl6.2.a
libtcl6.3.aThis is partially because when Tcl was first incorporated in VLSI tools it didn't have a good way to organize and modularize code. But this is also because the big VLSI tool shops realize they basically have a monopoly on their integration surface and have no incentive to improve it.
It's easier to freeze the integration surface and maintain backward compatibility than it is to move the surface forward.
https://newsgrouper.org/%3C119gpah$3eu5q$1@dont-email.me%3E (Tcl) and
https://newsgrouper.org/%3C119gpbh$3eu5q$2@dont-email.me%3E (Tk).
If you understand how generative models and agentic coding works, it's not a surprise. But for some reason it's still mind boggling to think that you can take very old stuff and build impressive programs.