code.html 75 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml" lang="English" xml:lang="English">
  5. <head>
  6. <!-- 2020-08-23 So 13:46 -->
  7. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  8. <meta name="viewport" content="width=device-width, initial-scale=1" />
  9. <title>The Little Schemer Notes</title>
  10. <meta name="generator" content="Org mode" />
  11. <meta name="author" content="Zelphir Kaltstahl" />
  12. <style type="text/css">
  13. <!--/*--><![CDATA[/*><!--*/
  14. .title { text-align: center;
  15. margin-bottom: .2em; }
  16. .subtitle { text-align: center;
  17. font-size: medium;
  18. font-weight: bold;
  19. margin-top:0; }
  20. .todo { font-family: monospace; color: red; }
  21. .done { font-family: monospace; color: green; }
  22. .priority { font-family: monospace; color: orange; }
  23. .tag { background-color: #eee; font-family: monospace;
  24. padding: 2px; font-size: 80%; font-weight: normal; }
  25. .timestamp { color: #bebebe; }
  26. .timestamp-kwd { color: #5f9ea0; }
  27. .org-right { margin-left: auto; margin-right: 0px; text-align: right; }
  28. .org-left { margin-left: 0px; margin-right: auto; text-align: left; }
  29. .org-center { margin-left: auto; margin-right: auto; text-align: center; }
  30. .underline { text-decoration: underline; }
  31. #postamble p, #preamble p { font-size: 90%; margin: .2em; }
  32. p.verse { margin-left: 3%; }
  33. pre {
  34. border: 1px solid #ccc;
  35. box-shadow: 3px 3px 3px #eee;
  36. padding: 8pt;
  37. font-family: monospace;
  38. overflow: auto;
  39. margin: 1.2em;
  40. }
  41. pre.src {
  42. position: relative;
  43. overflow: visible;
  44. padding-top: 1.2em;
  45. }
  46. pre.src:before {
  47. display: none;
  48. position: absolute;
  49. background-color: white;
  50. top: -10px;
  51. right: 10px;
  52. padding: 3px;
  53. border: 1px solid black;
  54. }
  55. pre.src:hover:before { display: inline;}
  56. /* Languages per Org manual */
  57. pre.src-asymptote:before { content: 'Asymptote'; }
  58. pre.src-awk:before { content: 'Awk'; }
  59. pre.src-C:before { content: 'C'; }
  60. /* pre.src-C++ doesn't work in CSS */
  61. pre.src-clojure:before { content: 'Clojure'; }
  62. pre.src-css:before { content: 'CSS'; }
  63. pre.src-D:before { content: 'D'; }
  64. pre.src-ditaa:before { content: 'ditaa'; }
  65. pre.src-dot:before { content: 'Graphviz'; }
  66. pre.src-calc:before { content: 'Emacs Calc'; }
  67. pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
  68. pre.src-fortran:before { content: 'Fortran'; }
  69. pre.src-gnuplot:before { content: 'gnuplot'; }
  70. pre.src-haskell:before { content: 'Haskell'; }
  71. pre.src-hledger:before { content: 'hledger'; }
  72. pre.src-java:before { content: 'Java'; }
  73. pre.src-js:before { content: 'Javascript'; }
  74. pre.src-latex:before { content: 'LaTeX'; }
  75. pre.src-ledger:before { content: 'Ledger'; }
  76. pre.src-lisp:before { content: 'Lisp'; }
  77. pre.src-lilypond:before { content: 'Lilypond'; }
  78. pre.src-lua:before { content: 'Lua'; }
  79. pre.src-matlab:before { content: 'MATLAB'; }
  80. pre.src-mscgen:before { content: 'Mscgen'; }
  81. pre.src-ocaml:before { content: 'Objective Caml'; }
  82. pre.src-octave:before { content: 'Octave'; }
  83. pre.src-org:before { content: 'Org mode'; }
  84. pre.src-oz:before { content: 'OZ'; }
  85. pre.src-plantuml:before { content: 'Plantuml'; }
  86. pre.src-processing:before { content: 'Processing.js'; }
  87. pre.src-python:before { content: 'Python'; }
  88. pre.src-R:before { content: 'R'; }
  89. pre.src-ruby:before { content: 'Ruby'; }
  90. pre.src-sass:before { content: 'Sass'; }
  91. pre.src-scheme:before { content: 'Scheme'; }
  92. pre.src-screen:before { content: 'Gnu Screen'; }
  93. pre.src-sed:before { content: 'Sed'; }
  94. pre.src-sh:before { content: 'shell'; }
  95. pre.src-sql:before { content: 'SQL'; }
  96. pre.src-sqlite:before { content: 'SQLite'; }
  97. /* additional languages in org.el's org-babel-load-languages alist */
  98. pre.src-forth:before { content: 'Forth'; }
  99. pre.src-io:before { content: 'IO'; }
  100. pre.src-J:before { content: 'J'; }
  101. pre.src-makefile:before { content: 'Makefile'; }
  102. pre.src-maxima:before { content: 'Maxima'; }
  103. pre.src-perl:before { content: 'Perl'; }
  104. pre.src-picolisp:before { content: 'Pico Lisp'; }
  105. pre.src-scala:before { content: 'Scala'; }
  106. pre.src-shell:before { content: 'Shell Script'; }
  107. pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
  108. /* additional language identifiers per "defun org-babel-execute"
  109. in ob-*.el */
  110. pre.src-cpp:before { content: 'C++'; }
  111. pre.src-abc:before { content: 'ABC'; }
  112. pre.src-coq:before { content: 'Coq'; }
  113. pre.src-groovy:before { content: 'Groovy'; }
  114. /* additional language identifiers from org-babel-shell-names in
  115. ob-shell.el: ob-shell is the only babel language using a lambda to put
  116. the execution function name together. */
  117. pre.src-bash:before { content: 'bash'; }
  118. pre.src-csh:before { content: 'csh'; }
  119. pre.src-ash:before { content: 'ash'; }
  120. pre.src-dash:before { content: 'dash'; }
  121. pre.src-ksh:before { content: 'ksh'; }
  122. pre.src-mksh:before { content: 'mksh'; }
  123. pre.src-posh:before { content: 'posh'; }
  124. /* Additional Emacs modes also supported by the LaTeX listings package */
  125. pre.src-ada:before { content: 'Ada'; }
  126. pre.src-asm:before { content: 'Assembler'; }
  127. pre.src-caml:before { content: 'Caml'; }
  128. pre.src-delphi:before { content: 'Delphi'; }
  129. pre.src-html:before { content: 'HTML'; }
  130. pre.src-idl:before { content: 'IDL'; }
  131. pre.src-mercury:before { content: 'Mercury'; }
  132. pre.src-metapost:before { content: 'MetaPost'; }
  133. pre.src-modula-2:before { content: 'Modula-2'; }
  134. pre.src-pascal:before { content: 'Pascal'; }
  135. pre.src-ps:before { content: 'PostScript'; }
  136. pre.src-prolog:before { content: 'Prolog'; }
  137. pre.src-simula:before { content: 'Simula'; }
  138. pre.src-tcl:before { content: 'tcl'; }
  139. pre.src-tex:before { content: 'TeX'; }
  140. pre.src-plain-tex:before { content: 'Plain TeX'; }
  141. pre.src-verilog:before { content: 'Verilog'; }
  142. pre.src-vhdl:before { content: 'VHDL'; }
  143. pre.src-xml:before { content: 'XML'; }
  144. pre.src-nxml:before { content: 'XML'; }
  145. /* add a generic configuration mode; LaTeX export needs an additional
  146. (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
  147. pre.src-conf:before { content: 'Configuration File'; }
  148. table { border-collapse:collapse; }
  149. caption.t-above { caption-side: top; }
  150. caption.t-bottom { caption-side: bottom; }
  151. td, th { vertical-align:top; }
  152. th.org-right { text-align: center; }
  153. th.org-left { text-align: center; }
  154. th.org-center { text-align: center; }
  155. td.org-right { text-align: right; }
  156. td.org-left { text-align: left; }
  157. td.org-center { text-align: center; }
  158. dt { font-weight: bold; }
  159. .footpara { display: inline; }
  160. .footdef { margin-bottom: 1em; }
  161. .figure { padding: 1em; }
  162. .figure p { text-align: center; }
  163. .equation-container {
  164. display: table;
  165. text-align: center;
  166. width: 100%;
  167. }
  168. .equation {
  169. vertical-align: middle;
  170. }
  171. .equation-label {
  172. display: table-cell;
  173. text-align: right;
  174. vertical-align: middle;
  175. }
  176. .inlinetask {
  177. padding: 10px;
  178. border: 2px solid gray;
  179. margin: 10px;
  180. background: #ffffcc;
  181. }
  182. #org-div-home-and-up
  183. { text-align: right; font-size: 70%; white-space: nowrap; }
  184. textarea { overflow-x: auto; }
  185. .linenr { font-size: smaller }
  186. .code-highlighted { background-color: #ffff00; }
  187. .org-info-js_info-navigation { border-style: none; }
  188. #org-info-js_console-label
  189. { font-size: 10px; font-weight: bold; white-space: nowrap; }
  190. .org-info-js_search-highlight
  191. { background-color: #ffff00; color: #000000; font-weight: bold; }
  192. .org-svg { width: 90%; }
  193. /*]]>*/-->
  194. </style>
  195. <script type="text/javascript">
  196. /*
  197. @licstart The following is the entire license notice for the
  198. JavaScript code in this tag.
  199. Copyright (C) 2012-2020 Free Software Foundation, Inc.
  200. The JavaScript code in this tag is free software: you can
  201. redistribute it and/or modify it under the terms of the GNU
  202. General Public License (GNU GPL) as published by the Free Software
  203. Foundation, either version 3 of the License, or (at your option)
  204. any later version. The code is distributed WITHOUT ANY WARRANTY;
  205. without even the implied warranty of MERCHANTABILITY or FITNESS
  206. FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
  207. As additional permission under GNU GPL version 3 section 7, you
  208. may distribute non-source (e.g., minimized or compacted) forms of
  209. that code without the copy of the GNU GPL normally required by
  210. section 4, provided you include this license notice and a URL
  211. through which recipients can access the Corresponding Source.
  212. @licend The above is the entire license notice
  213. for the JavaScript code in this tag.
  214. */
  215. <!--/*--><![CDATA[/*><!--*/
  216. function CodeHighlightOn(elem, id)
  217. {
  218. var target = document.getElementById(id);
  219. if(null != target) {
  220. elem.cacheClassElem = elem.className;
  221. elem.cacheClassTarget = target.className;
  222. target.className = "code-highlighted";
  223. elem.className = "code-highlighted";
  224. }
  225. }
  226. function CodeHighlightOff(elem, id)
  227. {
  228. var target = document.getElementById(id);
  229. if(elem.cacheClassElem)
  230. elem.className = elem.cacheClassElem;
  231. if(elem.cacheClassTarget)
  232. target.className = elem.cacheClassTarget;
  233. }
  234. /*]]>*///-->
  235. </script>
  236. </head>
  237. <body>
  238. <div id="content">
  239. <h1 class="title">The Little Schemer Notes
  240. <br />
  241. <span class="subtitle">The Y-combinator</span>
  242. </h1>
  243. <div id="table-of-contents">
  244. <h2>Table of Contents</h2>
  245. <div id="text-table-of-contents">
  246. <ul>
  247. <li><a href="#orga967236">1. Y-combinator</a></li>
  248. <li><a href="#orga4b2d59">2. Prerequisites</a></li>
  249. <li><a href="#org8fb4a52">3. Code</a>
  250. <ul>
  251. <li><a href="#orgc9f88ae">3.1. Writing <code>length-0</code></a></li>
  252. <li><a href="#org3ad5eb7">3.2. Endless inlining of <code>length-0</code></a></li>
  253. <li><a href="#orgf016cff">3.3. Creating <code>length-0</code></a></li>
  254. <li><a href="#orgafbe3a5">3.4. Creating <code>length-1</code> and <code>length-2</code></a></li>
  255. <li><a href="#org50da4be">3.5. Refactoring out the repeating part - making <code>length</code></a></li>
  256. <li><a href="#orgb7ac798">3.6. Making all kinds of recursive procedures</a></li>
  257. <li><a href="#org6e74d52">3.7. Separating the Y-combinator</a></li>
  258. </ul>
  259. </li>
  260. <li><a href="#orgede3d6b">4. Final words</a></li>
  261. </ul>
  262. </div>
  263. </div>
  264. <div id="outline-container-orga967236" class="outline-2">
  265. <h2 id="orga967236"><span class="section-number-2">1</span> Y-combinator</h2>
  266. <div class="outline-text-2" id="text-1">
  267. <p>
  268. The following is a way to get to the so called Y-combinator. It is a thought experiment assuming, that we have no <code>define</code> form available and are trying to implement the function <code>length</code> for lists without making use of <code>define</code>. In the end a way will be found. This way is the Y-combinator, a function, which can turn a function <i>f</i> into a function <i>f-wrap</i>, which applies <i>f</i> again and again, as required by the nature of its input to recursively consume all of the input. Since no <code>define</code> form is used anywhere to write the Y-combinator, the body of the Y-combinator cannot refer to any definitions, except for names of values in respective scopes. This property enables the Y-combinator to implement recursion in a programming language, which does not support recursion natively, as long as it has lambda expressions, function application and (not 100% sure it is required) lexical scope. If a language forbids calling a procedure from within itself, then the Y-combinator is still valid code, as it does not do so. It in turn can produce an <i>f-wrap</i>, which will apply an <i>f</i> over and over again, creating the same effect, as if <i>f</i> was recursive itself. To deny the use of the <code>define</code> form actually is intentionally done in the book, because then only the Y-combinator or something with the properties of the Y-combinator can help us solve the problem.
  269. </p>
  270. <p>
  271. On the way there, a few common refactoring steps or equivalent transformations for code are applied. Those are the following:
  272. </p>
  273. <ol class="org-ol">
  274. <li>inlining an implementation of a function where the call to it is made</li>
  275. <li>lambda wrapping of lambda expressions (explained when used)
  276. <ol class="org-ol">
  277. <li>for pulling out parts of the code and making them arguments</li>
  278. <li>for delaying evaluation of expressions</li>
  279. </ol></li>
  280. </ol>
  281. <p>
  282. Furthermore we make use of:
  283. </p>
  284. <ol class="org-ol">
  285. <li>immeditately invoked functions</li>
  286. </ol>
  287. </div>
  288. </div>
  289. <div id="outline-container-orga4b2d59" class="outline-2">
  290. <h2 id="orga4b2d59"><span class="section-number-2">2</span> Prerequisites</h2>
  291. <div class="outline-text-2" id="text-2">
  292. <p>
  293. Prerequisites contain code, which is needed to run examples, but is not given in the same chapter.
  294. </p>
  295. <div class="org-src-container">
  296. <pre class="src src-scheme" id="org4aa79f7">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">length</span>
  297. (<span style="color: #9FCA56;">lambda</span> (lst)
  298. (<span style="color: #9FCA56;">cond</span>
  299. [(null? lst) 0]
  300. [<span style="color: #9FCA56;">else</span> (+ (length (cdr lst)) 1)])))
  301. (<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  302. (<span style="color: #9FCA56;">lambda</span> (something)
  303. (eternity something)))
  304. </pre>
  305. </div>
  306. </div>
  307. </div>
  308. <div id="outline-container-org8fb4a52" class="outline-2">
  309. <h2 id="org8fb4a52"><span class="section-number-2">3</span> Code</h2>
  310. <div class="outline-text-2" id="text-3">
  311. <p>
  312. The whole example works with the length function, so to start, here is the length function as usually defined for lists:
  313. </p>
  314. <div class="org-src-container">
  315. <pre class="src src-scheme">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">length</span>
  316. (<span style="color: #9FCA56;">lambda</span> (lst)
  317. (<span style="color: #9FCA56;">cond</span>
  318. [(null? lst) 0]
  319. [<span style="color: #9FCA56;">else</span> (+ (length (cdr lst)) 1)])))
  320. </pre>
  321. </div>
  322. <p>
  323. We can try it out:
  324. </p>
  325. <div class="org-src-container">
  326. <pre class="src src-scheme">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">length</span>
  327. (<span style="color: #9FCA56;">lambda</span> (lst)
  328. (<span style="color: #9FCA56;">cond</span>
  329. [(null? lst) 0]
  330. [<span style="color: #9FCA56;">else</span> (+ (length (cdr lst)) 1)])))
  331. (display (simple-format #f <span style="color: #55B5DB;">"~a\n"</span> (length '(1 2 3 4 5 6))))
  332. (display (simple-format #f <span style="color: #55B5DB;">"~a\n"</span> (length '(1 2 3 4 5 (6)))))
  333. </pre>
  334. </div>
  335. <pre class="example">
  336. 6
  337. 6
  338. </pre>
  339. <p>
  340. There is a problem however. <code>length</code> refers to itself in its definition. In a programming language, which does not support recursion, this would not be possible. If we do not make use of <code>define</code>, then there is no way for length to directly refer to itself, as it is not bound to a name. So how could we write <code>length</code>, without referring to itself?
  341. </p>
  342. </div>
  343. <div id="outline-container-orgc9f88ae" class="outline-3">
  344. <h3 id="orgc9f88ae"><span class="section-number-3">3.1</span> Writing <code>length-0</code></h3>
  345. <div class="outline-text-3" id="text-3-1">
  346. <p>
  347. To start figuring out the solution, we write <code>length-0</code>, which calculates the length of the empty list, but does not return a value (gets stuck) for any list that contains elements:
  348. </p>
  349. <div class="org-src-container">
  350. <pre class="src src-scheme" id="orgc2e8854">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  351. (<span style="color: #9FCA56;">lambda</span> (something)
  352. (eternity something)))
  353. (<span style="color: #9FCA56;">lambda</span> (lst)
  354. (<span style="color: #9FCA56;">cond</span>
  355. [(null? lst) 0]
  356. [<span style="color: #9FCA56;">else</span> (+ 1 (eternity (cdr lst)))]))
  357. </pre>
  358. </div>
  359. <p>
  360. This does not recur on itself. It does not call itself in the body.
  361. </p>
  362. <p>
  363. Using this as a starting point, we then try to get back our original <code>length</code> functionality.
  364. </p>
  365. <div class="org-src-container">
  366. <pre class="src src-scheme" id="orgb28defa">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  367. (<span style="color: #9FCA56;">lambda</span> (something)
  368. (eternity something)))
  369. (<span style="color: #9FCA56;">lambda</span> (lst)
  370. (<span style="color: #9FCA56;">cond</span>
  371. [(null? lst) 0]
  372. [<span style="color: #9FCA56;">else</span> (+ 1 (eternity (cdr lst)))]))
  373. <span style="color: #75715E;">;; </span><span style="color: #41535B;">do not try for non-empty lists</span>
  374. <span style="color: #75715E;">;; </span><span style="color: #41535B;">(display</span>
  375. <span style="color: #75715E;">;; </span><span style="color: #41535B;">(simple-format</span>
  376. <span style="color: #75715E;">;; </span><span style="color: #41535B;">#f "~a\n"</span>
  377. <span style="color: #75715E;">;; </span><span style="color: #41535B;">((lambda (lst)</span>
  378. <span style="color: #75715E;">;; </span><span style="color: #41535B;">(cond</span>
  379. <span style="color: #75715E;">;; </span><span style="color: #41535B;">[(null? lst) 0]</span>
  380. <span style="color: #75715E;">;; </span><span style="color: #41535B;">[else (+ 1 (eternity (cdr lst)))]))</span>
  381. <span style="color: #75715E;">;; </span><span style="color: #41535B;">'(1 2 3))))</span>
  382. (display
  383. (simple-format
  384. #f <span style="color: #55B5DB;">"~a\n"</span>
  385. ((<span style="color: #9FCA56;">lambda</span> (lst)
  386. (<span style="color: #9FCA56;">cond</span>
  387. [(null? lst) 0]
  388. [<span style="color: #9FCA56;">else</span> (+ 1 (eternity (cdr lst)))]))
  389. '())))
  390. </pre>
  391. </div>
  392. <pre class="example">
  393. 0
  394. </pre>
  395. <p>
  396. OK, this works for the empty list.
  397. </p>
  398. </div>
  399. </div>
  400. <div id="outline-container-org3ad5eb7" class="outline-3">
  401. <h3 id="org3ad5eb7"><span class="section-number-3">3.2</span> Endless inlining of <code>length-0</code></h3>
  402. <div class="outline-text-3" id="text-3-2">
  403. <p>
  404. From <code>length-0</code>, we can create a function for calculating the length of a list with 1 element or the empty list by replacing the <code>else</code> branch with <code>length-0</code> itself. As the case of the empty list is handled in the first branch, the else branch would then handle the case of the list having one element. This works because we give the <code>cdr</code> of the list, which will be the empty list again, as an argument to the <code>length-0</code> in the <code>else</code> branch:
  405. </p>
  406. <div class="org-src-container">
  407. <pre class="src src-scheme" id="org7f3bd33">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  408. (<span style="color: #9FCA56;">lambda</span> (something)
  409. (eternity something)))
  410. (<span style="color: #9FCA56;">lambda</span> (lst)
  411. (<span style="color: #9FCA56;">cond</span>
  412. [(null? lst) 0]
  413. [<span style="color: #9FCA56;">else</span> (+ 1
  414. <span style="color: #75715E;">;; </span><span style="color: #41535B;">We insert length-0 here.</span>
  415. ((<span style="color: #9FCA56;">lambda</span> (lst)
  416. (<span style="color: #9FCA56;">cond</span>
  417. [(null? lst) 0]
  418. <span style="color: #75715E;">;; </span><span style="color: #41535B;">If there are more elements then 1, the function will still not return a value.</span>
  419. [<span style="color: #9FCA56;">else</span> (+ 1 (eternity (cdr lst)))]))
  420. <span style="color: #75715E;">;; </span><span style="color: #41535B;">length-0 will be applied to the cdr of the list</span>
  421. (cdr lst)))]))
  422. </pre>
  423. </div>
  424. <p>
  425. Let's try it out:
  426. </p>
  427. <div class="org-src-container">
  428. <pre class="src src-scheme" id="orgc9adfbf">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  429. (<span style="color: #9FCA56;">lambda</span> (something)
  430. (eternity something)))
  431. <span style="color: #75715E;">;; </span><span style="color: #41535B;">do not try this</span>
  432. <span style="color: #41535B;">#;(display</span>
  433. <span style="color: #41535B;"> (simple-format</span>
  434. <span style="color: #41535B;"> #f "~a\n"</span>
  435. <span style="color: #41535B;"> ((lambda (lst)</span>
  436. <span style="color: #41535B;"> (cond</span>
  437. <span style="color: #41535B;"> [(null? lst) 0]</span>
  438. <span style="color: #41535B;"> [else (+ 1</span>
  439. <span style="color: #41535B;"> ((lambda (lst)</span>
  440. <span style="color: #41535B;"> (cond</span>
  441. <span style="color: #41535B;"> [(null? lst) 0]</span>
  442. <span style="color: #41535B;"> [else (+ 1 (eternity (cdr lst)))]))</span>
  443. <span style="color: #41535B;"> (cdr lst)))]))</span>
  444. <span style="color: #41535B;"> '(a b))))</span>
  445. (display
  446. (simple-format
  447. #f <span style="color: #55B5DB;">"~a\n"</span>
  448. ((<span style="color: #9FCA56;">lambda</span> (lst)
  449. (<span style="color: #9FCA56;">cond</span>
  450. [(null? lst) 0]
  451. [<span style="color: #9FCA56;">else</span> (+ 1
  452. ((<span style="color: #9FCA56;">lambda</span> (lst)
  453. (<span style="color: #9FCA56;">cond</span>
  454. [(null? lst) 0]
  455. [<span style="color: #9FCA56;">else</span> (+ 1 (eternity (cdr lst)))]))
  456. (cdr lst)))]))
  457. '())))
  458. (display
  459. (simple-format
  460. #f <span style="color: #55B5DB;">"~a\n"</span>
  461. ((<span style="color: #9FCA56;">lambda</span> (lst)
  462. (<span style="color: #9FCA56;">cond</span>
  463. [(null? lst) 0]
  464. [<span style="color: #9FCA56;">else</span> (+ 1
  465. ((<span style="color: #9FCA56;">lambda</span> (lst)
  466. (<span style="color: #9FCA56;">cond</span>
  467. [(null? lst) 0]
  468. [<span style="color: #9FCA56;">else</span> (+ 1 (eternity (cdr lst)))]))
  469. (cdr lst)))]))
  470. '(a))))
  471. </pre>
  472. </div>
  473. <p>
  474. Our function now works for the list lenghts 0 and 1. Great. We can continue nesting deeper, to get to any length we want. For example we can replace the call to <code>eternity</code> again, in order to achieve a function, which can deal with lists up to length 2 as follows:
  475. </p>
  476. <div class="org-src-container">
  477. <pre class="src src-scheme" id="org3d5043e">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  478. (<span style="color: #9FCA56;">lambda</span> (something)
  479. (eternity something)))
  480. (<span style="color: #9FCA56;">lambda</span> (lst)
  481. (<span style="color: #9FCA56;">cond</span>
  482. [(null? lst) 0]
  483. [<span style="color: #9FCA56;">else</span> (+ 1
  484. ((<span style="color: #9FCA56;">lambda</span> (lst)
  485. (<span style="color: #9FCA56;">cond</span>
  486. [(null? lst) 0]
  487. [<span style="color: #9FCA56;">else</span> (+ 1
  488. <span style="color: #75715E;">;; </span><span style="color: #41535B;">We insert length-0 here.</span>
  489. ((<span style="color: #9FCA56;">lambda</span> (lst)
  490. (<span style="color: #9FCA56;">cond</span>
  491. [(null? lst) 0]
  492. [<span style="color: #9FCA56;">else</span> (+ 1 (eternity (cdr lst)))]))
  493. (cdr lst)))]))
  494. (cdr lst)))]))
  495. </pre>
  496. </div>
  497. <p>
  498. And a little test:
  499. </p>
  500. <div class="org-src-container">
  501. <pre class="src src-scheme" id="org5225ea2">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  502. (<span style="color: #9FCA56;">lambda</span> (something)
  503. (eternity something)))
  504. (display
  505. (simple-format
  506. #f <span style="color: #55B5DB;">"~a\n"</span>
  507. ((<span style="color: #9FCA56;">lambda</span> (lst)
  508. (<span style="color: #9FCA56;">cond</span>
  509. [(null? lst) 0]
  510. [<span style="color: #9FCA56;">else</span> (+ 1
  511. ((<span style="color: #9FCA56;">lambda</span> (lst)
  512. (<span style="color: #9FCA56;">cond</span>
  513. [(null? lst) 0]
  514. [<span style="color: #9FCA56;">else</span> (+ 1
  515. ((<span style="color: #9FCA56;">lambda</span> (lst)
  516. (<span style="color: #9FCA56;">cond</span>
  517. [(null? lst) 0]
  518. [<span style="color: #9FCA56;">else</span> (+ 1 (eternity (cdr lst)))]))
  519. (cdr lst)))]))
  520. (cdr lst)))]))
  521. '(a b))))
  522. </pre>
  523. </div>
  524. <pre class="example">
  525. 2
  526. </pre>
  527. <p>
  528. Yep, it still works.
  529. </p>
  530. <p>
  531. This way of proceeding by inlining <code>length-0</code> over and over again, although working correctly, seems not practical at all. We cannot anticipate at all times, what length a list we have to deal with will have and in consequence cannot know how to write our <code>length</code> function. Furthermore, this makes for very unreadable and very long code, only to have a function <code>length</code>. Using this is not feasible.
  532. </p>
  533. <p>
  534. We have to ask ourselves, how we could avoid having to inline the code of <code>length-0</code> manually. This will involve multiple steps.
  535. </p>
  536. </div>
  537. </div>
  538. <div id="outline-container-orgf016cff" class="outline-3">
  539. <h3 id="orgf016cff"><span class="section-number-3">3.3</span> Creating <code>length-0</code></h3>
  540. <div class="outline-text-3" id="text-3-3">
  541. <p>
  542. First, we can write a procedure, which creates <code>length-0</code> for us:
  543. </p>
  544. <div class="org-src-container">
  545. <pre class="src src-scheme" id="orgb4186dd">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  546. (<span style="color: #9FCA56;">lambda</span> (something)
  547. (eternity something)))
  548. ((<span style="color: #9FCA56;">lambda</span> (length)
  549. (<span style="color: #9FCA56;">lambda</span> (lst)
  550. (<span style="color: #9FCA56;">cond</span>
  551. [(null? lst) 0]
  552. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  553. eternity)
  554. </pre>
  555. </div>
  556. <p>
  557. All we did here is to wrap <code>length-0</code> with a lambda and make that lambda take one argument, a procedure, which is used in place of the call to <code>eternity</code>. To get back <code>length-0</code>, we need to pass in <code>eternity</code>, so that it gets back inside <code>length-0</code>, where it will be called. (In foresight the argument is named <code>length</code>, but it could really have any name.)
  558. </p>
  559. <p>
  560. Let us call this equivalent transformation <i>lambda wrapping</i>. To generalize, it is always possible to wrap one lambda with another lambda this way, making one or more bindings come from the outer scope, where they are passed in, to get an equivalent lambda. This is formulated in the following code:
  561. </p>
  562. <div class="org-src-container">
  563. <label class="org-src-name"><span class="listing-number">Listing 1: </span>equivalent transformation: lambda wrapping</label><pre class="src src-scheme" id="org3f368e2">(<span style="color: #9FCA56;">&#955;</span> (sth) (proc sth))
  564. <span style="color: #75715E;">;; </span><span style="color: #41535B;">is equivalent to</span>
  565. ((<span style="color: #9FCA56;">&#955;</span> (arg)
  566. (<span style="color: #9FCA56;">&#955;</span> (sth) (arg sth)))
  567. proc)
  568. </pre>
  569. </div>
  570. <p>
  571. This is how we can create <code>length-0</code>. Let us try to create <code>length-1</code> and <code>length-2</code> the same way and a pattern will emerge.
  572. </p>
  573. </div>
  574. </div>
  575. <div id="outline-container-orgafbe3a5" class="outline-3">
  576. <h3 id="orgafbe3a5"><span class="section-number-3">3.4</span> Creating <code>length-1</code> and <code>length-2</code></h3>
  577. <div class="outline-text-3" id="text-3-4">
  578. <p>
  579. Instead of giving the argument <code>eternity</code> to the function, which creates <code>length-0</code>, which will then be called in the <code>else</code> branch, causing the produced <code>length-0</code> to fail, if the list is not empty, we could give <code>length-0</code> as an argument, so that we will have it called in the else branch. This in effect will create <code>length-1</code>, as the function produced will only fail, when it enters the <code>else</code> branch of the argument <code>length-0</code>, as it has a call to <code>eternity</code> there.
  580. </p>
  581. <p>
  582. Let us see this in the following code.
  583. </p>
  584. </div>
  585. <div id="outline-container-org816cc6c" class="outline-4">
  586. <h4 id="org816cc6c"><span class="section-number-4">3.4.1</span> Creating <code>length-1</code></h4>
  587. <div class="outline-text-4" id="text-3-4-1">
  588. <p>
  589. This is the code before giving <code>length-0</code> as an argument, still giving <code>eternity</code> as an argument:
  590. </p>
  591. <div class="org-src-container">
  592. <pre class="src src-scheme" id="org9548e2a">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  593. (<span style="color: #9FCA56;">lambda</span> (something)
  594. (eternity something)))
  595. ((<span style="color: #9FCA56;">lambda</span> (length)
  596. (<span style="color: #9FCA56;">lambda</span> (lst)
  597. (<span style="color: #9FCA56;">cond</span>
  598. [(null? lst) 0]
  599. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  600. <span style="color: #75715E;">;; </span><span style="color: #41535B;">notice how we give eternity as an argument to produce length-0</span>
  601. eternity)
  602. </pre>
  603. </div>
  604. <p>
  605. Now we will replace <code>eternity</code> by <code>length-0</code>:
  606. </p>
  607. <div class="org-src-container">
  608. <pre class="src src-scheme" id="org61703c0">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  609. (<span style="color: #9FCA56;">lambda</span> (something)
  610. (eternity something)))
  611. ((<span style="color: #9FCA56;">lambda</span> (length)
  612. (<span style="color: #9FCA56;">lambda</span> (lst)
  613. (<span style="color: #9FCA56;">cond</span>
  614. [(null? lst) 0]
  615. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  616. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Now we give length-0, as produced by the lambda expression.</span>
  617. ((<span style="color: #9FCA56;">lambda</span> (length)
  618. (<span style="color: #9FCA56;">lambda</span> (lst)
  619. (<span style="color: #9FCA56;">cond</span>
  620. [(null? lst) 0]
  621. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  622. <span style="color: #75715E;">;; </span><span style="color: #41535B;">eternity will be given to create the argument length-0.</span>
  623. eternity))
  624. </pre>
  625. </div>
  626. <p>
  627. Instead of giving <code>eternity</code> immediately, <code>eternity</code> is now given as an argument for creating <code>length-0</code>, which in turn will be given as an argument, in order to create <code>length-1</code>.
  628. </p>
  629. <p>
  630. Notice, that we used the identifier <code>length</code> in both lambda expressions. They are however different, separated by scope.
  631. </p>
  632. <p>
  633. Let us try to use this <code>length-1</code> function.
  634. </p>
  635. <div class="org-src-container">
  636. <pre class="src src-scheme" id="orgcb10d23">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  637. (<span style="color: #9FCA56;">lambda</span> (something)
  638. (eternity something)))
  639. (display
  640. (simple-format
  641. #f <span style="color: #55B5DB;">"~a\n"</span>
  642. <span style="color: #75715E;">;; </span><span style="color: #41535B;">make length-1 and immediately apply it</span>
  643. (((<span style="color: #9FCA56;">lambda</span> (length)
  644. (<span style="color: #9FCA56;">lambda</span> (lst)
  645. (<span style="color: #9FCA56;">cond</span>
  646. [(null? lst) 0]
  647. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  648. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Now we give length-0, as produced by the lambda expression.</span>
  649. ((<span style="color: #9FCA56;">lambda</span> (length)
  650. (<span style="color: #9FCA56;">lambda</span> (lst)
  651. (<span style="color: #9FCA56;">cond</span>
  652. [(null? lst) 0]
  653. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  654. <span style="color: #75715E;">;; </span><span style="color: #41535B;">eternity will be given to create the argument length-0.</span>
  655. eternity))
  656. '())))
  657. (display
  658. (simple-format
  659. #f <span style="color: #55B5DB;">"~a\n"</span>
  660. <span style="color: #75715E;">;; </span><span style="color: #41535B;">make length-1 and immediately apply it</span>
  661. (((<span style="color: #9FCA56;">lambda</span> (length)
  662. (<span style="color: #9FCA56;">lambda</span> (lst)
  663. (<span style="color: #9FCA56;">cond</span>
  664. [(null? lst) 0]
  665. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  666. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Now we give length-0, as produced by the lambda expression.</span>
  667. ((<span style="color: #9FCA56;">lambda</span> (length)
  668. (<span style="color: #9FCA56;">lambda</span> (lst)
  669. (<span style="color: #9FCA56;">cond</span>
  670. [(null? lst) 0]
  671. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  672. <span style="color: #75715E;">;; </span><span style="color: #41535B;">eternity will be given to create the argument length-0.</span>
  673. eternity))
  674. '(a))))
  675. </pre>
  676. </div>
  677. <pre class="example">
  678. 0
  679. 1
  680. </pre>
  681. <p>
  682. It gives the expected result.
  683. </p>
  684. </div>
  685. </div>
  686. <div id="outline-container-org8781102" class="outline-4">
  687. <h4 id="org8781102"><span class="section-number-4">3.4.2</span> Creating <code>length-2</code></h4>
  688. <div class="outline-text-4" id="text-3-4-2">
  689. <p>
  690. Just like we created <code>length-1</code> by giving an on-the-fly produced <code>length-0</code> to the function which originally created <code>length-0</code>, we create <code>length-2</code>, by again replacing the call to <code>eternity</code>, by another <code>length-0</code>, increasing the possible iteration depth of the whole created function again by 1, as the <code>eternity</code> call will happen only in the innermost function, which is produced by creating <code>length-0</code> using <code>eternity</code>.
  691. </p>
  692. <div class="org-src-container">
  693. <pre class="src src-scheme" id="orgfe68f42">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  694. (<span style="color: #9FCA56;">lambda</span> (something)
  695. (eternity something)))
  696. ((<span style="color: #9FCA56;">lambda</span> (length)
  697. (<span style="color: #9FCA56;">lambda</span> (lst)
  698. (<span style="color: #9FCA56;">cond</span>
  699. [(null? lst) 0]
  700. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  701. ((<span style="color: #9FCA56;">lambda</span> (length)
  702. (<span style="color: #9FCA56;">lambda</span> (lst)
  703. (<span style="color: #9FCA56;">cond</span>
  704. [(null? lst) 0]
  705. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  706. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Now we give length-0, as produced by the lambda expression.</span>
  707. ((<span style="color: #9FCA56;">lambda</span> (length)
  708. (<span style="color: #9FCA56;">lambda</span> (lst)
  709. (<span style="color: #9FCA56;">cond</span>
  710. [(null? lst) 0]
  711. [<span style="color: #9FCA56;">else</span> (+ 1 (length (cdr lst)))])))
  712. <span style="color: #75715E;">;; </span><span style="color: #41535B;">eternity will be given to create the argument length-0.</span>
  713. eternity)))
  714. </pre>
  715. </div>
  716. <p>
  717. We delayed the call of <code>eternity</code> even more, by replacing <code>eternity</code> with another creation of <code>length-0</code>, which in turn does the call to <code>eternity</code>.
  718. </p>
  719. <p>
  720. While the code is not indented as much any longer, there are still repetitions, which are needed for each depth of recursion, so the problem is not yet solved.
  721. </p>
  722. </div>
  723. </div>
  724. </div>
  725. <div id="outline-container-org50da4be" class="outline-3">
  726. <h3 id="org50da4be"><span class="section-number-3">3.5</span> Refactoring out the repeating part - making <code>length</code></h3>
  727. <div class="outline-text-3" id="text-3-5">
  728. <p>
  729. If we could give a name to the repeating part, we could shorten the code a lot. We cannot use <code>define</code> to give a name, but what we <i>can</i> do is to <i>lambda wrap</i> the whole code and give the repeating part as an argument, enabling us to give it a name inside the wrap. We will call it <code>make-length</code> inside the wrap.
  730. </p>
  731. <p>
  732. For <code>length-0</code> we can do it as follows:
  733. </p>
  734. <div class="org-src-container">
  735. <pre class="src src-scheme" id="org4d3afd6">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  736. (<span style="color: #9FCA56;">lambda</span> (something)
  737. (eternity something)))
  738. <span style="color: #75715E;">;; </span><span style="color: #41535B;">The wrapping lambda internally applies the given argument (the repeating part) to eternity.</span>
  739. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  740. (make-length eternity))
  741. <span style="color: #75715E;">;; </span><span style="color: #41535B;">The wrapping lambda is immediately applied to the repeating part,</span>
  742. (<span style="color: #9FCA56;">lambda</span> (something)
  743. (<span style="color: #9FCA56;">lambda</span> (lst)
  744. (<span style="color: #9FCA56;">cond</span>
  745. [(null? lst) 0]
  746. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Notice how the repeating part applies `something` to the cdr of the list. `something` will</span>
  747. <span style="color: #75715E;">;; </span><span style="color: #41535B;">be `eternity` in this case.</span>
  748. [<span style="color: #9FCA56;">else</span> (+ 1 (something (cdr lst)))]))))
  749. </pre>
  750. </div>
  751. <p>
  752. If this is still <code>length-0</code>, we should be able to use it as such:
  753. </p>
  754. <div class="org-src-container">
  755. <pre class="src src-scheme" id="org27bddd4">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  756. (<span style="color: #9FCA56;">lambda</span> (something)
  757. (eternity something)))
  758. (display
  759. (simple-format
  760. #f <span style="color: #55B5DB;">"~a\n"</span>
  761. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  762. (make-length eternity))
  763. (<span style="color: #9FCA56;">lambda</span> (something)
  764. (<span style="color: #9FCA56;">lambda</span> (lst)
  765. (<span style="color: #9FCA56;">cond</span>
  766. [(null? lst) 0]
  767. [<span style="color: #9FCA56;">else</span> (+ 1 (something (cdr lst)))]))))
  768. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Apply it to the empty list.</span>
  769. '())))
  770. </pre>
  771. </div>
  772. <p>
  773. As we can see, this still works.
  774. </p>
  775. <p>
  776. Previously, we applied the repreating part to itself. We named it <code>make-length</code> here, so we can implement <code>length-1</code> and <code>length-2</code> by applying <code>make-length</code> to <code>make-length</code> inside the wrap as follows:
  777. </p>
  778. <div class="org-src-container">
  779. <pre class="src src-scheme" id="orgda9a684">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  780. (<span style="color: #9FCA56;">lambda</span> (something)
  781. (eternity something)))
  782. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  783. (make-length
  784. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Apply make-length to make-length.</span>
  785. (make-length eternity)))
  786. (<span style="color: #9FCA56;">lambda</span> (something)
  787. (<span style="color: #9FCA56;">lambda</span> (lst)
  788. (<span style="color: #9FCA56;">cond</span>
  789. [(null? lst) 0]
  790. [<span style="color: #9FCA56;">else</span> (+ 1 (something (cdr lst)))]))))
  791. </pre>
  792. </div>
  793. <div class="org-src-container">
  794. <pre class="src src-scheme" id="org9c9e340">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  795. (<span style="color: #9FCA56;">lambda</span> (something)
  796. (eternity something)))
  797. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  798. <span style="color: #75715E;">;; </span><span style="color: #41535B;">This is length-2.</span>
  799. (make-length
  800. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Apply make-length to make-length applied to make-length applied to eternity, which is length-1.</span>
  801. (make-length
  802. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Apply make-length to make-length applied to eternity, which is length-0.</span>
  803. (make-length eternity))))
  804. (<span style="color: #9FCA56;">lambda</span> (something)
  805. (<span style="color: #9FCA56;">lambda</span> (lst)
  806. (<span style="color: #9FCA56;">cond</span>
  807. [(null? lst) 0]
  808. [<span style="color: #9FCA56;">else</span> (+ 1 (something (cdr lst)))]))))
  809. </pre>
  810. </div>
  811. <p>
  812. Let us try <code>length-2</code> defined like this:
  813. </p>
  814. <div class="org-src-container">
  815. <pre class="src src-scheme" id="org9acde36">(<span style="color: #9FCA56;">define</span> <span style="color: #55B5DB;">eternity</span>
  816. (<span style="color: #9FCA56;">lambda</span> (something)
  817. (eternity something)))
  818. (display
  819. (simple-format
  820. #f <span style="color: #55B5DB;">"~a\n"</span>
  821. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  822. (make-length
  823. (make-length
  824. (make-length eternity))))
  825. (<span style="color: #9FCA56;">lambda</span> (something)
  826. (<span style="color: #9FCA56;">lambda</span> (lst)
  827. (<span style="color: #9FCA56;">cond</span>
  828. [(null? lst) 0]
  829. [<span style="color: #9FCA56;">else</span> (+ 1 (something (cdr lst)))]))))
  830. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Apply it to the empty list.</span>
  831. '())))
  832. (display
  833. (simple-format
  834. #f <span style="color: #55B5DB;">"~a\n"</span>
  835. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  836. (make-length
  837. (make-length
  838. (make-length eternity))))
  839. (<span style="color: #9FCA56;">lambda</span> (something)
  840. (<span style="color: #9FCA56;">lambda</span> (lst)
  841. (<span style="color: #9FCA56;">cond</span>
  842. [(null? lst) 0]
  843. [<span style="color: #9FCA56;">else</span> (+ 1 (something (cdr lst)))]))))
  844. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Apply it to the list with 1 element.</span>
  845. '(a))))
  846. (display
  847. (simple-format
  848. #f <span style="color: #55B5DB;">"~a\n"</span>
  849. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  850. (make-length
  851. (make-length
  852. (make-length eternity))))
  853. (<span style="color: #9FCA56;">lambda</span> (something)
  854. (<span style="color: #9FCA56;">lambda</span> (lst)
  855. (<span style="color: #9FCA56;">cond</span>
  856. [(null? lst) 0]
  857. [<span style="color: #9FCA56;">else</span> (+ 1 (something (cdr lst)))]))))
  858. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Apply it to the list with 2 elements.</span>
  859. '(a b))))
  860. </pre>
  861. </div>
  862. <p>
  863. It gives the correct results.
  864. </p>
  865. <p>
  866. At this point it seems like recursion actually is a conditionally infinite tower of applications of a procedure. Notice the multiple nested applications of <code>make-length</code> in the code above.
  867. </p>
  868. <p>
  869. The problem is still, that the <code>make-length</code> is repeated once per iteration though. We notice however, that we apply <code>eternity</code>, when we do not have sufficient applications of the procedure any longer to process the list given. This means there will be no error, but also no result. Instead we will have infinite useless recursion going on. This is kind of like an error, even if no error or exception is raised. We will have to stop the recursion at some point to be able to do something more useful. However, this only happens in the bad case, where the list is too long to be processed by our number of applications of the procedure. This means, that we actually do not really care about how it goes wrong there. We do not ever want to get to the case, where we do not have sufficient applications. This means we could use any other procedure instead of <code>eternity</code>. That would only change the error case. Let us try to raise an error, when the list has too many elements to process, by giving a lambda, which raises an error, instead of giving eternity:
  870. </p>
  871. <div class="org-src-container">
  872. <pre class="src src-scheme" id="org827386c">(catch
  873. 'list-too-deep
  874. <span style="color: #75715E;">;; </span><span style="color: #41535B;">thunk (procedure that takes 0 arguments) producing the exception</span>
  875. (<span style="color: #9FCA56;">lambda</span> ()
  876. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  877. (make-length
  878. (make-length
  879. (make-length
  880. <span style="color: #75715E;">;; </span><span style="color: #41535B;">here we use an error raising procedure instead of eternity</span>
  881. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  882. (throw 'list-too-deep rest-of-list))))))
  883. (<span style="color: #9FCA56;">lambda</span> (something)
  884. (<span style="color: #9FCA56;">lambda</span> (lst)
  885. (<span style="color: #9FCA56;">cond</span>
  886. [(null? lst) 0]
  887. [<span style="color: #9FCA56;">else</span> (+ 1 (something (cdr lst)))]))))
  888. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Apply it to the list with 3 (1 too many) elements.</span>
  889. '(a b c)))
  890. <span style="color: #75715E;">;; </span><span style="color: #41535B;">handler</span>
  891. (<span style="color: #9FCA56;">lambda</span> (key . args)
  892. (display
  893. (simple-format #f <span style="color: #55B5DB;">"~a args: ~a\n"</span> <span style="color: #55B5DB;">"The list is too deep."</span> args))))
  894. </pre>
  895. </div>
  896. <p>
  897. (The above code uses GNU Guile Scheme speciifc exception handling.)
  898. </p>
  899. <p>
  900. As we can see a useful error message is output, because that is the behavior in the bad case, that the list is too long.
  901. </p>
  902. <p>
  903. The idea now is, that we can use the fact, that it does not matter which procedure we give as an argument. Instead of giving <code>eternity</code> or a procedure for error handling, we can give a procedure, which in the bad case creates another application of <code>length-0</code>, so that we never run out of applications of <code>length-0</code>! We already know a procedure creating <code>length-0</code>: <code>make-length</code> applied to any procedure.
  904. </p>
  905. <p>
  906. Here is how we are going to do it:
  907. </p>
  908. <div class="org-src-container">
  909. <pre class="src src-scheme" id="org288f20f">((<span style="color: #9FCA56;">lambda</span> (make-length)
  910. <span style="color: #75715E;">;; </span><span style="color: #41535B;">apply make-length to itself</span>
  911. (make-length make-length))
  912. (<span style="color: #9FCA56;">lambda</span> (proc)
  913. (<span style="color: #9FCA56;">lambda</span> (lst)
  914. (<span style="color: #9FCA56;">cond</span>
  915. [(null? lst) 0]
  916. [<span style="color: #9FCA56;">else</span>
  917. (+ 1
  918. <span style="color: #75715E;">;; </span><span style="color: #41535B;">apply the given procedure (make-length in this case) to itself</span>
  919. ((proc proc)
  920. (cdr lst)))]))))
  921. </pre>
  922. </div>
  923. <p>
  924. We apply <code>make-length</code> to itself, in order to get another procedure, which we can use for the recursive call in the case, that the list has more elements. We already know, that <code>make-length</code> will create another <code>length-0</code>, which has had a bad <code>else</code> case, which would have led to no result or an error. Previously we solved this issue in a bad way, by writing more and more calls to <code>make-length</code> which we wrapped around an innermost <code>length-0</code>, which made use of <code>eternity</code> or raised an error. Now we produce an ad-hoc <code>length-0</code>, only in case the list has more elements, to apply it to the rest of the list. It can in turn produce another <code>length-0</code>, if it needs to do so. This way, the list can have arbitrary length and our <code>length</code> function will still work.
  925. </p>
  926. <p>
  927. We can demonstrate, that the above code works:
  928. </p>
  929. <div class="org-src-container">
  930. <pre class="src src-scheme" id="orgbf6b2c3">(display
  931. (simple-format
  932. #f <span style="color: #55B5DB;">"~a\n"</span>
  933. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  934. (make-length make-length))
  935. (<span style="color: #9FCA56;">lambda</span> (proc)
  936. (<span style="color: #9FCA56;">lambda</span> (lst)
  937. (<span style="color: #9FCA56;">cond</span>
  938. [(null? lst) 0]
  939. [<span style="color: #9FCA56;">else</span>
  940. (+ 1
  941. ((proc proc)
  942. (cdr lst)))]))))
  943. '(a b c d))))
  944. (display
  945. (simple-format
  946. #f <span style="color: #55B5DB;">"~a\n"</span>
  947. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  948. (make-length make-length))
  949. (<span style="color: #9FCA56;">lambda</span> (proc)
  950. (<span style="color: #9FCA56;">lambda</span> (lst)
  951. (<span style="color: #9FCA56;">cond</span>
  952. [(null? lst) 0]
  953. [<span style="color: #9FCA56;">else</span>
  954. (+ 1
  955. ((proc proc)
  956. (cdr lst)))]))))
  957. '(a b c d e f g h))))
  958. </pre>
  959. </div>
  960. <pre class="example">
  961. 4
  962. 8
  963. </pre>
  964. <p>
  965. This is an implementation of <code>length</code>, without using its name anywhere.
  966. </p>
  967. <p>
  968. What happened here is actually the following: We could not use the name <code>length</code> anywhere in the definition, because we cannot use any <code>define</code> form and furthermore we want to get to some other construct, which can implement recursion in programming languages, which do not support calling a procedure within its own body. What we did instead is to have the name in another scope, another lambda receiving the logic of <code>length</code> as an argument, to give a name to this argument. That argument <code>make-length</code> is the logic of <code>length</code>, but with one difference. It takes a procedure too (<code>proc</code>) and gives it a name (<code>proc</code>), so that it can call that procedure wih the same procedure <code>proc</code> as an argument. The procedure <code>proc</code> however, is nothing else than what the other lambda gives as an argument, which in turn is the logic of <code>length</code> again. This way the recursive call does not need a binding defined using a <code>define</code> form and can work completely anonymously.
  969. </p>
  970. <p>
  971. Another way to describe it is the following: <code>make-length</code> gets a procedure <code>proc</code> as argument, only to be able to have it named inside the inner lambda expression. This way the inner lambda expression can make use of the given procedure. The given procedure then is <code>make-length</code> itself, given by the sibling lambda expression, which will allow creating ad-hoc procedures, lambdas, which to use in case there are more elements in the list. All of the parts are necessary:
  972. </p>
  973. <ol class="org-ol">
  974. <li><p>
  975. application of <code>make-length</code> to itself:
  976. </p>
  977. <div class="org-src-container">
  978. <pre class="src src-scheme" id="org5cec9b8"> ((<span style="color: #9FCA56;">lambda</span> (make-length)
  979. (make-length make-length))
  980. ...)
  981. </pre>
  982. </div>
  983. <p>
  984. The application to itself is only possible by wrapping with a lambda, to give an argument a name <code>make-length</code>.
  985. </p></li>
  986. <li><p>
  987. <code>make-length</code>, taking a procedure as an argument:
  988. </p>
  989. <div class="org-src-container">
  990. <pre class="src src-scheme" id="org707b458"> (...
  991. (<span style="color: #9FCA56;">lambda</span> (proc)
  992. (<span style="color: #9FCA56;">lambda</span> (lst)
  993. (<span style="color: #9FCA56;">cond</span>
  994. [(null? lst) 0]
  995. [<span style="color: #9FCA56;">else</span>
  996. (+ 1
  997. ((proc proc)
  998. (cdr lst)))]))))
  999. </pre>
  1000. </div>
  1001. <p>
  1002. This contains the logic of <code>length</code> in it, as well as the production of new lambdas in the <code>else</code> branch.
  1003. </p></li>
  1004. <li><p>
  1005. The outer application of the 1. part to the 2. part:
  1006. </p>
  1007. <div class="org-src-container">
  1008. <pre class="src src-scheme" id="org3e08bad"> (...
  1009. ...)
  1010. </pre>
  1011. </div>
  1012. <p>
  1013. This part is necessary for actually creating the function <code>length</code> by application of the 1. part to the 2. part.
  1014. </p></li>
  1015. </ol>
  1016. <p>
  1017. After the function <code>length</code> is made, <code>length</code> can be applied to any list.
  1018. </p>
  1019. </div>
  1020. </div>
  1021. <div id="outline-container-orgb7ac798" class="outline-3">
  1022. <h3 id="orgb7ac798"><span class="section-number-3">3.6</span> Making all kinds of recursive procedures</h3>
  1023. <div class="outline-text-3" id="text-3-6">
  1024. <p>
  1025. Now that <code>length</code> has been implemented, we would like to have the whole concept of how that was done generalized, so that we can use it for any procedure. In order to achieve that, one last problem needs to be addressed. In order to use the concept for any procedure, we need to be able to give any procedure as an argument at some point. Currently however, the logic of <code>length</code> is somewhere inside and not given as a parameter.
  1026. </p>
  1027. <p>
  1028. To get to a version, where we give the logic of <code>length</code> as an argument let us look at the current definition again:
  1029. </p>
  1030. <div class="org-src-container">
  1031. <pre class="src src-scheme" id="org8a6ab45">((<span style="color: #9FCA56;">lambda</span> (make-length)
  1032. (make-length make-length))
  1033. <span style="color: #75715E;">;; </span><span style="color: #41535B;">lambda wrapping around the logic of length -- make-length</span>
  1034. (<span style="color: #9FCA56;">lambda</span> (proc)
  1035. (<span style="color: #9FCA56;">lambda</span> (lst)
  1036. (<span style="color: #9FCA56;">cond</span>
  1037. [(null? lst) 0]
  1038. [<span style="color: #9FCA56;">else</span>
  1039. (+ 1
  1040. <span style="color: #75715E;">;; </span><span style="color: #41535B;">usage of proc, argument to outer lambda</span>
  1041. ((proc proc)
  1042. (cdr lst)))]))))
  1043. </pre>
  1044. </div>
  1045. <p>
  1046. As we can see, the logic of <code>length</code> is wrapped in something we called <code>make-length</code> before. Inside the logic of <code>length</code> the argument <code>proc</code> is used, so the logic depends on the wrapper. If we managed to pull out the usage of <code>proc</code>, the logic of <code>length</code> would not depend on the wrap any longer. Then it can be imagined, that we could even give this logic as argument, in effect giving <code>length</code> as argument, allowing us to give any other procedure as well. So let us try to pull it out.
  1047. </p>
  1048. <p>
  1049. First we can try to naively pull it out by <i>lambda wrapping</i> as follows:
  1050. </p>
  1051. <div class="org-src-container">
  1052. <pre class="src src-scheme" id="orgaab9989">((<span style="color: #9FCA56;">lambda</span> (make-length)
  1053. (make-length make-length))
  1054. (<span style="color: #9FCA56;">lambda</span> (proc)
  1055. <span style="color: #75715E;">;; </span><span style="color: #41535B;">We need acces to the given procedure proc, so the lambda wrapping needs to</span>
  1056. <span style="color: #75715E;">;; </span><span style="color: #41535B;">be inside the wrapper. We name the argument length, because it is really</span>
  1057. <span style="color: #75715E;">;; </span><span style="color: #41535B;">the simple definition of length, with an external binding of length by a</span>
  1058. <span style="color: #75715E;">;; </span><span style="color: #41535B;">wrapping lambda expression now.</span>
  1059. (<span style="color: #9FCA56;">lambda</span> (length)
  1060. (<span style="color: #9FCA56;">lambda</span> (lst)
  1061. (<span style="color: #9FCA56;">cond</span>
  1062. [(null? lst) 0]
  1063. [<span style="color: #9FCA56;">else</span>
  1064. (+ 1
  1065. <span style="color: #75715E;">;; </span><span style="color: #41535B;">usage of length</span>
  1066. (length (cdr lst)))]))
  1067. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Here we produce the lambdas for usage in the else branch of length ...</span>
  1068. (proc proc))))
  1069. </pre>
  1070. </div>
  1071. <p>
  1072. However, there is a problem with this code. It does not work. While previously the application of <code>proc</code> to <code>proc</code> was inside the <code>else</code> branch and only evaluated, when that branch was entered. Now however, it is evaluated when the call <code>(make-length make-length)</code> is made. That means in order to evaluate the whole thing, one needs to know what <code>(proc proc)</code> is. But <code>proc</code> is the argument given to <code>make-length</code>, which is the same lambda expression, for whose evaluation we need to know what <code>(proc proc)</code> is. This will result in an endless expansion of code.
  1073. </p>
  1074. <p>
  1075. Previously, the call <code>(proc proc)</code> was inside the <code>else</code> branch. Evaluating it would still need to know what <code>(proc proc)</code> is and evaluate it. However, since in the evaluation of a <code>(proc proc)</code> is inside the <code>else</code> branch and in its evaluation the <code>proc</code> appears again in the <code>else</code> branch, it would not get evaluated over and over again. The code in an <code>else</code> branch of <code>cond</code> is only evaluated, when <code>else</code> is the case that is entered. This is because <code>cond</code> is a macro, not a procedure! This is what actually prevents endless code execution.
  1076. </p>
  1077. <p>
  1078. What can be done about this? We cannot put the call back into the <code>else</code> branch again, as we wanted to extract it. Instead, we need make use of <i>delayed evaluation</i> of the application of <code>proc</code> to itself to delay creating endless expansion of expressions, until the <code>else</code> branch is entered. Delayed evaluation of the application of <code>proc</code> to itself can be done using <i>lambda wrapping</i> again. Note, that <code>length</code> in the <code>else</code> branch takes 1 argument, which is the rest of the list. The delayed evaluation thus done as follows:
  1079. </p>
  1080. <div class="org-src-container">
  1081. <pre class="src src-scheme" id="orgf283b5d">((<span style="color: #9FCA56;">lambda</span> (make-length)
  1082. (make-length make-length))
  1083. (<span style="color: #9FCA56;">lambda</span> (proc)
  1084. ((<span style="color: #9FCA56;">lambda</span> (length)
  1085. (<span style="color: #9FCA56;">lambda</span> (lst)
  1086. (<span style="color: #9FCA56;">cond</span>
  1087. [(null? lst) 0]
  1088. [<span style="color: #9FCA56;">else</span>
  1089. <span style="color: #75715E;">;; </span><span style="color: #41535B;">usage of length, just like before, using 2 argument</span>
  1090. (+ 1 (length (cdr lst)))])))
  1091. <span style="color: #75715E;">;; </span><span style="color: #41535B;">lambda wrapping -- delayed evaluation of (proc proc)</span>
  1092. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1093. <span style="color: #75715E;">;; </span><span style="color: #41535B;">(proc proc) is not evaluated, until the wrapping lambda is called</span>
  1094. ((proc proc) rest-of-list)))))
  1095. </pre>
  1096. </div>
  1097. <p>
  1098. Let us try to use it:
  1099. </p>
  1100. <div class="org-src-container">
  1101. <pre class="src src-scheme" id="orgf644730">(display
  1102. (simple-format
  1103. #f <span style="color: #55B5DB;">"~a\n"</span>
  1104. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  1105. (make-length make-length))
  1106. (<span style="color: #9FCA56;">lambda</span> (proc)
  1107. ((<span style="color: #9FCA56;">lambda</span> (length)
  1108. (<span style="color: #9FCA56;">lambda</span> (lst)
  1109. (<span style="color: #9FCA56;">cond</span>
  1110. [(null? lst) 0]
  1111. [<span style="color: #9FCA56;">else</span>
  1112. <span style="color: #75715E;">;; </span><span style="color: #41535B;">usage of length, just like before, using 2 argument</span>
  1113. (+ 1 (length (cdr lst)))])))
  1114. <span style="color: #75715E;">;; </span><span style="color: #41535B;">lambda wrapping -- delayed evaluation of (proc proc)</span>
  1115. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1116. <span style="color: #75715E;">;; </span><span style="color: #41535B;">(proc proc) is not evaluated, until the wrapping lambda is called</span>
  1117. ((proc proc) rest-of-list)))))
  1118. <span style="color: #75715E;">;; </span><span style="color: #41535B;">apply to a list of 3 elements</span>
  1119. '(a b c))))
  1120. (display
  1121. (simple-format
  1122. #f <span style="color: #55B5DB;">"~a\n"</span>
  1123. (((<span style="color: #9FCA56;">lambda</span> (make-length)
  1124. (make-length make-length))
  1125. (<span style="color: #9FCA56;">lambda</span> (proc)
  1126. ((<span style="color: #9FCA56;">lambda</span> (length)
  1127. (<span style="color: #9FCA56;">lambda</span> (lst)
  1128. (<span style="color: #9FCA56;">cond</span>
  1129. [(null? lst) 0]
  1130. [<span style="color: #9FCA56;">else</span>
  1131. <span style="color: #75715E;">;; </span><span style="color: #41535B;">usage of length, just like before, using 2 argument</span>
  1132. (+ 1 (length (cdr lst)))])))
  1133. <span style="color: #75715E;">;; </span><span style="color: #41535B;">lambda wrapping -- delayed evaluation of (proc proc)</span>
  1134. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1135. <span style="color: #75715E;">;; </span><span style="color: #41535B;">(proc proc) is not evaluated, until the wrapping lambda is called</span>
  1136. ((proc proc) rest-of-list)))))
  1137. <span style="color: #75715E;">;; </span><span style="color: #41535B;">apply to a list of more elements</span>
  1138. '(a b c d e f))))
  1139. </pre>
  1140. </div>
  1141. <pre class="example">
  1142. 3
  1143. 6
  1144. </pre>
  1145. <p>
  1146. That is the correct and expected result.
  1147. </p>
  1148. <p>
  1149. We have managed to pull the call of <code>proc</code> to itself out of the <code>length</code> logic. Now we can extract that as well, as it does not depend on the wrapping lambda expression, which we call <code>make-length</code> any longer. Let us do that, in order to make this part interchangable with other procedures. To be clear about what shall be pulled out, here is the part of the code:
  1150. </p>
  1151. <div class="org-src-container">
  1152. <pre class="src src-scheme" id="org207428b">(<span style="color: #9FCA56;">lambda</span> (length)
  1153. (<span style="color: #9FCA56;">lambda</span> (lst)
  1154. (<span style="color: #9FCA56;">cond</span>
  1155. [(null? lst) 0]
  1156. [<span style="color: #9FCA56;">else</span>
  1157. (+ 1 (length (cdr lst)))])))
  1158. </pre>
  1159. </div>
  1160. <p>
  1161. We want to give this part of the code as an argument to the other part of the code, so that it can come from the outside. This means, that we need to wrap the other part of the code on the outermost level as follows:
  1162. </p>
  1163. <div class="org-src-container">
  1164. <pre class="src src-scheme" id="orga15fad5"><span style="color: #75715E;">;; </span><span style="color: #41535B;">Here is the wrapping lambda expression at the outermost level.</span>
  1165. ((<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1166. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1167. (make-length make-length))
  1168. (<span style="color: #9FCA56;">lambda</span> (proc)
  1169. (extracted-proc
  1170. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Here is the lambda that shall be applied to the rest of the list.</span>
  1171. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1172. ((proc proc) rest-of-list))))))
  1173. <span style="color: #75715E;">;; </span><span style="color: #41535B;">Here is the extracted logic of length. As an argument it requires the</span>
  1174. <span style="color: #75715E;">;; </span><span style="color: #41535B;">lambda that shall be applied to the rest of the list.</span>
  1175. (<span style="color: #9FCA56;">lambda</span> (length)
  1176. (<span style="color: #9FCA56;">lambda</span> (lst)
  1177. (<span style="color: #9FCA56;">cond</span>
  1178. [(null? lst) 0]
  1179. [<span style="color: #9FCA56;">else</span>
  1180. (+ 1 (length (cdr lst)))]))))
  1181. </pre>
  1182. </div>
  1183. <p>
  1184. Let us test this code again with a few examples:
  1185. </p>
  1186. <div class="org-src-container">
  1187. <pre class="src src-scheme" id="org9062564">(display
  1188. (simple-format
  1189. #f <span style="color: #55B5DB;">"~a\n"</span>
  1190. (((<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1191. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1192. (make-length make-length))
  1193. (<span style="color: #9FCA56;">lambda</span> (proc)
  1194. (extracted-proc
  1195. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1196. ((proc proc) rest-of-list))))))
  1197. (<span style="color: #9FCA56;">lambda</span> (length)
  1198. (<span style="color: #9FCA56;">lambda</span> (lst)
  1199. (<span style="color: #9FCA56;">cond</span>
  1200. [(null? lst) 0]
  1201. [<span style="color: #9FCA56;">else</span>
  1202. (+ 1 (length (cdr lst)))]))))
  1203. <span style="color: #75715E;">;; </span><span style="color: #41535B;">apply to a list of 3 elements</span>
  1204. '(a b c))))
  1205. (display
  1206. (simple-format
  1207. #f <span style="color: #55B5DB;">"~a\n"</span>
  1208. (((<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1209. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1210. (make-length make-length))
  1211. (<span style="color: #9FCA56;">lambda</span> (proc)
  1212. (extracted-proc
  1213. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1214. ((proc proc) rest-of-list))))))
  1215. (<span style="color: #9FCA56;">lambda</span> (length)
  1216. (<span style="color: #9FCA56;">lambda</span> (lst)
  1217. (<span style="color: #9FCA56;">cond</span>
  1218. [(null? lst) 0]
  1219. [<span style="color: #9FCA56;">else</span>
  1220. (+ 1 (length (cdr lst)))]))))
  1221. <span style="color: #75715E;">;; </span><span style="color: #41535B;">apply to a list of more elements</span>
  1222. '(a b c d e f))))
  1223. </pre>
  1224. </div>
  1225. <pre class="example">
  1226. 3
  1227. 6
  1228. </pre>
  1229. <p>
  1230. Still working.
  1231. </p>
  1232. <p>
  1233. If we go back to the first formulation of <code>make-length</code>, which is able to create <code>length-0</code>, we will see, that this is exactly, what we extracted.
  1234. </p>
  1235. <p>
  1236. We can now go ahead and give other procedures as arguments. For example we can give a procedure, which sums up all the numbers in a simple, not nested list as follows:
  1237. </p>
  1238. <div class="org-src-container">
  1239. <pre class="src src-scheme" id="org8365e2f">((<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1240. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1241. (make-length make-length))
  1242. (<span style="color: #9FCA56;">lambda</span> (proc)
  1243. (extracted-proc
  1244. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1245. ((proc proc) rest-of-list))))))
  1246. <span style="color: #75715E;">;; </span><span style="color: #41535B;">the procedure make-sum</span>
  1247. (<span style="color: #9FCA56;">lambda</span> (sum)
  1248. (<span style="color: #9FCA56;">lambda</span> (lst)
  1249. (<span style="color: #9FCA56;">cond</span>
  1250. [(null? lst) 0]
  1251. [<span style="color: #9FCA56;">else</span>
  1252. (+ (car lst)
  1253. (sum (cdr lst)))]))))
  1254. </pre>
  1255. </div>
  1256. <p>
  1257. Let us check, whether that works:
  1258. </p>
  1259. <div class="org-src-container">
  1260. <pre class="src src-scheme" id="org95f32e1">(display
  1261. (simple-format
  1262. #f <span style="color: #55B5DB;">"~a\n"</span>
  1263. (((<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1264. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1265. (make-length make-length))
  1266. (<span style="color: #9FCA56;">lambda</span> (proc)
  1267. (extracted-proc
  1268. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1269. ((proc proc) rest-of-list))))))
  1270. <span style="color: #75715E;">;; </span><span style="color: #41535B;">the procedure make-sum</span>
  1271. (<span style="color: #9FCA56;">lambda</span> (sum)
  1272. (<span style="color: #9FCA56;">lambda</span> (lst)
  1273. (<span style="color: #9FCA56;">cond</span>
  1274. [(null? lst) 0]
  1275. [<span style="color: #9FCA56;">else</span>
  1276. (+ (car lst)
  1277. (sum (cdr lst)))]))))
  1278. '(1 2 3))))
  1279. </pre>
  1280. </div>
  1281. <pre class="example">
  1282. 6
  1283. </pre>
  1284. <p>
  1285. Yes, we got the correct result! Let us make one for nested lists containing numbers:
  1286. </p>
  1287. <div class="org-src-container">
  1288. <pre class="src src-scheme" id="org17bdfd4">(display
  1289. (simple-format
  1290. #f <span style="color: #55B5DB;">"~a\n"</span>
  1291. (((<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1292. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1293. (make-length make-length))
  1294. (<span style="color: #9FCA56;">lambda</span> (proc)
  1295. (extracted-proc
  1296. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1297. ((proc proc) rest-of-list))))))
  1298. <span style="color: #75715E;">;; </span><span style="color: #41535B;">the procedure make-sum</span>
  1299. (<span style="color: #9FCA56;">lambda</span> (sum)
  1300. (<span style="color: #9FCA56;">lambda</span> (lst)
  1301. (<span style="color: #9FCA56;">cond</span>
  1302. [(null? lst) 0]
  1303. [(pair? (car lst))
  1304. (+ (sum (car lst))
  1305. (sum (cdr lst)))]
  1306. [<span style="color: #9FCA56;">else</span>
  1307. (+ (car lst)
  1308. (sum (cdr lst)))]))))
  1309. '(1 2 (3 4 5) 6))))
  1310. </pre>
  1311. </div>
  1312. <pre class="example">
  1313. 21
  1314. </pre>
  1315. <p>
  1316. The result is correct as well. We see, that we can define procedures for arbitrarily structured lists or other data structures, if we create the procedures accordingly and use them like this.
  1317. </p>
  1318. </div>
  1319. </div>
  1320. <div id="outline-container-org6e74d52" class="outline-3">
  1321. <h3 id="org6e74d52"><span class="section-number-3">3.7</span> Separating the Y-combinator</h3>
  1322. <div class="outline-text-3" id="text-3-7">
  1323. <p>
  1324. There is a question however. What is this other part of the code, which we do not change, when we adapt the lambda expression for length of a list or sum of all numbers in a list? This part seems to do all the magic, that allows us to write <code>length</code>, <code>sum</code> and <code>sum*</code> without creating a binding using a <code>define</code> form. It seems special, so let us write it down:
  1325. </p>
  1326. <div class="org-src-container">
  1327. <pre class="src src-scheme" id="org7efba7f">(<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1328. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1329. (make-length make-length))
  1330. (<span style="color: #9FCA56;">lambda</span> (proc)
  1331. (extracted-proc
  1332. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1333. ((proc proc) rest-of-list))))))
  1334. </pre>
  1335. </div>
  1336. <p>
  1337. This is the so called Y-combinator!
  1338. </p>
  1339. </div>
  1340. <div id="outline-container-org5e025f1" class="outline-4">
  1341. <h4 id="org5e025f1"><span class="section-number-4">3.7.1</span> Renaming arguments</h4>
  1342. <div class="outline-text-4" id="text-3-7-1">
  1343. <p>
  1344. In topic specific literature, the arguments in the lambda expressions of the Y-combinator are usually named differently. In order to get the same naming let us consider a few things:
  1345. </p>
  1346. <ol class="org-ol">
  1347. <li><p>
  1348. The argument <code>proc</code> can actually be called <code>make-length</code>, because it only ever will be <code>make-length</code>, as that lambda expression it is called as follows: <code>(make-length make-length)</code>. So let us write down a changed version:
  1349. </p>
  1350. <div class="org-src-container">
  1351. <pre class="src src-scheme" id="orgf3367df"> (<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1352. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1353. (make-length make-length))
  1354. (<span style="color: #9FCA56;">lambda</span> (make-length)
  1355. (extracted-proc
  1356. (<span style="color: #9FCA56;">lambda</span> (rest-of-list)
  1357. ((make-length make-length) rest-of-list))))))
  1358. </pre>
  1359. </div></li>
  1360. <li><p>
  1361. As we may work with other data structures than lists and accordingly adapted procedures we give to the Y-combinator, let us not use <code>rest-of-list</code> any longer as an argument name and instead use <code>x</code>, because it can really be anything:
  1362. </p>
  1363. <div class="org-src-container">
  1364. <pre class="src src-scheme" id="orgdbf5f98"> (<span style="color: #9FCA56;">lambda</span> (extracted-proc)
  1365. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1366. (make-length make-length))
  1367. (<span style="color: #9FCA56;">lambda</span> (make-length)
  1368. (extracted-proc
  1369. (<span style="color: #9FCA56;">lambda</span> (x)
  1370. ((make-length make-length) x))))))
  1371. </pre>
  1372. </div></li>
  1373. <li><p>
  1374. The argument name <code>extracted-proc</code> does not help, when seeing the Y-combinator in this form, as it is not clear, what the procedure given was extracted from. We might as well simply name it <code>proc</code> only:
  1375. </p>
  1376. <div class="org-src-container">
  1377. <pre class="src src-scheme" id="orgaa7bf58"> (<span style="color: #9FCA56;">lambda</span> (proc)
  1378. ((<span style="color: #9FCA56;">lambda</span> (make-length)
  1379. (make-length make-length))
  1380. (<span style="color: #9FCA56;">lambda</span> (make-length)
  1381. (proc
  1382. (<span style="color: #9FCA56;">lambda</span> (x)
  1383. ((make-length make-length) x))))))
  1384. </pre>
  1385. </div></li>
  1386. <li><p>
  1387. Lastly, the name <code>make-length</code> is no longer appropriate, since we can make all kinds of recursive procedures, not only <code>length</code>, using the Y-combinator. So let us name it <code>f</code>, as it can be any recursive procedure or function:
  1388. </p>
  1389. <div class="org-src-container">
  1390. <pre class="src src-scheme" id="orgfc211c7"> (<span style="color: #9FCA56;">lambda</span> (proc)
  1391. ((<span style="color: #9FCA56;">lambda</span> (f)
  1392. (f f))
  1393. (<span style="color: #9FCA56;">lambda</span> (f)
  1394. (proc
  1395. (<span style="color: #9FCA56;">lambda</span> (x)
  1396. ((f f) x))))))
  1397. </pre>
  1398. </div>
  1399. <p>
  1400. Or with different line-breaking:
  1401. </p>
  1402. <div class="org-src-container">
  1403. <pre class="src src-scheme" id="org31d76b2"> (<span style="color: #9FCA56;">lambda</span> (proc)
  1404. ((<span style="color: #9FCA56;">lambda</span> (f) (f f))
  1405. (<span style="color: #9FCA56;">lambda</span> (f)
  1406. (proc
  1407. (<span style="color: #9FCA56;">lambda</span> (x) ((f f) x))))))
  1408. </pre>
  1409. </div></li>
  1410. </ol>
  1411. <p>
  1412. To be precise, literature calls this form of the Y-combinator the <i>applicative-order Y-combinator</i>.
  1413. </p>
  1414. <p>
  1415. Let us see it in action one more time using a standard example:
  1416. </p>
  1417. <div class="org-src-container">
  1418. <pre class="src src-scheme" id="org1481843">(display
  1419. (simple-format
  1420. #f <span style="color: #55B5DB;">"Fibonacci of 10: ~a\n"</span>
  1421. (((<span style="color: #9FCA56;">lambda</span> (proc)
  1422. ((<span style="color: #9FCA56;">lambda</span> (f) (f f))
  1423. (<span style="color: #9FCA56;">lambda</span> (f)
  1424. (proc
  1425. (<span style="color: #9FCA56;">lambda</span> (x) ((f f) x))))))
  1426. (<span style="color: #9FCA56;">lambda</span> (fibonacci)
  1427. (<span style="color: #9FCA56;">lambda</span> (num)
  1428. (<span style="color: #9FCA56;">cond</span>
  1429. [(&lt;= num 2) 1]
  1430. [<span style="color: #9FCA56;">else</span>
  1431. (+ (fibonacci (- num 1))
  1432. (fibonacci (- num 2)))]))))
  1433. 10)))
  1434. </pre>
  1435. </div>
  1436. <pre class="example">
  1437. Fibonacci of 10: 55
  1438. </pre>
  1439. <p>
  1440. One can see, this also works on numbers. Basically it works on any data structure and how it works with a data structure depends only on the implementation of the procedure, which we give to the Y-combinator.
  1441. </p>
  1442. </div>
  1443. </div>
  1444. </div>
  1445. </div>
  1446. <div id="outline-container-orgede3d6b" class="outline-2">
  1447. <h2 id="orgede3d6b"><span class="section-number-2">4</span> Final words</h2>
  1448. <div class="outline-text-2" id="text-4">
  1449. <p>
  1450. Without the help of the book "The Little Schemer", I would most likely not have been able to derive the Y-combinator on my own. I had to think long and hard about some of the steps, why one would perform the equivalent transformations and how to describe these steps, so that there is more description than in the book. The book however, with its rather rare way of asking questions, making me think about the content a lot, helped me being able to write about the Y-combinator and how it can be derived.
  1451. </p>
  1452. <p>
  1453. I encourage everyone, who is a software developer to read "The Little Schemer". It can be an enormously insightful and enlightening read. It may take a lot of time to work through it and understand all or at least most of the content, but you really owe it to your computer science education.
  1454. </p>
  1455. </div>
  1456. </div>
  1457. </div>
  1458. <div id="postamble" class="status">
  1459. <p class="author">Author: Zelphir Kaltstahl</p>
  1460. <p class="date">Created: 2020-08-23 So 13:46</p>
  1461. <p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
  1462. </div>
  1463. </body>
  1464. </html>