identity function
The identity function accepts one value and simply returns that value.
Tcl 8.6 introduces a purpose built identity function in the core:
- string cat $x
Prior to that, different forms were common:
- return -level 0 $x -- a command intended for the purpose, but quite awkward to type
- lindex $x -- shorter but arguably less obvious
And in proc form, close variants of K serve:
Reference
- Identity function , Wikipedia
Description
Various built-in commands simply return their argument and can also be used as an identity function. Some commands are very near misses: they'll work most of the time, until they don't. Those are called out with counterexamples in a comment in the list below.
set x {some\{value}
#canonical identity functions
string cat $x ;# 8.6+
return -level 0 $x
# emergent identity functions and near misses:
concat $x ;# miss: " x "
expr {$x} ;# miss: 09, 1.00, 007, 0x10, " 100"
lindex $x
list $x ;# miss: \{, \$, \", [
lrepeat 1 $x ;# miss: \{, \$, \", [
regexp -inline .* $x
regsub .* $x $x
return -level 0 $x
string cat $x
string map {} $x
string range $x 0 end
string repeat $x 1
string replace $x -1 -1
string trim $x {}
string trimleft $x {}
string trimright $x {}
K $x {}
K* $xThere are various more obvious ways to get it wrong:
# misses due to under-quoting: expr $x ;# miss: 2+2 subst $x ;# miss: $somevar # only work on well-formed lists dict merge $x join $x lassign $x # only work on even-length lists dict remove $x dict replace $x
Discussion
AMG: Let's say you have to pass a script to eval, and the value eval returns is used somehow. What script do you pass if you want eval to simply return a constant, the result of a substitution, or a concatenated combination thereof? All of the above methods work, and return -level 0 avoids the need for extra quoting or proc wrappers. This all can be quite useful in functional contexts.
An example use from the if page:
set y [if {$x} {lindex a} else {lindex b}]Another approach, on the switch page, thanks to RS (2005-05-30):
proc is x {set x}
set type [switch -- $num {
1 - 9 {is odd}
2 - 3 - 5 - 7 {is prime}
0 - 4 - 6 - 8 {is even}
}]It's possible to delete the proc line and replace is with "lindex" or "return -level 0".
PYK: In the wild, list $x is seen being put to use as the identify function, but it's not a safe bet, because list will perform quoting on the argument when necessary to make the value well-formed item in a single-item list.
AMG: Brush offers the [:] command (that's a single colon) which acts as the identity function when passed one argument. Given zero arguments, it returns empty string. Given two arguments, it behaves as [K], returning only the first argument. Likewise three or more arguments: it returns the first. [:] can be implemented in Tcl thus:
proc : {args} {lindex $args 0}See Also
- I Know Nothing
- more discussion of -level
- Single-argument dict merge/remove/replace , a Tcl bug tracker ticket
- At the moment (2014-05-28), single-argument [dict merge/remove/replace] are unintentional identity functions, even when their argument is not a valid dict.
- shorthand dict set
- includes set and get where get acts as the identity function when 1 arg is passed, but acts like dict get for > 1 args.