on master help sign in
Number of type fixes for generators.udon
commit3d1a9e3ae712cb1a08799b58e6106c099a567179 authorDavid Kerschner <dkerschner@hcoop.net> dateTue 15 Jan 2019, 15:51 (8 years ago) parent7f51336
1 file changed+55−56
learn/arvo/arvo-internals/generators.udon+55−56
learn/arvo/arvo-internals/generators.udon+55−56
@@ -10,17 +10,17 @@
1010Generators are the most straightforward way to write programs for Urbit. They
1111are used for doing computations that do not require persistence: they take an
1212input and produce an output, then disappear. Generators might make sense for
13−for listing directory contents, or running unit tests, or fetching the
14−contents of a URL.
13+listing directory contents, or running unit tests, or fetching the contents of a
14+URL.
1515
1616There are four kinds of generators: naked, `%say`, `%get`, and `%ask`.
1717
1818### Naked Generators
1919
20−A naked generator is simply a `gate`; that is, an is an anonymous function that
21−takes a `sample` (argument) and produces a noun. All you need to do is to write a
22−`gate` and put it into file in the `/gen` directory. Let's take a look at a very
23−simple one:
20+A naked generator is simply a `gate`; that is, it is an anonymous function that
21+takes a `sample` (argument) and produces a noun. All you need to do is write a
22+`gate` and put it into a file in the `/gen` directory. Let's take a look at a
23+very simple one:
2424
2525```
2626|= a=*
@@ -59,7 +59,7 @@ as part of a `tape`, the `cord` is only a single character. So each atom in the
5959is terminated with.
6060
6161We can tell the Dojo to cast -- apply a specific type to -- the output of our
62−generator see something more familiar:
62+generator to see something more familiar:
6363
6464```
6565> _tape +echo "asdf"
@@ -95,11 +95,11 @@ useful when a generator is needed to pipe data to another program, a frequent
9595occurrence.
9696
9797To that end, `%say` generators use `mark`s to make it clear, to other Arvo
98−computations, what exactly their kind of data their output is. A `mark` is akin
98+computations, exactly what kind of data their output is. A `mark` is akin
9999to a MIME type on the Arvo level. A `mark` describes the data in
100100some way, indicating that it's an `%atom`, or that it's a standard such as
101101`%json`, or even that it's an application-specific data structure like
102−`%talk-command`. `mark`s are not specific to `%say` generators; any time data
102+`%talk-command`. `mark`s are not specific to `%say` generators; whenever data
103103moves between programs in Arvo, that data is marked.
104104
105105So, more formally, a `%say` generator is a `cell`. The head of that cell is the
@@ -146,9 +146,9 @@ the `|= *` expression on the line that follows.
146146
147147`|= *` constructs a gate that takes a noun. This gate will itself produce a
148148`cask`, which is cell formed by the prepending `:-`. The head of that `cask` is
149−`%noun` and the tail is rest of the program, `(add 40 2)`. The tail of the
150−`cask` will be our actual data produced by body of the program: in this case
151−just adding 40 and 2 together.
149+`%noun` and the tail is the rest of the program, `(add 40 2)`. The tail of the
150+`cask` will be our actual data produced by the body of the program: in this
151+case, just adding 40 and 2 together.
152152
153153#### `%say` generators with arguments
154154
@@ -163,7 +163,7 @@ in the gate's sample, which we only specified as `*` in the previous few
163163examples. But we can do more with `%say` generators if we do more with that
164164sample. Any valid sample will follow this 3-tuple scheme:
165165
166−`[[datetime, entropy, beak] [list of unnamed arguments] [list of named arguments]]`
166+`[[now, eny, beak] [list of unnamed arguments] [list of named arguments]]`
167167
168168This entire structure is a noun, which is why `*` is a valid sample if we
169169wish to not use any of the information here in a generator. But let's look at
@@ -177,8 +177,8 @@ atoms:
177177`beak` contains the current ship, desk, and case.
178178
179179You can access each of those pieces of data by typing their names into the Dojo.
180−But in a generator, we need put faces (variable names) onto that data so we can
181−easily use it in the program. We can do that like below:
180+But in a generator, we need to put faces (variable names) onto that data so we
181+can easily use it in the program. We can do so like this:
182182
183183```
184184|= [[now=@da eny=@uvJ bec=beak] ~ ~]
@@ -189,18 +189,18 @@ Any of those pieces of data could be omitted by replacing part of the noun with
189189didn't want `eny`, or `[* * bec=beak]` if we only wanted `beak`.
190190
191191The *second part* of the sample is a `list` of arguments that _must_ be passed
192−to the generator as it's run. Because it's a `list`, this element needs to be
192+to the generator as it is run. Because it's a `list`, this element needs to be
193193terminated with a `~`. In the example above, we used `~`, the empty list, to
194194represent this second part. But that would mean we don't want to use any new
195195faces for our generator. So a sample where we want to declare a single required
196−argument would look like this.
196+argument would look like this:
197197
198198```
199199|= [* [n=@ud ~] ~]
200200```
201201
202202In the above code, we use a `*` to ignore any of the information that would go
203−first part of the sample, kind of in the same way that we use a `~` to say
203+in the first part of the sample, somewhat similar to how we use a `~` to say
204204"nothing here" for the second or third parts of the sample.
205205
206206But to use both parts together, our gate and sample would look like this:
@@ -210,7 +210,7 @@ But to use both parts together, our gate and sample would look like this:
210210```
211211
212212The *third part* of the sample is a list of _optional_ arguments. These
213−arguments may be passed to the program as its being run, but the program doesn't
213+arguments may be passed to the program as it's being run, but the program doesn't
214214require them. The syntax for the third part is just like the syntax for the
215215second part, besides its position:
216216
@@ -229,15 +229,15 @@ file called `dice.hoon` in your `/gen` directory.
229229```
230230
231231This is a very simple dice program with an optional betting functionality.
232−In the code, our sample specifies faces on all the all of the Arvo data, meaning
233−that we can can easily access them. We also require the argument `[n=@ud ~]`,
234−and allow the _optional_ argument `[bet=@ud ~]`.
232+In the code, our sample specifies faces on all of the Arvo data, meaning that we
233+can easily access them. We also require the argument `[n=@ud ~]`, and allow the
234+_optional_ argument `[bet=@ud ~]`.
235235
236236But there's something new: `(~(rad og eny) n)`. This code pulls the `rad` arm
237237out of the `og` core with the subject of `eny`. Recall that `eny` is our entropy
238238value, so this is used to seed the generator. The `rad` arm will give us a
239−pseudorandom number between 0 and `n`, and the `bet` that it's in a cell with
240−will just return the argument that we might choose to give it.
239+pseudorandom number between 0 and `n`. Then we form a cell with the result and
240+`bet`, the optional named argument specified previously.
241241
242242We can run this generator like so:
243243
@@ -294,7 +294,7 @@ We use the `%ask` generator when we want to create an interactive program
294294that prompts for inputs as it runs, rather than expecting arguments to be passed
295295in at the time of initiation.
296296
297−Code-wise, you need two things to create a useful `%ask` generator.
297+Code-wise, two things are needed to create a useful `%ask` generator.
298298
299299The first is *`sole-result`*, which lives in `/sur/sole.hoon`. It's a
300300mold-builder that's required by any part of Arvo, such as the Dojo, that wants
@@ -305,7 +305,7 @@ molds and digests them into a type for the operating system. The simplest way to
305305use `sole-result` is by calling the `produce` gate from `/lib/generators.hoon`.
306306
307307The second is *`prompt`*, a gate that lives in `lib/generators.hoon`. `prompt`
308−allows you to get get information back from the user, which is essential to the
308+allows you to get information back from the user, which is essential to the
309309typical desired operation of an `%ask` generator.
310310
311311Since this isn't easy to digest in the abstract, we'll use an example generator
@@ -346,7 +346,7 @@ What is your favorite color?
346346
347347Something new happened. Instead of simply returning something, your Dojo's
348348prompt changed from `~your-urbit:dojo>` to `~your-urbit:dojo: color:`, and
349−expects additional input. Let's give it an input:
349+now expects additional input. Let's give it an input:
350350
351351```
352352: color: red
@@ -397,19 +397,18 @@ We use the `^-` rune to constrain the generator's output to such a
397397A `cask` is a pair of a `mark` name and a noun. Recall that a `mark` can be
398398thought of as an Arvo-level MIME type for data.
399399
400−A `tang` is a `list` of `tank` and a `tank` is a structure for printing data
401−that there are three types of: `leaf`, `palm`, and `rose`. A `leaf` is for
400+A `tang` is a `list` of `tank`, and a `tank` is a structure for printing data.
401+There are three types of `tank`: `leaf`, `palm`, and `rose`. A `leaf` is for
402402printing a single noun, a `rose` is for printing rows of data, and a `palm` is
403−printing backstep-indented lists.
403+for printing backstep-indented lists.
404404
405405```
406406%+ print leaf+"What is your favorite color?"
407407%+ prompt [%& %prompt "color: "]
408−|= t=tape :: we will come to this later
408+|= t=tape
409409%+ produce %tang
410410```
411411
412−
413412Because we imported `generators`, we can access its contained gates, three of
414413which we use in `axe.hoon`: `print`, `prompt`, and `produce`.
415414
@@ -423,39 +422,38 @@ argument which is a `tank` to print. The `+` here is syntactic sugar for
423422It takes a single argument that is a tuple. Most `%ask` generators will want to
424423use the `prompt` gate.
425424
426−The first element of the `prompt` sample is a flag that indicates what the
427−user typed should be echoed out to them or hidden. `%&` will produce echoed
425+The first element of the `prompt` sample is a flag that indicates whether what
426+the user typed should be echoed out to them or hidden. `%&` will produce echoed
428427output and `%|` will hide the output (for use in passwords or other secret
429428text).
430429
431−The second element of the `prompt` sample is a `%term` used The second argument
432−is intended to be information to use to create autocomplete options for the
433−prompt this is not yet implemented.
430+The second element of the `prompt` sample is intended to be information for use
431+in creating autocomplete options for the prompt. This functionality is not yet
432+implemented.
434433
435434The third element of the `prompt` sample is the `tape` that we would like to
436435use to prompt the user. In the case of our example, we use `"color: "`.
437436
438−*`produce`* is is used to construct the output of the generator. In our
439−example, we produce a `tang`.
437+*`produce`* is used to construct the output of the generator. In our example,
438+we produce a `tang`.
440439
441440
442441```
443442|= t=tape
444443```
445444
446−Our gate here takes a `tape` that was produced by `prompt` if we needed another
447−type of data we could use `parse` to obtain it.
445+Our gate here takes a `tape` that was produced by `prompt`. If we needed
446+another type of data we could use `parse` to obtain it.
448447
449448The rest of this generator should be intelligible to those with Hoon knowledge
450449at this point.
451450
452451One quirk that you should be aware of, though, is that `tang` prints in reverse
453452order from how it is created. The reason for this is that `tang` was originally
454−created to display stack trace information, which should be produced in
455−in reverse order. This leads to an annoyance: we either have to specify our
456−messages backwards or construct them in the order we want and then `flop` the
457−`list` This is a [known issue](https://github.com/urbit/arvo/issues/840) to be
458−resolved.
453+created to display stack trace information, which should be produced in reverse
454+order. This leads to an annoyance: we either have to specify our messages
455+backwards or construct them in the order we want and then `flop` the `list`.
456+This is a [known issue](https://github.com/urbit/arvo/issues/840) to be resolved.
459457
460458### `%get` generators
461459
@@ -484,8 +482,8 @@ u.my-json
484482```
485483
486484The above generator was written with the
487−[Studio Ghibli API](https://ghibliapi.herokuapp.com/). The generator below was
488−designed to use the this API to print the title of a Studio Ghibli film.
485+[Studio Ghibli API](https://ghibliapi.herokuapp.com/). It uses this API to
486+print the title of a Studio Ghibli film.
489487
490488```
491489/- sole
@@ -494,7 +492,7 @@ designed to use the this API to print the title of a Studio Ghibli film.
494492```
495493
496494Here we import types from `/sur/sole.hoon` and gates from
497−`/lib/generators.hoon`. We also use `=,` to exposes the namespace of
495+`/lib/generators.hoon`. We also use `=,` to expose the namespace of
498496`generators` that we just imported.
499497
500498```
@@ -502,9 +500,9 @@ Here we import types from `/sur/sole.hoon` and gates from
502500|= [* [url=tape ~] ~]
503501```
504502
505−Like with `%say` and `%ask` generators, we must have include the "boilerplate":
506−code that produces a generator-specific `cell`. At the head of that cell is
507−`%get`, and the tail is a gate that takes a `tape` of the URL that we are trying
503+Like with `%say` and `%ask` generators, we must include the "boilerplate":
504+code that produces a generator-specific `cell`. The head of that cell is `%get`,
505+and the tail is a gate that takes a `tape` of the URL that we are trying
508506to access.
509507
510508```
@@ -550,8 +548,9 @@ for us that we can then use to inspect the data.
550548```
551549
552550After parsing the JSON structure we want to make sure we got back a valid `json`
553−type. To do that, we test for null and crash that test passes. If not, we use
554−`=,` on the `dejs:format` core so that we can more easily pull arms out of it.
551+type. To do that, we test for null and crash if that test passes. If it doesn't
552+pass, we use `=,` on the `dejs:format` core so that we can more easily pull arms
553+out of it.
555554
556555```
557556%+ produce %json
@@ -600,5 +599,5 @@ the arguments of that function come first. It's used here to keep with the
600599principle that heaviest, or most complex, expressions should go to the bottom.
601600
602601The key we are looking up in our new `map` we've created from `my-json` is
603−`%title` which is an element in the original source to print out to produce as
604−the final result of the generator.
602+`%title`, which is an element in the original source, to produce the final
603+result of the generator.