Showing posts with label tcl. Show all posts
Showing posts with label tcl. Show all posts

Thursday, January 27, 2011

Filename Expansion in Tcl

Stupid, stupid, Tcl. If you want to run a shell command with a glob filename, like *.h, you can't just do:
exec ls -l *.h

You have to explicitly tell Tcl to expand the glob, because it will pass *.h to the shell literally. But you also can't do:
exec ls -l [glob *.h]

because it will pass the entire list to the shell literally (thanks, Tcl, that's useful). You get lucky and it works if there is exactly one file matched by the glob. Otherwise ls will complain that there's no file called "a.h b.h c.h".

So what do you do? Unfortunately, if you pull up the man page for exec on the internet, it tells you a way to do this that is only syntactically valid for Tcl 8.5 or greater. For those of us living in the past, the demonic incantation you must utter is:
eval [list exec ls -l] [glob *.h]

Don't use Tcl unless you have to.

Wednesday, April 28, 2010

Tcl Case Analysis Lunacy

This goes way back to the roots of this blog. Complaining about Tcl, and complaining about code that breaks down into unnecessary and confusing case analysis -- those topics were the first three posts here.

Unsurprisingly, the toy language that is Tcl is serving me up some ridiculous case analysis. It has to do with the C++-side of a Tcl integration. When you look at the internals of the language objects created by the Tcl interpreter, some things that are conceptually the same have different internal representations. It's bad enough that I have to succumb to case analysis to figure out what's what: but on the other side of that wall, Tcl had to do some case analysis to put them all in different representations! Bad, naughty Tcl.

Here's what's bugging me. When you look at a Tcl_Obj over in the C world, it has a typePtr member to distinguish different types of things:

  • A simple name like A has a NULL typePtr.
  • So does a list of things in braces, like { A B }.
  • A name with some special characters like A[0] has type "string".
  • So does a list of things in braces which extends over a few lines, like:
    { A \
          B }
    
  • An explicit list like [list A] has type "list".
  • A quoted string like "A B" has NULL. At least I think so. I lost track.
So obviously there are a bunch of if statements in the back-end tangling stuff up like this. But it's nearly impossible to untangle it on the C side.

Stupid Tcl. Stupid case analysis.

Wednesday, April 8, 2009

Extra Characters After Close-Brace

As noted previously, Tcl forces you to put open-braces "{" on the same line as the if or proc that they belong to, and forces you to use the atrocious "} else {" style.

That's appalling, but get this: it also requires a space to the right of the close-brace "}". That's just plain stupid.

Compounding the problem, the error message isn't something like "a space is required after a close-brace". Oh no. It says "extra characters after close-brace". And if the body of your if is very long, like this:
if {$tcl_is_stupid} {
  # ... many lines of code ...
  # Next line is the error
}else{
  i_eat_my_hat
}

then the error message is truncated so that you only see the part of the command that isn't broken, along with the line number of the "if", not the offending "else". As icing on the cake, in the case I was trying to help someone figure out, the error was at the top of one of Tcl's Icelandic Saga stacktraces, and the line number reported to be in error was with respect to the proc it was in, not the file.

Thankfully, Google led me to the answer, because Tcl sure didn't. I love the subtitle of that Tcl wiki page: Purpose: to discuss one of the few 'gotchas' in Tcl. Ha! What a crock!

Friday, April 3, 2009

Last Element in a Tcl List

Oh, thank you Tcl, for providing the special string end. That way I can get the last element in a list with:

[lindex $mylist end]

What a relief! I was about to type:

[lindex $mylist [expr {[llength $mylist] - 1}]]

And if I had had to type that, my head would have exploded. Fortunately, I got away with just a pulsing vein on my temple at the thought of a pseudo-keyword like end.

Thursday, December 4, 2008

Tcl is Still a Toy Language

Let's extend the chain of complaints about Tcl.

6. Expressions sometimes have to be wrapped in [expr {}], but not always:


if { $x == "a" || $x == "b" } {
return [expr {$x == "a"}]
}


7. Variable argument lists are handled with a special argument name: "args". It's not a keyword, just a variable treated differently from every other variable. That's just demented.

Thursday, August 28, 2008

More Tcl Lunacy

Funny how when you start making a list, you might even leave off the thing that inspired you to make the list in the first place. The aggravation that led me to my previous rant didn't even make it into that post. So let's extend the "Tcl is a Toy" list a little:

4. Comments don't always begin with "#". At the beginning of a line, "#" is the comment character. But if you want to put a comment at the end of a line of code, you have to use ";#". I'm sorry, but that's ridiculous. So ridiculous that I had to start a blog just to rant about it, but when I went to post to the blog, I got sidetracked by three other ridiculous things.

5. Backslashes don't increase the line-number count. If you have some fancy scripts, or embedded Tcl, where you want to report the line number of certain actions, backslashes throw off the count. Why did you have backslashes in your script to begin with? Because Tcl is a toy language that would do something different if you started a new line there without the backslash. Argggh!

Tuesday, August 26, 2008

Tcl is a Toy Language

I just took over some Tcl code at work. What a toy language! The following are some things that are completely wrong about Tcl.

1. "else/elseif" has to be to the right of a brace. It's one thing if you like using this style of idiotic formatting for your if-else statements:

if { $x == 0 } {
do_zero()
} else {
do_non_zero()
}

which hides the structure by putting the "else" in a different column than the "if". But for the language to require you to do such a stupid thing is, well, stupid. It's also bad that it requires you to cleverly put the open brace of the "if" on the same line. It's what I'd usually do anyway, but bad requirement.

2. $x is assigned to as "x". How insane is that? You have two names for the same thing, and you can silently do the wrong thing if you set $x "abc".

3. Whitespace is significant in multi-dimensional arrays. Excuse me? $matrix(1, 1) (with a space) is different than $matrix(1,1)?

I could go on, but that's enough ranting for today.