File: usermanual_9.html

package info (click to toggle)
ucblogo 6.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 7,636 kB
  • sloc: ansic: 16,989; cpp: 3,818; makefile: 186; perl: 3
file content (365 lines) | stat: -rw-r--r-- 17,787 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd">
<html>
<!-- Created on September, 3 2008 by texi2html 1.78 -->
<!--
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
            Karl Berry  <karl@freefriends.org>
            Olaf Bachmann <obachman@mathematik.uni-kl.de>
            and many others.
Maintained by: Many creative people.
Send bugs and suggestions to <texi2html-bug@nongnu.org>

-->
<head>
<title>BERKELEY LOGO 6.0: 9. Macros</title>

<meta name="description" content="BERKELEY LOGO 6.0: 9. Macros">
<meta name="keywords" content="BERKELEY LOGO 6.0: 9. Macros">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="texi2html 1.78">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
<!--
a.summary-letter {text-decoration: none}
pre.display {font-family: serif}
pre.format {font-family: serif}
pre.menu-comment {font-family: serif}
pre.menu-preformatted {font-family: serif}
pre.smalldisplay {font-family: serif; font-size: smaller}
pre.smallexample {font-size: smaller}
pre.smallformat {font-family: serif; font-size: smaller}
pre.smalllisp {font-size: smaller}
span.roman {font-family:serif; font-weight:normal;}
span.sansserif {font-family:sans-serif; font-weight:normal;}
ul.toc {list-style: none}
-->
</style>


</head>

<body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000">

<a name="MACROS"></a>
<a name="SEC366"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="usermanual_8.html#SEC365" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC367" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="usermanual_8.html#SEC320" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="usermanual.html#Top" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="usermanual_10.html#SEC371" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="usermanual.html#Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_13.html#SEC391" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h1 class="chapter"> 9. Macros </h1>

<table class="menu" border="0" cellspacing="0">
<tr><td align="left" valign="top"><a href="#SEC367">.macro</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC368">.defmacro</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC369">macrop</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                      
</td></tr>
<tr><td align="left" valign="top"><a href="#SEC370">macroexpand</a></td><td>&nbsp;&nbsp;</td><td align="left" valign="top">                 
</td></tr>
</table>

<hr size="6">
<a name="dMACRO"></a>
<a name="SEC367"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC366" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC368" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC366" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC366" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="usermanual_10.html#SEC371" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="usermanual.html#Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_13.html#SEC391" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h3 class="unnumberedsubsec"> .macro </h3>

<table><tr><td>&nbsp;</td><td><pre class="example">.MACRO procname :input1 :input2 ...			(special form)
.DEFMACRO procname text
</pre></td></tr></table>

<p>A macro is a special kind of procedure whose output is evaluated as Logo
instructions in the context of the macro's caller.  <code>.MACRO</code> is exactly
like <code>TO</code> except that the new procedure becomes a macro; <code>.DEFMACRO</code>
is exactly like <code>DEFINE</code> with the same exception.
</p>
<p>Macros are useful for inventing new control structures comparable to
<code>REPEAT</code>, <code>IF</code>, and so on.  Such control structures can almost, but
not quite, be duplicated by ordinary Logo procedures.  For example, here is an
ordinary procedure version of <code>REPEAT</code>:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">to my.repeat :num :instructions
if :num=0 [stop]
run :instructions
my.repeat :num-1 :instructions
end
</pre></td></tr></table>

<p>This version works fine for most purposes, e.g.,
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">my.repeat 5 [print &quot;hello]
</pre></td></tr></table>

<p>But it doesn't work if the instructions to be carried out include
<code>OUTPUT</code>, <code>STOP</code>, or <code>LOCAL</code>.  For example, consider this
procedure:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">to example
print [Guess my secret word.  You get three guesses.]
repeat 3 [type &quot;|?? | ~
          if readword = &quot;secret [pr &quot;Right! stop]]
print [Sorry, the word was &quot;secret&quot;!]
end
</pre></td></tr></table>

<p>This procedure works as written, but if <code>MY.REPEAT</code> is used instead of
<code>REPEAT</code>, it won't work because the <code>STOP</code> will stop
<code>MY.REPEAT</code> instead of stopping <code>EXAMPLE</code> as desired.
</p>
<p>The solution is to make <code>MY.REPEAT</code> a macro.  Instead of actually carrying
out the computation, a macro must return a list containing Logo
instructions.  The contents of that list are evaluated as if they
appeared in place of the call to the macro.  Here's a macro version of
<code>REPEAT</code>:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">.macro my.repeat :num :instructions
if :num=0 [output []]
output sentence :instructions ~
                (list &quot;my.repeat :num-1 :instructions)
end
</pre></td></tr></table>

<p>Every macro is an operation &mdash; it must always output something.  Even in
the base case, <code>MY.REPEAT</code> outputs an empty instruction list.  To show how
<code>MY.REPEAT</code> works, let's take the example
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">my.repeat 5 [print &quot;hello]
</pre></td></tr></table>

<p>For this example, <code>MY.REPEAT</code> will output the instruction list
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">[print &quot;hello my.repeat 4 [print &quot;hello]]
</pre></td></tr></table>

<p>Logo then executes these instructions in place of the original invocation of
<code>MY.REPEAT</code>; this prints <code>hello</code> once and invokes another
repetition.
</p>
<p>The technique just shown, although fairly easy to understand, has the
defect of slowness because each repetition has to construct an
instruction list for evaluation.  Another approach is to make <code>MY.REPEAT</code>
a macro that works just like the non-macro version unless the
instructions to be repeated include <code>OUTPUT</code> or <code>STOP</code>:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">.macro my.repeat :num :instructions
catch &quot;repeat.catchtag ~
      [op repeat.done runresult [repeat1 :num :instructions]]
op []
end

to repeat1 :num :instructions
if :num=0 [throw &quot;repeat.catchtag]
run :instructions
.maybeoutput repeat1 :num-1 :instructions
end

to repeat.done :repeat.result
if emptyp :repeat.result [op [stop]]
op list &quot;output quoted first :repeat.result
end
</pre></td></tr></table>

<p>If the instructions do not include <code>STOP</code> or <code>OUTPUT</code>, then
<code>REPEAT1</code> will reach its base case and invoke <code>THROW</code>.  As a result,
<code>MY.REPEAT</code>'s last instruction line will output an empty list, so the
evaluation of the macro result by the caller will do nothing.  But if a
<code>STOP</code> or <code>OUTPUT</code> happens, then <code>REPEAT.DONE</code> will output a
<code>STOP</code> or <code>OUTPUT</code> instruction that will be executed in the
caller's context.
</p>
<p>The macro-defining commands have names starting with a dot because
macros are an advanced feature of Logo; it's easy to get in trouble by
defining a macro that doesn't terminate, or by failing to construct the
instruction list properly.
</p>
<p>Lisp users should note that Logo macros are <em>not</em> special forms.  That is,
the inputs to the macro are evaluated normally, as they would be for any
other Logo procedure.  It's only the output from the macro that's
handled unusually.
</p>
<p>Here's another example:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">.macro localmake :name :value
output (list &quot;local          ~
             word &quot;&quot; :name   ~
             &quot;apply          ~
             &quot;&quot;make          ~
             (list :name :value))
end
</pre></td></tr></table>

<p>It's used this way:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">to try
localmake &quot;garply &quot;hello
print :garply
end
</pre></td></tr></table>

<p><code>LOCALMAKE</code> outputs the list
</p>
<table><tr><td>&nbsp;</td><td><pre class="display">[local &quot;garply apply &quot;make [garply hello]]
</pre></td></tr></table>

<p>The reason for the use of <code>APPLY</code> is to avoid having to decide whether or
not the second input to <code>MAKE</code> requires a quotation mark before it.  (In
this case it would &mdash; <code>MAKE &quot;GARPLY &quot;HELLO</code> &mdash; but the quotation mark
would be wrong if the value were a list.)
</p>
<p>It's often convenient to use the <tt>`</tt> function to construct the instruction
list:
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">.macro localmake :name :value
op `[local ,[word &quot;&quot; :name] apply &quot;make [,[:name] ,[:value]]]
end
</pre></td></tr></table>

<p>On the other hand, <tt>`</tt> is pretty slow, since it's tree recursive and
written in Logo.
</p>
<p>See section <a href="usermanual_7.html#SEC233">to</a> ,
<a href="usermanual_7.html#SEC234">define</a> ,
<a href="usermanual_8.html#SEC354">apply</a> ,
<a href="usermanual_8.html#SEC332">stop</a> ,
<a href="usermanual_8.html#SEC333">output</a> .
</p>
<hr size="6">
<a name="dDEFMACRO"></a>
<a name="SEC368"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC367" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC369" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC366" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC366" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="usermanual_10.html#SEC371" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="usermanual.html#Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_13.html#SEC391" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h3 class="unnumberedsubsec"> .defmacro </h3>

<p>See section <a href="#SEC367">.macro</a> .
</p>
<hr size="6">
<a name="MACROP"></a>
<a name="SEC369"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC368" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC370" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC366" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC366" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="usermanual_10.html#SEC371" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="usermanual.html#Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_13.html#SEC391" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h3 class="unnumberedsubsec"> macrop </h3>

<table><tr><td>&nbsp;</td><td><pre class="example">MACROP name
MACRO? name
</pre></td></tr></table>

<p>outputs <code>TRUE</code> if its input is the name of a macro.
</p>
<hr size="6">
<a name="MACROEXPAND"></a>
<a name="SEC370"></a>
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC369" title="Previous section in reading order"> &lt; </a>]</td>
<td valign="middle" align="left">[<a href="usermanual_10.html#SEC371" title="Next section in reading order"> &gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="#SEC366" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="#SEC366" title="Up section"> Up </a>]</td>
<td valign="middle" align="left">[<a href="usermanual_10.html#SEC371" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="usermanual.html#Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_13.html#SEC391" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<h3 class="unnumberedsubsec"> macroexpand </h3>

<table><tr><td>&nbsp;</td><td><pre class="example">MACROEXPAND expr				(library procedure)
</pre></td></tr></table>

<p>takes as its input a Logo expression that invokes a macro (that is, one
that begins with the name of a macro) and outputs the the Logo
expression into which the macro would translate the input expression.
</p>
<table><tr><td>&nbsp;</td><td><pre class="example">.macro localmake :name :value
op `[local ,[word &quot;&quot; :name] apply &quot;make [,[:name] ,[:value]]]
end

? show macroexpand [localmake &quot;pi 3.14159]
[local &quot;pi apply &quot;make [pi 3.14159]]
</pre></td></tr></table>



<hr size="6">
<table cellpadding="1" cellspacing="1" border="0">
<tr><td valign="middle" align="left">[<a href="#SEC366" title="Beginning of this chapter or previous chapter"> &lt;&lt; </a>]</td>
<td valign="middle" align="left">[<a href="usermanual_10.html#SEC371" title="Next chapter"> &gt;&gt; </a>]</td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left"> &nbsp; </td>
<td valign="middle" align="left">[<a href="usermanual.html#Top" title="Cover (top) of document">Top</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_13.html#SEC391" title="Index">Index</a>]</td>
<td valign="middle" align="left">[<a href="usermanual_abt.html#SEC_About" title="About (help)"> ? </a>]</td>
</tr></table>
<p>
 <font size="-1">
  This document was generated by <em>Brian Harvey</em> on <em>September, 3 2008</em> using <a href="http://www.nongnu.org/texi2html/"><em>texi2html 1.78</em></a>.
 </font>
 <br>

</p>
</body>
</html>