on master help sign in
rest of content
e644eeesyzygyzer
reference/hoon-expressions/rune/lus.md+48−18
@@ -135,41 +135,71 @@ Any Hoon expression, `q`, may be used to define the arm computation.
135
135
136### +* "lustar"
136### +* "lustar"
137
137
138−Used to assign an alias to doors `|_`.
138+Used to assign an alias to doors and define virtual arms.
139
139
140##### Syntax
140##### Syntax
141
141
142−Regular: **2-fixed**.
142+Regular: **variadic**.
143
143
144```hoon
144```hoon
145−+* p=term [q=term] r=spec
145++* a=term b=hoon
146+ c=term d=hoon
147+ ...
148+ e=term f=hoon
146```
149```
147
150
148−`p` is the arm name, `q` is the name of the argument for the constructor function enclosed in square brackets, and `r` is a structure expression that defines the constructor function.
151+`a`, `c`, `e` are arm names and `b`, `d`, `f` are any Hoon expression. Note that unlike all other
152+runes with a variable number of arguments, the list of arguments of `+*` does
153+not end with a terminating rune.
149
154
150##### Discussion
155##### Discussion
151
156
152−Arms produced by `+*` are essentially type constructors. They are used to construct new types from ones you already have. Consider `list`, which takes some type -- e.g., `@`, `tape`, etc. -- and returns a new type, e.g., `(list @)`, `(list tape)`, etc.
157+The primary use of `+*` is to assign aliases to doors (see Examples below).
158+However, they may also be used to define "virtual arms" which behave just like
159+ordinary arms except they allow nesting within cores that requires a specific
160+number of arms, such as Gall apps. Put another way, no matter how many virtual
161+arms are defined in a `+*` statement, the interpreter will see it as only being
162+a single arm for the purposes of nesting.
153
163
154−The Hoon subexpression, `r`, must be a structure expression. That is, it must be either a basic structure expression (`*`, `~`, `^`, `?`, and `@`), or a complex expression made with the `$` family of runes (including irregular variants).
164+Under the hood, `+*` gets compiled to `=*`.
155
165
156##### Examples
166##### Examples
157
167
168+To assign an alias to a door, we often write the following.
169+```hoon
170+|_ foo
171++* this .
158```
172```
159−> =c |%
173+This is the idomatic way to assign the alias `this` to the door.
160− +* triple [a] [a a a]
161− +* wrap-flag [a] [? a]
162− --
163
174
164−> `(triple.c @)`[12 14 16]
175+Gall apps have a fixed number of arms, but sometimes you'd like to have more.
165−[12 14 16]
176+This is where virtual arms come in.
166
177
167−> `(triple.c ?)`[12 14 16]
178+```hoon
168−nest-fail
179+|_ =bowl:gall
180++* this .
181+ samp +<
182+ cont +>
183+```
184+This assigns the door the alias `this`, the sample of the door `samp`, and the
185+context of the door `cont`.
169
186
170−> `(triple.c ?)`[& | |]
187+Using more than two arguments for `+*` is unnecessary if you do not care about
171−[%.y %.n %.n]
188+how many arms your core has. The above snippet has the same behavior as the
189+following one does, except it has more arms:
172
190
173−> `(wrap-flag.c @)`[& 22]
191+```hoon
174−[%.y 22]
192+|_ foo
193++* this .
194++* samp +<
195++* cont +>
196+```
197+
198+You are not restricted to lark expressions. Functions may be defined as well.
199+Another common snipper seen in Gall apps is the following.
200+
201+```hoon
202+|_ =bowl:gall
203++* this .
204+ def ~(. (default-agent this %|) bowl)
175```
205```