It's a combination of cumbersome syntax and the vendor's poor API design and execution environment.
For a syntax example, compare python to Tcl. In python, there's a compact array lookup operator, and dictionaries allow string keys:
mydata["channel"][2]
Tcl, however, requires a function call to access an array index, resulting in nested function calls with magic numbers for the simplest expressions:
lindex [lindex $mydata 35] 2 # Tcl
Then there isn't any static type checking so you have to run code to see if it would work; the shape of a return may surprise you. Connecting to hardware may be your only opportunity to exercise certain code paths.
So for any non trivial task, Tcl becomes effectively write-only.
Some tools allow you to export Tcl scripts that automate tasks like project creation to help you avoid tracking intermediate objects in source control, but because the Tcl cwd path can change throughout a script, they export every source path as a hard coded absolute path, including whatever developer's home directory it might be residing in. This is not suitable for source control (because it would preclude building on any other machine) so then you have to post process these scripts before tracking them. But since it's Tcl there aren't good scriptable tools for programmatic Tcl AST manipulation, so you have to modify these files with some sort of a state machine, looking for various sentinels to trigger the various string replace behaviors you need. It's not all Tcl's fault, but if a vendor is only using Tcl for automation and you need automation, you have a battle ahead of you.
Outside the language, you'll often find that your runtime tool locks the UI thread to run your scripts, so long running operations are impossible to pause or cancel. And I've never seen a vendor expose adequate objects to allow full control, so often, the critical actions you hoped to automate are only possible through the GUI.
In the 90s, an integrated Tcl interpreter was a good sign that your vendor cared about developers. Today it's more a sign of neglect.
> Tcl, however, requires a function call to access an array index, resulting in nested function calls with magic numbers for the simplest expressions:
I do understand how that one can be frustrating to a newbie, but I can't fault that implementation choice when thinking about Tcl as a "Lisp but it's strings".
> Then there isn't any static type checking so you have to run code to see if it would work; the shape of a return may surprise you. Connecting to hardware may be your only opportunity to exercise certain code paths.
This, though, yeah. I feel this in my whole body. I haven't checked out Tcl 9.0 to see how it's changed, but Tcl 8.6's abbreviated compilation phase definitely doesn't leave any room for type much type inference ahead-of-time.
> sentinels
Tangential, but man I wish Tcl had `gensym` out of the box. That alone was enough to start my own programming language over a decade ago.
Everything else, I largely agree with. Short of a hard fork or the Tcl team splitting their time between maintaining for the sake of EDA vendors, and trying different approaches, I don't see much changing.
I really appreciate the time you took to share your experiences here.
My experience with Tcl is 30 years of using EDA tools, all of them equipped with this language from hell. Luckily, I've been to restrict the scripting part to the minimum. I'm sure that if you know the language well, you can see the foundational model that's behind it, but for occasional users, there's nothing predictable about it.
I couldn't tell you exactly all the thing that are wrong with it. Let's just say that a language where this is ok:
Similar amount of experience with tcl here (since dc_shell-t was released). I love working in tcl. It can be expressive, redable, sufficiently performant, and makes it easy and fast to develop and test new features and functions in even very complex EDA design flows with 100k lines of code.
I find it curious that so many of the criticisms of tcl are that it doesn't have some feature or behavior of some other language. That has never stopped me from accomplishing what is needed with clear, elegant code.
Rule #10 in the Dodekalogue [0] explains why your preferred comment style is not supported: a command is not expected immediately after the last argument of the previous command. Terminate the command per rule #1 and it is perfectly fine:
puts "Hello" ;# A comment
Isn't that the same number of characters one would type to start a javascript comment? //
Almost any programming language can be beautiful in its simplicity if you work with it on its own terms. tcl doesn't deserve the hate.
I'd be curious to know what your experiences with Tcl have been, to better understand why you feel this way.
It's a combination of cumbersome syntax and the vendor's poor API design and execution environment.
For a syntax example, compare python to Tcl. In python, there's a compact array lookup operator, and dictionaries allow string keys:
Tcl, however, requires a function call to access an array index, resulting in nested function calls with magic numbers for the simplest expressions:
Then there isn't any static type checking so you have to run code to see if it would work; the shape of a return may surprise you. Connecting to hardware may be your only opportunity to exercise certain code paths.
So for any non trivial task, Tcl becomes effectively write-only.
Some tools allow you to export Tcl scripts that automate tasks like project creation to help you avoid tracking intermediate objects in source control, but because the Tcl cwd path can change throughout a script, they export every source path as a hard coded absolute path, including whatever developer's home directory it might be residing in. This is not suitable for source control (because it would preclude building on any other machine) so then you have to post process these scripts before tracking them. But since it's Tcl there aren't good scriptable tools for programmatic Tcl AST manipulation, so you have to modify these files with some sort of a state machine, looking for various sentinels to trigger the various string replace behaviors you need. It's not all Tcl's fault, but if a vendor is only using Tcl for automation and you need automation, you have a battle ahead of you.
Outside the language, you'll often find that your runtime tool locks the UI thread to run your scripts, so long running operations are impossible to pause or cancel. And I've never seen a vendor expose adequate objects to allow full control, so often, the critical actions you hoped to automate are only possible through the GUI.
In the 90s, an integrated Tcl interpreter was a good sign that your vendor cared about developers. Today it's more a sign of neglect.
> Tcl, however, requires a function call to access an array index, resulting in nested function calls with magic numbers for the simplest expressions:
I do understand how that one can be frustrating to a newbie, but I can't fault that implementation choice when thinking about Tcl as a "Lisp but it's strings".
> Then there isn't any static type checking so you have to run code to see if it would work; the shape of a return may surprise you. Connecting to hardware may be your only opportunity to exercise certain code paths.
This, though, yeah. I feel this in my whole body. I haven't checked out Tcl 9.0 to see how it's changed, but Tcl 8.6's abbreviated compilation phase definitely doesn't leave any room for type much type inference ahead-of-time.
> sentinels
Tangential, but man I wish Tcl had `gensym` out of the box. That alone was enough to start my own programming language over a decade ago.
Everything else, I largely agree with. Short of a hard fork or the Tcl team splitting their time between maintaining for the sake of EDA vendors, and trying different approaches, I don't see much changing.
I really appreciate the time you took to share your experiences here.
You can just use
for indexing nested lists, btw. Same for nested hash tables:
Mixing the two does get ugly with nested functions, granted.
My experience with Tcl is 30 years of using EDA tools, all of them equipped with this language from hell. Luckily, I've been to restrict the scripting part to the minimum. I'm sure that if you know the language well, you can see the foundational model that's behind it, but for occasional users, there's nothing predictable about it.
I couldn't tell you exactly all the thing that are wrong with it. Let's just say that a language where this is ok:
puts "Hello"
But this is not:
puts "Hello" # A comment
shouldn't exist.
Similar amount of experience with tcl here (since dc_shell-t was released). I love working in tcl. It can be expressive, redable, sufficiently performant, and makes it easy and fast to develop and test new features and functions in even very complex EDA design flows with 100k lines of code.
I find it curious that so many of the criticisms of tcl are that it doesn't have some feature or behavior of some other language. That has never stopped me from accomplishing what is needed with clear, elegant code.
Rule #10 in the Dodekalogue [0] explains why your preferred comment style is not supported: a command is not expected immediately after the last argument of the previous command. Terminate the command per rule #1 and it is perfectly fine:
puts "Hello" ;# A comment
Isn't that the same number of characters one would type to start a javascript comment? //
Almost any programming language can be beautiful in its simplicity if you work with it on its own terms. tcl doesn't deserve the hate.
[0] Dodekalogue is the common name for the twelve rules that define the syntax and semantics of Tcl. https://wiki.tcl-lang.org/page/Dodekalogue
Would you prefer dc-shell scripting?
(I still remember the excitement of EDA tools _starting_ to support TCL and replacing the custom scripting engines they used to have)