'''Question:''' Why is [Tcl] [syntax] so weird? '''Answer:''' it's not. Everything else is weird. Okay, you might not buy this. I don't either, completely. The point is, though, that Tcl may be the only language I've ever heard of where there are no special/built-in functions. ''[VL] 14 jun 2003: Hmmm, how about [Prolog], [LISP]-dialects, etc. etc. etc.? Or am I missing your point here? I suppose that what is a language and what is the "standard library" of that language are a bit of a grey area.'' ''[pdm] good point. I have mostly used procedural rather than functional languages. From my college days, I vaguely remember the syntax being simpler in prolog or lisp. Which actually made it harder for me to think that way. Maybe I was poisoned by an early exposure to [BASIC] :)'' There is no [Pascal] '''println''' that allows variable arguments when every other function has a fixed number of arguments. [LV] On the other hand, variable arguments are just fine in Tcl. It is just that the default output command, [puts], requires one string as its output format. If someone wanted to write something like println, they could write a proc that would collect its arguments, hand them to format and then to puts. In fact, you could have something like this: proc println { args } { puts [join $args {}] } so that you coded, in tcl, set a "STring 1" set b "string 2" println $a $b [list This is a list] [pdm] This shows one of the strengths of Tcl: you can make it do almost anything you want. Sometimes it isn't obvious, especially if you are stuck in Pascal-think. I find myself having to think harder because I'm trying to force [C] code into Tcl. If I just do it the Tcl way it can be much easier :) ---- There is no C '''for''' that has three arguments separated by semi-colons where each argument can have any number of operations separated by commas. [LV] There are, however, several looping constructs that you can do looping - for instance, where in C you would write: for (i=0;i<10;i++) { printf("x is %s\n", x); } in tcl you would write: for { set x 0 } {$x<10} { incr x } { puts "x is $x" } [glennj]: the tcl [for] is just like the C ''for'' -- the ''start'' and ''next'' parameters are arbitrary script bodies. Not that this is encouraged, but you can do: # add up the numbers from 0 to 9 for {set sum 0; set counter 0} {$counter < 10} {incr sum $counter; incr counter} {} puts $sum ;# ==> 45 [pdm] You're right, of course. What I meant was that the rules for Pascal or C are not simple and consistent. The rules for TCL are. Since I have "baggage" of C, Perl, etc, it seems weird at first. It is real simple: a '''command''' followed by zero or more '''arguments'''. That's it. Unfortunately, that means a simple assignment statement has to be written funny. Trying to say a = "12345" would try to run the '''a''' command, which probably doesn't exist. If you try to use Perl-like syntax, you might try $a = "12345" which would also fail because the parser would try to get the value of a variable called '''a''' and treat that as the command name (see [Substituting Command Names]). [LV] Unless you play games with [Salt and Sugar], which allows you to write assignments in more unusual ways. So, TCL has a '''set''' command that takes two arguments: the first is the name of a variable and the second is the value. I just think it's weird because everything else has special cases. [LV] other languages use set - csh for instance, which apparently provides a number of influences on Tcl. The original [BASIC] required a syntax like: [let] a = 1 which is even worse! [Arjen Markus] I can add to this, that formally and semantically the use of an equal sign, as it appears in many programming languages, is claimed to be a bad move by some. The reason is, that in a mathematical sense, an equal sign simply means that something is '''equal''' to something else. In descriptions of algorithms one frequently sees variable <- value to distinguish it from a check for equality. Still other languages, Eiffel for one, use this variable := value So, again, the fact that Tcl does not adhere to the commonly found constructs does not mean that '''it''' is weird. As a personal note, the first time I tried to find man pages about Tcl I was very disappointed to find only a description of the basic syntax - nothing about if, for or whatever. ''DKF'' - Note that in some BASIC systems (ZX80, ZX81 and ZXSpectrum in all its variants, though some came with variations that did not work this way IIRC) the ''LET'' keyword was inserted by pressing a single key, which made its use much less of a chore (though the platform was definitely fairly bizarre.) ''[Lars H]: That comment makes me remember when I wrote (in BASIC) a combined assembler/editor for the ZX Spectrum. The entire assembler program was stored in a string (now that we know that everything is a string, this is obvious, but back then it wasn't). And "n" is still my "foo loop variable", because "NEXT n" was just a matter of pressing the "n" key twice.'' ---- [LV] As a personal note in reply to the message about disappointment in the man pages - man pages were not, at least initially, intended as tutorials to the use of the subcommands, but simple reference items describing what a command's subcommands, etc. were. It was, and to the most part still is, expected that sites like this one, books, etc. would provide tutorial level information. If there is reference material that you feel is seriously lacking, there are several alternatives. 1. We have a variety of pages on this wiki, at least one per tcl ''command'', on which questions, and subsequently answers to those questions, can be placed. 1. http://tcl.sf.net/ and the tk sibling have a feature request option, where one can request changes. These may, or may not, be implemented, but at least they won't be lost. 1. At that same site, there is a patch manager, where people can submit patches to '''broken''' behavior. If you feel the man pages are broken, consider fixing at least one of them, and submitting it as an example of ''proper'' documentation. ---- As another note, there is a really, really weird construct in C that is explicitly allowed, if my memory serves, it is called the Duffy construct and consists of an unexpected mixture of switch and case statements. Unfortunately, both my memory and my library do not serve at this moment. The reason it is allowed by the standard is merely that it optimizes certain operations. [pdm] For the compiler/language-designer purists, that brings up an interesting question: when is it okay to "break" or "abuse" the syntax of a language in the name of faster runtime? My guess? The TCL and C designers answered this question "whenever a clever user/developer can figure out how" and "whenever needed", respectively :) '''EE''': Duffs Device [http://www.lysator.liu.se/c/duffs-device.html] is an example of loop unrolling, but the reason it is allowed by the standard is not "merely that it optimizes certain operations", but rather because it does not violate any syntax rules or constraints. [AMG]: I did a bit of loop unrolling here on the wiki. See my contribution to [Matrix Multiplication]. The Tcl script uses nested [[[for]]] loops to generate a single, long line of Tcl script that accomplishes matrix multiplication with no run-time loops. Alas, I wasn't responsible enough to profile before I optimized, or else I'd be able to say whether or not this is actually worth anything. In a sense, I embed a mini-compiler in my code. This ties in with the meta-language comment further down this page. ---- [RS] Call it weird or not, most "algebraic" languages like C have mathematical syntax (infix operators +-*/, parens etc.) mixed into another with keywords, braces etc. C++ goes so far as to allow overloading operators, but you couldn't define new operators or new arities (for instance, a unary /). Math syntax is of course needed as computers often compute. In Tcl, most math is concentrated into the [expr] command, leaving the rest of the language as clear and pure as it is. But even in expr, using the general rules of string manipulation we can do more things than are possible in C or other algebraic languages: foreach operator {+ - * /} { puts "3 $operator 3 = [expr 3 $operator 3]" } The [expr] parser would not accept the operator substitution, so in cases like this, leave the argument to expr unbraced, so you can enjoy the full freedom of Tcl. ''DKF'' - SML permits declaration of new operators. Overloading existing ones requires a language extension though. [AM] [Fortran] (90 and later) allows the definition of new unary and binary operators, it also allows extending the existing operators for new data types (but you can not redefine the meaning of summing two integers for instance - for obvious and wise reasons). ---- There are some weird items in the parsing of Tcl like: set x a"b set y $x.b set x.b c puts $y ; # is a"b.b but on the whole the language is simple. But the parser is just a small part of the story after the parser gets done with the source each command has almost complete freedom to add more levels of substutions, evaulation or what ever. I don't think this "strangeness" is too bad because I picked it up so easy but I can understand that others may be turned off by it. ;^) [Earl Johnson] ---- This is a response to Earl's remarks above: I think this "strangeness" is in the eye of the beholder. When I read this code it all looks right to me. Before I knew tcl I it would have told me that tcl is different. I'd expect it to be different, after all it is a different language. The question I needed to resolve is "Is it worth it to learn tcl?" since it's different. tk is what made it worthwhile for me, and I suspect it did for others. I didn't learn perl because it was different, didn't have a gui, and seemed to carry over a lot of the ills of other early shell languages. bob ---- [TV] What a strange page title.. I guess people have a certain structure or language in mind when they program, or maybe certain concepts, which could be either like comparing english and german, or maybe like comparing logo and C++. Tcl is of course simple in its fundamental form while it has the power to do most known programming things without too much effort. But if your mindset is to be grounded in pascal's formal definitions or your fingers just won't move without objects of your desire, you probably weren't raised on tcl or scripting. ---- Tcl syntax *is* weird, at least when compared to other (popular) languages. It's weird in that it doesn't have much syntax. Tcl uses semantics where most languages would use syntax: variable assignment, control flow and command definition are all done through the same syntax. Whereas most languages have a list of keywords and a BNR grammar for these sort of operations, Tcl has default commands and even these can be redefined. I think of Tcl more as a meta-language, and every program winds up being a custom and application specific language. It's similiar to Lisp and Forth in that regard, but (IMO) easier to read than either of those. And that is weird to anybody comming from a [C++]/[Perl]/[Java] or even [Python] background. In my experience, lisp-niks get it right away (but dislike Tcl for the syntax it does have). [pdm]... and for the heretical under-use of parentheses :) Seriously, though, this last comment puts it very well. Thank you, anonymous contributor! ---- [alove] 10 dec 2005 The reason this issue keeps coming up is because other languages all the way back to BASIC and including Perl and Python, have very user-friendly and intuitive syntax for math expressions, for example: Python: c = a + b Perl: $c = $a + $b; BASIC: c = a + b PHP: $c = $a + $b Ruby: c = a + b TCL: set c [expr {$a + $b}]] - can you feel the difference? Considering how basic and fundamental arithmetic expressions are, I'm amazed that no one has fixed this yet. User friendliness takes precedence over abstract ideas like the Dekalogue. If you have to make an exception to make arithmetic expressions look pretty, as in every other interpreted language, then I think you should. ---- [EMJ] 10 dec 2005 - I was going to correct the Tcl line above, then I thought it was better to have a visible correction: Tcl: set c [expr $a + $b] The original works (except for the extra right bracket), but the braces are unnecessary, so why put them in? Or why not put something unnecessary in the other languages? * [aricb], with apologies for interrupting [EMJ]: put in those braces for all the reasons at [Brace your expr-essions]. Those few extra keystrokes will pay big dividends--and you'll sleep better at night :) * [emj], apology accepted, I'm prepared to believe all the reasons, but would adding bits improve the behaviour of any of the other languages? I don't know, but when making comparisons you need to be on the same level. Everything is a string, and every line is a command - that's Tcl, it's clean, simple, and consistent. Of course, since it is flexible as well, you could just add a bit of logic to '''unknown''' to say the if the second argument is just an equals sign, convert the whole thing to '''set ... [[expr ...]'''. Naive users may think it's special syntax, but it won't be. And I won't do it, because I don't want it. Changing the foundations of Tcl to follow a fashion, or to be like some other language, is a very slippery slope. [jcw] - That last comment can be a two-edged sword. ([emj] I do not want to take a two edged sword down a slippery slope :) ) Tcl is also very adept at embedding domain-specific notations - the "expr" command itself is an example of that. There are ways to stay with the current rules, yet abbreviate: $ {c = a + b} This requires a command "$" which parses its arg, a bit like expr but treating names as variable or array references. [emj] - Embed what you like, no argument there. The other notational inconvenience is list indexing and such: set x [lindex $data 12] set y [lrange $data 1 end-1] If array index notation were allowed for lists, it could be written as: $ {x = data(12)} $ {y = data(1,-1)} All without changing anything in Tcl. As an extension which would work with any Tcl >= 8.2 [emj] - but what will happen if you do parray data to a list? ---- [slebetman] While I respect [alove]'s opinion, I have to disagree. Even in C, math expressions account for less than 10% of my code (I took C/C++ classes to avoid math ;-). Unless you're doing declarative programming, the majority of your code will be control flow - for, if, while etc. (Actually the majority of C++ code tend to be struct and class definitions in header files :-) Just look at your code, how many expr's are there and what's the ratio of expr to the rest of your code. It doesn't make sense to complicate the clean syntax of Tcl for something that accounts for such a small minority of code. [AMG]: [[[expr]]] isn't the only way to do math in Tcl: [[[if]]] and [[[while]]] have expression parameters. Some commands implement math using their own expression syntax, for instance [[[lindex]]] accepts end-$x and [[[incr]]] groks positive and negative integers. Plus there's a TIP (I think) that proposes to extend index notation to accept $x+$y. I'd have to double-check that to be sure, but my point still stands: you can't simply look for the [[[expr]]]s to see how much math is in your code. Regarding the above [[[expr]]] abbreviation discussion, I'd like to see support for '''$[[$insert + $math * $here]]''' notation. (Note the lack of braces inside the brackets.) Also see [Math Operators as Commands] for an alternative to most uses of [[[expr]]]. ---- Another way to think about this: in most other languages, syntax ''defines'' the development experience. With Tcl, though (as well as [Lisp] and [Forth]), syntax is available for extension at any time. Ed Watkeys writes [http://xmog.com/scrap/show/5] about this from a [Scheme] perspective. ---- [[ [Category Discussion] - [Category Syntax] ]]