# TIP 674: a new multiple expression command
	Author:         René Zaumseil <r.zaumseil@freenet.de>
	State:          Draft
	Type:           Project
	Vote:           Pending
	Tcl-Version:    9.1
-----

# Abstract

This TIP tries to address some of the `[expr]` command shortcomings.
It was inspired by discussion on [tip-672] and the syntax of the `switch` command.

# Rationale

Tcl has already a `expr` command with a special syntax to do mathematical calculations.
Due to the choosen syntax the usage is sometimes cumbersome and it is not possible to change this.
The new command tries to fill this gap.

# Specification

The `let` command has the following syntax:

~~~tcl
	let ?-local? { var expr ?var expr? .. }
~~~

The command will sucessively set the `var` to the value of the next `expr`.
If `var` is equal `=` then the value of the expr will be appended to the return value of the `let` command.
If the `-local` switch is given then all used `var` are local to the `let` command.

# Options

* Allow multiple arguments instead of a single list of 
* Use another name instead of `let`.

* Define some special variable names (p.e. starting with "@") to define internal variables used in later `expr` without polluting the current namespace.

* Extend, reduce, change or use a totally different syntax to calculate the given `expr` value.

* Add syntax to deal with vectors, matrix, etc.

# Discussion

* aspect@tkchat:

Multi arg version:

	let a {$x + 20} b {$x - 20}

Single arg version is fragile because of mistakes with whitespaces:

	let {a $x + 20}
	
Only single var on start of version:

	let var expr ?expr?

* yorick@tcl-core:

~~~
I still prefer two separate commands, and names separate from expressions:
	let a {$x + 20} b {$x - 20}
	.canvas enclosed {*}[calc {$x + 20} {$x - 20} {$y + 20} {$y - 20}]
If the number of arguments supplied to [let] are odd, the last argument could be the unnamed procedure body to evaluate:
	set result [let a {$x + 20} b {$x - 20} {
		# do stuff with $a and $b
		set c something
		return {some result}
	}]
	# a b and c does not exist at this point
~~~

* Steve Landers@tcl-core: I don´t like either of them. Why not enhance canvas...

	.canvas enclosed {$x + 20} {$x - 20} {$y + 20} {$y - 20}


	
# Examples

* set variable simple case

~~~tcl
    # expr
	set x [expr {1+2}]
    set y [expr {3*4}]
    set z [expr {$x+$y}]
    # let
	let {x 1+2 y 3*4 z $x+$y}
~~~

* use values

~~~tcl
	canvas .c
	set x 10
	set y 10
	# = x,y coord
	# expr
	.c create text [expr {$x+1}] [expr {$y+1}] -text a
	# let
	.c create text {*}[let {= $x+1 = $y+1}] -a
	# = coord list
	# expr
	.c create text [list [expr {$x+1}] [expr {$y+1}]] -text b
	# let
	.c create text [let {= $x+1 = $y+1}] -b
~~~

* calculations

~~~tcl
	set i 0.5;
	# expr
	set x [expr {sin($i)}]
	set y [expr {cos($i)+$x}]
	set z [expr {$x+$y}]
	# let
	let {x sin($i) y cos($i)+$x z $x+$y}
	let {
	  x sin($i)
	  y cos($i)+$y
	  z $x+$y
	}
~~~

# Implementation

The real implementation should be done in C.
The following implementation can be seen as proof of concept.
Especially a proper error handling is missing.

~~~tcl
	proc let {args} {
      if {[llength $args] == 2} {
        lassign $args mySwitch myList
        if {$mySwitch ne {-local}} {
          error "wrong switch: $mySwitch"
        }
      } elseif {[llength $args] == 1} {
        lassign $args myList mySwitch
      } else {
        error {wrong #args, should be: let ?-local? "var expr .."}
      }
	  set myRet {}
      set myVars {}
	  foreach {var exp} $myList {
        if {$var eq {=}} {
	      lappend myRet [uplevel 1 expr [list $exp]]
        } else {
	      uplevel 1 set $var \[expr [list $exp]\]
          lappend myVars $var
        }
        if {$mySwitch eq {-local}} {
          uplevel 1 unset -nocomplain {*}$myVars
        }
	  }
	  return $myRet
	}
~~~

# Discussion

# Copyright

This document has been placed in the public domain.

