Tcl Math Syntax is Inferior to JavaScript/Python/Ruby/C/C++/Java/Perl/PHP

Problem

Tcl's mathematical expression & assignment syntax is unnecessarily verbose and thus inferior to many other programming languages (especially Ruby, JavaScript & Python). Every extra redundant character means:

  • Potential typos/errors
  • More information that needs to be read and processed by both people and computers
  • More information that needs to be typed
  • Tarnishing Tcl's clean, simple and beautiful space delimited syntax

Proposed Solution

Add more standard operators to tcl::mathop in Tcl 8.6, such as:

	=
	+= -= *= /= %= **=
	&= |= ^=
	<<= >>=
	++ --

And add the function pi() to tcl::mathfunc.

Quick and dirty hack implementation for demonstration purposes:

	proc = {var args} {
		upvar 1 $var uvar
		set uvar [expr $args]
	}

	proc += {var args} {
		upvar 1 $var uvar
		set uvar [expr $uvar + ($args)]
	}

	proc ++ var {
		upvar 1 $var uvar
		incr uvar
	}

Examples/Comparisons of Clarity & Line Lengths

Assign Result of Single Operator Expression

	s = 60 * 60 * 24			# JavaScript, Python, Ruby
	s = 60 * 60 * 24;			# Perl, PHP
	int s = 60 * 60 * 24;			# C, C++, Java
	set s [expr 60 * 60 * 24]		# Tcl
	set s [* 60 60 24]			# Tcl 8.5
	= s 60 * 60 * 24			# Proposed Tcl 8.6

Assign Result of Multiple Operator Expression (Long Version)

	y = m * x + b				# JavaScript, Python, Ruby
	$y = $m * $x + $b;			# Perl, PHP
	float y = m * x + b;			# C, C++, Java
	set y [expr $m * $x + $b]		# Tcl
	= y $m * $x + $b			# Proposed Tcl 8.6
	= y m * x + b				# Future Fantasy Tcl: lookup
						# unrecognized tokens as variables/procedures

Assign Result of Multiple Operator Expression (Short Version)

	y=m*x+b					# JavaScript, Python, Ruby
	$y=$m*$x+$b;				# Perl, PHP
	float y=m*x+b;				# C, C++, Java
	set y [expr $m*$x+$b]			# Tcl
	= y $m*$x+$b				# Proposed Tcl 8.6
	= y m*x+b				# Future Fantasy Tcl: lookup
						# unrecognized tokens as variables/procedures

Assign Result of Mixed Expression

	$x = sin( pi() / 2 );			# PHP
	x = Math.sin Math::PI / 2		# Ruby
	x = Math.sin( Math.PI / 2 )		# JavaScript
	x = math.sin( math.pi / 2 )		# Python
	double x = Math.sin( Math.PI / 2 );	# Java

	const double PI = acos( -1 ); 		# C, C++: do it yourself Pi
	double x = sin( PI / 2 );

	use constant PI => atan2( 1, 1 ) * 4;	# Perl: do it yourself Pi
	$x = sin( PI / 2 );

	proc pi {} { expr acos( -1 ) }		# Tcl: do it yourself Pi
	set x [expr sin( [pi] / 2 )]

	= x sin( pi() / 2 )			# Proposed Tcl 8.6
	= x sin pi / 2				# Future Fantasy Tcl: optional parenthesis

Accumulate

	s += 60					# JavaScript, Python, Ruby
	s += 60;				# C, C++, Java, Perl, PHP
	incr s 60				# Tcl
	+= s 60					# Proposed Tcl 8.6

Increment

	++x					# JavaScript
	++x;					# C, C++, Java, Perl, PHP
	x += 1					# Python, Ruby
	incr x 1				# Tcl
	incr x					# Tcl 8.5
	++ x					# Proposed Tcl 8.6

Post Script

If this has been previously recommended/discussed then could someone provide a link?

I know this wiki may not be the ideal place to propose this, but it is the quickest.


NEM See e.g. let and expr shorthand for Tcl9. The proposed = command will be non-optimal as shown. See Brace your expr-essions for reasons why. The same applies to the other assignment short-cuts, which is probably why they were not added. See also http://tip.tcl.tk/ for various relevant TIPs along with rationale discussions. A pi() function is a simple addition. Such requests can either be TIPed or added as Feature Requests to the Tcl project tracker at http://sourceforge.net/projects/tcl .


Sarnold See xsource for an attempt to solve this problem.

Lars H: And infix for yet another approach.


ZB 30.06.2008. So, "duplicated syntax"? Both "++ x" and "incr x"? But what for? Those, who are accepting TCL's syntax, won't need it. For those, who feel uncomfortable with TCL's syntax, it's too limited change to be persuaded: "now you'll like TCL". So again: what for? I would to quote something from the main page: "Tcl is a simple-to-learn yet very powerful language. Its syntax is described in just a dozen rules". Not enough rules - let's add some more?

Perhaps it could be much better to switch to "project L" syntax change proposals completely instead? Just to keep consistency.


WJG (01/07/08) Personally I find that whilst the alternative symbols for keywords such as incr and set might make Tcl 'look more familiar' they are not necessary. In fact, I suspect that the replacing 'incr s' with '+= s' will cause as many key board entry errors. Indeed, my overall comment on such introspection would be that if a coder needs python or something else, then use it, Saying that Tcl needs to me more like python, perl or c++ is just an argument against using Tcl rather than urging the introduction of symbol synonyms. Extensibility, as I understand it implies a simple core Tcl with flexibility entering through the development project led extensions. With so many packages now becoming shipped with Tcl, a 'batteries included' version of Tcl is becoming bloatware. The more that is added, the more there is to dislike. Surely, there will be a point when potential users, unable distinguish what is core and add-on will find it all too confusing and therefore pursue an alternative. I myself went through a period of introspection a while ago and seriously thought of swapping from Tcl to something else, such as Lua or Python using wxWidgets. But I came back to Tcl, not for anything new that has come along, but because the original idea was both simple and clean. The command syntax, in keeping the flavour of shell scripting is robust. Perhaps the emergence of eclectic collections of packages and extensions is because Tcl is now being 'designed by committee' rather than the outcome and the vision of its original creator.


DKF: We've been considering doing assignment operators. The problem was (IIRC) that it introduces a new syntactic class in our expression parser (approximately "lvalue") and that makes it tricky in a number of ways. Once that's done, doing a bunch of infix assignment operators is easy enough.

You can do pi() for yourself right now. It's a one-line script!

 proc ::tcl::mathfunc::pi {} {expr {double(3.14159265)}}
 # I got the value from Google so it must be right!

Lars H: Why not take advantage of Tcl's status as dynamic language to construct the procedure body automatically?

 proc ::tcl::mathfunc::pi {} [list return [expr acos(-1)]]

In 8.5 this returns 3.141592653589793 for me, and all those digits are correct.