This page collects various suggestions from the [Tcl 9.0 WishList] about shorthands that one could use instead of the [expr] command. The original numbered suggestions were ''34.'' [GPS]: I would like the '''math commands + - * / in the standard Tcl 9.0'''. and ''41.'' [Larry Smith] - '''some special syntax to invoke [expr]''' the discussions of which follow below (slightly reordered). Two subsequent suggestions are [Lars H] - '''extended $ substitution as expr shorthand''' and [Martin Lemburg] - '''special quotation to allow the bytecompiler to recognize expression''' ---- '''Talk''' [GPS]: I would like the '''math commands + - * / in the standard Tcl 9.0'''. Expr is awkward, and having to use braces to workaround the byte-code compiler sucks. The issue with this as I see it is whether to make them operate on longs/ints or doubles. How can we solve this? [Lars H]: You can of course have them right here and now. Just define proc - {term1 term2} {expr {$term1 - $term2}} proc + {args} { set res [lindex $args 0] foreach arg [lrange $args 1 end] {set res [expr {$res + $arg}]} set res } proc * {args} { set res [lindex $args 0] foreach arg [lrange $args 1 end] {set res [expr {$res * $arg}]} set res } proc / {numer denom} {expr {$numer / $denom}} and you'll be able to write things like + 1 2 [- 3 4] [* 5 6] [/ 7 8] for 1+2+(3-4)+(5*6)+(7/8). The idea that one should decide whether mathematical operations operates on "longs/ints" or "doubles" shows clear signs of too much C programming. ''In Tcl, everything is a string.'' ---- [Martin Lemburg] 17.02.2003: ''In Tcl, everything is a string.''? No, definitely not! For calculations it is definitely important to handle number values only with commands that don't change the internal tcl type to string, so the exact representation is not lost! If you don't care, if you don't have to care for the internal representation, than you can act like ''[[i]]n Tcl, everything is a string.''! We have many matrices to be multiplied and so we have to care about the internal type and not decrease the calculation's precision! [Rfoxmich] The concept of an exact representation is nonesense. The best you get on any computing device is an approximate fixed precision representation. In Tcl, you can set the precision to be what you want it to be, but it's still the precision of a stringized - fixed point representation that is just as exact or inexact as the binary fixed precision representation. [Lars H]: That ''everything is a string'' is one of the basic principles of Tcl. It is quite true that the internal representation of real numbers currently contains more information than the string representation -- this is the subject of the [A real problem] page -- but IMO this is a bug in Tcl. (It can alternatively be seen as a malfeature of the [tcl_precision] variable.) The ''correct'' way (used by e.g. Knuth for TeX) to handle this problem is rather to make sure that the string representation of a number contains enough digits to uniquely specify all bits in the internal representation. This will mean that you generally "cannot trust the last digit" and will see numbers written with more digits than "what is really there", but since this is always "inside the program" that should not be a problem; anything shown to a user should be explicitly [format]ted. Finally, if you are interested in maximal precision then you should probably read what Robert Heller writes on the subject of guard bits on the [A real problem] page. ---- [Larry Smith] - '''some special syntax to invoke [expr]''' - () would be best. This would make code much easier to read and more compact.It would be fairly easy to turn the feature on and off for backward compatibility. ''This is not in the Tcl Way. If I ([FW]) had it my way, the correct thing to do for such a radical addition in that area would be to add math procedures to eliminate the need to use expr, for those who prefer a more purely Polish syntax.'' [LV] In other words, FW, you would prefer to say something like set a [add 2 3 [divide [multiply 4 5 ] 7]] '''YUCK!''' [FW]: Well, I'm not sure what the command names would be, perhaps they would just be named after the math operators, as in [GPS]'s suggestion in wish #34. [LV] I still respond '''YUCK''' - I find reverse polish notation difficult to read and more difficult to code. I prefer the notation currently used by [expr]. ---- [Lars H]: Another possibility is to extend '''$''' substitution. I have seen references that it was originally introduced as a shorthand for [[set ...]], and in view of this, it would be natural to consider making a form of it which is a shorthand for [[expr {...}]]. How about set res $={2*$a + 3*rand()} as a shorthand for set res [expr {2*$a + 3*rand()}] i.e., when $ is followed by = (a case not explicitly mentioned in the Tcl syntax rules, but in which currently no substitution will take place) and something in braces then these braces contain an [expr]-expression rather than the name of a variable. What one should perhaps think hard about here is the possibility to get rid of the need to put $'s before variable names in these $=-expressions. Simplicity and compatibility with [expr] suggest that they should be required, but forgetting the $ in expressions is probably the most common typo I make. This ''could'' be a sign that they are unnatural. ---- The tcl parser is a simple one - trying to replace [expr ...] with $= seems to me to be asking to break the parser for minimal benefit. As for a new command to which one need only supply variable names, and not $, that too violates the tcl parser's rules - to get a reference to a variable, use the name only, but to use the value of a variable, precede the name with a $. It doesn't seem to me that the resulting command is going to be all that much beneficial, and on the contrary, it seems like it is going to make tcl slower, more complicated, and more difficult to teach and to use. ---- In [bash] one can write things like $(($i+1)) for what would be [expr {$i+1}] in Tcl. The former currently refers to an element in the empty name array in Tcl, but if ''wish #39'' (the empty string is no longer the name of a variable) was to be implemented, then the [bash] syntax (with double or single parentheses) could be used as an [expr] shorthand in Tcl. (In fact one could take the implementation of this syntax in Tcl 8 as an exercise in [trace] hacking. Set up a read trace on the empty name variable, and pass every index through [expr] to compute the array element value. Should work, but there would be a ridiculous amount of shimmering.) However, I think '''$={'''...'''}''' would work better syntactically than '''$(('''...'''))''' or '''$('''...''')'''. The best case for the latter two is the analogy with [bash]. [Larry Smith] '''$('''...''')''' is not bad at all. "$(" is not currently defined so it is backward-compatible, and the () notation is natural for arithmetic expressions. It also plays well with the idea of $[[]] to expand the results of a command into a list. It even suggests that ${} is a cleaner and more logical way to indicate the "expand w/o eval" that we currently use "" for. This has always felt wrong because "" is otherwise meaningless in Tcl, and is frequently ignored or interpreted oddly (as in "10" == 10 in expr). [ulis] Sorry, "$(" *IS* currently defined (empty named array): set (1+2) 4 puts $(1+2) ->4 [Setok] -- Somehow that looks perlish. I prefer using the command: +, -, *, / etc. Result in lines like set a [[+ $b $c $d]]. Indeed, I use this form all the time. [Lars H]: Whether it ''looks'' perlish is completely irrelevant (even though it is a classical killer argument in Tcl discussions; '''$''' substitution got that critique too, in the beginning). What matters is whether is would ''be'' perlish, and I don't think it is. As for having the math operators as explicit procedures, I think it would be a good idea to add a package for this to [tcllib] ASAP. ---- [Sarnold] In my little experience of [Perl], I was surprised I could quite not force the interpreter to handle my numbers as integers. (they were automatically casted to float) IMHO it is quite better to have both the casting operators, and the math operators as commands. I hope those changes won't make things harder to understand. IMHO it is expected from a developer to have skills with floating-point numbers and integers. Many people don't think so, but it is awfully too often required to know the limits of our machine-related number representations. ---- [LV] anyone who wants to write such a package, and submit it to tcllib, could probably get it in pretty quickly. And releases occur frequently enough that it would end up '''in the library''' distribution in a small number of months. ---- There is no compatibility problem, and if people like them then they could get byte-coded by Tcl 8.5. And it would still be possible to provide another shorthand like '''$=''' in Tcl 9, if some such suggestion is approved of. [Setok] Well my point was not that being like perl is always necessary bad, but I find $={$a + $b} a bit strange to read, although now that I'm not so tired as when first reading this page it's not as impossible as I reckoned. As you mentioned opers-as-procs is a good compromise and I never liked [expr] having its own functions anyway (a [[rand]] procedure would be much more natural than rand()). ---- As long as expr continues to work, other syntactical sugar notations are easy enough to add on. I would not like to see such things become a part of the tcl.tar.gz distribution. However, if they were part of tcllib, that would be fine. In [ksh] one could write things like $(($i+1)) or let $i = $i + 1 for what would be [expr {$i+1}] or incr $i in Tcl. ''[Lars H]: I hope anonymous at 134.243.40.138 will refrain from making '''non-editorial''' changes to '''signed''' material in the future.'' ---- [Martin Lemburg] 17.02.2003: if there is a possibility to mark expression with a special quotation to allow the bytecompiler to recognize expression, than it would easier a lot the writing of calculations. What's about: set pi '4 * atan(1)'; And ... even if it's not tcl-ish to do, but if we break tcl style by using "()" for functions, why not applying the nice patch for expr to allow every proc and command to be invoked in the same way and to access variables without the "$"-sign? Why not ... proc pi {} [expr {4*atan(1)}]; proc perimeter {r} {expr {2 * r * pi()}}; or proc pi {} '4*atan(1)'; proc perimeter {r} {'2 * r * pi()'}; [Lars H]: The "special quotation" is probably too radical to meet general approval -- cf. the hassle with {expand} (Tcl9 wish #3) -- but you're on to something concerning access to variables in expressions without using $. That would be ''very nice!'' [AJD] Don't personally see any improvement in the above forms over the simple use of "$pi" or "[[pi]]". However, the use of argumentless functions within [expr] is something I've hacked around with... in particular, the case above of [[expr { pi() }]] to denote a constant. The core doesn't currently have any such beasts but they can be defined using the API function Tcl_CreateMathFunc. The idea being the core could define PI and other 'well known constants', saving users having to do it (possibly in a variety of places). There's even the opportunity for a teensy weensy performance gains (e.g., inline "2*pi()"). Maybe the ability to define "[expr] constants" could be exported to the script level... Overall though, probably doesn't buy enough beer to get taken to the bar. Maurice.Diamantini (03 mars 2003): I'd like to see the functionality from vexpr (http://mini.net/tcl/vexpr) or the vkit (is it dead ?) to be integrate into the expr command. so that one could write set a [list 1.0 4.0 3.0] set b [list 5.5 6.6 9.8] set c [expr {$a*$b}] Another amelioration I'd like in tcl9 is to extend incr, and add a few other command like mult to work with other type than int (double or list ) (il c ist the liste above: incr c 1 ;# add 1 to every element of the list c incr c 3.1 ;# add a double incr c $b ;# add another list ---- [RJM] Picking up the suggestion above to use simple () parentheses: Why not doing it without preceding $? Just as "[[" marks the start of a recursive script, "(" could mark the start of a math expression. (simple example) set y ($x*$a + 3.5) Note that the shortcut should '''only''' apply to expressions that can be evaluated in an expr {...} command notation. In the case the expression cannot be evaluated with {} quoting, the conventional [expr] command should still be applied: This is the case where STRINGS must be evaluated as a math expression. In other interpreter languages it is also usual to provide a command for such cases. [Lars H]: It would certainly be a language that made sense. The big problem with making '''(''' behave like '''[[''' (but for expressions rather than scripts) is however that it makes another character special, and thus breaks every old script in which that character wasn't protected. In particular the syntax for array elements would get into serious trouble. I suspect the change would be too great for ''any'' Tcl version increment. Math operations as explicit procedures are probably the way to go. [RJM]: I revised my contribution above. "[[" may also appear without space as to execute a script. However it does not mean that "(" as an expression shortcut should '''also''' evaluate an expression when it appears without a leading space. I suppose expression results mostly happen to appear as command arguments. When it happens to appear inside a string, the shortcut shall not apply. In such cases, the [expr] command should still be used. When a variable with trailing space exists, there will be a problem. But I hardly believe that anyone would define variables with trailing spaces. Hence, backward compatibility shouldn't be a problem. Moreover: To my opinion, backward compatibility is not a holy cow. It is consequent backward compatibility that made ''MS-windows'' a monster. Consider also that scripts can easily be adapted to conform a newer Tcl version, using a script. Another idea (yep, this is a brainstorm page): When "(" is not acceptable, a new command "=" should. For evaluation purposes, enter the following proc: proc = {args} {expr $args} According to my previously stated condition, this command should only work with true expressions (i.e. be equivalent to '''expr {text}'''). This way, any '''[[= 5*1.2 + $a]]''' inside a script text would execute the fast way round. ''Oops! (note few weeks later) This intention violates with Tcl rules - Tcl would do substitutions before passing the argument to the "="-command. So the fast way round is never possible with a new command. Conclusion: only a new substitution type will do (see above: $={...}, '...', $(...) and (...) ). Given the complaints with "(" I vote for $(...).'' Uhh, this is empty array access (see above) Recalling backward compatibility issues, I'd recommend a little bit more courage in changing things in Tcl. [expr] is historically given, because everything '''was''' a string in Tcl. When no shortcut will be introduced, I believe Tcl will early or late fade out in computing history, simply because the choice in scripting languages is really large. Anybody who is selecting a scripting language will tend to not select Tcl when he/she encounters "set a [[expr {....}]". This is [Tcl Marketing]-relevant! ---- [RS]: You can save a level in call stack by using this instead: interp alias {} = {} expr ([RJM]: still for evaluation purpose: executes slower and does not include {} in [expr]). ---- [DKF]: The problem with special syntax for expressions (or at least special syntax that isn't standard command invokation or the '''=''' alias) is that this is a major departure from the existing rules; you'd be making some kinds of syntax special, and one of Tcl's key strengths is that there are ''no special global syntaxes''. The [expr] syntax is always just a local syntax. A few notes here... * Unbraced expr was special in the alphas of Tcl 8.0, but this was deeply unpopular with many very influential Tclers. * It is possible to get commands that are as efficient as the expr bytecode, or rather it would be if it wasn't for the fact that we're not very proud of the actual compiler API and so haven't exposed it publically. :^) ---- [RJM] It can be seen, that no practicable shortcut for '''expr {...}''' seems to exist. Therefore, another approach should be discussed. Why not let appropriate commands '''expect''' an expression in one or more of its arguments, like the [if] command does. For example coords arguments for canvas operations. They '''must''' always be numeric, so rewriting commands involving coords to expect expressions would allow us to embed calculations within such commands in a more compact fashion, which improves readability. I also think this would not affect backwards compatibility problems, since numbers are already "expressions". Further, existing code, where [[expr {....}]] is already embedded, also yields no problems. I would see this idea closely related to what is written in [What some command arguments expect]. If the idea is interesting, an inventarisation of commands with this respect should be undertaken. Further, some new commands could be defined, such as xset/nset for expression/numeric set etc. [KPV] See tip #176 [http://www.tcl.tk/cgi-bin/tct/tip/176.html]. Personally, I like what that tip proposes--it would clean up most of the cases where adding ''expr'' gets really awkward. But I've not heard much momentum behind it. ---- [Lars H]: Another TIP which should be mentioned on this page is #174 [http://tip.tcl.tk/174.html]. It is pretty much what is listed as Wish #34 above. [HGO]: And yet another TIP which should be mentioned on this page is #232 [http://tip.tcl.tk/232.html]. It may help in many of the above stated cases. ---- [Category Suggestions] | [Category Command] | [Category Mathematics]