@Section @Tag { visibility } @Title { Nested definitions, body parameters, extend, import, and export } @Begin @PP A definition may contain nested.def @Index { Nested definitions } other definitions at the beginning of its body: @ID @OneRow @Code { "def @NineSquare" " right x" "{" " def @Three { x |0.2i x |0.2i x }" "" " @Three /0.2i @Three /0.2i @Three" "}" } A parameter like @Code x may be invoked anywhere within the body of the symbol it is a parameter of, including within nested definitions. A nested symbol like @Code "@Three" may be invoked anywhere from the beginning of its own body to the end of the body of the symbol it is defined within. So, assuming an appropriate definition of {@Code "@Box"}, @ID @Code { "@NineSquare @Box" } has result @ID @Fig { @NineSquare @Box { 0.2i @Wide 0.2i @High } } Nested definitions may themselves contain nested definitions, to arbitrary depth. @PP There are three special features which permit a nested symbol or parameter to be invoked outside its normal range; that is, outside the body of the enclosing symbol. The first and simplest of these features is the {@I {body parameter}}, parameter.body @SubIndex { @Code body parameter } body.par @Index { @Code body parameter } an alternative form of right parameter. The Eq equation formatting package @Cite { $kingston1995lout.user, Chapter 7 } is a classic example of the use of a body parameter. In outline, it looks like this: @ID @OneRow @Code { "export \"+\" sup over" "" "def @Eq" " body x" "{" " def \"+\" ..." " def sup ..." " def over ..." " ..." "" " Slope @Font x" "}" } First we list those nested symbols and parameters that we intend to refer to outside the body of @Code "@Eq" in an @Code export clause, export @Index { @Code export clause } preceding the definition as shown. Only exported symbols may be invoked outside the body of {@Code "@Eq"}. The body parameter is like a right parameter except that the exported symbols are visible within it: @ID @Code { "@Eq { {x sup 2 + y sup 2} over 2 }" } calls on the nested definitions of @Code "@Eq" to produce the result @ID { @Eq { {x sup 2 + y sup 2} over 2 } } The body parameter's value must be enclosed in braces. The term `body parameter' is a reminder that the value is interpreted as if it was within the body of the symbol. @PP A body parameter may not be exported, and in fact a body parameter may be invoked only within the body of the enclosing symbol, not within any nested definitions. For example, @Code "x" above may not be invoked within {@Code "sup"}. This restriction is needed to avoid the possibility of recursion, when the actual body parameter invokes an exported nested definition which invokes the body parameter, etc. @PP The second place where exported symbols may be used is in the right parameter of the @@Open symbol, and following its alternative form, @@Use (Section {@NumberOf open}). @PP Finally, exported nested symbols and parameters may be made visible within a subsequent definition or macro by preceding it with an @Code import import @Index { @Code import clause } clause, like this: @ID @OneRow @Code { "import @Eq" "def pythag { sqrt { x sup 2 + y sup 2 } }" } Note however that @Code pythag can only be used with some invocation of {@Code "@Eq"}: within the body parameter of an invocation of {@Code "@Eq"}, within the right parameter of an {@Code "@Eq&&tag @Open"}, or following a {@Code "@Use { @Eq ... }"}. There may be several symbols in the @Code import clause. @PP In a similar way to {@Code "import"}, a definition may be preceded by {@Code "extend"} followed by a symbol name: @ID @OneRow @Code { "extend @Eq" "def pythag { sqrt { x sup 2 + y sup 2 } }" } The effect of this is just as though the definition of @Code "pythag" had occurred directly after the existing definitions within {@Code "@Eq"}, with {@Code "pythag"} added to {@Code "@Eq"}'s export list. This is useful for extending the capabilities of a package of definitions like @Code "@Eq" without modifying its source file. The essential differences to @Code "import" are that all the symbols of @Code "@Eq" become visible within {@Code "pythag"}, not just the exported ones, and only one symbol may follow the @Code "extend" keyword. @PP Actually, more than one symbol may follow {@Code extend}, but this usage indicates a `path name' of the symbol. For example, @ID @OneRow @Code { "extend @DocumentLayout @ReportLayout" "def @Keywords ..." } causes the definition of @Code "@Keywords" to occur directly after the existing definitions of {@Code "@ReportLayout"}, which itself lies within {@Code "@DocumentLayout"}. @End @Section