builtin_fn_flow.d.elv 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #elvdoc:fn run-parallel
  2. #
  3. # ```elvish
  4. # run-parallel $callable ...
  5. # ```
  6. #
  7. # Run several callables in parallel, and wait for all of them to finish.
  8. #
  9. # If one or more callables throw exceptions, the other callables continue running,
  10. # and a composite exception is thrown when all callables finish execution.
  11. #
  12. # The behavior of `run-parallel` is consistent with the behavior of pipelines,
  13. # except that it does not perform any redirections.
  14. #
  15. # Here is an example that lets you pipe the stdout and stderr of a command to two
  16. # different commands in order to independently capture the output of each byte stream:
  17. #
  18. # ```elvish-transcript
  19. # ~> fn capture {|f|
  20. # var pout = (file:pipe)
  21. # var perr = (file:pipe)
  22. # var out err
  23. # run-parallel {
  24. # $f > $pout[w] 2> $perr[w]
  25. # file:close $pout[w]
  26. # file:close $perr[w]
  27. # } {
  28. # set out = (slurp < $pout[r])
  29. # file:close $pout[r]
  30. # } {
  31. # set err = (slurp < $perr[r])
  32. # file:close $perr[r]
  33. # }
  34. # put $out $err
  35. # }
  36. # ~> capture { echo stdout-test; echo stderr-test >&2 }
  37. # ▶ "stdout-test\n"
  38. # ▶ "stderr-test\n"
  39. # ```
  40. #
  41. # This command is intended for doing a fixed number of heterogeneous things in
  42. # parallel. If you need homogeneous parallel processing of possibly unbound data,
  43. # use `peach` instead.
  44. #
  45. # @cf peach
  46. #elvdoc:fn each
  47. #
  48. # ```elvish
  49. # each $f $inputs?
  50. # ```
  51. #
  52. # Calls `$f` on each [value input](#value-inputs).
  53. #
  54. # An exception raised from [`break`](#break) is caught by `each`, and will
  55. # cause it to terminate early.
  56. #
  57. # An exception raised from [`continue`](#continue) is swallowed and can be used
  58. # to terminate a single iteration early.
  59. #
  60. # Examples:
  61. #
  62. # ```elvish-transcript
  63. # ~> range 5 8 | each {|x| * $x $x }
  64. # ▶ 25
  65. # ▶ 36
  66. # ▶ 49
  67. # ~> each {|x| put $x[:3] } [lorem ipsum]
  68. # ▶ lor
  69. # ▶ ips
  70. # ```
  71. #
  72. # @cf peach
  73. #
  74. # Etymology: Various languages, as `for each`. Happens to have the same name as
  75. # the iteration construct of
  76. # [Factor](http://docs.factorcode.org/content/word-each,sequences.html).
  77. #elvdoc:fn peach
  78. #
  79. # ```elvish
  80. # peach $f $inputs?
  81. # ```
  82. #
  83. # Calls `$f` for each [value input](#value-inputs), possibly in parallel.
  84. #
  85. # Like `each`, an exception raised from [`break`](#break) will cause `peach`
  86. # to terminate early. However due to the parallel nature of `peach`, the exact
  87. # time of termination is non-deterministic, and termination is not guaranteed.
  88. #
  89. # An exception raised from [`continue`](#continue) is swallowed and can be used
  90. # to terminate a single iteration early.
  91. #
  92. # Example (your output will differ):
  93. #
  94. # ```elvish-transcript
  95. # ~> range 1 10 | peach {|x| + $x 10 }
  96. # ▶ (num 12)
  97. # ▶ (num 13)
  98. # ▶ (num 11)
  99. # ▶ (num 16)
  100. # ▶ (num 18)
  101. # ▶ (num 14)
  102. # ▶ (num 17)
  103. # ▶ (num 15)
  104. # ▶ (num 19)
  105. # ~> range 1 101 |
  106. # peach {|x| if (== 50 $x) { break } else { put $x } } |
  107. # + (all) # 1+...+49 = 1225; 1+...+100 = 5050
  108. # ▶ (num 1328)
  109. # ```
  110. #
  111. # This command is intended for homogeneous processing of possibly unbound data. If
  112. # you need to do a fixed number of heterogeneous things in parallel, use
  113. # `run-parallel`.
  114. #
  115. # @cf each run-parallel
  116. #elvdoc:fn fail
  117. #
  118. # ```elvish
  119. # fail $v
  120. # ```
  121. #
  122. # Throws an exception; `$v` may be any type. If `$v` is already an exception,
  123. # `fail` rethrows it.
  124. #
  125. # ```elvish-transcript
  126. # ~> fail bad
  127. # Exception: bad
  128. # [tty 9], line 1: fail bad
  129. # ~> put ?(fail bad)
  130. # ▶ ?(fail bad)
  131. # ~> fn f { fail bad }
  132. # ~> fail ?(f)
  133. # Exception: bad
  134. # Traceback:
  135. # [tty 7], line 1:
  136. # fn f { fail bad }
  137. # [tty 8], line 1:
  138. # fail ?(f)
  139. # ```
  140. #elvdoc:fn return
  141. #
  142. # ```elvish
  143. # return
  144. # ```
  145. #
  146. # Raises the special "return" exception. When raised inside a named function
  147. # (defined by the [`fn` keyword](language.html#fn)) it is captured by the
  148. # function and causes the function to terminate. It is not captured by an
  149. # ordinary anonymous function.
  150. #
  151. # Because `return` raises an exception it can be caught by a
  152. # [`try`](language.html#try) block. If not caught, either implicitly by a
  153. # named function or explicitly, it causes a failure like any other uncaught
  154. # exception.
  155. #
  156. # See the discussion about [flow commands and
  157. # exceptions](language.html#exception-and-flow-commands)
  158. #
  159. # **Note**: If you want to shadow the builtin `return` function with a local
  160. # wrapper, do not define it with `fn` as `fn` swallows the special exception
  161. # raised by return. Consider this example:
  162. #
  163. # ```elvish-transcript
  164. # ~> use builtin
  165. # ~> fn return { put return; builtin:return }
  166. # ~> fn test-return { put before; return; put after }
  167. # ~> test-return
  168. # ▶ before
  169. # ▶ return
  170. # ▶ after
  171. # ```
  172. #
  173. # Instead, shadow the function by directly assigning to `return~`:
  174. #
  175. # ```elvish-transcript
  176. # ~> use builtin
  177. # ~> var return~ = { put return; builtin:return }
  178. # ~> fn test-return { put before; return; put after }
  179. # ~> test-return
  180. # ▶ before
  181. # ▶ return
  182. # ```
  183. #elvdoc:fn break
  184. #
  185. # ```elvish
  186. # break
  187. # ```
  188. #
  189. # Raises the special "break" exception. When raised inside a loop it is
  190. # captured and causes the loop to terminate.
  191. #
  192. # Because `break` raises an exception it can be caught by a
  193. # [`try`](language.html#try) block. If not caught, either implicitly by a loop
  194. # or explicitly, it causes a failure like any other uncaught exception.
  195. #
  196. # See the discussion about [flow commands and exceptions](language.html#exception-and-flow-commands)
  197. #
  198. # **Note**: You can create a `break` function and it will shadow the builtin
  199. # command. If you do so you should explicitly invoke the builtin. For example:
  200. #
  201. # ```elvish-transcript
  202. # ~> use builtin
  203. # ~> fn break { put 'break'; builtin:break; put 'should not appear' }
  204. # ~> for x [a b c] { put $x; break; put 'unexpected' }
  205. # ▶ a
  206. # ▶ break
  207. # ```
  208. #elvdoc:fn continue
  209. #
  210. # ```elvish
  211. # continue
  212. # ```
  213. #
  214. # Raises the special "continue" exception. When raised inside a loop it is
  215. # captured and causes the loop to begin its next iteration.
  216. #
  217. # Because `continue` raises an exception it can be caught by a
  218. # [`try`](language.html#try) block. If not caught, either implicitly by a loop
  219. # or explicitly, it causes a failure like any other uncaught exception.
  220. #
  221. # See the discussion about [flow commands and exceptions](language.html#exception-and-flow-commands)
  222. #
  223. # **Note**: You can create a `continue` function and it will shadow the builtin
  224. # command. If you do so you should explicitly invoke the builtin. For example:
  225. #
  226. # ```elvish-transcript
  227. # ~> use builtin
  228. # ~> fn continue { put 'continue'; builtin:continue; put 'should not appear' }
  229. # ~> for x [a b c] { put $x; continue; put 'unexpected' }
  230. # ▶ a
  231. # ▶ continue
  232. # ▶ b
  233. # ▶ continue
  234. # ▶ c
  235. # ▶ continue
  236. # ```
  237. #elvdoc:fn defer
  238. #
  239. # ```elvish
  240. # defer $fn
  241. # ```
  242. #
  243. # Schedules a function to be called when execution reaches the end of the
  244. # current closure. The function is called with no arguments or options, and any
  245. # exception it throws gets propagated.
  246. #
  247. # Examples:
  248. #
  249. # ```elvish-transcript
  250. # ~> { defer { put foo }; put bar }
  251. # ▶ bar
  252. # ▶ foo
  253. # ~> defer { put foo }
  254. # Exception: defer must be called from within a closure
  255. # [tty 2], line 1: defer { put foo }
  256. # ```