Updated 2016-04-09 01:48:25 by aspect

The identity function accepts one value and simply returns that value.

Tcl 8.6 introduces a purpose built identity function in the core:

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:

• K \$x {}
• proc identity {x} {set x}
• proc K* {x args} {set x} -- a multi-purpose K variant

## Reference  edit

Identity function, Wikipedia

## Description  edit

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* \$x```

There 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  edit

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}`