Posted to tcl by stevel at Thu Jul 20 03:00:11 GMT 2023view raw

  1. # NAME
  2.  
  3. apply - Apply an anonymous function
  4.  
  5. # SYNOPSIS
  6.  
  7. **apply ***func* ?*arg1 arg2 \...*?
  8.  
  9. # DESCRIPTION
  10.  
  11. The command **apply** applies the function *func* to the arguments *arg1
  12. arg2 \...* and returns the result.
  13.  
  14. The function *func* is a two element list *{args body}* or a three
  15. element list *{args body namespace}* (as if the **list** command had
  16. been used). The first element *args* specifies the formal arguments to
  17. *func*. The specification of the formal arguments *args* is shared with
  18. the **proc** command, and is described in detail in the corresponding
  19. manual page.
  20.  
  21. The contents of *body* are executed by the Tcl interpreter after the
  22. local variables corresponding to the formal arguments are given the
  23. values of the actual parameters *arg1 arg2 \...*. When *body* is being
  24. executed, variable names normally refer to local variables, which are
  25. created automatically when referenced and deleted when **apply**
  26. returns. One local variable is automatically created for each of the
  27. function\'s arguments. Global variables can only be accessed by invoking
  28. the **global** command or the **upvar** command. Namespace variables can
  29. only be accessed by invoking the **variable** command or the **upvar**
  30. command.
  31.  
  32. The invocation of **apply** adds a call frame to Tcl\'s evaluation stack
  33. (the stack of frames accessed via **uplevel**). The execution of *body*
  34. proceeds in this call frame, in the namespace given by *namespace* or in
  35. the global namespace if none was specified. If given, *namespace* is
  36. interpreted relative to the global namespace even if its name does not
  37. start with
  38.  
  39. The semantics of **apply** can also be described by:
  40.  
  41. proc apply {fun args} {
  42. set len [llength $fun]
  43. if {($len < 2) || ($len > 3)} {
  44. error "can't interpret \"$fun\" as anonymous function"
  45. }
  46. lassign $fun argList body ns
  47. set name ::$ns::[getGloballyUniqueName]
  48. set body0 {
  49. rename [lindex [info level 0] 0] {}
  50. }
  51. proc $name $argList ${body0}$body
  52. set code [catch {uplevel 1 $name $args} res opt]
  53. return -options $opt $res
  54. }
  55.  
  56. # EXAMPLES
  57.  
  58. This shows how to make a simple general command that applies a
  59. transformation to each element of a list.
  60.  
  61. proc map {lambda list} {
  62. set result {}
  63. foreach item $list {
  64. lappend result [apply $lambda $item]
  65. }
  66. return $result
  67. }
  68. map {x {return [string length $x]:$x}} {a bb ccc dddd}
  69. ’ 1:a 2:bb 3:ccc 4:dddd
  70. map {x {expr {$x**2 + 3*$x - 2}}} {-4 -3 -2 -1 0 1 2 3 4}
  71. ’ 2 -2 -4 -4 -2 2 8 16 26
  72.  
  73. The **apply** command is also useful for defining callbacks for use in
  74. the **trace** command:
  75.  
  76. set vbl "123abc"
  77. trace add variable vbl write {apply {{v1 v2 op} {
  78. upvar 1 $v1 v
  79. puts "updated variable to \"$v\""
  80. }}}
  81. set vbl 123
  82. set vbl abc
  83.  
  84. # SEE ALSO
  85.  
  86. proc(n), uplevel(n)
  87.  
  88. # KEYWORDS
  89.  
  90. anonymous function, argument, lambda, procedure,
  91.