{\rtf1\mac\deff2 {\fonttbl{\f0\fswiss Chicago;}{\f2\froman New York;}{\f3\fswiss Geneva;}{\f4\fmodern Monaco;}{\f13\fnil Zapf Dingbats;}{\f16\fnil Palatino;}{\f20\froman Times;}{\f21\fswiss Helvetica;}{\f22\fmodern Courier;}{\f23\ftech Symbol;} {\f1948\fnil Lithos-Bold;}{\f2285\fnil Lithos-Light;}{\f2651\fnil Lithos-Black;}{\f2847\fnil Lithos-ExtraLight;}{\f3015\fnil Lithos-Regular;}{\f5862\fnil Bellevue;}{\f12899\fnil AppleGaramond LtIt;}{\f12900\fnil AppleGaramond BkIt;} {\f12901\fnil AppleGaramond BdIt;}{\f12902\fnil AppleGaramond Lt;}{\f12903\fnil AppleGaramond Bk;}{\f12904\fnil AppleGaramond Bd;}{\f13101\fnil Tekton Oblique;}{\f13102\fnil Tekton;}{\f14590\fnil BlkI New Aster BlackItalic;} {\f14591\fnil Blk New Aster Black;}{\f14592\fnil SBI New Aster SemiBoldItalic;}{\f14593\fnil SB New Aster SemiBold;}{\f14594\fnil BI New Aster BoldItalic;}{\f14595\fnil B New Aster Bold;}{\f14596\fnil I New Aster Italic;}{\f14597\fnil New Aster;} {\f14819\fnil BI LucidaSans BoldItalic;}{\f14820\fnil B LucidaSans Bold;}{\f14821\fnil I LucidaSans Italic;}{\f14822\fnil LucidaSans Roman;}{\f14887\fnil BI Lucida BoldItalic;}{\f14888\fnil B Lucida Bold;}{\f14889\fnil I Lucida Italic;} {\f14890\fnil Lucida;}{\f14917\fnil BI Letter Gothic BoldSlanted;}{\f14918\fnil B Letter Gothic Bold;}{\f14919\fnil I Letter Gothic Slanted;}{\f14920\fnil Letter Gothic;}}{\colortbl\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255; \red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;}{\stylesheet{\s224\li480\ri480 \b\v\f16\fs20 \sbasedon0\snext0 PostScript;}{\s231\li1440\ri720\keep\tqr\tldot\tx8640 \f16 \sbasedon232\snext0 toc 3;}{\s232\li960\ri480\tqr\tldot\tx8640 \f16 \sbasedon233\snext0 toc 2;}{\s233\li480\ri480\tqr\tldot\tx8640 \b\f16 \sbasedon0\snext0 toc 1;}{\s235\li1800\ri480 \f16 \sbasedon0\snext0 index 6;}{\s236\li1440\ri480 \f16 \sbasedon0\snext0 index 5;}{\s237\li1080\ri480 \f16 \sbasedon0\snext0 index 4;}{\s238\li720\ri480 \f16 \sbasedon0\snext0 index 3;}{\s239\li960 \f16 \sbasedon0\snext0 index 2;}{\s240\li480 \f16 \sbasedon0\snext0 index 1;}{\s242\li480\ri480 \f16 \sbasedon0\snext0 page number;}{\s243\li440\ri460\brdrt\brdrs \tqc\tx3600\tqr\tx8900 \i\f16 \sbasedon0\snext243 footer;}{\s244\ri480\brdrb\brdrs \tqr\tx8900 \i\f16\fs20 \sbasedon0\snext244 header;}{\s245\li480\ri480 \f16\fs20\up6 \sbasedon0\snext0 footnote reference;}{\s246\li480\ri480 \f16\fs20 \sbasedon0\snext246 footnote text;}{\s249\sb240\keep \i\f16\fs20 \sbasedon0\snext0 heading 7;}{\s250\sb240\keep \b\f16 \sbasedon251\snext0 heading 6;}{\s251\sb240\keep \b\f16 \sbasedon0\snext0 heading 5;}{ \s252\li475\ri480\keepn \b\f16 \sbasedon253\snext0 heading 4,heading 4 (1 top page),H3;}{\s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 \sbasedon7\snext0 heading 3,H2;}{\s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 \sbasedon3\snext0 heading 2,H1;}{\s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 \sbasedon1\snext0 heading 1;}{\li480\ri480 \f16 \sbasedon222\snext0 Normal;}{\s1\li480\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 \sbasedon2\snext2 sec1;}{\s2\li480\ri480\sa120 \f16 \sbasedon0\snext2 body;}{\s3\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 \sbasedon1\snext2 sec2;}{\s4\li480\ri480\tx2640 \f16 \sbasedon13\snext4 list 2;}{ \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 \sbasedon2\snext6 example 1;}{\s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 \sbasedon5\snext6 example 2;}{\s7\li480\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 \sbasedon3\snext2 sec3;}{ \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 \sbasedon6\snext6 example 3;}{\s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 \sbasedon2\snext10 def1;}{\s10\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 \sbasedon9\snext11 def2;}{ \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 \sbasedon10\snext11 def3;}{\s12\li480\ri480\sa240\tx2640 \f16 \sbasedon4\snext12 list 3;}{\s13\li480\ri480\sb120\tx2640 \f16 \sbasedon2\snext13 list 1;}{\s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \f16 \sbasedon2\snext14 table 1;}{\s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 \sbasedon14\snext15 table 2;}{\s16\fi-2160\li2640\ri480\sa240\tx2640 \f16 \sbasedon15\snext16 table 3;}{\s17\li480\ri480\sa120\tx2640 \f16 \sbasedon2\snext17 body tight;}{ \s18\fi-360\li1440\ri480\sa160 \f16 \sbasedon0\snext18 list13;}{\s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 \sbasedon9\snext19 def1-alt;}{\s20\fi-1800\li2880\ri480\sa160 \f16 \sbasedon15\snext20 table 2a;}{\s21\fi-360\li840\ri480\sa160 \f16 \sbasedon2\snext21 bulleted list;}{\s22\li960\ri480\sb120\sa240\keepn\tx2880\tx4800\tx6720 \f22\fs20 \sbasedon5\snext22 example13;}{\s23\fi-2160\li2640\ri480\sa240\keep\tx2640 \f16 \sbasedon14\snext23 table13;}{\s24\fi-2160\li4860\ri480\sa160\tx4860 \f16 \sbasedon15\snext24 table indented;}{\s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 \sbasedon6\snext25 example small;}{\s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 \sbasedon0\snext27 left side;}{\s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 \sbasedon26\snext26 right side;}{\s28\keep \f16 \sbasedon0\snext28 Normal Tight;}{\s29\sb240\keep \b\f16\fs96 \sbasedon0\snext29 Titlepage;}{\s30\li-360\ri720\sb120\keep\tx2880 \f16\fs20 \sbasedon32\snext30 Blurb;}{\s31\qc\li-2160\sb120\keep \f16\fs72 \sbasedon0\snext0 Chapter;}{\s32\ri720\sb120\keep\tx2880 \f16 \sbasedon0\snext32 Contributors;}{\s33\li2880\ri720\keep\tx2880 \f16 \sbasedon32\snext33 ContributorsMore;}{\s34\sb240\keep \v\f16 \sbasedon224\snext34 Hidden;}{ \s35\li360\keep\keepn\tx3240 \f22\fs20 \sbasedon0\snext35 code example;}{\s36\sb80\keep\keepn\tx360\tx3240 \f16\fs20 \sbasedon0\snext36 code w/tabbed comment;}{\s37\fi-280\li360\keep \i\f16 \sbasedon0\snext37 doc comment;}{\s38\fi-180\li180\sb120\keep \f16 \sbasedon0\snext38 Bulleted;}{\s39\sb240\keep\tqr\tx7920 \f16 \sbasedon0\snext39 design note title;}{\s40\sb180\keep \f65535\fs28 \sbasedon0\snext40 table description;}{\s41\li360\ri180\sb240\keep\keepn\box\brdrdot \phpg\absw2520 \f16 \sbasedon253\snext41 Note;}{\s42\sb720\sl240\keepn\pagebb\tx720 \b\f16\fs36 \sbasedon43\snext43 Heading;}{\s43\sb720\sl240\keepn\tx720 \b\f16\fs28 \sbasedon0\snext44 Subheading;}{\s44\li475\ri475\sb160\sl240\keep\tx720 \f16 \sbasedon0\snext44 Text;}{ \s45\fi-260\li980\sl240 \f16 \sbasedon0\snext45 blah;}{\s46\li360\sb240\sl240\keep\tx720 \f22\fs20 \sbasedon44\snext46 Code;}}\margl1440\margr1440\margt2160\margb2160\facingp\widowctrl\ftnbj\fracwidth \sectd \pgnrestart\linemod0\linex0\cols1\endnhere \pard\plain \li480\ri480\sb2880 \f16 {\fs120 Dylan}{\fs18\up52 TM}{\fs120 \par }\pard \li480\ri480 {\fs72 Interim \par Reference Manual\par }\pard \li480\ri480\sb480 {{\pict\macpict\picw228\pich31 035800000000001f00e4001102ff0c00ffffffff000000000000000000e40000001f00000000000000a1006400086450726f0000000100a0008200a0008c00a100d800040000400000a100d600040000400000a000d7001e0001000a00000000002000e50007000000000008001700230e0f00a100ca000800000000000000 0000a100c800080000015201520005001affff4ccd4ccd001b00000006f7160041000500040019001800a000c900a100d600040000400000a000d700a000d900a100d600040000400000a100d800040000400000a000be00a000d9000800080071001e00020001001c001b000200140015001b001c0009000a000100020014 00a100d800040000400000a000bf00a000d900a000d700a100d800040000400000a100d600040000400000a000d7000800170022000200143c0d00a100ca0008000000000000000000a100c80008000000150014fff1001affff799b4ccd0041000500460019005a00a000c900a100d600040000400000a000d700a000d900 a100d600040000400000a100d800040000400000a000be00a000d9000800080071001e00020043001c005e0002004b0009005e001c0056001500430002004b00a100d800040000400000a000bf00a000d900a000d700a100d800040000400000a100d600040000400000a000d70008001700220002004b490d00a100ca0008 000000000000000000a100c800080000002e002e000a001a0001cccb666400410005008a0019009e00a000c900a100d600040000400000a000d700a000d900a100d600040000400000a100d800040000400000a000be00a000d9000800080071001e00010086001e00a200010094001000a2001e0094000f00860001009400 a100d800040000400000a000bf00a000d900a000d700a100d800040000400000a100d600040000400000a000d700080017002200010094430e00a100ca0008000000000000000000a100c800080000015a0159ffe4001a4ccd8371ffff0041000500cc001900e000a000c900a100d600040000400000a000d700a000d900a1 00d600040000400000a100d800040000400000a000be00a000d9000800080071001e000300ca001c00e3000300de001700e3001c00cf000800ca000300de00a100d800040000400000a000bf00a000d900a000d700a0008d00a0008300ff}}{\fs72 \par }\pard \li480\ri480\sb720 {\fs36 June 4, 1994}{\fs48 \par }\pard \li480\ri480 \page \par \pard\plain \s2\li480\ri480\sa120\sl-220 \f16 {\fs16 \'a9 1992-1994 Apple Computer, Inc.\line All rights reserved.\line \par }\pard \s2\li480\ri480\sa120\sl-220 {\fs16 Apple Computer, Inc.\line 20525 Mariani Avenue\line Cupertino, CA 95014-6299\line (408) 996-1010\par }\pard \s2\li480\ri480\sa120\sl-220 {\fs16 Apple, and the Apple Logo are trademarks of Apple Computer, Inc., registered in the United States and other countries. Dylan is a trademark of Apple Computer.\par Smalltalk-80 is a trademark of ParcPlace Systems. PL/I is a trademark of International Business Machines Corp. Eiffel is a trademark of Interactive Software Engineering, Inc.\par }\pard \s2\li480\ri480\sa120\sl-220 {\fs16 \par }{\b\i\fs16 Limited Warranty on Media and Replacement}{\i\fs16 \par }\pard \s2\li480\ri480\sa120\sl-220 {\fs16 Even though Apple has reviewed this manual, Apple makes no warranty or representation , either express or implied, with respect to this manual, its quality, accuracy, merchantability, or fitness for a partic ular purpose; as a result, this manual is provided "as is," and you, the reader, are assuming the entire risk as to its quality and accuracy.\par }\pard \s2\li480\ri480\sa120\sl-220 {\fs16 In no event will Apple be liable for direct, indirect, special, incidental, or consequential damages resulting from any defect or inaccuracy in this manual, even if advised of the possibility of such damages. \par The warranty and remedies set forth above are exclusive and in lieu of all others, oral or written, express or implied. No Apple dealer, agent, or employee is authorized to make any modification, extension, or addition to this warranty.\par }\pard \s2\li480\ri480\sa120\sl-220 {\fs16 Some states do not allow the exclusion or limitation of implied warranties or liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. This warranty gives you specific legal rights, and you may also hav e other rights which vary from state to state.\par }\pard \s2\li480\ri480\sa120\sl-220 {\fs16 \par }\pard\plain \li480\ri480 \f16 \par \sect \sectd \sbknone\pgnrestart\pgnlcrm\linemod0\linex0\cols1\endnhere {\headerl \pard\plain \s2\li480\ri480\sa120 \f16 \par }{\headerr \pard\plain \s2\li480\ri480\sa120 \f16 \par }{\footerl \pard\plain \s243\li440\ri460\brdrt\brdrs \tqc\tx3600\tqr\tx8900 \i\f16 {\chpgn }\tab June 4, 1994\tab Dylan Interim Reference Manual\tab \par }{\footerr \pard\plain \s243\li440\ri460\brdrt\brdrs \tqc\tx5040\tqr\tx8900 \i\f16 Dylan Interim Reference Manual\tab June 4, 1994\tab {\chpgn }\par }\pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 About this Manual\par \pard\plain \s2\li480\ri480\sa120 \f16 When the first Dylan manual was published in 1992, it was met with an enthusiastic response. People agreed with our goals for the language, and many people suggested ways in which Dylan could better meet its goals. \par \pard \s2\li480\ri480\sa120 Since that time, an expanded group of engineers both inside and outside Apple have worked to refine the language design in response to those suggestions. The language has become simpler and more efficient. Loose ends have been tied up. The language has been given a new syntax. Throughout this process, changes to the language design have been published electronically in the form of design notes.\par With the exception of the macro system, the current round of language design is now essentially complete. A new Dylan language reference will be published early in 1995. The new book will be the definitive specification of the Dylan language. Apple is worki ng closely with other Dylan implementors to ensure that the new book will not be Apple-specific, but will apply equally to all Dylan implementations.\par We realize that many people want to read about Dylan now! For that reason, to fill the gap until the new book is published, we\rquote ve put together the {\i Dylan Interim Reference Manual} . This document is an interim user reference for the Dylan language. It combines the original Dylan book, the previously published design notes, and additional previously unpublished design decisions as of May 1994.\par \pard \s2\li480\ri480\sa120 Our goal for this interim document has been to get something useful out to you as soon as possible, not to spend time refining it, so it\rquote s important to understand the limitations of this document:\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab This is a very rough document, intended only as a temporary user reference until the new Dylan book is ready. The writing and formatting are messy in places. We hope you\rquote ll excuse us.\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab This document is not intended as a language specification. There are places where it is imprecise or inconsistent. We hope you will understand that these are shortcomings of this document, and not of the language design as a whole.\par \bullet \tab This document is not intended as a tutorial or introduction to Dylan programming. We assume that you are alrea dy somewhat familiar with object oriented programming. You will often need to devise your own examples and flip back and forth through the manual as you read.\par \pard \s2\li480\ri480\sa120 Despite these limitations, we think that this document will be useful to people who want to learn about Dylan, especially to those people who are using an early Dylan implementation. Enjoy, and let us know what you think! \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 Contents\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 About this Manual\tab i\par Contents\tab iii\par Foreword to the First Edition\tab vii\par Preface to the First Edition\tab ix\par Acknowledgments\tab xvii\par 1. Introduction\tab 1\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Manual Notation\tab 1\par Background and Goals\tab 3\par Language Overview\tab 4\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 2. Syntax\tab 7\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Lexical Notation\tab 7\par Expressions\tab 10\par Statement bodies\tab 14\par Special function call syntax\tab 15\par Syntax of Dylan Files\tab 17\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 3. Variables\tab 19\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Module Variables\tab 19\par Lexical Variables\tab 20\par Checking Types\tab 21\par Binding Multiple Values\tab 22\par Assignment\tab 24\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 4. Control Constructs\tab 27\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 True and False\tab 27\par Conditionals\tab 27\par Iteration Constructs\tab 31\par Non-local Exits\tab 35\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 5. Comparisons\tab 39\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Equality Comparisons\tab 39\par Magnitude Comparisons\tab 40\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 6. Functions\tab 43\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Function Defining Forms\tab 43\par Parameter Lists\tab 48\par Method Dispatch\tab 55\par Reflective Operations on Functions\tab 62\par The classes , , and \tab 65\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 7. Classes\tab 67\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Introduction\tab 67\par Defining New Classes\tab 69\par Slot Options\tab 71\par Instance creation\tab 78\par Reflective Operations on Types\tab 84\par Coercing and Copying Objects\tab 86\par The classes , , and \tab 87\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 8. Controlling Dynamism\tab 91\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Declaring characteristics of classes\tab 91\par Declaring sealing of generic functions\tab 92\par The seal generic form\tab 92\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 9. Collections\tab 95\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Functions for Collections\tab 96\par Functions for Sequences\tab 101\par The Instantiable Collection Classes\tab 110\par Operations on Arrays\tab 113\par Operations on Deques\tab 115\par Operations on Lists\tab 116\par Operations on Ranges\tab 118\par Operations on Stretchy Vectors\tab 119\par Operations on Strings\tab 119\par Operations on Tables\tab 121\par Operations on Vectors\tab 122\par The Iteration Protocol\tab 122\par Iteration Stability and Natural Order\tab 128\par Collection Keys \tab 128\par Mutability\tab 130\par Collection Alignment\tab 132\par Defining a New Collection Class: A Summary\tab 134\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 10. Characters and Symbols\tab 135\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Characters\tab 135\par Symbols \tab 136\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 11. Numbers \tab 137\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Automatic Type Conversion\tab 137\par Numeric Classes\tab 138\par General Arithmetic Functions\tab 138\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 12. Other Operations\tab 143\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Functional Operations\tab 143\par Function application\tab 146\par Identity function\tab 146\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 13. Conditions \tab 147\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Background\tab 147\par Overview\tab 149\par Specification\tab 152\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 14. Modules\tab 163\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Overview\tab 163\par Programs, module declarations\tab 164\par Module declarations\tab 165\par Examples\tab 168\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 15. Libraries\tab 171\par Appendix A: How to get more information\tab 175\par Appendix B: Dylan Syntax BNF\tab 177\par \pard\plain \s232\li960\ri480\tqr\tldot\tx8640 \f16 Lexical grammar\tab 177\par Phrase Grammar\tab 183\par \pard\plain \s233\li480\ri480\tqr\tldot\tx8640 \b\f16 Index\tab 189\par \pard\plain \li480\ri480 \f16 \page \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 Foreword to the First Edition\line {\plain \b\f16 by Larry Tesler\par }\pard\plain \s2\li480\ri480\sa120 \f16 In the mid-1980\rquote s, a number of researchers in Apple\rquote s Advanced Technology Group (ATG) discovered that exploration of their software ideas was increasingly constrained by languages and tools. They migrated a significant number of projects from Object Pasca l, C, and C++ to Smalltalk, Lisp, and various knowledge-engineering environments. \par \pard \s2\li480\ri480\sa120 Soon management became concerned that technologies developed in these unrelated environments woul d not be able to play together. Boldly, we proposed adoption of a single dynamic programming environment throughout the group. The goal was acknowledged, but we soon found that none of the environments we were using could meet every need. For some proje cts, Common Lisp was too big. For others, Smalltalk-80\rquote s simplicity was limiting. And of course, there were forcefully stated differences in personal preference.\par \pard \s2\li480\ri480\sa120 Humbled, we decided to search outside the company for an environment that satisfied all requirements\emdash at least technical considerations, if not matters of taste. We encountered some interesting languages, including Eiffel, Self, Beta, and OakLisp, to name just a few, but we could find no environment that met our requirements. \par \pard \s2\li480\ri480\sa120 Reluctantly, we entertained the thought of designing yet another language. We envisioned a language that would:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab combine the best aspects of Lisp and Smalltalk\par \bullet \tab provide static language users an attractive dynamic alternative\par \bullet \tab be practical on small machines\par \bullet \tab provide high dynamism during rapid prototyping and development\par \bullet \tab provide tools to achieve commercial performance in production code\par \pard\plain \s2\li480\ri480\sa120 \f16 During this exercise, we were approached by an Apple engineering group seeking an object-oriented dynamic language for a contemplated product. Instead of developing a language just for research, we agreed that ATG would strive to create a system practical for delivery of commercial applications.\par \pard \s2\li480\ri480\sa120 After some analysis, we concluded that a language that would meet all our requirements would be more like Lisp than Smalltalk, except that, like Smalltalk, it would be \ldblquote objects all the way down\rdblquote . By providing alternate syntaxes atop the extremely neutral base of Lisp, we believed we could present a familiar face not only to Lisp programmers, but also to those accustomed to other syntaxes, including Smalltalk\rquote s.\par \pard \s2\li480\ri480\sa120 We felt we could not design a good language without concurrently implementing it. But we did not have the skills in house to implement the kind of language we envisioned. Around that time we were approached by Massachusetts-based Coral Software, Inc., which was seeking to be acquired. Coral had created a popular Common Lisp implementation distinguished by its small memory footprint, very usable speed, interesting object system, and thorou gh integration into the Macintosh. A few months later, we acquired the assets of the company, hired most of the staff, and created \ldblquote ATG East\rdblquote in Cambridge. \par \pard \s2\li480\ri480\sa120 We asked the new group to accept two challenges: (1) continue to develop their Common Lisp implem entation, adding CLOS, ephemeral garbage collection, and other features; and (2) develop a new language and environment meeting the aforementioned requirements. They accepted both challenges. The first led to the very popular product known as Macintosh C ommon Lisp (MCL) 2.0. The second led to Dylan.\par \pard \s2\li480\ri480\sa120 Dylan is not yet a frozen language. Debates about proposed improvements continue. But enough of Dylan has been designed, implemented, and experienced that now is the time to take it public and benefit from the wisdom of a wider programming community. We welcome your comments.\par \pard\plain \li480\ri480 \f16 \par \tab {\i Larry Tesler\par \tab Cupertino, California\par \tab March 1992}\par \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 Preface to the First Edition\line {\plain \b\f16 by Ike Nassi\par }\pard\plain \s2\li480\ri480\sa120 \f16 Since its founding, Apple Computer has been dedicated to the cause of moving the power of computers into the hands of computer users. Our most successful product to date has been the Apple\'a8 Macintosh\'aa . Since its introduction eight years ago, Macintosh has defined the state of the art in computer ease of learning and ease of use. Macintosh, almost single-handedly, has transformed the way we use computers.\par \pard \s2\li480\ri480\sa120 It\rquote s time to transform the way we program them, as well.\par \pard \s2\li480\ri480\sa120 In 1984, before Macintosh, computer users were asked to make their work patterns conform to the requirements of the machine in front of them. All aspects of computing were presented in terms defined by the computer. The user was given little control ove r the organization of data, the order in which tasks were performed, and the manner in which work was presented. The machine presented a model which had little to do with the user\rquote s world, and the user had no choice but to conform to this model. Rather than facilitate work, the computer came between the user and the user\rquote s work. The user had to overcome the computer before getting any work done.\par \pard \s2\li480\ri480\sa120 In 1992, the situation is still much the same for programmers. There is still a large gap between software product conception and software product realization. This gap is filled with bits, bytes, arrays, machine-level debuggers, dangling poin ters, hours-long recompilations, and months-long design and redesign cycles. Programmers are still asked to present their high-level ideas of program behavior in low-level terms defined by CPU architectures of the early 1970\rquote s. Programming work flow is s till dictated by the historical limitations of compilers, linkers, and debuggers. Program design in 1992 is reminiscent of typographical design in 1982: design and execution are performed by a series of specialists, resulting in an awkward, lengthy and e xpensive design, test, and redesign process.\par \pard \s2\li480\ri480\sa120 {\i Time-to-market} is consistently rated very high in lists of factors affecting the success of high technology products. The end result of poor programming tools is either poor time-to-market or poor programs. Software companies are faced with a dilemma: they can take y ears, and do the job right, or they can cut corners and get their software into the market before their competitors. Neither solution results in a healthy software industry. Neither solution allows our products to keep up with our visions.\par \pard \s2\li480\ri480\sa120 Software development today also has a large {\i barrier to entry} . Only companies with deep financial resources can bring a full fledged application to market. The result is a loss of healthy competition and fresh ideas in the software field.\par \pard \s2\li480\ri480\sa120 Finally, our computing engines are becoming more diverse. In addition to the usual dimensions of speed, memory capacity, screen resolution, interconnectedness, power consumption, and size, the underlying operating systems and toolboxes are becoming broader in scope. Specific implementations can also become more focused, requiring a higher degree of tailorability. For example, with the introduction of mobile computing, software requirements may change as locations change. So ftware used on mobile computers needs to be able to rapidly respond to spontaneously changing conditions in a reliable way.\par \pard \s2\li480\ri480\sa120 Object oriented programming takes important steps towards fixing these problems. By letting programmers structure the text of thei r programs in terms of the problem at hand, object oriented programming narrows the gap between conception and realization. However, object oriented programming by itself is insufficient. It addresses how programs are described, but it does not address m any problems of the day-to-day activity of programming. It doesn\rquote t change programming\rquote s awkward work flow, nor does it make any guarantees about robustness, nor does it relieve the programmer of many tedious bookkeeping tasks, tasks which are better performed by a computer than by a human.\par Today\rquote s most popular object oriented languages are still {\i static languages} . In such languages, most of the information about objects is discarded during compilation, so programs cannot be modified without recompilation, and debugging is more likely to occur at machine level than the level at which the program was designed. In addition, these languages encourage mixing objects with non-object oriented bits and bytes. Even objects can be treated as undifferentiated bits, leading to the possibility of protocol violations and obscure errors. Finally, there is no attempt to put the process of programming into the hands of the programmer. Generally speaking, large programs must still be written in their entirety before they can be compiled and tested.\par \pard \s2\li480\ri480\sa120 Static object oriented languages provide only half of a solution. The other half is provided by {\i dynamism}, yielding what Apple calls {\i object oriented dynamic languages}, or {\i OODLs} . In addition to supporting the object oriented methodology, OODLs must support a number of features which guarantee that programming takes place in terms defined by the programmer, rather than in the terms of the hardware. \par \pard \s2\li480\ri480\sa120 OODLs must support rapid creation, delivery, and subsequent modification of ambitious, reliable, and efficient software. Among the specific requirements an ideal OODL should satisfy are the following:\par \pard \s2\li480\ri480\sa120 {\b Automatic Memory Management\par }\pard \s2\li480\ri480\sa120 Memory management bugs are among the most common and difficult errors in static programming languages. Bugs involving dangling pointers and twice-freed objects are notoriously hard to track down.\par \pard \s2\li480\ri480\sa120 The language run-time, and not the programmer, should be responsible for allocating storage for objects and reclaiming the storage of objects which are no longer used. There should be no explicit procedure calls for allocating or deallocating memory, or fo r deallocating objects. \par In a well engineered implementation, automatic memory management should be robust and scalable. It should not create memory fragmentation, or fail in the presence of large (possibly virtual) address spaces. It should not cause seemingly arbitrary and unpredictable delays for end users.\par \pard \s2\li480\ri480\sa120 In a true OODL, there should be no machine-level pointers, only objects. Once freed from dealing with pointers, the programmer can begin to think of objects at a higher level and the primitives become comparably richer. For example, a programmer working with collections of objects does not need to worry about memory leaks as collections expand and contract. The programmer can concentrate on the task at hand, rather than on the bookkeeping details.\par \pard \s2\li480\ri480\sa120 Many large programming projects begin with the design of a memory management subsystem. There is no reason that this task should not be performed once, and the corresponding implementation of that design embodied in the language run-time, and thereby made available to all programmers.\par \pard \s2\li480\ri480\sa120 {\b Dynamic Linking/ Incremental Development\par }\pard \s2\li480\ri480\sa120 Programmers should have the ability to build up their programs piece by piece, integrating preexisting pieces when possible and where available. The transition between rapid prototyping and mainstream development should be continuous rather than discrete. It should not require changing languages or tools.\par \pard \s2\li480\ri480\sa120 This requirement affects the programming process in at least four ways:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab During the initial construction of a program, classes and functions can be compiled and tested individually. This gives programmers the freedom to use a bottom-up programming style, if they so choose, obviating the nee d for the construction of a complex superstructure for initial testing.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab During debugging, individual functions and classes can be redefined without resorting to a full recompilation of the program and perhaps without even halting the execution of the program. \par \bullet \tab Programs can be delivered in components, which can be linked together on either the development machine or the end-user machine, using built-in language features.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab Program patches (i.e., field upgrades) can be distributed to end-users using buil t-in language features. Applying the patch should be a very low overhead operation. There should be virtually no performance penalty for executing patched code. Because you don\rquote t need source code for the original application in order to apply the patch, traditional intellectual property issues arising from propagating source code simply need not arise.\par \pard\plain \s2\li480\ri480\sa120 \f16 {\b Self Identifying Objects / Introspection\par }\pard \s2\li480\ri480\sa120 Operations should be checked for type safety before they are performed. If possible, this check should be perf ormed at compile-time, otherwise it should be performed at run-time. This feature guarantees that type errors are noticed as soon as they occur, before they can propagate and cause system corruption. Because the integrity of the object model is maintaine d, error reporting can occur in terms of programmer objects and end-user objects, rather than in machine-level terms. In many cases, complete error recovery is possible.\par \pard \s2\li480\ri480\sa120 The language should contain features for introspection. This means that the language run-time should have sufficient power to answer questions about itself and the objects it manages. For example, it should be possible at execution time to analyze the structure of an object, find the subclasses of a class, etc.\par \pard \s2\li480\ri480\sa120 To facilitate type-safety and introspection, objects are self-identifying in memory. Unless all uses of an object can be analyzed at compile-time, the run-time memory for the object should contain enough information to identify its class and value.\par \pard \s2\li480\ri480\sa120 {\b Object Oriented Programming Environment\par }\pard \s2\li480\ri480\sa120 The programming environment should present all debugging information at an object oriented level. Errors should be described in high-level terms similar to those used by the programmer in constructing the program. Inspection facilities should show a prog ram as a collection of objects, not as a mass of undifferentiated bits. There should be tools for performance analysis and monitoring of single objects as well as collections of objects.\par \pard \s2\li480\ri480\sa120 There should be rich libraries of components, and the means to navigate within and between them and to organize and administer them.\par \pard \s2\li480\ri480\sa120 There should be a well thought out distinction between development environment and execution environment, and where they are different, the development environment should manage the communication between them in as transparent a manner as possible. This f eature is missing from current OODLs, but it is essential for the delivery of OODL-based applications to end-users.\par \pard \s2\li480\ri480\sa120 An important aspect of these features is that they are mutually supporting, forming an {\i organic whole. } The simplest implementation of each depends on the existence of the others. For example, automatic memory management relies on the ability to walk memory and identify objects. Another example is that rapid prototyping requires rapid modification of the program, and so incremental dynamic linking becomes essential. Incremental dynamic relinking utilizes automatic reclamation of storage occupied by the functions, methods, and data being replaced.\par \pard \s2\li480\ri480\sa120 Many people in commercia l industry and in the research community have recognized the problems with static languages, and some have started to build products that provide some of the features of OODLs. For example, interactive programming environments for static languages are beg inning to appear. We applaud this development. However, we believe that starting with a static language requires too many compromises. If each OODL feature were to be added in isolation, the mutually supporting characteristics would be lost, creating re dundancy, conflicts, and inefficiency. When instead these features are built together into the core of a programming system, they provide a simple and secure foundation for growth. \par \pard \s2\li480\ri480\sa120 The common criticism of OODLs is that we cannot afford them. Most programmers view OODLs as slow and as memory hogs. The common wisdom is that OODLs do not make good use of machine resources. Fortunately, this view is out of date. The combination of im proved OODL implementation technology and increasingly powerful hardware make OODLs eminently practical. Every year or two our hardware gets twice as fast and has twice as much memory. Would anyone say that the quality of our software has increased at the same rate? Programming must be made easier, or the fastest hardware i n the world will only give us incremental software improvements. By investing a few cycles we can enable a new generation of applications.\par \pard \s2\li480\ri480\sa120 When Macintosh was first released, many people thought that windows, menus, and a bit mapped display were a waste of machine resources. We see in retrospect that this was not true. What good is the power of a computer, if it can\rquote t be accessed by a user?\par This book describes Dylan\'aa , a new object oriented dynamic language designed by Apple. Dylan is our attempt at a language which is simple, yet powerful, one which keeps programming at a high level but which can be compiled efficiently and has a relatively modest memory footprint. \par \pard \s2\li480\ri480\sa120 Apple already has one OODL product: Macintosh Common Lisp. Dylan is intended to complement Common Lisp, not to replace it. Common Lisp is a rich environment defined by a standard and available in compatible implementations on a broad range of platforms. Dylan is lean and stripped down to a minimum feature set. At present Dylan is not availab le on any platform (outside Apple), but is intended to run on a wide variety of machines, including very small machines that don\rquote t have the horsepower to support a modern Common Lisp. Common Lisp is aimed primarily at the Lisp community, while Dylan is ac cessible to application developers unfamiliar with Lisp. Common Lisp is oriented more towards exploratory programming with delivery capability, while Dylan is oriented more towards delivery with exploratory capability. \par \pard \s2\li480\ri480\sa120 In our research and development labs, Apple has its own implementations of Dylan, which are being produced hand in glove with the language definition as a design assurance measure. We would like to see others create additional implementations.{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }Since this was written, such implementations are well underway on a variety of platforms.}} We would be particularly interested in worki ng with a group to create a reference implementation optimized for portability rather than performance, so that anyone could try out Dylan no matter what brand of computer they use. Because Dylan is a trademark of Apple Computer, anyone implementing the l anguage must obtain permission to use the name. However, it is our intention that permission will be granted to anyone with a conforming implementation.\par Apple Eastern Research and Technology{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }Now Apple Cambridge Engineering.}} will be the focal point for discussion of the Dylan language, i ts implementations, and its future evolution. Current and prospective users or implementors of Dylan, as well as programming language researchers who are interested in object oriented dynamic languages, are invited to comment on the design of the language and suggest improvements that are consistent with the goals noted above. We will also continue our past policy of driving the evolution of the language from the needs and comments of our users, who are system and application developers whose previous exper ience is largely with conventional languages. We hope to integrate all inputs to make Dylan the best language we can and use it to bring the benefits of OODLs to as many programmers as we can possibly reach.\par \pard\plain \li480\ri480 \f16 \par {\i \tab Ike Nassi\par \tab Cambridge, Massachusetts\par \tab March 1992}\par \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 \page Acknowledgments\par \pard\plain \s2\li480\ri480\sa120 \f16 Designing Dylan has been a work of many hands.\par \pard \s2\li480\ri480\sa120 The primary contributors to the language design were Kim Barrett, Glenn S. Burke, Robert Cassels, Bill Chiles, Jerome T. Coonen, Scott Fahlman, Paul Gleichauf, James Grandy, Paul Haahr, Joh n Hotchkiss, Jeremy A. Jones, Michael Kahl, William Lott, Rob MacLachlan,David A. Moon, Ike Nassi, Jeffrey Piazza, Kent Pitman, Keith Playford, Andrew Shalit, Jonathan Sobel, Walter R. Smith, Bill St. Clair, Orca Starbuck, Oliver Steele, Robert Stockton, S teve Strassmann, Larry Tesler, Derek White, and Gail Zacharias.\par \pard \s2\li480\ri480\sa120 Additional design work and oodles of helpful comments were provided by Jim Allard, Peter Alley, Jonathan Bachrach, Richard Barber, David Betz, John Barr, Alan Bawden, Stoney Ballard, Ernie Bee rnink, Brent Benson, Eric Benson, Rasha Bozinovic, Bill Campbell, Steve Capps, Yu-Ying Chow, Doug Cutting, Ken Dickey, Richard Duncan, Mikel Evins, Marc Feeley, Gregg Foster, Tom Gordon, Jed Harris, Alice K. Hartley, Alan Kay, Larry Kenyon, Mike Lockwood, Matthew MacLaurin, Robin Mair, Neil Mayle, Tim McInerney, Scott McKay, Jim Meehan, John Meier, Jim Miller, Richard Mlynarik, Robert Muller, Carl Nelson, Julian Padgett, Paige Parsons, Ed Petrus, Peter Potrebic, Jonathan Rees, Kalman Reti, David Rosenfeld, Carl Schwarcz, David Singer, Andy Sizer, David C. Smith, Andy Stadler, Joshua Susser, Michael Tibbott, Tom Vrhel, John Wainwright, Bob Welland, Paul Wilson, and Dan Zigmond.\par \pard \s2\li480\ri480\sa120 Moral and logistical support were provided by Donna Auguste, Chrissy Boggs, Mickey Dennison, Gina Field, Rick Fleischman, James Joaquin, Rick LeFaivre, Ross Knights, Becky Mulhearn, David Nagel, Wendy Phillips, Mark Preece, Mary Reagan, Shane Robison, and Susan M. Whittemore.\par \pard \s2\li480\ri480\sa120 The Dylan project is directed by Ike Nassi and Carl Schwarcz.\par \pard \s2\li480\ri480\sa120 The first edition of the Dylan manual was written by Andrew Shalit with contributions from Jeffrey Piazza, David Moon, and Steve Strassmann. It was extensively revised by Orca Starbuck, with editorial help from Kim Barrett, David Moon, and Steve Strassman n to incorporate recent language changes.\par \pard \s2\li480\ri480\sa120 The first edition of the manual was designed by Scott Kim and Steve Strassmann. The original cover art was designed by Scott Kim.\par \pard \s2\li480\ri480\sa120 The Dylan project is funded by Apple Computer\rquote s AppleSoft Division.\par \pard\plain \li480\ri480 \f16 \par \pard \li480\ri480 \page \sect \sectd \sbknone\pgnrestart\linemod0\linex0\cols1\endnhere {\headerl \pard\plain \s2\li480\ri480\sa120 \f16 \par }{\headerr \pard\plain \s2\li480\ri480\sa120 \f16 \par }{\footerl \pard\plain \s243\li440\ri460\brdrt\brdrs \tqc\tx3600\tqr\tx8900 \i\f16 {\chpgn }\tab June 4, 1994\tab Dylan Interim Reference Manual\tab \par }{\footerr \pard\plain \s243\li440\ri460\brdrt\brdrs \tqc\tx3600\tqc\tx5040\tqr\tx8900 \i\f16 Dylan Interim Reference Manual\tab June 4, 1994\tab {\chpgn }{\plain \f16 \par }}\pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 1. Introduction\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Manual Notation\par \pard\plain \s2\li480\ri480\sa120 \f16 This manual uses a small number of typographic conventions:\par Body text appears in Roman.\par First uses of terms appear in {\b Bold}.\par \pard \s2\li480\ri480\sa120 Text which appears as it would be entered into the computer appears in {\f22 Courier}.\par In the body of the manual, the following notation is used to describe syntax forms:\par \pard\plain \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \f16 \{...\}\tab Curly braces indicate a group of items.\par \pard\plain \s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 \{\'c9\}{\fs20\up6 *}\tab Curly braces followed by an asterisk indicate that the contents can appear zero or more times.\par \{\'c9\}{\fs20\up6 +}\tab Curly braces followed by a plus sign indicate that the contents can appear one or more times.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 [\'c9]\tab Square brackets indicate that the contents are optional.\par \pard\plain \s16\fi-2160\li2640\ri480\sa240\tx2640 \f16 \'c9|\'c9\tab Items separated by a vertical bar are mutually exclusive. One or the other may appear.\par \pard\plain \s2\li480\ri480\sa120 \f16 The BNF grammar at the end of the manual uses its own notation which is different from the above.\par \pard \s2\li480\ri480\sa120 Formal parameters (i.e., place holders for the actual text you would enter) appear in {\i Italic}. The names of parameters are often descriptive of the type of value acceptable as a value of the parameter. They will often m atch the names of classes, indicating a general instance of the class. For example, {\i number} indicates a general instance of the class {\f22 }, and {\i string} indicates a general instance of the class {\f22 }.\par \pard \s2\li480\ri480\sa120 Interactions between a user and a Dylan interpreter are shown in a mixture of {\f22 Courier}{\b\f22 }and {\i\f22 Courier Italic}. {\f22 Courier }shows the text entered by the user, and {\i\f22 Courier Italic} shows the text printed by the interpreter. The question mark used in these sections is the interpreter\rquote s prompt.{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }The term {\i interpreter} is used, even though most implementations of Dylan are expected to be compiled. In most cases, an interpreter will be implemented by compiling Dylan expressions and immediately executing the compiled code.}}\par \pard \s2\li480\ri480\sa120 The error messages in the manual have been edited for brevity. The details of interactions with Dylan (prompt text, error message texts, etc.) will differ among implementations.\par \pard \s2\li480\ri480\sa120 The functions {\f22 format} and {\f22 print} are used in some examples but are not part of Dylan.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 \page Background and Goals\par \pard\plain \s2\li480\ri480\sa120 \f16 Dylan is a general-purpose high-level programming language, designed for use both in application and systems programming. Dylan includes garbage collection, run-time type checking, selective dynamism, error recovery, and a module system. These f eatures simplify programming and support attractive debugging and development tools.\par \pard \s2\li480\ri480\sa120 The motivation for Dylan is that programs and large software systems have become too complex for traditional static programming languages. To create a new generation of software\emdash and to ensure that this software is maintainable and extensible\emdash requires a new, friendlier set of programming tools. The core of these tools is a simple and expressive language, one that is efficient but which protects the programmer from crashes and machine-level debugging. All programming should take place at an object-oriented level. Improved implementation techniques and increasingly powerful computer hardware make it possible to use fully dynamic object-oriented languages for a wide range of programming tasks.\par \pard \s2\li480\ri480\sa120 Dylan is built from the ground up with a thoroughly integrated object model. Like some object-oriented extensions to Lisp, Dylan implements polymorphism through generic functions and class dispatch, rather than through a Smalltalk-styl e message-passing mechanism.{\fs20\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }Notable Lisp systems that use generic functions are CLOS (Common Lisp Object System), Oak Lisp, and EuLisp.}} Generic functions provide a very convenient model for a broad range of programming tasks.\par \pard \s2\li480\ri480\sa120 The target audience of Dylan is application developers now using languages such as C, C++, and Pascal who are ready to move up to Object Oriented Dynamic Languages. Dylan is not intended primarily for the Lisp or Smalltalk community, thus compatibility wi th Smalltalk or with Lisp dialects such as Scheme and Common Lisp is not a primary goal. Dylan has been rethought from the ground up, on a fully object-oriented foundation. A primary goal was to make the language as simple as possible, but no simpler. We have tried to avoid multiple ways to do the same thing, to omit features that are difficult for the average application developer to understand and use effectively, to leave out anything that we do not know how to implement efficiently in both space and time, and to provide a clear separation of the language executed at run-time from the development tools. At the same time, we\rquote ve moved complicated low-level bookkeeping underneath the language and taken it out of the hands of the application programmers, to make them more productive. The overriding goal of Dylan is rapid development and delivery of applications and application component s on very small computers.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Language Overview\par \pard\plain \s2\li480\ri480\sa120 \f16 Dylan is built around two central concepts: {\b objects} and {\b functions}.\par \pard \s2\li480\ri480\sa120 {\b Objects} are the data that exist in Dylan programs. Objects are mapped into a {\b class heterarchy}.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }A heterarchy\emdash also called a directed acyclic graph (DAG)\emdash is like a hierarchy, except that nodes can have multiple parents. Dylan classes are in a heterarchy because Dylan supports multiple inheritance.}} The class heterarchy describes the inheritanc e relationships among {\b classes}. The class {\f22 } is the root of the heterarchy. Every class inherits from its {\b direct superclasses} (except for {\f22 } which has no superclasses). Classes may also have {\b subclasses} , which inherit from them, either directly or indirectly. The {\b superclasses} of a class are the class itself, its direct superclasses, their direct superclasses, and so on back to the class {\f22 }.\par \pard \s2\li480\ri480\sa120 Every object in the Dylan world is a {\b direct} {\b instance} of exactly one class. This class is referred to as \ldblquote the class of\rdblquote the instance. For each object {\i O} that is a direct instance of class {\i C}, the object {\i O }is also an {\b indirect instance} of all the superclasses of {\i C} (except {\i C} itself). (It follows that every object in Dylan is an indirect instance of {\f22 }.) The term {\b general instance} means \ldblquote either a direct or indirect instance.\rdblquote \par \pard \s2\li480\ri480\sa120 Dylan defines four categories of classes:\par \pard\plain \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \f16 {\b Abstract Class}\tab A class that is not intended to have direct instances. Its general instances obey an interface implemented by subclasses. The opposite of an abstract class is a {\b concrete class}.\par \pard\plain \s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 {\b Instantiable Class}\tab A class that can be used as the first argument to {\f22 make}. The opposite of an instantiable class is an {\b uninstantiable class} . Note that an abstract class may be instantiable.\par \pard\plain \s16\fi-2160\li2640\ri480\sa240\tx2640 \f16 {\b Sealed Class}\tab A class that cannot be subclassed, other than those subclasses explicitly defined in the same library. The opposite of a sealed class is an {\b open class}.\par \pard \s16\fi-2160\li2640\ri480\sa240\tx2640 {\b Primary Class}\tab A class that may be used only as the primary superclass in multiple inheritance. It is illegal for a class to have two primary superclasses unless one is a subclass of the other. The opposite of a primary class is a {\b free class}.\par \pard\plain \s2\li480\ri480\sa120 \f16 {\b Functions} are a class of objects used for performing actions in Dylan. Functions correspond to the functions, procedures, methods, and messages of other languages. Dylan supports two classes of functions: methods and generic functions.\par \pard \s2\li480\ri480\sa120 A {\b method} is a basic callable unit of code. It contains a typed argument list and a code body. The types in the argument list are called the {\b specializers} of the method. A method can only be called with arguments that match the specializers of the argument list. (In the most common case, the specializer is a class, and the corresponding argument must be a general instance of the class.) When the speciali zers of a method match a set of arguments, the method is said to be {\b applicable} to the arguments. If a method is called with inappropriate arguments, an error is signaled.\par \pard \s2\li480\ri480\sa120 A {\b generic function} contains zero or more methods. When a generic function is called, the arguments are compared to the specializers of all the methods in the generic function. The method with the most appropriate specializers is run. In this way, a generic function chooses a method based on the classes and identities of its arguments. This is the basic technique for object-oriented dispatch in Dylan.\par \pard \s2\li480\ri480\sa120 In contrast to methods in other object-oriented languages, Dylan methods can also be called directly. They do not need to be added to generic functions. Used this way, methods play the role of blocks in Smalltalk, closures in Lisp, and functions in C.\par \pard \s2\li480\ri480\sa120 Classes and functions are themselves first-class objects, which can be manipulated by programs.\par \pard \s2\li480\ri480\sa120 \par \pard \s2\li480\ri480\sa120 \page \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 2. Syntax\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Lexical Notation\par \pard\plain \s2\li480\ri480\sa120 \f16 Here are the lexical conventions used in Dylan programs.\par \pard\plain \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \f16 \tab White space (including spaces, tabs, newlines, and newpage characters) serves as a delimiter. The amount of contiguous white space is not significant. Thus, any number of contiguous white space characters can be used for formatting.{\f22 \par }\pard\plain \s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 {\b\f22 foo}\tab Variable names are a series of alphanumeric characters, and characters from the set {\b\f22 ! & * < = > | ^ $ % @ _ - + ~ ? /} , that do not begin with one of the special characters {\b\f22 - + ~ ? /}. If a variable name begins with a numeric character, the name must contain two alphabetic characters in a row. Variable names are not case-sensitive.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 =}\tab Infix operators are the following one- or two-character sequences: {\b\f22 + - * / - = == < > <= >= ~= ~ & | ^}. \par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b \\}{\b\f22 =}\tab An infix operator variable name is the corresponding infix operator, prefixed with the infix operator escape character {\b\f22 \\} . This allows an infix operator to be used wherever a variable name is allowed (for example, as the variable name in a {\b\f22 define method} or as a function argument).\par \pard\plain \s4\li480\ri480\tx2640 \f16 {\b\f22 123}\tab The syntax of numbers is described in the numerics\par {\b\f22 1.5}\tab section of this manual.{\f22 \par }\pard \s4\li480\ri480\tx2640 {\b\f22 -4.0\par +57\par }\pard\plain \s12\li480\ri480\sa240\tx2640 \f16 {\b\f22 #x1f4e\par }\pard\plain \s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 {\b\f22 "abc"}\tab Literal strings are delimited by double-quote marks. The characters between the quotes are the elements of the string. Within the string, white space is significant (it contributes to the string). Double quotes can be included in strings by preceding them with a backslash character. Within a string, backslash ({\b\f22 \\} ) has the general effect of quoting the following character. To include a backslash in a string, the backslash must be preceded by another backslash.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 #"Hello"}\tab Symbols are interned strings. They are preceded by a .i.sharp-sign. See the section on symbols and keywords for more details.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 Hello:}\tab An alternative syntax for symbols is \ldblquote keyword syntax.\rdblquote See the section on symbols and keywords for more details.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 #(1, 2, 3)}\tab Literal lists are delimited by open and close parentheses, and preceded by a sharp-sign. The items between the parentheses are the elements of the list. They are separated with commas. \par {\b\f22 #[1, 2, 3]}\tab Literal vectors (one-dimensional arrays) are delimited with square brackets, and preceded by a sharp-sign. The items between the square brackets are the elements of the vector. They are separated with commas.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 'M'}\tab Character constants are represented by delimiting the character with single quotes.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 //}\tab A pair of slashes indicates the start of a comment. The comment continues until the end of the line. At the start of a new line, regular parsing begins again.\par {\b\f22 /* ... */}\tab Slash-star pairs delimit extended comments. These comments can run over multiple lines. Extended comments can be nested.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 #t}\tab The hash-sign t syntax is used to indicate the canonical true value.{\f22 \par }{\b\f22 #f}{\f22 \tab }The hash-sign f syntax is used to indicate the canonical false value.\par \pard\plain \s4\li480\ri480\tx2640 \f16 {\b\f22 #key}\tab {\f22 #key}, {\f22 #rest}, {\f22 #next} and {\f22 #all-keys} are used to indicate \line {\b\f22 #rest}{\f22 \tab }special tokens in parameter lists.{\f22 \par }\pard \s4\li480\ri480\tx2640 {\b\f22 #next\par }\pard\plain \s12\li480\ri480\sa240\tx2640 \f16 {\b\f22 #all-keys}\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Naming Conventions\par \pard\plain \s2\li480\ri480\sa120 \f16 Several conventions for naming variables help programmers identify the purposes of variables. The names of variables do not affect the semantics of a program, but are simply used to improve readability.\par \pard \s2\li480\ri480\sa120\keepn Dylan uses the following naming conventions:\par Variables used to hold classes begin and end with angle brackets.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 \tab \tab \par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 \tab \tab \par \pard\plain \s2\li480\ri480\sa120\keepn \f16 Module variables that are designed to have their values change in the course of a program (i.e., variables that are not read-only) begin and end with asterisks. \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 *parse-level*\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 *incremental-search-string*\par *machine-state*\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 *window-count*\par \pard\plain \s2\li480\ri480\sa120\keepn \f16 Program constants (read-only module variables) begin with a dollar sign.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 $pi\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 $end-of-file\par \pard\plain \s2\li480\ri480\sa120\keepn \f16 The names of most predicate functions end with a question mark. Predicates are functions which return a true or false value.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }Three notable exceptions to the terminal question mark convention are {\f22 <}, {\f22 >}, and =.}}\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 subclass?\tab even?\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 instance?\tab \par \pard\plain \s2\li480\ri480\sa120\keepn \f16 The names of most operations that destructively modify data structures end with an exclamation point.{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } Notable exceptions to the terminal exclamation point convention are := and all the setter variable names.}} These names sometimes contrast with versions that allocate new memory for the result.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 reverse!\tab {\i\f16 (non-destructive version is }reverse{\i\f16 )}\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 sort!\tab {\i\f16 (non-destructive version is }sort{\i\f16 )}\par \pard\plain \s2\li480\ri480\sa120 \f16 Operations that retrieve a value from a location are called {\b getters}. Operations that store into a location are called {\b setters} . In general, getters and setters come in pairs. Setter variable names are derived by appending \line \ldblquote {\f22 -setter}\rdblquote to the corresponding getter variable name. Actually, this is not simply a conventi on. The rule is exploited to generate setter names from getter names automatically, and it is used to expand calls to {\f22 :=}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx3420\tx4800\tx6720 \f22\fs20 {\i\f16 Getter \tab Setter }\par \pard\plain \s6\li960\ri480\keepn\tx3420\tx4800\tx6720 \f22\fs20 window-position\tab window-position-setter\par table-size\tab table-size-setter\par \pard\plain \s8\li960\ri480\sa320\tx3420\tx4800\tx6720 \f22\fs20 window-color\tab window-color-setter\par \pard\plain \s2\li480\ri480\sa120 \f16 These two expressions are equivalent; they both set the color of \line {\f22 my-window} to {\f22 green}:\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 window-color-setter (green, my-window)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 my-window.window-color := green\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Expressions\par \pard\plain \s2\li480\ri480\sa120\keep\keepn \f16 Dylan programs are composed of {\b expressions}. When an expression is {\b evaluated}, it {\b returns} zero or more v alues. Evaluating an expression may have side effects and may involve evaluating sub-expressions. \par \pard \s2\li480\ri480\sa120\keep\keepn An {\b outer expression} is an expression that is not a sub-expression of any expression. A {\b top-level expression} is either an outer expression or a direct sub-expression of a {\f22 begin} syntax form that itself is a top-level expression. (Such a {\f22 begin} cannot have local declarations in it, although the grammar allows it.) Definitions (see Syntax Forms, below) are restricted to be top-level expressions. Other expressi ons may appear either as top-level expressions, or as sub-expressions of other expressions.\par \pard \s2\li480\ri480\sa120\keep There are four kinds of expressions: literal constants, variable references, function calls, and syntax forms.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }The term \ldblquote syntax form\rdblquote describes both special forms and macros. They are equivalent to macros in other languages.}}\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Literal Constants\par \pard\plain \li480\ri480 \f16 A {\b literal constant }is an object that is specified explicitly in program text.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }"abc"\par \pard\plain \s6\li960\ri480\tx2880\tx4800\tx6720 \f22\fs20 {\i "abc"\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i ?} 123\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i 123\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i ?} foo:\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i foo:\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i ?} 'M'\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i 'M'\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i ?} #t\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #t\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i ?} #f\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #f\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i ?} #(1, 2, 3)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i #(1, 2, 3)\par }\pard\plain \li480\ri480 \f16 Literal constants are immutable. The keys and elements of collections that are literal constants are immutable. Attempting t o modify an immutable object has undefined consequences. Immutable objects may share structure. Literal constants that are = may or may not be ==.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Variable References\par \pard\plain \s2\li480\ri480\sa120 \f16 When an expression is a variable name, the expression indicates a variable reference. The variable name evaluates to the value of the variable.\par \pard \s2\li480\ri480\sa120 Dylan supports two kinds of variables: lexical variables and module variables. Lexical variables are created locally. They roughly correspond to local variables in other languages. Module varia bles are created by using a definition such as {\f22 define variable} or {\f22 define method}.{\f22 }They roughly correspond to global variables in other languages.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i \{the class \}\par ?} concatenate\par {\i \{the generic function concatenate\}\par ?} define variable my-variable = 25;\par {\i my-variable\par ?} my-variable\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i 25\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i ?} begin\par let x = 50;\par x + x;\par end;\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i 100\par \par }\pard\plain \s2\li480\ri480\sa120 \f16 Note that Dylan classes and functions are first-class objects and are named by variables, like other objects.\par See the chapter on Variables for detailed information about lexical and module variables.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Function Calls\par \pard\plain \s2\li480\ri480\sa120\keepn \f16 Function calls generally have the syntax\par \pard \s2\li480\ri480\sa120 {\i expression}{\f22 (}{\i arg}{\i\fs18\dn4 1}, {\i arg}{\i\fs18\dn4 2}, \'c9 {\i arg}{\i\fs18\dn4 n}{\f22 )}\par \pard \s2\li480\ri480\sa120 {\i expression} must evaluate to a function. This is the function to be called. The arguments to the function are the values of the elements in the list.\par \pard \s2\li480\ri480\sa120 The arguments to a function are evaluated in left-to-right order. The function is evaluated before the arguments.{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } Except in the special slot reference syntax {\f22 argument.function}, where {\f22 argument} is evaluated first, followed by {\f22 function}.}} Once the function and all the arguments are evaluated, the function is called with the arguments.\par \pard \s2\li480\ri480\sa120 A function call evaluates to the values returned by the function.\par \pard \s2\li480\ri480\sa120 {\i expression} is commonly a variable name. In the following example, the function being called is the value of the variable {\f22 factorial}:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 factorial(x, y)\par \par \pard\plain \s2\li480\ri480\sa120 \f16 However, the expression in the function position does not have to be a variable reference; it can be any expression that evaluates to a function. In this way, Dylan is like C and Scheme, and unlike Common Lisp. The following example has a complex express ion in the "function position." The complex expression creates and returns a function which adds one to its argument. This function is then applied to 99.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} (method(x) x + 1 end) (99)\par 100\par \pard\plain \s35\li360\keep\keepn\tx3240 \f22\fs20 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Syntax Forms\par \pard\plain \s2\li480\ri480\sa120 \f16 A {\b syntax form} is a form which has its own rule for evaluation. Syntax forms are introduced by {\b syntax operators}. Some examples of syntax operators are {\f22 define variable}, {\f22 for}, {\f22 method} , and {\f22 :=}.\par \pard \s2\li480\ri480\sa120 Syntax forms may have different evaluation rules than function calls. In a function call, all the subexpressions are evaluated and passed to the function as arguments. In contrast, a syntax form can examine its subexpressions literally and can choose to evaluate some and give special meaning to others. The special evaluation rules for each syntax form are listed along with that form\rquote s definition.\par \pard \s2\li480\ri480\sa120 Generally, the syntax operator is the first word or words appearing in the syntax form. For example, the {\f22 define variable} syntax form begins with the words {\f22 define variable}, and the {\f22 method} syntax form begins with the word {\f22 method}.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define variable foo = 3;\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 method (a :: , b :: )\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 list (a - b, a + b);\par end method;\par // Creates an anonymous method, which expects 2 \par // numeric arguments.\par {\b \par }\pard\plain \s2\li480\ri480\sa120 \f16 However, the syntax operator does not have to be the first word in the form. For example, the assignment operator, :=, is an infix operator that is also a syntax form with special evaluation rules.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 my-variable := 12;\par // Sets the value to 12\par {\b \par }\pard\plain \s2\li480\ri480\sa120 \f16 There are three kinds of syntax forms:\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab Most syntax forms are {\b macros} (introduced by {\b macro operators}). Some macros (like the {\f22 for} iteration construct) are part of the core Dylan language. Others are created by individual implementations or by programmers. Macros can be thought of as expanding into other, equivalent, expressions.\par \pard \s2\fi-360\li840\ri480\sa120 {\b \bullet \tab Special forms} (introduced by {\b special form operators}) are basic, built-in syntax forms that cannot be reduced to other expressions. Examples are {\f22 :=} and {\f22 method}.\par \pard \s2\fi-360\li840\ri480\sa120 {\b \bullet \tab Definitions} (introduced by {\b definition} {\b operators}) are declarative parts of a program. Definitions are restricted to be top level expressions (see the next section). They do not return values. Examples are {\f22 define method} and {\f22 define variable}.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Statement bodies\par \pard\plain \s2\li480\ri480\sa120\keepn \f16 Many kinds of expressions include {\b implicit bodies} , which may contain one or more other expressions, separated by semicolons. When an implicit body is evaluated, the expressions in the implicit body are evaluated in order (left to right). The value of the implicit body is the value of the last expressio n.\par \pard \s2\li480\ri480\sa120\keepn The simplest expression containing an implicit body is {\f22 begin}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keep\keepn\tx480\tx720\tqr\tx9360 \f16 {\b\f22 begin}\tab [Special Form]\line {\i body}\line {\b\f22 end}\line {\f23 \'de}{\i values}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The {\i body } consists of any number of expressions separated by semicolons. {\f22 begin} executes the expressions in the {\i body} sequentially. The values of the last expression are returned. If there are no expressions in the {\i body}, {\f22 #f} is returned.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 begin\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 close(airlock.outer-door);\tab // this\par pressurize(airlock);\tab // is an\par open(airlock.inner-door);\tab // implicit body\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 end;\par \pard\plain \s2\li480\ri480\sa120 \f16 Programs only need to use {\f22 begin} explicitly in order to limit the scope of a lexical variable, or in situations where a single expression is expected, such as an argument to a function call. Many other expressions contain implicit bodies. For example, the body of a method definition is an implicit body, and the {\f22 if} statement has an implicit body in each sub-part.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 if (moon-phase == #"full")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 wolf-form(werewolf);\tab // this is an\par howl-at-moon(werewolf);\tab // implicit body\par else\par human-form(werewolf);\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 end if;\par \pard\plain \s2\li480\ri480\sa120 \f16 Some statements use the word {\f22 end} to mark the end of an implicit body. Other statements use other markers, such as the {\f22 else} that marks the end of the first implicit body in an {\f22 if} statement. The syntax description for each statement defines where implicit bodies may appear, and how the boundary is marked.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Semicolons\par \pard\plain \li480\ri480\keepn \f16 Multiple expressions, such as top-level expressions appearing in source files, are separated by a semicolon \ldblquote {\f22 ;}\rdblquote . Semicolons are also required to separate all but the last expression in implicit bodies. The semicolon after the last expression is optional.\par \pard \li480\ri480\keepn \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Special function call syntax\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Infix Operators\par \pard\plain \s2\li480\ri480\sa120\keepn \f16 Certain predefined operators are called using standard algebraic syntax. Operators and their arguments must be separated by whitespace or parentheses. All binary operators are left-associative, except for the assignment operator {\f22 :=}, which is right-associative. \par \pard \s2\li480\ri480\sa120\keepn These are listed in descending order of precedence. Operators within a group share the same precedence. \par \pard\plain \s36\li360\keep\keepn\tx1800\tx3240\tx4680 \f16\fs20 {\i \par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i unary}\tab -\tab negative\par {\i unary}\tab ~\tab not (boolean)\par \par {\i binary}\tab ^\tab exponentiation\par \par {\i binary}\tab *\tab multiplication\par {\i binary}\tab /\tab division\par \par {\i binary}\tab +\tab addition\par {\i binary}\tab -\tab subtraction\par \par {\i binary}\tab =\tab equality\par {\i binary}\tab ==\tab identity\par {\i binary}\tab ~=\tab not equals\par {\i binary}\tab <\tab less than\par {\i binary}\tab >\tab greater than\par {\i binary}\tab <=\tab less than or equals\par {\i binary}\tab >=\tab greater than or equals\par \par {\i binary}\tab &\tab and\par {\i binary}\tab |\tab or\par \par {\i binary}\tab :=\tab assign\par \pard\plain \li480\ri480 \f16 \par \pard\plain \s2\li480\ri480\sa120 \f16 Except for the last three, all of these infix operators are functions. These functions are first class, like all Dylan functions, but in order to use one where a variable name is expected (for example, as the variable name in a {\f22 define method,} or as a function argument) the operator must be prefixed with the infix operator escape character ({\b \\}).\par \pard \s2\li480\ri480\sa120\keepn The order of evaluation for general infix expressions is as follows:\par In an expression of the form \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 arg}{\plain \f22\dn4 1}{\plain \f22 op \'c9 op arg}{\plain \f22\dn4 n}{\plain \f22 \par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 arg}{\f22\dn4 1}{\f22 \'c9 arg}{\f22\dn4 n}{\dn4 }are evaluated in that order. The evaluation time of module variables that {\f22 op} \rquote s are defined to invoke (e.g. the plus function for {\f22 +} ), is unspecified.\par The last three infix operators listed here ({\f22 &}, {\f22 |}, and {\f22 :=}) are syntax forms. They have special evaluation rules which are described where these forms are defined.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Slot Reference\par \pard\plain \li480\ri480\keepn \f16 Dylan provides a shorthand syntax for slot reference. The syntax {\f22 argument.function} applies {\i function} to {\i argument}. This syntax is usually used for slot reference, to access the {\i function } slot of the object {\i argument}.\par \pard \li480\ri480\keepn This can be cascaded and is left associative (i.e., {\f22 moo.goo.gai.pan} gets the {\i pan} slot of the {\i gai} slot of the {\i goo } slot of {\i moo}.).\par \pard \li480\ri480\keepn Examples: \par \pard\plain \s35\li360\keep\keepn\tx3240 \f22\fs20 \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} america.capital\par "Washington, D.C."\par {\i ?} me.mother.current-husband.favorite-child == me\par #t\par \pard\plain \li480\ri480\keepn \f16 \par \pard \li480\ri480\keepn Dylan\rquote s left-to-right evaluation rule applies here: {\f22 argument} is evaluated first, followed by {\f22 function}.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Array Reference\par \pard\plain \li480\ri480\keepn \f16 Dylan provides a shorthand syntax for array reference. The syntax {\f22 foo[i]} is equivalent to the function call {\f22 element(foo, i)}. The syntax foo[i{\fs18\dn4 1}, i{\fs18\dn4 2}, ... i{\fs18\dn4 n}] where n \'ad 1 is equivalent to the function call aref (foo, i{\fs18\dn4 1}, i{\fs18\dn4 2}, ... i{\fs18\dn4 n}).\par \pard \li720\ri480 \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define constant vect = #[7, 8, 9]\par defined vect\par {\i ?} vect[0]\par 7\par \pard\plain \s2\li480\ri480\sa120 \f16 \par In expressions of the form\par \pard \s2\li480\ri480\sa120 {\f22 \tab sequence[arg}{\f22\fs18\dn4 1}{\f22 , \'c9, arg}{\f22\fs18\dn4 n}{\f22 ]\par }\pard \s2\li480\ri480\sa120 {\f22 sequence} is evaluated first, then {\f22 arg}{\f22\fs18\dn4 1}{\f22 \'c9 arg}{\f22\fs18\dn4 n} in that order.\par \pard \s2\li480\ri480\sa120 The evaluation time of the variable <{\f22\fs20 element} in Dylan module> or <{\f22\fs20 aref} in Dylan module>, which this expression is defined to invoke, is unspecified.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Syntax of Dylan Files\par \pard\plain \s2\li480\ri480\sa120 \f16 A {\b Dylan source code file} is a standard portable file format for publishing Dylan source code. Such a file has two parts, the {\b header }and the {\b body}. The header comes before the body.\par \pard \s2\li480\ri480\sa120 The body consists of zero or more outer expressions and comments.\par The header consists of one or more keyword-value pairs, as follows:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 1) \tab The syntax of a keyword is as follows: a keyword is a letter, followed by zero or more letters, digits, and hyphens, followe d by a colon, contains only characters from the ISO 646 7-bit character set, and is case-independent.\par \pard \s21\fi-360\li840\ri480\sa160 2) \tab A keyword begins on a new line, and cannot be preceded by whitespace.\par \pard \s21\fi-360\li840\ri480\sa160 3) \tab All text (excluding padding whitespace) between the keyword and the newline is considered to be the value. Additional lines can be added by having the additional lines start with whitespace. Leading whitespace is ignored on all lines.\par \pard \s21\fi-360\li840\ri480\sa160 4) \tab Interpretation of the value is determined by the keyword.\par \pard \s21\fi-360\li840\ri480\sa160 5) \tab Implementations must recognize and handle standardized keywords properly, unless the specification for a keyword explicitly states that it can be ignored.\par \pard \s21\fi-360\li840\ri480\sa160 6) \tab When importing a file, implementations are free to ignore any non-standard keyword/value pair that they do not recognize.\par 7) \tab When exporting a file, implementations must use standard keywords properly. Implementations are free to use non-standard keywords. \par \pard \s21\fi-360\li840\ri480\sa160 8) \tab The definition of a keyword may specify that the keyword may occur more than once in a single file header. If it does n ot, then it is an error for the keyword to occur more than once. If it does, it should specify the meaning of multiple occurences.\tab \par \pard\plain \s2\li480\ri480\sa120 \f16 The header cannot contain comments.\par \pard \s2\li480\ri480\sa120 Blank lines may not appear in the header. A blank line defines the end of the header and the beginning of the code body. The blank line is not part of the code body. (A "blank line" is a line consisting of zero or more space or tab characters, ending in a newline character.)\par \pard\plain \li480\ri480\sl240 \f16 \par \pard\plain \s2\li480\ri480\sa120 \f16 The following standard keywords are defined:\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 module:} {\i module-name\tab }[Header keyword]{\i \tab \par }\pard\plain \s2\li480\ri480\sa120 \f16 Expressions in the file are associated with the named module. This keyword is required.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 author:}{\f22 }{\i arbitrary text\tab }[Header keyword]\par {\b\f22 copyright: }{\i arbitrary text\tab }[Header keyword]\par {\b\f22 version: }{\i arbitrary text\tab }[Header keyword]\par \pard\plain \s2\li480\ri480\sa120 \f16 These are provided for standardization. These are optional, and can be ignored by the implementation.\par \pard \s2\li480\ri480\sa120 \par A typical Dylan source file might look like this:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 module:\tab quickdraw\par author: \tab J. Random Rect\par \tab Linear Wheels, Inc., "Where quality is a slogan!"\par \tab rect@linear.com\par copyright: (c) 1993 Linear Wheels, Inc., All rights reserved\par version: \tab 1.3 alpha (not fully tested)\par \par define constant $black-color = ...\par ...\par \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 3. Variables\par \pard\plain \s2\li480\ri480\sa120 \f16 Dylan supports two kinds of variables: {\b lexical variables} and {\b module variables}.\par \pard \s2\li480\ri480\sa120 The term {\b environment} is used to refer to the set of variables that are available to a given part of a program. It includes both module variables and lexical variables.\par \pard \s2\li480\ri480\sa120 Variables can be set to new values with the {\f22 :=} special form, which is described in this chapter's section on Assignment.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Module Variables\par \pard\plain \s2\li480\ri480\sa120 \f16 Module variables can be referenced from anywhere inside the module. They play the role assumed by global variables in other languages.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx1080\tqr\tx9360 \f16 {\b\f22 define variable} {\i bindings}{\b\f22 = }{\i init}\tab [Definition]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 define variable} creates module variables in the current module. \par {\i bindings} are the variable(s) to be created, and mayhave the following forms:\par \tab \tab {\i variable}\par or \tab {\b\f22 ( }\{ {\i variable} \}* [ {\b\f22 #rest} {\i rest-variable-name } ]{\b\f22 )}\par \pard \s2\li480\ri480\sa120 where {\i variable} may be either {\i variable-name} or {\i variable-name} {\b\f22 ::} {\i type}. The {\i variable-names } and {\i rest-variable-name } must have the syntax of variable names, and are not evaluated. The values returned by {\i init} provide the initial values for the variable(s) specified by {\i bindings}.\par \pard \s2\li480\ri480\sa120 In the simplest case, {\i bindings} is just a variable name, and {\i init} returns one value which is used to initialize that variable. See Checking Types and Binding Multiple Values for more complex cases.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define variable foo = 10;\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i foo\par ?} foo + foo;\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 20\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx1080\tqr\tx9360 \f16 {\b\f22 define constant} {\i bindings}{\b\f22 = }{\i init}\tab [Definition]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 define constant} creates read-only module variables in the current module. This form has the same syntax and semantics as {\f22 define variable} except that the variables created are read-only.\par \pard \s2\li480\ri480\sa120 \par \pard \s2\li480\ri480\sa120 Several other forms create module variables. See {\f22 define class}, {\f22 define generic}, and {\f22 define method} for more information.\par \pard \s2\li480\ri480\sa120 Source code is associated with a specific module through the programming environment. This association occurs at development time and cannot be changed at run-time. See the Modules chapter for more details about modules. \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 A given module variable can only be defined once, except that multiple {\f22 define method} definitions with different specializers are allowed, together with at most one {\f22 define generic} definition.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Lexical Variables\par \pard\plain \s2\li480\ri480\sa120 \f16 Lexical variables are created locally and can be referenced only in a limited range of program text. They correspond to local variables in other languages.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx720\tqr\tx9360 \f16 {\b\f22 let}{\f22 }{\i bindings }{\f22 =} {\i init}\tab [Special Form]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 let} creates new lexical variables within the smallest enclosing implicit body containing the {\f22 let}. \par \pard \s2\li480\ri480\sa120 {\i bindings} are the variable(s) to be created, and may have the following forms:\par \tab \tab {\i variable}\par or \tab {\b\f22 ( }\{ {\i variable} \}* [ {\b\f22 #rest} {\i rest-variable-name } ]{\b\f22 )}\par \pard \s2\li480\ri480\sa120 where {\i variable} may be either {\i variable-name} or {\i variable-name} {\b\f22 ::} {\i type}. The {\i variable-names } and {\i rest-variable-name } must have the syntax of variable names, and are not evaluated. The values returned by {\i init} provide the initial values for the variable(s) specified by {\i bindings}.\par \pard \s2\li480\ri480\sa120\keepn In the simplest case, {\i bindings} is just a variable name, and {\i init} returns one value which is used to initialize that variable. See Checking Types and Binding Multiple Values for more complex cases.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} begin\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 let foo = 35;\par foo + foo\par end\par {\i 70\par \par }\pard\plain \s2\li480\ri480\sa120 \f16 A lexical variable shadows any module variable with the same name and any surrounding lexical variable with the same name. This rule means that the innermost version of a variable is the one referenced.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define variable foo = 10;\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i foo\par ?} foo\par {\i 10\par ?} begin \par let foo = 20;\par let foo = 50;\par foo + foo\par end\par 100\par {\i ?} foo\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 10\par \pard\plain \s2\li480\ri480\sa120 \f16 The bindings introduced by the {\f22 let} are in effect until the end of the smallest enclosing implicit body containing the {\f22 let}.\par Several other syntax forms, including {\f22 local} and {\f22 block}, also create lexical variables as part of their operation.\par \pard \s2\li480\ri480\sa120 Method parameters are another example of lexical variables; they can be referenced only from the body of the method. See the chapter on Functions for more information on method parameters.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Checking Types\par \pard\plain \s2\li480\ri480\sa120 \f16 Variable bindings appearing in parameter lists and in statements like {\f22 let} and {\f22 define variable} may be specialized or unspecialized. Specializing a variable indicates that the variable may only hold values of the specified type. Specialized variables have the syntax {\i variable-name }{\b\f22 ::}{\i type . } Leaving a variable unspecialized indicates that it may hold values of any type. Unspecialized variables simply appear as {\i variable-name}.\par \pard \s2\li480\ri480\sa120 Each {\i type} is any expression that evaluates to a valid Dylan type (that is, an instance of {\f22 }). The {\i types} are evaluated before the {\i init}, in the same environment as {\i init}. Each {\i type} specifies the type of the corresponding {\i variable}. Attempts to initialize or assign the {\i variable} to a value which is not an instance of the corresponding {\i type} results in a type error being signalled.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }begin\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 let x :: = sqrt (2);\par x\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 end\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 error: 1.4142135623730951 is not an instance of \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define variable foo :: = 10;\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i foo\par ?} foo := sqrt (2)\par {\i 10\par error: 1.4142135623730951 is not an instance of \par }\pard\plain \s28\keep \f16 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Binding Multiple Values\par \pard\plain \s2\li480\ri480\sa120 \f16 Evaluating a Dylan expression can yield one value, more than one value, or no values at all. This capability is called {\b multiple values}.\par \pard \s2\li480\ri480\sa120 Multiple values are supported through two capabilities:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab The function {\f22 values} is used to return multiple values.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab In the {\i bindings} parts of statements such as {\f22 let, define variable,} and{\f22 define constant}, {\i bindings} may have one of the following forms:\par \pard \s21\fi-360\li840\ri480\sa160 \tab \tab {\i variable}\tab or \tab {\b\f22 ( }\{ {\i variable} \}* [ {\b\f22 #rest} {\i rest-variable-name } ]{\b\f22 )}\par \tab The second form is used to receive multiple values.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 values} {\f22 #rest} {\i the-values} {\f23 \'de}{\i\f23 }{\i the-values}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Returns {\i the-values} as multiple values.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }values(1, 2, 3);\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i 1\tab }// first value returned{\i \par 2\tab }// second value returned\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 3\tab }// third value returned\par \pard\plain \s2\li480\ri480\sa120 \f16 When variables are initialized to values returned by an {\i init} in a statement such as {\f22 let, define variable,} and{\f22 define constant}, the number of {\i variables} and the number of values are compared: \par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab If there are the same number of {\i variables} and values, the variables are initialized to the corresponding values.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }begin\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 let (foo, bar, baz) = values (1, 2, 3);\par list (foo, bar, baz)\par end\par #(1, 2, 3)\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define method opposite-edges (center :: ,\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 radius :: );\par let (min, max) = edges (center, radius);\par values (max, min);\par end method;\par {\i opposite-edges\par ?} opposite-edges (100, 2);\par {\i 102\par }\pard\plain \s8\li960\ri480\sa120\tx2880\tx4800\tx6720 \f22\fs20 {\i 98}\par \pard\plain \s2\fi-360\li840\ri480\sa120 \f16 \bullet \tab If there are more {\i variables} than there are values returned by {\i init} , the remaining {\i variables} are initialized to {\f22 #f}. (If a specialized {\i variable} defaults to {\f22 #f} , and {\f22 #f} is not an instance of that variable's type, an error is signaled.)\par \bullet \tab If there are more values returned than there are {\i variables}, the excess values are placed in a sequence which is used as the initial value for {\i rest-variable}; if there is no {\i rest-variable}, these excess values are discarded. \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }begin\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 let (#rest nums) = edges (100, 2);\par nums;\par end\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 #(98, 102)\par \pard\plain \s2\fi-360\li840\ri480\sa120 \f16 \bullet \tab If there is a {\i rest-variable} but there are no excess values, {\i rest-variable} is initialized to an empty sequence.\par \pard\plain \s6\li960\ri480\tx2880\tx4800\tx6720 \f22\fs20 {\i \par }\pard\plain \s2\li480\ri480\sa120 \f16 Multiple values can be used to perform parallel binding:\par \pard\plain \s5\li960\ri480\sb60\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }begin\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 let x = 10;\par let y = 20;\par let (x, y) = values (y, x);\par list (x, y);\par end\par \pard\plain \s8\li960\ri480\sa120\tx2880\tx4800\tx6720 \f22\fs20 {\i #(20, 10)\par }\pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Assignment\par \pard\plain \s2\li480\ri480\sa120 \f16 The Dylan special form {\f22 := }is used to set variables to new values. It can also be used as an alternate syntax for calling setter functions and macros.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i place }{\b\f22 := }{\i new-value} {\f23 \'de} {\i new-value}\tab [Special Form]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 :=} stores {\i new-value} in {\i place}. Subsequent evaluations of {\i place} will yield {\i new-value}. {\f22 :=} returns {\i new-value}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\i place} commonly has the syntax of a variable name. Dylan also allows extended formats (described below). If {\i place} is not a variable name or one of these extended formats, an error is signaled. \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 If {\i place} is a variable name, then {\i new-value} is stored in the corresponding variable (which may be a lexical or module variable). An error is signaled if there is no lexical or module variable corresponding to the {\i place} , if the corresponding variable is a read-only variable, or if the corresponding variable is specialized to some type and the {\i new-value} is not an instance of that type.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define variable foo = 10;\par \pard\plain \s6\li960\ri-1260\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i 10\par ?} foo // this is a variable\par {\i 10 }// this is the variable\rquote s contents{\i \par ?} foo := 10 + 10;\par {\i 20\par ?} foo\par \pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i 20\par \par }\pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Extended form\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If {\i place} is not a variable name, then it may have the syntax of a call to a function. This is called the {\b extended form} of {\f22 :=} . In this case, the function call indicates an accessible location. The call to {\f22 :=} should change what future accesses of the location will return.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define variable foo = vector (10, 6, 8, 5);\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i foo\par ?} element(foo, 2)\par {\i 8\par ?} element(foo, 2) := "bar"\par {\i "bar"\par ?} foo\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i #[10, 6, "bar", 5]}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 In the general case,\par \pard\plain \s22\li960\ri480\sb120\sa240\tx2880\tx4800\tx6720 \f22\fs20 {\plain \i\f16 name}{\plain \f22 ( }{\plain \i\f16 arg}{\plain \i\f16\dn4 1}{\plain \i\f16 , ... arg}{\plain \i\f16\dn4 n}{\plain \f22\dn4 }{\plain \f22 ) := }{\plain \i\f16 new-value}{\plain \f22 \par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 means roughly\par \pard\plain \s22\li960\ri480\sb120\sa240\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \i\f16 name}{\plain \f22 -setter ( }{\plain \i\f16 new-value, arg}{\plain \i\f16\dn4 1}{\plain \i\f16 , ... arg}{\plain \i\f16\dn4 n}{\plain \f22\dn4 }{\plain \f22 ) \par }\pard\plain \s2\li480\ri480\sa120 \f16 In functional {\f22 :=}{\fs28 }expressions\par \pard \s2\li480\ri480\sa120 {\f22 \tab function-name(arg}{\f22\dn4 1}{\f22 , ..., arg}{\f22\dn4 n}{\f22 ) := value\par }\pard \s2\li480\ri480\sa120 where {\f22 function-name} is not a macro name, {\f22 arg}{\f22\fs18\dn4 1}{\f22 ... arg}{\f22\fs18\dn4 n} are evaluated first in that order, followed by {\f22 new-value}.\par The evaluation time of the variable {\f22 function-name-setter}, which this expression is defined to invoke, is unspecified.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Extended form using array reference or slot reference syntax\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The special syntactic shorthands for array reference and slot reference are also allowed as part of the extended form of :=.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 For example, the two forms\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 foo[2] := "quux"\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 element (foo, 2) := "quux"\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 are equivalent to\par \pard\plain \s22\li960\ri480\sb120\sa240\keepn\tx2880\tx4800\tx6720 \f22\fs20 element-setter ("quux", foo, 2).\par \pard\plain \s2\li480\ri480\sa120 \f16 In {\f22\fs20 .} := expressions\par \pard \s2\li480\ri480\sa120 {\f22 \tab argument.function-name := value\par }\pard \s2\li480\ri480\sa120 where {\f22 function-name} is not a macro name, {\f22 argument} is evaluated first, followed by {\f22 value}.\par The evaluation time of the variable {\f22 function-name-setter}, which this expression is defined to invoke, is unspecified.\par \pard \s2\li480\ri480\sa120 In implicit element {\f22 :=} expressions\par \pard \s2\li480\ri480\sa120 {\f22 \tab sequence[arg}{\f22\dn4 1}{\f22 , \'c9, arg}{\f22\dn4 n}{\f22 ] := value}\par \pard \s2\li480\ri480\sa120 {\f22 sequence} is evaluated first, then {\f22 arg}{\f22\fs18\dn4 1}{\f22 \'c9 arg}{\f22\fs18\dn4 n} in that order, then {\f22 value}. The evaluation time of the variable {\f22 element-setter} , which this expression is defined to invoke, is unspecified.\par \pard \s2\li480\ri480\sa120 \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 4. Control Constructs\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 True and False\par \pard\plain \s2\li480\ri480\sa120 \f16 In Dylan, there is a single object that counts as false. This object is indicated by the syntax {\b\f22 #f}{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } This is in sharp distinction to C, which equates 0 and the false value, and some dialects of Lisp, which equate the empty-list and the false value.}} . All other values are considered true for the sake of true/false testing. The canonical true object, indicated by the syntax {\b\f22 #t}, can be used for clarity of code.\par \pard \s2\li480\ri480\sa120 Throughout the manual, the phrases \ldblquote true,\rdblquote \ldblquote false,\rdblquote \ldblquote returns true,\rdblquote and \ldblquote returns false\rdblquote are used. It\rquote s important to remember that \ldblquote returns true\rdblquote does not necessarily mean \ldblquote returns the object {\f22 #t}.\rdblquote It simply means \ldblquote returns any object besides {\f22 #f}.\rdblquote Sometimes for efficiency, debuggability, or informational value, some value besides {\f22 #t} is returned.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 #t}\tab \tab [Object]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This is the canonical true value. In Dylan, all objects besides {\f22 #f} count as true, not just {\f22 #t}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 #f}\tab \tab [Object]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This is the only false value.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 ~} {\i thing} {\f23 \'de} {\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Returns true if {\i thing} is {\f22 #f}; otherwise returns false.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Conditionals\par \pard\plain \s2\li480\ri480\sa120 \f16 The following syntax forms are used to perform conditional execution.\par \pard\plain \s9\fi-480\li480\ri480\sa120\keepn\tx480\tx720\tqr\tx9360 \f16 {\b\f22 if} {\b\f22 (}{\f22 }{\i test}{\f22 }{\b\f22 )}{\f22 }{\i consequent}{\f22 \line }[{\b\f22 elseif} {\b\f22 (}{\f22 }{\i elseif-test}{\f22 }{\b\f22 )}{\i elseif-consequent}]*{\f22 \line }[{\b\f22 else} {\i alternate}]{\f22 \line \tab }{\b\f22 end} [{\b\f22 if} ] {\f23 \'de} {\i values}\tab [Special Form]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 if} evaluates {\i test}. If {\i test} evaluates to a true value, {\i consequent} is evaluated. \par \pard \s2\li480\ri480\sa120 If {\i test} evaluates to {\f22 #f} (the only false value), and any {\f22 elseif} clauses were supplied, the first {\i elseif-test } is evaluated. If that{\i elseif-test} evaluates to a true value, its {\i elseif-consequent} is evaluated. If it evaluates to {\f22 #f}, the next {\i elseif-test} is evaluated, and so on.\par \pard \s2\li480\ri480\sa120 Finally, if {\i test} and each {\i elseif-test} evaluates to #f, and {\i alternate} was supplied, the {\i alternate} is evaluated. If {\i alternate} was not supplied, #f is returned.\par \pard \s2\li480\ri480\sa120 The {\i consequent} , {\i elseif-consequent}, and {\i alternate} sections of an {\f22 if} statement are all implicit bodies (may contain any number of expressions, separated by semicolons). The values of the last expression in the appropriate {\i consequent} , {\i elseif-consequent}, or {\i alternate} form (whichever is evaluated) are returned.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define method test (thing :: ){\i \par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 if (thing)\par #t\par else\par #f\par end if\par end method;\par {\i test\par ?} test ("hello")\par {\i #t\par ?} test (#t)\par {\i #t\par ?} test (#f)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 #f\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define method show-and-tell (thing :: );\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 if (thing)\par print (thing);\par #t\par else\par #f\par end if\par end method;\par {\i show-and-tell\par ?} show-and-tell("hello")\par {\i hello\par }\pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 #t\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx720\tqr\tx9360 \f16 {\b\f22 unless}{\f22 }{\b\f22 (}{\f22 }{\i test}{\f22 }{\b\f22 )}\tab [Macro]\line \tab {\i body}{\f22 \line \tab }{\b\f22 end} [{\b\f22 unless}]{\i \line }{\f23 \'de} { \i values}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 unless} evaluates {\i test}. {\i body} is an implicit body. If {\i test} evaluates to a true value, then none of the expressions in the {\i body} are evaluated and {\f22 #f} is returned. If {\i test} evaluates to {\f22 #f}, then all the expressions in the {\i body} are evaluated and the values of the last expression are returned.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 If there are no expressions in the {\i body}, then {\f22 #f} is returned.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 unless(detect-gas? (nose))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 light(match)\par end unless\par {\b \par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx720\tqr\tx9360 \f16 {\b\f22 case}{\f22 }\tab [Macro]{\f22 \line \tab }{\i test}{\i\fs14\dn4 1} {\b\f22 =>} {\i body}{\i\fs14\dn4 1}{\fs14\dn4 }{\b\f22 ;}{\f22 \line \tab }... \line \tab {\i test}{\i\fs14\dn4 n} {\b\f22 =>} {\i body}{\i\fs14\dn4 n} {\b\f22 ;}\line \tab [{\b\f22 otherwise => }{\i otherwise-body} ] [{\b\f22 ;}]\line \tab {\b\f22 end}{\f22 }{\fs28 [}{\b\f22 case}{\fs28 ]\line }{\f23 \'de}{\i values}\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 case} evaluates the {\i tests} in order. \par \pard \s2\li480\ri480\sa120 If a {\i test} returns true, the corresponding {\i body }is evaluated, and the last expression in the {\i body} is returned. If there is no {\i body } in the {\i test} that succeeds, then the first value of the {\i test} is returned. Subsequent {\i tests} are not evaluated.\par \pard \s2\li480\ri480\sa120 If no {\i test} is true, then {\f22 case} returns {\f22 #f}.\par \pard \s2\li480\ri480\sa120 As a special case, the keyword {\f22 otherwise} may appear as a {\i test}. This {\i test} always succeeds if there are no other successful {\i tests}. \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 case\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 player1.money <= 0\par => end-game(player1);\par player2.money <= 0\par => end-game(player2);\par otherwise\par => move(player1);\par move(player2);\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 end case;\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx720\tqr\tx9360 \f16 {\b\f22 select} {\b\f22 (}{\f22 }{\i target-form} [{\b\f22 by} {\i test }] {\b\f22 )}\tab [Macro]\line \tab {\i match}{\i\fs18\dn4 1a}{\fs18 }{\b\f22\fs18 , }{\fs18 ... }{\i match-}{\i\fs18\dn4 1n} {\b\f22 => } {\i body}{\i\fs18\dn4 1};\line \tab ...\line \tab {\i match}{\i\fs18\dn4 ma}{\fs18 }{\b\f22\fs18 ,}{\fs18 ... }{\i match-}{\i\fs18\dn4 mn} {\b\f22 =>} {\i body}{\i\fs18\dn4 m};\line \tab [{ \b\f22 otherwise =>} {\i otherwise-body} ] [{\b\f22 ;}]\line \tab {\b\f22 end} [{\b\f22 select}]\line {\f23 \'de}{\i values}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Each {\i match-list} must be a sequence of expressions separated by commas, or the keyword {\f22 otherwise}. The {\i bodies} are implicit bodies (may be any number of expressions separated by semicolons).\par \pard\plain \s2\li480\ri480\sa120 \f16 When the {\f22 select} form is entered, the {\i target-form} is evaluated, generating a {\b target value}. \par \pard\plain \fi-360\li840\ri480 \f16 The{\f22\fs20 }clauses are tested in order, using the following procedure:\par \par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab Each {\i match i}s evaluated to produce a match object. The match expressions are evaluated in order. \par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab If a {\i test} function was supplied, this is used to compare the target object to the match objects. Otherwise, the match objects are compared to the target value with {\f22 ==}.\par \bullet \tab If a match is found, the corresponding {\i body } form is evaluated and the values of the last expression in the {\i body} are returned. If there is no {\i body } form in the matching clause, {\f22 #f} is returned.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab Once a match is found, the following match-object and body expressions, in this and subsequent clauses, are not evaluated at all.\par \pard\plain \s11\fi-360\li840\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 \bullet \tab If there is no matching clause, an error is signaled. \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 As a special case, the keyword {\f22 otherwise} may appear instead of a match-list. This clause will be considered a match if no other match is found. Because an {\f22 otherwise} clause matches when no other clause matches, a {\f22 select} form that includes an {\f22 otherwise} clause will never signal an error for failure to match.\par \pard\plain \s2\li480\ri480\sa120 \f16 Since testing stops when the first match is found, it is irrelevant whether the test function would also have returned true if called on later match-list elements of the same clause or on match-list elements of later clauses.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 select ( career-choice(student) )\par art:, music:, drama:\par => "Don\rquote t quit your day job";\par literature:, history:, linguistics:\par => "That really is fascinating";\par science:, math:, engineering:\par => "Say, can you fix my VCR?";\par otherwise => "I wish you luck";\par end select;\par \pard\plain \li720\ri480 \f16 {\f3\fs20 \par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Dylan\rquote s {\f22 select} with a test of {\f22 instance?} is similar in effect to a Common Lisp {\f22 typecase} statement.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 select ( my-object by instance? )\par , , => "a graphical object";\par , , => "a computational object";\par otherwise => "I don\rquote t know";\par end select\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i form1} {\b\f22 |} {\i form2} {\f23 \'de}{\i values}\tab [Macro]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 |} (\ldblquote or\rdblquote ) evaluates the {\i forms} from left to right. If {\i form1} returns true as its first value, that value is returned and {\i form2} is not evaluated. If {\i form1} returns {\f22 #f }as its first value, {\i form2} is evaluated and its values are returned.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i form1 } {\b\f22 &} {\i form2} {\f23 \'de}{\i values}\tab [Macro]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 &} (\ldblquote and\rdblquote ) evaluates the {\i forms} from left to right. If {\i form1} returns {\f22 #f} as its first value, {\f22 #f }is returned and {\i form2} is not evaluated. If {\i form1} returns true as its first value, {\i form2} is evaluated and its values are returned.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Iteration Constructs\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx720\tx900\tqr\tx9360 \f16 {\b\f22 while} {\b\f22 (}{\f22 }{\i test} {\b\f22 )}{\f22 }\tab [Macro]\line {\i \tab \tab body\line }\tab {\b\f22 end} {\fs28 [}{\b\f22 while}{\fs28 ]} \line { \f23 \'de}{\i\f23 }{\i }{\f22 #f}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 while} evaluates the expressions in the {\i body} over and over until the {\i test} returns false.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 Each pass through the loop begins by evaluating {\i test}. If {\i test} evaluates to a true value, the expressions in the {\i body} {\i }are evaluated and the looping continues. If {\i test} evaluates to {\f22 #f}, the loop terminates and {\f22 while} returns {\f22 #f}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx720\tx900\tqr\tx9360 \f16 {\b\f22 until} {\f22 }{\b\f22 (} {\i test} {\b\f22 )}{\f22 }\tab [Macro]\line \tab \tab {\i body}\line \tab {\b\f22 end} {\fs28 [}{\b\f22 until}{\fs28 ]}{\i } \line {\f23 \'de}{\i\f23 }{\i }{\f22 #f}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 until} evaluates the expressions in the {\i body} over and over until the {\i test} returns true.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 Each pass through the loop begins by evaluating {\i test}. If {\i test} evaluates to {\f22 #f}, the expressions in the {\i body} {\i }are evaluated and the looping continues. If {\i test} evaluates to a true value, the loop terminates and {\f22 until} returns {\f22 #f}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keep\keepn\tx480\tqr\tx9360 \f16 {\b\f22 for}{\f22 }{\b\f22 (}{\f22 }{\i clauses }\tab [Special Form]\line {\f22 }[\{{\b\f22 until} | {\b\f22 while}\} {\i end-test}] {\b\f22 )} \line {\i body}\line { \f22 [}{\b\f22 finally}{\f22 }{\i result-body}{\f22 ] \line }{\b\f22 end} [{\b\f22 for}]\line {\f23 \'de} {\i values\par }\pard\plain \li480\ri480 \f16 {\f22 for} allows one or more {\i clauses}. Each {\i clause}{\f22\fs20 }controls one {\b iteration variable} throughout the iteration. The optional {\i end-test}{\i\f22\fs20 } controls whether the iteration continues or terminates. It does not control any iteration variables.\par \pard \li1440\ri480 {\fs20 \par }\pard \li480\ri480 The kinds of {\i clauses}{\i\f22\fs20 }include {\b explicit step clauses}, {\b collection clauses}{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } Note that collection clauses are implemented using forward-iteration-protocol.}}, and {\b numeric clauses}: \par \pard \li480\ri480 \par {\ul Explicit step clauses\par }\par {\f22 \{}{\i variable}{\i\f22 }{\f22 | }{\i variable}{\f22 :: }{\i type}{\f22 \} }{\b\f22 =}{\f22 }{\i init-value}{\i\f22 }{\b\f22 then}{\f22 }{\i next-value}{\i\f22 \par }\pard \li1440\ri480 {\fs20 \par }\pard \li480\ri480 {\ul Collection clauses\par }\pard \li1440\ri480 {\fs20 \par }\pard \li480\ri480 {\f22 \{}{\i variable}{\i\f22 }{\f22 | }{\i variable}{\f22 :: }{\i type}{\f22 \} }{\b\f22 in}{\f22 }{\i collection}{\i\f22 \par }\pard \li1440\ri480 {\fs20 \par }\pard \li480\ri480 {\ul Numeric clauses}\par \pard \li480\ri480 {\f22\fs20 \par }\pard \li480\ri480\tx3780 {\f22 \{}{\i variable}{\i\f22 }{\f22 | }{\i variable}{\f22 :: }{\i type}{\f22 \}\tab }{\b\f22 from}{\f22 }{\i start}{\i\f22 \par }\pard \li480\ri480 {\i\f22 \tab }{\f22 [\{}{\b\f22 to}{\f22 | }{\b\f22 above}{\f22 | }{\b\f22 below}{\f22 \} }{\i bound}{\f22 ]\par \tab \tab \tab [}{\b\f22 by}{\f22 }{\i increment}{\f22 ]\par }\pard \li480\ri480 {\f22 \par }\pard \li2160\ri480 {\fs20 \par }\pard \li480\ri480 Iteration with {\f22 for}{\fs20 }proceeds through the following steps:\par \par \pard \fi-360\li1080\ri480 1) \tab Evaluate the expressions that are evaluated just once, in left to right order as they appear in the {\f22 for}{\f22\fs20 }statement. \par \pard \fi-360\li1440\ri280 \bullet \~\tab For explicit step clauses, these expressions are {\i type}{\i\f22\fs20 }and {\i init-value}{\fs28 .}\par \pard \fi-360\li1440\ri480 \bullet \~\tab For collection clauses, these are {\i type}{\i\f22\fs20 }and {\i collection}. If the value of {\i collection}{\i\f22\fs20 }is not a collection, signal an error. \par \bullet \~\tab For numeric clauses, these are {\i type}, {\i start}, {\i bound} if it is supplied, and {\i increment} if it is supplied. If {\i increment}{\i\f22\fs20 }is not supplied, it defaults to 1.\par \pard \fi-360\li1080\ri480 \par 2)\tab Bind the iteration variables of explicit step and numeric clauses.\par \pard \fi-360\li1440\ri480 \bullet \tab For each explicit step clause, bind {\i variable }to the value of {\i init-value}. If {\i type }is supplied and the value of {\i init-value }is not of the specified type, signal an error. \par \bullet \tab For each numeric clause, bind {\i variable }to the value of {\i start}. If {\i type }is supplied and the value of {\i start }is not of the specified type, signal an error.\par \pard \fi-360\li1080\ri480 \par \pard \fi-360\li1080\ri480 3)\tab Check numeric and collection clauses for exhaustion. If a clause is exhausted, go to step 9.\par \pard \fi-360\li1440\ri480 \bullet \tab A collection clause is exhausted if its collection has no next element.\par \pard \li1440\ri480 {\fs20 \par }\pard \fi-360\li1440\ri480 \bullet \tab Numeric clauses cannot be exhausted if {\i bound }is not supplied. If {\i bound }is supplied, the following table gives the conditions for exhaustion:\par \pard \fi-360\li1440\ri480 \par \trowd \trqc\trgaph14\trleft1426 \clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx3010\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx5890\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx8650\pard \qr\li180\ri376\intbl {\fs20 \cell }\pard \qc\li180\ri180\intbl {\i\f22\fs20 increment }{\f22\fs20 >= 0}{\fs20 \cell }\pard \qc\li180\ri180\intbl {\i\f22\fs20 increment }{\f22\fs20 < 0}{\fs20 \cell }\pard \intbl {\fs20 \row }\trowd \trqc\trgaph14\trleft1426 \clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx3010\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx5890\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx8650\pard \qr\li180\ri376\intbl {\f22\fs20 to}{\fs20 \cell }\pard \qc\li180\ri180\intbl {\i\f22\fs20 variable }{\f22\fs20 > }{\i\f22\fs20 bound}{\fs20 \cell }\pard \qc\li180\ri180\intbl {\i\f22\fs20 variable }{\f22\fs20 < }{\i\f22\fs20 bound}{\fs20 \cell }\pard \intbl {\fs20 \row }\pard \qr\li180\ri376\intbl {\f22\fs20 above}{\fs20 \cell }\pard \qc\li180\ri180\intbl {\i\f22\fs20 variable }{\f22\fs20 <= }{\i\f22\fs20 bound}{\fs20 \cell }\pard \qc\li180\ri180\intbl {\i\f22\fs20 variable } {\f22\fs20 <= }{\i\f22\fs20 bound}{\fs20 \cell }\pard \intbl {\fs20 \row }\trowd \trqc\trgaph14\trleft1426 \clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx3010\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0 \cellx5890\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx8650\pard \qr\li180\ri376\intbl {\f22\fs20 below}{\fs20 \cell }\pard \qc\li180\ri180\intbl {\i\f22\fs20 variable }{\f22\fs20 >= }{\i\f22\fs20 bound}{\fs20 \cell }\pard \qc\li180\ri180\intbl {\i\f22\fs20 variable }{\f22\fs20 >= }{\i\f22\fs20 bound}{\fs20 \cell }\pard \intbl {\fs20 \row }\pard \fi-360\li1080\ri480 \par \pard \fi-360\li1080\ri480 4)\tab Bind the iteration variables of collection clauses. Fresh bindings are created each time through the iteration.\par \pard \fi-360\li1440\ri480 \bullet \tab For each collection clause, bind {\i variable }to the next element of the collection for that clause. If {\i type }is supplied and this next element of the collection{\i } is not of the specified type, signal an error.\par \pard \fi-360\li1440\ri480 \par \pard \fi-360\li1080\ri480 5) \tab If {\i end-test} is supplied, evaluate it. The termination conditions depend on the symbol used to introduce the {\i end-test }in the {\f22 for }statement.\par \pard \fi-360\li1440\ri180 \bullet \tab If the value of {\i end-test }is false and the symbol is {\f22 while}, go to step 9.\par \bullet \tab If the value of {\i end-test }is true and the symbol is {\f22 until}, go to step 9.\par \pard \fi-360\li1080\ri480 \par \pard \fi-360\li1080\ri480 6) \tab Execute the expressions in the {\i body} in sequence. The expressions in the {\i body} are used to produce side-effects.\par \pard \fi-360\li1080\ri480 \par \pard \fi-360\li1080\ri480 7) \tab Obtain the next values for explicit step and numeric clauses. Values are obtained in left to right order, in the environment produced by step 6.\par \pard \fi-360\li1440\ri480 \bullet \tab For each explicit step clause, evaluate {\i next-value}.\par \pard \fi-360\li1440\ri100 \bullet \tab For each numeric clause, add the values of {\i variable }and {\i increment}.\par \pard \fi-360\li1080\ri480 \par \pard \fi-360\li1080\ri480 8)\tab Bind the iteration variables of explicit step and numeric clauses to the values obtained in step 7. For each clause, if {\i type }is supplied and the next value for that clause{\i } is not of the specified type, signal an error. Fresh bindings are created each time through the iteration. After variables are bound, go to step 3.\par \pard \fi-360\li1080\ri480 \par \pard \fi-360\li1080\ri480 9) \tab Evaluate the expressions in the {\i result-body} in sequence. Bindings created in step 2 and 8 {\ul are} visible during the execution of {\i result-body} . Bindings created in step 4 (i.e. the iteration variables of collection clauses) {\ul are not} visible during the execution of {\i result-body}. The values of the last expression in the {\i result-body} are returned by the {\f22 for } statement. If there are no expressions in the {\i result-body}, {\f22 for} returns {\f22 #f}.\par \pard \li480\ri480 {\b \par Examples of }{\b\f22 for}{\b :\par \par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 for ( thing = first-thing then next(thing),\par until done?(thing) )\par do-some(thing)\par end;\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 for (j :: from 0 to height)\par for (i :: from 0 to width)\par erase(i,j);\par plot (i,j);\par end for;\par end for;\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 for (city in olympic-cities,\par year from start-year by 4)\par schedule-olympic-game(city, year)\par finally notify(press);\par sell(tickets);\par end;\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 for (i from 0 below 100,\par zombies from 0 below 100,\par normals from 100 above 0 by -1)\par population[i] := zombies + normals\par end;\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Non-local Exits\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx720\tx900\tqr\tx9360 \f16 {\b\f22 block} {\b\f22 ( }[{\i exit-var}] {\b\f22 )} \tab [Special Form]\line \tab \tab {\i body} \line \tab \tab [{\b\f22 cleanup} {\i cleanup-clause} | {\b\f22 exception} {\i exception-clause} ]*\line {\f22 \tab }{\b\f22 end}{\f22 }[ {\b\f22 block}{\f22 }]\line {\f23 \'de} {\i values}\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 block} is a construct which combines the functionality of non-local exits, protected forms, and exception handling. block executes the expressions in the {\i body} in sequence, and then the optional {\i cleanup-clauses}. Any number of {\i cleanup-clauses} may be provided, and they may be arbitrarily interleaved with {\i exception-clauses} (described in the chapter on Conditions). Normally, the value returned by {\f22 block} is the value of the last expression in the {\i body}. If there are no expressions in the {\i body}, {\f22 #f} is returned.\par If {\i exit-var} is provided, {\i exit-var} is bound to an {\b exit procedure} during the execution of the {\i body} and {\i clauses}. At any point in time before the last {\i clause} returns, the exit procedure can be called. Calling the exit procedure has the effect of immediately terminating the execution of the {\i body} . The exit procedure accepts any number of arguments. These arguments are used as the return values of block. Calling an exit procedure is known as performing a {\b non-local exit.}\par \pard \s2\li480\ri480\sa120 Generally, the {\i cleanup-clauses} are guaranteed to be executed. Even if one of the expressions in the {\i body} is terminated by a non-local exit out of the {\f22 block}, the {\i cleanup-clauses} are executed before the non-local exit can complete. \par \pard \s2\li480\ri480\sa120 For example, the following code fragment ensures that files are closed even in the case of an error causing a non-local exit from the block body:\par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 block (return)\par open-files();\par ...\par if (error)\par return(#f);\par end if;\par ...\par result\par cleanup\par close-files();\par end block\par \pard\plain \li480\ri480 \f16 \par \pard\plain \s2\li480\ri480\sa120 \f16 However, if one of the {\i cleanup-clauses} is terminated by a non-local exit out of the {\f22 block}, any following {\i cleanup-clauses} within the same {\f22 block} are not executed.\par \pard\plain \li480\ri480 \f16 \par \pard \li480\ri480 {\b\fs28 Restrictions on the use of exit procedures\par }\pard \li480\ri480 \par \pard \li480\ri480 The exit procedure is a first-class object. Specifically, it can be passed as an argument to functions, stored in data structures, etc. Its use is not restricted to the lexical body of the {\b establishing block} (the block in which that exit procedure was established). Ho wever, invocation of the exit procedure is valid only during the execution of the establishing block. It is an error to invoke an exit procedure after its establishing block has returned, or after execution of the establishing block has been terminated by a non-local exit.\par \pard \li480\ri480 \par \pard \li480\ri480 In the following example, the {\f22 block} establishes an exit procedure and binds {\f22 bar} to that exit procedure. The {\f22 block} returns an anonymous method containing a call to {\f22 bar}. The anonymous method is then bound to {\f22 foo}. Calling the {\f22 foo} method is an error because it is no longer valid to invoke {\f22 bar} after its establishing block returns.\par \pard \li480\ri480 \par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 ? define constant foo =\par block (bar)\par method (n) bar(n) end;\par end block;\par ? foo(5)\par {\i error or other undefined consequences\par }\pard\plain \li480\ri480 \f16 \par \pard \li480\ri480 When an exit procedure is called, it initiates a non-local exit out of its establishing block. Before the non-local exit can complete, however, the cleanup clauses of {\b intervening blocks} (blocks that have been entered, but not exited, since the establishing block was entered) must b e executed, beginning with the most recently entered intervening block. Once the cleanup clauses of an intervening block have been executed, it is an error to invoke the exit procedure established by that block. Finally, the cleanup clauses of the estab lishing block are executed, further invocation of the exit procedure becomes invalid, and the establishing block returns with the values that were passed to the exit procedure.\par \pard \li480\ri480 \par \pard \li480\ri480 During the process of executing the cleanup clauses of the intervening blocks, any valid exit procedure may be invoked and may interrupt the current non-local exit.\par \pard \li480\ri480 \page \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 5. Comparisons\par \pard\plain \s2\li480\ri480\sa120 \f16 Dylan provides an identity function, as well as a group of equality and magnitude comparison functions that can be extended for user classes. The methods {\f22 ~}=, {\f22 >}, {\f22 <}=, and {\f22 >} = are defined in terms of {\f22 =} and {\f22 <}. By extending the behavior of {\f22 =} and {\f22 <}, programs can extend the behavior of the other methods.\par \pard \s2\li480\ri480\sa120 For the protocol to work, all methods on {\f22 =} and {\f22 <} must preserve the following properties:\par \pard\plain \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \f16 Identity:\tab If (a {\f22 ==} b), then (a {\f22 =} b).\par \pard\plain \s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 Transitivity: \tab If (a {\f22 <} b) and (b {\f22 <} c), then (a {\f22 <}\~\~c).\par \tab If (a {\f22 =} b) and (b {\f22 =}\~\~c), then (a {\f22 =}\~c).\par \pard\plain \s16\fi-2160\li2640\ri480\sa240\tx2640 \f16 Trichotomy: \tab Exactly one of: (a {\f22 <} b), (a {\f22 =} b), (b {\f22 <} a) always holds \line (on the assumption that these two operations are defined for the objects in question).{\up6 }{ \fs18\up6 \chftn {\footnote \pard\plain \s246\li480 \f16\fs20 {\fs18\up6 \chftn }Trichotomy also implies antisymmetry [if {\f22 (a < b)}, then {\f22 ~(b < a)}] and antireflexivity \line [if {\f22 (a == b)}, then {\f22 ~(a < b))} ]. It also implies commutativity for {\f22 =} [if {\f22 (a = b)}, then {\f22 (b = a)}].}}{\fs18\up6 ,}{\fs16\up6 \chftn {\footnote \pard\plain \s245\li480\ri480 \f16\fs20\up6 {\fs18 \chftn }{\plain \f16\fs20 The trichotomy rule doe s not hold for IEEE floating-point comparisons. IEEE requires all comparison operations to return false if one of the operands is a NaN. This means that the generic Dylan equality and magnitude predicates will not be IEEE compliant. }}}\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Equality Comparisons\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i object1 }{\b\f22 ==} {\i object2} {\f22 }{\f23 \'de}{\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 ==} returns true if {\i object1} and{\i object2} are identical. Otherwise, it returns false.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 Objects are considered identical if they are computationally equivalent. That is, there is no way for any possible Dylan program to distinguish them.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } At an implementation level, this will usually mean that the objects are pointers to the same storage or are the same immediate value. An extension is made for built-in number classes and characters. Because these objects are not mutable (i.e., cannot be changed), two with the same value will always be the same (and will thus be indistinguishable to programs).}}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i object1 } {\b\f22 =} {\i object2} {\f23 \'de}{\i boolean}\tab [Generic Function]\par \pard\plain \li540\ri480\tx540\tqr\tx7680\tqr\tx8640 \f16 Programmers may define methods for {\f22 =} specialized on classes they define. A programmer may be required to provide a {\f22 =} method when defining subclasses of some predefined classes in order to fullfill the protocol of the class, as described below.\par \pard \li540\ri480\tx520 \par \pard \li480\ri480 - Two collections are equal if they have identical {\f22 key-test} functions, they have the same keys (as determined by their {\f22 key-test} functions), the elements at corresponding keys are =, and neither is a dotted list.\par \pard \li540\ri480 {\i \par }\pard \li540\ri480 -Two dotted lists are equal if they are the same size, corresponding elements are =, and the final tails are =.\par \pard \li540\ri480\tx540 \par - Numbers are equal if they have the same mathematical value.\par \pard \li1440\ri480 {\b \par }\pard \li540\ri480 - For objects which do not have a more specific = method, = returns the same as ==.\par \pard \li540\ri480 \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 = is not guaranteed to return (for example, when called on circular structures or unbounded structures).\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i object1 }{\b\scaps\f22 ~=} {\i object2} {\f23 \'de}{\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 ~}= calls = on {\i object1} and {\i object2}. Returns true if = returns false.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\f22 ~}= is not a generic function, so you can\rquote t add methods to it. To extend the protocol, define methods on =.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Magnitude Comparisons\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i object1 }{\b\f22 <} {\i object2} {\f23 \'de}{\i boolean}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The predefined methods on {\f22 <} behave as follows:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \emdash \tab Built-in real numbers are compared by mathematical value.\par \pard \s21\fi-360\li840\ri480\sa160 \emdash \tab Characters are compared by the ordinal value of the underlying character set. Character case is significant.\par \pard \s21\fi-360\li840\ri480\sa160 \emdash \tab Strings are compared lexicographically, using {\f22 <} on corresponding elements. If one string is a strict prefix of the other, the shorter string is considered the \ldblquote smaller\rdblquote one. \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i object1 }{\b\f22 >}{\b } {\i object2} {\f23 \'de}{\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 >} compares the {\i objects} with {\f22 <} (with appropriate argument reordering). If {\i object1} is greater than {\i object2}, {\f22 >} returns true. Otherwise, {\f22 >} returns false.\par {\f22 >} is not a generic function, so you can\rquote t add methods to it. To extend the protocol, define methods on {\f22 <}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i object1 }{\b\f22 <=} {\i object2} {\f23 \'de}{\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 <}= compares the {\i objects} with {\f22 <} (with appropriate argument reordering). If {\i object1} is less than or equal to {\i object2}, {\f22 <}= returns true. Otherwise, {\f22 <} = returns false.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\f22 <}= is not a generic function, so you can\rquote t add methods to it. To extend the protocol, define methods on {\f22 <}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i object1 }{\b\f22 >=} {\i object2} {\f23 \'de}{\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 >}= compares the {\i objects} with {\f22 <}. If {\i object1} is greater than or equal to {\i object2}, {\f22 >}= returns true. Otherwise, {\f22 >}= returns false.\par {\f22 >}= is not a generic function, so you can\rquote t add methods to it. To extend the protocol, define methods on {\f22 <}.\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \par \pard\plain \s18\fi-360\li1440\ri480\sa160 \f16 \page \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 6. Functions\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Function Defining Forms\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Generic Functions and G. F. Methods\par \pard\plain \s2\li480\ri480\sa120 \f16 The basic tools for defining generic functions and methods are the defining forms {\f22 define\~generic} and {\f22 define method}.\par \pard \s2\li480\ri480\sa120 {\f22 define\~generic} is used to declare information about the generic function as a whole. It is not strictly necessary to use {\f22 define\~generic}; generic functions can be created with {\f22 define method} alone.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 define}{\f22 \~}[ {\i adjectives} ] {\b\f22 generic}{\b }{\i name parameter-list } \tab [Definition]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 define generic} creates a new generic function object. {\i name} is a variable name, and is defined as a read-only variable in the current module, containing the new generic function.\par The {\i adjectives} are words separated by spaces. The allowed {\i adjectives} are {\f22 open} and {\f22 sealed}. The {\i adjectives} control the level of dynamism of the generic function. See the Controlling Dynamism chapter for more details.\par \pard \s2\li480\ri480\sa120 The {\i parameter-list} specifies what arguments are acceptable to the generic function, and constrains which methods may be added to the generic function. In its simplest form, the {\i parameter-list} is a list of variable names, separated by commas, which represent the required parameters of the generic function. Methods added to the generic function must have parameter lists that are congruent with the generic function\rquote s parameter list. \par \pard \s2\li480\ri480\sa120 A generic function with no required parameters can contain a single method. Adding a method has the effect of replacing the old method.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 A complete description of parameter lists and congruency is given in the Function Applicability section.\par \pard\plain \s2\li480\ri480\sa120\keepn \f16 {\f22 define method} is used to add methods to a generic function. It can also be used to create a new generic function that does not already exist.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 define }[ {\i adjectives} ] {\b\f22 method }{\i name parameter-list }\tab [Definition]{\i \par }\pard\plain \s10\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 {\i implicit-body }\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\b\f22 end} [{\b\f22 method} [ {\i name }]]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 define method} creates a method and adds it to the generic function in {\i name}. If the module variable {\i name} is not already defined, it is defined as with {\f22 define\~generic}. Thus, {\f22 define method} will create a new generic function or extend an old one, as needed. Methods added to a generic function must have parameter lists that are congruent with the generic function\rquote s parameter list. A complete description of congruency is given in the Function Applicability section.\par \pard \s2\li480\ri480\sa120 The {\i adjectives} are words separated by spaces. The allowed {\i adjectives} are {\f22 open} and {\f22 sealed}. The {\i adjectives} control the level of dynamism of the named generic function. See the Controlling Dynamism chapter for more details.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The parameters of the method\emdash and the specializers of the parameters\emdash are described in the {\i parameter-list} . The specializers declare what kinds of arguments are acceptable to the method. The method can be called only with arguments that match the specializers of the parameters. A complete description of parameter lists is given in the Function Applicability section.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 When the method is invoked, it executes the {\i implicit-body}. Statements in the {\i implicit-body} are executed in order. The method parameters are bound as lexical variables over the scope of the { \i implicit-body}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The following example shows how a generic function {\f22 double} could be defined to work with some built-in classes.\par You can define a method for {\f22 double} that is applicable when {\f22 double} is called on a number.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define method double (thing :: )\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 thing + thing;\par end method;\par {\i double}\par {\i ?} double\par {\i \{the generic function double\}}\par {\i ?} double(10)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 20}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The generic function {\f22 double} is now defined, but because it has a method only for the class {\f22 }, it can be called only on instances of {\f22 }. If you try to call { \f22 double} with another class of argument, you will get an error.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }double("the rain in Spain.")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i error: no method for \{the generic function double\} was found\par }\pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i for the arguments ("the rain in Spain.")\par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 To operate on a second class of arguments, you have to add another method to {\f22 double}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define method double (thing :: ){\i \par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 concatenate (thing, thing);\par end method;\par {\i double\par ?} double("the rain in Spain.")\par {\i "the rain in Spain.the rain in Spain."\par \par }\pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Bare Methods\par \pard\plain \s2\li480\ri480\sa120 \f16 In Dylan, methods can also be created and used directly:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab To perform a local calculation.\par \bullet \tab For a function that does not require any class dispatch.\par \bullet \tab To build up generic functions programmatically.\par \pard\plain \s2\li480\ri480\sa120 \f16 The basic tool for creating methods is the special form {\f22 method}. \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 method}{\f22 }{\i parameter-list }\tab [Special Form]{\i \par }\pard\plain \s10\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 {\f22 }{\i implicit-body}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\b\f22 end} [{\b\f22 method}]\par \pard\plain \s9\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\f23 \tab \'de}{\i method}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 method} creates and returns {\i method}. {\i method} is a method that accepts the arguments described by {\i parameter-list} and then executes the {\i implicit-body}. Statements in the {\i implicit-body} are executed in order. The {\i parameter-list} describes the parameters for {\i method}. A complete description of parameter lists is given in the Function Applicability section.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 Here is an example:\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} method(num1, num2)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 num1 + num2\par end method\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i \{an anonymous method\}}\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ;the second argument to SORT is the test function\par ?} sort(person-list,\par method(person1, person2)\par person1.age < person2.age\par end method)\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} begin\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 let double = method(number) number + number end;\par double(double(10))\par end\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 40\par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The following example defines a method for {\f22 double} that works on functions. When you double a function, you get back a method that accepts arguments and calls the function twice, passing the arguments both times.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define method double (my-method :: )\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 method (#rest args)\par apply (my-method, args);\par apply (my-method, args);\par #f\par end method\par end method;\par {\i double\par ?} define constant print-twice = double(print)\par {\i print-twice\par ?} print-twice\par {\i \{an anonymous method\}\par ?} print-twice("The rain in Spain. . .")\par {\i The rain in Spain. . .The rain in Spain. . .\par #f\par ?} print-twice(55)\par {\i 5555\par }\pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i #f\par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Bare methods may be called directly or they may be added to generic functions.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } When methods are called directly, the {\f22 method} special form corresponds to the {\f22 lambda} special form of Lisp and to blocks in Smalltalk.}} Usually, however, when you want to add a method to a generic function, you create and add the method in a single step, with {\f22 define method}. \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx1700\tqr\tx9360 \f16 {\b\f22 local} {\i method-spec}{\i\fs18\dn4 1}{\i , method-spec}{\i\fs18\dn4 2}{\f22 , }\'c9{\b\f22 ;}\tab [Special Form]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 local} can be used for creating self- and mutually-recursive methods.\par \pard \s2\li480\ri480\sa120 Each {\i name} is bound to a method specified by the corresponding {\i method-spec .} Each {\i method-spec} has the same syntax as the {\f22 method} form, except that the word {\f22 method} is optional, and a variable name precedes the parameter list.\par \pard \s2\li480\ri480\sa120 {\f22 local} is similar to {\f22 let}, in that it binds variables within the current scope (usually the immediately enclosing {\f22 begin...end} block). The scope of the {\i names} also includes the parameter lists and the bodies of the methods. This means that the methods can refer to themselves and to the other methods created by the {\f22 local} form.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define method root-mean-square (s :: )\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 local method average (nums)\par reduce1 (\\+, nums) / size (nums)\par end average,\par method square (n)\par n * n \par end square;\par sqrt (average (map (square, s)))\par end method root-mean-square\par \par {\i ?} root-mean-square (#(5, 6, 6, 7 ,4))\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 5.692099788303083\par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define method newtons-sqrt (x)\par local method sqrt1 (guess)\par if (close? (guess))\par guess\par else\par sqrt1 (improve (guess))\par end if\par end sqrt1,\par method close? (guess)\par abs (guess * guess - x) < .0001\par end close?,\par method improve (guess)\par (guess + (x / guess)) / 2\par end improve;\par sqrt1 (1)\par end method newtons-sqrt\par {\i \par ?} newtons-sqrt (25)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 5.000000000053723}\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Parameter Lists\par \pard\plain \s2\li480\ri480\sa120 \f16 Dylan parameter lists support {\b required parameters}, {\b rest parameters}, {\b keyword parameters}, and sometimes a special {\b next-method parameter}. They also may include {\b return type declarations}.\par Required parameters correspond to arguments supplied when a function is called. The arguments are supplied in a fixed order and must appear before any other arguments.\par \pard \s2\li480\ri480\sa120 Each required parameter may be a variable name, or a variable name {\b specialized} by a type (using the syntax {\i variable}{\f22 :: }{\i type} ). This has the effect of declaring that supplied arguments must be general instances of that type. The singleton specializer syntax can also be used ({\i variable}{\f22 == }{\i expression}, which is equivalent to {\i variable}{\f22 :: singleton (}{ \i expression}{\f22 )}).\par \pard \s2\li480\ri480\sa120 A rest parameter allows a function to accept an unlimited number of arguments.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } In practice, an implementation may place a reasonable limit on the number of arguments that may be passed to any function.}} After the required arguments of a function have been supplied, any additional arguments are collected in a new sequence, which is passed as the value of the rest parameter.\par \pard \s2\li480\ri480\sa120 Keyword parameters correspond to arguments that are optional and may be given in any order. Symbols are used among the arguments to guide matching of argument values to parameter variables. We say that "the arguments are keyed by symbols." These symbols are usually written in keyword syntax and so they are informally known as keywords. The arguments and parameters are matched up by keyword name. Keyword arguments can only be supplied after all required arguments are supplied.\par \pard \s2\li480\ri480\sa120 Required parameters come first in the parameter list, followed by the rest parameter, if any, and then the keyword parameters, if any. A rest parameter is indicated by the token {\f22 #rest} , followed by the name of the parameter. Keyword parameters are indicated by the token {\f22 #key}, followed by the keyword parameter specifiers, optionally followed by the token {\f22 #all-keys}.\par \pard \s2\li480\ri480\sa120 If {\f22 #rest} and {\f22 #key} are used in the same parameter list, {\f22 #rest} must come first. The rest parameter will be bound to a sequence containing all the keywords and their corresponding values.\par \pard \s2\li480\ri480\sa120 A next-method parameter is indicated by the token {\f22 #next} , followed by the name of the parameter. It is not normally necessary to specify a next-method parameter explicitly. If a next-method parameter is not specified by the programmer, {\f22 define method} inserts one with the name {\f22 next-method} . If an explicit next-method parameter is given, it must come after the required parameters and before the rest and keyword parameters. Details of using {\f22 next-method} are given in the section on Calling More General Methods.\par \pard \s2\li480\ri480\sa120 The following are sample parameter lists as they would appear in a method definition.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4500\tx6720 \f22\fs20 (a, b, c)\tab \tab {\f16 three required parameters}\par (a :: , b, #rest c)\tab {\f16 two required parameters and a rest parameter}\par (#rest a)\tab \tab {\f16 a rest parameter, no required parameters}\par (a, b, #key foo, bar)\tab {\f16 two required and two keyword parameters}\par (#key bar, baz, bim)\tab {\f16 three keyword and no required parameters}\par \pard \s6\li960\ri280\keepn\tx2880\tx4500\tx6720 (#rest all, #key fee, fi)\tab {\f16 a rest parameter and two keyword parameters}\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Argument Passing Protocol\par \pard\plain \li480\ri480 \f16 The argument passing protocol for a generic function or method can be described in one of the following ways, depending on its parameter list:\par \pard \li480\ri480 \par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab It is said to {\b accept keyword arguments} if its parameter list specifies {\f22 #key}. The parameter list could also specify {\f22 #rest}.\par \bullet \tab A function that accepts keyword arguments is said to {\b accept all keyword arguments} if its parameter list specifies {\f22 #all-keys}.\par \bullet \tab It is said to {\b accept a variable number of arguments} if its parameter list specifies {\f22 #rest} but does not specify {\f22 #key}.\par \bullet \tab It is said to {\b require a fixed number of arguments} if its parameter list does not specify either {\f22 #rest} or {\f22 #key}.\par \pard\plain \li480\ri480 \f16 \par \pard \li480\ri480 A method that accepts keyword arguments is said to {\b recognize} the keywords mentioned in its parameter list. (A method may, of course, mention them in the parameter list and then explicitly ignore the values.) It is possible for a method t o accept keyword arguments in general, but not recognize any particular keywords.\par \pard \li480\ri480 \par \pard \li480\ri480 A generic function that accepts keyword arguments may specifiy a set of keywords which must be recognized by every method added to the generic function. These are the {\b mandatory keywords} for the generic function.\par \pard \li480\ri480 \par \pard \li480\ri480 A function that accepts keyword arguments is said to {\b permit} a keyword argument if the function is a method that recognizes the keyword, the function is a generic function and the keyword is recognized by any of the applicable methods, or the function accepts all keyword arguments.\par \pard \li480\ri480 \par \pard \li480\ri480 If a function that accepts keyword arguments is called, it will signal an error if called with a keyword argument that it does not permit, or if the arguments following the required arguments are not keyword/value pairs.\par \pard \li480\ri480 \par \pard \li480\ri480 If a method is called via a generic function or via next-method (rather than directly), the method itself does not check whether it received any keyword arguments it does not recognize, nor does it check that the arguments following the required arguments are keyword/value pairs.\par \pard \li480\ri480 \par \pard \li480\ri480 A call to a function may supply the same keyword argument more than once. When this is done, the value of the leftmost occurrence is used.\par \pard \li480\ri480 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Specializing Required Parameters\par \pard\plain \s2\li480\ri480\sa120 \f16 When you define a generic function or method, you may specify the classes or identities of the arguments appropriate for the generic function or method. This is called {\b specializing} the generic function or method.\par \pard \s2\li480\ri480\sa120 The following example defines a method on {\f22 double} which is applicable when {\f22 double} is called with a general instance of {\f22 } . The instance can be a direct instance or an indirect instance of the specializer class. In the example, the argument can be an integer, a float, or any other kind of number.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define method double (thing :: )\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 thing + thing\par end method\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} double(10)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i 20\par ?} double(4.5)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 9.0}\par \pard\plain \s2\li480\ri480\sa120 \f16 Specialization restricts the arguments that may be passed as the value of the parameter. The function can be called only with arguments that match the specializers of the corresponding parameters. If a specializer is a class, the corresponding argument must be a general instance of the class. If the specializer is a {\b singleton} (used to indicate an individual object), the corresponding argument must be the singleton\rquote s object. \par \pard \s2\li480\ri480\sa120 Providing this information offers two key benefits:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab It indicates to the compiler (and to anyone reading your code) that an error is signalled if arguments of the wrong type are provided.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab It allows the compiler to optimize your code and possibly improve its performance, due to the restrictions it can infer from the type information you provide.\par \pard\plain \s2\li480\ri480\sa120 \f16 Specialized parameters are also used in method dispatch. A generic function chooses among its methods on the basis of the methods\rquote specializers. The generic function chooses the method whose specializers most closely match the classes and identities of the actual parameters.\par \pard \s2\li480\ri480\sa120 The following are examples of parameter lists that include specializers:\par \pard\plain \s17\li480\ri480\sa120\tx3600 \f16 {\f22\fs20 (a :: , b, c)}\tab {\fs20 Three required arguments. \line \tab The first must be a window.}{\f22\fs20 \par }\pard \s17\li480\ri480\sa120\tx3600 {\f22\fs20 (a :: ,\tab }{\fs20 Three required arguments.}{\f22\fs20 \line b :: ,\tab }{\fs20 The first must be a window and the second a character. }{\f22\fs20 \line c)\tab }\par \pard \s17\li480\ri480\sa120\tx3600 {\f22\fs20 (a :: ,\tab }{\fs20 Three required arguments.}{\f22\fs20 \line b :: ,\tab }{\fs20 The first must be a window, the second a character, }{\f22\fs20 \line c :: singleton (0))}{\fs20 \tab the third the integer 0.\par }\pard \s17\li480\ri480\sa120\tx3600 {\f22\fs20 (a, b :: ,\tab }{\fs20 Two required arguments and a rest argument.}{\f22\fs20 \line #rest c)\tab }{\fs20 The second argument must be a string.\par }{\f22\fs20 (a :: , b,\tab }{\fs20 Two required and two keyword arguments.}{\f22\fs20 \line #key foo, bar)\tab }{\fs20 The first required argument must be a vector.\par }\pard \s17\li480\ri480\sa120\tx3600 {\fs20 \par }\pard\plain \s2\li480\ri480\sa120 \f16 Specializers are evaluated once, when a method is created. They are not reevaluated each time the method or containing generic function is called.\par \pard \s2\li480\ri480\sa120 Specializers will usually be module-variables or singleton specializers. However, they are not restricted to these forms. A specializer can be any expression that evaluates to a type. \par \pard \s2\li480\ri480\sa120 Dylan also allows a special syntax for {\b singleton specializers}, which is equivalent to explicitly using a singleton as a specializer:\par \pard\plain \s17\li480\ri480\sa120\tx3600 \f16 {\f22\fs20 (a :: ,\tab }{\fs20 Three required arguments.}{\f22\fs20 \line b :: ,\tab }{\fs20 The first must be a window, the second a character, }{\f22\fs20 \line c == 0)}{\fs20 \tab the third the integer 0.\par }\pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Keyword Parameters\par \pard\plain \s2\li480\ri480\sa120 \f16 When defining a method that includes keyword parameters, each keyword specifier must have one of the following forms:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 \tab }{\plain \i\f16 name}{\plain \f22 \par }{\plain \f16 or}{\plain \i\f16 \tab name}{\plain \f22 ( }{\plain \i\f16 default}{\plain \f22 )\par }{\plain \f16 or}{\plain \i\f16 \tab keyword parameter}{\plain \f22 \par }{\plain \f16 or\tab }{\plain \i\f16 keyword parameter}{\plain \f22 ( }{\plain \i\f16 default}{\plain \f22 )\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \par \pard\plain \s2\li480\ri480\sa120 \f16 In the first two forms, the {\i name} is used to indicate both the keyword and the parameter. In the last two forms, the keyword and parameter are given independentl y. The keyword is used when calling the method, and the parameter is used to refer to the value inside the body of the method. \par \pard \s2\li480\ri480\sa120 The {\i default} supplies a default value for the argument. It is used when the method is called and the keyword is not supplied. The {\i default} should be an expression. It is evaluated each time the method is called and the corresponding keyword argument is not supplied. If no {\i default} is specified, the parameter corresponding to an unsupplied keyword argument is initialized to {\f22 #f} . The {\i default} is evaluated in a scope that includes all the preceding parameters, including required parameters, the rest parameter (if any), the preceding keyword parameters, and the next-method parameter (if any).\par \pard \s2\li480\ri480\sa120\keepn For example:\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method percolate (#key brand (#"maxwell-house"),\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 cups (4),\par strength (#"strong"))\par make-coffee (brand, cups, strength);\par end method;\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method layout (widget, #key position: the-pos,\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 size: the-size)\par let the-sibling = sibling (widget);\par unless (the-pos = position (the-sibling))\par align-objects (widget, the-sibling, the-pos, the-size);\par end method;\par \par \pard\plain \s2\li480\ri480\sa120 \f16 These methods could be called as follows:\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 percolate (brand: #"folgers", cups: 10);\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 percolate (strength: #"weak",\par brand: #"tasters-choice",\par cups: 1);\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 layout (my-widget, position: point (10, 10),\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 size: point (30, 50));\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 layout (my-widget, size: query-user-for-size() );\par \pard\plain \s2\li480\ri480\sa120 \f16 The extended syntax for declaring keyword arguments (in which the keyword name and parameter name are given separately) is needed to allow keyword names such as {\f22 position:} without forcing the method to use { \f22 position} as a parameter name. If a method uses {\f22 position} as a parameter name, it cannot access the function stored in the module variable {\f22 position}. The lexical variable will shadow the module variable.\par \pard \s2\li480\ri480\sa120 All required arguments must be supplied before any keyword arguments can be supplied.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Result Values\par \pard\plain \s2\li480\ri480\sa120 \f16 Parameter lists may include value declarations, which must come at the end of the parameter list and are separated from the parameters by {\f22 =>}. A value declaration can be of the form {\i variable-name }{\f22 :: }{\i type-expression}, or just {\i variable-name }if the {\i type-expression }is {\f22 }, just like a required parameter. The result of evaluating the {\i type-expression } at the time the function is defined is a type, called a \ldblquote value type.\rdblquote The {\i variable-name } never comes into scope, so it is just there for documentation and for syntactic consistency with parame ters. It is valid for the same variable name to be used in both one parameter and one value declaration in the same parameter list; this is useful as documentation that a function returns one of its arguments, for example.\par \pard \s2\li480\ri480\sa120 The last value declaration can be preceded by {\f22 #rest} to indicate a variable number of values returned. A value declaration preceded by {\f22 #rest} is called a \ldblquote rest value declaration.\rdblquote A value declaration not preceded by {\f22 #rest} is called a \ldblquote required value declaration.\rdblquote The value type in a rest value declaration is the type of each one of the remaining individual values, not the type of a conceptual sequence of multiple values.\par \pard \s2\li480\ri480\sa120 If a parameter-list does not contain {\f22 =>}, it defaults to {\f22 => #rest x :: }, i.e. the function can return any number of values of any type.\par \pard \s2\li480\ri480\sa120\keepn A function must always return the number and types of values declared in its parameter-list. More precisely:\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab Each value returned by a function must be an instance of the corresponding value type, or else an error of type {\f22 } will be signalled.\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab If fewer values are returned by the function\rquote s body (or by the applicable method if the function is a generic function) than the number of required value declarations in the function\rquote s parameter-list, the missing values are defaulted to {\f22 #f} and returned. If {\f22 #f} is not an instance of the corresponding value type, an error of type {\f22 } will be signalled.\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab If a function does not have a rest value declaration, and more values are returned by the function\rquote s body (or by the appli cable method if the function is a generic function) than the number of required value declarations in the function\rquote s parameter-list, the extra values are discarded and not returned.\par \pard \s2\li480\ri480\sa120 Generic functions can have value declarations in the parameter list used in {\f22 define generic} . The values returned by the generic function will be instances of the value types. Rather than adding run-time checking to the generic function dispatch, the parameter list congruency rules are augmented to require each method added to t he generic function to have congruent value declarations. {\f22 add-method}, {\f22 define method}, {\f22 define class}, etc. signal an error if this requirement is violated.\par \pard \s2\li480\ri480\sa120 If a generic function is implicitly defined by {\f22 define method }or \line {\f22 define class}, it is not given any value declarations, so it defaults to{\f22 => #rest x :: } , which imposes no restrictions on its methods.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Parameter List Congruency\par \pard\plain \s2\li480\ri480\sa120 \f16 For any given generic function, the generic function and all methods for that function must have {\b congruent parameter lists}. Two parameter lists are congruent if they satisfy the following conditions:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 1.\tab They have the same number of required arguments.\par \pard \s21\fi-360\li840\ri480\sa160 2.\tab Each of the method\rquote s parameter specializers is a subtype of the corresponding parameter specializer of the generic function.\par \pard \s21\fi-360\li840\ri480\sa160 3. \tab Either\par \pard \s21\fi-360\li1800\ri480\sa160 \bullet \tab both accept keyword arguments,\par \bullet \tab both accept a variable number of arguments,\par \bullet \tab or both require a fixed number of arguments.\par \pard \s21\fi-360\li840\ri480\sa160 4. \tab If the generic function accepts keyword arguments, each method must recognize the mandatory keywords of the generic function.\par 5. \tab If a method accepts all keyword arguments, then the generic function must accept all keyword arguments.\par \pard \s21\fi-360\li840\ri480\sa160 6.\tab In addition, the value declarations must be congruent, defined as follows:\par \pard \s21\fi-360\li840\ri480\sa160 \tab If the generic function\rquote s parameter list does not contain a rest value declaration, then:\par \pard \s21\fi-400\li1800\ri480\sa160 \bullet \tab the method\rquote s parameter list must not contain a rest value declaration.\par \bullet \tab the two parameter lists must contain the same number of required value declarations.\par \pard \s21\fi-400\li1800\ri480\sa160 \bullet \tab each value type in the method\rquote s parameter list must be a subtype of the corresponding value type in the generic function\rquote s parameter list.\par \pard \s21\fi-360\li840\ri480\sa160 \tab If the generic function\rquote s parameter list contains a rest value declaration, then:\par \pard \s21\fi-360\li1800\ri480\sa160 \bullet \tab the method\rquote s parameter list is permitted, but not required, to contain a rest value declaration.\par \bullet \tab the method\rquote s parameter list must contain at least as many required value declarations as the generic function\rquote s parameter list.\par \pard \s21\fi-360\li1800\ri480\sa160 \bullet \tab each value type in the method\rquote s parameter list must be a subtype of the corresponding value type in the generic function\rquote s parameter list. If the method has a rest value type, it corresponds to the generic function\rquote s rest value type. If the method has more required value types than the generic function, the extra ones correspond to the generic function\rquote s rest value type.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Method Dispatch\par \pard\plain \s2\li480\ri480\sa120 \f16 When a generic function is called, the generic function uses the classes and identities of the arguments to determine which methods to call. This process is called method dispatch.\par Method dispatch occurs in three phases. First, all the applicable methods are selected. Next, the applicable methods are sorted by specificity. Then the most specific method is called.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Method specificity{\plain \f16\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } This section is similar to the approach taken in Craig Chambers' language Cecil (U. Washington). This approach is different from CLOS in that there is no referenc e to the lexicographic order of arguments when multimethods are sorted. See the examples for more detail on these differences.}}\par \pard\plain \s2\li480\ri480\sa120 \f16 This section covers how methods are sorted by specificity.\par \pard \s2\li480\ri480\sa120 For any two methods A and B that are applicable to a given generic function call, one method may be {\b more specific than} the other, or the methods may be {\b ambiguous methods}.\par \pard \s2\li480\ri480\sa120 To order two methods A and B with respect to a particular set of arguments, compare each of A\rquote s specializers with B\rquote s specializer in the corresponding position using the corresponding argument. The comparison works in the following way.\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab If the specializers are type equivalent, then A and B are unordered at the current argument position. That is, this argument position provides no information about the order of the two methods. \par \bullet \tab Otherwise, if the specializer of A is a subtype of the specializer of B, then A precedes B at the current argument position. Similarly, B precedes A at this position if B\rquote s specializer is a subtype of A\rquote s specializer.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab Otherwise, if both specializers are classes, then their order in the {\b class precedence list} of the argument\rquote s class is used to determine which is more specific. (See the next section, Computing the Class Precedence List, for more detail.) If A\rquote s specializer precedes B\rquote s specializer in the class precedence list of the argument\rquote s class, then A precedes B at the current argument position. Similarly, B precedes A at this position if B\rquote s specializer precedes A\rquote s in the class precedence list of the argument\rquote s class.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab Otherwise, the methods are ambiguous methods.\par \pard\plain \s2\li480\ri480\sa120 \f16 The method A is more specific than the method B if and only if A precedes B or is unordered with respect to B in all required argument positions, and precedes B in at least one argument position. Similarly, B is more specific than A if and only if B prece des A or is unordered with respect to A in all required argument positions, and precedes A in at least one argument position. If neither of these cases apply, i.e. neither method is more specific than the other, then A and B are ambiguous methods.\par \pard \s2\li480\ri480\sa120 When the applicable methods are sorted by specificity, the sorted list is divided into two parts, each possibly empty. The first part contains methods that are more specific than every method that follows them. The second part (which cannot be sorted its elf) begins at the first point of ambiguity; there are at least two methods that could equally well go first in the second part. If the first part is empty, generic function dispatch signals an \ldblquote ambiguous method\rdblquote error. If the last method in the first part calls {\f22 next-method}, the call signals an \ldblquote ambiguous next method\rdblquote error.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Examples of method specificity\par \pard\plain \s2\li480\ri480\sa120 \f16 Consider the following class definitions\par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class () ... end class;\par define class () ... end class;\par define class () ... end class;\par define class () ... end class;\par define class (, ) ... end class;\par \pard\plain \li720\ri480 \f16 \par \pard\plain \s2\li480\ri480\sa120 \f16 which form the class relationships shown in the following graph:\par \pard\plain \qc\li720\ri480 \f16 {{\pict\macpict\picw162\pich102 018c00000000005e00a2001102ff0c00ffffffff000000000000000000a20000005e00000000000000a10064000c574f524400000000005e00a200a10096000c010000000100000000000000001e0001000a00000000005e00a2002c000a001607436f757269657200030016000d000a002e0004000000000010005e00a200 5e00a2002b3a58083c76756c63616e3e0000a0009700a10096000c0100000001000000000000000028003d00040d3c696e74656c6c6967656e743e00a0009700a10096000c0100000001000000000000000028003c00620a3c68756d616e6f69643e0000a0009700a10096000c0100000001000000000000000028000c0032 0b3c6c6966652d666f726d3e00a0009700a10096000c010000000100000000000000002b2e19093c6269706564616c3e00a0009700a10096000c01000000010000000000000000280025000c0a3c73656e7469656e743e0000a0009700220010004be90a0022000e0058180d002200280077010a002200280029010b002200 43002c250a0022004d00561df200ff}} \par \pard\plain \s2\li480\ri480\sa120 \f16 Computing the class precedence list for {\f22\fs20 }yields {\f22\fs20 \par }\pard\plain \s25\li720\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 (,,,,,)\par \pard \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \par \pard\plain \s2\li480\ri480\sa120 \f16 In this class precedence list, note that classes in the simple superclass chains {\f22 (,) }and {\f22 (,) }are kept adjacent.\par \pard \s2\li480\ri480\sa120 The class precedence lists computed for two different classes may have different precedence orders for some intermediate superclasses. This is not a problem as long as there is no clas s which inherits from both classes. For example, we could define a class {\f22 }as follows:\par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class (, ) ... end class;\par \par \pard\plain \s2\li480\ri480\sa120 \f16 For the class {\f22 }defined as above, the class precedence list would be {\f22\fs20 \par }\pard \s2\li480\ri480\sa120 {\f22\fs20 (,,,,,)}\par \pard \s2\li480\ri480\sa120 It is not a problem that the two class precedence lists give different orders to some of the intermediate superclasses such as {\f22 }and {\f22 } as long as no class is added which inherits from both {\f22 } and {\f22 }.\par \pard \s2\li480\ri480\sa120 When sorting the applicable methods, each specializer pair needs to be compared with respect to the class precedence list for the class of the argument passed to the generic function in that argument position, because the class precedence list might be dif ferent depending on which class it was computed from. For example, given the following definitions\par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class (, ) end class;\par define class (, ) end class;\par define method psychoanalyze (being :: ) ... \par end method;\par define method psychoanalyze (being :: ) ... \par end method;\par \par \pard\plain \s2\li480\ri480\sa120 \f16 calling the generic function {\f22 psychoanalyze }on a being of type {\f22 } would cause the method for {\f22 } to be called first, while calling the generic function on a being of type {\f22 } would cause the method for {\f22 } to be called first.\par \pard \s2\li480\ri480\sa120 There is no reference to lexicographic order in sorting multimethods.{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } This is a difference from CLOS. Under the CLOS system, the example would work as follows: when {\f22 superior-being }is called on a being of type {\f22 } and a being of type {\f22 }, the {\f22 best-looking-being} is chosen when the {\f22 }is the first argument, and the {\f22 most-intelligent-being} is chosen when the {\f22 }is the first argument.}} Given the above class definitions, the following methods are unambiguous when {\f22 superior-being } is called on two beings of type {\f22 }or two beings of type {\f22 }, but the methods are ambiguous when {\f22 superior-being }is called on a being of type {\f22 }and a being of type {\f22 } (because it is ambiguous whether to choose the {\f22 most-intelligent-being}, or the {\f22 best-looking-being}):\par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method superior-being (a :: ,\par b :: ) \par most-intelligent-being (a, b)\par end method;\par \par define method superior-being (a :: ,\par b :: )\par best-looking-being (a, b)\par end method;\par \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Computing the Class Precedence List{\plain \f16\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }This section is intended to present the same alg orithm as in CLOS.}}\par \pard\plain \s2\li480\ri480\sa120 \f16 The definition of a class specifies a total ordering on that class and its direct superclasses. This ordering is called the {\b local precedence order} . In the local precedence order, the class precedes its direct superclasses, and each direct superclass precedes all other direct superclasses following it in the sequence of direct superclasses of the class definition.\par \pard \s2\li480\ri480\sa120 The {\b class precedence list} for a class C is a total ordering on C and its superclasses that is consistent with the local precedence orders for each of C and its superclasses. \par \pard \s2\li480\ri480\sa120 Sometimes there are several possible total orderings on C and its superclasses that are consistent with the local precedence orders for each of C and its superclasses. Dylan uses a deterministic algorithm to compute the class precedence list, which choose s one of the possible total orderings. The algorithm has the effect that the classes in a simple superclass chain are adjacent in the class precedence list, and classes in each relatively separated subgraph are adjacent in the class precedence list. \par \pard \s2\li480\ri480\sa120 Sometimes there is no possible total ordering on C and its superclasses that is consistent with the local precedence orders for each of C and its superclasses. In this case, the class precedence list cannot be computed, and Dylan signals an error.\par \pard \s2\li480\ri480\sa120 To compute the class precedence list:\par Let S be the set of C and all of its superclasses. \par For each class c in S, let\par \tab R{\fs20\dn4 c} = \{(c, c{\fs20\dn4 1}), (c{\fs20\dn4 1}, c{\fs20\dn4 2}), .... , (c{\fs20\dn4 n-1}, c{\fs20\dn4 n})\}\par \pard \s2\li480\ri480\sa120 where c{\fs20\dn4 1} ,..., c{\fs20\dn4 n} are the direct superclasses of c in the order in which they are mentioned in the class definition for c.\par \pard \s2\li480\ri480\sa120 Let R be the union of all R{\fs20\dn4 c} for every class c in S. The set R might or might not generate a partial ordering, depending on whether the R{\fs20\dn4 c} are consistent; it is assumed that they are consistent and that R generates a partial ordering. When the R{\fs20\dn4 c} are not consistent, it is said that R is inconsistent.\par \pard \s2\li480\ri480\sa120 To compute the class precedence list for C, topologically sort C and its superclasses with respect to R. Topological sorting proceeds in the following way:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 1.\tab Find a class N in S such that no other class precedes N according to the elements in R. \par \pard \s21\fi-360\li840\ri480\sa160 \tab If there are several classes from S with no predecessors, select the one that has a direct subclass rightmost in the partial class precedence list computed so far. In more precise terms, let \{N{\fs20\dn4 1},...N{ \fs20\dn4 m}\}, m\'b32, be the classes from S with no predecessors. Let (C{\fs20\dn4 1},...,C{\fs20\dn4 n}), n\'b31, be the partial class precedence list computed so far. C{\fs20\dn4 1} is the most specific class, and C{\fs20\dn4 n} is the least specific. Let 1\'b2j\'b2n be the largest number such that there exists an i where 1\'b2i\'b2m and N{\fs20\dn4 i} is a direct superclass of C{\fs20\dn4 j}. Select N{\fs20\dn4 i}.\par \pard \s21\fi-360\li840\ri480\sa160 2.\tab Place N first in the result. Remove N from S, and remove all pairs of the form (N, M), such that M is an element of S, from R.\par 3.\tab Repeat the process, adding classes with no predecessors to the end of the result. Stop when no element can be found that has no predecessor.\par \pard\plain \s2\li480\ri480\sa120 \f16 If S is not empty and the process has stopped, R is inconsistent because it contains a loop. That is, there is a chain of classes C{\fs20\dn4 1},....,C{\fs20\dn4 n} in S such that C{\fs20\dn4 i }precedes C{ \fs20\dn4 i+1}, 1\'b2i} prints out a notice and then calls {\f22 next-method}, which invokes the next most specific method, in this case the method for {\f22 }.{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }Another way to think of {\f22 next-method} is that it invokes the method that would have been invoked if the current method did not exist.}}\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define method double (num :: )\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 print("doubling a floating-point number")\par next-method()\par end method;\par {\i \par ?} double(10.5)\par {\i doubling a floating-point number\par }\pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 21.0}\par \pard\plain \s2\li480\ri480\sa120 \f16 If there are no more methods available, the next-method parameter will be bound to the value {\f22 #f} instead of to a method.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Passing Different Arguments to Next-Method\par \pard\plain \s2\li480\ri480\sa120 \f16 In the usual case, {\f22 next-method} is called with no arguments. This indicates that the next-method should be passed the same arguments that were supplied to the current method.\par \pard \s2\li480\ri480\sa120 It is valid to supply arguments, including different arguments, when calling next-method. However, if you pass different arguments, the new arguments must result in the same ordered sequence of applicable methods, in the same order, as the original argume nts. Otherwise, the behavior of Dylan is undefined.\par In some cases, the methods in a generic function accept different keyword arguments. In such cases, it\rquote s convenient for the methods also to accept a rest parameter. That way, {\i all} the non-required arguments to the generic function are captured in the rest parameter. By using {\f22 apply}, the next-method can be invoked with the complete set of arguments.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 The Next-Method Parameter\par \pard\plain \s2\li480\ri480\sa120 \f16 The next-method parameter is passed behind the scenes. When a method is called by its generic function, the generic function dispatch mechanism automatically passes the appropriate value for next-method. There is no way for a user program to s pecify the next-method argument when calling a method.\par \pard \s2\li480\ri480\sa120 If you create a method directly (i.e., with {\f22 method} rather than with {\f22 define method}) and you want this method to accept a next-method parameter, then you should insert a {\f22 #next} into the parameter list explicitly. You would do this if you are creating a method that you plan to add to a generic function, and you want this method to be able to call next-method. You can also supply the next-method parameter when using {\f22 define method}, in cases where you want to give the parameter a different name.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Reflective Operations on Functions\par \pard\plain \s2\li480\ri480\sa120 \f16 The following functions don\rquote t need to be called in routine programming, but are useful for implementation of the language and in the construction of the programming environment.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 generic-function-methods} {\i generic-function}\tab [Function]\line {\f23 \'de}{\i sequence}\tab \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 generic-function-methods} returns a sequence of all of the methods in {\i generic-function}. The order of the methods in the sequence is not significant.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }A method may be removed from a generic function if it is proved that it will never be called. This will be the case if any of the objects on which the method specializes are garbage collected.}} \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 If {\i generic-function} is sealed, an implementation may choose not to return a sequence of methods, but instead signal an error of type {\f22 }.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 add-method} {\i generic-function method} \tab [Function]\line {\f23 \'de}{\i new-method old-method\par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 add-method} adds {\i method} to {\i generic-function}. This operation modifies the generic function object.\par In general, you do not need to call {\f22 add-method} directly. It is called by {\f22 define method}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 If you add a method to a generic function, and the generic function already has a method with the exact same specializers, then the old method is replaced with the new one.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 A single method may be added to any number of generic functions.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\f22 add-method} returns two values. The first is the new {\i method}. The second will be either the method in {\i generic-function} which is being replaced by {\i method}, or it will be {\f22 #f} , if no method is being replaced.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 generic-function-mandatory-keywords }{\i generic-function}\tab [Function]\par \pard\plain \li540\ri480 \f16 If {\i generic-function} accepts keyword arguments, returns a collection of the mandatory keywords for {\i generic-function.} Returns {\f22 #f} if {\i generic-function }does not accept keyword arguments.\par \pard \li540\ri480 \par \pard \li540\ri480 The collection returned should never be destructively modified. Doing so may cause unpredictable behavior.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 function-specializers} {\i function} {\f23 \'de}{\i\f23 }{\i sequence}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 function-specializers} returns a sequence of the specializers for {\i function}. The length of the sequence will equal the number of required arguments of {\i function} . The first element of the sequence will be the specializer of the first argument of {\i function}, the second will be the specializer of the second argument, etc.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 function-arguments} {\i function}\tab [Function]\line {\f23 \'de}{\i\f23 }{\i required-number rest-boolean kwd-sequence}\par \pard\plain \li340\ri720 \f16 {\f22 function-arguments} returns three values:\par \pard \li480\ri720 \par \pard \fi-360\li720\ri720 1.\tab The number of required arguments accepted by the function.\par \pard \fi-360\li720\ri720 2.\tab A boolean that indicates whether the function accepts a variable number of arguments.\par \pard \fi-360\li720\ri720 3.\tab If the value is {\f22 #f} then the function does not accept keyword arguments. Otherwise, the function does accept keyword arguments, and the value is either a collection of the keywords which are permissible for any call to the function, or the symbol {\f22 all} if all keywords are permitted by the function.\par \pard \fi-360\li720\ri720 \par \pard \li360\ri720 Note that particular calls to a generic function may accept additional keywords not included in the third value returned by {\f22 function-arguments}, by virtue of their being recognized by applicable methods.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 applicable-method?} {\i function }{\f22 #rest} {\i sample-arguments} \tab [Function]\line {\f23 \'de}{\i boolean}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 applicable-method?} returns true if {\i function} is a method or contains a method that would be applicable for {\i sample-arguments}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 sorted-applicable-methods} {\i \tab }[Function]\line {\i generic-function }{\f22 #rest} {\i sample-arguments \line }{\f23 \'de}{\i sequence1 sequence2\par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 sorted-applicable-methods} returns two sequences that, taken together, contain the methods in {\i generic-function} that are applicable for the {\i sample-arguments}. {\i sequence1} contains methods that are more specific than every method that follows them. {\i sequence2} (which cannot be sorted itself) begins at the first point of ambiguity; there are at least two methods that could equally well go first in {\i sequence2}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The sequences returned should never be destructively modified. Doing so may cause unpredictable behavior.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 find-method} {\i generic-function specializer-list} \tab [Function]\line {\f23 \'de}{\i \{method }{\i\fs16 or}{\i }{\f22 #f}{\i \}}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 find-method} returns the method in {\i generic-function} that has the specializers in {\i specializer-list} as its specializers. The specializers must match exactly for a method to be returned. If {\i generic-function} is sealed, an implementation may choose to signal an error of type {\f22 } (instead of returning any value at all) .\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove-method} {\i generic-function method} {\f23 \'de}{\i method}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 remove-method} removes {\i method} from {\i generic-function} and returns {\i method}. {\f22 remove-method} will signal an error if {\i method} is not in {\i generic-function}. If {\i generic-function} is sealed, or if {\i method} is a sealed method of {\i generic-function} , then an error of type {\f22 } is signaled.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 The classes , , and \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 } is the class of all objects that can be applied to arguments. It is the superclass of generic functions and methods. {\f22 } inherits from {\f22 }.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 } is the class of functions which contain methods. Generic functions inherit from {\f22 }.\par \pard \s2\li480\ri480\sa120 The class {\f22 } supports the following init-keywords:\par \pard\plain \fi-1080\li1440\ri720 \f16 {\f22 required:} {\i number-or-sequence}\par \pard \fi-1080\li1440\ri720 \tab This represents the required arguments that the generic function accepts. If a sequence is supplied, the size of the sequence is the number of required arguments, and the elements of the sequence are the specializers. If a number is supplied, it is the number of required arguments, and the specializers default to {\f22 }. If the argument is not supplied, or the supplied argument is neither a sequence nor a non-negative integer, an error is signaled.\par \pard \fi-1080\li1440\ri720 \par {\f22 rest?:} {\i boolean} \par \pard \fi-1080\li1440\ri720 \tab A true value indicates that the generic function accepts a variable number of arguments. The default is {\f22 #f}.\par \pard \fi-1080\li1440\ri720 {\b \par }{\f22 key:} {\i collection-of-keywords-or-#f . \par }\pard \fi-1080\li1440\ri720 \tab If the value is a collection, then the generic function accepts keyword arguments, and the collection specifies the set of mandatory keywords for the generic function. A value of {\f22 #f} indicates that the generic function does not accept keyword arguments. The default is {\f22 #f}.\par \pard \fi-1080\li1440\ri720 \par \pard \fi-1080\li1440\ri720\keepn {\f22 all-keys?:}{\b }{\i boolean\par }\pard \fi-1080\li1440\ri720 \tab A true value indicates that the generic function accepts all keyword arguments. The default is {\f22 #f.}{\f22\fs20 \par }\pard \fi-1080\li1440\ri720 \par \pard\plain \s2\li480\ri480\sa120 \f16 An error is signaled if the value of {\f22 rest?:} is true and the value of {\f22 key:} is a collection.\par An error is signaled if the value of {\f22 all-keys?:} is true and the value of {\f22 key:} is {\f22 #f}. \par \pard \s2\li480\ri480\sa120 The new generic function initially has no methods. An error will be signaled if the generic function is called before methods are added to it. Once a generic function is created, you can give it behavior by adding methods to it with {\f22 add\_method} or {\f22 define method}.\par \pard \s2\li480\ri480\sa120 Generic functions are not usually created directly. Most often they are created by {\f22 define generic} or indirectly by {\f22 define method}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Methods inherit from {\f22 }.\par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 7. Classes\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Introduction\par \pard\plain \s2\li480\ri480\sa120 \f16 Classes are used to categorize Dylan objects. Classes specify the structure of their instances. In concert with methods, classes help determine the behavior of their instances. Every object is a direct instance of exactly one class.\par \pard \s2\li480\ri480\sa120 A class determines which {\b slots} its instances have. Slots are the local storage available within instances. They are used to store the state of objects. \par \pard \s2\li480\ri480\sa120 A class also helps determine the behavior of its instances. When an object is passed as an argument to a generic function, the generic function looks at the class (and perhaps identity) of the object to determine which method should be run.\par \pard \s2\li480\ri480\sa120 Singletons are specializers used to indicate an individual object. A singleton for an object is created by passing the object to the function {\f22 singleton}. Singletons are used to cu stomize the behavior of individual objects. Singletons can be used for specialization, like classes, but the specialization will only apply to the singleton object. When determining whether a method is applicable for a set of arguments, an argument with a singleton specializer must be {\f22 ==} to the object used to create the singleton.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Slots and slot access\par \pard\plain \s2\li480\ri480\sa120 \f16 Slots correspond to the {\i fields} or {\i instance variables} of other object-oriented programming languages. For most slots, each instance of the class has privat e storage for the slot, so one instance can have one value in the slot and another instance can have another value.\par \pard \s2\li480\ri480\sa120 Dylan follows the lead of some newer object-oriented languages by always accessing slots through function calls, rather than variable references.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }For example, Self, and to some degree, CLOS.}} In Dylan, slots are accessed through methods. The method that returns the value of a slot is called the {\b getter method}, and the method that sets the value of a slot is called the {\b setter method}. The getter and setter methods are added to generic functions. When defining a class, you specify slots by specifying to which generic functions the getter and setter methods should be added.\par \pard \s2\li480\ri480\sa120 \par For example, the class definition for {\f22 } might be\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class ()\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 slot horizontal;\par slot vertical;\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 end class;\par \pard\plain \s2\li480\ri480\sa120 \f16 This definition indicates that instances of {\f22 } should have two slots, {\f22 horizontal} and {\f22 vertical}. The getter method for the first slot is added to the generic function {\f22 horizontal} , and the getter method for the second slot is added to the generic function {\f22 vertical}. The setter method for the first slot is added to the generic function {\f22 horizontal-setter} , while the setter method for the second slot is added to the generic function {\f22 vertical-setter.}\par \pard \s2\li480\ri480\sa120 To get the horizontal coordinate of a point, make the call\par \pard\plain \s22\li960\ri480\sb120\sa240\keepn\tx2880\tx4800\tx6720 \f22\fs20 horizontal(my-point)\par \pard\plain \s2\li480\ri480\sa120 \f16 To set the horizontal coordinate to 10, use the corresponding setter function:\par \pard\plain \s22\li960\ri480\sb120\sa240\keepn\tx2880\tx4800\tx6720 \f22\fs20 horizontal-setter(10, my-point)\par \pard\plain \s2\li480\ri480\sa120 \f16 or\par \pard\plain \s22\li960\ri480\sb120\sa240\keepn\tx2880\tx4800\tx6720 \f22\fs20 horizontal(my-point) := 10;\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Singleton types\par \pard\plain \s2\li480\ri480\sa120 \f16 Singletons provide a way to add methods to single instances. This lets programs specialize a single object, without changing other objects of the same class, and without defining a whole new class just for the object.\par \pard \s2\li480\ri480\sa120 A singleton is a type, but it is not a class. It is little more than a pointer to a single object. The singleton\rquote s sole purpose is to indicate that object, so that a method can be created that specializes on the object. By defining a method that specializes on a singleton (rather than on a class), you have defined a method that discriminates on the singleton \rquote s object.\par \pard \s2\li480\ri480\sa120 Singleton methods are considered more specific than methods defined on an object\rquote s original class. Singletons are the most specific specializer.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define method double (thing :: singleton(#"cup"))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 #"pint"\par end method\par {\i \par ?} double (#"cup")\par {\i #"pint"\par ?} double (10)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 20}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Dylan provides a shorthand for singletons used as method specializers. The folowing definition is equivalent to the one above.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define method double (thing == #"cup")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 #"pint"\par end method\par {\i \par ?} double (#"cup")\par {\i #"pint"\par }\pard\plain \s22\li960\ri480\sb120\sa240\keepn\tx2880\tx4800\tx6720 \f22\fs20 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Defining New Classes\par \pard\plain \s2\li480\ri480\sa120 \f16 The {\f22 double} example given in the Functions chapter showed how to define methods for classes that already exist. A large portion of Dylan programming consists of defining new classes. New classes are created with {\f22 define class}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 define }[{\i adjectives} ] {\b\f22 class }{\i class-name} {\f22 (}{\i superclasses })\tab [Definition]\line {\i slot-spec}{\i\fs18\dn4 1} {\f22 ; } {\i slot-spec}{\i\fs18\dn4 2 }{\fs18\dn4 }\'c9\par \pard\plain \s10\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 {\f22 }{\b\f22 end} [{\b\f22 class}] [{\i class-name}]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 define class} is used to create classes. {\f22 define class} defines the module variable {\i class-name} and creates a class to store in the variable. The variable is made read\endash only.\par The {\i adjectives} are words that describe features of the class. The permitted adjectives are {\f22 sealed}, {\f22 open}, {\f22 primary}, {\f22 free}, {\f22 abstract}, and {\f22 concrete}. See the Controlling Dynamism chapter for more information. \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The new class inherits from the {\i superclass} es, which is a sequence of expressions separated by commas which evaluate to classes. The elements of the list are evaluated. The list cannot contain duplicates, and the class heterarchy cannot be circular\emdash that is, a c lass cannot be its own direct or indirect superclass. At least one superclass must be specified.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 In addition to inheriting slots from its superclasses, the new class is given a slot for each of the {\i slot-spec} arguments. In the simplest format, a slot-spec is just:\par \pard \s11\li480\ri480\sa120\tx1080\tqr\tx8640\tqr\tx9360 \tab {\f22 slot }{\i variable-name} \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 A getter method is defined on the generic function {\i name}, and a setter function is defined on the generic function {\i\f22 name}{\f22 -setter} . The full syntax for slot-specs is given in the Slot Options section below. The full syntax allows many more options when defining slots.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The following definition creates a new class and stores it in the module variable {\f22 }. Instances of the class will have two slots. The first slot is read with the generic function {\f22 title} and set with the generic function {\f22 title-setter}. The second slot is read with the generic function {\f22 action} and set with the generic function {\f22 action-setter}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i }define class ()\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 slot title;\par slot action;\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 end class;\par \pard\plain \s2\li480\ri480\sa120 \f16 The creation and initialization of instances is controlled by the generic functions {\f22 initialize} and {\f22 make}. See the section on instance creation for more details.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Slot Uniqueness\par \pard\plain \s2\li480\ri480\sa120 \f16 The collection of all the getter and setter generic functions for slots specified in a class or inherited from its superclasses must not contain any duplicates. This implies that an inherited slot cannot be overridden.\par \pard \s2\li480\ri480\sa120 If a superclass is inherited through multiple paths, its slots are only counted once. For example, if class A has direct superclasses B and C, and both B and C hav e D as a direct superclass, A inherits from D both through B and through C, but D\rquote s slots are only counted once so this multiple inheritance does not by itself create any duplicates among the getters and setters.\par Note that if two classes each specify a slot and the two slots have the same getter and/or setter generic function, these two classes are {\i disjoint }\emdash they can never have a common subclass and no object can be an instance of both classes. The same is true if one slot\rquote s getter function is the other slot\rquote s setter function (this would also cause a parameter list congruency error).\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Slot Options\par \pard\plain \li480\ri480 \f16 There are three kinds of {\i slot-specs} that are allowed in class definitions. These are {\b slot specifications}, {\b initialization argument specifications}, and {\b inherited slot specifications.\par }\pard \li480\ri480 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Slot Specifications \par \pard\plain \s2\li480\ri480\sa120 \f16 A slot specification describes a slot.\par The syntax of a slot specification is as follows:\par \pard\plain \fi-340\li700\ri480 \f16 \tab [ {\i adjectives} ] [ {\i allocation} ] {\f22 slot} {\i getter-name} [{\f22 ::} {\i type} ] {\f22 #key }{\i setter init-keyword required-init-keyword init-value init-function\par }\pard \fi-340\li700\ri480 \par \pard\plain \s2\li480\ri480\sa120 \f16 {\i getter-name }specifies the getter name for the slot. It must be a variable name.\par \pard \s2\li480\ri480\sa120 The {\i adjectives} are words separated by spaces. Currently, the allowed {\i adjectives} are {\f22 open} and {\f22 sealed}. These {\i adjectives} control the level of dynamism of the getter, and (if present) the setter for this slot. See the Controlling Dynamism chapter for more details.\par \pard \s2\li480\ri480\sa120 {\i allocation} controls the allocation of the slot. See the Specifying Allocation section for details.\par \pard \s2\li480\ri480\sa120 The keywords {\i setter}, {\i init-keyword}, {\i init-value}, and {\i init-function} respectively specify a setter name, an init-keyword, and (if the allocation is not {\f22 virtual}) a default value specified with {\f22 init-value:} or {\f22 init-function:}. See the Keywords Allowed in Slot Specs section for more detail.\par \pard \s2\li480\ri480\sa120 If there is an init-keyword specified with {\f22 init-keyword:} or {\f22 required-init-keyword:}, the slot is said to be {\b\i keyword initializable}{\b } \par The following example defines a class with two keyword initializable slots accessed by the generic functions {\f22 bar-x} and {\f22 bar-y}. \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class ()\par slot bar-x, init-keyword: x:;\par slot bar-y, init-keyword: y:;\par end class ;\par \par \pard\plain \s2\li480\ri480\sa120 \f16 In this example, the call {\f22 make (, x: 2, y: 3)} will make an instance in which these slots are initialized to {\f22 2} and {\f22 3} respectively; the call {\f22 make ()} will make in instance in which these slots are not initialized (attempting to get the values by calling the getter functions signals an error).\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Initialization Argument Specifications\par \pard\plain \s2\li480\ri480\sa120 \f16 An initialization argument specification does not describe a slot; it describes how a particular initialization argument is to be handled. It allows the type of the initialization argument to be restricted, it allows the initialization argument to be declared to be required, and it allows the specification of a default value for an initi alization argument which is not required.\par \pard \s2\li480\ri480\sa120 There are two kinds of initialization argument specifications: required initialization argument specifications, and optional initialization argument specifications.\par \pard \s2\li480\ri480\sa120 A required initialization argument specification has the form\par \pard\plain \fi-340\li700\ri480 \f16 \tab {\f22 required keyword }{\i keyword }{\f22 #key }{\i type\par }\pard \fi-340\li700\ri480 {\f22 \par }\pard\plain \s2\li480\ri480\sa120 \f16 A required initialization argument specification asserts that the initialization argument is required in a call to {\f22 make} \emdash the default {\f22 make} method will signal an error if no such initialization argument is supplied.\par \pard \s2\li480\ri480\sa120 An optional initialization argument specification has the form\par \pard\plain \fi-340\li700\ri480 \f16 \tab {\f22 keyword }{\i keyword }{\f22 #key }{\i type init-value init-function\par }\pard \fi-340\li700\ri480 {\f22 \par }\pard\plain \s2\li480\ri480\sa120 \f16 An optional initialization argument specification can be used to specify a default value for the initialization argument. When a call to make does not specify the keyword, the default value is used by the default { \f22 make} method in computing the {\i defaulted initialization arguments ,} and indirectly to initialize a slot. (See the next section on slot initialization for more details.)\par \pard \s2\li480\ri480\sa120 The type argument has the same meaning in both kinds of initialization argument specification: It restricts the type of that initialization argument. (Note that this is not the same thing as restricting the type of the slot.) \par \pard \s2\li480\ri480\sa120 The following example defines a class similar to the previous example class {\f22 }, but with modified initialization behavior.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class ()\par required keyword x:;\par keyword y:, init-value: #t;\par end class ;\par \par \pard\plain \s2\li480\ri480\sa120 \f16 The {\f22 x:} initialization argument is specified as being required: {\f22 make} will signal an error if an {\f22 x:} keyword argument is not supplied. The {\f22 y:} initialization argument , and consequently the initial value for the {\f22 bar-y} slot, now defaults to {\f22 #t} if not specified in the call to {\f22 make}.\par \pard \s2\li480\ri480\sa120 More than one keyword initializable slot may be initialized from the same initialization argument (i.e., more than one keyword initializable slot may specify the same init-keyword). However, an error is signaled if a single { \f22 define-class} form has more than one initialization argument specification for the same keyword. An error will also be signaled if a single {\f22 define-class} form has keyword initializable slots which specify {\f22 init-value:} or {\f22 init-function:} and an initialization argument specification for the same keyword which either requires a value ({\f22 required-init-keyword:}) or provides a default value with {\f22 init-value:} or {\f22 init-function:} \emdash i.e., the initial value specification for the slot can never be used.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Inherited Slot Specifications\par \pard\plain \li480\ri480 \f16 An inherited slot specification specifies a getter generic function, and optionally an {\f22 init-value:} or {\f22 init-function:} slot option, but not both.\par \pard \li480\ri480 \par The syntax of an inherited slot specification is as follows:\par \par {\f22 inherited slot }{\i getter-name}{\f22 #key }{\i init-value init-function}\par \par \pard \li480\ri480 {\i getter-name} identifies the slot. It must be a variable name. A superclass of the class being defined must specify a slot with the same getter.\par \pard \li480\ri480 \par \pard \li480\ri480 If neither {\f22 init-value:} nor {\f22 init-function:} is specified, the only function of the inherited slot specification is to require that some superclass of the class being defined specify a slot with the same getter. It could also be useful as documentation, perhaps. Because the {\f22 init-value:} and {\f22 init-function:} slot options are not allowed for virtual slots, this is the only valid form of inherited slot specification for virtual slots.\par \pard \li480\ri480 \par \pard \li480\ri480 If either {\f22 init-value:} or {\f22 init-function:} is specified, the superclass's slot's {\f22 init-value:} and {\f22 init-function:} slot options are ignored and the options in the inherited specification are used instead. This allows the {\f22 init-value:} and {\f22 init-function:} slot-options of an inherited slot to be replaced in a subclass so the default initial value of the slot can be changed.\par \pard \li480\ri480 \par \pard \li720\ri480 {\f22\fs20 define class ()\par slot n-legs, init-value: 4;\par end class;\par \par define class ()\par inherited slot n-legs, init-value: 8;\par end class;\par }\pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Specifying Allocation\par \pard\plain \s2\li480\ri480\sa120 \f16 {\i allocation} in a slot specification specifies how storage for the slot is allocated. {\i allocation} should be one of the symbols {\f22 instance}, {\f22 class}, {\f22 each-subclass}, {\f22 virtual}, or {\f22 constant}, or it may be an implementation-dependent value. This argument is not evaluated.\par \pard\plain \s20\fi-2340\li2880\ri480\sa160 \f16 {\b\f22 instance}\tab Indicates that each instance gets its own storage for the slot. This is the default.\par \pard \s20\fi-2340\li2880\ri480\sa160 {\b\f22 class}\tab Indicates there is only one storage location used by all the direct and indirect instances of the class. All the instances share a single value for the slot. If the value is changed in one instance, all the instances see the new value.\par \pard \s20\fi-2340\li2880\ri480\sa160 {\b\f22 each-subclass}\tab Indicates that the class gets one storage location for the slot, to be used by all the direct instances of the class. In addition, every subclass of the class gets a storage location for the slot, for use by its direct instances.\par \pard \s20\fi-2340\li2880\ri480\sa160 {\b\f22 constant}\tab Indicates a constant value for the slot. There will be no setter method. The value of the slot must be specified as an init-value.\par \pard \s20\fi-2340\li2880\ri480\sa160 {\b\f22 virtual}\tab Indicates that no storage will be automatically allocated for the slot. If allocation is {\f22 virtual} , then it is up to the programmer to define methods on the getter and setter generic functions to retrieve and store the value of the slot. Dylan will ensure the existence of generic functions for any specified getter and setter but will not add any metho ds to them. \par \pard\plain \s2\li480\ri480\sa120 \f16 The values of virtual slots are not automatically initialized when a new instance is created. The programmer must perform any necessary initialization. This would usually be done inside a method on {\f22 initialize }. Because the values of virtual slots are often computed from other values at run-time, many virtual slots will not require any explicit initialization.\par \pard \s2\li480\ri480\sa120 To support the {\f22 slot-initialized?} protocol in a virtual slot, programmers must define a method for {\f22 slot-initialized?} that shares a protocol with the getter method for the slot.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Keywords allowed in slot-specs\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Each keyword can be specified no more than once and must be followed by a value. Implementations may add additional keyword arguments.\par \pard\plain \s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 {\b\f22 setter}{\f22 :}\tab The name of a module variable to which the setter method should be added, or {\f22 #f} if no setter method should be defined. This argument is not evaluated. If it is not supplied, it will default to the symbol whose name is the concatenation of {\i getter-name} and "-setter", unless the allocation of the slot is {\f22 constant} in which case it defaults to {\f22 #f}.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 type:}\tab Should be a type specifier that limits the types of values that can be stored in the slot. This type specification is enforced by the low-level slot storage mechanisms. It is not enforced for virtual slots, which do not use the low-level slot storage mechanisms.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 \tab This argument defaults to {\f22 } , which allows any object to be stored in the slot. The argument is evaluated once, after the variable containing the class is defined and before the slot is first added to an instance.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 init-value:}{\f22 \tab }Supplies a default initial value for the slot. The argument is evaluated once, afte r the variable containing the class is defined and before the slot is first added to an instance. The resultant value is used as the initial value when an instance is created. If you want to create a new value for every instance, you should supply an { \f22 init-function:} rather than an {\f22 init-value:}. There is no default value for this argument. \par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\f22 \tab init-value:} may not be specified with {\f22 init\_function:}. \par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 init-function:}{\f22 \tab }Should be a function of no arguments. It will be called to generate an initial value for the slot when a new instance is created. There is no default value for this argument. The argument is evaluated once, after the variable containing the class is defined and before the slot is first added to an instance.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 \tab {\f22 init-function:} may not be specified with {\f22 init\_value:}. \par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 init-keyword:}{\f22 \tab }Should be a keyword. It permits an initial value for the slot to be passed to {\f22 make}, as a keyword argument using this keyword. For use, see \ldblquote Slot Initialization,\rdblquote below. This argument is not evaluated.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 \tab There is no default for the {\f22 init-keyword:} argument. If none is specified, there will be no init-keyword for the slot.\par {\f22 \tab init-keyword:} and {\f22 required-init-keyword:} cannot both be specified for a single slot.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b\f22 required-init-keyword:}{\f22 \line }Like {\f22 init-keyword:}, except it indicates an init-keyword that must be provided when the class is instantiated. If {\f22 make} is called on the class and a required init-keyword is not provided, an error is signaled.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 \tab If {\f22 required-init-keyword:} is specified for a slot, then {\f22 init-keyword:}, {\f22 init-value:}, and {\f22 init-function:} cannot be specified.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Filtered Slots\par \pard\plain \s2\li480\ri480\sa120 \f16 In some situations, the value of a slot will be stored directly in instances of one class but will require some computation in a subclass. For example, the {\f22 position} slot could be stored as a value in direct instances of {\f22 } while requiring some computation in direct instances of the <{\f22 view>} subclass {\f22 }.\par Both classes provide the same interface to {\f22 position} (the {\f22 position} generic function). If the implementor of either class decides to change the imple mentation, users of the classes will not need to change or recompile code, because there is no change in the interface. Consistent function call syntax helps hides implementation details.\par \pard \s2\li480\ri480\sa120 In this case, the {\f22 } class supports {\f22 position} as an instance slot, and the {\f22 } class supports {\f22 position} as a filtered slot. Methods for {\f22 position} and {\f22 position-setter} are added automatically by the slot definition in {\f22 }; these methods access the raw value of the slot in the instance. In contrast, the implementor of {\f22 } must explicitly add methods to the two generic functions. The { \f22 } methods can call{\f22 next-method} to access (get or set) the stored value of the slot.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class ()\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 instance slot position;\par ...\par end class;\par \par define class ()\par ...\par end class;\par \par define method position (v :: )\par displace-transform (next-method (v));\par end method;\par \par define method position-setter (new-position),\par v :: )\par next-method (undisplace-transform (new-position), v);\par end method;\par \par \pard\plain \s2\li480\ri480\sa120 \f16 In other situations, a programmer will want storage in an instance for a slot value, but will want to perform some auxiliary action whenever the slot is accessed. In this case, the programmer should define two slots: an instance slot to provide the stora ge and a virtual slot to provide the interface. In general, only the virtual slot will be documented. The instance slot will be an internal implementation used by the virtual slot for storage. An example of such use would be a slot that caches a value. \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class ()\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 virtual slot image;\par instance slot cached-image, init-value: #f;\par ...\par end class;\par \par define method image (shape :: )\par cached-image (shape)\par | (cached-image (shape) := compute-image (shape));\par end method;\par \par define method image-setter (new-image, shape :: )\par cached-image (shape) := new-image;\par end method;\par \par \pard\plain \s2\li480\ri480\sa120 \f16 Note that, as in the above example, if you define a virtual slot, you are expected to define an internal instance slot in order to provide a value for the slot accessor.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Instance creation\par \pard\plain \s2\li480\ri480\sa120 \f16 The creation and initialization of instances is controlled by the generic functions {\f22 initialize} and {\f22 make}.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Overview\par \pard\plain \s2\li480\ri480\sa120 \f16 Instance creation and initialization works in the following way:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 (1) The user calls {\f22 make} specifying a class and a set of keyworded arguments.\par \pard \s21\fi-360\li840\ri480\sa160 (2) Optionally, the system-supplied {\f22 make} method may be shadowed by a user-supplied method specialized with a {\f22 singleton} specializer. This enables the user method to get at all the arguments to {\f22 make} , and to provide actual initializations based on them, perhaps in combination. Typically, the method uses {\f22 next-method} with the new or modified keyworded arguments to actually create and initialize the instance.\par (3) The default {\f22 make} method examines its keyworded arguments, the {\b supplied initialization arguments}. Next, {\f22 make} produces a set of {\b defaulted initialization arguments} , which will be used in creating and initializing the instance, by augmenting the supplied initialization arguments with any additional initialization arguments for which default values are defined by class or any of its superclasses.\par \pard \s21\fi-360\li840\ri480\sa160 (4) The default {\f22 make} method allocates an instance and initializes all slots it can provide values for: those which are keyword initializable are initialized from the corresponding values of the defaulted initialization arguments; slots which are not keyword initializable b ut have a default initial value specification have the appropriate value assigned.\par \pard \s21\fi-360\li840\ri480\sa160 (5) It then calls {\f22 initialize} on the initialized instance and the defaulted initialization arguments.\par \pard \s21\fi-360\li840\ri480\sa160 (6) Each {\f22 initialize} method typically calls {\f22 next-method()}, and then (having used {\f22 #key} to access the initargs it needs) performs the initializations it needs to. (Note that it won\rquote t have to initialize slots that were handled by step 4.)\par \pard \s21\fi-360\li840\ri480\sa160 (7) The default {\f22 make} method ignores the value of the call to {\f22 initialize}, and returns the instance.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Definitions of make and initialize\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 make} {\i class }{\f22 #key #all-keys} => {\i instance}\tab [Generic Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 make} returns an instance of {\i class}, with characteristics specified by the keyword value pairs.\par \pard \s2\li480\ri480\sa120 Dylan does not specify whether the value returned must be a newly allocated instance, or whether {\f22 make} is permitted to return a previously created instance. If a new instance is allocated, {\f22 make} will call {\f22 initialize} on the instance before returning it.\par The object returned is guaranteed to be a general instance of {\i class} but not necessarily a direct instance of {\i class}. This liberality allows {\f22 make} to be called on an abstract class; it can instantiate and return a direct instance of one of the concrete subclasses of the abstract class.\par \pard \s2\li480\ri480\sa120 (Note that the default method on {\f22 make }returns a newly allocated direct instance of {\i class} .)\par \pard \s2\li480\ri480\sa120 Programmers may customize {\f22 make} for particular classes by defining methods specialized by {\f22 singleton} specializers. These methods may obtain the default {\f22 make} behavior, if desired, by calling {\f22 next-method }. \par \pard \s2\li480\ri480\sa120 In the absence of any customization, the default {\f22 make} method is invoked.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 make} {\i class} {\f22 #rest} {\i supplied-initialization-arguments} {\f22 #key} => {\i instance}\tab [Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The default method for {\f22 make} does the following:\par \pard \s2\li480\ri480\sa120 It signals an error if {\i class} is abstract. An instantiable abstract class must override this method with its own method for {\f22 make}.\par Any deferred evaluations which have not yet been performed for {\i class} and its superclasses are performed first.{\i \par }\pard \s2\li480\ri480\sa120 If {\i supplied-initialization-arguments } contains duplicate keywords, {\f22 make} will use the leftmost occurence. (This is consistent with {\f22 #key} argument conventions in function calls.)\par \pard \s2\li480\ri480\sa120 {\f22 make} starts with {\i supplied-initialization-arguments } and constructs the set of defaulted initialization arguments , which will be used in creating and initializing the instance, by augmenting it with any additional initialization arguments for which default values are defined by {\i class} or any of its superclasses. {\f22 make} signals an error if any required initialization argument is absent from the defaulted initialization arguments, or if any of the defaulted initializatio n arguments are not valid for initialization of that class (that is, some keyword is neither usable for slot initialization nor recognized by some {\f22 initialize }method applicable to an instance of {\i class } ). Note that init-functions used to construct the defaulted initialization arguments will only be invoked if the initialization argument is in fact missing from the supplied initialization arguments.\par \pard \s2\li480\ri480\sa120 {\f22 make} then allocates an instance and initializes all slots for which it can compute values. If a slot is keyword initializable and the corresponding {\i initialization argument is present in the defaulted initialization arguments , the} slot is set to that value. Otherwise, if the slot has a default initial value specification, that is used to provide the initial value: either the init-value, or the result of calling the init-function. In either case, an error is signaled if the value is not of the type declared for the slot.\par \pard \s2\li480\ri480\sa120 The exact order in which instance allocation and init-function invocation occurs in the above is undefined.\par \pard \s2\li480\ri480\sa120 {\f22 make} calls {\f22 initialize} on the initialized instance and the defaulted initialization arguments, to perform any custom or complex initializations. User-defined {\f22 initialize} methods may use {\f22 #key} parameters to access particular initialization arguments, or {\f22 #rest} to access the entire set of initialization arguments. If the entire set of initialization arguments is examined and {\i supplied initialization arguments} contained duplicate keywords, it is undefined whether any entries other than the leftmost for that keyword will be present.\par \pard \s2\li480\ri480\sa120 {\f22 make} ignores any values returned by the call to {\f22 initialize}, and returns the instance.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 initialize} {\i instance} {\f22 #key #all-keys}\tab [Generic Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 The {\f22 initialize} generic function provides a way for users to handle initialization of instances which cannot be expressed simply by init-values or init-functions. This is typically because a computation requires inputs from initargs or slot values, or a single computati on needs to be used to initialize multiple slots. \par \pard \s2\li480\ri480\sa120\keepn For instance, the following example shows a {\f22 } class which presents an interface of storing three sides, but actually stores two sides and an angle:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class ()\par slot side-a, required-init-keyword: side-a:;\par slot side-b, required-init-keyword: side-b:;\par slot angle-C;\par virtual slot side-c, required-init-keyword: side-c:\par end class ;\par \par define method initialize (x :: ,\par #key side-a, side-b, side-c)\par next-method();\par x.angle-C := three-sides-to-angle (side-a, side-b, side-c);\par end method initialize;\par \pard\plain \li360\ri480 \f16 {\f22 \par }\pard\plain \s2\li480\ri480\sa120 \f16 By convention, all {\f22 initialize} methods should call {\f22 next-method} very early, to make sure that any initializations from less specific classes are performed first. Dylan implementations may provide warnings about code style for methods on {\f22 initialize} which do not call {\f22 next-method}.\par \pard \s2\li480\ri480\sa120 The {\f22 initialize} generic function {\i permits} all keywords, and requires none. It does this because the keyword argument checking has already been performed by the default method on {\f22\fs20 make}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 initialize} {\i instance} {\f22 :: } {\f22 #key}\tab [Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The default {\f22 initialize} method does nothing. It is present so that {\f22 next-method()} may be used with abandon by modularly written {\f22 initialize} methods.\par \pard\plain \li360\ri480 \f16 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Initialization Argument Inheritance\par \pard\plain \s2\li480\ri480\sa120 \f16 If a slot is keyword-initializable, it is possible to change the default value for the initialization argument alone, without mention of the slot. \par \pard \s2\li480\ri480\sa120\keepn This is illustrated by the modified default for {\f22 favorite-beverage} in the following example.\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class (...)\par slot favorite-beverage, init-value: #"milk",\par init-keyword: favorite-beverage:;\par slot name required-init-keyword: name:;\par end class ;\par \par define class ()\par keyword favorite-beverage: init-value: #"tang";\par keyword name: init-value: "Bud";\par end class ;\par \par \pard\plain \s2\li480\ri480\sa120 \f16 Another common use is to supply a default which is required in the superclass, as illustrated with the {\f22 name:} init-keyword above; this makes the {\f22 name:} keyword no longer required when calling {\f22 make} on {\f22 }.\par \pard \s2\li480\ri480\sa120 Initialization argument specification inheritance is defined as follows. There are four cases:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 1.\tab A slot specification which supplies an init-keyword {\i K} by using {\f22 required-init-keyword:} is treated as if the initialization argument specification {\f22 required-init-keyword: }{\i\f22 K}{ \f22 } had been specified in the class definition.\par \pard \s21\fi-360\li840\ri480\sa160 \tab A slot specification which supplies both an init-keyword and also an init-value or init-function is {\i not}{\b\i }equivalent to an initialization argument specification which includes the init-keyword a nd init-value or init-function. The former is used to default the value of the slot directly, but does not affect the defaulted initialization arguments; the latter is used to default the value of the slot indirectly, by affecting the defaulted initializa tion arguments.\par \pard \s21\fi-360\li840\ri480\sa160 2.\tab The initialization argument is being specified for the first time \emdash it is not inherited from any superclasses.\par \pard\plain \fi-340\li1100\ri480 \f16 a. The {\f22 type:} argument, which defaults to {\f22 }, specifies the required type of the initialization argument.\par b. If the initialization argument is specified with {\f22 required-init-keyword:} then it is required, otherwise it is optional.\par \pard \fi-340\li1100\ri480 c. If the initialization argument is specified with {\f22 init-keyword:}, then it can provide an initial value specification which is used by the default {\f22 make} method to provide a default value for the initialization argument in the defaulted initialization arguments. This is either a value specified with {\f22 init-value:} or a function (called each time a value is needed) specified with {\f22 init-function: \par }\pard \fi-340\li1100\ri480 \par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 3.\tab An initialization argument specification is being specified for an initialization argument which is inherited from a single superclass.\par \pard\plain \fi-340\li1100\ri480 \f16 a. The type must be a subtype of the type of the inherited initialization argument.\par \pard \fi-340\li1100\ri480 b. The initialization argument is required if the overriding initialization argument specification uses {\f22 required-init-keyword:} , or if the inherited initialization argument specification is required and the overriding initialization argument specification uses neither {\f22 init-value:} nor {\f22 init-function:} . When the the overriding initialization argument specification uses {\f22 required-init-keyword:}, any init-value or init-function in the inherited initialization argument specification is discarded. \par \pard \fi-340\li1100\ri480 c. Otherwise, the initialization argument is optional. If the overriding specification provides an {\f22 init-value:} or {\f22 init-function:} , then that is used to compute the defaulted initialization argument when the class is instantiated. Otherwise, the inherited initial value specification is used.\par \pard \fi-340\li1100\ri480 \par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 4.\tab An initializa tion argument specification is being inherited from multiple superclasses. If the superclasses have exactly the same definition for the initialization argument, then that definition can simply be inherited. If the definitions differ, then the class which combines these other classes must provide an initialization argument specification which is compatible with all of the inherited ones, as described above.\par \pard\plain \s2\li480\ri480\sa120 \f16 (3)b. means that a subclass can force an initialization argument used by a superclass to become requ ired, but cannot force a required initialization argument to become optional without specifying a default value to be used.\par \pard\plain \li480\ri480 \f16 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Initialization of Class Allocated Slots\par \pard\plain \s2\li480\ri480\sa120 \f16 Initialization of slots of allocations {\f22 class} and {\f22 each-subclass} works in the following way. There are four cases to consider, depending on whether the slot is keyword initializable, and whether any way to compute a default value was specified:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 1.\tab The slot is not keyword initializable, and there is no default value for the slot (i.e., neither {\f22 init-value:} nor {\f22 init-function:} were specified). The slot value is not changed, and if it is presently uninitialized it remains so.\par \pard \s21\fi-360\li840\ri480\sa160 2.\tab The slot is not keyword initializable, but there is a default value for it (specified with either {\f22 init-value:} or {\f22 init-function:} ). The init-value (or value of the call to the init-function) is used to initialize the slot some time before or during the first call to {\f22\fs20 make }on a class that shares this slot.\par 3.\tab The slot is keyword-initializable, but the corresponding initialization argument is absent from the defaulted initialization arguments of the call to {\f22 make}. The slot value is not changed, and if it is presently uninitialized it remains so. \par 4.\tab The slot is keyword-initializable, and the corresponding initialization argument is present in the defaulted initialization arguments of the call to {\f22 make}. The slot is unconditionally set to the value of that initialization argument.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Testing the Initialization of a Slot\par \pard\plain \s2\li480\ri480\sa120 \f16 A program can test to see whether a slot has been initialized.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 slot-initialized?} {\i instance getter} {\f23 \'de} {\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 slot-initialized?} returns true if the slot in {\i instance} that would be accessed by the {\i getter} generic function is initialized. If the slot is not initialized, then false is returned.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\f22 slot-initialized?} will signal an error if the {\i getter} does not access a slot in the {\i instance}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 There is no mechanism for resetting a slot to the uninitialized state.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Reflective Operations on Types\par \pard\plain \s2\li480\ri480\sa120 \f16 The following operations return information about types and objects.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 instance?} {\i object type} {\f23 \'de}{\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 instance?} returns true if {\i object} is a general instance of {\i type}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 subtype?} {\i type}{\i\fs20\dn4 1}{\i type}{\i\fs20\dn4 2} {\f23 \'de}{\i boolean}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 subtype?} returns true if {\i type}{\i\fs20\dn4 1}{\i } is a subtype\emdash either direct or indirect\emdash of {\i type}{\i\fs20\dn4 2}, or if {\i type}{\i\fs20\dn4 1}{\i } and {\i type}{\i\fs20\dn4 2 } are the same type.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 object-class} {\i object} {\f23 \'de}{\i class}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 object-class} returns the class of which {\i object} is a direct instance.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 all-superclasses} {\i class} {\f23 \'de}{\i sequence}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 all-superclasses} returns all the superclasses of {\i class} in a sequence. The order of the classes in the sequence is significant. The first element in the sequence will always be { \i class}, and {\f22 } will always be the last.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior. If {\i class} is sealed, an implementation may choose to signal an error of type {\f22 } rather than returning the sequence of all superclasses.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 direct-superclasses} {\i class} {\f23 \'de}{\i sequence}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 direct-superclasses} returns the direct superclasses of {\i class} in a sequence. These are the classes that were passed as arguments to {\f22 make} or {\f22 define class} when the { \i class} was created. The order of the classes in the sequence is the same as the order in which they were passed to {\f22 define class}, or {\f22 make} when {\i class} was created.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior. If {\i class} is sealed, an implementation may choose to signal an error of type {\f22 } rather than returning the direct superclasses.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 direct-subclasses} {\i class} {\f23 \'de}{\i sequence}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 direct-subclasses} returns the direct subclasses of {\i class} in a sequence. These are the classes that have {\i class} as a direct superclass. The order of the classes in the sequence is insignificant.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The sequence returned should never be destructively modified. Doing so may cause unpredictable behavior.{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } Note that the pointer from a class to its subclasses is through a weak link, so subclasses may be garbage collected if there are no other references to them.}} If {\i class} is sealed, an implementation may choose to signal an error of type {\f22 } rather than returning the direct subclasses.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Coercing and Copying Objects\par \pard\plain \s2\li480\ri480\sa120 \f16 These functions are used to perform shallow copies on objects, and to coerce objects to other classes.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as} {\i class object} {\f23 \'de}{\i instance}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 as} coerces {\i object} to {\i class}. That is, it returns an instance of {\i class} that has the same contents as {\i object}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 If {\i object} is already an instance of {\i class}, it is returned unchanged.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 Predefined methods allow coercion between numeric types, between integers and characters, between strings and symbols, and between collection types. No methods are defined for other classes.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 When converting between collection types, the new collection (the returned object) will have the same number of elements as the source collection (the {\i object} ). If the source and target class are both subclasses of {\f22 }, the elements will be in the same order. The individual elements may also undergo some conversion.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 shallow-copy} {\i object} {\f23 \'de}{\i new-object}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 shallow-copy} returns a new object that has the same contents as {\i object}. The contents are not copied but are the same objects contained in {\i object}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 Dylan includes methods for copying collections. The method for {\f22\fs20 } creates a new object by calling {\f22 make} on the {\f22 class-for-copy} of {\i object} . For other classes, the programmer must provide a method.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 class-for-copy} {\i object} {\f23 \'de}{\i class}\tab [Generic Function]\par \pard\plain \li480\ri480 \f16 {\f22 class-for-copy} returns an appropriate collection class for creating mutable copies of the argument. For collections that are already mutable, the collection\rquote s actual class is generally the mo st appropriate, so the {\f22 } method of {\f22 class-for-copy} can be used. The {\f22 class-for-copy} value of a sequence should be a subclass of {\f22 }, and the {\f22 class-for-copy} value of an explicit-key-collection should be a subclass of {\f22 }. In all cases, the {\f22 class-for-copy} value must be a mutable collection.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 The classes , , and \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 All types (including {\f22 } and {\f22 }) are general instances of {\f22 }. {\f22 } is a subclass of {\f22 }.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 All classes (including {\f22 }) are general instances of {\f22 }. {\f22 } is a subclass of {\f22 }.\par \pard\plain \li480\ri480 \f16 In most programs the majority of classes are created with {\f22 define class}. However, there is nothing to prevent programmers from creating classes by calling {\f22 make} , for example, if they want to create a class without storing it in a module variable, or if they want to create new classes at runtime.\par \pard \li480\ri480 \par \pard \li480\ri480 If {\f22 make} is used to create a new class and creating the new class would violate any restrictions specified by sealing directives, then an error of type {\f22 } is signaled.\par \pard \li480\ri480 \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The class {\f22 } supports the following init-keywords:\par \pard\plain \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \f16 {\f22 superclasses:}\tab Specifies the direct superclasses of the class. {\f22 superclasses:} should be a class or a sequence of classes. The default value is {\f22 } . The meaning of the order of the superclasses is the same as in {\f22 define class}.\par \pard \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 {\f22 slots:}\tab A sequence of slot specs, where each slot-spec is a sequence of keyword/value pairs.\par \pard \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \tab The following keywords and corresponding values are accepted by all implementations. Implementations may also define additional keywords and values for use within slot specs.\par \pard\plain \s15\fi-2160\li4860\ri480\sa160\tx4860 \f16 {\f22 getter:}\tab A generic function of one argument. Unless the allocation of the slot is virtual, the getter method for the slot will be added to this generic function. This option is required. \par {\f22 setter:}\tab A generic function of two arguments. Unless the allocation of the slot is virtual, the setter method for the slot will be added to this generic function. There is no default.\par \pard \s15\fi-2160\li4860\ri480\sa160\tx4860 {\f22 type:}\tab A type. Values stored in the slot are restricted to be of this type. The default value for this option is {\f22 }.\par \pard \s15\fi-2160\li4860\ri480\sa160\tx4860 {\f22 deferred-type:}{\f22\fs20 \tab }A function of no arguments, which returns a type, and is called once to compute the type of the slot, within the call to {\f22 make} which constructs the first instance of that class.\par \pard \s15\fi-2160\li4860\ri480\sa160\tx4860 {\f22 init-value:}\tab Supplies a default initial value for the slot. This option cannot be specified along with {\f22 init-function:}. There is no default.\par \pard \s15\fi-2160\li4860\ri480\sa160\tx4860 {\f22 init-function:}\tab A function of no arguments. This function will be called to generate an initial value for the slot when new instances are created. This option cannot be specified along with {\f22 init-value:}. There is no default\par \pard \s15\fi-2160\li4860\ri480\sa160\tx4860 {\f22 init-keyword:}\tab A keyword. This option permits an initial value for the slot to be passed to make, as a keyword argument using this keyword. There is no default. This option cannot be specified along with {\f22 required-init-keyword:}.\par \pard \s15\fi-2160\li4860\ri480\sa160\tx4860 {\f22 required-init-keyword:}\line A keyword. This option is like {\f22 init-keyword:}, except it indicates an init-keyword that must be provided when the class is instantiated. If {\f22 make} is called on the class and a required init-keyword is not provided, an error is signaled. There is no default. This option cannot be specified if {\f22 init-keyword:}, {\f22 init-value:}, or {\f22 init-function:} is specified.\par \pard \s15\fi-2160\li4860\ri480\sa160\tx4860 {\f22 allocation:}\tab One of the keywords {\f22 instance:}, {\f22 class:}, {\f22 each-subclass:}, {\f22 constant:}, or {\f22 virtual:} , or an implementation defined keyword. The meaning of this option is the same as adding the corresponding adjective to a {\f22 define class} form.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The class {\f22 } supports the following init-keyword:\par \pard\plain \s23\fi-2160\li2640\ri480\sa240\keep\tx2640 \f16 {\f22 object:}\tab The object that the singleton indicates. There is no default for this argument. If it is not supplied, an error will be signaled.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If a singleton for the specified object already exists, implementations are free to fold the two instances into one.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 singleton} {\i object} {\f23 \'de}{\i singleton}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 singleton} returns a singleton for {\i object}.\par {\f22 singleton(}{\i object}{\f22 )} is equivalent to {\f22 make(, object: }{\i object}{\f22 ).\par }\pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \page \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 8. Controlling Dynamism{\plain \f16 \par }\pard\plain \s2\li480\ri480\sa120 \f16 This section describes how you can selectively control the dynamism of Dylan\rquote s functions and classes. The techniques for selectively controlling dynamism in Dylan are:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab Declaring a class to be {\f22 sealed} or {\f22 open}\par \bullet \tab Declaring a class to be {\f22 abstract} or {\f22 concrete}\par \bullet \tab Declaring a class to be {\f22 primary} or {\f22 free}\par \bullet \tab Declaring a generic function to be {\f22 sealed} or {\f22 open}\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab Using the {\f22 seal generic} form, or using the abbreviations {\f22 define sealed method} and {\f22 sealed slot.\par }\pard\plain \s2\li480\ri480\sa120 \f16 Syntactically, these are all expressed as {\i adjectives} on the generic function, class, or method definition, or slot specification, with the exception of the {\f22 seal generic} form.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Declaring characteristics of classes\par \pard\plain \s2\li480\ri480\sa120 \f16 A class definition (see the previous chapter on Classes) may include the adjectives {\f22 sealed}, {\f22 open}, {\f22 primary}, {\f22 free}, {\f22 abstract}, or {\f22 concrete} . These adjectives declare characteristics of the class.\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab A class can be declared to be either {\f22 sealed} or {\f22 open}. If a class is sealed then no additional subclasses other than those {\i explicitly defined} in the same {\i library} may be created. Thus, it is an error to define a subclass of a sealed class in some {\i library} other than the one which defined the sealed class, or to use {\f22 make} of {\f22 } with a sealed class directly or indirectly in the superclasses. An open class does not prohibit such operations. It is an error to define an open subclass of a sealed class.\par \pard \s2\fi-360\li840\ri480\sa120 \tab When {\i explicitly defining} a class, the default is for the class to be sealed. This may be overriden by explicitly specifying that it is open. A class created using {\f22 make} of {\f22 } is open. There is no specified way to create a sealed class using {\f22 make}.\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab An explicitly defined class may be declared to be either {\f22 primary} or {\f22 free}. The default is {\f22 free} . It is illegal for a class to have two primary superclasses unless one is a subclass of the other.\par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab An explicitly defined class may be defined to be either {\f22 abstract} or {\f22 concrete}. The default is {\f22 concrete} . The superclasses of an abstract class must be abstract. An abstract class does not usually have slots; although defining slots in an abstract class is not forbidden, it should be done with caution, especially for instance allocated slots.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Declaring sealing of generic functions\par \pard\plain \s2\li480\ri480\sa120 \f16 A generic function definition (see the previous chapter on Functions) may include the adjective {\f22 sealed} or the adjective {\f22 open}. These adjectives declare whether the generic function is sealed..\par \pard \s2\li480\ri480\sa120 If a generic function is sealed then no additional methods other than those {\i explicitly defined} in the same {\i library} may be added to the generic functio n. Thus, it is an error to define a method for a sealed generic function in some {\i library} other than the one which defined the sealed generic function, or to apply {\f22 add-method} or {\f22 remove-method} to a sealed generic function. An open generic function does not prohibit such operations.\par \pard \s2\li480\ri480\sa120 When {\i explicitly defining} a generic function, the default is for the generic function to be sealed. This may be overridden by explicitly specifying that it is open. A generic function that has no {\i explicit definition} but has implicit definitions provided by {\i explicit definitions} of {\i generic function methods} for it is sealed. A generic function created using {\f22 make} of {\f22 } is open. There is no specified way to create a sealed generic function using {\f22 make.}{\f22\fs20 \par }\pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 The seal generic form\par \pard\plain \s2\li480\ri480\sa120 \f16 There is also a {\f22 seal generic} top-level form, with the following syntax:\par \pard\plain \li480\ri480 \f16 {\f22 \tab seal generic }{\i function}{\f22 ( }{\i type}{\i\f22 , ...}{\f22 );\par }\pard \li480\ri480 {\f22\fs20 \par }\pard\plain \s2\li480\ri480\sa120 \f16 The {\i function} must be a module variable that refers to a generic function.\par \pard \s2\li480\ri480\sa120 The {\i types} must be expressions that evaluate to instances of {\f22 }. The number of {\i types }must be the same as the number of required arguments accepted by the {\i function.\par }\pard \s2\li480\ri480\sa120 A {\f22 seal generic} form in a library L for a generic function G with types T{\dn4 1}...T{\dn4 n} imposes the following constraints on programs:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 1. \tab A method M which is congruent to G and which is not an explicitly known method in L may be added to G if and only if at least one of the specializers for M is disjoint from the corresponding type in the sealing form.\par 2. \tab A method M may be removed from G if and only if at least one of the specializers for M is disjoint from the corresponding type in the sealing form.\par \pard \s21\fi-360\li840\ri480\sa160 3. \tab A class C with direct superclasses D{\fs20\dn4 1}...D{\fs20\dn4 m} and which is not an explicitly known class in L may be created if and only if\par \pard \s21\fi-360\li1800\ri480\sa160 a. \tab none of the classes D{\fs20\dn4 1}...D{\fs20\dn4 m} are subtypes of any of the types T{\fs20\dn4 1}...T{\fs20\dn4 n} in the sealing form, or\par \pard \s21\fi-360\li1800\ri480\sa160 b. \tab for every method M in G with specializers S{\fs20\dn4 1}...S{\fs20\dn4 n}, if there exists an i such that S{\fs20\dn4 i} is disjoint from T{\fs20\dn4 i} , then M must satisfy condition (1) below, otherwise M must satisfy condition (2) below.\par \pard \s21\fi-360\li2520\ri480\sa160 i. \tab There exists an i such that S{\fs20\dn4 i} is disjoint from T{\fs20\dn4 i} and such that there do not exist j and k such that D{\fs20\dn4 j} is a subtype of S{\fs20\dn4 i} and D{\fs20\dn4 k} is a subtype of T{ \fs20\dn4 i}.\par ii. \tab There do not exist i, j, and k such that D{\fs20\dn4 j} and D{\fs20\dn4 k} are subtypes of T{\fs20\dn4 i}, D{\fs20\dn4 j} is disjoint from D{\fs20\dn4 k}, D{\fs20\dn4 j} is a subtype of S{\fs20\dn4 i}, and D{\fs20\dn4 k} is not a subtype of S{ \fs20\dn4 i}.\par \pard\plain \li480\ri480 \f16 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Abbreviations for seal generic\par \pard\plain \li480\ri480 \f16 {\f22 define sealed method} defines a normal method and then seals the generic function for the types that are the specializers of the method. {\f22 define sealed method} is a convenient abbreviation for the {\f22 seal generic} form.\par \pard \li480\ri480 \par \pard \li480\ri480 The {\f22 sealed slot} option to {\f22 define class }defines a normal slot and then seals the getter generic function for the class, and seals the setter generic function, if there is one, on {\f22 } and the class. The {\f22 sealed slot} option to {\f22 define class} is a convenient abbreviation for the {\f22 seal generic} form.\par \pard \li480\ri480 \page \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 9. Collections\par \pard\plain \s2\li480\ri480\sa120\keepn \f16 This section describes the design of the classes of aggregate data structures (collections). In addition to the concrete classes provided by the D ylan language, the heterarchy for collection classes contains several abstract classes, each of which embodies some particular behavior, usually expressed as a protocol of generic functions. Every subclass of an abstract class implements every generic fun ction of the corresponding protocol.\par \pard \s2\li480\ri480\sa120\keepn The following diagram shows the collection class heterarchy. Abstract classes are shown in italic and sealed classes are shown in bold.\par \pard \s2\li480\ri480\sa120\keepn \par \pard\plain \li480\ri480 \f16 {{\pict\macpict\picw399\pich303 127401140053024301e2001102ff0c00ffffffff005300000114000001e20000024300000000000000a0008200a10064000a53504e5403e80001000000a10064000e53504e540cd001140053024301e200a10064000a53504e540bb8000b000000a0008c00a10064000a53504e540bb80005000100a10064000a53504e540c 9400000000001e001ad900d900d9000001000a01140053024301e2000b001b001b004101230054024301e200a10064000a53504e540bb800050043001affffffffffff000900000000000000000041011c0053024001df00a100b6000400010004001a0000000000000009ffffffffffffffff004800a100b6000400040001 00a100b600040001000100a10064000a53504e540bb800050043001affffffffffff00090000000000000000004101ea0060023301d400a100b6000400010004001a0000000000000009ffffffffffffffff004800a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b6000400 010004002001a2005301a201de00a100b600040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c26012d0112013d014400050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a01140053013901e2 002c000c00150948656c7665746963610003001500040200000d0007002e0004000000000028013601170c3c636f6c6c656374696f6e3e0000a0009700a10064000a53504e540bb80003004200a100b60004000100040001000a01140053024301e20022013b012e201a00a100b600040004000100a100b600040001000100 a10064000a53504e540bb80001000000a10064001a53504e540c260195005601a6009600050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0500000002000000000000000001000a0114005301a201e200040000000d00080028019f005b0841425354524143540000a0009700a10064000a 53504e540bb80001000000a10064001a53504e540c2601a0005601b2009e00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0500000002000000000000000001000a0114005301ae01e2002a0b0c494e5354414e544941424c4500a0009700a10064000a53504e540bb80001000000a100 64001a53504e540c2601ee006001fe009400050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0500000002000000000000000001000a0114005301fa01e2002b0a4e065345414c45440000a0009700a10064000a53504e540bb800040043001affffffffffff0001000a01140053024301e2 000900000000000000000031011400e20126015e00a100b6000400010004001a0000000000000009ffffffffffffffff003800a100b600040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c26011400d50127016b00050002ffffffffffffffff00a10064000a53504e 540c940000000000a10096000c0600000002000000000000000001000a01140053012301e200040100000d00090028012000e612434f4c4c454354494f4e20434c41535345530000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c26015601250167017f00050002ffffffffffffffff00a10064 000a53504e540c940000000000a10096000c0600000002000000000000000001000a01140053016301e200040200000d0008002b4840143c6d757461626c652d636f6c6c656374696f6e3e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c26017e005e018f00e500050002ffffffffffffff ff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a01140053018b01e2002801880069213c6d757461626c652d6578706c696369742d6b65792d636f6c6c656374696f6e3e00a0009700a10064000a53504e540bb80001000000a10064001a53504e540c260155018b016601c1 00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a01140053016201e20028015f01910a3c73657175656e63653e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c2601550053016600b900050002ffffffffffffff ff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000028015f005c193c6578706c696369742d6b65792d636f6c6c656374696f6e3e00a0009700a10064000a53504e540bb80003004200a100b60004000100040001000a01140053024301e20022013b0132791900a100b6000400040001 00a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040020013b012b0154008f00a100b600040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c26017e0132018f018b00050002ffffffffffffffff00a10064000a53504e540c9400 00000000a10096000c0600000002000000000000000001000a01140053018b01e2002bdf29123c6d757461626c652d73657175656e63653e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c2601a900f301ba011a00050002ffffffffffffffff00a10064000a53504e540c940000000000a1 0096000c0600000002000000000000000001000a0114005301b601e200040000002801b300f9073c61727261793e00a0009700a10064000a53504e540bb80001000000a10064001a53504e540c2601a8009701b900bd00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c06000000020000 00000000000001000a0114005301b501e2002801b2009d073c7461626c653e00a0009700a10064000a53504e540bb80001000000a10064001a53504e540c2601bb00d901cb010400050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a0114005301c7 01e2002b4213083c766563746f723e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c2601c2013501d3015f00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a0114005301cf01e2002b5d07083c737472696e673e 0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c2601bb010f01cc013a00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a0114005301c801e2002801c50116073c64657175653e00a0009700a10064000a53504e54 0bb80001000000a10064001a53504e540c2601c201a501d301cf00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a0114005301cf01e2002b9607073c72616e67653e00a0009700a10064000a53504e540bb80003004200a100b600040001000400 01000a01140053024301e2002201630086151900a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b6000400010004002201640150071a00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022016201aab31c 00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b600040001000400200164014f017b009c00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022016201aa0f6000a100b600040004000100a100b6000400 01000100a10064000a53504e540bb80003004200a100b60004000100040022018c015dc82f00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022018f015ced3300a100b600040004000100a100b600040001000100a10064000a53504e540bb800030042 00a100b60004000100040022018b015dac2100a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022018a009e0c1d00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b6000400010004002201c800efd30d00 a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022018c015d3a7600a100b600040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c2601d4008f01e500dd00050002ffffffffffffffff00a10064000a 53504e540c940000000000a10096000c0600000002000000000000000001000a0114005301e101e2002801de0098113c73747265746368792d766563746f723e00a0009700a10064000a53504e540bb80003004200a100b60004000100040001000a01140053024301e2002201c800f0e33600a100b600040004000100a100 b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c260202008f021300fb00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a01140053020f01e200040100002b022e163c73696d706c652d6f626a6563742d7665 63746f723e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c26020200fa0213014d00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c060000000200000000000000002969103c756e69636f64652d737472696e673e00a0009700a10064000a53504e540b b80001000000a10064001a53504e540c260202014c0213019000050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000029520d3c627974652d737472696e673e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c260202018e0213 01b000050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c060000000200000000000000002940063c6c6973743e00a0009700a10064000a53504e540bb80003004200a100b60004000100040001000a01140053024301e2002201c800f1363a00a100b600040004000100a100b60004000100 0100a10064000a53504e540bb80003004200a100b6000400010004002201d00146223200a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b6000400010004002201cf0146e53300a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a1 00b6000400010004002201c700f0723b00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022020f01a1140e00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022020f019ee80e00a100 b600040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c26021b0194022c01d400050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a01140053022801e2002b08190c3c656d7074792d6c697374 3e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c26021b016f022c019500050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c060000000200000000000000002802250176063c706169723e0000a0009700a10064000a53504e540bb80001000000a1006400 1a53504e540c26015600c30167011d00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a01140053016301e2000402000028016000cc153c73747265746368792d636f6c6c656374696f6e3e00a0009700a10064000a53504e540bb8000300020001 000a01140053024301e20022015601012ae600a10064000a53504e540bb8000300020022016500f2ba4400a10064000a53504e540bb8000300020022016700f3ce6f00a10064000a53504e540bb8000300020022016a00f5315000a10064000a53504e540bb800030002002201be00ed15f600a10064000a53504e540bb800 0c000000a0008d00a10064000653504e5403e900a0008300ff}}\par \pard \li480\ri480 \par \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Functions for Collections\par \pard\plain \s2\li480\ri480\sa120 \f16 The Dylan run-time system provides default implementations for all of the functions described in this section.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 size} {\i collection} {\f23 \'de} {\i \{integer }{\i\fs16 or}{\i }{\f22 #f}{\i \}}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 size} returns the number of keys contained in {\i collection}. A default method is provided by the Dylan run-time system which simply counts while iterating through the collection. { \f22 size} may return {\f22 #f} for collections of unbounded size.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 class-for-copy}{\i mutable-collection} {\f23 \'de} {\i class}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 class-for-copy} returns an appropriate collection class for creating mutable copies of the argument. For collections that are already mutable, the collection\rquote s actual class is generally the most appropriate, so the {\f22 } method of class-for-copy can be used. The class-for-copy value of a sequence should be an instantiable subclass of {\f22 } , and the class-for-copy value of an explicit-key-collection should be an instantiable subclass of {\f22 }.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 empty?}{\i collection }{\f23 \'de}{\i boolean}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Returns {\f22 #t} if {\i collection} contains no elements, and {\f22 #f} otherwise.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 do}{\i procedure collection }{\f22 #rest}{\i more-collections }\tab [Function]\line {\f23 \'de}{\i false}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 do} applies {\i procedure} to corresponding elements of all the collections. Returns {\f22 #f}. If all the collections are sequences, {\f22 do} guarantees that they will be processed in their natural order.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} do (method (a b) print (a + b) end,\par \pard \s5\li960\ri480\keepn\tx2880\tx4800\tx6720 #(100, 100, 200, 200),\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 #(1, 2, 3, 4))\par {\i 101\par 102\par 203\par 204\par }\pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i #f}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 map} {\i procedure collection }{\f22 #rest}{\i more-collections} \tab [Function]\line {\f23 \'de}{\i new-collection}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 map} creates a new collection whose elements are obtained by calling {\i procedure} on corresponding elements of all the collection arguments. If all the collections are sequences, processing is performed in the natural order.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\f22 map} returns a collection whose value is an instance of the {\f22 class-for-copy} value of {\i collection} . The new collection is created by calling make on that class, with a size: initialization argument whose value is the number of corresponding elements in the argument collections.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} map (\\+,\par \pard \s5\li960\ri480\keepn\tx2880\tx4800\tx6720 #(100, 100, 200, 200),\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 #(1, 2, 3, 4))\par {\i #(101, 102, 203, 204)\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 map-as} {\i class procedure collection }{\f22 #rest}{\i more-collections} \tab [Function]\line {\f23 \'de}{\i new-collection}\tab \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 map-as} creates a new collection of class {\i class} whose elements are obtained by applying {\i procedure} to corresponding elements of the collection arguments. {\i class} must be an instantiable subclass of {\f22 } and acceptable as the required argument to {\f22 make}. {\f22 size:} with a non-negative integer value must be an acceptable initarg for {\f22 make} of the class. The new collection is created by calling {\f22 make} on the indicated class, with a {\f22 size:} initialization argument whose value is the number of corresponding elements in the argument collections. If all the collections are sequences (including the created collection), processing is done in the natural order.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} map-as (, \\+,\par \pard \s5\li960\ri480\keepn\tx2880\tx4800\tx6720 #(100, 100, 200, 200),\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 #(1, 2, 3, 4))\par {\i #(101, 102, 203, 204)\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx1160\tqr\tx9360 \f16 {\b\f22 map-into} {\i mutable-collection procedure}\tab [Function]\line {\i \tab collection }{\f22 #rest}{\i more-collections} \line {\f23 \'de}{\i mutable-collection} \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 map-into} returns the {\i mutable-collection} argument after modifying it by replacing its elements with the results of applying {\i procedure} to corresponding elements of {\i collection } and {\i more-collections}. If {\i mutable-collection} and all the other collections are sequences, processing is done in the natural order.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 When {\i mutable-collection} is an instance of {\f22 } , the usual alignment requirement (described in the section on collection alignment) is relaxed. In this case, the key sequence of {\i mutable-collection} is not considered during alignment. Rather, only the key sequences for the source collections are aligned, with procedure called on the corresponding elements. The result of each call to {\i procedure} is then stored into {\i mutable-collection} with the corresponding key (possibly stretching {\i mutable-collection} in the process), using {\f22 element-setter}. Other keys in {\i mutable-collection } remain undisturbed.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The target collection for {\f22 map-into} must have the same key-test function as the rest of the collections, even if it is a {\f22 } and therefore does no t get aligned. Otherwise, an error is signalled.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\i mutable-collection}{\b\i }may be the same as {\i collection} or any of the {\i more-collections}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable x = list (100, 100, 200, 200)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i x\par ?} map-into (x, \\+, #(1, 2, 3, 4))\par {\i #(101, 102, 203, 204)\par ?} x\par {\i #(101, 102, 203, 204)\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 any?}{\i procedure collection }{\f22 #rest}{\i more-collections } \tab [Function]\line {\f23 \'de}{\i value}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If {\i procedure} returns a value other than {\f22 #f} when applied to some group of corresponding elements of {\i collection} and {\i more-collections}, then {\f22 any?} returns the (first) value returned by {\i procedure}. Otherwise, if {\i procedure} returns {\f22 #f} when applied to every such group, then {\f22 any?} returns {\f22 #f}. If all the collection arguments are sequences, {\f22 any?} operates in natural order. In all cases, {\f22 any?} stops on the first true value returned by {\i procedure}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} any? (\\>, #(1, 2, 3 ,4), #(5, 4, 3, 2))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #t\par ?} any? (even?, #(1, 3, 5, 7))\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #f}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 every?}{\i procedure collection }{\f22 #rest}{\i more-collections }\tab [Function]\line {\f23 \'de}{\i boolean}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 every?} is similar to {\f22 any?}, but {\f22 every? }returns {\f22 #f} if {\i procedure} ever returns {\f22 #f} and otherwise returns {\f22 #t}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} every? (\\>, #(1, 2, 3, 4), #(5, 4, 3, 2))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #f\par ?} every? (odd?, #(1, 3, 5, 7))\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #t}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 reduce}{\i procedure initial-value collection } {\f23 \'de}{\i value}\tab [Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\i procedure} is a binary function used to combine all the elements of {\i collection} into a single value. If {\i collection} is empty, {\f22 reduce} returns {\i initial-value}; otherwise, { \i procedure} is applied to {\i initial-value} and the first element of {\i collection} to produce a new value. If more elements remain in the {\i collection}, then {\i procedure} is called again, this time wi th the value from the previous application and the next element from {\i collection}. This process continues until all elements of {\i collection} have been processed. Processing is always done in the natural order for {\i collection}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable high-score = 10\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i high-score\par }\pard\plain \s5\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} reduce (max, high-score, #(3, 1, 4, 1, 5, 9))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i 10\par }\pard\plain \s5\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} reduce (max, high-score, #(3, 12, 9, 8, 8, 6))\par \pard\plain \s6\li960\ri480\tx2880\tx4800\tx6720 \f22\fs20 {\i 12}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 reduce1} {\i procedure collection } {\f23 \'de}{\i value}\tab [Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 reduce1} is just like {\f22 reduce}, except that the first element of {\i collection} is taken as an initial value, and all the remaining elements of {\i collection} are processed as if by {\f22 reduce}. (In other words, the first value isn\rquote t used twice.) For unstable collections, \ldblquote first\rdblquote element effectively means \ldblquote an element chosen at random.\rdblquote It is an error for {\i collection} to be an empty collection. Processing is done in the natural order for {\i collection}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} reduce1 (\\+, #(1, 2, 3, 4, 5))\par \pard\plain \s6\li960\ri480\tx2880\tx4800\tx6720 \f22\fs20 {\i 15}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 member?} {\i value collection }{\f22 #key}{\i test } {\f23 \'de}{\i boolean}\tab [Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 member?} returns {\f22 #t} if and only if {\i collection} contains {\i value} (as determined by {\i test}, which defaults to {\f22 ==}). The {\i test} function may be non-commutative: it is always called with {\i value} as its first argument and an element from {\i collection} as its second argument.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define constant flavors = #(#"vanilla", #"pistachio", #"ginger")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i flavors\par ?} member? (#"vanilla", flavors) \par {\i #t } {\i \par ?} member? (#"banana", flavors)\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #f}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 find-key} {\i collection procedure }{\f22 #key}{\i skip failure } {\f23 \'de}{\i key}\tab [Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function returns a key value such that {\f22 (}{\i procedure} {\f22 (element} {\i collection key}{\f22 ))} is true. If no element in the collection satisfies {\i procedure}, it returns { \i failure} (default {\f22 #f}).\par The {\i skip} argument (default 0) indicates that the first {\i skip} matching elements should be ignored. If {\i skip} or fewer elements of {\i collection} satisfy {\i predicate}, then {\i failure} is returned.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} flavors\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(#"vanilla", #"pistachio", #"ginger")\par ?} find-key (flavors, has-nuts?)\par {\i 1\par ?} flavors[1]\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #"pistachio"}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx2240\tqr\tx9360 \f16 {\b\f22 replace-elements!}{\i mutable-collection predicate \tab }[Generic\~Function]{\i \line \tab new-value-fn }{\f22 #key}{\i count\line }{\f23 \'de} {\i mutable-collection}\tab \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function replaces those elements of {\i mutable-collection} for which {\i predicate} returns true. The elements are replaced with the value of calling {\i new-value-fn} on the element. If {\i count} is specified, no more than {\i count} elements are replaced.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable numbers = list (10, 13, 16, 19)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i numbers\par ?} replace-elements! (numbers, odd?, double)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i #(10, 26, 16, 38)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 fill!} {\i mutable-collection value }{\f22 #key}{\i start end\tab }[Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 fill!} alters {\i mutable-collection} so that {\f22 (element} {\i mutable-collection key}{\f22 )} returns {\i value} for every {\i key}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 If {\i mutable-collection} is a mutable sequence, then {\i start} and {\i end} keywords may be specified to indicate that only a part of the sequence should be filled. {\i start} is considered an inclusive bound and defaults to 0; {\i end} is an exclusive bound and defaults to the length of the sequence.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable numbers = list (10, 13, 16, 19)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i numbers\par ?} fill! (numbers, 3, start: 2)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i #(10, 13, 3, 3)\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 key-test} {\i collection} => {\i test-function}\tab [Generic Function]\par \pard\plain \li340\ri480 \f16 Returns the function used by the collection to compare keys. All collection classes must provide or inherit a method that returns a result consistent with their iteration protocol and {\f22 element} methods. A given method for {\f22 key-test} must return the same value (compared with {\f22 ==}) each time it is called.\par \pard \li480\ri480 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Functions for Sequences\par \pard\plain \s2\li480\ri480\sa120 \f16 Dylan provides default implementations for all of the functions described in this section.\par \pard \s2\li480\ri480\sa120 The default methods for {\f22 add}, {\f22 add-new}, {\f22 remove}, {\f22 choose}, {\f22 choose-by}, {\f22 intersection}, {\f22 union}, {\f22 remove-duplicates}, {\f22 copy-sequence}, {\f22 concatenate}, {\f22 reverse}, and { \f22 sort} all return new sequences that are instances of the {\f22 class-for-copy} of the primary sequence argument. However, more specialized methods are permitted to choose a more appropriate result class; for example, {\f22 copy-sequence} of a range returns another range, even though the {\f22 class-for-copy} value of a range is the {\f22 } class.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 size-setter}{\i n stretchy-sequence }{\f23 \'de} {\i n}\tab [Generic Function]{\i \par }\pard\plain \li480\ri480 \f16 Sets the size of {\i stretchy-sequence }to be {\i n} . {\i stretchy-sequence }is destructively modified.\par \pard \li480\ri480 \par \pard \li480\ri480 If {\i n }is less than or equal to the original size of {\i stretchy-sequence }, then the first {\i n} elements of {\i stretchy-sequence }are retained at the same positions. If {\i n } is greater than the original size of {\i stretchy-sequence }, then the previous elements of the {\i stretchy-sequence }are retained at the same positions, and enough new elements are added to reach the new size. The value of each new element is the same as would have been used if {\i stretchy-sequence }had been created with {\f22 make}, specifying {\f22 size:} {\i n } but not {\f22 fill:}.\par \pard \li480\ri480 \par \pard \li480\ri480 It is not specified how {\f22 size-setter} adds new elements to a {\i stretchy-sequence }. In particular, it is not required to call {\f22 add!} or any other predefined Dylan function.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 add} {\i sequence} {\i new-element } {\f23 \'de}{\i new-sequence\tab }[Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 add} returns a new sequence that contains {\i new-element} and all the elements of {\i sequence}. The resultant sequence\rquote s size is one greater than the size of {\i sequence} . The resultant sequence shares no structure with {\i sequence}, and {\i sequence} will be unmodified. The generic function {\f22 add} doesn\rquote t specify where the new element will be added, although individual methods may do so.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable numbers = #(3, 4, 5)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i numbers\par ?} add (numbers, 1)\par {\i #(1, 3, 4, 5)\par ?} numbers\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #(3, 4, 5)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 add!} {\i sequence1} {\i new-element } {\f23 \'de}{\i sequence2\tab }[Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 add!} returns a sequence made from {\i sequence1} that includes {\i new-element}. The result may or may not be {\f22 ==} to {\i sequence1}. The size of {\i sequence2} is one greater than the size of {\i sequence1}. {\i sequence1} may be modified as a side effect of this operation. {\i sequence2} may share structure with {\i sequence1}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable numbers = list (3, 4, 5)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i numbers\par ?} add! (numbers, 1)\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #(1, 3, 4, 5)\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 add-new} {\i sequence} {\i new-element }{\f22 #key}{\i test } {\f23 \'de}{\i new-sequence\tab }[Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If {\i new-element} is not already a member of {\i sequence} (as determined by the {\i test} function, which defaults to {\f22 ==}), then {\f22 add-new} operates just as {\f22 add} would. If { \i new-element} is already a member of {\i sequence}, then {\i sequence} is returned. {\i sequence} is never modified by this operation. The {\i test} function may be non-commutative: it is always called with an element from {\i sequence} as its first argument and {\i new-element}\~ as its second argument.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} add-new (#(3, 4, 5), 1)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(1, 3, 4, 5)\par ?} add-new (#(3, 4, 5), 4)\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #(3, 4, 5)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 add-new!} {\i sequence} {\i new-element }{\f22 #key}{\i test } {\f23 \'de}{\i new-sequence}\tab [Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If {\i new-element} is not already a member of {\i sequence} (as determined by the {\i test} function, which defaults to {\f22 ==}), then {\f22 add-new!} operates just as {\f22 add!} would. If {\i new-element} is already a member of {\i sequence}, then {\i sequence} is returned. {\i sequence} may be modified by this operation. The {\i test} function may be non-commutative: it is always called with an element from {\i sequence} as its first argument and {\i new-element}\~ as its second argument.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} add-new! (list (3, 4, 5), 1)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(1, 3, 4, 5)\par ?} add-new! (list (3, 4, 5), 4)\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #(3, 4, 5)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove} {\i sequence value }{\f22 #key}{\i test count} {\f23 \'de}{\i new-sequence\tab }[Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 remove} returns a new sequence consisting of the elements of {\i sequence} not equal to {\i value}. {\i test}, which defaults to {\f22 ==}, is a function which determines whether an element is equal to {\i value}. If {\i count} is specified, then no more than {\i count} copies of {\i value} are removed (so additional elements equal to {\i value} might remain). The resultant sequence must share no structure with {\i sequence} and {\i sequence} will not be modified by this operation. The {\i test} function may be non-commutative: it is always called with an element from {\i sequence} as its first argument and {\i value}\~ as its second argument.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} remove (#(3, 1, 4, 1, 5, 9), 1)\par \pard\plain \s6\li960\ri480\tx2880\tx4800\tx6720 \f22\fs20 {\i #(3, 4, 5, 9)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove!} {\i sequence value }{\f22 #key}{\i test count} {\f23 \'de}{\i new-sequence}[\tab Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 remove!} returns a sequence consisting of the elements of {\i sequence} which are not equal to {\i value}. {\i test}, which defaults to {\f22 ==} , is a function which determines whether an element is equal to {\i value}. If {\i count} is specified, then no more than {\i count} copies of {\i value} are removed (so additional elements equal to {\i value} might remain). The resultant sequence may or may not be {\f22 ==} to {\i sequence} and may share structure with {\i sequence}. {\i sequence} may be modified by this operation. The {\i test} function may be non-commutative: it is always called with an element from {\i sequence} as its first argument and {\i value}\~ as its second argument.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} remove! (list (3, 1, 4, 1, 5, 9), 1)\par \pard\plain \s6\li960\ri480\tx2880\tx4800\tx6720 \f22\fs20 {\i #(3, 4, 5, 9)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 choose}{\f22 }{\i predicate sequence }{\f23 \'de} {\i new-sequence}\tab [Generic Function]{\i \par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 choose}{\i }returns a new sequence containing only those elements of {\i sequence} that satisfy {\i predicate}.\par \pard\plain \s6\li960\ri480\sb240\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} choose (even?, #(3, 1, 4, 1, 5, 9))\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #(4)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 choose-by}{\i predicate test-sequence value-sequence }\tab [Generic Function]\line {\f23 \'de} {\i new-sequence}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 choose-by} returns a new sequence formed of elements from {\i value-sequence} whose corresponding elements in {\i test-sequence} satisfy {\i predicate}.\par \pard\plain \s6\li960\ri480\sb240\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} choose-by (even?, range (from: 1),\par \pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 #("a", "b", "c", "d", "e", "f", "g", "h", "i"))\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #("b", "d", "f", "h")}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 intersection}{\i sequence1 sequence2 }{\f22 #key}{\i test }\tab [Generic Function]\line {\f23 \'de} {\i new-sequence}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 intersection}{\i }returns a new sequence containing only those elements of {\i sequence1} that also appear in {\i sequence2}. {\i test}, which defaults to {\f22 ==} , is used to determine whether an element appears in {\i sequence2}. It is always called with an element of {\i sequence1}\~ as its first argument and an element from {\i sequence2}\~ as its second argument. The order of elements in the result sequence is not specified. The result sequence may or may not share structure with the argument sequences.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} intersection (#("john", "paul", "george", "ringo"),\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 #("richard", "george", "edward", "charles"),\par test: \\=)\par {\i #("george")}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 union}{\i sequence1 sequence2 }{\f22 #key}{\i test }{\f23 \'de} {\i new-sequence}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 union} returns a sequence containing every element of {\i sequence1} and {\i sequence2} . If the same element appears in both argument sequences, this will not cause it to appear twice in the result sequence. However, if the same element appears more than once in a single argument sequence, it may appear more than once in the result sequenc e. {\i test}, which defaults to {\f22 ==}, is used for all comparisons. It is always called with an element from {\i sequence1}\~ as its first argument and an element from {\i sequence2}\~ as its second argument . The order of elements in the result is not specified. The result sequence may or may not share structure with the argument sequences.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} union (#("butter", "flour", "sugar", "salt", "eggs"),\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 #("eggs", "butter", "mushrooms", "onions", "salt"),\par test: \\=)\par \pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i #("salt", "butter", "flour", "sugar", "eggs", "mushrooms", "onions")}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove-duplicates} {\i sequence }{\f22 #key}{\i test }{\f23 \'de} {\i new-sequence}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function returns a new sequence that contains all the unique elements from {\i sequence} but no duplicate elements. The result shares no structure with {\i sequence}, and {\i sequence} will not be modified by the operation. {\i test} , which defaults to {\f22 ==}, is the function used to determine whether one element is a duplicate of another. The {\i test} argument may be non-commutative; it will always be called with its arguments in the same order as they appear in {\i sequence}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} remove-duplicates (#("spam", "eggs", "spam", \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 "sausage", "spam", "spam"),\par test: \\=)\par {\i #("spam", "eggs", "sausage")}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove-duplicates!} {\i sequence }{\f22 #key}{\i test }{\f23 \'de} {\i new-sequence}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function returns a sequence that contains all the unique elements from {\i sequence} but no duplicate elements. The result may or may not share structure with {\i sequence} , the result may or may not be {\f22 ==} to {\i sequence}, and {\i sequence} may or may not be modified by the operation. {\i test} , which defaults to {\f22 ==}, is the function used to determine whether one element is a duplicate of another. The {\i test} argument may be non-commutative; it will always be called with its arguments in the same order as they appear in {\i sequence}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} remove-duplicates! (#("spam", "eggs", "spam", \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 "sausage", "spam", "spam"),\par test: \\=)\par {\i #("spam", "eggs", "sausage")}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 copy-sequence}{\i source }{\f22 #key}{\i start end }{\f23 \'de} {\i new-sequence }\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 copy-sequence}{\i }creates a new sequence containing the elements of {\i source} between {\i start} (default 0) and {\i end} (which defaults to the size of {\i source}).\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define constant hamlet = #("to", "be", "or", "not", "to", "be")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i hamlet}\par {\i ?} hamlet == copy-sequence (hamlet)\par {\i #f\par ?} copy-sequence (hamlet, start: 2, end: 4)\par {\i #("or", "not")\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 concatenate-as}{\i class sequence1 }{\f22 #rest}{\i more-sequences \tab }[Function]\line {\f23 \'de} {\i new-sequence}\tab \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 concatenate-as} returns a new sequence, of class {\i class}, containing all the elements of all the sequences, in order. {\i class} must be a subclass of {\f22 } and acceptable as the required argument to {\f22 make}. {\f22 size: }with a non-negative integer value must be an acceptable initarg for {\f22 make} of the class. The new sequence is created by calling {\f22 make} on the indicated class, with a {\f22 size: }initialization argument whose value is the sum of the sizes of the arguments.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} concatenate-as (, #('n', 'o', 'n'), #('f', 'a', 't'))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i "nonfat"}{\b\i \par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 concatenate}{\i sequence1 }{\f22 #rest}{\i sequences }{\f23 \'de} {\i new-sequence}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 concatenate} returns a new sequence containing all the elements of all the sequences, in order. {\i new-sequence} may non-destructively share structure with any of the input sequences, but it is not guaranteed to do so. {\f22 concatenate} returns a sequence whose value is an instance of the {\f22 class-for-copy} value for the first sequence. The {\f22 class-for-copy} value for the first sequence must be a subclass of {\f22 }, and it must support the init-keyword {\f22 size: } The {\i new-sequence} is created by calling {\f22 make} on the indicated class, with a {\f22 size:} initialization argument whose value is the sum of the sizes of the argument sequences.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} concatenate ("low-", "calorie")\par \pard\plain \s6\li960\ri480\tx2880\tx4800\tx6720 \f22\fs20 {\i "low-calorie"}{\b\i \par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b replace-subsequence! }{\i sequence insert-sequence} #key {\i start end} \tab [Generic Function]\par \pard\plain \li480\ri480\keepn \f16 {\f23 \'de} {\i result-sequence\par }\pard \li480\ri480\keepn \par \pard \li480\ri480\keepn This function returns a sequence with the same elements as {\i sequence}, except that elements of the indicated subsequence are replaced by all the elements of {\i insert-sequence} . The subsequence to be overridden begins at index {\i start} and ends at index {\i end}. If {\i start} is not supplied, it defaults to 0. If {\i end} is not supplied, it defaults to {\f22 size}({\i sequence}). {\i result-sequence} may or may not share structure with {\i sequence} , it may or may not be {\f22 ==} to {\i sequence} , and {\i sequence} may or may not be modified by the operation. {\i result-sequence } will not share structure with {\i insert-sequence}. {\i result-sequence} is not destroyed.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 ? define variable x = list ("a", "b", "c", "d", "e")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i // unspecified\par }? abcde := replace-subsequence! (x, #("x", "y", "z"), end: 1))\par {\i #("x", "y", "z", "b", "c", "d", "e")\par }? abcde := replace-subsequence! (x, #("x", "y", "z"), start: 4))\par {\i #("x", "y", "z", "b", "x", "y", "z")\par }? abcde := replace-subsequence! (x, #("a", "b", "c"), \par start: 2, end: 4))\par {\i #("x", "y", "a", "b", "c", "x", "y", "z")\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 reverse}{\i sequence }{\f23 \'de} {\i new-sequence}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 {\f22 reverse}{\i }creates a new sequence containing the same elements as {\i sequence}, but in reverse order. The result is generally of the same class as the {\i sequence}\~ argument. \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define constant x = #("bim", "bam", "boom")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i x\par ?} reverse(x)\par {\i #("boom", "bam", "bim")}\par {\i ?} x\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #("bim", "bam", "boom")\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 reverse!}{\i sequence1 }{\f23 \'de} {\i sequence2}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 {\f22 reverse!}{\i }returns a sequence containing the same elements as {\i sequence}, but in reverse order, possibly reusing {\i sequence\rquote s} storage to hold the result. Even if the storage is recycled, the result may or may not be {\f22 ==} to {\i sequence}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 sort}{\i sequence }{\f22 #key}{\i test stable }{\f23 \'de} {\i new-sequence}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 sort}{\i }returns a new sequence containing the elements of {\i sequence} sorted into ascending order. {\i test}, which defaults to {\f22 <}, is used to determine what an \ldblquote ascending order\rdblquote is. If {\i stable} is supplied and not {\f22 #f}, a possibly slower algorithm will be used that will leave in their original order any two elements, {\i x} and {\i y}, such that {\i test(x, y)} and {\i test(y, x)} are both false.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable numbers = #(3, 1, 4, 1, 5, 9)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i numbers}\par {\i ?} sort (numbers)\par {\i #(1, 1, 3, 4, 5, 9)\par ?} numbers\par {\i #(3, 1, 4, 1, 5, 9)\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 sort!}{\i sequence1 }{\f22 #key}{\i test stable }{\f23 \'de} {\i sequence2}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function is like {\f22 sort}, but may reuse the storage from {\i sequence} to form the result. The result may or may not be {\f22 ==} to {\i sequence}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 first}{\i sequence }{\f22 #key}{\i default }{\f23 \'de} {\i value}\tab [Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 second}{\i sequence }{\f22 #key}{\i default }{\f23 \'de} {\i value}\tab [Function]\par {\b\f22 third}{\i sequence }{\f22 #key}{\i default }{\f23 \'de} {\i value}\tab [Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 Each of these functions returns the indicated element of the {\i sequence} by calling {\f22 element} with the supplied arguments and the corresponding index.\par Note that because {\f22 element} is zero-based, {\f22 first(seq)} is equivalent to {\f22 element (seq, 0)} and {\f22 seq[0]}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 first-setter}{\i new-value sequence }{\f23 \'de} {\i new-value}\tab [Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 second-setter}{\i new-value sequence }{\f23 \'de} {\i new-value}\tab [Function]\par {\b\f22 third-setter}{\i new-value sequence }{\f23 \'de} {\i new-value}\tab [Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 Each of these functions sets the indicated element of the {\i sequence} and returns the {\i new-value}, by calling {\f22 element-setter }with the supplied arguments and the corresponding index.\par \pard \s2\li480\ri480\sa120 Note that because {\f22 element} is zero-based, {\f22 first-setter(val, seq)} is equivalent to {\f22 element-setter (val, seq, 0)} and {\f22 seq[0] := val}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 last}{\i sequence }{\f22 #key}{\i default }{\f23 \'de} {\i value}\tab [Generic\~Function]\par \pard\plain \li480\ri480 \f16 {\f22 last} returns the last element of {\i sequence}. If the sequence is empty, then the behavior of {\f22 last} depends on whether it was called with a {\i default} argument. If the {\i default} argument was supplied, its value is returned; otherwise, an error is signaled.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} last (#("emperor", "of", "china"))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i "china"}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 last-setter} {\i new-value} {\i mutable-sequence }{\f23 \'de} {\i new-value}\tab [Generic Function]\par \pard\plain \li480\ri480 \f16 Replaces the last element of {\i mutable-sequence} with {\i new-value}. {\i new-value} must obey any type restrictions for elements of {\i mutable-sequence} . An error is signaled if {\i mutable-sequence} is empty or unbounded.\par \pard \li480\ri480 \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define variable my-list = list (1, 2, 3)\par {\i ? }my-list\par {\i #(1, 2, 3)\par ? }last (my-list) := 4\par {\i 4\par ? }my-list\par {\i #(1, 2, 4)\par }\par {\i ? }define variable my-empty-vector = vector()\par {\i ? }my-empty-vector\par {\i #[]\par ? }last (my-empty-vector) := 4\par {\i // error\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 subsequence-position}{\i big pattern }{\f22 #key}{\i test count }{\f23 \'de} {\i index}\tab [Generic\~Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\i big} and {\i pattern} must be sequences. Searches {\i big} for a subsequence that is element-for-element equal to {\i pattern}, as determined by the {\i test} argument (which defaults to { \f22 ==}). That is, {\i test} is applied to the subsequence of {\i big} and corresponding elements of the {\i pattern} to determine whether a match has occurred. If {\i count} is specified, then the {\i count} th such subsequence is selected. If a subsequence is found, returns the index at which the subsequence starts; otherwise, returns {\f22 #f}. \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} subsequence-position ("Ralph Waldo Emerson", "Waldo")\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 6 \par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i sequence}{\i\fs20\dn4 1 }{\i }{\b\f22 = }{\i sequence}{\i\fs20\dn4 2}{\i } {\f23 \'de} {\i boolean}\tab [G.F. Method]\par \pard\plain \li540\ri480 \f16 For sequences, {\f22 =} returns {\f22 #f} unless {\i sequence}{\i\dn4 1} and {\i sequence}{\i\dn4 2} have the same size and elements with = keys are =. \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 key-test} {\i sequence} => {\i test-function}\tab [G.F. Method]\par \pard\plain \li360\ri480 \f16 The method of {\f22 key-test} for sequences returns the function {\f22 ==}.\par \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 The Instantiable Collection Classes\par \pard\plain \s2\li480\ri480\sa120 \f16 Dylan provides several standard instantiable collection classes, in addition to classes the user might wish to add. Each provides unique capabilities, strengths, and weaknesses.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Instantiable Class]\par \pard\plain \s2\li480\ri480\sa120 \f16 Arrays are structures whose elements are arranged according to a Cartesian coordinate system. An array element is referred to by a (possibly empty) series of indices. The length of the series must equal the rank of the array. Each index must be a non-ne gative integer less than the corresponding dimension. An array element may alternatively be referred to by an integer, which is interpreted as a row-major index.\par \pard \s2\li480\ri480\sa120 Arrays typically use space efficient representations, and the average time required to access a randomly chosen element is typically sublinear in the number of elements.\par \pard \s2\li480\ri480\sa120 {\f22 make} of {\f22 } supports the keywords {\f22 dimensions:} and {\f22 fill:}. {\f22 dimensions:} is required and must be a sequence of non-negative integers. {\f22 fill:} (default {\f22 #f} ) specifies the initial value to be placed in all elements of the array.\par \pard \s2\li480\ri480\sa120 Each concrete subclass of {\f22 } must either provide or inherit implementations of the functions {\f22 element} and {\f22 element-setter}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Sealed Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This sealed subclass of {\f22 } provides efficient storage for elements that are eight-bit characters. It also inherits lexicographic ordering from the {\f22 } class. {\f22 make} of {\f22 } supports the keywords {\f22 size:} and {\f22 fill:}. {\f22 size:} (default 0) tells how large a {\f22 } to create; {\f22 fill:} specifies the initial value of every element.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This subclass of {\f22 } implements double-ended queues. {\f22 make} of {\f22 } supports the keywords {\f22 size:} and {\f22 fill:}. {\f22 size:} (default 0) tells how large a {\f22 } to create; {\f22 fill:} (default {\f22 #f}) specifies the initial value of every element.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Sealed Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This sealed subclass of {\f22 } provides efficient support for linked lists. {\f22 make} of {\f22 } supports the keywords {\f22 size:} and {\f22 fill:}. {\f22 size:} (default 0) tells how large a {\f22 } to create; {\f22 fill:} (default {\f22 #f}) specifies the initial value of every element.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Sealed Instantiable Class]\par \pard\plain \li480\ri480 \f16 The class {\f22 } has only one instance, the empty list. The empty list is a direct instance of {\f22 } and an indirect instance of {\f22 }. Note that {\f22 } is not {\f22 ==} to { \f22 singleton (#())}.\par \pard \li480\ri480 \par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }object-class (#())\par {\i \par ? }define method f (x :: ) 1 end;\par {\i ? }define method f (x == #()) 2 end;\par {\i ? }define method f (x :: ) 3 end;\par {\i ? }f (#())\par {\i 2\par ? }f (#("chocolate", "vanilla"))\par {\i 3\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s2\li480\ri480\sa120 \f16 A subclass of {\f22 } that represents arithmetic sequences. Some ranges can be infinitely large. The permitted initargs are {\f22 from:, to:, above:, below:, by:, }and {\f22 size:}.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 from:} (default 0) is the first value in the range. {\f22 by:} (default 1) is the step between consecutive elements of the range. {\f22 size:} specifies the size of the range. {\f22 range:} has three additional initargs, {\f22 to:}, {\f22 above: }and {\f22 below:}, which constrain the range. {\f22 to: }is an inclusive bound, {\f22 above: }is an exclusive lower bound and {\f22 below }is an exclusive upper bound. {\f22 above: }and { \f22 below: }constrain the range independent of the sign of {\f22 by:.} It is permissible to specify a range that runs from a higher to a lower value by specifying a negative value for {\f22 by:}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Sealed Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This sealed subclass of {\f22 } supports elements of any class. {\f22 make} of {\f22 } supports the keywords {\f22 size:} and {\f22 fill:}. {\f22 size:} (default 0) specifies the size of the {\f22 }; {\f22 fill:} (default {\f22 #f}) specifies the initial value of every element.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This subclass of {\f22 } supports elements of any class. {\f22 make} of {\f22 } supports the keywords {\f22 size:}, {\f22 fill:}. {\f22 size:} (default 0) tells how large a {\f22 } to create; {\f22 fill:} (default {\f22 #f}) specifies the initial value of every element.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 A subclass of {\f22 } whose elements are all characters. {\f22 } supports lexicographic comparison. {\f22 } has no direct instances; calling {\f22 make} on {\f22 } will return an instance of a concrete subclass of {\f22 }. {\f22 make} of {\f22 }supports the init-keywords {\f22 size:} and {\f22 fill:}. {\f22 size:} (default {\f22 0}) tells how large a string to create.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Also called a hashtable, a table is an unordered mapping between arbitrary keys and elements. Tables are the only predefined collections that are unstable under iteration. {\f22 make} of { \f22
} supports the init-keyword {\f22 size:}. W hen specified, it provides a hint to the implementation of the class as to the expected number of elements to be stored in the table, which might be used to control how much space to initially allocate for the table. The default value is unspecified. \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The class {\f22
} provides an implementation of the Iteration Protocol, using the function {\f22 table-protocol}. Every concrete subclass of {\f22
} must provide or inherit a method for { \f22 table-protocol}. See the Table Protocol section for details.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\f22
} has no direct instances; calling {\f22 make} on {\f22
} will return an instance of {\f22 }.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Sealed Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 A subclass of {\f22
} that compares keys using {\f22\fs20 ==.}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Sealed Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This sealed subclass of {\f22 } provides efficient storage for elements that are sixteen-bit Unicode characters. It inherits lexicographic ordering from the {\f22 } class. { \f22 make} of {\f22 } supports the keywords {\f22 size:} and {\f22 fill:}. {\f22 size:} (default {\f22 0}) tells how large a {\f22 } to create; {\f22 fill:} (default {\f22 ' '} ) specifies the initial value of every element.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Instantiable Class]\par \pard\plain \s2\li480\ri480\sa120 \f16 The subclass of whose instances are of rank one (i.e. have exactly one dimension). All one-dimensional arrays are vectors.\par {\f22 } has no direct instances; calling {\f22 make} on {\f22 } returns an instance of {\f22 }.\par Each concrete subclass of {\f22 } must either provide or inherit an implementation of {\f22 size} that shadows the method provided by {\f22 }.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Operations on Arrays\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 dimensions} {\i array} {\f23 \'de}{\i sequence}\tab [Function]\par \pard\plain \li480\ri480 \f16 Returns the dimensions {\i }of {\i array}, as a sequence of integers. The consequences are undefined if the resulting sequence is modified.\par \pard \li480\ri480 This function forms the basis for all the other array operations. Each concrete subclass of {\f22 } must either provide or inherit an implementation of this function.\par \pard\plain \s6\li960\ri480\sb240\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} dimensions (make (, dimensions: #(4, 4)))\par \pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i #(4, 4)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 size} {\i array} {\f23 \'de} {\i size} \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The method for {\f22 } is equivalent to {\f22 reduce (\\*, 1, dimensions (}{\i\f22 array}{\f22 ))}.\par \pard \s2\li480\ri480\sa120 \par \pard \s2\li480\ri480\sa120 There is a standard library for arrays, containing the following generic functions and methods, as defined below: {\f22 rank}, {\f22 row-major-index}, {\f22 aref}, {\f22 aref-setter}, and {\f22 dimension}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 rank} {\i array} {\f23 \'de} {\i rank}\tab [Generic Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 Returns the number of dimensions (the rank) of {\i array}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 rank} {\i array} {\f23 \'de} {\i rank}\tab [G. F. Method]\tab \par \pard\plain \s2\li480\ri480\sa120 \f16 The method for {\f22 } computes {\f22 rank} by calling {\f22 size} on the {\f22 dimensions} of {\f22 array}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 row-major-index} {\i array} {\f22 #rest} {\i subscripts} {\f23 \'de }{\i index} \tab [Generic Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 Computes the position according to the row-major ordering of {\f22 array} for the element that is specified by {\f22 subscripts} , and returns the offset of the element in the indicated position from the start of the {\f22 array} . An error is signaled if the number of subscripts is not equal to the rank of the array. An error is signaled if any of the subscripts are out of bounds for array.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 row-major-index} {\i array} {\f22 #rest} {\i subscripts} {\f23 \'de }{\i index} \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The method for {\f22 } computes the {\f22 index} using the result of calling {\f22 dimensions} on the {\f22 array}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 aref} {\i array} {\f22 #rest} {\i indices} {\f23 \'de }{\i element} \tab [Generic Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 Returns the element of {\i array} indicated by {\i indices}. An error is signaled if the number of {\i indices} is not equal to the rank of the {\i array}. An error is signaled if any of the {\i indices} are out of bounds for {\i array}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 aref} {\i array} {\f22 #rest} {\i indices} {\f23 \'de }{\i element} \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The method for {\f22 } calls {\f22 element} on the {\i array}, using the result of applying {\f22 row-major-index} to the {\i array}and {\i indices} as the key.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 aref-setter}{\f22\fs18 }{\i new-value}{\i\fs18 }{\i array }{\f22 #rest}{\f22\fs18 }{\i indices} {\f23 \'de }{\i new-value } \tab [Generic Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 Sets the element of {\i array} indicated by {\i indices} to the new value and returns the new value. An error is signaled if the number of {\i indices} is not equal to the rank of the {\i array} . An error is signaled if any of the {\i indices} are out of bounds for {\i array}. An error is signaled if the {\i array}is limited to hold objects of a particular type and the new value is not an instance of that type.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 aref-setter}{\fs18 }{\i new-value}{\i\fs18 }{\i array }{\i\f22 }{\f22 #rest}{\fs18 }{\i indices} {\f23 \'de }{\i new-value }\tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The method for {\f22 } calls {\f22 element-setter} on the array and new value, using the result of applying {\f22 row-major-index} to the {\f22 array} and indices as the key.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 dimension} {\i array axis} {\f23 \'de }{\i dimension } \tab [Generic Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 Returns the {\f22 axis} dimension of {\f22 array}. {\f22 axis} must be a non-negative integer less than the rank of {\f22 array}. An error is signaled if {\f22 axis} is out of bounds for {\f22 array}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 dimension} {\i array axis} {\f23 \'de }{\i dimension } \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The method for {\f22 } calls {\f22 element} on the result of calling {\f22 dimensions} on the {\f22 array}, using the {\f22 axis} number as the key.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Operations on Deques\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 push} {\i deque new-value }{\f23 \'de} {\i deque}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 push} augments {\i deque} by adding {\i new-value} to the front of the deque.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 pop} {\i deque }{\f23 \'de} {\i first-element}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 pop} removes the first element from {\i deque} and returns it.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 push-last} {\i deque new-value }{\f23 \'de} {\i deque}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 push-last} augments {\i deque} by adding {\i new-value} to the end of the deque.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 pop-last} {\i deque }{\f23 \'de} {\i last-element}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 pop-last} removes the last element from {\i deque} and returns it.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 add!}{\i deque new-value }{\f23 \'de} {\i deque}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method is the same as {\f22 push}. That is, the result is {\f22 ==} to {\i deque}, and {\i deque} is destructively modified by this operation.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove!}{\i deque value }{\f22 #key}{\i test count }{\f23 \'de} {\i deque}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The result of {\f22 remove!} on a deque is {\f22 ==} to the {\i deque} argument. {\i deque} is destructively modified by this operation.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Operations on Lists\par \pard\plain \s2\li480\ri480\sa120 \f16 The {\f22 } class is partitioned into two subclasses, {\f22 } and {\f22 }. The classes {\f22 }, {\f22 }, and {\f22 } are sealed; users cannot create new subclasses of {\f22 }.\par \pard \s2\li480\ri480\sa120 An {\b improper list} is a list that is not terminat ed by the empty list, either because it is terminated by something that is not a list, or because it is circular and thus non-terminating. Except when their behavior on improper lists is documented explicitly, collection or sequence functions are not guar anteed to return an answer when an improper list is used as a collection or a sequence. At the implementation\rquote s option, these functions may return the correct result, signal a {\f22 } , or (in the case of a circular list) fail to return.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 pair}{\i head tail }{\f23 \'de} {\i pair\tab }[Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 pair}{\i }creates a new pair whose head and tail values are as indicated.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} pair (1, 2)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(1 . 2)\par ?} pair (1, #(2, 3, 4, 5))\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #(1, 2, 3, 4, 5)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 list} {\f22 #rest}{\i args }{\f23 \'de} {\i list\tab }[Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 list} returns a list of the {\i args}, in order.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} list (1, 2, 3)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(1, 2, 3)\par ?} list (4 + 3, 4 - 3)\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #(7, 1)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 head} {\i list }{\f23 \'de} {\i object\tab }[Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If {\i list} is a pair, this function returns the value of the head slot. Otherwise, {\i list} is the empty list, and {\f22 head} returns the empty list.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} head (#(4, 5, 6))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i 4\par ?} head (#())\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #()}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 tail}{\i list }{\f23 \'de} {\i object\tab }[Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If {\i list} is a pair, this function returns the value of the tail slot. Otherwise, {\i list} is the empty list, and {\f22 tail} returns the empty list.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} tail (#(4, 5, 6))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(5, 6)\par ?} tail (#())\par {\i #()}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 head-setter}{\i object pair }{\f23 \'de} {\i object\tab }[Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function sets the head of {\i pair} to contain {\i object} and returns {\i object}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable x = list (4, 5, 6)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(4, 5, 6)\par ?} head (x) := 9\par {\i 9\par ? }x\par {\i #(9, 5, 6)\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 tail-setter}{\i object pair }{\f23 \'de} {\i object\tab }[Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function sets the tail of {\i pair} to contain {\i object} and returns {\i object}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable x = list (4, 5, 6)\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(4, 5, 6)\par ?} tail (x) := #(9, 8, 7)\par {\i #(9, 8, 7)\par ? }x\par {\i #(4, 9, 8, 7)\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 add!}{\i list element }{\f23 \'de} {\i pair}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Equivalent to {\f22 (pair} {\i element list}{\f22 )}. That is, the result shares structure with {\i list} but will not be {\f22 ==} to {\i list.}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove!}{\i list element }{\f22 #key}{\i test count}{\f23 \'de} {\i list}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 remove!} destructively modifies {\i list}. The result is not necessarily {\f22 ==} to {\i list}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 size}{\i list} {\f23 \'de} {\i \{integer }{\i\fs16 or}{\i #f\}}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 For circular lists, {\f22 size} is guaranteed to terminate and return {\f22 #f}. For non-circular lists, {\f22 size} returns an integer size value.\par \pard\plain \li540\ri480\tx540\tqr\tx7680 \f16 {\b\fs20 \par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i list}{\i\fs18\dn4 1}{\fs18\dn4 }{\b\f22 =} {\i list}{\i\fs18\dn4 2}{\i }{\f23 \'de} {\i boolean}\tab [G.F. Method]\par \pard\plain \li540\ri480 \f16 For lists, {\f22 =} returns {\f22 #f} unless the two lists are the same size, corresponding elements of {\i list}{\i\fs18\dn4 1} and {\i list}{\i\fs18\dn4 2} are {\f22 =} and the final tails are {\f22 =}. \par \pard \li540\ri480 \par \pard\plain \s9\fi-480\li480\ri480\keepn\tx480\tqr\tx9360 \f16 {\i list }{\b\f22 =} {\i sequence} {\f23 \'de} {\i boolean}\tab [G.F. Method]\par \pard \s9\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 {\i sequence }{\b\f22 =} {\i list} {\f23 \'de} {\i boolean}\tab [G.F. Method]\par \pard\plain \li540\ri480 \f16 For mixed lists and sequences, {\f22 =} returns {\f22 #f} unless the {\i list} is not a dotted list, both have the same size, and elements with {\f22 =} keys are {\f22 =}.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Operations on Ranges\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 range} {\f22 #key} {\i from to above below by size }{\f23 \'de} {\i range}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Creates a range. {\i from} (default 0) is the first value in the range. {\i by} (default 1) is the step between consecutive elements of the range. {\i to}, {\i above }and {\i below} , constrain the range. {\i to }is an inclusive bound, {\i above }is an exclusive lower bound and {\i below }is an exclusive upper bound. {\i above }and {\i below }constrain the range independent of the sign of {\i by.}{\f22 }See {\f22 }\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 member?} {\i val range} {\f22 #key} {\i test} {\f23 \'de} {\i boolean\tab }[G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 I}f {\i range} is unbounded, this method is guaranteed to terminate if {\i test} is {\f22 == }(the default).\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 size} {\i range }{\f23 \'de} {\i size}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 For unbounded ranges, {\f22 size} always terminates and returns {\f22 #f}. For finite ranges, {\f22 size} returns an integer.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 copy-sequence} {\i range }{\f22 #key}{\i start end }{\f23 \'de} {\i new-range\tab }[G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 When applied to a range, {\f22 copy-sequence} returns another range, even though the {\f22 class-for-copy} of a range is the {\f22 } class.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i range1 }{\b\f22 =}{\i range2 }{\f23 \'de} {\i boolean\tab }[G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 When called with two ranges, {\f22 =} always terminates, even if one or both ranges are unbounded in size.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 reverse}{\i range }{\f23 \'de} {\i new-range}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Reversing a range produces another range. An unbounded range cannot be reversed.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 reverse!}{\i range }{\f23 \'de} {\i range}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The result of {\f22 reverse!} on a range is {\f22 ==} to the {\i range} argument. An unbounded range cannot be reversed.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 intersection}{\i range1 range2 } {\f22 #key} {\i test} {\f23 \'de} {\i range}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 intersection} applied to two ranges and a test of {\f22 ==} (the default) will produce another range as its result, even though the {\f22 class-for-copy} of a range is not {\f22 } . If either {\i range1} or {\i range2} is unbounded, this method is guaranteed to terminate only if the {\i test} is {\f22 ==}.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Operations on Stretchy Vectors\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 add!}{\i stretchy-vector new-element }{\f23 \'de} {\i stretchy-vector}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 add!}{\i }adds {\i new-element} at the end of {\i stretchy-vector}. The result is {\f22 ==} to {\i stretchy-vector}, and {\i stretchy-vector} is destructively modified by this operation.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove!}{\i stretchy-vector element }{\f22 #key}{\i test count }{\f23 \'de} {\i stretchy-vector}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The result of {\f22 remove!} on a stretchy vector is {\f22 ==} to {\i stretchy-vector,} and {\i stretchy-vector} is destructively modified by this operation.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Operations on Strings\par \pard\plain \s2\li480\ri480\sa120 \f16 Strings support lexicographic ordering through a shared implementation of {\f22 <}:\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\i string1 }{\b\f22 <} {\i string2 }{\f23 \'de} {\i boolean}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 When both arguments are strings, {\f22 <} compares strings lexicographically, using {\f22 <} on corresponding elements. If one string is a strict prefix of the other, the shorter string is considered the \ldblquote smaller\rdblquote one. \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 For variations on string comparison (such as comparisons that ignore case), different comparison operators must be used.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as-lowercase}{\i string }{\f23 \'de} {\i new-string}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method is equivalent to {\f22 map (as-lowercase, } {\i string}{\f22 )}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable x = "Van Gogh"\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i x\par ?} as-lowercase (x)\par {\i "van gogh"}{\b\i \par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as-lowercase!}{\i string }{\f23 \'de} {\i string}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method is equivalent to {\f22 map-into (} {\i string} {\f22 , as-lowercase, } {\i string}{\f22 )}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable x = "Van Gogh"\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i x\par ?} as-lowercase! (x)\par {\i "van gogh"\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as-uppercase}{\i string }{\f23 \'de} {\i new-string}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method is equivalent to {\f22 map} ({\f22 as-uppercase,} {\i string}{\f22 )}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable x = "Van Gogh"\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i x\par ?} as-uppercase (x)\par {\i "VAN GOGH"\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as-uppercase!}{\i string }{\f23 \'de} {\i string}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method is equivalent to {\f22 map-into (} {\i string }{\f22 , as-uppercase} , {\i string}{\f22 )}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define variable x = "Van Gogh"\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i x\par ?} as-uppercase (x)\par {\i "VAN GOGH"\par \par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element} {\i unicode-string index} #key {\i default} {\f23 \'de } {\i character} \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The class {\f22 } provides a constant time implementation for the {\f22 element} function.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element-setter} {\i character} {\i unicode-string index} {\f23 \'de } {\i character} \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The class {\f22 } provides a constant time implementation for the {\f22 element-setter} function.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element} {\i byte-string index} #key {\i default} {\f23 \'de } {\i character} \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The class {\f22 } provides a constant time implementation for the {\f22 element} function.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element-setter} {\i character} {\i byte-string index} {\f23 \'de } {\i character} \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The class {\f22 } provides a constant time implementation for the {\f22 element-setter} function.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Operations on Tables\par \pard\plain \s2\li480\ri480\sa120 \f16 Tables are \ldblquote stretchy,\rdblquote in that they allow the addition and removal of keys, but they are not stretchy sequences (because they are not sequences). {\f22
} and its subclasses are the only predefined classes that are stretchy but are not stretchy sequences.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22
} provides an implementation of the Iteration Protocol, using the function {\f22 table-protocol}. Every concrete subclass of {\f22
} must provide or inherit a methodfor { \f22 table-protocol}. See the Table Protocol section for details.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remove-key!} {\i table key }{\f23 \'de} {\i table}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 remove-key!} modifies {\i table} so that it no longer has a key equal to {\i key}. Equality is determined by the table\rquote s test function.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element-setter}{\i new-value table key }\tab [G. F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Even if no element with the given key exists, {\f22 element-setter} for a table will add key and new-value to the table.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Operations on Vectors\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 vector}{\f22 #rest}{\i args }{\f23 \'de} {\i vector}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function returns a vector of the {\i args}, in order.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 dimensions} {\i vector} {\f23 \'de} {\i sequence}\tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 Returns a sequence whose single element is the size of the vector.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element} {\i simple-object-vector} {\i index} #key {\i default} {\f23 \'de} {\i element} \tab [G. F. Method]\par \pard\plain \s2\li480\ri480\sa120 \f16 The class provides a constant time implementation for the {\f22 element} function.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element-setter} {\i new-element} {\i simple-object-vector} {\i index} \tab [G. F. Method]\line {\f23 \'de} {\i new-element} \par \pard\plain \s2\li480\ri480\sa120 \f16 The class {\f22 } provides a constant time implementation for the {\f22 element-setter} function.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 The Iteration Protocol\par \pard\plain \s2\li480\ri480\sa120 \f16 All collections implement an {\b iteration protocol }that allows iteration to be specified abstractly. Many higher level operations on collections can be defined in terms of only the iteration protocol.\par \pard \s2\li480\ri480\sa120 The iteration protocol centers on the notion of a \ldblquote state\rdblquote object for an iteration. Each collection class chooses its own most appropriate representation for an iteration state, and only the functions of the iteration protocol are affected by this choice.\par Use of the iteration protocol is based on the assumption that the collection over which iteration occurs remains static for the duration of the iteration. That is, arbitrary changes to a mutable collection while an iteration is in prog ress may cause the iteration to produce incorrect results.\par \pard \s2\li480\ri480\sa120 In general, two or more iterations over the same collection are not guaranteed to produce the same values in the same order, even if the collection is unaltered (but see the next section on Iteration Stability).\par \pard \s2\li480\ri480\sa120 The iteration protocol consists of the following two functions:\par \pard\plain \s9\fi-480\li480\ri480\sb240\keepn\tx480\tqr\tx9360 \f16 {\b\f22 forward-iteration-protocol} {\i collection}\tab [Generic Function]\par \pard\plain \li480\ri480\tx720\tx1260\tx4760 \f16 {\f22 \tab }{\f23 \'de}{\f22 \tab initial-state\tab :: \par }\pard \li480\ri480\tx720\tx1260\tx4760 {\f22 \tab \tab limit\tab :: \par \tab \tab next-state\tab :: \par \tab \tab finished-state?\tab :: \par \tab \tab current-key\tab :: \par \tab \tab current-element\tab :: \par \tab \tab current-element-setter\tab :: \par \tab \tab copy-state}{\i\f22 \tab }{\f22 :: \par }\pard \li480\ri480\tx5300 {\f22 \par }\pard \li480\ri480 The eight values returned by this function are used to implement iteration over the {\i collection} argument. Only the {\i collection} argument this function was called with may be used as the {\i collection} argument to functions returned by this function. Only the {\f22 initial-state} object and state objects returned by the {\f22 next-state} and {\f22 copy-state} functions may be used as the {\i state} argument to functions retur ned by this function. Only the {\f22 limit} object may be used as the {\i limit} argument to the {\f22 finished-state?} function.\par \pard \li480\ri480 \par \pard \li360\ri480 {\f22 initial-state\par }\pard \li540\ri480 The initial iteration state object.\par \par \pard \li360\ri480 {\f22 limit\par }\pard \li540\ri480 A value that may be used by the {\f22 finished-state?} function to determine whether the iteration has been completed.\par \pard \li360\ri480 \par \pard \fi-180\li540\ri480 {\f22 next-state }{\i collection state} {\f22 => }{\i new-state}{\i\f22 \par }\pard \li540\ri480 This function \ldblquote steps\rdblquote the iteration by producing a new state from the associated {\i collection} and {\i state.} The {\f22 next-state} function may or may not modify the {\i state} argument; it is an error t o use a state value after it has been passed to the associated {\f22 next-state} function. The {\f22 copy-state} function provides a mechanism for saving a particular state in an iteration for later resumption. \par \pard \li480\ri480 \par \pard \li360\ri480 {\f22 finished-state? }{\i collection state limit} {\f22 => }{\i boolean}{\i\f22 \par }\pard \li540\ri480 This function returns {\f22 #t} if the iteration of the collection has been completed, i.e., there are no other elements of the collection to consider. It returns {\f22 #f} otherwise. It is an error to use a finished state in a call to the associated {\f22 next-state}, {\f22 current-element}, {\f22 current-key} or {\f22 current-element-setter} functions.\par \pard \li360\ri480 {\f22 \par }\pard \li360\ri480 {\f22 current-key }{\i collection state} {\f22 => }{\i key}{\i\f22 \par }\pard \li540\ri480 This function returns the unique key associated with {\i state } in the {\i collection}. If the {\f22 current-key} function were called once with each {\i state} value produced during an iteration over a collection, the resulting sequence of values would contain every key from the collection exactly once.\par \pard \li360\ri480 {\f22 \par }\pard \li360\ri480 {\f22 current-element }{\i collection state} {\f22 => }{\i element}{\i\f22 \par }\pard \li540\ri480 This function returns the element of {\i collection} \ldblquote currently indicated\rdblquote by {\i state}.\par \pard \li480\ri480 {\f22 \par }\pard \li360\ri480 {\f22 current-element-setter }{\i value} {\i collection state}{\i\f22 }{\f22 => }{\i value}{\i\f22 \par }\pard \li540\ri480 This function sets the element of {\i collection} indicated by {\i state} to {\i value} and returns {\i value.} If the collection is not mutable, i.e. is not a generalized instance of {\f22 } , this function instead signals an error.\par \pard \li480\ri480 {\f22 \par }\pard \li360\ri480 {\f22 copy-state }{\i collection state} {\f22 => }{\i new-state}{\i\f22 \par }\pard \li540\ri480 This function returns a state which represents the same point in the iteration over {\i collection} as is represented by {\i state.} \par \pard \li480\ri480 {\f22\fs20 \par }\pard\plain \s9\fi-480\li480\ri480\sb240\keepn\tx480\tqr\tx9360 \f16 {\b\f22 backward-iteration-protocol} {\i collection}\tab [Generic Function]\par \pard\plain \li480\ri480\keepn\tx720\tx1260\tx4760 \f16 {\f22 \tab }{\f23 \'de}{\f22 \tab final-state\tab :: \par }\pard \li480\ri480\keepn\tx720\tx1260\tx4760 {\f22 \tab \tab limit\tab :: \par \tab \tab previous-state\tab :: \par \tab \tab finished-state?\tab :: \par \tab \tab current-key\tab :: \par \tab \tab current-element\tab :: \par \tab \tab current-element-setter\tab :: \par \tab \tab copy-state\tab :: \par }\pard \li480\ri480 {\f22\fs20 \par }\pard \li480\ri480 Some collection classes that are stable under iteration additionally support the ability to iterate in the reverse of the natural order, by providing a method on the generic function {\f22 backward-iteration-protocol} . The eight values returned by this function are analogous to the corresponding values returned by {\f22 forward-iteration-protocol}, except that the {\f22 final-state} object indicates the last element in the collection and the {\f22 previous-state} returns a state for the preceding element.\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard \s2\li480\ri480\sa120 An example of the use of the iteration protocol is the following definition of a single-argument version of the {\f22 do} function:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method do1 (f :: , c :: )\par let (init, limit, next, end?, key, elt) = \par forward-iteration-protocol(c);\par for (state = init then next(c, state),\par \tab until end?(c, state, limit))\par f(elt(c, state));\par end for;\par end method do1;\par \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 The Table Protocol\par \pard\plain \s2\li480\ri480\sa120 \f16 Tables, also known as hashtables, map arbitrary keys to elements. Table keys may be any object, including complex objects such as strings. Each table has an associated {\b equivalence predicate} which is used to compare keys. The table maps keys that are equivalent under the predicate to the same table element.\par \pard \s2\li480\ri480\sa120 An equivalence predicate is a boolean function of two arguments that returns true if an d only if the arguments are "the same" according to some specified criteria. For a function to be used as an equivalence predicate, it must be reflexive, commutative, and transitive. That is, for a function F and any arguments X, Y, and Z in the domain o f F, it must be true that (1) F(X,X) is true, (2) F(X,Y) is true if and only if F(Y,X) is true, and (3) if both F(X,Y) and F(Y,Z) are true then F(X,Z) is true.\par \pard \s2\li480\ri480\sa120 An {\b equivalence class} (for an equivalence predicate) is a set of objects, or potential objects, that are all the same under the specified equivalence predicate and different from all objects not in the class. (This \ldblquote class\rdblquote is not meant to refer to Dylan classes as in {\f22 define class}.)\par An object is said to be {\b visibly modified} with respect to an equivalence predicate if the modification changes the equivalence class of the object. The modifications that are visible to an equivalence predicate are determined by the definition of the predicate.\par \pard \s2\li480\ri480\sa120 If an object X is a key in a table T and is visibly modified with regard to the test function of T, then the consequences are unspecified if any of the following objects are used as a key in any subsequent operations on T: \par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab The original object, X.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab Some object Y that is in the same equivalence class (as determined by the test function) as X prior to the modification of X.\par \bullet \tab Some object Z that is in the same equivalence class (as determined by the test function) as X after the modification of X.\par \pard\plain \s2\li480\ri480\sa120 \f16 Each table also has an associated {\b hash function}, which is a function that relates table keys and table elements by computing {\b hash codes}. A hash code is a conceptual object consisting of a {\b hash id} and its associated {\b hash state} . (It is not an actual Dylan object.) A hash id is an integer encoding of an object. A hash state is an object of implementation-dependent type which is associated with a particular hash id and can be used by the implementation to determine whether the hash id has been invalidated. All hash functions have one argument, a key, and return two values, a hash id and a hash state, which together represent the hash code.\par \pard \s2\li480\ri480\sa120 Each hash function is associated with a specific equivalence predicate, and must obey the following constraints:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 1. \tab The domain of the hash function must include the domain of valid arguments to the corresponding equivalence predicate. A hash function need not be defined for all Dylan objects, only those which are acceptable as arguments to the equivalence predicate. \par \pard \s21\fi-360\li840\ri480\sa160 2. \tab All objects in a given equivalence class have the same ({\f22 =}) valid hash id, where validity is determined from the associated hash state.\par \pard\plain \s2\li480\ri480\sa120 \f16 In addition, a hash function should have the property that the hash ids computed by it are well distributed over the range of possible values. That is, it should be unlikely that two randomly chosen equivalence classes have the same valid hash id.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx1080\tqr\tx9360 \f16 {\b\f22 table-protocol}{\f22 }{\i table}\tab [Generic Function]\line {\f23 \'de}\tab {\i test-function hash-function}\par \pard\plain \s2\li480\ri480\sa120 \f16 The class {\f22
} provides an implementation of the Iteration Protocol, using the function {\f22 table-protocol}. Every concrete subclass of {\f22
} must provide or inherit a method for {\f22 table-protocol}. {\f22 table-protocol} returns the following functions:\par \pard \s2\li540\ri480\sa120 {\f22 test-function} {\i key1 key2} {\f23 \'de} {\i boolean}\par \pard \s2\li720\ri480\sa120 The {\f22 test-function} is used to compare keys. It returns true if the keys are members of the same equivalence class according to the table\rquote s equivalence predicate.\par \pard \s2\li540\ri480\sa120 {\f22 hash-function} {\i key} {\f23 \'de} {\i id} {\i state\par }\pard \s2\li720\ri480\sa120 The {\f22 hash-function} computes the hash code of the {\i key}, using the hash function associated with the table\rquote s equivalence predicate. The hash code is returned as two values, {\i id} (an integer) and {\i state} (a hash state).\par \pard \s2\li480\ri480\sa120 Users can choose either to define a new subclass of {\f22
} for every test function they use, or to define a generic subclass of {\f22
} which holds its test function and hash function in slots, according to their particular needs.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx1080\tqr\tx9360 \f16 {\b\f22 table-protocol}{\f22 }{\i object-table}\tab [G. F. Method]\line {\f23 \'de}\tab {\i test-function hash-function\par }\pard\plain \s2\li480\ri480\sa120 \f16 The method for {\f22 } returns {\f22 ==} as the {\i test-function} and {\f22 object-hash} (described below) as the {\i hash-function}. It could be written as\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method table-protocol (table :: )\par => test-function :: , hash-function :: ;\par values(\\==, object-hash);\par end method table-protocol;\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 merge-hash-codes}{\f22 }{\i id1 state1 id2 state2 }{\f22 #key} {\i ordered} \tab [Function]{\f22 \par }\pard\plain \s2\li480\ri480\sa120 \f16 {\f23 \'de}\tab {\i merged-id merged-state}{\f22 \par }\pard \s2\li480\ri480\sa120 This function computes a new hash code by merging the argument hash codes in some implementation dependent way. {\i id1}, {\i id2}, and {\i merged-id } are all integers. {\i state1}, {\i state2}, and {\i merged-state } are all hash states. {\i ordered} is a boolean and determines whether the algorithm used to perform the merge is permitted to be order dependent. If {\f22 #f} , which is the default, then the merged result must be independent of the order in which the argument pairs are provided. If true, then the order of the argument pairs matters because the algorithm used need not be either commutative or associative in thi s case. Providing a true value for {\i ordered} is recommended when doing so will not cause the hash function to violate the second constraint on hash functions, because it may result in a better distribution of hash ids.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 $permanent-hash-state}\tab [Constant]\par \pard\plain \s2\li480\ri480\sa120 \f16 An implementation-dependent hash state that indicates that the associated hash id is always valid, and does not depend on any mutable property of the object that can be changed without a visible modification to the object.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 object-hash}{\f22 }{\i object} {\f23 \'de} {\i id state}\tab [Function]\par \pard\plain \s2\li480\ri480\sa120 \f16 This is the hash function for the equivalence predicate {\f22 ==}. It is made available as a tool for writing hash functions in which the object identity of some component o f a key is to be used in computing the hash code. It returns a hash id (an integer) and associated hash state for the object, computed in some implementation dependent manner. The values returned by {\f22 object-hash } when called repeatedly on the same object might not be the same for each call. If the {\i id} value changes then the {\i state} value will also change.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Iteration Stability and Natural Order\par \pard\plain \s2\li480\ri480\sa120 \f16 A collection is {\b stable under iteration} if any two iterations over the collection are guaranteed to produce the same va lues in the same order (unless, of course, the collection has been modified). A collection that is not stable under iteration is said to be {\b unstable under iteration}. \par \pard \s2\li480\ri480\sa120 Collections in general are not required to be stable under iteration, although several important subclasses are so required. In particular, sequences are required to be stable under iteration.\par \pard \s2\li480\ri480\sa120 The order in which elements (and keys) are enumerated by the iteration protocol for a particular iteration is known as the \ldblquote natural order\rdblquote for that it eration over the collection. If a collection is stable under iteration, then every iteration over that collection will have the same natural order, and we may speak of the natural order of the collection itself. Most of the higher order operations are re quired to operate in \ldblquote natural order,\rdblquote usually for the purpose of understanding interactions among side effects. \par Collection Keys All collections in Dylan are \ldblquote keyed\rdblquote collections, i.e., all collections can be viewed abstractly as partial functions that take keys to elements. (This choice precludes pure sets from being considered collections, although it is straightforward simply to ignore the keys for a collection and consider it simply as a set of elements.) The {\f22 element} function implements this partial mapping of keys to elements. In addition, it is possible to obtain all the keys for a given collection, formed into a sequence collection.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element} {\i collection key }{\f22 #key}{\i default} {\f23 \'de} {\i element}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 element} returns the element associated with {\i key} in {\i collection}. If no element is associated with {\i key}, then the behavior of {\f22 element} depends on whether it was called with a {\i default} argument: if a {\i default} argument was passed, its value is returned; otherwise, an error is signaled.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 All collections are required to implement {\f22 element}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 key-sequence} {\i collection} {\f23 \'de} {\i keys}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 key-sequence} returns a sequence containing the keys of {\i collection}. Although elements may be duplicated in a collection, keys, by their nature, must be unique; two different ele ments in a collection may not share a common key, even though distinct keys may yield identical elements.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The order in which the keys from {\i collection} appear in the key sequence is unspecified if {\i collection} is unstable under iteration. In particular, different calls to {\f22 key-sequence} with the same argument may yield differently ordered key sequences. If {\i collection}\~ is stable under iteration, however, the resulting sequence of keys will be in the natural order for {\i collection}.\par \pard\plain \s2\li480\ri480\sa120 \f16 Iterating through a collection of ten involves examining keys as well as elements. To allow some freedom of implementation, the protocol recognizes two strategies for associating keys with states of iteration: explicitly or implicitly. The distinction between these strategies gives rise to two covering subclasses of {\f22 }. Every concrete subclass of {\f22 } must also be a subclass of either {\f22 } or {\f22 } (or both):\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }{\i \tab }[Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is the class of all collections that are not sequences. \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is a subclass of {\f22 } whose keys are consecutive integers ranging from zero up to (but not including) the size of the sequence. \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 Sequences must be stable under iteration, and the iteration order must match the order of keys. Thus, the key associated with a sequence\rquote s iteration state can be determined by keeping a counter in parallel with the iteration state, as in the next example.\par \pard\plain \s2\li480\ri480\sa120 \f16 Since every collection must be a sequence or an explicit-key-collection, it is always possible to keep track of keys during an iteration by defining appropriate methods on {\f22 } and {\f22 .}{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }That is, no more than two implementations are required for a function that operates on both keys and elements.}}{\fs18 } For example, consider these two methods for a function that applies a function {\f22 f} to each key-and-element pair in a collection. The method on {\f22 } uses the {\f22 current-key} function returned by {\f22 forward-iteration-protocol}; the method on {\f22 } keeps a counter \ldblquote alongside\rdblquote the state during the iteration:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method do-with-keys (f :: , \par c :: )\par let (init, limit, next, end?, key, elt) = \par forward-iteration-protocol(c);\par for (state = init then next(c, state),\par \tab until end?(c, state, limit))\par f(key(c, state), elt(c, state));\par end for;\par end method do-with-keys;\par \pard\plain \li480\ri480 \f16 \par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method do-with-keys (f :: , c :: )\par let (init, limit, next, end?, key, elt) = \par forward-iteration-protocol(c);\par for (key :: from 0,\par \tab state = init then next(c, state),\par \tab until end?(c, state, limit))\par \tab f(key, elt(c, state));\par end for;\par end method do-with-keys;\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Mutability\par \pard\plain \s2\li480\ri480\sa120 \f16 Some collections can be modified after they have been created; others cannot. To allow methods to distinguish between mutable and immutable collections, the {\f22 } and {\f22 } mixin classes are provided:\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This abstract subclass of {\f22 } is used to indicate collections that can be modified. Every mutable collection is required to allow modification by implementing {\f22 element-setter}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This abstract subclass of {\f22 } is used to indicate collections that may grow or shrink to accomodate adding or removing elements.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 element-setter} {\i new-value} {\i mutable-collection key \tab }[Generic Function]\line {\f23 \'de}{\i new-value}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function alters {\i mutable-collection } so that the value associated with {\i key} will subsequently be {\i new-value}. \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 An error is signaled if a program calls {\f22 element-setter} with a key that is not already a key to {\i collection}, unless the collection supports the dynamic addition of keys and adds the {\i key} and {\i new-value}.\par \pard\plain \s2\li480\ri480\sa120 \f16 Stretchy collections allow {\f22 element-setter} to be called with a key that is not present in the collection, expanding the collection as necessary to add a new element in that case. Each concrete subclass of { \f22 } must provide or inherit a method for {\f22 element-setter} that behaves as follows when there is not already an element present for the indicated key:\par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab If the class is a subclass of {\f22 }, adds a new element to the collection with the indicated key.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab If the class is a subclass of {\f22 }, first calls {\f22 size-setter} on the key + 1 and the collection to expand the sequence. The key must be a non-negative integer.\par \pard\plain \s2\li480\ri480\sa120 \f16 {\f22 } is mixed in with {\f22 } and {\f22 }, respectively, to form the classes {\f22 } and {\f22 }:\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This class inherits from {\f22 } and from {\f22 }. \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This class inherits from {\f22 } and {\f22 }. \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Collection Alignment\par \pard\plain \s2\li480\ri480\sa120 \f16 Some operations on collections, such as mapping, are defined to allow the use of more than a single collection. The presence of potentially \ldblquote unstable\rdblquote collections, i.e., collections for which two iterations may produce values in different orders even though the collection remains unchan ged, can create problems for multi-collection operations unless special care is taken. That is, if iteration is effectively performed in random order in the general case, then naively performing parallel iterations over two different collections would ran domly pair values from the two collections, which would presumably have no meaning.\par \pard \s2\li480\ri480\sa120 To prevent such random pairing, when operating on more than one collection, {\f22 map}, {\f22 do}, etc. must, in general, \ldblquote align\rdblquote the collections, by first computing the intersection of the collections \rquote key sequences and then using the random-access operations ({\f22 element} and {\f22 element-setter}) to operate on the collections themselves.\par \pard\plain \li480\ri480 \f16 Collection alignment is only possible for collections whose key-test is identical, i.e. {\f22 key-test(c1) == key-test(c2)}. Otherwise, an error is signalled.\par \pard\plain \s2\li480\ri480\sa120 \f16 As a concrete example, here is the two-collection case for {\f22 do}:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method do2 (f :: , c1 :: , \par c2 :: )\par let keys = intersection(key-sequence(c1), key-sequence(c2));\par let (init, limit, next, end?, key, elt)\par \tab = forward-iteration-protocol(keys);\par for (state = init then next(keys, state),\par until end?(keys, state, limit))\par let key = elt(keys, state);\par f(c1[key], c2[key]);\par end for;\par end method do2;\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard \s2\li480\ri480\sa120 Note that this definition has the potential for extreme inefficiency, because of its dependence on {\f22 element} and the potential loops implied by the calls to {\f22 key-sequence}.\par \pard \s2\li480\ri480\sa120 An important special case of this problem is that of iterating over multiple sequences. In this case, the intersection of key sequences is clearly the non-negative integers up to the length of the shortest sequence. Further, unlike collections in general, sequences are required to exhibit stability, so no explicit computation of key sequen ces need be made. Instead, it is correct (and much more efficient) simply to iterate until one or more of the sequences is exhausted. Here is a concrete example for {\f22 do2}:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method do2 (f :: , c1 :: , c2 :: )\par \pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 let (init1, limit1, next1, end1?, key1, elt1)\par \tab \tab = forward-iteration-protocol(c1);\par let (init2, limit2, next2, end2?, key2, elt2)\par \tab \tab = forward-iteration-protocol(c2);\par for (state1 = init1 then next1(c1, state1),\par state2 = init2 then next2(c2, state2),\par until (end1?(c1, state1, limit1) | \par end2?(c2, state2, limit2)))\par f(elt1(c1, state1), elt2(c2, state2));\par end for;\par end method do2;\par \pard\plain \s2\li480\ri480\sa120 \f16 \par \pard \s2\li480\ri480\sa120 Most cases of iteration over more than a single collection will be iterations over sequences, rather than over arbitrary collections. Since this case {\i is} efficient, the requirement for alignment is probably not burdensome in practice.\par \pard \s2\li480\ri480\sa120 Any iteration operations that modify a collection must also include the key sequence of the target collection during \ldblquote alignment\rdblquote of the collection arguments. For example, consider these definitions for a simplified {\f22 map-into} function:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define method map-into1 (target :: ,\par f :: ,\par source :: )\par let keys = intersection(key-sequence(target), \par key-sequence(source));\par let (init, limit, next, end?, key, elt)\par \tab = forward-iteration-protocol(keys);\par for (state = init then next(keys, state),\par until end?(keys, state, limit))\par let key = elt(keys, state);\par target[key] := f(source[key]);\par end for;\par end method map-into1;\par \par define method map-into1 (target :: ,\par \tab f :: ,\par \tab source :: )\par let (init1, limit1, next1, end1?, key1, elt1, setter)\par \tab = forward-iteration-protocol(target);\par let (init2, limit2, next2, end2?, key2, elt2)\par \tab = forward-iteration-protocol(source);\par for (state1 = init1 then next1(target, state1),\par state2 = init2 then next2(source, state2),\par until (end1?(target, state1, limit1) |\par end2?(source, state2, limit2)))\par setter(target, state1, f(elt2(source, state2)));\par end for;\par end method map-into1;\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Defining a New Collection Class: A Summary\par \pard\plain \s2\li480\ri480\sa120 \f16 Every collection class must provide an implementation of the iteration protocol ({\f22 forward-iteration-protocol}; backward is optional). \par \pard \s2\li480\ri480\sa120 Every collection must provide or inherit methods for {\f22 element} and {\f22 key-test}. If the collection is also a {\f22 }, it must provide or inherit a method for {\f22 element-setter} . A collection that is not a {\f22 } must provide an implementation of {\f22 class-for-copy}.\par \pard \s2\li480\ri480\sa120 Individual collection classes may impose further requirements on their subclasses. For example, concrete subclasses of {\f22
} must provide or inherit a method for {\f22 table-protocol}.\par \pard \s2\li480\ri480\sa120 For efficiency, it may be desirable to provide specialized implementations for certain generic functions. Collections that can implement functions such as {\f22 size} or {\f22 member?} more efficiently should do so. Sequences that can reuse storage to implement functions such as {\f22 reverse!} and {\f22 sort!} should do so.\par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 10. Characters and Symbols\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Characters\par \pard\plain \s2\li480\ri480\sa120 \f16 See also the description of comparison operations, which discuss the comparison of characters.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is a subclass of {\f22 }.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as-uppercase} {\i character} {\f23 \'de}{\i uppercase-character}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The {\f22 } method on {\f22 as-uppercase} returns the upper-case equivalent for {\i character}. If {\i character} already is uppercase or does not exist in two cases, it is returned unchanged.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as-lowercase} {\i character} {\f23 \'de}{\i lowercase-character}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 The {\f22 } method on {\f22 as-lowercase} returns the lower-case equivalent for {\i character}. If {\i character} already is lowercase or does not exist in two cases, it is returned unchanged.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as} {\f22 }{\i character} {\f23 \'de}{\i integer}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method on {\f22 as} returns a numeric equivalent for {\i character}. The integer returned is implementation dependent.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as} {\f22 }{\i integer} {\f23 \'de}{\i character}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method on {\f22 as} returns the character equivalent to {\i integer}. The meaning of {\i integer} is implementation dependent.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Symbols{\plain \f16\fs36 }\par \pard\plain \s2\li480\ri480\sa120\keep \f16 The {\f22 } class provides a built-in, non-case-sensitive dictionary that associates a string with a unique immutable object that can be compared with {\f22 ==} (whi ch should be faster than calling a string-comparison routine). This dictionary is accessed through the {\f22 as }function:{\f22 as(, }{\i string}{\f22 )} and {\f22 as(, }{\i symbol}{\f22 )}. Any string can be used, even ones that aren \rquote t allowed as variable names.\par \pard \s2\li480\ri480\sa120 For symbols that use the same restricted character set that are allowed in variable names, the \ldblquote keyword syntax\rdblquote {\f22 foo:} (the symbol followed by \ldblquote {\f22 :}\rdblquote ) may be used everywhere that keywords are allowed in the grammar. The trailing colon is not part of the symbol.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} example: == #"Example"\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #t\par }\pard\plain \s2\li480\ri480\sa120 \f16 \par \pard \s2\li480\ri480\sa120 The case of symbols is remembered from the first time the symbol is entered. {\f22 as(, }{\i\f22 symbol}{\f22 )} returns the original case.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is a subclass of {\f22 }.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as} {\f22 }{\i string} {\f23 \'de}{\i symbol}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method on {\f22 as} returns the symbol that has the name {\i string}. If the symbol does not yet exist, it is created. This method on {\f22 as} will always return the same symbol for strings of the same characters, without regard to alphabetic case.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} as (, "foo")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #"foo"\par ?} #"FOO" == as (, "Foo")\par {\i #t\par ?} #"Foo"\par {\i #"foo"\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 as} {\f22 }{\i symbol} {\f23 \'de}{\i string}\tab [G.F. Method]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This method on {\f22 as} returns the name of the symbol, which will be a string.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} as (, #"Foo")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i "Foo"\par }\par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 11. Numbers{\plain \f16 }\par \pard\plain \s2\li480\ri480\sa120 \f16 Dylan supports several kinds of numerical representations. The classes for these representations are placed in a hierarchy of abstract classes corresponding to mathematical number types. The abstract classes have no direct instances but are useful for spec ialization. The complete class hierarchy is shown below. Abstract classes are shown in italics. Sealed classes are shown in bold.\par \pard\plain \li480\ri480 \f16 \par \pard\plain \s2\li480\ri480\sa120 \f16 {{\pict\macpict\picw367\pich175 0aa200af0069015e01d8001102ff0c00ffffffff0069000000af000001d80000015e00000000000000a0008200a10064000a53504e5403e80001000000a10064000e53504e540cd000af0069015e01d800a10064000a53504e540bb8000b000000a0008c00a10064000a53504e540bb80005000100a10064000a53504e540c 9400000000001e001ad900d900d9000001000a00af0069015e01d8000b001b001b004100bd006c015e01d800a10064000a53504e540bb800050043001affffffffffff00090000000000000000004100ba0069015b01d500a100b6000400010004001a0000000000000009ffffffffffffffff004800a100b6000400040001 00a100b600040001000100a10064000a53504e540bb80003004200a100b6000400010004002000d6006900d601c500a100b600040004000100a100b600040001000100a10064000a53504e540bb800050043001affffffffffff00090000000000000000004100fc0073015101cc00a100b6000400010004001a0000000000 000009ffffffffffffffff004800a100b600040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c2600c400e400d7011b00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a00af006900d301d8 002c000c00150948656c7665746963610003001500040200000d0009002e000400000000002becd0083c6e756d6265723e0000a0009700a10064000a53504e540bb80003004200a100b60004000100040001000a00af0069015e01d80022012e00b7f30f00a100b600040004000100a100b600040001000100a10064000a53 504e540bb80001000000a10064001a53504e540c2600e700cc00fa010a00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a00af006900f601d800040000002800f300d5093c636f6d706c65783e00a0009700a10064000a53504e540bb800010000 00a10064001a53504e540c26010400bf011700e800050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a00af0069011301d8000401000028011000c4063c7265616c3e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c 26011f009e013200da00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a00af0069012e01d80028012b00a30a3c726174696f6e616c3e0000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c26013c007b014f00b40005 0002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a00af0069014b01d8002801480080093c696e74656765723e00a0009700a10064000a53504e540bb80001000000a10064001a53504e540c26013c00b2014f00df00050002ffffffffffffffff00a100 64000a53504e540c940000000000a10096000c060000000200000000000000002937073c726174696f3e0000a0009700a10064000a53504e540bb80003004200a100b60004000100040001000a00af0069015e01d80022012e00c20c0f00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003 004200a100b60004000100040022011300d7421100a100b600040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c26012101020134012f00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a00 af0069013001d80028012d0107073c666c6f61743e00a0009700a10064000a53504e540bb80003004200a100b60004000100040001000a00af0069015e01d80022011300cef40f00a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b6000400010004002200f800e6f40f00a1 00b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b6000400010004002200d100fef11900a100b600040004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022012e0119f51100a100b600040004000100a100b600040001000100 a10064000a53504e540bb80001000000a10064001a53504e540c26013c00de014f012c00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a00af0069014b01d80028014800e30e3c73696e676c652d666c6f61743e0000a0009700a10064000a5350 4e540bb80001000000a10064001a53504e540c26013c0124014f017500050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000029460e3c646f75626c652d666c6f61743e00a0009700a10064000a53504e540bb80001000000a10064001a53504e540c26013c01 6d014f01cd00050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c06000000020000000000000000294a103c657874656e6465642d666c6f61743e00a0009700a10064000a53504e540bb80003004200a100b60004000100040001000a00af0069015e01d80022012e011c2f1100a100b60004 0004000100a100b600040001000100a10064000a53504e540bb80003004200a100b60004000100040022012e01236f1100a100b600040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c2600c9006c00da00b000050002ffffffffffffffff00a10064000a53504e540c 940000000000a10096000c0500000002000000000000000001000a00af006900d601d800040000000d0008002800d300710841425354524143540000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c2600d5006b00e600b600050002ffffffffffffffff00a10064000a53504e540c9400000000 00a10096000c0500000002000000000000000001000a00af006900e201d8002800df00700c494e5354414e544941424c450000a0009700a10064000a53504e540bb80001000000a10064001a53504e540c2600fe0076010f00b100050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c050000 0002000000000000000001000a00af0069010b01d8002b0b29065345414c45440000a0009700a10064000a53504e540bb800040043001affffffffffff0001000a00af0069015e01d800090000000000000000003100af00db00c1013f00a100b6000400010004001a0000000000000009ffffffffffffffff003800a100b6 00040004000100a100b600040001000100a10064000a53504e540bb80001000000a10064001a53504e540c2600af00d800c2014200050002ffffffffffffffff00a10064000a53504e540c940000000000a10096000c0600000002000000000000000001000a00af006900be01d800040100000d0009002800bb00de0e4e55 4d42455220434c41535345530000a0009700a10064000a53504e540bb8000c000000a0008d00a10064000653504e5403e900a0008300ff}}\par \pard \s2\li480\ri480\sa120 The {\f22 }, {\f22 }, and {\f22 } classes implement the IEEE standard floating-point formats{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } With one exception: comparison operations may not behave in IEEE fashion when performed on NaNs.}}.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Automatic Type Conversion\par \pard\plain \s2\li480\ri480\sa120 \f16 The Dylan rules for automatic type conversion are the same as in Common Lisp (X3J13): floating-point contagion (with rational contagion for comparisons) and rational canonicalization. Argument coercions are implemented by the individual methods on the ari thmetic functions.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Numeric Classes\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Sealed Class]\par {\b\f22 }\tab [Sealed Class]\par {\b\f22 }\tab [Sealed Class]\par {\b\f22 }\tab [Sealed Class]\par {\b\f22 }\tab [Sealed Class]\par {\b\f22 }\tab [Sealed Class]\par {\b\f22 }\tab [Sealed Class]\par {\b\f22 }\tab [Sealed Class]\par {\b\f22 }\tab [Sealed Class]\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 General Arithmetic Functions \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Properties\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 odd?}{\i integer} {\f23 \'de}{\i boolean\tab }[Generic Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 even?}{\b }{\i integer} {\f23 \'de}{\i boolean\tab }[Generic Function]\par {\b\f22 zero?}{\i number} {\f23 \'de}{\i boolean}\tab [Generic Function]\par {\b\f22 positive?}{\i real} {\f23 \'de}{\i boolean}\tab [Generic Function]\par {\b\f22 negative?}{\i real} {\f23 \'de}{\i boolean}\tab [Generic Function]\par {\b\f22 integral?}{\i number} {\f23 \'de}{\i boolean}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 These functions test a number for the given property and return a Boolean result.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Arithmetic Operations\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 +}{\b }{\i number1} {\i number2} {\f23 \'de}{\i number}\tab [Generic Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 * }{\b }{\i number1} {\i number2} {\f23 \'de}{\i number}\tab [Generic Function]\par {\b\f22 \endash }{\b }{\i number1} {\i number2} {\f23 \'de}{\i number}\tab [Generic Function]\par {\b\f22 /}{\b }{\i number1} {\i number2} {\f23 \'de}{\i number}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 These functions return the sum, product, difference, and quotient of their arguments, respectively. Division by zero signals an error.\par Use the name of the function ({\f22 +, *, -, }or{\f22 /}) when you use the function in an infix expression:\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 5 + 6 * 4\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Use the name of the function preceded by a backslash ({\f22 \\+, \\*, \\-, }or{\f22 \\/} ) when you are using the function in any other way, such as adding new methods to it or passing it as a functional argument:\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 define class () end class;\par \par define method \\+ (a :: , b :: )\par my-personal-addition-method(a, b);\par end method;\par {\b \par }\pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 negative}{\b }{\i number} {\f23 \'de}{\i number}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This function returns the additive inverse of its argument. The unary minus operator is defined to call {\f22 negative}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 floor}{\b }{\i real} {\f23 \'de}{\i integer real}\tab [Generic Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 ceiling}{\b }{\i real} {\f23 \'de}{\i integer real}\tab [Generic Function]\par {\b\f22 round}{\b }{\i real} {\f23 \'de}{\i integer real}\tab [Generic Function]\par {\b\f22 truncate}{\b }{\i real} {\f23 \'de}{\i integer real}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 These functions are equivalent to the one-argument forms of the like-named Common Lisp (X3J13) functions.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 floor/}{\b }{\i real1 real2} {\f23 \'de}{\i integer real}\tab [Generic Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 ceiling/}{\b }{\i real1 real2 }{\f23 \'de} {\i integer real}\tab [Generic Function]\par {\b\f22 round/}{\b }{\i real1 real2 }{\f23 \'de} i{\i nteger real}\tab [Generic Function]\par {\b\f22 truncate/}{\b }{\i real1 real2} {\f23 \'de} {\i integer real}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 These functions are equivalent to the two-argument forms of {\f22 floor}, {\f22 ceiling}, {\f22 round}, and {\f22 truncate} in Common Lisp (X3J13). Division by zero signals an error.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 modulo}{\b }{\i real1 real2} {\f23 \'de}{\i real}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 modulo} returns the second value of {\f22 floor/ ( }{\i real1}{\f22 , }{\i real2}{\f22 )}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 remainder} {\i real1 real2} {\f23 \'de}{\i real}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 remainder} returns the second value of {\f22 truncate/ ( }{\i real1}{\f22 , }{\i real2}{\f22 )}.\par \pard\plain \s19\fi-480\li480\ri480\sa100\keepn\tx480\tqr\tx9360 \f16 {\i number1 }{\b ^} {\i integer2} {\f23 \'de}{\i number}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Returns {\i number1} raised to the power {\i integer2}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa100\keepn\tx480\tqr\tx9360 \f16 {\b\f22 abs} {\i number} {\f23 \'de}{\i number}\tab [Generic Function]\par \pard\plain \s19\fi-480\li480\ri480\sa100\keepn\tx480\tqr\tx9360 \f16 {\b\f22 logior} {\f22 #rest} {\i integers} {\f23 \'de}{\i integer}\tab [Generic Function]\par {\b\f22 logxor} {\f22 #rest} {\i integers} {\f23 \'de}{\i integer}\tab [Generic Function]\par {\b\f22 logand} {\f22 #rest} {\i integers} {\f23 \'de}{\i integer}\tab [Generic Function]\par {\b\f22 lognot} {\i integer} {\f23 \'de}{\i integer}\tab [Generic Function]\par {\b\f22 logbit?} {\i index integer} {\f23 \'de}{\i boolean}\tab [Generic Function]\par {\b\f22 ash} {\i integer count} {\f23 \'de}{\i integer}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa100\keepn\tqr\tx8640\tqr\tx9360 \f16 The generic functions {\f22 abs}, {\f22 logior}, {\f22 logxor}, {\f22 logand}, {\f22 lognot}, {\f22 ash} are as defined in Common Lisp. {\f22 logbit?} is equivalent to Common Lisp \rquote s {\f22 logbitp}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 rationalize} {\i number} {\f23 \'de}{\i number}\tab [Generic Function]\par \pard\plain \s19\fi-480\li480\ri480\sa100\keepn\tx480\tqr\tx9360 \f16 {\b\f22 numerator} {\i number} {\f23 \'de}{\i number}\tab [Generic Function]\par {\b\f22 denominator} {\i number} {\f23 \'de}{\i number}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 The generic functions {\f22 rationalize}, {\f22 numerator}, and {\f22 denominator} are as defined in {\i Revised}{\i\fs18\up6 4}{\i Report on Scheme}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa100\keepn\tx480\tqr\tx9360 \f16 {\b\f22 lcm} {\i integer1 integer2} {\f23 \'de}{\i integer}\tab [Generic Function]\par \pard\plain \s19\fi-480\li480\ri480\sa100\keepn\tx480\tqr\tx9360 \f16 {\b\f22 gcd} {\i integer1 integer2} {\f23 \'de}{\i integer}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 These functions return the least common multiple and greatest common divisor of {\i integer1} and {\i integer2}, respectively\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa100\keepn\tx480\tqr\tx9360 \f16 {\b\f22 min}{\b }{\i real }{\f22 #rest}{\i more-reals} {\f23 \'de}{\i real}\tab [Function]\par \pard\plain \s19\fi-480\li480\ri480\sa100\keepn\tx480\tqr\tx9360 \f16 {\b\f22 max} {\i real} {\f22 #rest} {\i more-reals} {\f23 \'de} {\i real}\tab [Function]\par \pard\plain \s11\li480\ri480\sa100\tqr\tx8640\tqr\tx9360 \f16 {\f22 min} returns the argument that is least (closest to negative infinity). {\f22 max} returns the argument that is greatest (closest to positive infinity). The methods operate by calling { \f22 <}.\par \pard \s11\li480\ri480\sa100\tqr\tx8640\tqr\tx9360 \page \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 12. Other Operations\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Functional Operations\par \pard\plain \s2\li480\ri480\sa120 \f16 The following operations are used to create new functions from other functions or objects. Often the Dylan compiler will have special knowledge of these operations, to allow for efficient in-line compilation.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 compose} {\i function1 }{\f22 #rest} {\i more-functions} {\f23 \'de}{\i function}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 When called with just a single argument, {\f22 compose} returns that argument.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 When called with two arguments, {\f22 compose} returns a function that applies the second function to its arguments and then applies the first function to the (single) result value.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 With three or more arguments, {\f22 compose} composes pairs of argument functions, until a single composite function is obtained. (It doesn\rquote t matter if the pairings are done from the left or from the right, as long as the order of application is preserved.)\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }define method square (x :: ) x * x end;\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i square\par }\pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 {\i ? }define method square-all (coords :: ) \line map (square, coords);\par \pard \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 end;\par {\i square-all\par ? }define method sum (numbers :: )\par reduce1 (\\+, numbers);\par end;\par {\i sum\par ? }define constant distance = compose(sqrt, sum, square-all);{\i \par distance\par ? }distance ( #(3, 4, 5) );\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i 7.0710678118654755}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 complement} {\i predicate} {\f23 \'de}{\i function}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 complement} returns a function that applies {\i predicate } to its arguments. If the {\i predicate }returns {\f22 #f}, the complement returns {\f22 #t} ; otherwise, the complement returns {\f22 #f}. For example, {\f22 odd?} could be defined as {\f22 complement (even?)}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }map (female?, list (michelle, arnold, roseanne));{\i \par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(#t, #f, #t)\par ? }map (complement (female?), list (michelle, arnold, roseanne));{\i \par }\pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i #(#f, #t, #f)}\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 disjoin}{\b }{\i predicate1} {\f22 #rest} {\i more-predicates} {\f23 \'de}{\i function}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\keep\tqr\tx8640\tqr\tx9360 \f16 {\f22 disjoin} returns a single function, termed the dis junction of its argument functions. The disjunction accepts any number of arguments and operates by applying the predicates, in order, to the arguments. If any of the predicates returns true, the remaining predicates (if any) are not applied, and the tru e result is returned. Otherwise, all the predicates will be applied, and {\f22 #f} returned.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 A disjunction is similar to an {\f22 |} expression of calls to the predicates.\par \pard\plain \s9\fi-480\li480\ri480\sb220\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 conjoin}{\b }{\i predicate1 }{\f22 #rest} {\i more-predicates} {\f23 \'de}{\i function}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 conjoin} returns a single funct ion, termed the conjunction of its argument functions. The conjunction accepts any number of arguments and operates by applying the predicates, in order, to the arguments. If any of the predicates returns {\f22 #f} , the remaining predicates (if any) are not applied and {\f22 #f} is immediately returned. Otherwise, all the predicates will be applied, and the result of the last application is returned.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 A conjunction is similar to an {\f22 &} expression of calls to the predicates.\par \pard\plain \s9\fi-480\li480\ri480\sb220\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 curry}{\b }{\i function }{\f22 #rest}{\i curried-args} {\f23 \'de}{\i new-function}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 curry} returns a function that applies {\i function} to {\i curried-args} plus its own arguments, in that order. For example {\f22 curry\~(\\=,\~"x")} is a predicate that tests for equality with the string {\f22 "x"}; {\f22 curry\~(\\+,\~1)} is an incrementing function; {\f22 curry\~(\\>, 6)} is a predicate that returns true for values less than 6; {\f22 curry (concatenate, "set-")} is a function that concatenates the string {\f22 "set-"} to any additional sequences it is passed.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} map (curry (\\+, 1), #(3, 4, 5))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i #(4, 5, 6)}\par \pard\plain \s9\fi-480\li480\ri480\sb220\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 rcurry} {\i function }{\f22 #rest} {\i curried-args} {\f23 \'de}{\i new-function}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 rcurry} (\ldblquote right\rdblquote curry) operates just like {\f22 curry}, except it allows the rightmost arguments of {\i function } to be specified in advance, rather than the leftmost arguments. For example, {\f22 rcurry\~(\\>,\~6)} is a predicate that returns true for values greater than 6.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} define constant yuppify = rcurry (concatenate, ", ayup");\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i yuppify\par ?} yuppify ("I'm from New Hampsha");\par \pard \s6\li960\ri480\tx2880\tx4800\tx6720 {\i "I'm from New Hampsha, ayup"\par }\pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 always}{\b }{\i object} {\f23 \'de}{\i function}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 {\f22 always} returns a function that can be called with any number of arguments. The function ignores its arguments and always returns {\i object}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ? }always (1) ("x", "y", "z")\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i 1\par ?} always (#t) (#f, #f)\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i #t}\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 \page \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Function application\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 apply} {\i function} {\f22 #rest} {\i args} {\f23 \'de}{\i values}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 {\f22 apply} calls {\i function} with {\i args} as the arguments. The last {\i arg} must be a sequence. The elements of the sequence are spread out and taken as individual arguments to {\i function}.\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i ?} apply(\\+, #(1, 2))\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\i 3\par ?} 1 + 2\par {\i 3\par ?} define constant math-functions = list (\\+, \\*, \\/, \\\endash ))\par {\i ?} math-functions\par {\i #(\{generic +\}, \{generic *\}, \{generic /\}, \{generic \endash \})\par ?} first (math-functions)\par {\i \{generic +\}\par ?} apply (first (math-functions), #(1, 2))\par \pard\plain \s8\li960\ri480\sa320\tx2880\tx4800\tx6720 \f22\fs20 {\i 3}\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Identity function\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 identity}{\b }{\i object} {\f23 \'de}{\i object}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 identity} simply returns {\i object.\par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 13. Conditions \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Background\par \pard\plain \s2\li480\ri480\sa120 \f16 A long-standing problem of software engineering is the need to develop an organized way to deal with exceptions, situations that must be handled gracefully but that are not conceptually part of the normal operation of the program. A number of programming languages contain linguistic features for exceptions, among them Common Lisp, C++, PL/I, and Ada.\par \pard \s2\li480\ri480\sa120 Of course it is possible to program exception handling without using special linguistic features. For example, all functions could return an extra result that indicates whether they succeeded or failed, functions could take an extra argument that they con sult if an exception occurs, or a designated exception-handling function could be called whenever a problem arises. All of these approaches have been used in one real-life system or another, but they are deficient in two ways. First, they are too informal and don\rquote t provide enough structure to allow an organized, systematic approach to exception handling. Second, and more importantly, the first two approaches do not provide textual separation between \ldblquote normal code\rdblquote and \ldblquote code for dealing with exceptions\rdblquote ; exception-related code is sprinkled throughout the program. This leads to two problems: one is the well-known mistake of forgetting to test error codes and thus f ailing to detect an exception, perhaps one that \ldblquote could never happen;\rdblquote the other is that program clarity is lost because it isn\rquote t easy to think about the main flow of the program while temporarily ignoring exceptions.\par \pard \s2\li480\ri480\sa120 Thus, the most important requirements of a linguistic exception-handling facility are to provide overall structure, to eliminate the possibility of failing to notice an exception, and to provide a clean separation between \ldblquote normal code\rdblquote and \ldblquote code for dealing with exceptions.\rdblquote \par \pard \s2\li480\ri480\sa120 All exception systems involve the concept of \ldblquote signal\rdblquote (sometimes with a different name, such as \ldblquote raise\rdblquote or \ldblquote throw\rdblquote ) and the concept of \ldblquote handle\rdblquote (sometimes with a different name such as \ldblquote on-unit\rdblquote or \ldblquote catch\rdblquote ). All exception systems considered here dynamically match signalers with handlers, first invoking the most recently established matching handler still active, and then, if that matching handler declines to handle the exception, invoking the next most recent matching handler, and so on. Thus, exception systems really are a way of establishing a run-time connection between a signaler and a handler, as distinct from the usual fixed connection between a caller and a callee through function-name matching.\par \pard \s2\li480\ri480\sa120 The major design choices in exception systems\emdash name-based versus object-based, calling versus terminating, and formal versus ad-hoc recovery\emdash are discussed in the following paragraphs.\par PL/I and Ada have name-based exception systems. A program signals a name, and a handler matches if it handles the same name or \ldblquote any.\rdblquote The name is a constant in the source text of the program, not the result of an expression.\par \pard \s2\li480\ri480\sa120 C++ and Common Lisp have object-based exception systems. A program signals an object, and a handler matches if it handles a type that object belongs to. Object-based exceptions are more powerful, because the object can communicate additional information from the signaler to the handler, because the object to be signaled can be chosen at run-time rather than signaling a fixed name, and because type inheritance in the handler matching adds abstraction and provides an organizing framework.\par \pard \s2\li480\ri480\sa120 The C++ object-based exception system has complicated inheritance rules and allows any object whatsoever to be used as an exception. Common Lisp, in contrast, allows only objects that inherit from a certain built-in class to be used as exceptions, thus li miting the inheritance rules to class inheritance and providing a class on which to hang any protocols specific to exceptions.\par \pard \s2\li480\ri480\sa120 Ada and C++ have terminating exception systems: before a handler r eceives control, all dynamic state between the handler and the signaler is unwound, as if signaling were a non-local goto from the signaler to the handler. PL/I has a calling exception system: when a handler receives control, the signaler is still active and control can be returned to it, as if signaling were a function call from the signaler to the handler. Common Lisp has both, with the calling semantics regarded as fundamental and the terminating semantics explained in terms of it. Note that calling s emantics need not imply that the signal operation can return the way a function call returns; Common Lisp provides a \ldblquote restart\rdblquote mechanism that signalers use to grant handlers permission to return. The Common Lisp model shows that terminating versus calling is a property of handlers, not of exception systems as a whole.\par \pard \s2\li480\ri480\sa120 Terminating exception systems are acceptable for errors. However, they do not work for an exception that is not an error and doesn\rquote t require termination, either because there is a default wa y to handle it and recover or because it can safely be ignored by applications that don\rquote t care about it. Non-error exceptions are quite common in networked environments, in computers with gradually expiring resources (such as batteries), in complex user i nterfaces, and as one approach for reflecting hardware exceptions such as page protection violations or floating-point overflow to the application.\par \pard \s2\li480\ri480\sa120 Most languages have not formalized how to recover from exceptions, leaving programmers to invent ad hoc mechanisms. Common Lisp provides \ldblquote restarts,\rdblquote which is an object-based way of establishing a run-time connection from a handler back to the signaler or to any other part of the dynamically active program. A handler can choose to return control to any availabl e restart, or else can mimic terminating semantics, using the language\rquote s normal non-local exit mechanisms. Restarts can also be a good way for programs to indicate to an interactive debugger what the end user\rquote s choices are for recovery from an exception that lands in the debugger. In this sense, the debugger can be understood as just a complicated handler. Unfortunately some details of restarts are somewhat poorly designed in Common Lisp.\par \pard \s2\li480\ri480\sa120 It is necessary to have a way to clean up when execution of a function is terminated by a non-local exit initiated either by the function itself or by something it explicitly or implicitly called. In C++ this includes invoking destructors for automatic ob jects, as well as application-specific cleanup. Ada, C++, and the Multics dialect of PL/I associate this action with exception handling. Common Lisp realizes it is related but different and calls it {\f22 unwind-protect} . Dylan uses the Common Lisp approach, except that Common Lisp\rquote s {\f22 unwind-protect} becomes a cleanup clause in Dylan\rquote s {\f22 block} statement.\par For detailed information on exceptions in Common Lisp, refer to chapter 29 of {\i Common Lisp: the Language}, Second Edition, by Guy L. Steele Jr. For detailed information on exceptions in C++ (not yet implemented in many C++ implem entations but adopted into the draft proposed ANSI C++ standard), refer to chapter 15 of {\i The Annotated C++ Reference Manual} , by Margaret A. Ellis and Bjarne Stroustrup. Although it is not necessary to read either document to understand the Dylan condition system, they may be helpful as sources of background information.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Overview\par \pard\plain \s2\li480\ri480\sa120 \f16 The Dylan exception facility is object-based. It uses calling semantics but also provides terminating handlers. It provides formal recovery.\par \pard \s2\li480\ri480\sa120 Conditions are a dynamically bound, type-based mechanism for finding and invoking functions. When an exceptional situation occurs, it is indicated to the calling code by signaling a condition. The condition facility locates an applicable handler and calls it. An applicable handler is one that matches the signaled condition by type and by (an optional) test function associated with the handler. The condition system is simply a way for a signaler and a handler to be introduced to each other. Once they have met, they communicate through an ordinary function call.\par Like any function, the called handler either returns some values or takes a non-local exit. Either way, the handler has handled the condition, and the act of signaling is completed. A dynamic handler also has the option of declining to handle the conditi on, passing the buck to the next applicable handler, by calling a next-handler function passed to the dynamic handler as an argument. A default handler cannot decline because it is always the last applicable handler. Every signale d condition is handled, because the system ensures that there is always an applicable default handler.\par \pard \s2\li480\ri480\sa120 The following terms describe portions of the dynamic state of execution. These terms come from the stack model of function calling.\par \pard\plain \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \f16 {\b outside stack}\tab The state existing just before the handler was established\par \pard\plain \s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 {\b signaling unit }\tab The conceptual program component that includes the form that signaled the condition and does not include the form that established the handler. This informal concept provides a notion o f where the interface boundary between the signaler and the handler lies.\par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\b middle stack}\tab The state existing just before the signaling unit was called, minus the outside stack\par \pard\plain \s16\fi-2160\li2640\ri480\sa240\tx2640 \f16 {\b inside stack}\tab The state existing just before signaling occurred, minus the middle stack and outside stack\par \pard\plain \s2\li480\ri480\sa120 \f16 The simplest way to handle a condition is to terminate the signaling unit by taking a non-local exit established in the outside stack. The convenient {\f22 exception} clause of the {\f22 block} statement is provided for this purpose.\par \pard \s2\li480\ri480\sa120 A less common handling style is to terminate the signaling unit by taking a non-local exit established in the middle stack, leaving the handler in force.\par \pard \s2\li480\ri480\sa120 Instead of terminating, a handler can recover, returning control to the signaling unit. This can be done either by returning values that the signaling unit will understand or by taking a non-local exit established in the inside stack. Returning or exitin g can be done directly, or a more formal recovery mechanism called restarting can be used. The advantage of the fo rmal mechanism is the advantage of any formal interface: it provides more assurance that the handler and the signaling unit agree on the meaning of what they are doing and provides some isolation of the handler from names and data representations internal to the signaling unit.\par \pard \s2\li480\ri480\sa120 Returning values or non-locally exiting directly, rather than restarting, is a less formal mechanism with an increased likelihood of accidentally violating the protocol or contract between a signaler and a handler. Nonetheless it is allowed, in the spirit of freedom and because it is the primitive upon which restarting is built. When the direct mechanism is used, it should be used with due care.\par \pard \s2\li480\ri480\sa120 A handler restarts by signaling a restart. This is the formal recovery mechanism. Any values needed for recovery are passed in the restart (that is, in initialization arguments that the restart remembers either in slots or in any other way it chooses). The restart is handled by a restart handler which either returns or takes a non-local exit. If the restart handler returns some values, {\f22 signal} returns those values and the handler that called {\f22 signal} also returns them. The call to {\f22 signal} from the signaling unit that signaled the original condition returns the same values, and the signaling unit recovers as directed by those values. If the restart handler was established by the signaling unit, then it was established in the inside stack a nd typically takes a non-local exit in the inside stack. It is just as valid to invoke a restart handler established in the outside or middle stack by a program component other than the signaling unit.\par \pard \s2\li480\ri480\sa120 For every condition class there should be a \ldblquote recovery protocol\rdblquote that defines the meaning of handling by returning, the meaning of the values returned, and which restart handlers are supposed to be established by the signaling unit. The recovery protocol t ells the handler what to expect from the signaler. For many condition classes, this is the empty protocol: handling by returning isn\rquote t allowed, and no particu lar restart handlers are provided. In this case only handling by terminating is possible. (Terminating might be accomplished by signaling a restart whose handler was established in the outside or middle stack, or by an ordinary non-local exit.) The reco very protocol for a subclass should be compatible with the recovery protocol of a superclass. That is, a handler that applies the superclass\rquote s recovery protocol, when the condition actually signaled was a direct instance of the subclass, should operate correctly.\par \pard \s2\li480\ri480\sa120 An example recovery protocol for a hypothetical {\f22 } condition could be: returning a value uses that value as if it had been the contents of the slot; a restart handler for {\f22 } is available; { \f22 } has initialization arguments {\f22 value:}, the value to use, and {\f22 permanent:}, {\f22 #t} to store the value into the slot or {\f22 #f} (the default) to leave the slot unbound.\par At present, no formal mechanism is provided for describing recovery protocols; they are left to the documentation of a condition class. Introspective functions are provided for discovering which recovery facilities are actually available, but this is different from (and sometimes is a superset of) the recovery facilities guaranteed by a recovery protocol always to be available. \par \pard \s2\li480\ri480\sa120 The debugger is the condition handler of last resort which receives control if no program-provided handler handles a serious condition. (This is true even if the \ldblquote debugger\rdblquote provided cannot analyze or intervene in the execution of programs but can only abort or restart them. The debugger might be merely a \ldblquote core dumper,\rdblquote a \ldblquote bomb box,\rdblquote or something similar.) An interactive debugger ought to offer the user the ability to signal any restart for which a restart handler is applicable and to return if the condition\rquote s recovery protocol allows it. This could, for example, be done with a menu titled \ldblquote Recovery.\rdblquote \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Specification\par \pard\plain \s2\li480\ri480\sa120 \f16 The following sections outline the classes and operations on conditions available in Dylan.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Format Strings\par \pard\plain \li480\ri480 \f16 A \ldblquote format string\rdblquote is a string template into which values can be inserted to construct a message. The two-character sequences {\f22 %d}, {\f22 %b}, {\f22 %o}, {\f22 %x}, {\f22 %c}, {\f22 %s}, and {\f22 %=} are replaced by the next element of the associated sequence of \ldblquote format arguments.\rdblquote Upper and lower case letters are equivalent in these format directives. The inserted value is formatted according to the following table:\par \pard \li480\ri480 \par \trowd \trgaph80\trleft460 \clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx2440\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx4960\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0 \cellx9180\pard \qc\li480\ri480\tqc\tx560\intbl {\b\fs20 directive\cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\b\fs20 argument type\cell }\pard \qc\li480\ri480\tqc\tx2360\intbl {\b\fs20 textual format\cell }\pard \intbl {\fs20 \row }\trowd \trgaph80\trleft460 \clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx2440\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx4960\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0 \cellx9180\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %d}{\fs20 \cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\f22\fs20 }{\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 decimal number\cell }\pard \intbl {\fs20 \row }\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %b}{\fs20 \cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\f22\fs20 }{\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 binary number\cell }\pard \intbl {\fs20 \row }\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %o}{\fs20 \cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\f22\fs20 }{\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 octal number\cell }\pard \intbl {\fs20 \row }\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %x}{\fs20 \cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\f22\fs20 }{\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 hexadecimal number\cell }\pard \intbl {\fs20 \row }\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %c}{\fs20 \cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\f22\fs20 }{\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 character (with no quotes)\cell }\pard \intbl {\fs20 \row }\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %s}{\fs20 \cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\f22\fs20 }{\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 string (with no quotes)\cell }\pard \intbl {\fs20 \row }\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %s}{\fs20 \cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\f22\fs20 }{\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 error message (with no quotes)\cell }\pard \intbl {\fs20 \row }\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %=\cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\f22\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 unspecified but works for any object\cell }\pard \intbl {\fs20 \row }\trowd \trgaph80\trleft460 \clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx2440\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0\cellx4960\clbrdrt\brdrs \clbrdrl\brdrs \clbrdrb\brdrs \clbrdrr\brdrs \clshdng0 \cellx9180\pard \qc\li480\ri480\tqc\tx560\intbl {\f22\fs20 %%}{\fs20 \cell }\pard \qc\li480\ri480\tqc\tx1280\intbl {\i\fs20 none}{\fs20 \cell }\pard \li200\ri480\tqc\tx2360\intbl {\fs20 literal }{\f22\fs20 %}{\fs20 \cell }\pard \intbl {\fs20 \row }\pard \li1440\ri480 {\b\fs20 \par }{\fs20 \par }\pard \li480\ri480 The text printed by the {\f22 %=} format directive for any given object is implementation-defined. The behavior when a format argument is not of the type specified in the table above is implementation-defined. The behavior when too many or too few format arguments are supplied is implem entation-defined.\par \pard \li480\ri480 \par \pard \li480\ri480 The two-character sequence {\f22 %%} does not consume a format argument, but inserts a {\f22 %} character.\par \pard \li480\ri480 \par \pard \li480\ri480 All other uses of the {\f22 %} character in a format string are implementation-defined. Extensions in the style of Common Lisp {\f22 format} or C {\f22 printf} might exist in some implementations but are not portable. This is not attempting to be a general text-formatting package, just a simple least common denominator for casual construction of error messages.\par \pard \li480\ri480 \par \pard \li480\ri480 There is no standard way to get the \ldblquote error message\rdblquote from a condition, although it can be inserted into another message by using the {\f22 %s} directive in a format string. Debuggers get the error message using implementation-dependent mechanisms. When a streams library is present, it might include a function to get the \ldblquote error message\rdblquote from a condition.\par \pard \li480\ri480 \par \pard \li480\ri480 There is no standard way for a user-defined condition class that does not inherit from {\f22 } {\f22 , }or {\f22 } to supply an \ldblquote error message.\rdblquote Individual platforms, application frameworks, or user interfaces should specify a mechanism for this that is appropriate to their needs.\par \pard \li480\ri480 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Classes\par \pard\plain \s2\li480\ri480\sa120 \f16 The classes described in this section are defined by Dylan. In addition, numerous condition classes specific to particular Dylan built-in functions or user functions will no doubt exist. Note that there can be other direct subclasses of {\f22 } besides the three specified ones. Also note that the subclass relationships shown below are not necessarily direct subclass relationships (i.e. implementation-specific classes can be inserted in the class hierarchy).\par \pard \s2\li480\ri480\sa120 Abstract classes are shown in italics.\par \pard\plain \s9\li480\ri480\keepn\tx480\tqr\tx9360 \f16 {{\pict\macpict\picw360\pich139 0884ffffffff008a0167001102ff0c00ffffffffffff0000ffff000001670000008a00000000000000a1006400086450726f0000000100a0008200a0008c001e001ad999d999d9990001000affffffff008a0167000b001b001b0041000f0003008a016600a100b600040001000100070000000000230000001affffffffff ff000900000000000000000041000c00000087016300a100b6000400010080001a0000000000000007000100010009ffffffffffffffff004800a100b60004000100010007000000000023000000a100b60004000100800007000100010020006000000060016200a100b60004000100010007000000000023000000a0009b 00a10096000c02000000000000000000000000a0009800a1006400186450726f000f39e6000200240000000100000000000000000001000a001b00a9002800e4002c001339e6104c756369646153616e7320526f6d616e00000339e600040200000d0009002e0004ff0001000015d655002bac240b3c636f6e646974696f6e 3e00a0009900a0009700a0009c00a0009b00a10096000c02000000000000000000000000a0009800a1006400186450726f000f39e6000200240000000100000000000000000001000a00360027004300ad00159d4d0028003f003f133c736572696f75732d636f6e646974696f6e3e00a0009900a0009700a0009c00a0009b 00a10096000c02000000000000000000000000a0009800a1006400186450726f000f39e6000200240000000100000000000000000001000a004b00470058008a0015b42d002b1815073c6572726f723e00a0009900a0009700a0009c00a0009b00a10096000c02000000000000000000000000a0009800a100640018645072 6f000f39e6000000240000000100000000000000000001000a00700015007d005c0004000000155e490028007900180e3c73696d706c652d6572726f723e0000a0009900a0009700a0009c00a0009b00a10096000c02000000000000000000000000a0009800a1006400186450726f000f39e6000000240000000100000000 000000000001000a0070005c007d00990015c1470029470c3c747970652d6572726f723e00a0009900a0009700a0009c00a100b60004002000800001000affffffff008a01670007000100010022002500c7001100a100b60004000100010007000000000023000000a0009b00a10096000c02000000000000000000000000 a0009800a1006400186450726f000f39e6000000240000000100000000000000000001000a0070009c007d00f10015ace5002940103c73696d706c652d7761726e696e673e00a0009900a0009700a0009c00a0009b00a10096000c02000000000000000000000000a0009800a1006400186450726f000f39e6000000240000 000100000000000000000001000a007000ef007d013d0015cd53002953103c73696d706c652d726573746172743e00a0009900a0009700a0009c00a0009b00a10096000c02000000000000000000000000a0009800a1006400186450726f000f39e6000000240000000100000000000000000001000a00700139007d016200 15c42100294a073c61626f72743e0000a0009900a0009700a0009c00a0009b00a10096000c01000000000000000000000000a0009800a1006400186450726f000f39e6000000200000000100000000000000000001000a0055000300610032000d00080015b0210028005e00060841425354524143540000a0009900a00097 00a0009c00a0009b00a10096000c01000000000000000000000000a0009800a1006400186450726f000f39e6000000200000000100000000000000000001000a00610002006d00400015f0210028006a00050c494e5354414e544941424c450000a0009900a0009700a0009c001affffffffffff0001000affffffff008a01 670009000000000000000000310000007a001200f400a100b6000400010080001a0000000000000007000100010009ffffffffffffffff003800a100b60004000100010007000000000022006a003d000000a0009b00a10096000c02000000000000000000000000a0009800a1006400186450726f000f39e6000100240000 000100000000000000000001000a00030082001000ec00040100000d0009001511b90028000c008511434f4e444954494f4e20434c415353455300a0009900a0009700a0009c00a100b60004002000800001000affffffff008a01670007000100010022002500cb681100a100b60004000100010007000000000023000000 a0009b00a10096000c02000000000000000000000000a0009800a1006400186450726f000f39e6000200240000000100000000000000000001000a003600a1004300ed00040200001520d5002b2a33093c7761726e696e673e00a0009900a0009700a0009c00a0009b00a10096000c02000000000000000000000000a00098 00a1006400186450726f000f39e6000200240000000100000000000000000001000a00360118004301490015e52500296c093c726573746172743e0000a0009900a0009700a0009c00a100b60004002000800001000affffffff008a01670007000100010022002500c4a51100a100b6000400010001000700000000002300 0000a100b6000400200080000700010001002200420069000800a100b60004000100010007000000000023000000a100b60004002000800007000100010022004400c7002a00a100b60004000100010007000000000023000000a100b6000400200080000700010001002200560065e91800a100b600040001000100070000 00000023000000a100b600040020008000070001000100220056006a181800a100b60004000100010007000000000023000000a100b600040020008000070001000100220044012eea2800a100b60004000100010007000000000023000000a100b6000400200080000700010001002200440133162800a100b60004000100 010007000000000023000000a0008d00a0008300ff}}{\fs18 \par }\pard \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 {\b\f22 }\tab [Abstract Class]{\f22 \par }\pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 A condition is a general instance of the abstract class {\f22 } . It is an object that represents the occurrence of an exception. Conditions have indefinite extent and no special restrictions. A program that does not encounter any exceptional situations will not implicitly allocate any conditions.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 There is a default handler for {\f22 } that returns {\f22 #f}.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is the abstract class of all conditions that cannot safely be ignored. There is a default handler for {\f22 } that calls the debugger, using an unspecified mechanism.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is the abstract class of all conditions that represent something invalid about the program (as opposed to environmental conditions such as running out of memory or battery power, or inability to establish a network connection, for example). {\f22 } is a subclass of {\f22 }. {\f22 } is distinct from {\f22 } so one can establish a handler for errors that does not also trap unpredictable environmental exceptions such as network problems.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is the concrete class of error conditions that consist of just an error message constructed from a format string and arguments; it is a subclass of {\f22 } . The recovery protocol is empty. The initialization arguments {\f22 format-string: }and {\f22 format-arguments:} are accepted. The accessor functions {\f22 condition-format-string} and {\f22 condition-format-arguments} are applicable.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is a concrete subclass of {\f22 } used by {\f22 check-type}. The recovery protocol is empty. The initialization arguments {\f22 value:} and {\f22 type:} are accepted. The accessor functions {\f22 type-error-value} and {\f22 type-error-expected-type} are applicable.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is a subclass of {\f22 }\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is an abstract subclass of {\f22 }. There is a default handler for {\f22 } that displays the warning in a user-interface dependent way and then returns { \f22 #f}. The recovery protocol is that any value can be returned and will be ignored.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is a concrete subclass of {\f22 } used by {\f22 signal}. The recovery protocol is the same as for {\f22 } . The initialization arguments and accessor functions are the same as for {\f22 }.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Abstract Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 A restart is a general instance of the abstract class {\f22 }. {\f22 } is a subclass of {\f22 }. There is a default handler for {\f22 } that signals an error reporting an attempt to use a restart for which no restart handler was established. The recovery protocol concept is not applicable to restarts. The initialization argument {\f22 condition:} is accepted and ignored by {\f22 }; some subclasses save the value of this initialization argument and use it to associate a restart with a particular condition from which the restart can recover. At present, none of these subclasses are defined as part of the language. Other restarts do not care; they can recover from any condition.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is a concrete subclass of {\f22 } that is used by {\f22 cerror}. The initialization arguments {\f22 format-string:} and {\f22 format-arguments:} are accepted. The accessor functions {\f22 condition-format-string} and {\f22 condition-format-arguments} are applicable. Typical implementations will use the format string and format arguments to produce a description of the restart.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 }\tab [Instantiable Class]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 } is a concrete subclass of {\f22 } whose handlers are expected to terminate execution of the current application command, or similar unit of execution, and return control to something like an application command loop. This is comparable to command-period on the Macintosh. The exact detai ls of this feature depend on the particular environment, of course, but signaling an instance of {\f22 } is a uniform way to \ldblquote get out.\rdblquote \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Basic Operator for Signaling\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 signal} {\i condition} {\f23 \'de}{\i values}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Signals the {\i condition}, trying each active dynamic handler, the most recent first. If all dynamic handlers decline, {\f22 signal} calls {\f22 default-handler (}{\i condition}{\f22 )} . If a handler returns, all the values that it returned are returned from {\f22 signal}. If {\f22 signal} returns when {\i condition}\rquote s recovery protocol does not allow returning, some handler has violated protocol; {\f22 signal} does not check for this error. If {\i condition} is a restart, the caller of {\f22 signal} should always assume that it might return.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 Additional operators for signaling, defined for convenience, are described in a later section.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Basic Operator for Handling Conditions\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tx1620\tqr\tx9360 \f16 {\b\f22 let handler} {\i condition}{\f22 }{\b\f22 =}{\f22 }{\i handler}\tab [Local Declaration]\line \tab \par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 let handler} establishes a condition handler during the dynamic extent of the evaluation of the rest of the enclosing body. It is scoped as in {\f22 let}.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\i condition} should be of the form\par \pard \s11\li480\ri480\sa120\tx1440\tqr\tx8640\tqr\tx9360 \tab {\i type}\par or\tab {\f22 ( }{\i type}{\f22 }[, {\f22 test: }{\i test} ] [, {\f22 init-arguments: }{\i init-arguments} ]{\f22 )}\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 {\i type}, {\i handler}, {\i test}, and {\i init-arguments} are evaluated before evaluation of the rest of the enclosing body begins.\par \pard\plain \s14\fi-2160\li2640\ri480\sb120\sa120\tx2640 \f16 {\i type} \tab The handler applies to conditions that are general instances of {\i type}. \par \pard\plain \s15\fi-2160\li2640\ri480\sa160\tx2640 \f16 {\i test} \tab A function called with a condition that is a general instance of {\i type} and that returns true if this handler applies to this condition. The default is a function that always returns true. An example usage is a restart handler for restarting only from a particular condition object, for example, restarting from an unbound-s lot error by setting the slot and retrying the invocation of the accessor. The {\f22 } restart condition will have the signaled {\f22 } condition in a slot, and the handler\rquote s test will check for it. (These class names are invented for this example and are not part of the specification.) \par \pard \s15\fi-2160\li2640\ri480\sa160\tx2640 {\i handler}\tab A function called to handle a condition that matches {\i type} and passes {\i test} . The values of the arguments are the condition being signaled and the next handler function. The function handles the condition by taking a non-local exit, returning values according to the condition\rquote s recovery protocol, or tail-recursively calling {\f22 signal} of a restart. The function can decline to handle the condition by tail-recursively calling {\i next-handler} with no arguments.{\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }The two calling possibilities are described as tail-recursive to ensure that all values returned by the call are returned by the handler. Not returning all the values could interfere with the condition\rquote s recovery protocol. A handler that {\i really} knows what it is doing could use a non-tail-recursive call, but anything that knows what it\rquote s doing in this situation is probably unmodular. Note that a handler might not know the full recovery protocol, because the condition\rquote s class might be a subclass of the handler\rquote s expected type.}}\par \pard\plain \s16\fi-2160\li2640\ri480\sa240\tx2640 \f16 {\i init-arguments}\tab A sequence of alternating keywords and objects which can be used as initialization arguments to construct an instance of {\i\f22\fs20 type} . It defaults to an empty sequence. This is probably used only in restart handlers.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\i test} and {\i handler} are distinct so that ha ndler applicability can be tested without actually handling (which might take a non-local exit). One use for this is constructing a list of available restart handlers.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 There is no \ldblquote condition wall,\rdblquote i.e., when executing {\i handler } the set of available handlers is not reset to the handlers that were in effect when the {\f22 let handler} was entered. {\fs18\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn }This is necessary to keep restart handlers available to other condition handlers.}}\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The expansion of a {\f22 let handler} form is implementation-dependent. Implementations are encouraged to use an expansion that optimizes establishing a handler for both speed and space, even if that increases the cost of signaling. The assumption is that most of the time a handler will never be used, because the exception it is looking for will never occur.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Miscellaneous Condition Operations\par \pard\plain \s2\li480\ri480\sa120 \f16 Some condition classes define accessor functions. The accessor functions for the standardized classes are specified briefly with the class above. None of these are settable.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Full Set of Operators for Signaling\par \pard\plain \s2\li480\ri480\sa120 \f16 The first operator listed here is a repeat of the basic operator. The others all have straightforward implementations in terms of other primitives but are provided to enable concise code in simple, common cases. \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 signal}{\b }{\i condition} {\f23 \'de}{\i values\tab }[Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 signal}{\b }{\i string argument}{\i\fs18\dn4 1}{\i argument}{\i\fs18\dn4 2} \'c9 {\f23 \'de} {\i values}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Signals the {\i condition}, trying each active dynamic handler, the most recent first. If all dynamic handlers decline, {\f22 signal} calls {\f22 default-handler(}{\i condition}{\f22 )} . If a handler returns, all the values that it returned are returned from {\f22 signal}. If {\f22 signal} returns when the condition\rquote s recovery protocol does not allow returning, some handler has violated protocol; {\f22 signal} does not check for this error. If the condition is a restart, the caller of {\f22 signal} should always assume that it might return.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The second form signals a condition of type {\f22 }. \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 error}{\i condition} {\f23 \'de}{\i \{will never return\}\tab }[Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 error} {\i string argument}{\i\fs18\dn4 1}{\i argument}{\i\fs18\dn4 2} \'c9 {\f23 \'de} {\i \{will never return\}}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 error} is similar to {\f22 signal} but never returns; if a handler returns, {\f22 error} bombs directly to the debugger. {\f22 error} is used to ma ke it clear that a program does not expect to receive control again after signaling a condition and might enable the compiler to generate slightly more compact code.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The second form signals a condition of type {\f22 }.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 cerror} {\i restart-description condition} {\f23 \'de}{\i }{\f22 #f}{\i \tab }[Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 cerror} {\i restart-description string argument}{\i\fs18\dn4 1}{\i argument}{\i\fs18\dn4 2}{\fs18\dn4 }\'c9 {\f23 \'de} {\f22 #f}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 cerror} is the same as {\f22 error} but first establishes a handler for{\f22 }, with {\f22 init-arguments:} specifying {\f22 format-string:} {\i\f22 restart-description} and {\f22 format-arguments: }the sequence {\i\f22 argument}{\i\f22\fs20\dn4 1}, {\i\f22 argument}{\i\f22\fs20\dn4 2}, ... .\par If the restart handler is invoked, {\f22 cerror} returns {\f22 #f}; otherwise, {\f22 cerror} never returns. If {\f22 cerror} returns, the program should take the corrective actions promised in the restart-description. {\f22 cerror} is the standard way to signal correctable errors when no special class of restart condition is required.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 break} [{\i condition}] {\f23 \'de}{\i }{\f22 #f}{\i \tab }[Function]\par \pard\plain \s19\fi-480\li480\ri480\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 break} [{\i string argument}{\i\fs18\dn4 1}{\i argument}{\i\fs18\dn4 2}\'c9] {\f23 \'de} {\f22 #f}\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 break} obtains a condition in the same way as {\f22 signal} but then invokes the debugger immediately without signaling first. {\f22 break} establishes a {\f22 } so the debugger can continue execution. This is useful for breakpoints. {\f22 break} always returns {\f22 #f}. With no arguments, a default message string is used.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 check-type}{\i value type} {\f23 \'de}{\i value\tab }[Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 check-type} signals a {\f22 } if {\f22 instance?(}{\i value , type}{\f22 )} is false.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 abort}\tab [Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 Performs {\f22 error(make ())}. This function is provided as a convenient shortcut.\par The call is to {\f22 error}, rather than to {\f22 signal}, to guarantee that {\f22 abort} will never return.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Additional Operators for Handling\par \pard\plain \s2\li480\ri480\sa120 \f16 The optional {\f22 exception} clauses in Dylan\rquote s {\f22 block} statement establish exception handlers during the dynamic extent of the evaluation of the {\i body }of the {\f22 block} statement. Any number of { \i cleanup-clauses} (described under {\f22 block} in the chapter on Control Constructs) may be provided, and they may be arbitrarily interleaved with {\i exception-clauses} .The syntax of an exception clause is as follows:\par \pard \s2\li480\ri480\sa120 {\f22 \tab exception ( }{\i type} | {\i name}{\f22 :: }{\i type} #key {\i test init-arguments}{\f22 )}\par \tab {\i exception-body} [;]\par \pard \s2\li480\ri480\sa120 If one of these handlers is invoked, it never declines, but immediately takes a non-local exit, executes the expressions in the {\i exception-body} , and returns the values of the last expression in the {\i exception-body}, or {\f22 #f} if the {\i exception-body} contains no expressions. If the exception handlers are never invoked, {\f22 block} returns the values of the last expression in the {\f22 block} {\i body} (or the the values of the last expression in the last {\i cleanup-clause}, if there are {\i cleanup-clauses}). Note that when the expressions in an {\i exception-body} are executed, the handler established by that {\f22 exception} clause is no longer active.\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\i type}, {\i test}, and {\i init-arguments } are as for {\f22 let handler}. {\i name} , if present, is not evaluated but is the name of a variable that is bound to the condition around the expressions in the {\f22 block} {\i body}. \par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 The exception clauses are checked in the order in which they appear. That is, the first handler will take precedence over the second, etc.\par \pard \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 A very trivial use of an exception clause might look like:\par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 block (return)\par open-files();\par ...\par result\par \pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 exception () \par return(#f);\par \pard\plain \s25\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 cleanup\par close-files();\par \pard \s25\li960\ri480\tx2880\tx4800\tx6720 end block\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 default-handler} {\i condition} {\f23 \'de}{\i values}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\keep\tqr\tx8640\tqr\tx9360 \f16 {\f22 default-handler} is called if no dynamic handler handles a condition. There are predefined methods for {\f22 }, which returns an empty sequence, {\f22 }, which calls the debugger, {\f22 }, which prints the message and returns {\f22 #f}, and {\f22 }, which signals an error.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Operators for Interactive Handling\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 restart-query} {\i restart}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 restart-query} engages the interactive user in a dialog and stores the results in slots of restart. This function is designed to be called from a handler, after making a restart and before signaling it. The debugger uses {\f22 restart-query} , for example. There is a default method for {\f22 } which does nothing.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 return-query}{\b }{\i condition}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If the recovery protocol of {\i condition} allows returning values, this engages the interactive user in a dialog and returns the results as any number of values, which the handler should return. {\f22 return-query} should not be called if {\f22 return-allowed?} returns {\f22 #f} . If you define your own condition class whose recovery protocol allows returning values, you need to define a method for {\f22 return-query}, unless the inherited method is suitable.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Operators for Introspection\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 do-handlers} {\i funarg\tab }[Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 {\f22 do-handlers} applies{\i funarg} to all dynamically active handlers, the most recently established first. {\i funarg} receives four arguments: {\i type}, {\i test}, {\i function}, and { \i init-arguments}. The arguments describe a dynamically active handler. All arguments have dynamic extent and must not be modified. {\i test} is defaulted to a function that always returns {\f22 #t}. {\i init-arguments} is {\f22 #f} if unsupplied by the handler.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 return-allowed?}{\b }{\i condition} {\f23 \'de}{\i boolean}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 This predicate returns {\f22 #t} if the recovery protocol of {\i condition} allows returning values, or {\f22 #f} if it does not. There is a default method for {\f22 } that returns {\f22 #f}. If you define your own condition class, you need to define a method for {\f22 return-allowed?} unless the inherited method is suitable.\par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 return-description}{\b }{\i condition} {\f23 \'de}{\i description}\tab [Generic Function]\par \pard\plain \s11\li480\ri480\sa120\tqr\tx8640\tqr\tx9360 \f16 If the recovery protocol of this condition allows returning values, {\f22 return-description} returns a description of the meaning of returning values. This {\i description} can be a restart, a string, or {\f22 #f}. {\f22 return-description} should not be called if {\f22 return-allowed? }returns {\f22 #f}. If you define your own condition class whose recovery prot ocol allows returning values, you need to define a method for {\f22 return-description} unless the inherited method is suitable.\par \pard\plain \s6\li900\ri-1260\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\b \par }\pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 14. Modules{\plain \f16 \par }\pard\plain \s2\li480\ri480\sa120 \f16 Modules are used for creating large-scale variable namespaces. Modules let you build programs and program segments that have private variables. Only the variables you export are visible from outside the module. { \b Module variables} are similar to global variables of other languages. \par \pard \s2\li480\ri480\sa120 Some languages have module systems with distinct support for exporting variables, functions, types, and classes. Dylan modules operate only on variables. Because functions and classes are stored in variables, you can control access to them by controlling access to the variables that contain them. If you export the variable containing a class or function, you have effectively exported the class or function. If you do not export the variable, then you have effectively kept the class or function private.{\fs16\up6 \chftn {\footnote \pard\plain \s246\li480\ri480 \f16\fs20 {\fs18\up6 \chftn } In the general case, reflective operations can be used to defeat module encapsulation. For example, a programmer can trace from an instance to its class by calling {\f22 object-class} on the instance, even if the implementor of the class did not export the variable containing the class. This problem can sometimes be solved by the proper use of sealing, which blocks many reflective operations. }}\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Overview\par \pard\plain \li1440\ri480\sl240 \f16 {\fs20 \par }\pard \li480\ri480\sl240 A module establishes a mapping from variable names to variables (memory locations containing values). It does this in one of two ways: a variable can be {\b owned} by the module, or the module may {\b import } variables exported by another module by {\b using} the other module. Modules {\b export} variables to make them accessible to other modules. Only exported variables can be imported by other modules.\par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 Within a given module, a variable name refers to at most one variable. It is an error to create or import two or more different variables with the same name in a single module. If a name does refer to a variable, the variable is said to be {\b accessible} from the module. Each variable is owned by exactly one module, but it can be accessible from many modules.\par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 Owned variables are created by a {\f22 create} clause in a {\f22 define\~module} and in some cases by definitions associated with a module.\par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 Dylan includes two kinds of definitions. Explicit definitions are created by {\f22 define constant}, {\f22 define variable}, {\f22 define generic}, and the class name in {\f22 define class}. Implicit definitions are created by { \f22 define method }and the slot specifications of {\f22 define class}. \par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 Definitions are used both to create variables and to provide values for variables. An explicit definition performed on a variable which was not imported creates an owned variable and provides a value for it. An explicit definition performed on a variable which was imported just provides a value for the variable. An implicit definition has the same behavior, but only if there is no explicit definition for the variable. (If there is an explicit definition for the variabl e, then the implicit definition does not create the variable, nor does it provide the value for it.)\par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 There must be exactly one explicit definition for each module variable, with the exception that the explicit definition can be left out if there are one or more implicit definitions. Any module variable whose value is a generic function can have any numbe r of implicit definitions.\par \pard \li480\ri480\sl240 \par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Programs, module declarations, and expressions\par \pard\plain \li480\ri480\sl240 \f16 {\b \par }\pard \li480\ri480\sl240 A Dylan program is composed of expressions. Each expression is associated wit h a module. Within an expression, variables are referenced by variable names. The module associated with the expression provides the mapping from variable name to variable used within the expression. It is an error to reference a variable name for the p urpose of getting or setting its value if the variable name does not designate either a variable locally bound with a scope that includes the reference or a variable accessible in the associated module. \par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 Module declarations are expressions. Like other \ldblquote defining forms,\rdblquote module declarations are only allowed at top level or inside of {\f22 begin} . The variable names in module declarations are relative either to the module being declared or to a module that it uses, as specified in part b, and thus are not affected by the module declaration\rquote s associated module. A module declaration can be associated with any module where {\f22 define\~module} has its normal meaning.\par \pard \li380\ri480\sl240 \par \pard \li480\ri480\sl240 Before an expression can be compiled, the module declaration for the module associated with the expression must be compiled and then made available to the development environment in an implementation-defined way.\par \pard \li480\ri480\sl240 {\b \par }\pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Module declarations\par \pard\plain \li480\ri480\sl240 \f16 \par Modules are defined by {\f22 define\~module} forms.\par \par \pard\plain \s9\fi-480\li480\ri480\sb240\sa120\keepn\tx480\tqr\tx9360 \f16 {\b\f22 define module}{\f22 }{\i module-name} \tab [Definition]\par \pard\plain \s10\li480\ri480\sa120\keepn\tqr\tx8640\tqr\tx9360 \f16 {\f22 [ }{\i module-clauses} {\f22 ] \par end [ module ] [ }{\i module-name} {\f22 ]\par }\pard\plain \qj\li480\ri480\sl240\tqr\tx9340 \f16 \par \pard\plain \s2\li480\ri480\sa120 \f16 where each module-clause is either a {\b use clause}, a {\b create clause}, or an {\b export clause}. (see below)\par \pard\plain \li480\ri480\sl240 \f16 This form defines the module with the given name. It describes which modules are used by the module being defined, which variables are import ed from the used modules, and which variables are exported by the module being defined.\par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 {\i module-name} has the same syntax as a variable name. Module names are scoped to a library. The namespace of module names is distinct from that of variables. No variable with the name {\i module-name }is created.\par \pard \li480\ri480\sl240 \par \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Used modules\par \pard\plain \li480\ri480\sl240 \f16 {\b \par }\pard \li480\ri480\sl240 There is one or more {\i use-clause} for each module used by the module being defined. Each {\i use-clause} has the form:\par \pard \li480\ri480\sl240 \par {\f22 \tab }{\b\f22 use}{\f22 }{\i module-name}{\f22 [ }{\b\f22 ,}{\f22 }{\i module-use-options} {\f22 ] ;\par }\pard \li1440\ri480\sl240 {\fs20 \par }\pard \li480\ri480\sl240 {\i module-name} is the name of a module to be used. By default all exported variables from the used module are imported by the module being defined, under the same name they had in the used module.\par \pard \li1440\ri480\sl240 {\fs20 \par }\pard \li480\ri480\sl240 When there are multiple use clauses using the same module, the set of imported variables is the union of those specified by all the use clauses. Some variables may be imported under more than one variable name.\par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 Circular use relationships among modules are not allowed. The graph of the module-uses-module relation must be a directed acyclic graph.\par \pard \li480\ri480\sl240 \par \pard \li480\ri480 The module-use-options are used to prevent some variables from being imported, to give some or all variables different names in the new module, and to re-export variables which were imported from a used module. Each of these options applies within the sco pe of the particular use clause, and does not affect the behavior of other use clauses (even if the other use clauses indicate the same module). The various options in a module-use-option may each appear no more than once.\par \pard \li1440\ri480\sl240 {\fs20 \par }\pard \li480\ri480\sl240 {\i\f22\fs20 import-option}{\f22\fs20 ::=\par \tab }{\b\f22\fs20 import: all\par }{\f22\fs20 \tab }{\b\f22\fs20 import: }{\i\f22\fs20 import-set\par \par import-set }{\f22\fs20 ::=\par \tab }{\b\f22\fs20 \{}{\f22\fs20 }{\i\f22\fs20 imports}{\i\f22\fs20\dn4 opt}{\f22\fs20 }{\b\f22\fs20 \}\par \par }{\i\f22\fs20 imports }{\f22\fs20 ::=\par \tab }{\i\f22\fs20 import\par }{\f22\fs20 \tab }{\i\f22\fs20 import }{\b\f22\fs20 ,}{\f22\fs20 }{\i\f22\fs20 imports\par \par import }{\f22\fs20 ::=\par \tab }{\i\f22\fs20 variable-name}{\f22\fs20 \par \tab }{\i\f22\fs20 variable-name}{\f22\fs20 }{\b\f22\fs20 =>}{\f22\fs20 }{\i\f22\fs20 variable-name\par }{\f22\fs20 \par }\pard \li480\ri480\sl240 Indicates which variables are to be imported from the module being used. The default is {\f22 all} , meaning that all the variables exported by the used module should be imported. When => appears in an import-option, it specifies both an import and a rename. In other words, \ldblquote {\f22 import: \{foo => bar\}}\rdblquote is simply an abbreviation for \ldblquote {\f22 import: \{foo\}, rename: \{foo => bar\}}\rdblquote and means exactly the same thing. \par \pard \li480\ri480\sl240 {\f22\fs20 \par }{\i\f22\fs20 exclude-option}{\f22\fs20 ::=\par \tab }{\b\f22\fs20 exclude:}{\f22\fs20 }{\i\f22\fs20 variable-name-set\par }{\f22\fs20 \par }{\i\f22\fs20 variable-name-set}{\f22\fs20 ::=\par \tab }{\b\f22\fs20 \{}{\f22\fs20 }{\i\f22\fs20 variable-names}{\i\f22\fs20\dn4 opt}{\f22\fs20 }{\b\f22\fs20 \}\par \par }{\i\f22\fs20 variable-names}{\f22\fs20 ::=\par \tab }{\i\f22\fs20 variable-name\par }{\f22\fs20 \tab }{\i\f22\fs20 variable-name}{\f22\fs20 }{\b\f22\fs20 ,}{\f22\fs20 }{\i\f22\fs20 variable-names\par }\pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 Indicates variables which should not be imported. This keyword can only be used if {\f22 import:} is {\f22 all}. The default for the {\f22 exclude:} keyword is {\f22 \{\})}.\par \pard \li480\ri480\sl240 {\f22\fs20 \par }{\i\f22\fs20 prefix-option}{\f22\fs20 ::=\par \tab }{\b\f22\fs20 prefix:}{\f22\fs20 string\par }{\i\f22\fs20 \par }\pard \li480\ri480\sl240 Prepends {\i string} to the names of variables as they are imported from the used module. This option can be overridden for a particular variable by using the {\f22 rename:} keyword for that variable. The default value for the {\f22 prefix: }keyword is {\f22 ""} (the empty string).\par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 {\i\f22\fs20 rename-option}{\f22\fs20 ::=\par \tab }{\b\f22\fs20 rename: \{}{\f22\fs20 }{\i\f22\fs20 rename-specs}{\f22\fs20\dn4 opt}{\f22\fs20 }{\b\f22\fs20 \}\par \par }{\i\f22\fs20 rename-specs}{\f22\fs20 ::=\par \tab }{\i\f22\fs20 rename-spec\par }{\f22\fs20 \tab }{\i\f22\fs20 rename-spec}{\f22\fs20 }{\b\f22\fs20 ,}{\f22\fs20 }{\i\f22\fs20 rename-specs\par \par rename-spec}{\f22\fs20 ::=\par \tab }{\i\f22\fs20 variable-name}{\f22\fs20 }{\b\f22\fs20 =>}{\f22\fs20 }{\i\f22\fs20 variable-name\par }{\f22\fs20 \par }\pard \li480\ri480\sl240 Used to override the {\f22 import:}, {\f22 exclude:}, and {\f22 prefix:} keywords. The variables named are imported, regardless of whether the {\f22 import:} and {\f22 export:}keywords indicate they should be imported. {\i old-name }indicates the name of the variable in the module being used; {\i new-name }indicates the name to be given to the variable in the module being defined. The {\f22 prefix:} keyword of the use clause is ignored for variables specified by the { \f22 rename:} keyword. The default value for the {\f22 rename:} keyword is {\f22 \{\}}.\par \pard \li480\ri480\sl240 \par \pard \li480\ri480\sl240 {\i\f22\fs20 export-option}{\f22\fs20 ::=\par \tab }{\b\f22\fs20 export: all\par }{\f22\fs20 \tab }{\b\f22\fs20 export:}{\f22\fs20 }{\i\f22\fs20 variable-name-set\par }{\f22\fs20 \par }\pard \li480\ri480\sl240 Specifies variables which should be exported from the module being defined. Each of these variables must have been imported by this use clause. {\i variable-name} is the name of the variab le in the module being defined. It is also the name under which the variable will be exported. It is allowed for the same {\i variable-name} to appear more than once, as this is sometimes useful for documentation purposes. {\f22 all } indicates that all the variables imported by this use clause should be exported. The default value for the {\f22 export:} keyword is {\f22 \{\}}.\par \pard \li480\ri480\sl240 {\b \par }\pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Exporting owned variables\par \pard\plain \li480\ri480\sl240 \f16 \par A {\b module export clause} has the following syntax:\par \par {\f22 \tab }{\b\f22 export}{\f22 }{\i variable-names}{\i\f22 \par }\pard \li1440\ri480\sl240 {\fs20 \par }\pard \li480\ri480\sl240 This option specifies that the named variables are to be exported from the module being defined. Each {\i variable-name } is the name of a variable to export. These variables must be defined by a defining form in the module being defined. It is an error if any of the variables were imported from other modules. It is allowed for the same name to appear more than once, sinc e this is sometimes useful for documentation purposes.\par \pard \li480\ri480\sl240 \par A {\b module create clause} has the following syntax:\par \par {\f22 \tab }{\b\f22 create}{\f22 }{\i variable-names}{\i\f22 \par }\par \pard \li480\ri480\sl240 This option specifies that the named variables are to be created in and exported from the module being defined. A {\i variable-name } is the name of a variable to create and export. These variables must not be defined by a defining form in the module being defined, and they must be defined by a module which uses the module being defined. It is an error if any of the variables were impo rted from other modules. It is allowed for the same name to appear more than once, since this is sometimes useful for documentation purposes.\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Examples\par \pard\plain \li720\ri480\sl240 \f16 {\f22\fs20 \par define module graphics\par use dylan;\par create draw-line,\par erase-line,\par invert-line,\par skew-line\par frame-rect,\par fill-rect,\par erase-rect,\par invert-rect;\par end module graphics;\par \par define module lines\par use dylan;\par use graphics,\par \tab import: \{draw-line,\par erase-line,\par invert-line,\par skew-line\};\par end module lines;\par \par define module rectangles\par use dylan;\par use graphics,\par \tab prefix: "graphics$",\par \tab exclude: \{skew-line\};\par end module rectangles;\par \par define module dylan-gx\par use dylan, export: all;\par use graphics,\par \tab rename: \{skew-line => warp-line\},\par export: all;\par end module dylan-gx;\par \par \par }\pard \li720\ri480\sl240 The modules created by these module declarations would have access to variables with the following names:\par \pard \li720\ri480\sl240 \par \pard \li720\ri480\sl240 {\f22\fs20 graphics\tab draw-line\par \tab \tab erase-line\par \tab \tab invert-line\par \tab \tab skew-line\par \tab \tab frame-rect\par \tab \tab fill-rect\par \tab \tab erase-rect\par \tab \tab invert-rect\par }\pard \li720\ri480\sl240 \tab \tab {\i plus all the variables in the }{\i\f22 Dylan}{\i module}\par \par \pard \li720\ri480\sl240 {\f22\fs20 lines\tab \tab draw-line\par \tab \tab erase-line\par \tab \tab invert-line\par \tab \tab skew-line\par }\pard \li720\ri480\sl240 \tab \tab {\i plus all the variables in the }{\i\f22 Dylan}{\i module}\par \par \pard \li720\ri480\sl240 {\f22\fs20 rectangles\tab graphics$draw-line\par \tab \tab graphics$erase-line\par \tab \tab graphics$invert-line\par \tab \tab graphics$frame-rect\par \tab \tab graphics$fill-rect\par \tab \tab graphics$erase-rect\par \tab \tab graphics$invert-rect\par }\pard \li720\ri480\sl240 \tab \tab {\i plus all the variables in the }{\i\f22 Dylan}{\i module}\par \par \pard \li720\ri480\sl240 {\f22\fs20 dylan-gx\tab draw-line\par \tab \tab erase-line\par \tab \tab invert-line\par \tab \tab warp-line\par \tab \tab frame-rect\par \tab \tab fill-rect\par \tab \tab erase-rect\par \tab \tab invert-rect\par }\pard \li720\ri480\sl240 \tab \tab {\i plus all the variables in the }{\i\f22 Dylan}{\i module}\par \par \pard \li720\ri480\sl240 The {\f22 lines }and {\f22 rectangles }modules do not export any variables. They are presumably used to provide definitions for the variables created and exported by the {\f22 graphics }modules. The difference between the {\f22 graphics }module and the {\f22 dylan-gx }module is that one variable is renamed, and the {\f22 dylan-gx }module exports the variables which it imports from the {\f22 dylan} module, while the {\f22 graphics }module does not.\par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 15. Libraries\par \pard\plain \li480\ri480 \f16 A library description consists of the following parts:\par \pard \li480\ri480 {\f22\fs20 \par }\pard\plain \s21\fi-360\li840\ri480\sa160 \f16 \bullet \tab A single library declaration form. It specifies a name for the library, a set of modules which are exported by the library for use by other libraries, and a set of modules that are imported from other libraries for use by the library being defined. Library declaration forms are described below.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab The association of source code with the library. The mechanism by which this association is made is implementation-defined.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab The association of executable code with the library. The mechanism by which this association is made is implementation-defined. The mechanism by which the compiler is invoked to produce the executable code is implementation-defined.\par \pard \s21\fi-360\li840\ri480\sa160 \bullet \tab The association of library export information with the library. The mechanism by which this association is made is implementation-defined. The mechanism by which the compiler is invoked to produce the library export information is implementation-defined. The contents of library export information is implementation-de pendent, but it comprises the information required to process the source code of some other library that imports the library.\par \pard\plain \li480\ri480 \f16 \par \pard \li480\ri480 The library export information is the only part of a Dylan library that is needed to allow some other library to import it. A li brary that exports some modules does not have any additional declarations whose purpose is to provide information to the compiler when it is processing the code of a library that imports those modules. Rather, any such information that might be needed is obtained in some implementation defined way while processing the source expressions of the exporting library and is retained in the library export information of the exporting library.\par \pard \li480\ri480 {\fs20 \par }\pard \li480\ri480 The syntax for library declarations matches the syntax for module definitions exactly, except of course that the word {\f22 module} is replaced with the word {\f22 library}, and that library declarations do not have create clauses. \par \pard \li480\ri480 \par \pard \li480\ri480 Exporting a module from a library makes all of the variables exported by the module available for import by modules in other libraries. There are two ways in which a module may be exported from a library.\par \pard \li1440\ri480 \par \pard\plain \s21\fi-360\li840\ri480\sa160 \f16 (1) If the module is defined in the library, it is exported by including a {\i library-export-clause} that names the module in the library declaration. Each {\i module-name} in a {\i library-export-clause} is the name of a module exported by the library.\par (2) If the module is imported from some other library, it is exported by including an {\i export-option} that specifies the module (either by name or implicitly by using \ldblquote export: all\rdblquote ) in a {\i library-use-option} that imported the module.\par \pard\plain \li480\ri480 \f16 \par \pard \li480\ri480 Importing a module into a library allows the module to be used by modules defined within the library. Importing a module into a library does not allow expressions in the library to be associ ated with the module. A module is imported into a library by including a {\i library-use-clause} in the library declaration that includes the module in the set of modules imported from the used library. By default, all exported modules from the used library are imported by the library being defined, under the same name they had in the used library. \par \pard \li480\ri480 \par \pard \li480\ri480 When there are multiple use clauses using the same library, the set of imported modules is the union of those specified by all the {\i use-clauses.} Some modules may be imported under more than one module name.\par \pard \li480\ri480 \par \pard \li480\ri480 The options in a {\i use-clause} are used to prevent some modules from being imported, to give some or all the imported modules different names in the new library, and to re-export modules which were imported from a used library. Each of these options applies within the scope of the pa rticular {\i use-clause,} and does not affect the behavior of other {\i use-clauses.\par }\pard \li480\ri480 \par \pard \li480\ri480 The meanings of the various options in a {\i library-use-clause} are similar to the corresponding options in a {\i module-use-clause,} except that it is module names in libraries that are being specified, rather than variable names in modules.\par \pard \li480\ri480 \par \pard \li480\ri480 The mechanism by which the {\i library-name} in a {\i library-use-clause} is associated with the corresponding library description is implementation-defined.\par \pard \li480\ri480 \par \pard \li480\ri480 Each implementation must provide a library named {\f22 dylan} which exports a module named {\f22 dylan} . That module must export exactly those variables documented as being part of the Dylan language, and the values of those variables must be as specified by the Dylan language. The {\f22 dylan} library is permitted to export additional implementation dependent modules.\par \pard \li480\ri480 \par \pard \li480\ri480 Library declarations are expressions. Like other \ldblquote defining forms,\rdblquote library declarations are only allowed at top level or inside of {\f22 begin} . The names in a library declaration are not module variable names, and thus are not affected by the library declaration\rquote s associated module. A library declaration can be associated with any module where \ldblquote {\f22 define library} \rdblquote has its normal meaning.\par \pard \li480\ri480 \par \pard \li480\ri480 Macros can expand into library declarations. This happens during compilation of the library declaration.\par \pard \li480\ri480 \par \pard \li480\ri480 Each library contains an implicitly defined module whose name is {\f22 dylan-user} . Within this module, all the variables specified by the Dylan language are accessible using their specified names. Additional implementation-dependent variables may also be accessible from this module.\par \pard \li480\ri480 {\f22\fs20 \page \par }\pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 Appendix A: How to get more information\par \pard\plain \li480\ri480 \f16 Internet anonymous ftp site: \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 cambridge.apple.com:/pub/dylan/\par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 \par }\pard\plain \li480\ri480 \f16 This contains the latest version of this manual, the Dylan FAQ, design notes (language spec updates), public Dylan implementations, code, and papers about Dylan.\par \pard \li480\ri480 {\f22 \par }\pard \li480\ri480 Mosaic/World-Wide Web site:\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 http://legend.gwydion.cs.cmu.edu:8001/dylan\par }\pard\plain \li480\ri480 \f16 \par Internet newsgroup:\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 comp.lang.dylan\par }\pard\plain \li480\ri480 \f16 \par The Dylan newsgroup is also available as an email list or daily digest.\par To subscribe, send email to {\f22 majordomo@cambridge.apple.com\par }containing one of these requests in the message body:\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 subscribe info-dylan }{\plain \i\f16 your name}{\plain \f22 \par }\pard\plain \li480\ri480 \f16 or\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 subscribe info-dylan-digest }{\plain \i\f16 your name}{\plain \i\f22 \par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 \par }\pard\plain \li480\ri480 \f16 or just send a message saying \ldblquote {\f22 help}\rdblquote for more information.\par \par Dylan information on Applelink:\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 Developer Support:Developer Services:Development Platforms:Dylan Related:\par }\pard\plain \li480\ri480 \f16 \par For inquiries about Apple\rquote s Dylan products, send email to\par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 DYLAN@applelink.apple.com\par }\pard\plain \li480\ri480 \f16 {\f22 \par }\pard \li480\ri480 If you have questions or comments about the Dylan language design, or if you\rquote re considering building your own Dylan implementation, please\par \pard \li480\ri480 let us know! Email to: \par \pard\plain \s5\li960\ri480\sb120\keepn\tx2880\tx4800\tx6720 \f22\fs20 {\plain \f22 dylan-comments@cambridge.apple.com\par }\pard\plain \s6\li960\ri480\keepn\tx2880\tx4800\tx6720 \f22\fs20 \page \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 Appendix B: Dylan Syntax BNF\par \pard\plain \s2\li480\ri480\sa120 \f16 The grammar uses some special notation to make it more readable. \par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab The {\i\fs18\dn4 opt} suffix means that the preceding item is optional. \par \pard \s2\fi-360\li840\ri480\sa120 \bullet \tab A trailing ellipsis ({\i ...}) is used in two different ways to signal possible repetition. \par \pard \s2\fi-360\li1800\ri480\sa120 \bullet \tab If there is only one item on the line preceding the ellipsis, the item may appear one or more times. \par \pard \s2\fi-360\li1800\ri480\sa120 \bullet \tab If more than one item precedes the ellipsis, the last of these items is designated a separator; the rest may appear one or more times, with the separator appearing after each occurrence but the last. (When only one item appe rs, the separator does not appear.)\par \pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 Lexical grammar\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Lexical notes\par \pard\plain \s2\li480\ri480\sa120 \f16 In the lexical grammar, the various elements that come together to form a single token on the right-hand sides of rules must {\i not} be separated by white-space, so that the end result will be a single token. This is in contrast to the phrase grammar, where each element is already a complete token or a series of complete tokens.\par \pard \s2\li480\ri480\sa120 Arbitrary white-space is permitted between tokens, but it is required only as necessary to separate tokens that might otherwise blend together.\par Case is not significant except within character and string literals. The grammars do not reflect this, using one case or the other, but it is still true.\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\pagebb\brdrt\brdrs \b\f16\fs28 Comments\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 comment:\par \pard\plain \s27\li720\sl-240\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 //}{\plain \f16\fs20 \'c9}{\plain \f16\fs18 the rest of the line}{\plain \f16\fs20 \line }{\plain \b\f22\fs20 /*}{\plain \f16\fs20 \'c9}{\plain \f16\fs18 everything even across lines}{\plain \f16\fs20 \'c9 }{\plain \b\f22\fs20 */\par }\pard\plain \s253\li475\ri480\sb240\sa120\keepn\brdrt\brdrs \b\f16\fs28 Tokens\par \pard\plain \s26\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 token:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 SYMBOL}\line {\plain \caps\f16\fs18 keyword}\line {\plain \caps\f16\fs18 literal\line string\line unary-operator\line binary-operator\line }reserved-word{\plain \caps\f16\fs18 \line } punctuation\line #-word\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 literal}:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 number\line character-literal\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 punctuation:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of\tab }{\plain \b\f22\fs20 ( ) , . ; [ ] \{ \} :: - = == => #( #[ ? ?? ...}\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 #-word:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of\tab }{\plain \b\f22\fs20 #t #f #next #rest #key #all-keys\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Reserved words\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 reserved-word:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 core-word\line begin-word\line intermediate-word\line {\plain \caps\f16\fs18 define-word\par }\pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 begin-word:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 simple-begin-word\par }\pard \s27\li720\sl-240\keep\tx720\tx2160 {\plain \caps\f16\fs18 expr-begin-word\par begin-word\par }\pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 intermediate-word:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 simple-intermediate-word\par }\pard \s27\li720\sl-240\keep\tx720\tx2160 {\plain \caps\f16\fs18 expr-intermediate-word\par intermediate-word\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 core-word:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}{\fs18 \tab }{\plain \b\f22\fs20 define end generic handler let\line }{\plain \f16\fs18 one of}{\plain \b\f22\fs20 \tab local method macro otherwise}\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 \page Symbols and keywords\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol}{\caps\fs18 :}\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 any}{\plain \f16\fs20 }symbol{\plain \f16\fs20 }{\plain \f16\fs18 that\rquote s not also a }reserved-word{\plain \f16\fs20 \line }{\plain \b\f22\fs20 \\}{\plain \f16\fs20 } operator-symbol{\b\f22 \par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 keyword}:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 symbol {\plain \b\f22\fs20 :\line #} {\plain \caps\f16\fs18 string}{\b\f22 \par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 symbol:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 leading-alphabetic\line leading-numeric alphabetic-character leading-alphabetic\line leading-graphic leading-alphabetic\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 leading-alphabetic:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 alphabetic-character\line leading-alphabetic any-character\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 leading-numeric:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 numeric-character\line leading-numeric any-character\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 leading-graphic:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 graphic-character\line leading-graphic any-character\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 any-character:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 alphabetic-character\line numeric-character\line graphic-character\line special-character\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 alphabetic-character:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of\tab }{\plain \b\f22\fs20 a b c d e f g h i j k l m n o p q r s t u v w x y z\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 numeric-character:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}\tab {\plain \b\f22\fs20 0 1 2 3 4 5 6 7 8 9}\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 graphic-character:{\plain \f16\fs20 \par }\pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}\tab {\plain \b\f22\fs20 ! & * < = > | ^ $ % @ _\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 special-character:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}{\plain \f16\fs20 \tab }{\plain \b\f22\fs20 - + ~ ? /\par }\pard\plain \s253\li475\ri480\sb120\sa120\keepn\pagebb\brdrt\brdrs \b\f16\fs28 Operators\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 unary-operator}:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 unary-operator\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 binary-operator}:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 binary-operator\line special-operator\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 operator-symbol:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 unary-operator\line binary-operator\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 unary-operator:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}{\fs18 \tab }{\plain \b\f22\fs20 - ~}{\b\f22 \par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 binary-operator:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}\tab {\plain \b\f22\fs20 + - * / ^ = == ~= < <= > >=}\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 special-operator:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}{\fs18 \tab }{\plain \b\f22\fs20 & | :=\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Character and string literals\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 character-literal:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 '} character {\plain \b\f22\fs20 '}{\b\f22 \par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 character:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 any printing character (including space) except for}{\plain \f16\fs20 }{\plain \b\f22\fs20 '}{\plain \f16\fs20 }{\plain \f16\fs18 or}{\plain \f16\fs20 }{\plain \b\f22\fs20 \\}{\plain \f16\fs20 \line }{\plain \b\f22\fs20 \\} escape-character\line {\plain \b\f22\fs20 \\}{\plain \f16\fs20 }{\plain \b\f22\fs20 '}\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 string}:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 "} more-string\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 more-string:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 string-character more-string\line {\plain \b\f22\fs20 "}\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 string-character:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 any printing character (including space) except for}{\plain \f16\fs20 }{\plain \b\f22\fs20 "}{\plain \f16\fs20 }{\plain \f16\fs18 or}{\plain \f16\fs20 }{\plain \b\f22\fs20 \\}{\plain \f16\fs20 \line }{\plain \b\f22\fs20 \\} escape-character\line {\plain \b\f22\fs20 \\}{\plain \f16\fs20 }{\plain \b\f22\fs20 "}\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 escape-character:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of\tab }{\plain \b\f22\fs20 \\ a b e f n r t 0}\par \pard\plain \s253\li475\ri480\keepn\pagebb \b\f16\fs28 Numbers\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 number:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 integer\par ratio\par floating-point\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 integer:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 binary-integer\par octal-integer\par sign{\fs18\dn4 opt} decimal-integer\par hex-integer\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 binary-integer:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 #b} binary-digit\par binary-integer binary-digit\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 octal-integer:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 #o} octal-digit\par octal-integer octal-digit\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 decimal-integer:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 decimal-digit\par decimal-integer decimal-digit\par \pard\plain \s26\sb80\sl-240\keepn\tx720\tx2160 \i\f16\fs20 hex-integer:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 #x} hex-digit\par hex-integer hex-digit\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 binary-digit:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}{\plain \f16\fs20 \tab }{\plain \b\f22\fs20 0 1}\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 octal-digit:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of\tab }{\plain \b\f22\fs20 0 1 2 3 4 5 6 7}\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 decimal-digit:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of\tab }{\plain \b\f22\fs20 0 1 2 3 4 5 6 7 8 9}\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 hex-digit:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of\tab }{\plain \b\f22\fs20 0 1 2 3 4 5 6 7 8 9 A B C D E F}\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 ratio:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 sign{\fs18\dn4 opt} decimal-integer {\plain \b\f22\fs20 /}{\plain \f16\fs20 } decimal-integer\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 floating-point:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 sign{\fs18\dn4 opt} decimal-integer{\fs18\dn4 opt} {\plain \b\f22\fs20 .} decimal-integer exponent{\fs18\dn4 opt}\par sign{\fs18\dn4 opt} decimal-integer {\plain \b\f22\fs20 .} decimal-integer{\fs18\dn4 opt} exponent{\fs18\dn4 opt}\par sign{\fs18\dn4 opt} decimal-integer exponent\par \pard\plain \s26\sb80\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 exponent:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 E} sign{\fs18\dn4 opt} decimal-integer\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 sign:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \f16\fs18 one of}{\plain \f16\fs20 \tab }{\plain \b\f22\fs20 + -\par }\pard\plain \s254\li480\ri480\sb240\sa240\keepn\brdrt\brdrs \b\f16\fs36 \page \page Phrase Grammar\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Program structure\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 dylan-program:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 body{\fs18\dn4 opt\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 body:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 constituents {\plain \b\f22\fs20 ;}{\fs18\dn4 opt\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 constituents:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 constituent {\plain \b\f22\fs20 ;} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 constituent:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 defining-form\line local-declaration\line expression\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 \par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 Property lists\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 property-list:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 property \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 property:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 ,} {\plain \caps\f16\fs18 keyword} value\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 value:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 expression\line {\plain \b\f22\fs20 \{} property-set{\fs18\dn4 opt} {\plain \b\f22\fs20 \}\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 property-set:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 property-set-member {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 property-set-member:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 property-set-item\line property-set-item {\plain \b\f22\fs20 =>} property-set-item\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 property-set-item:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol}\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 \page Defining Forms\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 defining-form:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 define} modifiers{\fs18\dn4 opt} {\plain \b\f22\fs20 method} method-definition\line {\plain \b\f22\fs20 define} modifiers{\fs18\dn4 opt} {\plain \b\f22\fs20 generic} generic-function-definition\line {\plain \b\f22\fs20 define} modifiers{\fs18\dn4 opt} {\plain \caps\f16\fs18 define-word} definition\line {\plain \b\f22\fs20 define} modifiers{\fs18\dn4 opt} {\plain \caps\f16\fs18 define-word} bindings\line macro-definition\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 modifiers:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 method-definition:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol} method-body {\plain \b\f22\fs20 end} {\plain \b\f22\fs20 method}{\fs18\dn4 opt} {\plain \caps\f16\fs18 symbol}{\fs18\dn4 opt}{\plain \f16\fs20 \par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 generic-function-definition:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol}{\plain \f16\fs20 }generic-function-body property-list{\fs18\dn4 opt\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 definition:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol} detail-info{\fs18\dn4 opt} item-list{\fs18\dn4 opt} {\plain \b\f22\fs20 end} {\plain \caps\f16\fs18 define-word}{\fs18\dn4 opt} {\plain \caps\f16\fs18 symbol}{ \fs18\dn4 opt\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 item-list:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 items {\plain \b\f22\fs20 ;}{\fs18\dn4 opt}\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 items:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 item {\plain \b\f22\fs20 ;} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 item:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 item-modifiers{\fs18\dn4 opt} item-word item-contents property-list{\fs18\dn4 opt\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 item-modifiers:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 item-modifier \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 item-modifier:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol\line define-word\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 item-word:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 item-contents:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 variable{\fs18\dn4 \line }{\plain \caps\f16\fs18 keyword}{\fs18\dn4 \line }{\plain \caps\f16\fs18 symbol} {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 \page Local declarations\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 local-declaration:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 let} bindings\line {\plain \b\f22\fs20 let} {\plain \b\f22\fs20 handler} condition {\plain \b\f22\fs20 =} handler\line {\plain \b\f22\fs20 local} local-methods\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 condition:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 type\line {\plain \b\f22\fs20 (} type property-list{\fs18\dn4 opt} {\plain \b\f22\fs20 )\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 handler:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 expression\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 local-methods:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 method}{\fs18\dn4 opt} method-definition {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 bindings:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 variable {\plain \b\f22\fs20 =} expression\line {\plain \b\f22\fs20 (} variable-list {\plain \b\f22\fs20 )} {\plain \b\f22\fs20 =} expression\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 variable-list:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 variables\line variables {\plain \b\f22\fs20 ,} {\plain \b\f22\fs20 #rest} {\plain \caps\f16\fs18 symbol}\line {\plain \b\f22\fs20 #rest} {\plain \caps\f16\fs18 symbol}\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 variables:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 variable {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 variable:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol}\line {\plain \caps\f16\fs18 symbol} {\plain \b\f22\fs20 ::} type\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 type:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 operand\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 \page Expressions\par \pard\plain \s26\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 expressions:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 expression {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 expression:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 binary-operand {\plain \caps\f16\fs18 binary-operator} \'c9\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 binary-operand:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 keyword}\line {\plain \caps\f16\fs18 unary-operator}{\fs18\dn4 opt} operand\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 operand:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 operand {\plain \b\f22\fs20 (} arguments{\fs18\dn4 opt} {\plain \b\f22\fs20 )}\line operand {\plain \b\f22\fs20 [} arguments {\plain \b\f22\fs20 ]\line }operand {\plain \b\f22\fs20 .} {\plain \caps\f16\fs18 symbol\line }leaf\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 arguments:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 keyword}{\fs18\dn4 opt} expression {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 leaf:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 literal\line {\plain \caps\f16\fs18 symbol}\line {\plain \b\f22\fs20 (} expression {\plain \b\f22\fs20 )\line method}{\plain \b\f16\fs20 }method-body{\plain \f16\fs20 }{\plain \b\f22\fs20 end}{\plain \f16\fs20 }{\plain \b\f22\fs20 method}{\fs18\dn4 opt}{\plain \b\f22\fs20 \line }statement\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 literal:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 literal\line string} \'c9\line {\plain \b\f22\fs20 #t}\line {\plain \b\f22\fs20 #f}\line {\plain \b\f22\fs20 #(} constants {\plain \b\f22\fs20 .} constant {\plain \b\f22\fs20 )}{\caps\fs18 \line }{\plain \b\f22\fs20 #(} constants{\fs18\dn4 opt} {\plain \b\f22\fs20 )}{\plain \f16\fs20 \line }{\plain \b\f22\fs20 #[} constants{\fs18\dn4 opt} {\plain \b\f22\fs20 ]\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 constants:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 constant {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 constant:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 literal\line {\plain \caps\f16\fs18 keyword\par }\pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 \page Statements\par \pard\plain \s26\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 statement:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 begin-clause body{\fs18\dn4 opt} intermediate-clauses{\fs18\dn4 opt} end-clause\line begin-clause case-body {\plain \b\f22\fs20 ;}{\fs18\dn4 opt} end-clause\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 begin-clause:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 begin-word} detail-info\line {\plain \caps\f16\fs18 expr-begin-word} {\plain \b\f22\fs20 (} expression {\plain \b\f22\fs20 )}\line {\plain \caps\f16\fs18 simple-begin-word \par }\pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 intermediate-clauses:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 intermediate-clause body \'c9\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 intermediate-clause:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 intermediate-word} detail-info\line {\plain \caps\f16\fs18 expr-intermediate-word} {\plain \b\f22\fs20 (} expression {\plain \b\f22\fs20 )}{\fs18\dn4 \line }{\plain \caps\f16\fs18 simple-intermediate-word}{\plain \b\f22\fs20 \par }\pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 end-clause\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 end} begin-word{\fs18\dn4 opt}{\plain \b\f22\fs20 \par }\pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 begin-word:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 begin-word}{\fs18\dn4 \line }{\plain \caps\f16\fs18 expr-begin-word}{\fs18\dn4 \line }{\plain \caps\f16\fs18 simple-begin-word}{\fs18\dn4 \par }\pard\plain \s26\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 case-body:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 case-label constituents{\fs18\dn4 opt} {\plain \b\f22\fs20 ;} \'c9\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 case-label:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 expressions {\plain \b\f22\fs20 =>\line (} expressions {\plain \b\f22\fs20 )} {\plain \b\f22\fs20 =>\line otherwise} {\plain \b\f22\fs20 =>}{\fs18\dn4 opt\par }\pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 detail-info:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 (} detail-list{\fs18\dn4 opt} {\plain \b\f22\fs20 )}\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 detail-list:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 expression detail-clauses{\fs18\dn4 opt} property-list{\fs18\dn4 opt}\line details property-list{\fs18\dn4 opt}\line details {\plain \b\f22\fs20 ,} {\plain \caps\f16\fs18 expr-begin-word} expression{\fs18\dn4 \par }\pard\plain \s26\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 details:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 detail {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 detail:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 variable detail-clauses{\fs18\dn4 opt}\line variable {\plain \b\f22\fs20 =} expression detail-clauses{\fs18\dn4 opt\par }\pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 detail-clauses:\par \pard\plain \s27\li720\keep\tx720\tx2160 \i\f16\fs20 detail-clause \'c9\par \pard\plain \s26\sl360\keep\keepn\tx720\tx2160 \i\f16\fs20 detail-clause:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 symbol} expression\par \pard\plain \s253\li475\ri480\sb120\sa120\keepn\brdrt\brdrs \b\f16\fs28 \page Methods and generic functions\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 method-body:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 (} parameter-list{\fs18\dn4 opt} {\plain \b\f22\fs20 )} {\plain \b\f22\fs20 ;}{\fs18\dn4 opt} body{\fs18\dn4 opt}{\plain \b\f22\fs20 \line (} parameter-list{\fs18\dn4 opt } {\plain \b\f22\fs20 )} {\plain \b\f22\fs20 =>} variable {\plain \b\f22\fs20 ;} body{\fs18\dn4 opt}{\plain \b\f22\fs20 \line (} parameter-list{\fs18\dn4 opt} {\plain \b\f22\fs20 )} {\plain \b\f22\fs20 =>} {\plain \b\f22\fs20 (} variable-list{ \fs18\dn4 opt} {\plain \b\f22\fs20 )} {\plain \b\f22\fs20 ;}{\fs18\dn4 opt} body{\fs18\dn4 opt}{\plain \b\f22\fs20 \par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 generic-function-body:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 (} parameter-list{\fs18\dn4 opt} {\plain \b\f22\fs20 )\line (} parameter-list{\fs18\dn4 opt} {\plain \b\f22\fs20 )} {\plain \b\f22\fs20 =>} variable{\plain \b\f22\fs20 \line (} parameter-list{\fs18\dn4 opt} {\plain \b\f22\fs20 )} {\plain \b\f22\fs20 =>} {\plain \b\f22\fs20 (} variable-list{\fs18\dn4 opt} {\plain \b\f22\fs20 )\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 parameter-list:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 parameters\line parameters {\plain \b\f22\fs20 ,} next-rest-key-parameter-list\line next-rest-key-parameter-list\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 next-rest-key-parameter-list:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 #next} {\plain \caps\f16\fs18 symbol\line }{\plain \b\f22\fs20 #next} {\plain \caps\f16\fs18 symbol} {\plain \b\f22\fs20 ,} rest-key-parameter-list{\plain \caps\f16\fs18 \line }rest-key-parameter-list{\plain \caps\f16\fs18 \par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 rest-key-parameter-list:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 #rest} {\plain \caps\f16\fs18 symbol\line }{\plain \b\f22\fs20 #rest} {\plain \caps\f16\fs18 symbol} {\plain \b\f22\fs20 ,} key-parameter-list{\plain \caps\f16\fs18 \line }key-parameter-list\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 key-parameter-list:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 #key}{\plain \f16\fs20 }keyword-parameters{\fs18\dn4 opt}\line {\plain \b\f22\fs20 #key}{\plain \f16\fs20 }keyword-parameters{\fs18\dn4 opt} {\plain \b\f22\fs20 ,} {\plain \b\f22\fs20 #all-keys\line #all-keys}\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 parameters:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 parameter {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 parameter:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 variable\line {\plain \caps\f16\fs18 symbol} {\plain \b\f22\fs20 ==} expression\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 keyword-parameters:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 keyword-parameter {\plain \b\f22\fs20 ,} \'c9\par \pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 keyword-parameter:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \caps\f16\fs18 keyword}{\fs18\dn4 opt}{\plain \f16\fs20 }{\plain \caps\f16\fs18 symbol} default{\fs18\dn4 opt}{\plain \caps\f16\fs18 \par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 default:\par \pard\plain \s27\li720\sl-240\keep\tx720\tx2160 \i\f16\fs20 {\plain \b\f22\fs20 (}{\plain \f16\fs20 }expression{\plain \f16\fs20 }{\plain \b\f22\fs20 )\par }\pard\plain \s26\sb160\sl-240\keep\keepn\tx720\tx2160 \i\f16\fs20 \par \pard\plain \s255\li475\ri475\sb80\sa360\keepn\pagebb\brdrt\brdrs \b\f16\fs48 Index\par \pard\plain \li480\ri480 \f16 \par \pard \sect \sectd \sbknone\linemod0\linex0\cols2\endnhere {\headerl \pard\plain \s2\li480\ri480\sa120 \f16 \par }{\headerr \pard\plain \s2\li480\ri480\sa120 \f16 \par }{\footerl \pard\plain \s243\li440\ri460\brdrt\brdrs \tqc\tx3600\tqr\tx8900 \i\f16 {\chpgn }\tab June 4, 1994\tab Dylan Interim Reference Manual\tab \par }{\footerr \pard\plain \s243\li440\ri460\brdrt\brdrs \tqc\tx3600\tqc\tx5040\tqr\tx8900 \i\f16 Dylan Interim Reference Manual\tab June 4, 1994\tab {\chpgn }{\plain \f16 \par }}\pard\plain \s240\li480 \f16 ^ 140\par #() 111\par #(\'c9) 8, 111\par #all-keys 8, 48\par #f 8, 27\par #key 8, 48\par #next 8, 48, 60-62\par #rest 8, 48-54\par #t 8, 27\par #[\'c9] 8, 111\par $ 9\par $permanent-hash-state 127\par % (format directives) 152\par & 31, 144\par '\'c9' 8\par * 139\par *\'c9* 9\par + 139\par -setter syntax 10, 68, 70\par . 16\par / 139\par /* ... */ 8\par // 8\par :=\par \pard\plain \s239\li960 \f16 extended form of 24\par used with -setter names 10\par variable assignment 24\par \pard\plain \s240\li480 \f16 < 40\par \pard\plain \s239\li960 \f16 strings 120\par \pard\plain \s240\li480 \f16 <= 41\par 156\par 110\par 110\par 135\par 87\par 138\par 154\par 110\par 138\par 111\par 154\par 129\par 138\par 138\par 65\par 65\par 138\par 111\par 66\par 130\par \pard \s240\li480 131\par \pard \s240\li480 131\par 138\par 112\par 111, 118\par 138\par 138\par 138\par 155\par 155\par 129\par 154\par 154\par 111\par 156\par 155\par 138\par 89\par 131\par 112, 119\par 112\par 136\par
112, 121\par 155\par 87\par 112\par 113\par 155\par <\'c9> 9\par ~= 40\par = 40\par \pard\plain \s239\li960 \f16 lists 118\par ranges 119\par sequences 109\par \pard\plain \s240\li480 \f16 ==\par \pard\plain \s239\li960 \f16 identity comparison 39\par singleton shorthand 48, 51, 69\par \pard\plain \s240\li480 \f16 > 41\par >= 41\par ? 9\par abort 159\par abs 141\par abstract 69, 91\par abstract class 4\par accessible 163\par add\par \pard\plain \s239\li960 \f16 sequences 102\par \pard\plain \s240\li480 \f16 add!\par \pard\plain \s239\li960 \f16 deques 115\par lists 117\par sequences 102\par stretchy-vectors 119\par \pard\plain \s240\li480 \f16 add-method 62\par add-new 102\par add-new! 102\par all 166, 167\par all-superclasses 85\par always 145\par and 31\par angle brackets 9\par any? 98\par applicable 5\par applicable-method? 64\par apply 146\par aref 114\par aref-setter 114\par as 86\par \pard\plain \s239\li960 \f16 135\par 135\par 136\par 136\par \pard\plain \s240\li480 \f16 as-lowercase 120, 135\par as-lowercase! 120\par as-uppercase 120, 135\par as-uppercase! 120\par ash 141\par automatic memory management {\i xi}\par backslash (\\) 7, 16, 139\par backward-iteration-protocol 124\par begin 14\par block 35, 160\par break 159\par case 29\par ceiling 139\par ceiling/ 140\par cerror 159\par character constants 8\par characters 135\par check-type 159\par choose 103\par choose-by 104\par class heterarchy 4\par class precedence list 59\par class-for-copy 86, 96\par classes 4, 67\par cleanup 35\par coercing objects 86\par collection clause 32\par collection keys 128\par collections 95-134\par comments 8\par complement 143\par compose 143\par concatenate 106\par concatenate-as 106\par concrete 69, 91\par concrete class 4\par conditions 147\par congruent parameter lists 54\par conjoin 144\par controlling dynamism 91\par copy-sequence 105, 118\par copying objects 86\par create 168\par curry 144\par \pard \s240\li480 defaulted initialization arguments, 78\par \pard \s240\li480 define class 69\par define constant 20\par define generic 43\par define method 44\par define sealed method 93\par define variable 19\par denominator 141\par dimension 115\par dimensions 113, 122\par direct instance 4\par direct-subclasses 85\par direct-superclasses 4, 85\par disjoin 144\par do 96\par do-handlers 161\par dollar sign 9\par dylan library 173\par dylan module 173\par dylan-user module 173\par dynamism, controlling 91\par element\par \pard\plain \s239\li960 \f16 collections 129\par strings 121\par vectors 122\par \pard\plain \s240\li480 \f16 element-setter\par \pard\plain \s239\li960 \f16 collections 131\par strings 121\par tables 122\par vectors 122\par \pard\plain \s240\li480 \f16 empty? 96\par end [ block ] 35\par environment 19\par equivalence class 125\par equivalence predicate 125\par error 159\par establishing block 36\par even? 138\par every? 98\par exception 35, 160\par exception handling 147\par exclude: 166\par exit procedure 35\par explicit step clause 32\par export: 167\par expressions 10\par false 8, 27\par fields 67\par fill! 100\par find-key 100\par find-method 64\par first 108\par first-setter 108\par floor 139\par floor/ 140\par for 32\par format string 152\par forward-iteration-protocol 123\par free 69, 91\par free class 5\par function-arguments 63\par function-specializers 63\par functions 4, 5\par garbage collection {\i xi}\par gcd 141\par general instance 4\par generic function 5\par \pard \s240\li480 generic-function-mandatory-keywords 63\par \pard \s240\li480 generic-function-methods 62\par getter method 67, 70\par getters 9\par hash code 126\par hash function 126\par hash id 126\par hash state 126\par head 116\par head-setter 117\par identity 146\par \pard\plain \s239\li960 \f16 comparison predicate 39\par \pard\plain \s240\li480 \f16 if 28\par implicit body 14\par import: 166\par improper list 116\par indirect instance 4\par \pard \s240\li480 infix operator escape character (\\) 16, 139\par \pard \s240\li480 infix operators 7, 15\par initialize 80\par instance variables 67\par instance? 84\par instantiable class 4\par integral? 138\par intersection 104\par \pard\plain \s239\li960 \f16 ranges 119\par \pard\plain \s240\li480 \f16 intervening blocks 36\par iteration protocol 122\par iteration variable 32\par key-sequence 129\par key-test\par \pard\plain \s239\li960 \f16 collections 101\par sequences 109\par \pard\plain \s240\li480 \f16 keyword initializable 71\par keyword parameters 48\par keywords 8, 136\par last 108\par last-setter 109\par lcm 141\par let 20\par let handler 156\par lexical conventions 7\par lexical variables 19\par libraries 171-173\par list 116\par lists 8\par literal constant 10\par local 47\par local precedence order 59\par logand 141\par logbit? 141\par logior 141\par lognot 141\par logxor 141\par make 79\par mandatory keywords 49\par map 97\par map-as 97\par map-into 97\par max 141\par member?\par \pard\plain \s239\li960 \f16 collections 99\par ranges 118\par \pard\plain \s240\li480 \f16 merge-hash-codes 127\par method 5\par \pard\plain \s239\li960 \f16 special form 45\par \pard\plain \s240\li480 \f16 min 141\par minus 139\par module declarations 164\par module variables 19, 163\par modules 163\par modulo 140\par multiple values 22\par \pard\plain \s239\li960 \f16 used to perform parallel binding 23\par \pard\plain \s240\li480 \f16 mutability 130\par namespaces 163\par naming variables 9\par negative 139\par negative? 138\par next-method 60-62\par next-method parameter 48\par non-local exit 35\par numerator 141\par numeric clause 32\par object-class 85\par object-hash 128\par objects 4\par odd? 138\par open 69, 91\par open class 4\par or 31\par otherwise 29, 30\par outer expression 10\par pair 116\par parameter list congruency 54\par parameter lists 48\par permit 50\par pop 115\par pop-last 115\par positive? 138\par prefix: 167\par primary 69, 91\par primary class 5\par private variables 163\par push 115\par push-last 115\par question mark 9\par range 118\par rank 113\par rationalize 141\par rcurry 144\par recognize 49\par reduce 99\par reduce1 99\par remainder 140\par remove\par \pard\plain \s239\li960 \f16 sequences 103\par \pard\plain \s240\li480 \f16 remove!\par \pard\plain \s239\li960 \f16 deques 115\par lists 117\par sequences 103\par stretchy-vectors 119\par \pard\plain \s240\li480 \f16 remove-duplicates 105\par remove-duplicates! 105\par remove-key! 121\par remove-method 64\par rename: 167\par replace-elements! 100\par replace-subsequence! 106\par required parameters 48\par rest parameters 48\par restart 151\par restart-query 161\par return type declarations 48\par return-allowed? 161\par return-description 162\par return-query 161\par reverse 107\par \pard\plain \s239\li960 \f16 ranges 119\par \pard\plain \s240\li480 \f16 reverse! 107\par \pard\plain \s239\li960 \f16 ranges 119\par \pard\plain \s240\li480 \f16 round 139\par round/ 140\par row-major-index 114\par sealed 69, 91\par \pard\plain \s239\li960 \f16 class 4, 85, 91\par generic 91, 92, 93\par method 91, 93\par slot 91, 93\par \pard\plain \s240\li480 \f16 second 108\par second-setter 108\par select 30\par semicolon 15\par setter method 67, 70\par setters 9\par shallow-copy 86\par sharp-sign 8\par shorthand syntax\par \pard\plain \s239\li960 \f16 for array reference 16\par for singletons 48, 51, 69\par for slot reference 16\par \pard\plain \s240\li480 \f16 signal 156, 158\par singleton 68, 89\par size 96\par \pard\plain \s239\li960 \f16 arrays 113\par lists 117\par ranges 118\par \pard\plain \s240\li480 \f16 size-setter 101\par slot 67\par slot-initialized? 84\par sort 107\par sort! 108\par sorted-applicable-methods 64\par specializers 5\par stretchy vectors 119\par strings 7\par subclasses 4\par subsequence-position 109\par subtype? 84\par superclasses 4\par \pard \s240\li480 supplied initialization arguments. 78\par \pard \s240\li480 symbols 8, 136\par syntax 7\par syntax form 12\par syntax operators 12\par table-protocol 126, 127\par tables 121\par tail 117\par tail-setter 117\par target value 30\par test-function 126\par third 108\par third-setter 108\par top-level expression 10\par true 8, 27\par truncate 139\par truncate/ 140\par uninstantiable class 4\par union 104\par unless 29\par until 32\par use 165\par values 22\par variable names 7\par variable references 11\par variables 19\par vector 122\par visible modification 125\par while 31\par white space 7\par zero? 138\par [\'c9] 16\par \\\par \pard\plain \s239\li960 \f16 in strings 7\par with infix operators 7, 16, 139\par \pard\plain \s240\li480 \f16 | 31, 144\par \endash 139\par }