Version 19 of identity function

Updated 2016-04-08 07:41:22 by foobar

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

Reference

Identity function , Wikipedia

Description

PYK: The identity function is trivial to implement in Tcl:

proc identity val {return $val}

An unnamed variant looks like this:

apply {x {set x}} $x

return -level 0 $x is the canonical built-in identity function. It simply sets the interpreter result to $x, and returns to the current level, allowing Tcl to continue processing the script at the current level. It's an unusual, but often quite useful, way to employ return.

AMG: Does return -level 0 $x have any advantage over lindex $x? Why do you say it is the canonical identity function?

PYK 2014-05-29: I dubbed it "canonical" because I see it as the only built-in command explicitly designed to do this. Yes, I know that lindex $mylist was also given this behaviour not-by-accident, but why then was return -level 0 $x also devised ? Actually, I always use lindex for this purpose.

AMG: return -level 0 exists due to the generality of the -level option. Tcl actually has many cases of features emerging by accident, for instance variables (especially arrays) with empty string as their name.


PYK: Various built-in commands simply return their argument and can also be used as an identity function.

set x {some\{value}

#the following all act as identity functions

concat $x
#brace-quoted for safety
expr {$x}
lindex $x
lrepeat 1 $x    
regexp -inline .* $x
regsub .* $x $x
return -level 0 $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 {}
#brace-quoted for safety
subst {$x}

K $x {}
K* $x

# The following behave as identity functions, but only due to a bug in Tcl
dict remove $x
dict replace $x

#these only work when $x is a well-formed list
dict merge $x
join $x
lassign $x

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.