on master help sign in
Merge pull request #861 from urbit/lustar-description
50f38a4poprox
reference/hoon-expressions/rune/lus.md+68−19
@@ -135,42 +135,91 @@ Any Hoon expression, `q`, may be used to define the arm computation.
135
135
136### `+*` "lustar"
136### `+*` "lustar"
137
137
138−
138+Defines aliases within doors.
139−Produce a type constructor arm.
140
139
141##### Syntax
140##### Syntax
142
141
143−Regular: **2-fixed**.
142+Regular: **variadic**.
144
143
145```hoon
144```hoon
146−+* p=term [q=term] r=spec
145++* a=term b=hoon
146+ c=term d=hoon
147+ ...
148+ e=term f=hoon
147```
149```
148
150
149−`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 terminator.
154+
155+`+*` arms must always come at the beginning of the battery, before any other
156+type of lus arm.
150
157
151##### Discussion
158##### Discussion
152
159
153−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.
160+The primary use of `+*` is to create aliases within doors (see Examples below).
161+Aliases given by `+*` do not count towards the number of arms in the door and
162+thus are also called "virtual arms", which
163+can be important for things like Gall app cores that require a fixed number of arms.
164+
165+Under the hood, `+*` gets compiled as `=*`'s. `+* foo bar` rewrites each `++`
166+arm beneath it in the core to include
167+`=* foo bar`. For example, the interpreter sees the Nock compiled from this Hoon expression
154
168
155−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).
169+```hoon
170+|_ z=@ud
171++* n 1
172+++ x (add z n)
173+++ y (sub z n)
174+--
175+```
176+as being identical the Nock compiled from this one:
177+```hoon
178+=| z=@ud
179+|%
180+++ x
181+ =* n 1
182+ (add z n)
183+++ y
184+ =* n 1
185+ (sub z n)
186+--
187+```
156
188
157##### Examples
189##### Examples
158
190
191+To assign an alias to a door, we often write the following.
192+```hoon
193+|_ foo
194++* this .
159```
195```
160−> =c |%
196+This is the idomatic way to assign the alias `this` to the door.
161− +* triple [a] [a a a]
162− +* wrap-flag [a] [? a]
163− --
164
197
165−> `(triple.c @)`[12 14 16]
198+Sometimes cores, such as Gall app cores, have a fixed number of arms, but you'd
166−[12 14 16]
199+like to include more. This is where aliases employed as "virtual arms" may be of
200+use. We note that it is often better style to compose cores with `=>` or `=<` to add more arms to a
201+Gall app core. This usage of `+*` is controversial and should be minimized.
167
202
168−> `(triple.c ?)`[12 14 16]
203+```hoon
169−nest-fail
204+|_ =bowl:gall
205++* this .
206+ samp +<
207+ cont +>
208+```
209+This assigns the door the alias `this`, the sample of the door `samp`, and the
210+context of the door `cont`.
170
211
171−> `(triple.c ?)`[& | |]
212+You may also call functions with `+*` by making use of e.g. the `%~` rune.
172−[%.y %.n %.n]
173
213
174−> `(wrap-flag.c @)`[& 22]
214+```hoon
175−[%.y 22]
215+=<
216+ |_ a=@
217+ +* do ~(. +> a)
218+ ++ stuff foo:do
219+::etc
220+--
221+|_ b=@
222+++ foo %bar
223+::etc
224+--
176```
225```