
I can't believe I'm praising Tcl (2008) - panic
http://yosefk.com/blog/i-cant-believe-im-praising-tcl.html
======
jasomill
While I like Tcl, which I have used to write substantial portions of a
shipping product, the author does make a good point about the difficulty of
creating a language that is simultaneously a good programming language and a
good scripting language: I love IPython dearly, but I've never seriously
considered using it as a bash replacement (nor bash as a substitute for
anything but the simplest Python scripts).

As an aside, I have to praise one particular, easily overlooked aspect of Tcl:
its _comm_ facility is, from a (non-Tcl) client implementation perspective,
the easiest "foreign function interface"[1] I've ever worked with _by far_ ,
due almost entirely to the simplicity and consistency of Tcl syntax.

[1] Technically, _comm_ was designed as a remote execution facility, but it
works just as well locally to run Tcl code from within a non-Tcl program
without the hassle of embedding an interpreter.

~~~
kevin_thibedeau
Tcl is an aw some configuration language. Delete all the commands to make it
non-Turing complete. Throw in infix assignment for ergonomics and you have a
minimal configuration language that can be enhanced by adding back more
commands as needed.

~~~
unixhero
I think I get this. Would you have any code examples laying around?

~~~
sirn
MacPorts' Portfile[1], maybe? Portfile is being evaluated entirely within
interp[2] with only few functions exposed inside the environment

[1]: [https://github.com/macports/macports-
ports/blob/master/lang/...](https://github.com/macports/macports-
ports/blob/master/lang/lua/Portfile)

[2]:
[https://www.tcl.tk/man/tcl8.4/TclCmd/interp.htm](https://www.tcl.tk/man/tcl8.4/TclCmd/interp.htm)

~~~
unixhero
Very decent, that file from the Macports repo looks very clean and sane. Thank
you.

------
jmpman
Expect! I learned Tcl just for Expect. It’s one of those tools that takes you
from “I have no idea how to do this” to “this is trivial” in just an
afternoon.

~~~
thesuperbigfrog
Expect is such a useful tool, I am surprised that similar functionality is not
found in most scripting languages.

I use the Perl Expect.pm module
([https://metacpan.org/pod/release/RGIERSIG/Expect-1.15/Expect...](https://metacpan.org/pod/release/RGIERSIG/Expect-1.15/Expect.pod))
since I create and maintain a lot of Perl scripts. It combines the utility of
expect with the power of Perl regexes.

~~~
monday_
There is [1] a pure python package for expect. It provides essentially the
same interface and is incredibly useful.

[1]
[https://pexpect.readthedocs.io/en/stable/](https://pexpect.readthedocs.io/en/stable/)

------
rauhl
I recently dug up some old Tcl bindings in Go I wrote a few years ago for my
employer and used them for a new tool. It really does shine when it’s used
correctly. I like how easy it is to build a shell-like environment for the
whole application. In a lot of ways it feels like the POSIX shell environment
done right (and, yes, a few things — e.g. pipes — aren’t quite as good).

Although our tool itself is strictly in-house, when we get the time to give
them a quality-control once-over we would like to open-source the bindings.
Tcl and Go make a pretty good pair!

I would definitely reach for Tcl the next time I need to add a scripting
language to a static-language project.

------
ed25519FUUU
> _(ever noticed how the space bar is much easier to hit than a comma, you
> enlightened dynamic language devotee? Size does matter)._

This author makes so many good points about key ergonomics with languages. I’d
love to see more research into this, and the results being incorporated into
languages.

~~~
thesz
Hehe:
[http://www.cs.stir.ac.uk/~kjt/techreps/pdf/TR141.pdf](http://www.cs.stir.ac.uk/~kjt/techreps/pdf/TR141.pdf)

A paper that tries to compute Halstead language level for Haskell. It was so
high they had to change constants in the computation of Halstead volume (page
6 in the paper above). Basically, many spaces in Haskell program are "apply"
operator and one have to count these spaces to even attempt to be compatible
with the theory.

I also have to say that I like Tcl very much but for different reason: values
in Tcl are immutable and passing a dictionary or list to a procedure will not
change that dictionary in unpredictable way (will not "pull the rug").

I once ranked languages by their support for drunken programming (diminished
higher thinking ability - how much thinking programming language really takes
from you) and Haskell and Tcl came out first and second - both have immutable
values and Haskell also helps with the type system. Other contenders like C,
C++, C#, Python and some other languages were much worse to use when one is
drunk. Mainly due to the need to remember effects on the arguments passed to a
function and/or method, but also for infamous "null".

C# had third place - some type safety and garbage collection help a lot (and
compiler accepts more code than Java). Everything else just brings you more
headache when you try to decipher and make work what you wrote being drunk.

~~~
IgorPartola
When I was in college I once wrote Java code while drunk late into the night.
I reviewed it the next morning (afternoon, really). The good news was that the
code worked exactly as expected and produced correct results. The bad news was
that it was completely incomprehensible. As in my sober self could not
construct a mental model of how the code worked.

Then again, I also sometimes write code in my sleep if I left a problem
unsolved during the workday and then I implement that solution when I wake up.
Does anyone else also do this?

~~~
swiley
This is my experience coding drunk as well. I also really hated the
experience. As someone who enjoys getting lost and getting drunk and
programming I thought I would love doing both together, it turns out for me
drinking just maximizes the magical transient errors when coding caused by
false assumptions which are always the hardest to debug.

~~~
thesz
These magical transient errors are exactly why one should choose language with
immutable values. You have old value and you compute new one (with sharing if
possible). You can continue to use old value or throw it away.

The mutation operation can be seen as resource management optimization,
premature (and thusly evil) more often than not.

------
ufo
Recently I've discovered that TCL is a very pleasant language for shell
scripting. The command-based syntax and the "everything is a string" design
are a perfect fit for that problem domain.

Next time that you have a shell script that is too complicated for bash but
not complicated enough for Python, give TCL a try!

~~~
chubot
Any examples of this to share?

I think Tcl would suffer from the lack of syntax for pipelines, for example.

~~~
ufo
One of these days I'm going to write a blog post about it...

The built in "exec" command supports pipelines and file redirections with the
usual syntax so you can do

    
    
        exec foo < bar | baz
    

and it works similarly to a bash command substitution

    
    
        $(exec foo < bar | baz)
    

The main catch is that if you have an argument that is "|" or "<" then TCL
interprets it as part of a pipeline, even if it came from a variable. However,
the flip side us that you don't need to worry about arguments with spaces or
asterisks. There is no word splitting or glob expansion so it is OK to leave
everything unquoted.

    
    
        set r "<"
        set p "|"
        exec foo $r bar $p baz
    

There are also a couple things that are slightly different from bash. One is
that exec raises an exception if the command returns a nonzero exit code. If
that is not what you want then you will need to use the TCL equivalent of try-
catch. I wrote a small helper function for this common use case.

Another thing is that exec returns a string with the output of the command,
similarly to $() in bash. If you want to output to stdout then you need to
work around that.

------
bitwize
Wait till he discovers Lisp. Tcl's flexibility combined with actual types (and
not stringly typed). That's how I got seriously into Lisp: reading about the
"Tcl Wars" and then trying out Guile.

That said, Tcl/Tk is still _the_ fastest way I've seen to go from zero to GUI.
Not even Visual Basic beats it in terms of quickness and simplicity.

~~~
_ph_
For GUIs, you can have the best of the two worlds by using LTk
([https://github.com/herth/ltk](https://github.com/herth/ltk))

~~~
StevePerkins
And cl-icebox ([https://github.com/VitoVan/cl-
icebox](https://github.com/VitoVan/cl-icebox)) is a build system, that can
compile your Ltk apps into standalone executables for easy distribution.

------
swiley
TCL/tk has some rough edges.

But compared to most GUI toolkits especially anything cross platform, it’s
really nice!

------
sn41
Hey... what's wrong with Tcl? Whenever I have a shell script and want to tack
on a "GUI", Tcl/Tk is the most time-economical one for me. I am happy that it
is still around, and that it works on most platforms (of course not mobiles...
but I "wish").

~~~
Toenex
Granted (on Android at least.)
[https://www.androwish.org/home/home](https://www.androwish.org/home/home)

~~~
appleflaxen
Oh man, that's awesome. You need to install by downloading a package.

If any maintainers are reading: putting it in the F-Droid store would improve
visibility / discoverability.

------
7thaccount
"Lovecraftian toolchain" made me almost poop myself when I first read this
article.

I've been learning TCL for fun lately and I both adore it and am frustrated by
it.

------
idolaspecus
> I have a bug, I'm frigging anxious, I gotta GO GO GO as fast as I can to
> find out what it is already, and you think now is the time to type parens,
> commas and quotation marks?! Fuck you! By which I mean to say, short code is
> important, short commands are a must.

Hahaha! This is excellent, made me crack a big IRL smile.

------
amelius
See also:
[https://news.ycombinator.com/item?id=7069642](https://news.ycombinator.com/item?id=7069642)

(Nice discussion on homoiconicity)

------
unemphysbro
The ease of creating and using child interpreters is a really neat thing about
TCL.

------
haolez
What I like about it (at least for my usage) is that you compose functions
like they were command line tool. That's some unique ergonomics right there
(regardless of its cons).

------
StevePerkins
Is Tcl still a COMPLETELY interpreted language?

I heard that they added a JIT compiler somewhat recently. But I'm not sure if
there's any kind of "true" compiler (or at least linter?), that can find your
basic errors prior to runtime.

I used to dabble a lot with Tcl back in the 1990's and early 2000's. I
eventually moved into Lisp to scratch that side-project itch, mostly just
because I wanted to find more mistakes at build-time than runtime.

~~~
blacksqr
Tcl switched to a bytecode compiler with version 8.0 about 20 years ago, which
delivered significant speedups in execution.

~~~
StevePerkins
Yes, but I thought that was a JIT compiler. For all practical purposes, still
an interpreter model from the user perspective.

Does it allow for ahead of time compilation to bytecode? With build-time
reporting of errors in the source code?

~~~
blacksqr
If you mean the wikipedia definition of compiling source code to machine code
at runtime, then no. The Tcl interpreter contains a bytecode virtual machine,
more along the Java model.

Source code is converted to bytecode on the procedure level, not the program
level, so there's no program-wide checks for consistency. It's done at
runtime.

There are some officially unsupported tools built in to the interpreter that
let you dump bytecode of compiled procedures and reload it. You'd have to roll
your own dumping and loading scripts if you wanted to deliver an entire
program using those tools.

~~~
blacksqr
There is an AOT Tcl-to LLVM IR compiler in development.

[https://wiki.tcl-lang.org/page/tclquadcode](https://wiki.tcl-
lang.org/page/tclquadcode)

