/doc/srfi-std/srfi-86.html

http://github.com/gmarceau/PLT · HTML · 1937 lines · 1768 code · 169 blank · 0 comment · 0 complexity · 9b1391b61a1743729cb7d17456b08b44 MD5 · raw file

Large files are truncated click here to view the full file

  1. <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
  2. <html><head><title>SRFI 86: MU and NU simulating VALUES &amp; CALL-WITH-VALUES, and their related LET-syntax</title></head><body>
  3. <h1>Title</h1>
  4. MU and NU simulating VALUES &amp; CALL-WITH-VALUES, and their related LET-syntax
  5. <h1>Author</h1>
  6. Joo ChurlSoo
  7. <h1>Status</h1>
  8. This SRFI is currently in ``final'' status. To see an explanation of each
  9. status that a SRFI can hold, see
  10. <a href="http://srfi.schemers.org/srfi%20minus%20process.html">here</a>.
  11. To
  12. provide input on this SRFI, please <code>
  13. <a href="mailto:srfi-86%20at%20srfi%20dot%20schemers%20dot%20org">mailto:srfi minus 86 at srfi dot schemers dot org</a></code>.
  14. See <a href="http://srfi.schemers.org/srfi%20minus%20list-subscribe.html">instructions
  15. here</a> to subscribe to the list. You can access the discussion via
  16. <a href="http://srfi.schemers.org/srfi-86/mail-archive/maillist.html">the
  17. archive of the mailing list</a>.
  18. You can access
  19. post-finalization messages via
  20. <a href="http://srfi.schemers.org/srfi-86/post-mail-archive/maillist.html">
  21. the archive of the mailing list</a>.
  22. <p>
  23. </p><ul>
  24. <li>Received: <a href="http://srfi.schemers.org/cgi-bin/viewcvs.cgi/*checkout*/srfi/srfi-86/srfi-86.txt?rev=1.1">2006/04/03</a></li>
  25. <li>Revised: <a href="http://srfi.schemers.org/cgi-bin/viewcvs.cgi/*checkout*/srfi/srfi-86/srfi-86.txt?rev=1.2">2006/05/08</a></li>
  26. <li>Revised: <a href="http://srfi.schemers.org/cgi-bin/viewcvs.cgi/*checkout*/srfi/srfi-86/srfi-86.txt?rev=1.3">2006/05/22</a></li>
  27. <li>Revised: <a href="http://srfi.schemers.org/cgi-bin/viewcvs.cgi/*checkout*/srfi/srfi-86/srfi-86.txt?rev=1.4">2006/06/20</a></li>
  28. <li>Final: <a href="http://srfi.schemers.org/cgi-bin/viewcvs.cgi/*checkout*/srfi/srfi-86/srfi-86.html?rev=1.7">2006/06/20</a></li>
  29. <li>Draft: 2006/04/04 - 2006/06/01</li>
  30. </ul>
  31. <h1>Abstract</h1>
  32. <p>
  33. Unlike the <code>values</code>/<code>call-with-values</code> mechanism of
  34. R5RS, this SRFI uses an explicit representation for multiple return
  35. values as a single value, namely a procedure. Decomposition of
  36. multiple values is done by simple application. Each of the two
  37. macros, <code>mu</code> and <code>nu</code>, evaluates to a procedure
  38. that takes one procedure argument. The <code>mu</code> and
  39. <code>nu</code> can be compared with <code>lambda</code>. While
  40. <code>lambda</code> expression that consists of &lt;formals&gt; and &lt;body&gt;
  41. requires some actual arguments later when the evaluated
  42. <code>lambda</code> expression is called, <code>mu</code> and
  43. <code>nu</code> expressions that consist of &lt;expression&gt;s
  44. corresponding to actual arguments of <code>lambda</code> require
  45. &lt;formals&gt; and &lt;body&gt;, that is, an evaluated <code>lambda</code>
  46. expression, later when the evaluated <code>mu</code> and
  47. <code>nu</code> expressions are called.
  48. </p>
  49. <p>
  50. This SRFI also introduces new <code>let</code>-syntax depending on
  51. <code>mu</code> and <code>nu</code> to manipulate multiple values,
  52. <code>alet</code> and <code>alet*</code> that are compatible with
  53. <code>let</code> and <code>let*</code> of R5RS in single value
  54. bindings. They also have a binding form making use of
  55. <code>values</code> and <code>call-with-values</code> to handle
  56. multiple values. In addition, they have several new binding forms for
  57. useful functions such as escape, recursion, etc.
  58. </p>
  59. <h1>Rationale</h1>
  60. <p>
  61. It is impossible to bind the evaluated result of <code>values</code>
  62. expression to a single variable unlike other Scheme expressions.
  63. Moreover, the pair of <code>values</code> and
  64. <code>call-with-values</code> is clumsy to use and somewhat slow under
  65. some circumstances. A solution would be to enclose the arguments of
  66. <code>values</code> expression in a procedure of one argument, a
  67. consumer procedure of <code>call-with-values</code>. The following are examples to
  68. show the differences.
  69. </p>
  70. <pre>(define v (values 1 2 3)) =&gt; error
  71. (define v (lambda () (values 1 2 3))) =&gt; (lambda () (values 1 2 3))
  72. (define m (mu 1 2 3)) =&gt; (lambda (f) (f 1 2 3))
  73. (define a (apply values 1 '(2 3))) =&gt; error
  74. (define a
  75. (lambda () (apply values 1 '(2 3)))) =&gt; (lambda () (apply values 1 '(2 3)))
  76. (define n (nu 1 '(2 3))) =&gt; (lambda (f) (apply f 1 '(2 3)))
  77. (call-with-values v list) =&gt; (1 2 3)
  78. (m list) =&gt; (1 2 3)
  79. (call-with-values a list) =&gt; (1 2 3)
  80. (n list) =&gt; (1 2 3)
  81. </pre>
  82. <p>
  83. The <code>alet</code> and <code>alet*</code> are cases in point to use
  84. <code>mu</code> and <code>nu</code>. The differences between this
  85. <code>let</code>-syntax and others, and some additional functions are
  86. best explained by simple examples.
  87. </p>
  88. <ol>
  89. <li>
  90. <p>The following are rest argument forms of each SRFI.</p>
  91. <p>In <a href="#SRFI11">SRFI 11</a>:</p>
  92. <pre>(let-values ((a (values 1 2)) ((b c) (values 3 4)))
  93. (list a b c))
  94. =&gt; ((1 2) 3 4)
  95. </pre>
  96. <p>In <a href="#SRFI71">SRFI 71</a>:</p>
  97. <pre>(srfi-let (((values . a) (values 1 2)) ((values b c) (values 3 4)))
  98. (list a b c))
  99. =&gt; ((1 2) 3 4)
  100. </pre>
  101. <p>In this SRFI:</p>
  102. <pre>(alet (a (mu 1 2) ((b c) (mu 3 4)))
  103. (list a b c))
  104. =&gt; ((1 2) 3 4)
  105. </pre>
  106. </li>
  107. <li><p>The expressions for <code>alet</code> bindings are evaluated in
  108. sequence from left to right unlike <code>let</code> of R5RS and
  109. <code>let</code> of <a href="#SRFI71">SRFI 71</a>.</p>
  110. <p>In <a href="#SRFI71">SRFI 71</a>:</p>
  111. <pre>(srfi-let ((a (begin (display "1st") 1))
  112. (b c (values (begin (display "2nd") 2) 3))
  113. (d (begin (display "3rd") 4))
  114. ((values e . f) (values (begin (display "4th") 5) 6)))
  115. (list a b c d e f))
  116. =&gt; 2nd4th1st3rd(1 2 3 4 5 (6))
  117. </pre>
  118. <p>In this SRFI:</p>
  119. <pre>(alet ((a (begin (display "1st") 1))
  120. (b c (mu (begin (display "2nd") 2) 3))
  121. (d (begin (display "3rd") 4))
  122. ((e . f) (mu (begin (display "4th") 5) 6)))
  123. (list a b c d e f))
  124. =&gt; 1st2nd3rd4th(1 2 3 4 5 (6))
  125. </pre>
  126. </li>
  127. <li><p>The bindings that require multiple values can take multiple expressions, if
  128. syntactically possible, as well as a single expression that produce
  129. multiple values.</p>
  130. <pre>(alet* (((a b) (mu 1 2))
  131. ((c d e) a (+ a b c) (+ a b c d))
  132. ((f . g) (mu 5 6 7))
  133. ((h i j . k) e 9 10 h i j))
  134. (list a b c d e f g h i j k))
  135. =&gt; (1 2 1 4 8 5 (6 7) 8 9 10 (8 9 10))
  136. </pre>
  137. </li>
  138. <li><p>The named-<code>alet</code> and named-<code>alet*</code> are
  139. allowed to take multiple values bindings.</p>
  140. <p>In <a href="#SRFI71">SRFI 71</a>:</p>
  141. <pre>(srfi-let tag ((a 1) (b 2) (c 3) (d 4) (e 5))
  142. (if (&lt; a 10) (tag 10 b c d e) (list a b c d e)))
  143. =&gt; (10 2 3 4 5)
  144. </pre>
  145. <p>In this SRFI:</p>
  146. <pre>(alet* tag ((a 1) (a b b c (mu (+ a 2) 4 5 6)) ((d e e) b 5 (+ a b c)))
  147. (if (&lt; a 10) (tag a 10 b c c d e d) (list a b c d e)))
  148. =&gt; (10 6 6 5 5)
  149. </pre>
  150. </li>
  151. <li><p>They have a new binding form that has a recursive function like
  152. named-<code>alet</code>. It is also allowed to take multiple values
  153. bindings.</p>
  154. <pre>(alet* ((a 1)
  155. ((b 2) (b c c (mu 3 4 5)) ((d e d (mu a b c)) . intag) . tag)
  156. (f 6))
  157. (if (&lt; d 10)
  158. (intag d e 10)
  159. (if (&lt; c 10)
  160. (tag b 11 c 12 a b d intag)
  161. (list a b c d e f))))
  162. =&gt; (1 11 12 10 3 6)
  163. </pre>
  164. </li>
  165. <li><p>They have a new binding form that has an escape function.</p>
  166. <pre>(alet ((exit)
  167. (a (begin (display "1st") 1))
  168. (b c (mu (begin (display "2nd") 2) (begin (display "3rd") 3))))
  169. (display (list a b c))
  170. (exit 10)
  171. (display "end"))
  172. =&gt; 1st2nd3rd(1 2 3)10
  173. </pre>
  174. </li>
  175. <li><p> The <code>and-let</code> and <code>and-let*</code> are
  176. integrated into the <code>alet</code> and <code>alet*</code> with a
  177. syntactic keyword <code>and</code>.</p>
  178. <pre>(alet ((and (a (begin (display "1st") 1))
  179. (b (begin (display "2nd") 2))
  180. (c (begin (display "false") #f))
  181. (d (begin (display "3nd") 3))))
  182. (list a b c d))
  183. =&gt; 1st2ndfalse#f
  184. (alet ((and (a (begin (display "1st") 1))
  185. (b (begin (display "2nd") 2) (&lt; b 2)) ; different from <a href="#SRFI2">SRFI 2</a>
  186. (c (begin (display "false") #f))
  187. (d (begin (display "3nd") 3))))
  188. (list a b c d))
  189. =&gt; 1st2nd#f
  190. </pre>
  191. </li>
  192. <li><p>The <code>rest-values</code> of <a href="#SRFI51">SRFI 51</a> is integrated into the
  193. <code>alet</code> and <code>alet*</code> with
  194. syntactic keywords <code>opt</code> and <code>cat</code> in the
  195. similar way to <code>let-optionals</code> in Scsh.</p>
  196. <pre>((lambda (str . rest)
  197. (alet* ((len (string-length str))
  198. (opt rest
  199. (start 0 (integer? start)
  200. (if (&lt; start 0) 0 (if (&lt; len start) len start))) ;true
  201. (end len (integer? end)
  202. (if (&lt; end start) start (if (&lt; len end) len end)))));true
  203. (substring str start end))) "abcdefg" 1 20)
  204. =&gt; "bcdefg"
  205. ((lambda (str . rest)
  206. (alet* ((len (string-length str))
  207. (min (apply min rest))
  208. (cat rest
  209. (start 0 (= start min)
  210. (if (&lt; start 0) 0 (if (&lt; len start) len start))) ;true
  211. (end len (integer? end)
  212. (if (&lt; end start) start (if (&lt; len end) len end)))));true
  213. (substring str start end))) "abcdefg" 20 1)
  214. =&gt; "bcdefg"
  215. ((lambda (str . rest)
  216. (alet ((cat rest
  217. (start 0
  218. (and (list? start) (= 2 (length start))
  219. (eq? 'start (car start)))
  220. (cadr start)) ; true
  221. (end (string-length str)
  222. (and (list? end) (= 2 (length end)) (eq? 'end (car end)))
  223. (cadr end)))) ; true
  224. (substring str start end))) "abcdefg" '(end 6) '(start 1))
  225. =&gt; "bcdef"
  226. </pre>
  227. </li>
  228. <li><p>The <code>let-keywords</code> and <code>let-keywords*</code>
  229. are integrated into the <code>alet</code> and
  230. <code>alet*</code> with a syntactic keyword <code>key</code>.
  231. They use any Scheme objects as keywords.
  232. </p><pre>(define rest-list '(a 10 cc 30 40 b 20))
  233. (alet ((key rest-list (a 1) (b 2) ((c 'cc) 3) . d)) (list a b c d))
  234. =&gt; (10 2 30 (40 b 20))
  235. (alet ((key rest-list (a 1) (b 2) ((c 'cc) 3) #f . d)) (list a b c d))
  236. =&gt; (10 2 30 (40 b 20))
  237. (alet ((key rest-list (a 1) (b 2) ((c 'cc) 3) #t . d)) (list a b c d))
  238. =&gt; (10 20 30 (40))
  239. (define rest (list 'a 10 'd 40 "c" 30 50 'b 20))
  240. (alet ((key rest (a 1) (b 2) ((c "c") 3) . d)) (list a b c d))
  241. =&gt; (10 2 30 (d 40 50 b 20))
  242. (alet ((key rest (a 1) (b 2) ((c "c") 3) #f . d)) (list a b c d))
  243. =&gt; (10 2 3 (d 40 "c" 30 50 b 20))
  244. (alet ((key rest (a 1) (b 2) ((c "c") 3) #t . d)) (list a b c d))
  245. =&gt; (10 20 30 (d 40 50))
  246. ((lambda (m . n)
  247. (alet* ((opt n (a 10) (b 20) (c 30) . d)
  248. (key d (x 100) (y 200) (a 300)))
  249. (list m a b c x y)))
  250. 0 1 2 3 'a 30 'y 20 'x 10)
  251. =&gt; (0 30 2 3 10 20)
  252. ((lambda (m . n)
  253. (alet* ((key n (x 100) (y 200) (a 300) . d)
  254. (opt d (a 10) (b 20) (c 30)))
  255. (list m a b c x y)))
  256. 0 'a 30 'y 20 'x 10 1 2 3)
  257. =&gt; (0 1 2 3 10 20)
  258. </pre>
  259. </li>
  260. <li><p>The <code>letrec</code>and <code>letrec*</code> are integrated
  261. into the <code>alet</code> and <code>alet*</code> with a
  262. syntactic keyword <code>rec</code>.</p>
  263. <pre>(alet* ((a 1)
  264. (rec (a 2) (b 3) (b (lambda () c)) (c a))
  265. (d 50))
  266. (list a (b) c d))
  267. =&gt; '(2 2 2 50)
  268. </pre>
  269. </li>
  270. <li><p>They have a binding form that use <code>call-with-values</code>
  271. and <code>values</code> to handle multiple values with a syntactic
  272. keyword <code>values</code> like <a href="#SRFI71">SRFI 71</a>.</p>
  273. <pre>(alet ((a b (mu 1 2))
  274. (values c d (values 3 4)) ;This is different from <a href="#SRFI71">SRFI 71</a>.
  275. ((e f) (mu 5 6))
  276. ((values g h) (values 7 8))
  277. ((i j . k) (nu 9 '(10 11 12)))
  278. ((values l m . n) (apply values 13 '(14 15 16)))
  279. o (mu 17 18)
  280. ((values . p) (values 19 20)))
  281. (list a b c d e f g h i j k l m n o p))
  282. =&gt; (1 2 3 4 5 6 7 8 9 10 (11 12) 13 14 (15 16) (17 18) (19 20))
  283. </pre>
  284. </li>
  285. <li><p>They have a new binding form that works as an intervening external
  286. environment in <code>alet</code> and as an intervening internal
  287. environment in <code>alet*</code>.</p>
  288. <pre>(alet ((a 1)
  289. (() (define a 10) (define b 100))
  290. (b a))
  291. (list a b))
  292. =&gt; (1 10)
  293. (alet* ((a 1)
  294. (() (define a 10) (define b 100))
  295. (b a))
  296. (list a b))
  297. =&gt; (10 10)
  298. </pre>
  299. </li>
  300. </ol>
  301. <h1>Specification</h1>
  302. <pre>(mu &lt;expr&gt; ...) =&gt; (lambda (f) (f &lt;expr&gt; ...))
  303. (nu &lt;expr&gt; ... &lt;exprn&gt;) =&gt; (lambda (f) (apply f &lt;expr&gt; ... &lt;exprn&gt;))
  304. </pre>
  305. <p>The &lt;exprn&gt; should be a list.</p>
  306. <p>
  307. Each macro evaluates to a procedure of one argument. The environment
  308. in effect when the macro expression was evaluated is remembered as
  309. part of the procedure. When the procedure is later called with an
  310. actual argument, a procedure, the environment in which the macro was
  311. evaluated is extended by binding &lt;expr&gt;s to the corresponding
  312. variables in the formal argument list of the argument procedure. The
  313. argument procedure of <code>mu</code> is called with the &lt;expr&gt;s,
  314. and that of <code>nu</code> is applied to APPLY procedure with the
  315. &lt;expr&gt;s.</p>
  316. <pre>(alet (&lt;binding spec&gt; ...) body ...)
  317. (alet* (&lt;binding spec&gt; ...) body ...)
  318. </pre>
  319. <p>
  320. <code>syntax-rules</code> identifier: <code>opt</code>
  321. <code>cat</code> <code>key</code> <code>and</code>
  322. <code>rec</code> <code>values</code>
  323. </p>
  324. <p>&lt;binding spec&gt;:</p>
  325. <ol>
  326. <li><pre>(&lt;var&gt; &lt;expr&gt;)</pre></li>
  327. <li><pre>(&lt;var1&gt; &lt;var2&gt; &lt;var3&gt; ... &lt;expr&gt;)</pre></li>
  328. <li><pre>((&lt;var&gt;) &lt;expr&gt;)</pre></li>
  329. <li><pre>((&lt;var1&gt; &lt;var2&gt; &lt;var3&gt; ... ) &lt;expr&gt;)</pre></li>
  330. <li><pre>((&lt;var1&gt; ... &lt;varm&gt; . &lt;varn&gt;) &lt;expr&gt;)</pre></li>
  331. <li><pre>((&lt;var1&gt; &lt;var2&gt; &lt;var3&gt; ... ) &lt;expr1&gt; &lt;expr2&gt; &lt;expr3&gt; ...)</pre></li>
  332. <li><pre>((&lt;var1&gt; ... &lt;varm&gt; . &lt;varn&gt;) &lt;expr1&gt; ... &lt;exprm&gt; &lt;exprn&gt; ...)</pre></li>
  333. <li><pre>&lt;var&gt; &lt;expr&gt; </pre></li>
  334. <li><pre>(&lt;var&gt;) </pre></li>
  335. <li><pre>(&lt;binding spec1&gt; &lt;binding spec2&gt; ... . &lt;var&gt;)</pre></li>
  336. <li><pre>(() . &lt;var&gt;)</pre></li>
  337. <li><pre>(and (&lt;var1&gt; &lt;expr1&gt; [&lt;test1&gt;]) (&lt;var2&gt; &lt;expr2&gt; [&lt;test2&gt;]) ...)</pre></li>
  338. <li><pre>(opt &lt;rest list&gt;
  339. (&lt;var1&gt; &lt;default1&gt; [&lt;test1&gt; [&lt;true substitute1&gt; [&lt;false substitute1&gt;]]])
  340. ...
  341. (&lt;varn&gt; &lt;defaultn&gt; [&lt;testn&gt; [&lt;true substituten&gt; [&lt;false substituten&gt;]]])
  342. . [&lt;rest var&gt;])</pre></li>
  343. <li><pre>(cat &lt;rest list&gt;
  344. (&lt;var1&gt; &lt;default1&gt; [&lt;test1&gt; [&lt;true substitute1&gt; [&lt;false substitute1&gt;]]])
  345. ...
  346. (&lt;varn&gt; &lt;defaultn&gt; [&lt;testn&gt; [&lt;true substituten&gt; [&lt;false substituten&gt;]]])
  347. . [&lt;rest var&gt;])</pre></li>
  348. <li><pre>(key &lt;rest list&gt;
  349. (&lt;var spec1&gt; &lt;default1&gt; [&lt;test1&gt; [&lt;true substitute1&gt; [&lt;false substitute1&gt;]]])
  350. ...
  351. (&lt;var specn&gt; &lt;defaultn&gt; [&lt;testn&gt; [&lt;true substituten&gt; [&lt;false substituten&gt;]]])
  352. [&lt;option&gt;]
  353. . [&lt;rest var&gt;])</pre></li>
  354. <li><pre>(rec (&lt;var1&gt; &lt;expr1&gt;) (&lt;var2&gt; &lt;expr2&gt;) ...)</pre></li>
  355. <li><pre>(values &lt;var1&gt; &lt;var2&gt; ... &lt;expr&gt;)</pre></li>
  356. <li><pre>((values &lt;var1&gt; &lt;var2&gt; ...) &lt;expr&gt;)</pre></li>
  357. <li><pre>((values &lt;var1&gt; ... . &lt;varn&gt;) &lt;expr&gt;) </pre></li>
  358. <li><pre>((values &lt;var1&gt; &lt;var2&gt; &lt;var3&gt; ...) &lt;expr1&gt; &lt;expr2&gt; &lt;expr3&gt; ...)</pre></li>
  359. <li><pre>((values &lt;var1&gt; ... . &lt;varn&gt;) &lt;expr1&gt; ... &lt;exprn&gt; ...) </pre></li>
  360. <li><pre>(() &lt;expr1&gt; &lt;expr2&gt; ...)</pre></li>
  361. </ol>
  362. <p>
  363. The <code>alet*</code> is to the <code>alet</code> what the
  364. <code>let*</code> is to the <code>let</code>. However, the &lt;binding
  365. spec&gt;s of <code>alet</code> are evaluated in sequence from left to
  366. spec&gt;right unlike <code>let</code> of
  367. R5RS. The <code>alet</code> and <code>alet*</code> make use of
  368. <code>mu</code> or <code>nu</code> instead of <code>values</code> to
  369. handle multiple values. So, the single &lt;expr&gt; of multiple values
  370. binding should be a <code>mu</code> or <code>nu</code> expression, or
  371. its equivalent. And the number of arguments of <code>mu</code> or the
  372. number of `applied' arguments of <code>nu</code> must match the number
  373. of values expected by the binding specification. Otherwise an error
  374. is signaled, as <code>lambda</code> expression would.
  375. </p>
  376. <ol>
  377. <li><pre>(&lt;var&gt; &lt;expr&gt;)</pre>
  378. This is the same as <code>let</code> (R5RS, 4.2.2).
  379. </li>
  380. <li><pre>(&lt;var1&gt; &lt;var2&gt; &lt;var3&gt; ... &lt;expr&gt;)</pre>
  381. This is the same as 4.</li>
  382. <li><pre>((&lt;var&gt;) &lt;expr&gt;)</pre>
  383. This is the same as 1.</li>
  384. <li><pre>((&lt;var1&gt; &lt;var2&gt; &lt;var3&gt; ... ) &lt;expr&gt;)</pre></li>
  385. <li><pre>((&lt;var1&gt; ... &lt;varm&gt; . &lt;varn&gt;) &lt;expr&gt;)</pre>
  386. The &lt;expr&gt; must be a <code>mu</code> or <code>nu</code>
  387. expression or its equivalent. The matching of &lt;var&gt;s to the
  388. values of &lt;expr&gt; is as for the matching of &lt;formals&gt; to
  389. arguments in a <code>lambda</code> expression (R5RS, 4.1.4).
  390. </li>
  391. <li><pre>((&lt;var1&gt; &lt;var2&gt; &lt;var3&gt; ... ) &lt;expr1&gt; &lt;expr2&gt; &lt;expr3&gt; ...)</pre>
  392. This is the same as
  393. <pre>(let[*] ((&lt;var1&gt; &lt;expr1&gt;) (&lt;var2&gt; &lt;expr2&gt;) (&lt;var3&gt; &lt;expr3&gt;) ...).</pre>
  394. </li>
  395. <li><pre>((&lt;var1&gt; ... &lt;varm&gt; . &lt;varn&gt;) &lt;expr1&gt; ... &lt;exprm&gt; &lt;exprn&gt; ...) </pre>
  396. This is the same as
  397. <pre>(let[*] ((&lt;var1&gt; &lt;expr1&gt;) ... (&lt;varm&gt; &lt;exprm&gt;) (&lt;varn&gt; (list &lt;exprn&gt; ...))).</pre>
  398. </li>
  399. <li><pre>&lt;var&gt; &lt;expr&gt;</pre>
  400. The &lt;var&gt; is a rest argument, so the &lt;expr&gt; should be a form that can deliver
  401. multiple values, that is, a <code>mu</code> or <code>nu</code> expression or its equivalent.
  402. </li>
  403. <li><pre>(&lt;var&gt;)</pre>
  404. The &lt;var&gt; becomes an escape procedure that can take return
  405. values of <code>alet</code>[*] as its arguments.
  406. </li><li><pre>(&lt;binding spec1&gt; &lt;binding spec2&gt; ... . &lt;var&gt;)</pre>
  407. The &lt;var&gt; becomes a recursive procedure that takes all &lt;vars&gt; of &lt;binding
  408. spec&gt;s as arguments.
  409. </li>
  410. <li><pre>(() . &lt;var&gt;)</pre>
  411. The &lt;var&gt; becomes a recursive thunk that takes no argument.
  412. </li>
  413. <li><pre>(and (&lt;var1&gt; &lt;expr1&gt; [&lt;test1&gt;]) (&lt;var2&gt; &lt;expr2&gt; [&lt;test2&gt;]) ...)</pre>
  414. Each &lt;expr&gt; is evaluated sequentially and bound to the
  415. corresponding &lt;var&gt;. During the process, if there is no
  416. &lt;test&gt; and the value of &lt;expr&gt; is false, it stops and
  417. returns <code>#f</code>. When there is a &lt;test&gt;, the process is continued
  418. regardless of the value of &lt;expr&gt; unless the value of &lt;test&gt; is
  419. false. If the value of &lt;test&gt; is false, it stops and returns #f.
  420. </li>
  421. <li>
  422. <pre>(opt &lt;rest list&gt;
  423. (&lt;var1&gt; &lt;default1&gt; [&lt;test1&gt; [&lt;true substitute1&gt; [&lt;false substitute1&gt;]]])
  424. ...
  425. (&lt;varn&gt; &lt;defaultn&gt; [&lt;testn&gt; [&lt;true substituten&gt; [&lt;false substituten&gt;]]])
  426. . [&lt;rest var&gt;])
  427. </pre>
  428. This binds each &lt;var&gt; to a corresponding element of &lt;rest list&gt;.
  429. If there is no more element, then the corresponding &lt;default&gt; is
  430. evaluated and bound to the &lt;var&gt;. An error is signaled when
  431. there are more elements than &lt;var&gt;s. But if &lt;rest var&gt; is
  432. given, it is bound to the remaining elements. If there is a
  433. &lt;test&gt;, it is evaluated only when &lt;var&gt; is bound to an
  434. element of &lt;rest list&gt;. If it returns a false value and there is no
  435. &lt;false substitute&gt;, an error is signaled. If it returns a false value
  436. and there is a &lt;false
  437. substitute&gt;, &lt;var&gt; is rebound to the result of evaluating &lt;false substitute&gt;
  438. instead of signaling an error. If it returns a true value and there is a
  439. &lt;true substitute&gt;, &lt;var&gt; is rebound to the result of evaluating &lt;true
  440. substitute&gt;.
  441. </li>
  442. <li><pre>(cat &lt;rest list&gt;
  443. (&lt;var1&gt; &lt;default1&gt; [&lt;test1&gt; [&lt;true substitute1&gt; [&lt;false substitute1&gt;]]])
  444. ...
  445. (&lt;varn&gt; &lt;defaultn&gt; [&lt;testn&gt; [&lt;true substituten&gt; [&lt;false substituten&gt;]]])
  446. . [&lt;rest var&gt;])
  447. </pre>
  448. This is the same as the above <code>opt</code> except the binding
  449. method. It temporarily binds &lt;var&gt; to each elements of &lt;rest
  450. list&gt; sequentally, until &lt;test&gt; returns a true value, then
  451. the &lt;var&gt; is finally bound to the passed element. If there is
  452. no &lt;test&gt;, the first element of the remained &lt;rest list&gt;
  453. is regarded as passing. If any element of the &lt;rest list&gt; does
  454. not pass the &lt;test&gt;, the &lt;default&gt; is bound to the
  455. &lt;var&gt; instead of signaling an error. If there is a &lt;false
  456. substitute&gt; and &lt;test&gt; returns a false value, &lt;var&gt; is
  457. finally bound to the result of evaluating &lt;false substitute&gt;
  458. instead of the above process. If there is a &lt;true substitute&gt;
  459. and &lt;test&gt; returns a true value, &lt;var&gt; is finally bound to
  460. the result of evaluating &lt;true substitute&gt;.
  461. </li>
  462. <li><pre>(key &lt;rest list&gt;
  463. (&lt;var spec1&gt; &lt;default1&gt; [&lt;test1&gt; [&lt;true substitute1&gt; [&lt;false substitute1&gt;]]])
  464. ...
  465. (&lt;var specn&gt; &lt;defaultn&gt; [&lt;testn&gt; [&lt;true substituten&gt; [&lt;false substituten&gt;]]])
  466. [&lt;option&gt;]
  467. . [&lt;rest var&gt;])
  468. &lt;var spec&gt; --&gt; &lt;var&gt; | (&lt;var&gt; &lt;keyword&gt;)
  469. &lt;option&gt; --&gt; #f | #t
  470. &lt;keyword&gt; --&gt; &lt;any scheme object&gt;
  471. &lt;default&gt; --&gt; &lt;expression&gt;
  472. &lt;test&gt; --&gt; &lt;expression&gt;
  473. &lt;true substitute&gt; --&gt; &lt;expression&gt;
  474. &lt;false substitute&gt; --&gt; &lt;expression&gt;
  475. </pre>
  476. This <code>key</code> form is the same as the <code>cat</code> form in view of the fact that both
  477. don't use argument position for binding &lt;var&gt;s to elements of &lt;rest list&gt;.
  478. However, for extracting values from &lt;rest list&gt;, the former uses explicitly
  479. keywords and the latter uses implicitly &lt;test&gt;s. The keywords in this form
  480. are not self-evaluating symbols (keyword objects) but any scheme objects. The
  481. keyword used in &lt;rest list&gt; for the corresponding variable is a symbol of the
  482. same name as the variable of the &lt;var spec&gt; composed of a single &lt;var&gt;. But
  483. the keyword can be any scheme object when the &lt;var spec&gt; is specified as a
  484. parenthesized variable and a keyword.
  485. The elements of &lt;rest list&gt; are sequentially interpreted as a series of pairs,
  486. where the first member of each pair is a keyword and the second is the
  487. corresponding value. If there is no element for a particular keyword, the
  488. &lt;var&gt; is bound to the result of evaluating &lt;default&gt;. When there is a &lt;test&gt;,
  489. it is evaluated only when &lt;var&gt; is bound to an element of &lt;rest list&gt;. If it
  490. returns a false value and there is no &lt;false substitute&gt;, an error is
  491. signaled. If it returns a false value and there is a &lt;false substitute&gt;,
  492. &lt;var&gt; is rebound to the result of evaluating &lt;false substitute&gt; instead of
  493. signaling an error. If it returns a true value and there is a &lt;true
  494. substitute&gt;, &lt;var&gt; is rebound to the result of evaluating &lt;true substitute&gt;.
  495. When there are more elements than ones that are specified by &lt;var spec&gt;s, an
  496. error is signaled. But if &lt;rest var&gt; is given, it is bound to the remaining
  497. elements.
  498. The following options can be used to control binding behavior when the keyword
  499. of keyword-value pair at the bind processing site is different from any
  500. keywords specified by &lt;var spec&gt;s.
  501. <ol>
  502. <li>default -- the remaining elements of &lt;rest list&gt; are continually
  503. interpreted as a series of pairs.</li>
  504. <li><code>#f</code> - the variable is bound to the corresponding &lt;default&gt;.</li>
  505. <li><code>#t</code> - the remaining elements of &lt;rest list&gt; are
  506. continually interpreted as a single element until the element is a
  507. particular keyword.</li>
  508. </ol>
  509. </li>
  510. <li><pre>(rec (&lt;var1&gt; &lt;expr1&gt;) (&lt;var2&gt;
  511. &lt;expr2&gt;) ...)</pre>
  512. This is the same as <pre>(letrec[*] ((&lt;var1&gt; &lt;expr1&gt;) (&lt;var2&gt; &lt;expr2&gt;) ...)</pre>
  513. </li>
  514. <li><pre>(values &lt;var1&gt; &lt;var2&gt; ... &lt;expr&gt;)</pre>
  515. This is the same as 17.
  516. </li>
  517. <li><pre>((values &lt;var1&gt; &lt;var2&gt; ...) &lt;expr&gt;)</pre></li>
  518. <li><pre>((values &lt;var1&gt; ... . &lt;varn&gt;) &lt;expr&gt;)</pre>
  519. The &lt;expr&gt; should be a <code>values</code> expression or its
  520. equivalent. The matching of &lt;var&gt;s to the values of
  521. &lt;expr&gt; is as for the matching of &lt;formals&gt; to arguments in a
  522. <code>lambda</code> expression.
  523. </li>
  524. <li><pre>((values &lt;var1&gt; &lt;var2&gt; &lt;var3&gt; ...) &lt;expr1&gt; &lt;expr2&gt; &lt;expr3&gt; ...)</pre>
  525. This is the same as
  526. <pre>(let[*] ((&lt;var1&gt; &lt;expr1&gt;) (&lt;var2&gt; &lt;expr2&gt;) (&lt;var3&gt; &lt;expr3&gt;) ...)</pre>
  527. </li>
  528. <li><pre> ((values &lt;var1&gt; ... . &lt;varn&gt;) &lt;expr1&gt; ... &lt;exprn&gt; ...) </pre>
  529. This is the same as (let[*] ((&lt;var1&gt; &lt;expr1&gt;)
  530. ... (&lt;varn&gt; (list &lt;exprn&gt; ...))).
  531. </li>
  532. <li><pre>(() &lt;expr1&gt; &lt;expr2&gt; ...)</pre>
  533. This works as an intervening external environment in
  534. <code>alet</code>, and an intervening internal environment in
  535. <code>alet*</code>.
  536. </li>
  537. </ol>
  538. <pre>(alet name (&lt;binding spec&gt; ...) body ...)
  539. (alet* name (&lt;binding spec&gt; ...) body ...)
  540. </pre>
  541. <p>
  542. These are the same as the named-<code>let</code> (R5RS, 4.2.4) except
  543. binding specification. These allow all sorts of bindings in &lt;binding
  544. spec&gt;.</p>
  545. <h1>Examples</h1>
  546. <pre>(alet ((a (begin (display "1st") 1))
  547. ((b c) 2 (begin (display "2nd") 3))
  548. (() (define m #f) (define n (list 8)))
  549. ((d (begin (display "3rd") 4))
  550. (key '(e 5 tmp 6) (e 0) ((f 'tmp) 55)) . p)
  551. g (nu (begin (display "4th") 7) n)
  552. ((values . h) (apply values 7 (begin (display "5th") n)))
  553. ((m 11) (n n) . q)
  554. (rec (i (lambda () (- (j) 1)))
  555. (j (lambda () 10)))
  556. (and (k (begin (display "6th") m))
  557. (l (begin (display "end") (newline) 12)))
  558. (o))
  559. (if (&lt; d 10)
  560. (p 40 50 60)
  561. (if (&lt; m 100)
  562. (q 111 n)
  563. (begin (display (list a b c d e f g h (i) (j) k l m n))
  564. (newline))))
  565. (o (list o p q))
  566. (display "This is not displayed"))
  567. =&gt; 1st2nd3rd4th5th6th#f
  568. (alet* ((a (begin (display "1st") 1))
  569. ((b c) 2 (begin (display "2nd") 3))
  570. (() (define m #f) (define n (list 8)))
  571. ((d (begin (display "3rd") 4))
  572. (key '(e 5 tmp 6) (e 0) ((f 'tmp) 55)) . p)
  573. g (nu (begin (display "4th") 7) n)
  574. ((values . h) (apply values 7 (begin (display "5th") n)))
  575. ((m 11) (n n) . q)
  576. (rec (i (lambda () (- (j) 1)))
  577. (j (lambda () 10)))
  578. (and (k (begin (display "6th") m))
  579. (l (begin (display "end") (newline) 12)))
  580. (o))
  581. (if (&lt; d 10)
  582. (p 40 50 60)
  583. (if (&lt; m 100)
  584. (q 111 n)
  585. (begin (display (list a b c d e f g h (i) (j) k l m n))
  586. (newline))))
  587. (o (list o p q))
  588. (display "This is not displayed"))
  589. =&gt; 1st2nd3rd4th5th6thend
  590. 4th5th6thend
  591. 6thend
  592. (1 2 3 40 50 60 (7 8) (7 8) 9 10 111 12 111 (8))
  593. (#&lt;continuation&gt; #&lt;procedure:p&gt; #&lt;procedure:q&gt;)
  594. (define (arg-message head-message proc . message)
  595. (display head-message) (newline)
  596. (alet ((() . lp)
  597. (() (for-each display message))
  598. (arg (read)))
  599. (if (proc arg) arg (lp))))
  600. (define (substr str . rest)
  601. (alet* ((len (string-length str))
  602. (opt rest
  603. (start 0
  604. (and (integer? start) (&lt;= 0 start len))
  605. start
  606. (arg-message
  607. "The first argument:"
  608. (lambda (n) (and (integer? n) (&lt;= 0 n len)))
  609. "Write number (" 0 " &lt;= number &lt;= " len "): "))
  610. (end len
  611. (and (integer? end) (&lt;= start end len))
  612. end
  613. (arg-message
  614. "The second argument:"
  615. (lambda (n) (and (integer? n) (&lt;= start n len)))
  616. "Write number (" start " &lt;= number &lt;= " len "): "))))
  617. (substring str start end)))
  618. (substr "abcdefghi" 3)
  619. =&gt; "defghi"
  620. (substr "abcdefghi" 3 7)
  621. =&gt; "defg"
  622. (substr "abcdefghi" 20 7)
  623. =&gt; The first argument:
  624. Write number (0 &lt;= number &lt;= 9): 3
  625. "defg"
  626. (substr "abcdefghi" "a" 20)
  627. =&gt; The first argument:
  628. Write number (0 &lt;= number &lt;= 9): 2
  629. The second argument:
  630. Write number (2 &lt;= number &lt;= 9): 10
  631. Write number (2 &lt;= number &lt;= 9): 9
  632. "cdefghi"
  633. </pre>
  634. <h1>Implementation</h1>
  635. <p>
  636. The following implementation is written in R5RS hygienic macros and
  637. requires SRFI 23 (Error reporting mechanism).
  638. </p>
  639. <pre>;;; mu &amp; nu
  640. (define-syntax mu
  641. (syntax-rules ()
  642. ((mu argument ...)
  643. (lambda (f) (f argument ...)))))
  644. (define-syntax nu
  645. (syntax-rules ()
  646. ((nu argument ...)
  647. (lambda (f) (apply f argument ...)))))
  648. ;;; alet
  649. (define-syntax alet
  650. (syntax-rules ()
  651. ((alet (bn ...) bd ...)
  652. (%alet () () (bn ...) bd ...))
  653. ((alet var (bn ...) bd ...)
  654. (%alet (var) () (bn ...) bd ...))))
  655. (define-syntax %alet
  656. (syntax-rules (opt cat key rec and values)
  657. ((%alet () ((n v) ...) () bd ...)
  658. ((lambda (n ...) bd ...) v ...))
  659. ((%alet (var) ((n v) ...) () bd ...)
  660. ((letrec ((var (lambda (n ...) bd ...)))
  661. var) v ...))
  662. ((%alet (var (p ...) (nv ...) (bn ...)) ((n v) ...) () bd ...)
  663. ((letrec ((t (lambda (v ...)
  664. (%alet (p ...) (nv ... (n v) ... (var t))
  665. (bn ...) bd ...))))
  666. t) v ...))
  667. ((%alet (p ...) (nv ...) ((() a b ...) bn ...) bd ...)
  668. ((lambda () a b ... (%alet (p ...) (nv ...) (bn ...) bd ...))))
  669. ((%alet (p ...) (nv ...) (((a) c) bn ...) bd ...)
  670. ((lambda (t) (%alet (p ...) (nv ... (a t)) (bn ...) bd ...)) c))
  671. ((%alet (p ...) (nv ...) (((values a) c) bn ...) bd ...)
  672. ((lambda (t) (%alet (p ...) (nv ... (a t)) (bn ...) bd ...)) c))
  673. ((%alet (p ...) (nv ...) (((values . b) c d ...) bn ...) bd ...)
  674. (%alet "dot" (p ...) (nv ...) (values) (b c d ...) (bn ...) bd ...))
  675. ((%alet "dot" (p ...) (nv ...) (values t ...) ((a . b) c ...)
  676. (bn ...) bd ...)
  677. (%alet "dot" (p ...) (nv ... (a tn)) (values t ... tn) (b c ...)
  678. (bn ...) bd ...))
  679. ((%alet "dot" (p ...) (nv ...) (values t ...) (() c) (bn ...) bd ...)
  680. (call-with-values (lambda () c)
  681. (lambda (t ...) (%alet (p ...) (nv ...) (bn ...) bd ...))))
  682. ((%alet "dot" (p ...) (nv ...) (values t ...) (() c ...) (bn ...) bd ...)
  683. ((lambda (t ...) (%alet (p ...) (nv ...) (bn ...) bd ...)) c ...))
  684. ((%alet "dot" (p ...) (nv ...) (values t ...) (b c) (bn ...) bd ...)
  685. (call-with-values (lambda () c)
  686. (lambda (t ... . tn)
  687. (%alet (p ...) (nv ... (b tn)) (bn ...) bd ...))))
  688. ((%alet "dot" (p ...) (nv ...) (values t ...) (b c ...) (bn ...) bd ...)
  689. ((lambda (t ... . tn)
  690. (%alet (p ...) (nv ... (b tn)) (bn ...) bd ...)) c ...))
  691. ((%alet (p ...) (nv ...) (((a . b) c d ...) bn ...) bd ...)
  692. (%alet "dot" (p ...) (nv ... (a t)) (t) (b c d ...) (bn ...) bd ...))
  693. ((%alet "dot" (p ...) (nv ...) (t ...) ((a . b) c ...) (bn ...) bd ...)
  694. (%alet "dot" (p ...) (nv ... (a tn)) (t ... tn) (b c ...) (bn ...)
  695. bd ...))
  696. ((%alet "dot" (p ...) (nv ...) (t ...) (() c) (bn ...) bd ...)
  697. (c (lambda (t ...) (%alet (p ...) (nv ...) (bn ...) bd ...))))
  698. ((%alet "dot" (p ...) (nv ...) (t ...) (() c ...) (bn ...) bd ...)
  699. ((lambda (t ...) (%alet (p ...) (nv ...) (bn ...) bd ...)) c ...))
  700. ((%alet "dot" (p ...) (nv ...) (t ...) (b c) (bn ...) bd ...)
  701. (c (lambda (t ... . tn) (%alet (p ...) (nv ... (b tn)) (bn ...) bd ...))))
  702. ((%alet "dot" (p ...) (nv ...) (t ...) (b c ...) (bn ...) bd ...)
  703. ((lambda (t ... . tn)
  704. (%alet (p ...) (nv ... (b tn)) (bn ...) bd ...)) c ...))
  705. ((%alet (p ...) (nv ...) ((and (n1 v1 t1 ...) (n2 v2 t2 ...) ...) bn ...)
  706. bd ...)
  707. (%alet "and" (p ...) (nv ...) ((n1 v1 t1 ...) (n2 v2 t2 ...) ...) (bn ...)
  708. bd ...))
  709. ((%alet "and" (p ...) (nv ...) ((n v) nvt ...) (bn ...) bd ...)
  710. (let ((t v))
  711. (and t (%alet "and" (p ...) (nv ... (n t)) (nvt ...) (bn ...) bd ...))))
  712. ((%alet "and" (p ...) (nv ...) ((n v t) nvt ...) (bn ...) bd ...)
  713. (let ((tt v))
  714. (and (let ((n tt)) t)
  715. (%alet "and" (p ...) (nv ... (n tt)) (nvt ...) (bn ...) bd ...))))
  716. ((%alet "and" (p ...) (nv ...) () (bn ...) bd ...)
  717. (%alet (p ...) (nv ...) (bn ...) bd ...))
  718. ((%alet (p ...) (nv ...) ((opt z a . e) bn ...) bd ...)
  719. (%alet "opt" (p ...) (nv ...) z (a . e) (bn ...) bd ...))
  720. ((%alet "opt" (p ...) (nv ...) z ((n d t ...)) (bn ...) bd ...)
  721. (let ((x (if (null? z)
  722. d
  723. (if (null? (cdr z))
  724. (wow-opt n (car z) t ...)
  725. (error "alet: too many arguments" (cdr z))))))
  726. (%alet (p ...) (nv ... (n x)) (bn ...) bd ...)))
  727. ((%alet "opt" (p ...) (nv ...) z ((n d t ...) . e) (bn ...) bd ...)
  728. (let ((y (if (null? z) z (cdr z)))
  729. (x (if (null? z)
  730. d
  731. (wow-opt n (car z) t ...))))
  732. (%alet "opt" (p ...) (nv ... (n x)) y e (bn ...) bd ...)))
  733. ((%alet "opt" (p ...) (nv ...) z e (bn ...) bd ...)
  734. (let ((te z))
  735. (%alet (p ...) (nv ... (e te)) (bn ...) bd ...)))
  736. ((%alet (p ...) (nv ...) ((cat z a . e) bn ...) bd ...)
  737. (let ((y z))
  738. (%alet "cat" (p ...) (nv ...) y (a . e) (bn ...) bd ...)))
  739. ((%alet "cat" (p ...) (nv ...) z ((n d t ...)) (bn ...) bd ...)
  740. (let ((x (if (null? z)
  741. d
  742. (if (null? (cdr z))
  743. (wow-cat-end z n t ...)
  744. (error "alet: too many arguments" (cdr z))))))
  745. (%alet (p ...) (nv ... (n x)) (bn ...) bd ...)))
  746. ((%alet "cat" (p ...) (nv ...) z ((n d t ...) . e) (bn ...) bd ...)
  747. (let ((x (if (null? z)
  748. d
  749. (wow-cat! z n d t ...))))
  750. (%alet "cat" (p ...) (nv ... (n x)) z e (bn ...) bd ...)))
  751. ((%alet "cat" (p ...) (nv ...) z e (bn ...) bd ...)
  752. (let ((te z))
  753. (%alet (p ...) (nv ... (e te)) (bn ...) bd ...)))
  754. ((%alet (p ...) (nv ...) ((key z a . e) bn ...) bd ...)
  755. (let ((y z))
  756. (%alet "key" (p ...) (nv ...) y () () (a . e) () (bn ...) bd ...)))
  757. ((%alet "key" (p ...) (nv ...) z ()
  758. (ndt ...) (((n k) d t ...) . e) (kk ...) (bn ...) bd ...)
  759. (%alet "key" (p ...) (nv ...) z ()
  760. (ndt ... ((n k) d t ...)) e (kk ... k) (bn ...) bd ...))
  761. ((%alet "key" (p ...) (nv ...) z ()
  762. (ndt ...) ((n d t ...) . e) (kk ...) (bn ...) bd ...)
  763. (%alet "key" (p ...) (nv ...) z ()
  764. (ndt ... ((n 'n) d t ...)) e (kk ... 'n) (bn ...) bd ...))
  765. ((%alet "key" (p ...) (nv ...) z ()
  766. (ndt nd ...) (#t . e) (kk k ...) (bn ...) bd ...)
  767. (%alet "key" (p ...) (nv ...) z (#t)
  768. (ndt nd ...) e (kk k ...) (bn ...) bd ...))
  769. ((%alet "key" (p ...) (nv ...) z ()
  770. (ndt nd ...) (#f . e) (kk k ...) (bn ...) bd ...)
  771. (%alet "key" (p ...) (nv ...) z (#f)
  772. (ndt nd ...) e (kk k ...) (bn ...) bd ...))
  773. ((%alet "key" (p ...) (nv ...) z (o ...)
  774. (((n k) d t ...) ndt ...) e (kk ...) (bn ...) bd ...)
  775. (let ((x (if (null? z)
  776. d
  777. (wow-key! z (o ...) (kk ...) (n k) d t ...))))
  778. (%alet "key" (p ...) (nv ... (n x)) z (o ...)
  779. (ndt ...) e (kk ...) (bn ...) bd ...)))
  780. ((%alet "key" (p ...) (nv ...) z (o ...) () () (kk ...) (bn ...) bd ...)
  781. (if (null? z)
  782. (%alet (p ...) (nv ...) (bn ...) bd ...)
  783. (error "alet: too many arguments" z)))
  784. ((%alet "key" (p ...) (nv ...) z (o ...) () e (kk ...) (bn ...) bd ...)
  785. (let ((te z)) (%alet (p ...) (nv ... (e te)) (bn ...) bd ...)))
  786. ((%alet (p ...) (nv ...) ((rec (n v) (nn vv) ...) bn ...) bd ...)
  787. (%alet "rec" (p ...) (nv ... (n t)) ((n v t))
  788. ((nn vv) ...) (bn ...) bd ...))
  789. ((%alet "rec" (p ...) (nv ...) (nvt ...) ((n v) (nn vv) ...)
  790. (bn ...) bd ...)
  791. (%alet "rec" (p ...) (nv ... (n t)) (nvt ... (n v t)) ((nn vv) ...)
  792. (bn ...) bd ...))
  793. ((%alet "rec" (p ...) (nv ...) ((n v t) ...) () (bn ...) bd ...)
  794. ((let ((n '&lt;undefined&gt;) ...)
  795. (let ((t v) ...)
  796. (set! n t) ...
  797. (mu n ...)))
  798. (lambda (t ...) (%alet (p ...) (nv ...) (bn ...) bd ...))))
  799. ((%alet (p ...) (nv ...) ((a b) bn ...) bd ...)
  800. ((lambda (t) (%alet (p ...) (nv ... (a t)) (bn ...) bd ...)) b))
  801. ((%alet (p ...) (nv ...) ((values a c) bn ...) bd ...)
  802. ((lambda (t) (%alet (p ...) (nv ... (a t)) (bn ...) bd ...)) c))
  803. ((%alet (p ...) (nv ...) ((values a b c ...) bn ...) bd ...)
  804. (%alet "not" (p ...) (nv ... (a t)) (values t) (b c ...) (bn ...) bd ...))
  805. ((%alet "not" (p ...) (nv ...) (values t ...) (a b c ...) (bn ...) bd ...)
  806. (%alet "not" (p ...) (nv ... (a tn)) (values t ... tn) (b c ...)
  807. (bn ...) bd ...))
  808. ((%alet "not" (p ...) (nv ...) (values t ...) (z) (bn ...) bd ...)
  809. (call-with-values (lambda () z)
  810. (lambda (t ...) (%alet (p ...) (nv ...) (bn ...) bd ...))))
  811. ((%alet (p ...) (nv ...) ((a b c ...) bn ...) bd ...)
  812. (%alet "not" (p ...) (nv ... (a t)) (t) (b c ...) (bn ...) bd ...))
  813. ((%alet "not" (p ...) (nv ...) (t ...) (a b c ...) (bn ...) bd ...)
  814. (%alet "not" (p ...) (nv ... (a tn)) (t ... tn) (b c ...) (bn ...)
  815. bd ...))
  816. ((%alet "not" (p ...) (nv ...) (t ...) (z) (bn ...) bd ...)
  817. (z (lambda (t ...) (%alet (p ...) (nv ...) (bn ...) bd ...))))
  818. ((%alet (p ...) (nv ...) ((a) bn ...) bd ...)
  819. (call-with-current-continuation
  820. (lambda (t) (%alet (p ...) (nv ... (a t)) (bn ...) bd ...))))
  821. ((%alet (p ...) (nv ...) ((a . b) bn ...) bd ...)
  822. (%alet "rot" (p ...) (nv ...) (a) b (bn ...) bd ...))
  823. ((%alet "rot" (p ...) (nv ...) (new-bn ...) (a . b) (bn ...) bd ...)
  824. (%alet "rot" (p ...) (nv ...) (new-bn ... a) b (bn ...) bd ...))
  825. ((%alet "rot" (p ...) (nv ...) (()) b (bn ...) bd ...)
  826. (%alet (b (p ...) (nv ...) (bn ...)) () () bd ...))
  827. ((%alet "rot" (p ...) (nv ...) (new-bn ...) b (bn ...) bd ...)
  828. (%alet (b (p ...) (nv ...) (bn ...)) () (new-bn ...) bd ...))
  829. ((%alet (p ...) (nv ...) (a b bn ...) bd ...)
  830. (b (lambda t (%alet (p ...) (nv ... (a t)) (bn ...) bd ...))))))
  831. ;;; alet*
  832. (define-syntax alet*
  833. (syntax-rules (opt cat key rec and values)
  834. ((alet* () bd ...)
  835. ((lambda () bd ...)))
  836. ((alet* ((() a b ...) bn ...) bd ...)
  837. ((lambda () a b ... (alet* (bn ...) bd ...))))
  838. ((alet* (((a) c) bn ...) bd ...)
  839. ((lambda (a) (alet* (bn ...) bd ...)) c))
  840. ((alet* (((values a) c) bn ...) bd ...)
  841. ((lambda (a) (alet* (bn ...) bd ...)) c))
  842. ((alet* (((values . b) c) bn ...) bd ...)
  843. (call-with-values (lambda () c)
  844. (lambda* b (alet* (bn ...) bd ...))))
  845. ((alet* (((values . b) c d ...) bn ...) bd ...)
  846. (alet* "dot" (b c d ...) (bn ...) bd ...))
  847. ((alet* "dot" ((a . b) c d ...) (bn ...) bd ...)
  848. ((lambda (a) (alet* "dot" (b d ...) (bn ...) bd ...)) c))
  849. ((alet* "dot" (()) (bn ...) bd ...)
  850. (alet* (bn ...) bd ...))
  851. ((alet* "dot" (b c ...) (bn ...) bd ...)
  852. ((lambda b (alet* (bn ...) bd ...)) c ...))
  853. ((alet* (((a . b) c) bn ...) bd ...)
  854. (c (lambda* (a . b) (alet* (bn ...) bd ...))))
  855. ((alet* (((a . b) c d ...) bn ...) bd ...)
  856. ((lambda (a) (alet* "dot" (b d ...) (bn ...) bd ...)) c))
  857. ((alet* ((and (n1 v1 t1 ...) (n2 v2 t2 ...) ...) bn ...) bd ...)
  858. (alet-and* ((n1 v1 t1 ...) (n2 v2 t2 ...) ...) (alet* (bn ...) bd ...)))
  859. ((alet* ((opt z a . e) bn ...) bd ...)
  860. (%alet-opt* z (a . e) (alet* (bn ...) bd ...)))
  861. ((alet* ((cat z a . e) bn ...) bd ...)
  862. (let ((y z))
  863. (%alet-cat* y (a . e) (alet* (bn ...) bd ...))))
  864. ((alet* ((key z a . e) bn ...) bd ...)
  865. (let ((y z))
  866. (%alet-key* y () () (a . e) () (alet* (bn ...) bd ...))))
  867. ((alet* ((rec (n1 v1) (n2 v2) ...) bn ...) bd ...)
  868. (alet-rec* ((n1 v1) (n2 v2) ...) (alet* (bn ...) bd ...)))
  869. ((alet* ((a b) bn ...) bd ...)
  870. ((lambda (a) (alet* (bn ...) bd ...)) b))
  871. ((alet* ((values a c) bn ...) bd ...)
  872. ((lambda (a) (alet* (bn ...) bd ...)) c))
  873. ((alet* ((values a b c ...) bn ...) bd ...)
  874. (alet* "not" (values a) (b c ...) (bn ...) bd ...))
  875. ((alet* "not" (values r ...) (a b c ...) (bn ...) bd ...)
  876. (alet* "not" (values r ... a) (b c ...) (bn ...) bd ...))
  877. ((alet* "not" (values r ...) (z) (bn ...) bd ...)
  878. (call-with-values (lambda () z)
  879. (lambda* (r ...) (alet* (bn ...) bd ...))))
  880. ((alet* ((a b c ...) bn ...) bd ...)
  881. (alet* "not" (a) (b c ...) (bn ...) bd ...))
  882. ((alet* "not" (r ...) (a b c ...) (bn ...) bd ...)
  883. (alet* "not" (r ... a) (b c ...) (bn ...) bd ...))
  884. ((alet* "not" (r ...) (z) (bn ...) bd ...)
  885. (z (lambda* (r ...) (alet* (bn ...) bd ...))))
  886. ((alet* ((a) bn ...) bd ...)
  887. (call-with-current-continuation (lambda (a) (alet* (bn ...) bd ...))))
  888. ((alet* ((a . b) bn ...) bd ...)
  889. (%alet* () () ((a . b) bn ...) bd ...))
  890. ((alet* (a b bn ...) bd ...)
  891. (b (lambda a (alet* (bn ...) bd ...))))
  892. ((alet* var (bn ...) bd ...)
  893. (%alet* (var) () (bn ...) bd ...))))
  894. (define-syntax %alet*
  895. (syntax-rules (opt cat key rec and values)
  896. ((%alet* (var) (n ...) () bd ...)
  897. ((letrec ((var (lambda* (n ...) bd ...)))
  898. var) n ...))
  899. ((%alet* (var (bn ...)) (n ...) () bd ...)
  900. ((letrec ((var (lambda* (n ...) (alet* (bn ...) bd ...))))
  901. var) n ...))
  902. ((%alet* (var (p ...) (nn ...) (bn ...)) (n ...) () bd ...)
  903. ((letrec ((var (lambda* (n ...)
  904. (%alet* (p ...) (nn ... n ... var) (bn ...)
  905. bd ...))))
  906. var) n ...))
  907. ((%alet* (p ...) (n ...) ((() a b ...) bn ...) bd ...)
  908. ((lambda () a b ... (%alet* (p ...) (n ...) (bn ...) bd ...))))
  909. ((%alet* (p ...) (n ...) (((a) c) bn ...) bd ...)
  910. ((lambda (a) (%alet* (p ...) (n ... a) (bn ...) bd ...)) c))
  911. ((%alet* (p ...) (n ...) (((values a) c) bn ...) bd ...)
  912. ((lambda (a) (%alet* (p ...) (n ... a) (bn ...) bd ...)) c))
  913. ((%alet* (p ...) (n ...) (((values . b) c) bn ...) bd ...)
  914. (%alet* "one" (p ...) (n ...) (values) (b c) (bn ...) bd ...))
  915. ((%alet* "one" (p ...) (n ...) (values r ...) ((a . b) c) (bn ...) bd ...)
  916. (%alet* "one" (p ...) (n ... a) (values r ... a) (b c) (bn ...) bd ...))
  917. ((%alet* "one" (p ...) (n ...) (values r ...) (() c) (bn ...) bd ...)
  918. (call-with-values (lambda () c)
  919. (lambda* (r ...) (%alet* (p ...) (n ...) (bn ...) bd ...))))
  920. ((%alet* "one" (p ...) (n ...) (values r ...) (b c) (bn ...) bd ...)
  921. (call-with-values (lambda () c)
  922. (lambda* (r ... . b) (%alet* (p ...) (n ... b) (bn ...) bd ...))))
  923. ((%alet* (p ...) (n ...) (((values . b) c d ...) bn ...) bd ...)
  924. (%alet* "dot" (p ...) (n ...) (b c d ...) (bn ...) bd ...))
  925. ((%alet* (p ...) (n ...) (((a . b) c) bn ...) bd ...)
  926. (%alet* "one" (p ...) (n ... a) (a) (b c) (bn ...) bd ...))
  927. ((%alet* "one" (p ...) (n ...) (r ...) ((a . b) c) (bn ...) bd ...)
  928. (%alet* "one" (p ...) (n ... a) (r ... a) (b c) (bn ...) bd ...))
  929. ((%alet* "one" (p ...) (n ...) (r ...) (() c) (bn ...) bd ...)
  930. (c (lambda* (r ...) (%alet* (p ...) (n ...) (bn ...) bd ...))))
  931. ((%alet* "one" (p ...) (n ...) (r ...) (b c) (bn ...) bd ...)
  932. (c (lambda* (r ... . b) (%alet* (p ...) (n ... b) (bn ...) bd ...))))
  933. ((%alet* (p ...) (n ...) (((a . b) c d ...) bn ...) bd ...)
  934. ((lambda (a)
  935. (%alet* "dot" (p ...) (n ... a) (b d ...) (bn ...) bd ...)) c))
  936. ((%alet* "dot" (p ...) (n ...) ((a . b) c d ...) (bn ...) bd ...)
  937. ((lambda (a)
  938. (%alet* "dot" (p ...) (n ... a) (b d ...) (bn ...) bd ...)) c))
  939. ((%alet* "dot" (p ...) (n ...) (()) (bn ...) bd ...)
  940. (%alet* (p ...) (n ...) (bn ...) bd ...))
  941. ((%alet* "dot" (p ...) (n ...) (b c ...) (bn ...) bd ...)
  942. ((lambda b (%alet* (p ...) (n ... b) (bn ...) bd ...)) c ...))
  943. ((%alet* (p ...) (n ...) ((and (n1 v1 t1 ...) (n2 v2 t2 ...) ...) bn ...)
  944. bd ...)
  945. (alet-and* ((n1 v1 t1 ...) (n2 v2 t2 ...) ...)
  946. (%alet* (p ...) (n ... n1 n2 ...) (bn ...) bd ...)))
  947. ((%alet* (p ...) (n ...) ((opt z a . e) bn ...) bd ...)
  948. (%alet* "opt" (p ...) (n ...) z (a . e) (bn ...) bd ...))
  949. ((%alet* "opt" (p ...) (nn ...) z ((n d t ...)) (bn ...) bd ...)
  950. (let ((n (if (null? z)
  951. d
  952. (if (null? (cdr z))
  953. (wow-opt n (car z) t ...)
  954. (error "alet*: too many arguments" (cdr z))))))
  955. (%alet* (p ...) (nn ... n) (bn ...) bd ...)))
  956. ((%alet* "opt" (p ...) (nn ...) z ((n d t ...) . e) (bn ...) bd ...)
  957. (let ((y (if (null? z) z (cdr z)))
  958. (n (if (null? z)
  959. d
  960. (wow-opt n (car z) t ...))))
  961. (%alet* "opt" (p ...) (nn ... n) y e (bn ...) bd ...)))
  962. ((%alet* "opt" (p ...) (nn ...) z e (bn ...) bd ...)
  963. (let ((e z))
  964. (%alet* (p ...) (nn ... e) (bn ...) bd ...)))
  965. ((%alet* (p ...) (nn ...) ((cat z a . e) bn ...) bd ...)
  966. (let ((y z))
  967. (%alet* "cat" (p ...) (nn ...) y (a . e) (bn ...) bd ...)))
  968. ((%alet* "cat" (p ...) (nn ...) z ((n d t ...)) (bn ...) bd ...)
  969. (let ((n (if (null? z)
  970. d
  971. (if (null? (cdr z))
  972. (wow-cat-end z n t ...)
  973. (error "alet*: too many arguments" (cdr z))))))
  974. (%alet* (p ...) (nn ... n) (bn ...) bd ...)))
  975. ((%alet* "cat" (p ...) (nn ...) z ((n d t ...) . e) (bn ...) bd ...)
  976. (let ((n (if (null? z)
  977. d
  978. (wow-cat! z n d t ...))))
  979. (%alet* "cat" (p ...) (nn ... n) z e (bn ...) bd ...)))
  980. ((%alet* "cat" (p ...) (nn ...) z e (bn ...) bd ...)
  981. (let ((e z))
  982. (%alet* (p ...) (nn ... e) (bn ...) bd ...)))
  983. ((%alet* (p ...) (m ...) ((key z a . e) bn ...) bd ...)
  984. (let ((y z))
  985. (%alet* "key" (p ...) (m ...) y () () (a . e) () (bn ...) bd ...)))
  986. ((%alet* "key" (p ...) (m ...) z ()
  987. (ndt ...) (((n k) d t ...) . e) (kk ...) (bn ...) bd ...)
  988. (%alet* "key" (p ...) (m ...) z ()
  989. (ndt ... ((n k) d t ...)) e (kk ... k) (bn ...) bd ...))
  990. ((%alet* "key" (p ...) (m ...) z ()
  991. (ndt ...) ((n d t ...) . e) (kk ...) (bn ...) bd ...)
  992. (%alet* "key" (p ...) (m ...) z ()
  993. (ndt ... ((n 'n) d t ...)) e (kk ... 'n) (bn ...) bd ...))
  994. ((%alet* "key" (p ...) (m ...) z ()
  995. (ndt nd ...) (#t . e) (kk k ...) (bn ...) bd ...)
  996. (%alet* "key" (p ...) (m ...) z (#t)
  997. (ndt nd ...) e (kk k ...) (bn ...) bd ...))
  998. ((%alet* "key" (p ...) (m ...) z ()
  999. (ndt nd ...) (#f . e) (kk k ...) (bn ...) bd ...)
  1000. (%alet* "key" (p ...) (m ...) z (#f)
  1001. (ndt nd ...) e (kk k ...) (bn ...) bd ...))
  1002. ((%alet* "key" (p ...) (m ...) z (o ...)
  1003. (((n k) d t ...) ndt ...) e (kk ...) (bn ...) bd ...)
  1004. (let ((n (if (null? z)
  1005. d
  1006. (wow-key! z (o ...) (kk ...) (n k) d t ...))))
  1007. (%alet* "key" (p ...) (m ... n) z (o ...)
  1008. (ndt ...) e (kk ...) (bn ...) bd ...)))
  1009. ((%alet* "key" (p ...) (m ...) z (o ...) () () (kk ...) (bn ...) bd ...)
  1010. (if (null? z)
  1011. (%alet* (p ...) (m ...) (bn ...) bd ...)
  1012. (error "alet*: too many arguments" z)))
  1013. ((%alet* "key" (p ...) (m ...) z (o ...) () e (kk ...) (bn ...) bd ...)
  1014. (let ((e z)) (%alet* (p ...) (m ... e) (bn ...) bd ...)))
  1015. ((%alet* (p ...) (n ...) ((rec (n1 v1) (n2 v2) ...) bn ...) bd ...)
  1016. (alet-rec* ((n1 v1) (n2 v2) ...)
  1017. (%alet* (p ...) (n ... n1 n2 ...) (bn ...) bd ...)))
  1018. ((%alet* (p ...) (n ...) ((a b) bn ...) bd ...)
  1019. ((lambda (a) (%alet* (p ...) (n ... a) (bn ...) bd ...)) b))
  1020. ((%alet* (p ...) (n ...) ((values a c) bn ...) bd ...)
  1021. ((lambda (a) (%alet* (p ...) (n ... a) (bn ...) bd ...)) c))
  1022. ((%alet* (p ...) (n ...) ((values a b c ...) bn ...) bd ...)
  1023. (%alet* "not" (p ...) (n ... a) (values a) (b c ...) (bn ...) bd ...))
  1024. ((%alet* "not" (p ...) (n ...) (values r ...) (a b c ...) (bn ...) bd ...)
  1025. (%alet* "not" (p ...) (n ... a) (values r ... a) (b c ...) (bn ...)
  1026. bd ...))
  1027. ((%alet* "not" (p ...) (n ...) (values r ...) (z) (bn ...) bd ...)
  1028. (call-with-values (lambda () z)
  1029. (lambda* (r ...) (%alet* (p ...) (n ...) (bn ...) bd ...))))
  1030. ((%alet* (p ...) (n ...) ((a b c ...) bn ...) bd ...)
  1031. (%alet* "not" (p ...) (n ... a) (a) (b c ...) (bn ...) bd ...))
  1032. ((%alet* "not" (p ...) (n ...) (r ...) (a b c ...) (bn ...) bd ...)
  1033. (%alet* "not" (p ...) (n ... a) (r ... a) (b c ...) (bn ...) bd ...))
  1034. ((%alet* "not" (p ...) (n ...) (r ...) (z) (bn ...) bd ...)
  1035. (z (lambda* (r ...) (%alet* (p ...) (n ...) (bn ...) bd ...))))
  1036. ((%alet* (p ...) (n ...) ((a) bn ...) bd ...)
  1037. (call-with-current-continuation
  1038. (lambda (a) (%alet* (p ...) (n ... a) (bn ...) bd ...))))
  1039. ((%alet* (p ...) (n ...) ((a . b) bn ...) bd ...)
  1040. (%alet* "rot" (p ...) (n ...) (a) b (bn ...) bd ...))
  1041. ((%alet* "rot" (p ...) (n ...) (new-bn ...) (a . b) (bn ...) bd ...)
  1042. (%alet* "rot" (p ...) (n ...) (new-bn ... a) b (bn ...) bd ...))
  1043. ((%alet* "rot" () () (()) b (bn ...) bd ...)
  1044. (%alet* (b (bn ...)) () () bd ...))
  1045. ((%alet* "rot" (p ...) (n ...) (()) b (bn ...) bd ...)
  1046. (%alet* (b (p ...) (n ...) (bn ...)) () () bd ...))
  1047. ((%alet* "rot" () () (new-bn ...) b (bn ...) bd ...)
  1048. (%alet* (b (bn ...)) () (new-bn ...) bd ...))
  1049. ((%alet* "rot" (p ...) (n ...) (new-bn ...) b (bn ...) bd ...)
  1050. (%alet* (b (p ...) (n ...) (bn ...)) () (new-bn ...) bd ...))
  1051. ((%alet* (p ...) (n ...) (a b bn ...) bd ...)
  1052. (b (lambda a (%alet* (p ...) (n ... a) (bn ...) bd ...))))))
  1053. ;;; auxiliaries
  1054. (define-syntax lambda*
  1055. (syntax-rules ()
  1056. ((lambda* (a . e) bd ...)
  1057. (lambda* "star" (ta) (a) e bd ...))
  1058. ((lambda* "star" (t ...) (n ...) (a . e) bd ...)
  1059. (lambda* "star" (t ... ta) (n ... a) e bd ...))
  1060. ((lambda* "star" (t ...) (n ...) () bd ...)
  1061. (lambda (t ...)
  1062. (let* ((n t) ...) bd ...)))
  1063. ((lambda* "star" (t ...) (n ...) e bd ...)
  1064. (lambda (t ... . te)
  1065. (let* ((n t) ... (e te)) bd ...)))
  1066. ((lambda* e bd ...)
  1067. (lambda e bd ...))))
  1068. (define-syntax alet-and
  1069. (syntax-rules ()
  1070. ((alet-and ((n v t ...) ...) bd ...)
  1071. (alet-and "and" () ((n v t ...) ...) bd ...))
  1072. ((alet-and "and" (nt ...) ((n v) nvt ...) bd ...)…