]> git.lizzy.rs Git - rust.git/blob - doc/po/tutorial-macros.md.pot
1b540ea8b1e85eb3ade8fb8df0a02261853f17d0
[rust.git] / doc / po / tutorial-macros.md.pot
1 # SOME DESCRIPTIVE TITLE
2 # Copyright (C) YEAR The Rust Project Developers
3 # This file is distributed under the same license as the Rust package.
4 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5 #
6 #, fuzzy
7 msgid ""
8 msgstr ""
9 "Project-Id-Version: Rust 0.8-pre\n"
10 "POT-Creation-Date: 2013-07-22 23:37+0900\n"
11 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
12 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13 "Language-Team: LANGUAGE <LL@li.org>\n"
14 "Language: \n"
15 "MIME-Version: 1.0\n"
16 "Content-Type: text/plain; charset=UTF-8\n"
17 "Content-Transfer-Encoding: 8bit\n"
18
19 #. type: Plain text
20 #: doc/rust.md:4 doc/rustpkg.md:4 doc/tutorial.md:4
21 #: doc/tutorial-borrowed-ptr.md:4 doc/tutorial-ffi.md:4
22 #: doc/tutorial-macros.md:4 doc/tutorial-tasks.md:4
23 msgid "# Introduction"
24 msgstr ""
25
26 #. type: Plain text
27 #: doc/rust.md:2136 doc/rust.md:2223 doc/tutorial-macros.md:323
28 msgid "~~~~"
29 msgstr ""
30
31 #. type: Plain text
32 #: doc/tutorial-macros.md:2
33 msgid "% Rust Macros Tutorial"
34 msgstr ""
35
36 #. type: Plain text
37 #: doc/tutorial-macros.md:12
38 msgid ""
39 "Functions are the primary tool that programmers can use to build "
40 "abstractions.  Sometimes, however, programmers want to abstract over compile-"
41 "time syntax rather than run-time values.  Macros provide syntactic "
42 "abstraction.  For an example of how this can be useful, consider the "
43 "following two code fragments, which both pattern-match on their input and "
44 "both return early in one case, doing nothing otherwise:"
45 msgstr ""
46
47 #. type: Plain text
48 #: doc/tutorial-macros.md:30
49 #, no-wrap
50 msgid ""
51 "~~~~\n"
52 "# enum t { special_a(uint), special_b(uint) };\n"
53 "# fn f() -> uint {\n"
54 "# let input_1 = special_a(0);\n"
55 "# let input_2 = special_a(0);\n"
56 "match input_1 {\n"
57 "    special_a(x) => { return x; }\n"
58 "    _ => {}\n"
59 "}\n"
60 "// ...\n"
61 "match input_2 {\n"
62 "    special_b(x) => { return x; }\n"
63 "    _ => {}\n"
64 "}\n"
65 "# return 0u;\n"
66 "# }\n"
67 "~~~~\n"
68 msgstr ""
69
70 #. type: Plain text
71 #: doc/tutorial-macros.md:38
72 msgid ""
73 "This code could become tiresome if repeated many times.  However, no "
74 "function can capture its functionality to make it possible to abstract the "
75 "repetition away.  Rust's macro system, however, can eliminate the "
76 "repetition. Macros are lightweight custom syntax extensions, themselves "
77 "defined using the `macro_rules!` syntax extension. The following "
78 "`early_return` macro captures the pattern in the above code:"
79 msgstr ""
80
81 #. type: Plain text
82 #: doc/tutorial-macros.md:59
83 #, no-wrap
84 msgid ""
85 "~~~~\n"
86 "# enum t { special_a(uint), special_b(uint) };\n"
87 "# fn f() -> uint {\n"
88 "# let input_1 = special_a(0);\n"
89 "# let input_2 = special_a(0);\n"
90 "macro_rules! early_return(\n"
91 "    ($inp:expr $sp:ident) => ( // invoke it like `(input_5 special_e)`\n"
92 "        match $inp {\n"
93 "            $sp(x) => { return x; }\n"
94 "            _ => {}\n"
95 "        }\n"
96 "    );\n"
97 ")\n"
98 "// ...\n"
99 "early_return!(input_1 special_a);\n"
100 "// ...\n"
101 "early_return!(input_2 special_b);\n"
102 "# return 0;\n"
103 "# }\n"
104 "~~~~\n"
105 msgstr ""
106
107 #. type: Plain text
108 #: doc/tutorial-macros.md:65
109 msgid ""
110 "Macros are defined in pattern-matching style: in the above example, the text "
111 "`($inp:expr $sp:ident)` that appears on the left-hand side of the `=>` is "
112 "the *macro invocation syntax*, a pattern denoting how to write a call to the "
113 "macro. The text on the right-hand side of the `=>`, beginning with `match "
114 "$inp`, is the *macro transcription syntax*: what the macro expands to."
115 msgstr ""
116
117 #. type: Plain text
118 #: doc/tutorial-macros.md:67
119 msgid "# Invocation syntax"
120 msgstr ""
121
122 #. type: Plain text
123 #: doc/tutorial-macros.md:71
124 msgid ""
125 "The macro invocation syntax specifies the syntax for the arguments to the "
126 "macro. It appears on the left-hand side of the `=>` in a macro definition. "
127 "It conforms to the following rules:"
128 msgstr ""
129
130 #. type: Bullet: '1. '
131 #: doc/tutorial-macros.md:76
132 msgid "It must be surrounded by parentheses."
133 msgstr ""
134
135 #. type: Bullet: '2. '
136 #: doc/tutorial-macros.md:76
137 msgid "`$` has special meaning (described below)."
138 msgstr ""
139
140 #. type: Plain text
141 #: doc/tutorial-macros.md:76
142 #, no-wrap
143 msgid ""
144 "3. The `()`s, `[]`s, and `{}`s it contains must balance. For example, `([)` is\n"
145 "forbidden.\n"
146 msgstr ""
147
148 #. type: Plain text
149 #: doc/tutorial-macros.md:78
150 msgid "Otherwise, the invocation syntax is free-form."
151 msgstr ""
152
153 #. type: Plain text
154 #: doc/tutorial-macros.md:83
155 #, no-wrap
156 msgid ""
157 "To take as an argument a fragment of Rust code, write `$` followed by a name\n"
158 " (for use on the right-hand side), followed by a `:`, followed by a *fragment\n"
159 " specifier*. The fragment specifier denotes the sort of fragment to match. The\n"
160 " most common fragment specifiers are:\n"
161 msgstr ""
162
163 #. type: Bullet: '* '
164 #: doc/tutorial-macros.md:92
165 msgid ""
166 "`ident` (an identifier, referring to a variable or item. Examples: `f`, `x`, "
167 "`foo`.)"
168 msgstr ""
169
170 #. type: Bullet: '* '
171 #: doc/tutorial-macros.md:92
172 msgid ""
173 "`expr` (an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`; "
174 "`f(42)`.)"
175 msgstr ""
176
177 #. type: Bullet: '* '
178 #: doc/tutorial-macros.md:92
179 msgid "`ty` (a type. Examples: `int`, `~[(char, ~str)]`, `&T`.)"
180 msgstr ""
181
182 #. type: Bullet: '* '
183 #: doc/tutorial-macros.md:92
184 msgid ""
185 "`pat` (a pattern, usually appearing in a `match` or on the left-hand side of "
186 "a declaration. Examples: `Some(t)`; `(17, 'a')`; `_`.)"
187 msgstr ""
188
189 #. type: Bullet: '* '
190 #: doc/tutorial-macros.md:92
191 msgid ""
192 "`block` (a sequence of actions. Example: `{ log(error, \"hi\"); return 12; }"
193 "`)"
194 msgstr ""
195
196 #. type: Plain text
197 #: doc/tutorial-macros.md:95
198 msgid ""
199 "The parser interprets any token that's not preceded by a `$` literally. "
200 "Rust's usual rules of tokenization apply,"
201 msgstr ""
202
203 #. type: Plain text
204 #: doc/tutorial-macros.md:98
205 msgid ""
206 "So `($x:ident -> (($e:expr)))`, though excessively fancy, would designate a "
207 "macro that could be invoked like: `my_macro!(i->(( 2+2 )))`."
208 msgstr ""
209
210 #. type: Plain text
211 #: doc/tutorial-macros.md:100
212 msgid "## Invocation location"
213 msgstr ""
214
215 #. type: Plain text
216 #: doc/tutorial-macros.md:105
217 msgid ""
218 "A macro invocation may take the place of (and therefore expand to)  an "
219 "expression, an item, or a statement.  The Rust parser will parse the macro "
220 "invocation as a \"placeholder\" for whichever of those three nonterminals is "
221 "appropriate for the location."
222 msgstr ""
223
224 #. type: Plain text
225 #: doc/tutorial-macros.md:112
226 msgid ""
227 "At expansion time, the output of the macro will be parsed as whichever of "
228 "the three nonterminals it stands in for. This means that a single macro "
229 "might, for example, expand to an item or an expression, depending on its "
230 "arguments (and cause a syntax error if it is called with the wrong argument "
231 "for its location). Although this behavior sounds excessively dynamic, it is "
232 "known to be useful under some circumstances."
233 msgstr ""
234
235 #. type: Plain text
236 #: doc/tutorial-macros.md:115
237 msgid "# Transcription syntax"
238 msgstr ""
239
240 #. type: Plain text
241 #: doc/tutorial-macros.md:119
242 msgid ""
243 "The right-hand side of the `=>` follows the same rules as the left-hand "
244 "side, except that a `$` need only be followed by the name of the syntactic "
245 "fragment to transcribe into the macro expansion; its type need not be "
246 "repeated."
247 msgstr ""
248
249 #. type: Plain text
250 #: doc/tutorial-macros.md:126
251 msgid ""
252 "The right-hand side must be enclosed by delimiters, which the transcriber "
253 "ignores.  Therefore `() => ((1,2,3))` is a macro that expands to a tuple "
254 "expression, `() => (let $x=$val)` is a macro that expands to a statement, "
255 "and `() => (1,2,3)` is a macro that expands to a syntax error (since the "
256 "transcriber interprets the parentheses on the right-hand-size as delimiters, "
257 "and `1,2,3` is not a valid Rust expression on its own)."
258 msgstr ""
259
260 #. type: Plain text
261 #: doc/tutorial-macros.md:133
262 msgid ""
263 "Except for permissibility of `$name` (and `$(...)*`, discussed below), the "
264 "right-hand side of a macro definition is ordinary Rust syntax. In "
265 "particular, macro invocations (including invocations of the macro currently "
266 "being defined)  are permitted in expression, statement, and item locations. "
267 "However, nothing else about the code is examined or executed by the macro "
268 "system; execution still has to wait until run-time."
269 msgstr ""
270
271 #. type: Plain text
272 #: doc/tutorial-macros.md:135
273 msgid "## Interpolation location"
274 msgstr ""
275
276 #. type: Plain text
277 #: doc/tutorial-macros.md:139
278 msgid ""
279 "The interpolation `$argument_name` may appear in any location consistent "
280 "with its fragment specifier (i.e., if it is specified as `ident`, it may be "
281 "used anywhere an identifier is permitted)."
282 msgstr ""
283
284 #. type: Plain text
285 #: doc/tutorial-macros.md:141
286 msgid "# Multiplicity"
287 msgstr ""
288
289 #. type: Plain text
290 #: doc/tutorial-macros.md:143
291 msgid "## Invocation"
292 msgstr ""
293
294 #. type: Plain text
295 #: doc/tutorial-macros.md:150
296 msgid ""
297 "Going back to the motivating example, recall that `early_return` expanded "
298 "into a `match` that would `return` if the `match`'s scrutinee matched the "
299 "\"special case\" identifier provided as the second argument to "
300 "`early_return`, and do nothing otherwise. Now suppose that we wanted to "
301 "write a version of `early_return` that could handle a variable number of "
302 "\"special\" cases."
303 msgstr ""
304
305 #. type: Plain text
306 #: doc/tutorial-macros.md:156
307 msgid ""
308 "The syntax `$(...)*` on the left-hand side of the `=>` in a macro definition "
309 "accepts zero or more occurrences of its contents. It works much like the `*` "
310 "operator in regular expressions. It also supports a separator token (a comma-"
311 "separated list could be written `$(...),*`), and `+` instead of `*` to mean "
312 "\"at least one\"."
313 msgstr ""
314
315 #. type: Plain text
316 #: doc/tutorial-macros.md:179
317 #, no-wrap
318 msgid ""
319 "~~~~\n"
320 "# enum t { special_a(uint),special_b(uint),special_c(uint),special_d(uint)};\n"
321 "# fn f() -> uint {\n"
322 "# let input_1 = special_a(0);\n"
323 "# let input_2 = special_a(0);\n"
324 "macro_rules! early_return(\n"
325 "    ($inp:expr, [ $($sp:ident)|+ ]) => (\n"
326 "        match $inp {\n"
327 "            $(\n"
328 "                $sp(x) => { return x; }\n"
329 "            )+\n"
330 "            _ => {}\n"
331 "        }\n"
332 "    );\n"
333 ")\n"
334 "// ...\n"
335 "early_return!(input_1, [special_a|special_c|special_d]);\n"
336 "// ...\n"
337 "early_return!(input_2, [special_b]);\n"
338 "# return 0;\n"
339 "# }\n"
340 "~~~~\n"
341 msgstr ""
342
343 #. type: Plain text
344 #: doc/tutorial-macros.md:181
345 msgid "### Transcription"
346 msgstr ""
347
348 #. type: Plain text
349 #: doc/tutorial-macros.md:191
350 msgid ""
351 "As the above example demonstrates, `$(...)*` is also valid on the right-hand "
352 "side of a macro definition. The behavior of `*` in transcription, especially "
353 "in cases where multiple `*`s are nested, and multiple different names are "
354 "involved, can seem somewhat magical and intuitive at first. The system that "
355 "interprets them is called \"Macro By Example\". The two rules to keep in "
356 "mind are (1) the behavior of `$(...)*` is to walk through one \"layer\" of "
357 "repetitions for all of the `$name`s it contains in lockstep, and (2) each `"
358 "$name` must be under at least as many `$(...)*`s as it was matched against.  "
359 "If it is under more, it'll be repeated, as appropriate."
360 msgstr ""
361
362 #. type: Plain text
363 #: doc/tutorial-macros.md:193
364 msgid "## Parsing limitations"
365 msgstr ""
366
367 #. type: Plain text
368 #: doc/tutorial-macros.md:197
369 msgid ""
370 "For technical reasons, there are two limitations to the treatment of syntax "
371 "fragments by the macro parser:"
372 msgstr ""
373
374 #. type: Plain text
375 #: doc/tutorial-macros.md:210
376 #, no-wrap
377 msgid ""
378 "1. The parser will always parse as much as possible of a Rust syntactic\n"
379 "fragment. For example, if the comma were omitted from the syntax of\n"
380 "`early_return!` above, `input_1 [` would've been interpreted as the beginning\n"
381 "of an array index. In fact, invoking the macro would have been impossible.\n"
382 "2. The parser must have eliminated all ambiguity by the time it reaches a\n"
383 "`$name:fragment_specifier` declaration. This limitation can result in parse\n"
384 "errors when declarations occur at the beginning of, or immediately after,\n"
385 "a `$(...)*`. For example, the grammar `$($t:ty)* $e:expr` will always fail to\n"
386 "parse because the parser would be forced to choose between parsing `t` and\n"
387 "parsing `e`. Changing the invocation syntax to require a distinctive token in\n"
388 "front can solve the problem. In the above example, `$(T $t:ty)* E $e:exp`\n"
389 "solves the problem.\n"
390 msgstr ""
391
392 #. type: Plain text
393 #: doc/tutorial-macros.md:212
394 msgid "# Macro argument pattern matching"
395 msgstr ""
396
397 #. type: Plain text
398 #: doc/tutorial-macros.md:214
399 msgid "Now consider code like the following:"
400 msgstr ""
401
402 #. type: Plain text
403 #: doc/tutorial-macros.md:216
404 msgid "## Motivation"
405 msgstr ""
406
407 #. type: Plain text
408 #: doc/tutorial-macros.md:236
409 #, no-wrap
410 msgid ""
411 "~~~~\n"
412 "# enum t1 { good_1(t2, uint), bad_1 };\n"
413 "# pub struct t2 { body: t3 }\n"
414 "# enum t3 { good_2(uint), bad_2};\n"
415 "# fn f(x: t1) -> uint {\n"
416 "match x {\n"
417 "    good_1(g1, val) => {\n"
418 "        match g1.body {\n"
419 "            good_2(result) => {\n"
420 "                // complicated stuff goes here\n"
421 "                return result + val;\n"
422 "            },\n"
423 "            _ => fail!(\"Didn't get good_2\")\n"
424 "        }\n"
425 "    }\n"
426 "    _ => return 0 // default value\n"
427 "}\n"
428 "# }\n"
429 "~~~~\n"
430 msgstr ""
431
432 #. type: Plain text
433 #: doc/tutorial-macros.md:241
434 msgid ""
435 "All the complicated stuff is deeply indented, and the error-handling code is "
436 "separated from matches that fail. We'd like to write a macro that performs a "
437 "match, but with a syntax that suits the problem better. The following macro "
438 "can solve the problem:"
439 msgstr ""
440
441 #. type: Plain text
442 #: doc/tutorial-macros.md:263
443 #, no-wrap
444 msgid ""
445 "~~~~\n"
446 "macro_rules! biased_match (\n"
447 "    // special case: `let (x) = ...` is illegal, so use `let x = ...` instead\n"
448 "    ( ($e:expr) ~ ($p:pat) else $err:stmt ;\n"
449 "      binds $bind_res:ident\n"
450 "    ) => (\n"
451 "        let $bind_res = match $e {\n"
452 "            $p => ( $bind_res ),\n"
453 "            _ => { $err }\n"
454 "        };\n"
455 "    );\n"
456 "    // more than one name; use a tuple\n"
457 "    ( ($e:expr) ~ ($p:pat) else $err:stmt ;\n"
458 "      binds $( $bind_res:ident ),*\n"
459 "    ) => (\n"
460 "        let ( $( $bind_res ),* ) = match $e {\n"
461 "            $p => ( $( $bind_res ),* ),\n"
462 "            _ => { $err }\n"
463 "        };\n"
464 "    )\n"
465 ")\n"
466 msgstr ""
467
468 #. type: Plain text
469 #: doc/tutorial-macros.md:277
470 #, no-wrap
471 msgid ""
472 "# enum t1 { good_1(t2, uint), bad_1 };\n"
473 "# pub struct t2 { body: t3 }\n"
474 "# enum t3 { good_2(uint), bad_2};\n"
475 "# fn f(x: t1) -> uint {\n"
476 "biased_match!((x)       ~ (good_1(g1, val)) else { return 0 };\n"
477 "              binds g1, val )\n"
478 "biased_match!((g1.body) ~ (good_2(result) )\n"
479 "                  else { fail!(\"Didn't get good_2\") };\n"
480 "              binds result )\n"
481 "// complicated stuff goes here\n"
482 "return result + val;\n"
483 "# }\n"
484 "~~~~\n"
485 msgstr ""
486
487 #. type: Plain text
488 #: doc/tutorial-macros.md:288
489 #, no-wrap
490 msgid ""
491 "This solves the indentation problem. But if we have a lot of chained matches\n"
492 "like this, we might prefer to write a single macro invocation. The input\n"
493 "pattern we want is clear:\n"
494 "~~~~\n"
495 "# macro_rules! b(\n"
496 "    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*\n"
497 "      binds $( $bind_res:ident ),*\n"
498 "    )\n"
499 "# => (0))\n"
500 "~~~~\n"
501 msgstr ""
502
503 #. type: Plain text
504 #: doc/tutorial-macros.md:291
505 msgid ""
506 "However, it's not possible to directly expand to nested match statements. "
507 "But there is a solution."
508 msgstr ""
509
510 #. type: Plain text
511 #: doc/tutorial-macros.md:293
512 msgid "## The recursive approach to macro writing"
513 msgstr ""
514
515 #. type: Plain text
516 #: doc/tutorial-macros.md:297
517 msgid ""
518 "A macro may accept multiple different input grammars. The first one to "
519 "successfully match the actual argument to a macro invocation is the one that "
520 "\"wins\"."
521 msgstr ""
522
523 #. type: Plain text
524 #: doc/tutorial-macros.md:301
525 msgid ""
526 "In the case of the example above, we want to write a recursive macro to "
527 "process the semicolon-terminated lines, one-by-one. So, we want the "
528 "following input patterns:"
529 msgstr ""
530
531 #. type: Plain text
532 #: doc/tutorial-macros.md:308
533 #, no-wrap
534 msgid ""
535 "~~~~\n"
536 "# macro_rules! b(\n"
537 "    ( binds $( $bind_res:ident ),* )\n"
538 "# => (0))\n"
539 "~~~~\n"
540 "...and:\n"
541 msgstr ""
542
543 #. type: Plain text
544 #: doc/tutorial-macros.md:317
545 #, no-wrap
546 msgid ""
547 "~~~~\n"
548 "# macro_rules! b(\n"
549 "    (    ($e     :expr) ~ ($p     :pat) else $err     :stmt ;\n"
550 "      $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*\n"
551 "      binds  $( $bind_res:ident ),*\n"
552 "    )\n"
553 "# => (0))\n"
554 "~~~~\n"
555 msgstr ""
556
557 #. type: Plain text
558 #: doc/tutorial-macros.md:321
559 msgid ""
560 "The resulting macro looks like this. Note that the separation into "
561 "`biased_match!` and `biased_match_rec!` occurs only because we have an outer "
562 "piece of syntax (the `let`) which we only want to transcribe once."
563 msgstr ""
564
565 #. type: Plain text
566 #: doc/tutorial-macros.md:342
567 #, no-wrap
568 msgid ""
569 "macro_rules! biased_match_rec (\n"
570 "    // Handle the first layer\n"
571 "    (   ($e     :expr) ~ ($p     :pat) else $err     :stmt ;\n"
572 "     $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*\n"
573 "     binds $( $bind_res:ident ),*\n"
574 "    ) => (\n"
575 "        match $e {\n"
576 "            $p => {\n"
577 "                // Recursively handle the next layer\n"
578 "                biased_match_rec!($( ($e_rest) ~ ($p_rest) else $err_rest ; )*\n"
579 "                                  binds $( $bind_res ),*\n"
580 "                )\n"
581 "            }\n"
582 "            _ => { $err }\n"
583 "        }\n"
584 "    );\n"
585 "    ( binds $( $bind_res:ident ),* ) => ( ($( $bind_res ),*) )\n"
586 ")\n"
587 msgstr ""
588
589 #. type: Plain text
590 #: doc/tutorial-macros.md:364
591 #, no-wrap
592 msgid ""
593 "// Wrap the whole thing in a `let`.\n"
594 "macro_rules! biased_match (\n"
595 "    // special case: `let (x) = ...` is illegal, so use `let x = ...` instead\n"
596 "    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*\n"
597 "      binds $bind_res:ident\n"
598 "    ) => (\n"
599 "        let ( $( $bind_res ),* ) = biased_match_rec!(\n"
600 "            $( ($e) ~ ($p) else $err ; )*\n"
601 "            binds $bind_res\n"
602 "        );\n"
603 "    );\n"
604 "    // more than one name: use a tuple\n"
605 "    ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*\n"
606 "      binds  $( $bind_res:ident ),*\n"
607 "    ) => (\n"
608 "        let ( $( $bind_res ),* ) = biased_match_rec!(\n"
609 "            $( ($e) ~ ($p) else $err ; )*\n"
610 "            binds $( $bind_res ),*\n"
611 "        );\n"
612 "    )\n"
613 ")\n"
614 msgstr ""
615
616 #. type: Plain text
617 #: doc/tutorial-macros.md:378
618 #, no-wrap
619 msgid ""
620 "# enum t1 { good_1(t2, uint), bad_1 };\n"
621 "# pub struct t2 { body: t3 }\n"
622 "# enum t3 { good_2(uint), bad_2};\n"
623 "# fn f(x: t1) -> uint {\n"
624 "biased_match!(\n"
625 "    (x)       ~ (good_1(g1, val)) else { return 0 };\n"
626 "    (g1.body) ~ (good_2(result) ) else { fail!(\"Didn't get good_2\") };\n"
627 "    binds val, result )\n"
628 "// complicated stuff goes here\n"
629 "return result + val;\n"
630 "# }\n"
631 "~~~~\n"
632 msgstr ""
633
634 #. type: Plain text
635 #: doc/tutorial-macros.md:382
636 msgid ""
637 "This technique applies to many cases where transcribing a result all at once "
638 "is not possible.  The resulting code resembles ordinary functional "
639 "programming in some respects, but has some important differences from "
640 "functional programming."
641 msgstr ""
642
643 #. type: Plain text
644 #: doc/tutorial-macros.md:390
645 msgid ""
646 "The first difference is important, but also easy to forget: the "
647 "transcription (right-hand) side of a `macro_rules!` rule is literal syntax, "
648 "which can only be executed at run-time. If a piece of transcription syntax "
649 "does not itself appear inside another macro invocation, it will become part "
650 "of the final program. If it is inside a macro invocation (for example, the "
651 "recursive invocation of `biased_match_rec!`), it does have the opportunity "
652 "to affect transcription, but only through the process of attempted pattern "
653 "matching."
654 msgstr ""
655
656 #. type: Plain text
657 #: doc/tutorial-macros.md:398
658 msgid ""
659 "The second, related, difference is that the evaluation order of macros feels "
660 "\"backwards\" compared to ordinary programming. Given an invocation `m1!(m2!"
661 "())`, the expander first expands `m1!`, giving it as input the literal "
662 "syntax `m2!()`. If it transcribes its argument unchanged into an appropriate "
663 "position (in particular, not as an argument to yet another macro "
664 "invocation), the expander will then proceed to evaluate `m2!()` (along with "
665 "any other macro invocations `m1!(m2!())` produced)."
666 msgstr ""
667
668 #. type: Plain text
669 #: doc/tutorial-macros.md:400
670 msgid "# A final note"
671 msgstr ""
672
673 #. type: Plain text
674 #: doc/tutorial-macros.md:407
675 msgid ""
676 "Macros, as currently implemented, are not for the faint of heart. Even "
677 "ordinary syntax errors can be more difficult to debug when they occur inside "
678 "a macro, and errors caused by parse problems in generated code can be very "
679 "tricky. Invoking the `log_syntax!` macro can help elucidate intermediate "
680 "states, invoking `trace_macros!(true)` will automatically print those "
681 "intermediate states out, and passing the flag `--pretty expanded` as a "
682 "command-line argument to the compiler will show the result of expansion."
683 msgstr ""