TIP #57 Version 1.4: Multiple Assignment Command

This is not necessarily the current version of this TIP.


TIP:57
Title:Multiple Assignment Command
Version:$Revision: 1.4 $
Authors: Agnar Renolen <agnar dot renolen at emap dot no>
Donal K. Fellows <fellowsd at cs dot man dot ac dot uk>
State:Draft
Type:Project
Tcl-Version:8.4
Vote:Pending
Created:Thursday, 30 August 2001

Abstract

This TIP proposes a new function mset (or a modification to set) to perform multiple assignment.

Introduction

In many cases, a command needs to return more than one return value to the caller. For example, suppose that the statement:

 set coords [LocateFeature $featureID]

would set the variable "coords" to a list containing two elements "x" and "y". Assume that you need to set the "x" and "y" components directly, you can do this today using the following statement:

 foreach {x y} [LocateFeature $featureID] {}

Now, this is not what the foreach command was designed for, and it is not obvious at first glance from the source code what the statement does. Although it is quite useful for the purpose described in this TIP, It would be more logical if the developer could write the following:

 set {x y} [LocateFeature $featureID]

or

 mset {x y} [LocateFeature $featureID]

Design Alternatives

mset command

The following Tcl code is an implementation I have made myself for mset. Because it returns the remaining elements in the list that were not assigned to a value, the proposed specification is not suitable as an extension to set, but rather as a new command mset.

 ##
 #   mset - set multiple variables with values from a list
 #
 # SYNOPSIS
 #   [mset <varlist> <valuelist>]
 #
 # DESCRIPTION
 #   Sets multiple variables with values from a list.  The <varlist>
 #   contains variable names and each variable will be assigned the
 #   corresponding value in <valuelist>.  For example
 #
 #   [mset \{name age sex\} \{Bill 42 male\}]
 #
 #   It is an error if <valuelist> contains fewer elements than the
 #   <varlist>.  If the valuelist contains more elements than the
 #   <varlist> the exceeding values will not be assigned to any
 #   variable.
 #
 #   The procedure returns the a list containing the remaining 
 #   elements in <valuelist> that were no assigned to a variable.
 ##
 
 proc misc::mset {varList valueList} {
     if {[llength $varList] > [llength $valueList]} {
 	error "mset error: more variables than values"
     }
     set i 0
     foreach varName $varList {
 	upvar $varName var
 	set var [lindex $valueList $i]
 	incr i
     }
     return [lrange $valueList 0 [expr $i - 1]]
 }

Following this definition the command

 mset {name age} {Bill 42 male developer}

will set name to "Bill" and age to "42" and return the list

 {male developer}

Extended set command

If set is extended rather than introducing a new mset command, it should return a list comprising the elements that were set, so

 set {name age} {Bill 42 male developer}

would return the list,

 {Bill 42}

However, this is incompatible with the current set function, as it would set a variable named "{name age}" to the entire list. This alternative must therefore be rejected.

lassign command

There is an lassign command evailable in TclX, The author is unaware of its definition, but expect the functionality described for extended set command above.

Can somebody fill me inn(?)

other alternatives

So far, we have described two types of multiple assignment functions, one that returns the list containing the values that were assigned to variables, and one that would return the remaining values of the input list. A third alternatvie would be to define the command such that the user actually can specify what he'd like to have returned. Let's call the new command assign, and define it like this:

 assign ?switches? <varList> <valueList>

Suggested switches:

--nocomplain

prevents assign from throwing an error if the <valueList> is shorter than the <varList>.

--count

makes assign return the number of variables set.

--ecount

makes assign return the number of items in the <valueList> minus the number of items in th <varList>.

--exceed

makes assign return the exceeding values in <valueList> that were not assigned to variables in the list (same as mseet above).

---

marks the end of switches.

Default behaviour is that assign returns the list of the variables set.

Hence:

 assign {name age} {Bill 42 male developer}

returns "{Bill 42}"

 assign -count {name age} {Bill 42 male developer}

returns "2"

 assign -ecount {name age sex} {Bill 42 male developer}

returns "1"

 assign -exceed {name age {Bill 42 male developer}

returns "{male developer}"

Evaluation of Alternatives

The advantage of the mset command is that it provides a convenient way to take care of exceeding values when you have assigned the first values to variables. The -exceed switch of assign would handle this. assign provides the most flexibility and also provides extensibilty since switches are implemented into the function (Hence it is possible to add more switches and options).

Feedback

dkf - This is, of course, [lassign] from TclX, and it is a really bad idea to change the syntax of [set] as it is our only mechanism for handling wierdly-named variables.

Copyright

This document is placed in the public domain.


Powered by TclThis is not necessarily the current version of this TIP.

TIP AutoGenerator - written by Donal K. Fellows