Schrödinger’s Tcl – Values that differ if you look at them
github.com
github.com
Having spent my life in networking tech, Tcl...please die.
TCL is an unreasonably effective language for certain use cases (the company we worked for were driven by extremely tight deadlines and high performance requirements (appserver written in pure C in late 90s, with call-outs to TCL for business logic).
I haven't touched TCL since, though.
Let's say you want to process a list of numbers, a set of data records, or something fairly complex. Internally, you can pass it between functions in a fairly compact, but almost illegible form. If a human user wants to see what's getting passed around, though, it could be handy if the system could automatically transform it to smoothing more human readable: tabulated, indented, pretty-printed, what-have-you.
I could definitely see a use for this, strange as it might seem.
http://search.cpan.org/~dconway/Quantum-Superpositions-1.03/...
http://alquerubim.blogspot.com.br/2011/10/quantum-countdown-...
This is somewhat interesting. You can't use frames to differentiate between puts [schro] and schro, as they're both in the same frame. In fact, in the general case for a programming language, this is impossible - it would depend on using an oracle to predict what's going to happen to the value you return.
Happily, in Tcl we can cheat! There are three vital points - 1. Tcl compiles lines passed into the repl to bytecode, 2. Tcl bytecode is a stack machine and 3. Tcl has a pointer to the current execution location in the bytecode (note that point 1 only became true in Tcl 8.6 (I believe) so this code won't work before then).Python may well be able to do it with just the stdlib since it has excellent debugging capabilities, but Tcl is relatively weak. You might be able to do something with `tcl::unsupported::getbytecode` and checking the frame level, but this was just a throw-away novelty so I'm not particularly motivated to find out.
Like overriding a built-in type and getting function.caller into valueOf(). As far as I can tell, JS doesn't let you just tweak valueOf(), you would have to re-implement all of, for example, the String class.
Luckily console.log calls are actually excluded from the callers stack, so the only way is to change console itself. Just as evil if you also intercept console methods logging and return the original ones, but less of a mess at least.
The last app I built like this was a graphical front-end for joining PDF files with Ghostscript (choose files, choose destination, press go).
Tcl is actually pretty decent as a language, very elegant in its utmost simplicity. I don't get the bashing here.
My main complaints against TCL basically center around the everything-is-a-string mentality and the corresponding lack of type safety anywhere.
A more minor objection is that I strongly dislike the syntax for numerous reasons, such as
- Comments aren't like any other language and have numerous gotchas, e.g., you can't use mismatched {}s in a comment within a proc,
- Whitespace is relevant in surprising ways, such as requiring Egyptian brackets for procs/ifs, and I constantly forget line continuations
- Using foo for lvalues but $foo for rvalues, while sensible, is a constant source of typos...
but, of course, you do get used to it. Mostly. But the comment thing really irks me.
I will certainly agree that you can do worse. TCL is surely a fine alternative to awful shell languages (bash, C shell, etc.)
But in the realm of dynamically typed scripting languages, I'd absolutely nominate Python or Ruby as a much more reasonable and sensible for your everyday programmer, and Lisp's S-expressions seem far more elegant if you insist on a unifying principle like everything-is-a-...
If you use it like, say, perl, then yes - some of the code looks horrible.
If you take a step back, really try to grok it, and then use it like a lisp (but for strings, rather than linked-lists), then its actually quite elegant (with sometimes messy indentation).
If you take another step back, glance sideways, look at every other unix shell, then look again at tcl's "undefined cmd" behaviour, the exec cmd, its inherent lispiness (see above) ...
... then you smack yourself on the head when you realise this is yet another defeat grasped from the jaws of victory.
Tcl should have replaced bash et al.
Especially so for jimtcl (a lightweight reimplementation of tcl, started by the redis author).
- The cross platform UI, Tk. Even if you didn't like Tcl, it was, for a while, one of very few open source ways to get a UI that worked on a variety of platforms. Many things, mostly the web, killed this need. Also, there are Tk bindings for other languages now.
- Dead simple, lightweight, way to embed a user facing scripting engine into your application. Especially when the end user might be "technical", but not a developer by trade. This is still a need, but it looks like people are turning to Lua, Javascript, etc. Tcl is still embedded in a lot of hardware devices though...cisco routers, F5 load balancers, etc.
Edit: Related trivia. TCL's inventor, John Ousterhout, was also one of the co-creators of the raft consensus algorithm.
I think ultimately we've come the conclusion that whole design space isn't that productive. Pervasive string expansion in an era of untrusted input probably killed it for the web before it even began.
However, these drag in the entire Tcl implementation as a dependency. IIRC some of the ttk widgets are written in Tcl, at least partially: https://github.com/tcltk/tk/blob/master/library/ttk/treeview...
It's a very ugly thing; I'd never drag this into a programming language as a prominent "this is the go-to way to do UI listed in FAQ #3" package.
You really want to confine a Tcl/Tk UI to its own process so all that string churning is happening in its own address space.
getters that change value... muahahaha
>>> from datetime import datetime
>>> x = lambda: f'{datetime.now()}'
>>> x
<function <lambda> at 0x7f9f435e4510>
>>> x()
'2017-09-17 02:14:12.834957'
>>> from sys import setrwatch
>>> setrwatch({id(x): lambda f, o: o()})
>>> x # look, ma: no parens!
'2017-09-17 02:14:16.306198'
>>> x
'2017-09-17 02:14:17.734965'Another common cause can be the difference between interactive and command modes for Tcl. When you start up a Tcl interpreter, get a prompt, and type in commands to Tcl, this is called interactive mode. In this mode, Tcl does a few extra things for you. For instance, if you type ls, and you have no proc called ls defined, Tcl will try to exec a command called ls. This sometimes misleads a new Tcl user into thinking that Tcl has ls defined." [1]