@@ -0,0 +1,2576 @@
1+---
2+navhome: /docs
3+---
4+
5+
6+Reference
7+=========
8+
9+Data Models
10+-----------
11+
12+### `++axle`, formal state
13+
14+ ++ axle :: all %ford state
15+ $: %1 :: version for update
16+ pol=(map ship baby) ::
17+ == ::
18+
19+This is the formal state of our vane. Anything that must be remembered
20+between calls to ford must be stored here. The number `%1` is a version
21+number for our state that allows us to upgrade the structure of our
22+state in the future if we wish.
23+
24+`pol` is the a map from every ship on our pier to their individual ford
25+state. There is no shared ford state -- every ship is entirely separate.
26+
27+### `++baby`, state by ship
28+
29+ ++ baby :: state by ship
30+ $: tad=[p=@ud q=(map ,@ud task)] :: tasks by number
31+ dym=(map duct ,@ud) :: duct to task number
32+ jav=(map ,* calx) :: cache
33+ == ::
34+
35+This is the state specific to each ship.
36+
37+`tad` and `dym` keep track of the tasks we're currently working on.
38+`dym` is a map from ducts to task numbers, and `q.tad` is a map from
39+task number to the task itself. `p.tad` is the next available task
40+number. Thus, the keys of `q.tad` are a subset of the numbers less than
41+`p.tad`, and ford has attempted exactly `p.tad` tasks so far.
42+
43+`jav` is the cache of previously-solved problems. The keys are a pair of
44+a term (either `%hood`, `%slap`, or `%slam`) and a noun that represents
45+the exact problem solved. In the case of a `%hood`, then, the key is of
46+the form `[%hood beam cage]`. For `%slap`, there is `[%slap vase twig]`.
47+For `%slam`, there is `[%slam vase vase]`. The values are the result of
48+solving the problem. Note that this cache is wiped in `++stay` when ford
49+is reloaded.
50+
51+### `++task`, problem in progress
52+
53+ ++ task :: problem in progress
54+ $: nah=duct :: cause
55+ kas=silk :: problem
56+ kig=[p=@ud q=(map ,@ud beam)] :: blocks
57+ == ::
58+
59+This is all the state we keep regarding a particular task. `nah` is the
60+duct which asked us to solve the problem, and `kas` is the most recent
61+statement of the problem.
62+
63+`kig` keeps track of which resources we are blocked on. Our blocks are
64+stored by index in `q.kig`, and the next available index is `p.kig`.
65+
66+### `++silk`, problem
67+
68+ ++ silk :: construction layer
69+ $& [p=silk q=silk] :: cons
70+ $% [%bake p=mark q=beam r=path] :: local synthesis
71+ [%boil p=mark q=beam r=path] :: general synthesis
72+ [%call p=silk q=silk] :: slam
73+ [%cast p=mark q=silk] :: translate
74+ [%diff p=silk q=silk] :: diff
75+ [%done p=(set beam) q=cage] :: literal
76+ [%dude p=tank q=silk] :: error wrap
77+ [%dune p=(set beam) q=(unit cage)] :: unit literal
78+ [%mute p=silk q=(list (pair wing silk))] :: mutant
79+ [%pact p=silk q=silk] :: patch
80+ [%plan p=beam q=spur r=hood] :: structured assembly
81+ [%reef ~] :: kernel reef
82+ [%ride p=twig q=silk] :: silk thru twig
83+ [%vale p=mark q=ship r=*] :: validate [our his]
84+ == ::
85+
86+This is the every type of problem we can solve. Every `%exec` kiss that
87+requests us to solve a problem must choose one of these problems to
88+solve.
89+
90+Because this is both an internal structure used in ford and the public
91+interface to ford, we choose to document this structure in our
92+discussion of the public interface to ford below.
93+
94+### `++calx`, cache line
95+
96+ ++ calx :: concrete cache line
97+ $% [%hood p=calm q=(pair beam cage) r=hood] :: compile
98+ [%slap p=calm q=[p=vase q=twig] r=vase] :: compute
99+ [%slam p=calm q=[p=vase q=vase] r=vase] :: compute
100+ == ::
101+
102+There are three kinds of cache entries. Every entry includes some
103+metadata in `p` and is the combination of an input and its output.
104+
105+The input to a `%hood` is the location of the resource and a cage
106+representing the data at that location. The output is the hood found by
107+compiling the given cage at the given location.
108+
109+The input to a `%slap` is the vase of the subject and the twig of the
110+formula against which we are slapping the subject. The output is the
111+vase produced by slapping them.
112+
113+The input to a `%slam` is the vase of the subject and the vase of the
114+gate which we are slapping. The output is the vase produced by slamming
115+them.
116+
117+### `++calm`, cache line metadata
118+
119+ ++ calm :: cache metadata
120+ $: laz=@da :: last accessed
121+ dep=(set beam) :: dependencies
122+ == ::
123+
124+Every line in the cache needs to have two pieces of metadata. We must
125+know the last time this line in the cache was accessed, and we must know
126+what are the dependencies of this line.
127+
128+### `++hood`, assembly components
129+
130+ ++ hood :: assembly plan
131+ $: zus=@ud :: zuse kelvin
132+ sur=(list hoot) :: structures
133+ lib=(list hoof) :: libraries
134+ fan=(list horn) :: resources
135+ src=(list hoop) :: program
136+ == ::
137+
138+When assembling a hook file, we split it into several sections.
139+
140+`zus` is the kelvin version of the required zuse. In general, we assume
141+that any newer (lower-numbered) zuse will retain backward compatibility,
142+so any newer zuse is also permissible. This number is set with a `/?` at
143+the beginning of the file.
144+
145+`sur` is the set of structures included. These are included with the
146+`/-` rune. When a structure is included, we look in `/=main=/sur` for
147+the given structure and we load the gate there. When compiling, all the
148+included structures are collected into a single core placed in the
149+subject of the body with a `=>`.
150+
151+`lib` is the set of librarires included. These are included with the
152+`/+` rune. When a library is included, we look in `/=main=/lib` for the
153+given library and we load the library there. As with structures, all the
154+included libraries are collected into a single core placed in the
155+subject of the body with a `=>`.
156+
157+`fan` is the set of resources included. These are loaded in many
158+different ways and may load resources from any location. These are
159+placed in the subject of the body with a `=~`.
160+
161+`src` is the set of twigs or references to twigs in the body of the
162+program. Generally, each of these will represent a core, but this is not
163+required. When compiling, these are strung together in a `=~`.
164+
165+### `++hoot`
166+
167+ ++ hoot (pair bean hoof) :: structure gate/core
168+
169+A structures may be either a direct gate or a core. These are
170+syntactically distinguished by adding a `*` to the beginning of the
171+structure name for a core. The structure itself is a `hoof`.
172+
173+### `++hoof`
174+
175+ ++ hoof (pair term (unit (pair case ship))) :: resource reference
176+
177+A hoof, which is either a structure or a library, has a name, and it may
178+also specify which version of the resource to use and which ship to
179+retrieve it from.
180+
181+### `++horn`
182+
183+ ++ horn :: resource tree
184+ $% [%ape p=twig] :: /~ twig by hand
185+ [%arg p=twig] :: /$ argument
186+ [%day p=horn] :: /| list by @dr
187+ [%dub p=term q=horn] :: /= apply face
188+ [%fan p=(list horn)] :: /. list
189+ [%for p=path q=horn] :: /, descend
190+ [%hub p=horn] :: /@ list by @ud
191+ [%man p=(map span horn)] :: /* hetero map
192+ [%nap p=horn] :: /% homo map
193+ [%now p=horn] :: /& list by @da
194+ [%saw p=twig q=horn] :: /; operate on
195+ [%see p=beam q=horn] :: /: relative to
196+ [%sic p=tile q=horn] :: /^ cast
197+ [%toy p=mark] :: /mark/ static
198+ == ::
199+
200+This is how we represent the static resources hook files can load. The
201+discussion of their use from a user's perspective is documented
202+elsewhere (link), so we will here only give a description of the data
203+structure itself.
204+
205+A `%ape` horn is simply a twig that gets evaluated and placed in the
206+subject.
207+
208+A `%arg` is a gate that gets evaluated with a sample of our location and
209+our heel.
210+
211+A `%day` is a horn that applies to each of a list of `@dr`-named files
212+in the directory.
213+
214+A `%dub` is a term and horn, where the result of a horn is given the
215+face of the term.
216+
217+A `%fan` is a list of horns, all at the current directory level.
218+
219+A `%for` is a path and a horn, where the horn is evaluated relative to
220+the given path, where the given path is relative to the current
221+location.
222+
223+A `%hub` is a horn that applies to each of a list of `@ud`-named files
224+in the directory.
225+
226+A `%man` is a map of spans to horns where the result is a set of each
227+horn applied to the current directory given the associated face.
228+
229+A `%nap` is a homogenous map where each entry in a directory is handled
230+with the same horn and is given a face according to its name.
231+
232+A `%now` is a horn that applies to each of a list of `@da`-named files
233+in the directory.
234+
235+A `%saw` is a twig and a horn, where the twig operates on the result of
236+the horn.
237+
238+A `%see` is a beam and a horn, where the horn is evaluated at a location
239+of the given beam.
240+
241+A `%sic` is a tile and a horn, where the horn is evaluated and cast to
242+the type associated with the tile.
243+
244+A `%toy` is simply a mark to be baked.
245+
246+### `++hoop`, body
247+
248+ ++ hoop :: source in hood
249+ $% [%& p=twig] :: direct twig
250+ [%| p=beam] :: resource location
251+ == ::
252+
253+This is an entry in the body of the hook file. The hoop can either be
254+defined directly in the given file or it can be a reference to another
255+file. The second is specified with a `//` rune.
256+
257+### `++bolt`, monadic edge
258+
259+ ++ bolt :: gonadic edge
260+ |* a=$+(* *) :: product clam
261+ $: p=cafe :: cache
262+ $= q ::
263+ $% [%0 p=(set beam) q=a] :: depends/product
264+ [%1 p=(set ,[p=beam q=(list tank)])] :: blocks
265+ [%2 p=(list tank)] :: error
266+ == ::
267+ == ::
268+
269+Throughout our computation, we let our result flow through with the set
270+of dependencies of the value. At various times, we may wish to either
271+throw an error or declare that the actual result cannot be found until a
272+particular resource is retrieved. This is a perfect case for a monad, so
273+here we define a data structure for it.
274+
275+At every step, we have a cache, so we store that in `p`. In `q` we store
276+the data.
277+
278+In the case of `%0`, we have the result in `q` and the set of
279+dependencies in `p`.
280+
281+In the case of `%1`, we have a set of dependencies on which we are
282+blocking. When this happens, we make a call to clay to get the
283+dependencies, and we proceed with the computation when we receive them.
284+Technically, we restart the computation, but since every expensive step
285+is cached, there is no significant performance penalty to doing this.
286+Referential transparency has its uses.
287+
288+In the case of `%2`, we have a hit an error. This gets passed all the
289+way through to the calling duct. The list of tanks is some description
290+of what went wrong, often including a stack trace.
291+
292+### `++burg`, monadic rule
293+
294+ ++ burg :: gonadic rule
295+ |* [a=$+(* *) b=$+(* *)] :: from and to
296+ $+([c=cafe d=a] (bolt b)) ::
297+ :: ::
298+
299+To operate on bolts, we use `++cope` as our bind operator, and the
300+functions it works on are of type `burg`. Our functions that operate on
301+bolts should have a sample of the cache and a value. Their output should
302+be a bolt of the output value. Then, `++cope` will only call the
303+function when necessary (in the `%0` case), and it will do so without
304+the wrapping of a bolt.
305+
306+If you understand monads, this is probably fairly obvious. Otherwise,
307+see the discussion on `++cope` (link).
308+
309+Public Interface
310+----------------
311+
312+Ford does not export a scry interface, so the only way to interact with
313+ford is by sending kisses and receiving gifts. In fact, ford only sends
314+accepts one kiss and gives one gift. This is, of course, misleading
315+because ford actually does many different things. It does, however, only
316+produce one type of thing -- a result of a computation, which is either
317+an error or the value produced along with the set of dependencies
318+referenced by it.
319+
320+ ++ kiss :: in request ->$
321+ $% [%exec p=@p q=(unit silk)] :: make / kill
322+ == ::
323+
324+The `%exec` gift requests ford to perform a computation on behalf of a
325+particular ship. `p` is the ship, and `q` is the computation. If `q` is
326+null, then we are requesting that ford cancel the computation that it is
327+currently being run along this duct. Thus, if you wish to cancel a
328+computation, you must send the kiss along the same duct as the original
329+request.
330+
331+Otherwise, we ask ford to perform a certain computation, as defined in
332+`++silk`. Since all computations produce the same type of result, we
333+will discuss that result before we jump into `++silk`.
334+
335+ ++ gift :: out result <-$
336+ $% [%made p=(each bead (list tank))] :: computed result
337+ == ::
338+
339+We give either a `bead`, which is a result, or a list of tanks, which is
340+an error messge, often including a stack trace.
341+
342+ ++ bead ,[p=(set beam) q=cage] :: computed result
343+
344+This is a set of dependencies required to compute this value and a cage
345+of the result with its associated mark.
346+
347+There are twelve possible computations defined in `++silk`.
348+
349+ ++ silk :: construction layer
350+ $& [p=silk q=silk] :: cons
351+ $% [%bake p=mark q=beam r=path] :: local synthesis
352+ [%boil p=mark q=beam r=path] :: general synthesis
353+ [%call p=silk q=silk] :: slam
354+ [%cast p=mark q=silk] :: translate
355+ [%done p=(set beam) q=cage] :: literal
356+ [%dude p=tank q=silk] :: error wrap
357+ [%dune p=(set beam) q=(unit cage)] :: unit literal
358+ [%mute p=silk q=(list (pair wing silk))] :: mutant
359+ [%plan p=beam q=spur r=hood] :: structured assembly
360+ [%reef ~] :: kernel reef
361+ [%ride p=twig q=silk] :: silk thru twig
362+ [%vale p=mark q=ship r=*] :: validate [our his]
363+ == ::
364+
365+First, we allow silks to autocons. A cell of silks is also a silk, and
366+the product vase is a cell of the two silks. This obviously extends to
367+an arbitrary number of silks.
368+
369+`%bake` tries to functionally produce the file at a given beam with the
370+given mark and heel. It fails if there is no way to translate at this
371+level.
372+
373+`%boil` functionally produces the file at a given beam with the given
374+mark and heel. If there is no way to translate at this beam, we pop
375+levels off the stack and attempt to bake there until we find a level we
376+can bake. This should almost always be called instead of `%bake`.
377+
378+`%call` slams the result of one silk against the result of another.
379+
380+`%cast` translates the given silk to the given mark, if possible. This
381+is one of the critical and fundamental operations of ford.
382+
383+`%done` produces exactly its input. This is rarely used on its own, but
384+many silks are recursively defined in terms of other silks, so we often
385+need a silk that simply produces its input. A monadic return, if you
386+will.
387+
388+`%diff` diffs the two given silks (which must be of the same mark),
389+producing a cage of the mark specified in `++mark` in `++grad` for the
390+mark of the two silks.
391+
392+`%dude` computes the given silk with the given tank as part of the stack
393+trace if there is an error.
394+
395+`%dune` produces an error if the cage is empty. Otherwise, it produces
396+the value in the unit.
397+
398+`%mute` takes a silk and a list of changes to make to the silk. At each
399+wing in the list we put the value of the associated silk.
400+
401+`%pact` applies the second silk as a patch to the first silk. The second
402+silk must be of the mark specified in `++mark` in `++grad` for the mark
403+of the first silk.
404+
405+`%plan` performs a structured assembly directly. This is not generally
406+directly useful because several other silks perform supersets of this
407+functionality. We don't usually have naked hoods outside ford.
408+
409+`%reef` produces a core containing the entirety of zuse and hoon,
410+suitable for running arbitrary code against. The mark is `%noun`.
411+
412+`%ride` slaps a twig against a subject silk. The mark of the result is
413+`%noun`.
414+
415+`%vale` validates untyped data from a ship against a given mark. This is
416+an extremely useful function.
417+
418+Commentary
419+==========
420+
421+Parsing Hook Files
422+------------------
423+
424+In the commentary on other vanes, we have traced through the lifecycle
425+of various external requests. This is generally a very reasonable order
426+to examine vanes since it will eventually cover the entire vane, and we
427+are never left wondering why we are doing something.
428+
429+For ford, however, it makes more sense to begin by discussing the
430+parsing and assembliing of hook files. Many of the possible requests
431+require us to assemble hook files, so we may as well examine this
432+immediately.
433+
434+First, we will examine the parsing. We parse a file at a beam to a hood
435+in `++fade:zo:za`. The top-level parsing rule is `++fair`, which takes a
436+beam and produces a rule to parse an entire hood file.
437+
438+A note on the naming scheme: the parsing the combinators that parse into
439+a particular structure are conventionally given the same name as the
440+structure. Although this locally clobbers the type names, this pattern
441+makes obvious the intent of the parsing combinators.
442+
443+We kick off with `++hood:fair`.
444+
445+ ++ hood
446+ %+ ifix [gay gay]
447+ ;~ plug
448+ ;~ pose
449+ (ifix [;~(plug fas wut gap) gap] dem)
450+ (easy zuse)
451+ ==
452+ ::
453+ ;~ pose
454+ (ifix [;~(plug fas hep gap) gap] (most ;~(plug com gaw) hoot))
455+ (easy ~)
456+ ==
457+ ::
458+ ;~ pose
459+ (ifix [;~(plug fas lus gap) gap] (most ;~(plug com gaw) hoof))
460+ (easy ~)
461+ ==
462+ ::
463+ (star ;~(sfix horn gap))
464+ (most gap hoop)
465+ ==
466+
467+There are five sections to a hood: system version, structures,
468+libraries, resources, and body.
469+
470+First, we parse the requested version number of the system. This is
471+specified with a unary `/?` rune. If not present, then we default to the
472+current version.
473+
474+Second, we may have zero or more `/-` runes followed by a parsing of a
475+`++hoot`, which represents a shared structure.
476+
477+Third, we may have zero or more `/+` runes followed by a parsing of a
478+`++hoof`, which represents a shared library.
479+
480+Fourth, we may have zero or more other `/` runes (as described in
481+`++horn`), which represent program-specific resources to be loaded.
482+
483+Fifth and finally, we must have one or more body statements (hoops),
484+which are either direct twigs or `//` runes.
485+
486+ ++ hoot
487+ ;~ pose
488+ (stag %| ;~(pfix tar hoof))
489+ (stag %& hoof)
490+ ==
491+
492+A structure can either be a direct gate, or it can be a simple core.
493+Either one is parsed with `++hoof`, so we distinguish the two cases by
494+requireing core references to be prefixed by a `*`.
495+
496+ ++ hoof
497+ %+ cook |=(a=^hoof a)
498+ ;~ plug
499+ sym
500+ ;~ pose
501+ %+ stag ~
502+ ;~(plug ;~(pfix fas case) ;~(pfix ;~(plug fas sig) fed:ag))
503+ (easy ~)
504+ ==
505+ ==
506+
507+A hoof must have a name, which is a term. Optionally, we also include a
508+case and a ship. This is marked by appending a `/` followed by a case to
509+denote the requested version of the resource and a `/` followed by a
510+ship name to denote the requested source of the resource. For example,
511+`resource/1/~zod` requests the first version of `resource` on `~zod`.
512+
513+ ++ case
514+ %- sear
515+ :_ nuck:so
516+ |= a=coin
517+ ?. ?=([%$ ?(%da %ud %tas) *] a) ~
518+ [~ u=(^case a)]
519+
520+Here, we parse a literal with `++nuck:so`, and we accept the input if it
521+is either an absolute date, an unsigned decimal, or a label.
522+
523+This leaves only horns and hoops to parse. Hoops are much simple to
524+parse, so we'll discuss those first.
525+
526+ ++ hoop
527+ ;~ pose
528+ (stag %| ;~(pfix ;~(plug fas fas gap) have))
529+ (stag %& tall:vez)
530+ ==
531+
532+There are two types of hoops. Direct twigs are parsed with
533+`++tall:vast`, which is the just the hoon parser for a tall-form twig.
534+
535+References to external twigs are marked with a `//` rune followed by a
536+beam, which is parsed with `++have`.
537+
538+ ++ hath (sear plex:voz (stag %clsg poor:voz)) :: hood path
539+ ++ have (sear tome ;~(pfix fas hath)) :: hood beam
540+
541+`++have` parses a path with `++hath`, and then it converts the path into
542+a beam with `++tome`.
543+
544+`++hath` parses a `/`-separated list with `++poor:vast`, then converts
545+it to an actual path with `++plex:vast`.
546+
547+This leaves only horns to parse.
548+
549+ ++ horn
550+ =< apex
551+ =| tol=?
552+ |%
553+ ++ apex
554+ %+ knee *^horn |. ~+
555+ ;~ pfix fas
556+ ;~ pose
557+ (stag %toy ;~(sfix sym fas))
558+ (stag %ape ;~(pfix sig ape:read))
559+ (stag %arg ;~(pfix buc ape:read))
560+ (stag %day ;~(pfix bar day:read))
561+ (stag %dub ;~(pfix tis dub:read))
562+ (stag %fan ;~(pfix dot fan:read))
563+ (stag %for ;~(pfix com for:read))
564+ (stag %hub ;~(pfix pat day:read))
565+ (stag %man ;~(pfix tar man:read))
566+ (stag %nap ;~(pfix cen day:read))
567+ (stag %now ;~(pfix pam day:read))
568+ (stag %saw ;~(pfix sem saw:read))
569+ (stag %see ;~(pfix col see:read))
570+ (stag %sic ;~(pfix ket sic:read))
571+ ==
572+ ==
573+
574+Horn parsing is slightly complex, so we create an internal core to
575+organize our code. Our core has a global variable of `tol`, which is
576+true if tall form is permissible and false if we're already in wide
577+form. We kick off the parsing with `++apex`.
578+
579+`++apex` specifies how each rune is parsed. This allows us to offload
580+the different ways of parsing the arguments to these runes into separate
581+arms. The exception here is that the `%toy` horn is simply of the form
582+`/mark/`.
583+
584+We'll examine each of the horn parsing arms right after we discuss
585+`++rail`, which is used in each one.
586+
587+ ++ rail
588+ |* [wid=_rule tal=_rule]
589+ ?. tol wid
590+ ;~(pose wid tal)
591+
592+This takes a wide-form and a tall-form parsing rule. If tall form is
593+permissible, then it allows either rule to match; else, it allows only
594+the wide form rule.
595+
596+ ++ read
597+ |% ++ ape
598+ %+ rail
599+ (ifix [sel ser] (stag %cltr (most ace wide:vez)))
600+ ;~(pfix gap tall:vez)
601+
602+`++ape:read` parses for both the `/~` and the `/$` runes. It produces a
603+twig. The wide form is a tuple of one or more ace-separated wide-form
604+twigs parsed with `++wide:vast` and surrounded by `[` and `]`. The tall
605+form is a single tall form twig parsed by `++tall:vast`
606+
607+ ++ day
608+ %+ rail
609+ apex(tol |)
610+ ;~(pfix gap apex)
611+
612+This parses for the `/|`, `/@`, `/%`, and `/&` runes. It produces a
613+horn. The wide form is, recursively, the entire horn parser with tall
614+form disabled. The tall form is a gap followed by, recursively, the
615+entire horn parser.
616+
617+ ++ dub
618+ %+ rail
619+ ;~(plug sym ;~(pfix tis apex(tol |)))
620+ ;~(pfix gap ;~(plug sym ;~(pfix gap apex)))
621+
622+This parses for the `/=` rune. It produces a term followed by a horn.
623+The wide form is a symbol name followed by a `=` and, recursively, the
624+entire horn parser with tall form disabled. The tall form is a gap
625+followed by a symbol name, another gap, and, recursively, the entire
626+horn parser.
627+
628+ ++ fan
629+ %+ rail fail
630+ ;~(sfix (star ;~(pfix gap apex)) ;~(plug gap duz))
631+
632+This parses for the `/.` rune. It produces a list of horns. There is no
633+wide form. The tall form is a stet-terminated series of gap-separated
634+recursive calls to the entire horn parser.
635+
636+ ++ for
637+ %+ rail
638+ ;~(plug (ifix [sel ser] hath) apex(tol |))
639+ ;~(pfix gap ;~(plug hath ;~(pfix gap apex)))
640+
641+This parses for the `/,` rune. It produces a path and a horn. The wide
642+form is a `[`-`]`-surrounded path followed by, recursively, the entire
643+horn parser with tall form disabled. The tall form is a gap followed by
644+a path, another gap, and, recursively, the entire horn parser.
645+
646+ ++ man
647+ %+ rail fail
648+ %- sear
649+ :_ ;~(sfix (star ;~(pfix gap apex)) ;~(plug gap duz))
650+ |= fan=(list ^horn)
651+ =| naf=(list (pair term ^horn))
652+ |- ^- (unit (map term ^horn))
653+ ?~ fan (some (~(gas by *(map term ^horn)) naf))
654+ ?. ?=(%dub -.i.fan) ~
655+ $(fan t.fan, naf [[p.i.fan q.i.fan] naf])
656+
657+This parses for the `/*` rune. It produces a map of spans to horns.
658+There is no wide form. The tall form is a stet-terminated series of
659+gap-separated recursive calls to the entire horn parser. All produced
660+horns are expected to be from `/=` runes. The term and horn in each `/=`
661+horn is inserted into the produced map as a key-value pair.
662+
663+ ++ saw
664+ %+ rail
665+ ;~(plug ;~(sfix wide:vez sem) apex(tol |))
666+ ;~(pfix gap ;~(plug tall:vez ;~(pfix gap apex)))
667+
668+This parses for the `/;` rune. It produces a twig and a horn. The wide
669+form is a wide-form twig followed by a `;` and, recursively, the entire
670+horn parser with tall form disabled. The tall form is a gap followed by
671+a tall-form twig, another gap, and, recursively, the entire horn parser.
672+
673+ ++ see
674+ %+ rail
675+ ;~(plug ;~(sfix have col) apex(tol |))
676+ ;~(pfix gap ;~(plug have ;~(pfix gap apex)))
677+
678+This parses for the `/:` rune. It produces a beam and a horn. The wide
679+form is a beam followed by a `;` and, recursively, the entire horn
680+parser with tall form disabled. The tall form is a gap followed by a
681+beam, another gap, and, recursively, the entire horn parser.
682+
683+ ++ sic
684+ %+ rail
685+ ;~(plug ;~(sfix toil:vez ket) apex(tol |))
686+ ;~(pfix gap ;~(plug howl:vez ;~(pfix gap apex)))
687+ --
688+
689+This parses for the `/^` rune. It produces a tile and a horn. The wide
690+form is a wide-form tile, parsed with `++toil:vast`, followed by a `^`
691+and, recursively, the entire horn parser with tall form disabled. The
692+tall form is a gap followed by a tall-form tile, parsed with
693+`++howl:vast`, another gap, and, recursively, the entire horn parser.
694+
695+Assembling Hook Files
696+---------------------
697+
698+At this point, we've parsed a hook file into a hood. We will now
699+describe exactly how this hood is assembled into a vase. The problem of
700+assembling is handled entirely within the `++meow:zo:za` core.
701+
702+ ++ meow :: assemble
703+ |= [how=beam arg=heel]
704+ =| $: rop=(map term (pair hoof twig)) :: structure/complex
705+ zog=(set term) :: structure guard
706+ bil=(map term (pair hoof twig)) :: libraries known
707+ lot=(list term) :: library stack
708+ zeg=(set term) :: library guard
709+ boy=(list twig) :: body stack
710+ hol=? :: horns allowed?
711+ ==
712+ |%
713+
714+We take two arguments and keep seven pieces of state. `how` is the
715+location of the hook file we're assembling, and `arg` is the heel, or
716+virtual path extension, of the file.
717+
718+In `rop`, we maintain a map of terms to pairs of hooves and twigs to
719+represent the structures we've encountered that we will put together in
720+a core at the top of the file.
721+
722+In `zog`, we maintain the set of structures we're in the middle of
723+loading. If we try to load a structure already in our dependency
724+ancestry, then we fail because we do not allow circular dependencies.
725+This enforces that our structure dependency graph is a DAG.
726+
727+In `bil`, we maintain a map of terms to pairs of hooves and twigs to
728+represent the libraries we've encountered that we will put together in a
729+series of cores after the structure core.
730+
731+In `lot`, we maintain a stack of library names as they are encountered
732+during a depth-first search. More precisely, we push a library onto the
733+stack after we've processed all its children. Thus, every library
734+depends only on things deeper in the list. The libraries must be loaded
735+in the reverse of this order. Concisely, this is a topological sort of
736+the library dependency partial ordering.
737+
738+In `zeg`, we maintain the set of libraries we're in the middle of
739+loading. If we try to load a library already in our dependency ancestry,
740+then we fail because we do not allow circular dependencies. This
741+enforces that our library dependency graph is a DAG.
742+
743+In `boy`, we maintain a stack of body twigs, which we'll put together in
744+a series of cores at the end of the file.
745+
746+In `hol`, we decide if we're allowed to contain horns. Libraries and
747+structures are not allowed to contain horns.
748+
749+We in every case enter `++meow` through `++abut`. You'll notice that
750+there are four (count 'em, four!) calls to `++cope` in `++abut`. If
751+you've glanced at the ford code in general, you've probably seen cope
752+over and over. It is called in 79 different places. We need to discuss
753+the use of this critical function in detail, so we may as well do it
754+here.
755+
756+ ++ cope :: bolt along
757+ |* [hoc=(bolt) fun=(burg)]
758+ ?- -.q.hoc
759+ %2 hoc
760+ %1 hoc
761+ %0 =+ nuf=(fun p.hoc q.q.hoc)
762+ :- p=p.nuf
763+ ^= q
764+ ?- -.q.nuf
765+ %2 q.nuf
766+ %1 q.nuf
767+ %0 [%0 p=(grom `_p.q.nuf`p.q.hoc p.q.nuf) q=q.q.nuf]
768+ == ==
769+
770+In monad-speak, this is the bind operator for the bolt monad. If monads
771+aren't your thing, don't worry, we're going to explain the use of cope
772+without further reference to them.
773+
774+Recall that there are three different types of bolt. A `%2` error bolt
775+contains a list of tanks describing the error, a `%1` block bolt
776+contains a set of resources we're blocked on, and a `%0` value bolt
777+contains an actual value and the set of its dependencies.
778+
779+We most commonly want to perform an operation on the value in a bolt if
780+it is a `%0` bolt. If it's not a `%0` bolt, we want to leave it alone.
781+This requires us to write a certain amount of boilerplate between each
782+of our operations to see if any of them produced a `%1` or a `%2` bolt.
783+This gets tiresome, so we pull it out into a separate arm and call it
784+`++cope`.
785+
786+Intuitively, we're calling the function `fun` with the value in `hoc`,
787+where `fun` takes an argument of type whatever is the value in a `%0`
788+case of `hoc`, and it produces a bolt of some (possibly different) type.
789+For brevity, we will refer to the type of the of the value in the `%0`
790+case of a bolt as the "type of the bolt".
791+
792+If the `hoc` bolt we're given as input to `fun` is already a `%1` or a
793+`%2` bolt, then we simply produce that. We don't even try to run `fun`
794+on it.
795+
796+Otherwise, we run `fun` with the arguments from the bolt and, if it
797+produces a `%1` or a `%2` bolt, we simply produce that. If it produces a
798+`%0` bolt, then we produce that with the old set of dependencies merged
799+in with the new set.
800+
801+We'll see more about how the bolt monad works as we run into more
802+interesting uses of it. For now, this is sufficient to move on with
803+`++abut`.
804+
805+ ++ abut :: generate
806+ |= [cof=cafe hyd=hood]
807+ ^- (bolt vase)
808+ %+ cope (apex cof hyd)
809+ |= [cof=cafe sel=_..abut]
810+ =. ..abut sel
811+ %+ cope (maim cof pit able)
812+ |= [cof=cafe bax=vase]
813+ %+ cope (chap cof bax [%fan fan.hyd])
814+ |= [cof=cafe gox=vase]
815+ %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
816+ |= [cof=cafe fin=vase]
817+ (fine cof fin)
818+
819+Our job is simple: we must assemble a hood file into a vase. Hopefully,
820+the usage of `++cope` is fairly understandable. The correct way to read
821+this is that it does essentially five things.
822+
823+First, we call `++apex` to process the structures, libraries, and body.
824+This changes our state, so we set our context to the produced context.
825+Second, we call `++able` to assemble the strucutres and libraries into a
826+twig, which we slap against zuse with `++maim`. Third, we call `++chap`
827+to process the resources in the context of the already-loaded structures
828+and libraries. Fourth, we slap the body against the structures,
829+libraries, and resources. Fifth and finally, we produce the resultant
830+vase.
831+
832+ ++ apex :: build to body
833+ |= [cof=cafe hyd=hood]
834+ ^- (bolt ,_..apex)
835+ ?. |(hol ?=(~ fan.hyd))
836+ %+ flaw cof :_ ~ :- %leaf
837+ "horns not allowed in structures and libraries: {<[how arg]>}"
838+ %+ cope (body cof src.hyd)
839+ |= [cof=cafe sel=_..apex]
840+ =. ..apex sel
841+ %+ cope (neck cof lib.hyd)
842+ |= [cof=cafe sel=_..apex]
843+ =. ..apex sel(boy boy)
844+ %+ cope (head cof sur.hyd)
845+ |= [cof=cafe sel=_..apex]
846+ (fine cof sel)
847+
848+First, we make sure that if we're not allowed to have horns, we don't.
849+Otherwise, we produce and error with `++flaw`.
850+
851+ ++ flaw |=([a=cafe b=(list tank)] [p=a q=[%2 p=b]]) :: bolt from error
852+
853+This produces a `%2` error bolt from a list of tanks. Fairly trivial.
854+
855+We should be starting to get used to the cope syntax, so we can see that
856+we really only do three things here. We process the body with `++body`,
857+the libraries with `++neck`, and the structures with `++head`.
858+
859+ ++ body :: produce functions
860+ |= [cof=cafe src=(list hoop)]
861+ ^- (bolt _..body)
862+ ?~ src (fine cof ..body)
863+ %+ cope (wilt cof i.src)
864+ |= [cof=cafe sel=_..body]
865+ ^$(cof cof, src t.src, ..body sel)
866+
867+We must process a list of hoops that represent our body. If there are no
868+more hoops, we just produce our context in a `%0` bolt with `++fine`.
869+
870+ ++ fine |* [a=cafe b=*] :: bolt from data
871+ [p=`cafe`a q=[%0 p=*(set beam) q=b]] ::
872+
873+In monad-speak, this is the return operator. For us, this just means
874+that we're producing a `%0` bolt, which contains a path and a set of
875+dependencies. We assume there are no dependencies for the given data, or
876+that they will be added later.
877+
878+If there are more hoops in `++body`, we call `++wilt` to process an
879+individual hoop and recurse.
880+
881+ ++ wilt :: process body entry
882+ |= [cof=cafe hop=hoop]
883+ ^- (bolt _..wilt)
884+ ?- -.hop
885+ %& (fine cof ..wilt(boy [p.hop boy]))
886+ %|
887+ %+ cool |.(leaf/"ford: wilt {<[(tope p.hop)]>}")
888+ %+ cope (lend cof p.hop)
889+ |= [cof=cafe arc=arch]
890+ ?: (~(has by r.arc) %hoon)
891+ %+ cope (fade cof %hoon p.hop)
892+ |= [cof=cafe hyd=hood]
893+ %+ cope (apex(boy ~) cof hyd)
894+ |= [cof=cafe sel=_..wilt]
895+ (fine cof sel(boy [[%tssg boy.sel] boy]))
896+ =+ [all=(lark (slat %tas) arc) sel=..wilt]
897+ %+ cope
898+ |- ^- (bolt (pair (map term foot) _..wilt))
899+ ?~ all (fine cof ~ ..wilt)
900+ %+ cope $(all l.all)
901+ |= [cof=cafe lef=(map term foot) sel=_..wilt]
902+ %+ cope ^$(all r.all, cof cof, sel sel)
903+ |= [cof=cafe rig=(map term foot) sel=_..wilt]
904+ %+ cope
905+ %= ^^^^$
906+ cof cof
907+ ..wilt sel(boy ~)
908+ s.p.hop [p.n.all s.p.hop]
909+ ==
910+ |= [cof=cafe sel=_..wilt]
911+ %+ fine cof
912+ [`(map term foot)`[[p.n.all [%ash [%tssg boy.sel]]] lef rig] sel]
913+ |= [cof=cafe mav=(map term foot) sel=_..wilt]
914+ ?~ mav
915+ (flaw cof [%leaf "source missing: {<(tope p.hop)>}"]~)
916+ (fine cof sel(boy [[%brcn mav] boy]))
917+ ==
918+
919+In the case of a direct twig hoop, we just push it onto `boy` and we're
920+done. In the case of an indirect hoop, we must compile the referenced
921+file.
922+
923+First, we push onto the stack trace a message indicating which file
924+exactly we're compiling at the moment with `++cool`.
925+
926+ ++ cool :: error caption
927+ |* [cyt=trap hoc=(bolt)]
928+ ?. ?=(%2 -.q.hoc) hoc
929+ [p.hoc [%2 *cyt p.q.hoc]]
930+
931+If an error occurred in computing `hoc`, we put the bunt of `cyt` onto
932+the stack trace. Thus, `cyt` is not evaluated at all unless an error
933+occurred.
934+
935+Next in `++wilt`, we load the information about the filesystem node
936+referenced by the hoop with `++lend`.
937+
938+ ++ lend :: load arch
939+ |= [cof=cafe bem=beam]
940+ ^- (bolt arch)
941+ =+ von=(ska %cy (tope bem))
942+ ?~ von [p=cof q=[%1 [bem ~] ~ ~]]
943+ (fine cof ((hard arch) (need u.von)))
944+
945+This is a simple call to the namespace. If the resource does not yet
946+exist, we block on it by producing a `%1` bolt. Otherwise, we cast it to
947+an arch and produce this.
948+
949+Continuing in `++wilt`, we examine the produced arch. If the referenced
950+filesystem node has a `hoon` child node, then we've found the required
951+source, so we parse it with `++fade`. Recall that we referred earlier to
952+`++fade`. The salient point there is that it takes a beam, reads in the
953+hook file there, and parses it into a hood file with `++fair`.
954+
955+Now, we simply recurse on `++apex` to compile the new hood. Note that,
956+while we do clear the `boy` list, we do not clear the other lists. Thus,
957+we are accumulating all the structures and libraries referenced in all
958+the referenced hook files in one group, which we will put at the top of
959+the product.
960+
961+After this, we put the new list of body twigs into a `=~`, push this
962+onto our old list of body twigs, and produce the result.
963+
964+If there is no hoon file here, then we descend into each of our children
965+until we find a hoon file. First, we produce a list of all our children
966+whose names are terms with `++lark`.
967+
968+ ++ lark :: filter arch names
969+ |= [wox=$+(span (unit ,@)) arc=arch]
970+ ^- (map ,@ span)
971+ %- ~(gas by *(map ,@ span))
972+ =| rac=(list (pair ,@ span))
973+ |- ^+ rac
974+ ?~ r.arc rac
975+ =. rac $(r.arc l.r.arc, rac $(r.arc r.r.arc))
976+ =+ gib=(wox p.n.r.arc)
977+ ?~(gib rac [[u.gib p.n.r.arc] rac])
978+
979+We traverse the children map of `arc` to filter out those children whose
980+names aren't accepted by `wox` and produce a map from the product of
981+`wox` to the original name. `++lark` is used in many cases to parse
982+names into other types, like numbers or dates, ignoring those which do
983+not fit the format. In `++wilt`, though, we simply want to filter out
984+those children whose names are not terms.
985+
986+Next, we will produce a map from terms to feet. Each of these feet will
987+be placed in a core named by the child name, and it will contain arms
988+according to its children. Thus, if the indirect hoop references
989+`/path`, then to access the twig defined in `/path/to/twig/hoon`, our
990+body must refer to `twig:to`.
991+
992+If there are no more children, then we are done, so we produce our
993+current context.
994+
995+Else, we recurse into the left and right sides of our map. Finally, we
996+process our current entry in the map. We first recurse by calling
997+`++wilt` one level down. Thus, in the previous example, the first time
998+we get to this point we are processing `/path`, so we recurse on
999+`++wilt` with path `/path/to`. We also remove our current body from the
1000+recursion, so that we may add it back in later the way we want to.
1001+
1002+After recursing, we push the new body onto our map, keyed by its name.
1003+We also produce the new context so that all external structures,
1004+libraries, and resources are collected into the same place.
1005+
1006+Finally, we have a map of names to feet. If this map is empty, then
1007+there were no twigs at the requested path, so we give an error with
1008+`++flaw`.
1009+
1010+If the map is nonempty, then we finally produce our context with with
1011+one thing pushed onto the front: a core made out of the map we just
1012+produced.
1013+
1014+This concludes our discussion of `++wilt` and `++body`. Thus, it remains
1015+in `++apex` to discuss `++neck` and `++head`.
1016+
1017+ ++ neck :: consume libraries
1018+ |= [cof=cafe bir=(list hoof)]
1019+ ^- (bolt ,_..neck)
1020+ ?~ bir (fine cof ..neck)
1021+ ?: (~(has in zeg) p.i.bir)
1022+ (flaw cof [%leaf "circular library dependency: {<i.bir>}"]~)
1023+ =+ gez=(~(put in zeg) p.i.bir)
1024+ =+ byf=(~(get by bil) p.i.bir)
1025+ ?^ byf
1026+ ?. =(`hoof`i.bir `hoof`p.u.byf)
1027+ (flaw cof [%leaf "library mismatch: {<~[p.u.byf i.bir]>}"]~)
1028+ $(bir t.bir)
1029+ =+ bem=(hone %core %lib i.bir)
1030+ %+ cope (fade cof %hook bem)
1031+ |= [cof=cafe hyd=hood]
1032+ %+ cope (apex(zeg gez, hol |, boy ~) cof hyd)
1033+ |= [cof=cafe sel=_..neck]
1034+ =. ..neck
1035+ %= sel
1036+ zeg zeg
1037+ hol hol
1038+ lot [p.i.bir lot]
1039+ bil (~(put by bil) p.i.bir [i.bir [%tssg (flop boy.sel)]])
1040+ ==
1041+ ^^$(cof cof, bir t.bir)
1042+
1043+Here, we're going to consume the list of libraries and place them in
1044+`bil`. If there are no more libraries, we're done, so we just produce
1045+our current context.
1046+
1047+Otherwise, we check to see if the next library in the list is in `zeg`.
1048+If so, then this library is one of the libraries that we're already in
1049+the middle of compiling. There is a circular dependency, so we fail.
1050+
1051+Otherwise, we let `gez` be `zeg` plus the current library so that while
1052+compiling the dependencies of this library we don't later create a
1053+circular dependency. We check next to see if this library is alredy in
1054+`bil`. If so, then we have already included this library earlier, so we
1055+check to see if this is the same version of the library as we included
1056+earlier. If so, we skip it. Else, we fail since we can't include two
1057+different versions of a library. We really should allow for newer
1058+versions of a library since in kelvin versioning we assume backwards
1059+compatibility, but for now we require an exact match.
1060+
1061+If we haven't already included this library, then we're going to do
1062+that. First, we get the location of the library with `++hone`.
1063+
1064+ ++ hone :: plant hoof
1065+ |= [for=@tas way=@tas huf=hoof]
1066+ ^- beam
1067+ ?~ q.huf
1068+ how(s ~[for p.huf way])
1069+ [[q.u.q.huf %main p.u.q.huf] ~[for p.huf way]]
1070+
1071+If we haven't specified the version of the library, we use the current
1072+ship, desk, and case. Otherwise, we use the given ship and case on desk
1073+`%main`. In either case, the path is `/way/p.huf/for`. In the case of
1074+`++neck`, this means `/lib/core/[library name]`.
1075+
1076+In `++neck`, we next compile the hook file at that location with
1077+`++fade`. Again, we will delay the discussion of `++fade`, noting only
1078+that it takes a beam and parses the hook file there into a hood.
1079+
1080+We recurse on this to compile the library. During the compilation, we
1081+let `zeg` be `gez` to avoid circular dependencies, we let `hol` be false
1082+since we don't allow horns in libraries, and we let `boy` be null so
1083+that we can isolate the new body twigs.
1084+
1085+Next, we reintegrate the new data into our context. We use the context
1086+created by the recursion with four changes. First, we reset `zeg` to our
1087+old `zeg`. Second, we reset `hol` to our old `hol`. Third, we put the
1088+name of our library onto the stack of libraries. This means all of a
1089+libraries dependencies will be earlier in `lot` than the library itself,
1090+making `lot` a topological ordering on the dependency graph. Fourth, we
1091+put in `bil` the library hoof and body (with all body twigs collected in
1092+a `=~`), keyed by the library name.
1093+
1094+Finally, we recurse, processing the next library in our list.
1095+
1096+To complete our disucssion of `++apex`, we must process our structures.
1097+
1098+ ++ head :: consume structures
1099+ |= [cof=cafe bir=(list hoot)]
1100+ |- ^- (bolt ,_..head)
1101+ ?~ bir
1102+ (fine cof ..head)
1103+ ?: (~(has in zog) p.q.i.bir)
1104+ (flaw cof [%leaf "circular structure dependency: {<i.bir>}"]~)
1105+ =+ goz=(~(put in zog) p.q.i.bir)
1106+ =+ byf=(~(get by rop) p.q.i.bir)
1107+ ?^ byf
1108+ ?. =(`hoof`q.i.bir `hoof`p.u.byf)
1109+ (flaw cof [%leaf "structure mismatch: {<~[p.u.byf q.i.bir]>}"]~)
1110+ $(bir t.bir)
1111+ =+ bem=(hone ?:(p.i.bir %gate %core) %sur q.i.bir)
1112+ %+ cope (fade cof %hook bem)
1113+ |= [cof=cafe hyd=hood]
1114+ %+ cope (apex(zog goz, hol |, boy ~) cof hyd)
1115+ |= [cof=cafe sel=_..head]
1116+ ?. =(bil bil.sel)
1117+ (flaw cof [%leaf "structures cannot include libraries: {<i.bir>}"]~)
1118+ =. ..head
1119+ %= sel
1120+ boy ?: p.i.bir
1121+ boy
1122+ (welp boy [[[%cnzy p.q.i.bir] [%$ 1]] ~])
1123+ zog zog
1124+ hol hol
1125+ rop %+ ~(put by (~(uni by rop) rop.sel))
1126+ p.q.i.bir
1127+ [q.i.bir [%tssg (flop boy.sel)]]
1128+ ==
1129+ ^^$(cof cof, bir t.bir)
1130+
1131+The processing of our structures is very similar to that of our
1132+libraries. For clarity, we'll use many of the same phrases in describing
1133+the parallel natures. First, we check to see if there are more
1134+structures to process. If not, we're done, so we produce our context.
1135+
1136+Otherwise, we let `goz` be `zog` plus the current structure so that
1137+while compiling the dependencies of this structure we don't later create
1138+a circular dependency. We check next to see if this structure is alredy
1139+in `rop`. If so, then we have already included this structure earlier,
1140+so we check to see if this is the same version of the structure as we
1141+included earlier. If so, we skip it. Else, we fail since we can't
1142+include two different versions of a structure.
1143+
1144+If we haven't loaded this structure, then we call `++hone` to get the
1145+beam where the file structure should be. If the loobean in the hoot is
1146+true, then we're looking for a gate; otherwise, we're looking for a
1147+core. We parse this file with `++fade`.
1148+
1149+Now, we recurse on this to compile the structure. During the recursion,
1150+there we have threee changes. Frist, we let `zog` be `goz` so that we
1151+don't create a circular dependency. Second, we let `hol` be false since
1152+we do not allow horns in structures. Third, we let `boy` be null so that
1153+we can isolate the new body twigs.
1154+
1155+Next, we reintegrate the new data into our context. We use the context
1156+cretaed by the recursion with four changes. First, if we're including a
1157+gate structure, then we reset the body to its original body. Else we put
1158+on the top of our list of body twigs what is essentially a
1159+`=+ structure-name` to take off the face of the structure. Second, we
1160+reset `zog` to our old `zog`. Third, we reset `hol` to our old `hol`.
1161+Finally, we put in `rop` the structure hoof and body (with all body
1162+twiggs collected in a `=~`), keyed by the structure name.
1163+
1164+Finally, we recurse, processing the next structure in our list.
1165+
1166+This concludes our discussion of `++apex`.
1167+
1168+ ++ abut :: generate
1169+ |= [cof=cafe hyd=hood]
1170+ ^- (bolt vase)
1171+ %+ cope (apex cof hyd)
1172+ |= [cof=cafe sel=_..abut]
1173+ =. ..abut sel
1174+ %+ cope (maim cof pit able)
1175+ |= [cof=cafe bax=vase]
1176+ %+ cope (chap cof bax [%fan fan.hyd])
1177+ |= [cof=cafe gox=vase]
1178+ %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
1179+ |= [cof=cafe fin=vase]
1180+ (fine cof fin)
1181+
1182+Returning to `++abut`, we have now processed the structures, libraries
1183+and body twigs. Next, we slap our preamble (structures and libraries)
1184+against zuse. First, we construct our preamble in `++able`.
1185+
1186+ ++ able :: assemble preamble
1187+ ^- twig
1188+ :+ %tsgr
1189+ ?:(=(~ rop) [%$ 1] [%brcn (~(run by rop) |=([* a=twig] [%ash a]))])
1190+ [%tssg (turn (flop lot) |=(a=term q:(need (~(get by bil) a))))]
1191+
1192+We first put the structures in `rop` into a single `|%` at the top and
1193+`=>` it onto a `=~` of our libraries, in the reverse order that they
1194+appear in `lot`. Thus, the structures are in a single core while the
1195+libraries are in consecutive cores.
1196+
1197+We slap the preamble against zuse with `++maim`.
1198+
1199+ ++ maim :: slap
1200+ |= [cof=cafe vax=vase gen=twig]
1201+ ^- (bolt vase)
1202+ %+ (clef %slap) (fine cof vax gen)
1203+ |= [cof=cafe vax=vase gen=twig]
1204+ =+ puz=(mule |.((~(mint ut p.vax) [%noun gen])))
1205+ ?- -.puz
1206+ | (flaw cof p.puz)
1207+ & %+ (coup cof) (mock [q.vax q.p.puz] (mole ska))
1208+ |= val=*
1209+ `vase`[p.p.puz val]
1210+ ==
1211+
1212+Here we start to get into ford's caching system. We wrap our computation
1213+in a call to `++clef` so that we only actually compute it if the result
1214+is not already in our cache. First we'll discuss the computation, then
1215+we'll discuss the caching system.
1216+
1217+We call `++mule` with a call to `++mint:ut` on the type of our subject
1218+vase against the given twig. In other words, we're compiling the twig
1219+with against the subject type in the given subject vase.
1220+
1221+If compilation fails, then we produce an error bolt with the produced
1222+stack trace. Otherwise, we run the produced nock with `++mock` and our
1223+sky function. We convert the produced toon to a bolt with `++coup` and
1224+use the type from `puz` combined with the value from `mock` to produce
1225+our vase.
1226+
1227+If this process seems harder than just calling `++slap`, it's because it
1228+is. We have two requirements that `++slap` doesn't satisfy. First, we
1229+want the to use an explicit sky function for use with `.^`. With
1230+`++slap`, you get whatever sky function is available in the calling
1231+context, which in ford is none. Second, we want to explicitly handle the
1232+stack trace on failure. `++slap` would cause crash on failure.
1233+
1234+We haven't yet discussed either `++clef` or `++coup`. We'll start with
1235+`++coup` to finish the discussion of the computation.
1236+
1237+\``++ coup :: toon to bolt |= cof=cafe |* [ton=toon fun=$+(* *)] :- p=cof ^= q ?- -.ton %2 [%2 p=p.ton] %0 [%0 p=*(set beam) q=(fun p.ton)] %1 ~& [%coup-need ((list path) p.ton)] =- ?- -.faw & [%1 p=(sa (turn p.faw |=(a=beam [a *(list tank)])))] | [%2 p=p.faw] == ^= faw |- ^- (each (list beam) (list tank)) ?~ p.ton [%& ~] =+ nex=$(p.ton t.p.ton) =+ pax=(path i.p.ton) ?~ pax [%| (smyt pax) ?:(?=(& -.nex) ~ p.nex)] =+ zis=(tome t.pax) ?~ zis [%| (smyt pax) ?:(?=(& -.nex) ~ p.nex)] ?- -.nex & [%& u.zis p.nex] | nex == ==`
1238+
1239+Recall that a toon is either a `%0` value, a `%1` block, or a `%2`
1240+failure. Converting a `%2` toon failure into a `%2` bolt failure is
1241+trivial. Converting a `%0` toon value into a `%0` bolt value is easy
1242+since we assume there were no dependencies. Converting the blocks is
1243+rather more difficult.
1244+
1245+To compute `faw`, we recurse through the list of paths in the `%1` toon.
1246+At each one, we make sure with `++tome` that it is, in fact, a beam. If
1247+so, then we check to see if the later paths succeed as well. If so, we
1248+append the current path to the list of other paths. If not, we produce
1249+the error message we got from processing the rest of the paths. If this
1250+path is not a beam, then we fail, producing a list of tanks including
1251+this path and, if later paths fail too, those paths as well.
1252+
1253+If some paths were not beams, then we produce a `%2` error bolt. If all
1254+paths were correct, then we produce a `%1` blocking bolt.
1255+
1256+We will now discuss `++clef`. This is where the cache magic happens.
1257+
1258+ ++ clef :: cache a result
1259+ |* sem=*
1260+ |* [hoc=(bolt) fun=(burg)]
1261+ ?- -.q.hoc
1262+ %2 hoc
1263+ %1 hoc
1264+ %0
1265+ =^ cux p.hoc ((calk p.hoc) sem q.q.hoc)
1266+ ?~ cux
1267+ =+ nuf=(cope hoc fun)
1268+ ?- -.q.nuf
1269+ %2 nuf
1270+ %1 nuf
1271+ %0
1272+ :- p=(came p.nuf `calx`[sem `calm`[now p.q.nuf] q.q.hoc q.q.nuf])
1273+ q=q.nuf
1274+ ==
1275+ [p=p.hoc q=[%0 p=p.q.hoc q=((calf sem) u.cux)]]
1276+ ==
1277+
1278+If the value is already an error or a block, we just pass that through.
1279+Otherwise, we look up the request in the cache with `++calk`.
1280+
1281+ ++ calk :: cache lookup
1282+ |= a=cafe ::
1283+ |= [b=@tas c=*] ::
1284+ ^- [(unit calx) cafe] ::
1285+ =+ d=(~(get by q.a) [b c]) ::
1286+ ?~ d [~ a] ::
1287+ [d a(p (~(put in p.a) u.d))] ::
1288+
1289+When looking up something in the cache, we mark it if we find it. This
1290+way, we have in our cache the set of all cache entries that have been
1291+referenced. While we do not at present do anything with this data, it
1292+should be used to clear out old and unused entries in the cache.
1293+
1294+Moving on in `++clef`, we check to see if we actually found anything. If
1295+we didn't find a cache entry, then we run the computation in `fun`, and
1296+examine its result. If it produced a `%2` error or `%1` block bolt, we
1297+just pass that through. Otherwise, we produce both the value and an
1298+updated cache with this new entry. We add the entry with `++came`.
1299+
1300+ ++ came ::
1301+ |= [a=cafe b=calx] :: cache install
1302+ ^- cafe ::
1303+ a(q (~(put by q.a) [-.b q.b] b)) ::
1304+
1305+We key cache entries by the type of computation (`-:calx`) and the
1306+inputs to the computation (`q:calc`). This just puts the cache line in
1307+the cache at the correct key.
1308+
1309+Back in `++clef`, if we did find a cache entry, then we just produce the
1310+value at that cache line. We convert the cache line into a value with
1311+`++calf`.
1312+
1313+ ++ calf :: reduce calx
1314+ |* sem=* :: a typesystem hack
1315+ |= cax=calx
1316+ ?+ sem !!
1317+ %hood ?>(?=(%hood -.cax) r.cax)
1318+ %slap ?>(?=(%slap -.cax) r.cax)
1319+ %slam ?>(?=(%slam -.cax) r.cax)
1320+ ==
1321+
1322+This is simply a typesystem hack. Because the `sem` is passed in through
1323+a wet gate, we know at type time which of the three cases will be
1324+chosen. Thus, the correct type of the value in the cache line gets
1325+passed through to the caller. This also depends on the fact that
1326+`++clef` is wet. The type stuff here is mathematically interesting, but
1327+the action is simple: we get the value from the cache line.
1328+
1329+This concludes our discussion of `++clef` and `++maim`.
1330+
1331+Back in `++abut`, recall that we processed the structures, libraries,
1332+and body with `++apex`. Then, we slapped our preamble (structures and
1333+libraries) against zuse with `++maim`. Next, we process our resources
1334+with `++chap`. Note that we pass in the preamble so that we may refer to
1335+anything in there in our resources.
1336+
1337+`++chap` is broken up into a different case for each horn. We'll go
1338+through them one by one.
1339+
1340+ ++ chap :: produce resources
1341+ |= [cof=cafe bax=vase hon=horn]
1342+ ^- (bolt vase)
1343+ ?- -.hon
1344+ %ape (maim cof bax p.hon)
1345+
1346+This is `/~`. We slap the twig against our context.
1347+
1348+ %arg
1349+ %+ cope (maim cof bax p.hon)
1350+ |= [cof=cafe gat=vase]
1351+ (maul cof gat !>([how arg]))
1352+
1353+This is `/$`. We slap the twig against our context, which we expect to
1354+produce a gate. We slam this gate with a sample of `how` and `arg`,
1355+which is our location and the heel (virtual path extension).
1356+
1357+`++maul` is similar to `++maim`, but it slams instead of slaps.
1358+
1359+ ++ maul :: slam
1360+ |= [cof=cafe gat=vase sam=vase]
1361+ ^- (bolt vase)
1362+ %+ (clef %slam) (fine cof gat sam)
1363+ |= [cof=cafe gat=vase sam=vase]
1364+ =+ top=(mule |.((slit p.gat p.sam)))
1365+ ?- -.top
1366+ | (flaw cof p.top)
1367+ & %+ (coup cof) (mong [q.gat q.sam] (mole ska))
1368+ |= val=*
1369+ `vase`[p.top val]
1370+ ==
1371+
1372+We cache slams exactly as we cache slaps. We use `++slit` to find the
1373+type of the product of the slam given the types of the gate and the
1374+sample.
1375+
1376+If this type fails, we produce the given stack trace as a `%2` error
1377+bolt. Otherwise, we produce the top produced above combined with the
1378+value we get from slamming the values in the vases with `++mong`.
1379+
1380+Back to `++chap`.
1381+
1382+ %day (chad cof bax %dr p.hon)
1383+
1384+This is `/|`. We call `++chad` to convert textual names to relative
1385+dates and process the next horn against each of the discovered paths.
1386+
1387+ ++ chad :: atomic list
1388+ |= [cof=cafe bax=vase doe=term hon=horn]
1389+ ^- (bolt vase)
1390+ %+ cope ((lash (slat doe)) cof how)
1391+ |= [cof=cafe yep=(map ,@ span)]
1392+ =+ ^= poy ^- (list (pair ,@ span))
1393+ %+ sort (~(tap by yep) ~)
1394+ |=([a=[@ *] b=[@ *]] (lth -.a -.b))
1395+ %+ cope
1396+ |- ^- (bolt (list (pair ,@ vase)))
1397+ ?~ poy (fine cof ~)
1398+ %+ cope $(poy t.poy)
1399+ |= [cof=cafe nex=(list (pair ,@ vase))]
1400+ %+ cope (chap(s.how [q.i.poy s.how]) cof bax hon)
1401+ |= [cof=cafe elt=vase]
1402+ (fine cof [[p.i.poy elt] nex])
1403+ |= [cof=cafe yal=(list (pair ,@ vase))]
1404+ %+ fine cof
1405+ |- ^- vase
1406+ ?~ yal [[%cube 0 [%atom %n]] 0]
1407+ (slop (slop [[%atom doe] p.i.yal] q.i.yal) $(yal t.yal))
1408+
1409+First, we call `++lash` to parse the children of the current beam and
1410+pick out those ones that are of the requested format.
1411+
1412+ ++ lash :: atomic sequence
1413+ |= wox=$+(span (unit ,@))
1414+ |= [cof=cafe bem=beam]
1415+ ^- (bolt (map ,@ span))
1416+ %+ cope (lend cof bem)
1417+ |= [cof=cafe arc=arch]
1418+ (fine cof (lark wox arc))
1419+
1420+First, we get the arch with `++lend`, as described above. We filter and
1421+parse the child names with `++lark` according to the given parser
1422+function.
1423+
1424+In `++chad`, this parser function is `(slat doe)`, which will parse a
1425+cord into an atom of the requested odor. For `%day` the odor is for
1426+relative dates.
1427+
1428+Thus, we now have a map from atoms of the given odor to the actual child
1429+names. We next turn this map into a list and sort it in increasing order
1430+by the atom.
1431+
1432+We next convert this list of pairs of atoms and spans to a list of pairs
1433+of atoms and vases. We process the given horn once at every child beam,
1434+producing the resource at that location.
1435+
1436+Finally, we convert this list of pairs of atoms and vases to a vase of a
1437+list of pairs of atoms to (well-typed) values. Each entry in the list is
1438+of type atom with the given odor combined with the type of the produced
1439+vase.
1440+
1441+Back in `++chap`, we continue parsing resources.
1442+
1443+ %dub
1444+ %+ cope $(hon q.hon)
1445+ |= [cof=cafe vax=vase]
1446+ (fine cof [[%face p.hon p.vax] q.vax])
1447+
1448+This is `/=`. We process the given horn, giving us a vase. We put as a
1449+face on the vase so that it may be referred to later by name.
1450+
1451+ %fan
1452+ %+ cope
1453+ |- ^- (bolt (list vase))
1454+ ?~ p.hon (fine cof ~)
1455+ %+ cope ^$(hon i.p.hon)
1456+ |= [cof=cafe vax=vase]
1457+ %+ cope ^$(cof cof, p.hon t.p.hon)
1458+ |= [cof=cafe tev=(list vase)]
1459+ (fine cof [vax tev])
1460+ |= [cof=cafe tev=(list vase)]
1461+ %+ fine cof
1462+ |- ^- vase
1463+ ?~ tev [[%cube 0 [%atom %n]] 0]
1464+ (slop i.tev $(tev t.tev))
1465+
1466+This is `/.`. We first process each of the child horns, producing a list
1467+of vases. This is done by just recursing on `++chap`. Then, we simply
1468+fold over this list to create a vase of the list of values.
1469+
1470+ %for $(hon q.hon, s.how (weld (flop p.hon) s.how))
1471+
1472+This is `/,`. We simply recurse on the horn with the given path welded
1473+onto our current beam.
1474+
1475+ %hub (chad cof bax %ud p.hon)
1476+
1477+This is `/@`. This is exactly like the processing of `%day` except we
1478+expect the children to be named as unsigned integers rather than
1479+relative dates. We process the horn at each of the children's locations
1480+and produce a list of pairs of absolute dates and values.
1481+
1482+ %man
1483+ |- ^- (bolt vase)
1484+ ?~ p.hon (fine cof [[%cube 0 [%atom %n]] 0])
1485+ %+ cope $(p.hon l.p.hon)
1486+ |= [cof=cafe lef=vase]
1487+ %+ cope ^$(cof cof, p.hon r.p.hon)
1488+ |= [cof=cafe rig=vase]
1489+ %+ cope ^^^$(cof cof, hon q.n.p.hon)
1490+ |= [cof=cafe vax=vase]
1491+ %+ fine cof
1492+ %+ slop
1493+ (slop [[%atom %tas] p.n.p.hon] vax)
1494+ (slop lef rig)
1495+
1496+This is `/*`. We process each of the horns in the given map by recursion
1497+through `++chap`. Once we have these vases, we create a vase of a map
1498+from the given textual names to the produced values.
1499+
1500+ %now (chad cof bax %da p.hon)
1501+
1502+This is `/&`. This is exactly like the processing of `%now` except we
1503+expect the children to be names as absolute dates rather than relative
1504+dates. We process the horn at each of the children's locations and
1505+produce a list of pairs of absolute dates and values.
1506+
1507+ %nap (chai cof bax p.hon)
1508+
1509+This is `/%`. Here, we process the horn at each of our children with
1510+`++chai`.
1511+
1512+ ++ chai :: atomic map
1513+ |= [cof=cafe bax=vase hon=horn]
1514+ ^- (bolt vase)
1515+ %+ cope (lend cof how)
1516+ |= [cof=cafe arc=arch]
1517+ %+ cope
1518+ |- ^- (bolt (map ,@ vase))
1519+ ?~ r.arc (fine cof ~)
1520+ %+ cope $(r.arc l.r.arc)
1521+ |= [cof=cafe lef=(map ,@ vase)]
1522+ %+ cope `(bolt (map ,@ vase))`^$(cof cof, r.arc r.r.arc)
1523+ |= [cof=cafe rig=(map ,@ vase)]
1524+ %+ cope (chap(s.how [p.n.r.arc s.how]) cof bax hon)
1525+ |= [cof=cafe nod=vase]
1526+ (fine cof [[p.n.r.arc nod] lef rig])
1527+ |= [cof=cafe doy=(map ,@ vase)]
1528+ %+ fine cof
1529+ |- ^- vase
1530+ ?~ doy [[%cube 0 [%atom %n]] 0]
1531+ %+ slop
1532+ (slop [[%atom %a] p.n.doy] q.n.doy)
1533+ (slop $(doy l.doy) $(doy r.doy))
1534+
1535+We get the arch at our current beam with `++lend`. Then, we process the
1536+horn at each of our children to give us a map of atoms to vases.
1537+Finally, we convert that into a vase of a map of these atoms to the
1538+values. This is very similar to `++chad` and the handling of `%man`.
1539+
1540+ %see $(hon q.hon, how p.hon)
1541+
1542+This is `/:`. We process the given horn at the given beam.
1543+
1544+ %saw
1545+ %+ cope $(hon q.hon)
1546+ |= [cof=cafe sam=vase]
1547+ %+ cope (maim cof bax p.hon)
1548+ |= [cof=cafe gat=vase]
1549+ (maul cof gat sam)
1550+
1551+This is `/;`. First, we process the given horn. Then, we slap the given
1552+twig against our context to produce (hopefully) a gate. Finally, we slam
1553+the vase we got from processing the horn against the gate.
1554+
1555+ %sic
1556+ %+ cope $(hon q.hon)
1557+ |= [cof=cafe vax=vase]
1558+ %+ cope (maim cof bax [%bctr p.hon])
1559+ |= [cof=cafe tug=vase]
1560+ ?. (~(nest ut p.tug) | p.vax)
1561+ (flaw cof [%leaf "type error: {<p.hon>} {<q.hon>}"]~)
1562+ (fine cof [p.tug q.vax])
1563+
1564+This is `/^`. First, we process the given horn. Then, we slap the the
1565+bunt of the given tile against our context. This will produce a vase
1566+with the correct type. We test to see if this type nests within the type
1567+of the vase we got from processing the horn. If so, we produce the value
1568+from the horn along with the type from the tile. Otherwise, we produce a
1569+`%2` error bolt.
1570+
1571+ %toy (cope (make cof %bake p.hon how ~) feel)
1572+ ==
1573+
1574+This is `/mark/`. Here, we simply run the `%bake` silk on the given
1575+mark, producing a cage. We convert this cage into a vase with `++feel`,
1576+which is exactly as simple as it sounds like it should be.
1577+
1578+ ++ feel |=([a=cafe b=cage] (fine a q.b)) :: cage to vase
1579+
1580+This is trivial.
1581+
1582+We will discuss later `++make` and how `%bake` is processed. Suffice it
1583+to say that baking a resource with a given mark gets the resource and
1584+converts it, if necessary, to the requested mark.
1585+
1586+This concludes our discussion of `++chap`.
1587+
1588+We return once more to `++abut`.
1589+
1590+ ++ abut :: generate
1591+ |= [cof=cafe hyd=hood]
1592+ ^- (bolt vase)
1593+ %+ cope (apex cof hyd)
1594+ |= [cof=cafe sel=_..abut]
1595+ =. ..abut sel
1596+ %+ cope (maim cof pit able)
1597+ |= [cof=cafe bax=vase]
1598+ %+ cope (chap cof bax [%fan fan.hyd])
1599+ |= [cof=cafe gox=vase]
1600+ %+ cope (maim cof (slop gox bax) [%tssg (flop boy)])
1601+ |= [cof=cafe fin=vase]
1602+ (fine cof fin)
1603+
1604+Recall that we processed our structures, libraries and body with
1605+`++apex`. We slapped our structures and libraries against zuse with
1606+`++maim`. We processed our resources with `++chap`. Now, all our body
1607+twigs are collected in a `=~` and slapped against our structures,
1608+libraries, and resources. This produces our final result.
1609+
1610+The hook file has been assembled. And there was great rejoicing.
1611+
1612+Lifecycle of a Kiss
1613+-------------------
1614+
1615+We're now going to go through a series of lifecycle descriptions. When a
1616+user of ford sends a kiss, it is one of a dozen different types of silk.
1617+We'll go through each one, tracing through the flow of control of each
1618+of these.
1619+
1620+First, though, we'll describe the common handling to all kisses.
1621+
1622+The silk in a `%exec` kiss to ford ends up in `++apex`, so we'll enter
1623+the narrative here.
1624+
1625+ ++ apex :: call
1626+ |= kus=(unit silk)
1627+ ^+ +>
1628+ ?~ kus
1629+ =+ nym=(~(get by dym.bay) hen)
1630+ ?~ nym :: XX should never
1631+ ~& [%ford-mystery hen]
1632+ +>.$
1633+ =+ tas=(need (~(get by q.tad.bay) u.nym))
1634+ amok:~(camo zo [u.nym tas])
1635+ =+ num=p.tad.bay
1636+ ?< (~(has by dym.bay) hen)
1637+ =: p.tad.bay +(p.tad.bay)
1638+ dym.bay (~(put by dym.bay) hen num)
1639+ ==
1640+ ~(exec zo [num `task`[hen u.kus 0 ~]])
1641+
1642+Recall that a `%exec` kiss actually sends a unit silk. If it's null,
1643+we're trying to cancel the request. We first look up the task number
1644+keyed by duct. If we don't find it, then we're trying to cancel a
1645+request that either was never started or has already completed. We print
1646+out `%ford-mystery` and do nothing. If we do find the task number, then
1647+we look up the task from it, call `++camo:zo` to cancel pending
1648+requests, and call `++amok:zo` to remove the task from our task lists.
1649+
1650+ ++ camo :: stop requests
1651+ ^+ .
1652+ =+ kiz=(~(tap by q.kig) *(list ,[p=@ud q=beam]))
1653+ |- ^+ +>
1654+ ?~ kiz +>
1655+ %= $
1656+ kiz t.kiz
1657+ mow :_ mow
1658+ :- hen
1659+ :^ %pass [(scot %p our) (scot %ud num) (scot %ud p.i.kiz) ~]
1660+ %c
1661+ [%warp [our p.q.i.kiz] q.q.i.kiz ~]
1662+ ==
1663+
1664+Our list of blocks is in `q.kig`, so we iterate over it, cancelling our
1665+pending requests for each block. Our requests are all to clay, so we
1666+need only to send `%warp` kisses with a null instead of a rave.
1667+
1668+ ++ amok
1669+ %_ ..zo
1670+ q.tad.bay (~(del by q.tad.bay) num)
1671+ dym.bay (~(del by dym.bay) nah)
1672+ ==
1673+
1674+We remove the task number from the map of numbers to tasks and the duct
1675+from the map of ducts to task numbers.
1676+
1677+Back in `++apex`, if we were given a silk, we need to process it. We add
1678+the task to our maps, increment the next task number, and call
1679+`++exec:zo` on the new task.
1680+
1681+ ++ exec :: execute app
1682+ ^+ ..zo
1683+ ?: !=(~ q.kig) ..zo
1684+ |- ^+ ..zo
1685+ =+ bot=(make [~ jav.bay] kas)
1686+ =. ..exec (dash p.bot)
1687+ ?- -.q.bot
1688+ %0 amok:(expo [%made %& p.q.bot q.q.bot])
1689+ %2 amok:(expo [%made %| p.q.bot])
1690+ %1 =+ zuk=(~(tap by p.q.bot) ~)
1691+ =< abet
1692+ |- ^+ ..exec
1693+ ?~ zuk ..exec
1694+ =+ foo=`_..exec`(camp %x `beam`p.i.zuk)
1695+ $(zuk t.zuk, ..exec foo)
1696+ ==
1697+
1698+If we're still blocked on something in `q.kig`, we don't do anything.
1699+
1700+Otherwise, we try to process the silk with `++make`. `++make` handles
1701+each individual request and will be the entire focus of the remainder of
1702+this doc after this section. It produces a bolt of a cage.
1703+
1704+We put the new cache in our state with `++dash`.
1705+
1706+ ++ dash :: process cache
1707+ |= cof=cafe
1708+ ^+ +>
1709+ %_(+> jav.bay q.cof)
1710+
1711+The cache is put in the baby so that it gets stored across calls to
1712+ford.
1713+
1714+In `++exec`, we process the bolt in three different ways according to
1715+the type of bolt produced. If we produced a `%0` value bolt, we use
1716+`++expo` to give the produced value and set of dependencies as a `%made`
1717+gift, and we remove ourselves from the task list with `++amok`.
1718+
1719+ ++ expo :: return gift
1720+ |= gef=gift
1721+ %_(+> mow :_(mow [hen %give gef]))
1722+
1723+We simply push the gift onto our list of moves.
1724+
1725+In `++exec`, if we produced a `%2` error bolt, we produce a `%made` gift
1726+with the stack trace.
1727+
1728+If we produced a `%1` block bolt, we iterate through each of the blocks
1729+and call `++camp` to produce a clay request for the resource.
1730+
1731+ ++ camp :: request a file
1732+ |= [ren=care bem=beam]
1733+ ^+ +>
1734+ %= +>
1735+ kig [+(p.kig) (~(put by q.kig) p.kig bem)]
1736+ mow :_ mow
1737+ :- hen
1738+ :^ %pass [(scot %p our) (scot %ud num) (scot %ud p.kig) ~]
1739+ %c
1740+ [%warp [our p.bem] q.bem [~ %& %x r.bem s.bem]]
1741+ ==
1742+
1743+We put the resource in our block list in `q.kig` so that we save the
1744+fact that we're blocked. We then produce the `%warp` request to clay for
1745+the resource. Our request path has the format
1746+\`/[our-ship]/[task-number]/[block-number]'.
1747+
1748+We'll now describe how each of the individual silks are processed in
1749+`++make`.
1750+
1751+Lifecycle of a Cell
1752+-------------------
1753+
1754+ ^
1755+ %. [cof p.kas q.kas]
1756+ ;~ cope
1757+ ;~ coax
1758+ |=([cof=cafe p=silk q=silk] ^$(cof cof, kas p.kas))
1759+ |=([cof=cafe p=silk q=silk] ^$(cof cof, kas q.kas))
1760+ ==
1761+ ::
1762+ |= [cof=cafe bor=cage heg=cage] ^- (bolt cage)
1763+ [p=cof q=[%0 ~ [%$ (slop q.bor q.heg)]]]
1764+ ==
1765+
1766+Silks autocons. The product of a cell of silks is a cell of the products
1767+of the silks, so we evaluate the two silks in parallel with `++coax` and
1768+slop together the results in a cell vase. We mark the product with `%$`,
1769+which means we know no more mark information than that it is a noun.
1770+
1771+ ++ coax :: bolt across
1772+ |* [hoc=(bolt) fun=(burg)]
1773+ ?- -.q.hoc
1774+ %0 =+ nuf=$:fun(..+<- p.hoc)
1775+ :- p=p.nuf
1776+ ^= q
1777+ ?- -.q.nuf
1778+ %0 [%0 p=(grom p.q.hoc p.q.nuf) q=[q.q.hoc q.q.nuf]]
1779+ %1 q.nuf
1780+ %2 q.nuf
1781+ ==
1782+ %1 =+ nuf=$:fun(..+<- p.hoc)
1783+ :- p=p.nuf
1784+ ^= q
1785+ ?- -.q.nuf
1786+ %0 q.hoc
1787+ %1 [%1 p=(grom p.q.nuf p.q.hoc)]
1788+ %2 q.nuf
1789+ ==
1790+ %2 hoc
1791+ ==
1792+
1793+If the first bolt is a value, we evaluate the burg to get the next bolt.
1794+If that also produces a value, we merge the dependency sets and produce
1795+a cell of the two values. Otherwise, we produce the block or error of
1796+the second bolt.
1797+
1798+If the first bolt is a block, we evaluate the burg to get the next bolt.
1799+If that produces a value, we just produce the block. If it produces a
1800+block, we merge the two block sets. If it produces an error, we produce
1801+that error.
1802+
1803+If the first bolt is already an error, we just pass that through.
1804+
1805+Note that `++coax` (and, indeed, `++cope`) is reasonable to use with
1806+`;~`.
1807+
1808+Lifecycle of a `%bake`
1809+----------------------
1810+
1811+ %bake
1812+ %+ cool |.(leaf/"ford: bake {<p.kas>} {<(tope q.kas)>}")
1813+ %+ cope (lima cof p.kas q.kas r.kas)
1814+ |= [cof=cafe vux=(unit vase)]
1815+ ?~ vux
1816+ (flaw cof (smyt (tope q.kas)) ~)
1817+ (fine cof [p.kas u.vux])
1818+
1819+This is one of the most critical silks. We are going to functionally
1820+produce the hook file at the given beam with the given heel. The result
1821+will be of the correct mark, even if we need to run conversion
1822+functions. The functionality is encapsulated in `++lime`. If it produces
1823+null, then we produce an error. Otherwise, we take the vase produced and
1824+give it the correct mark.
1825+
1826+ ++ lima :: load at depth
1827+ |= [cof=cafe for=mark bem=beam arg=heel]
1828+ ^- (bolt (unit vase))
1829+ %+ cope (lend cof bem)
1830+ |= [cof=cafe arc=arch]
1831+ ^- (bolt (unit vase))
1832+ ?: (~(has by r.arc) for)
1833+ (lace cof for bem(s [for s.bem]) arg)
1834+ =+ haz=(turn (~(tap by r.arc) ~) |=([a=@tas b=~] a))
1835+ ?~ haz (fine cof ~)
1836+ %+ cope (lion cof for -.bem haz)
1837+ |= [cof=cafe wuy=(unit (list ,@tas))]
1838+ ?~ wuy (fine cof ~)
1839+ ?> ?=(^ u.wuy)
1840+ %+ cope (make cof %bake i.u.wuy bem arg)
1841+ |= [cof=cafe hoc=cage]
1842+ %+ cope (lope cof i.u.wuy t.u.wuy -.bem q.hoc)
1843+ |= [cof=cafe vax=vase]
1844+ (fine cof ~ vax)
1845+
1846+First, we load the arch at the given beam with `++lend`. If we have a
1847+child named the mark, our job is straightforward, so we go ahead and
1848+load that with `++lace`.
1849+
1850+Otherwise, we iterate through our children. If we have no children, we
1851+produce null, signifying that we didn't find any way to convert to the
1852+requested mark. Otherwise, we call `++lion` to find a translation path
1853+from one of the available marks into the target mark. We recursively
1854+bake the child that has a path to the target mark, and then we call
1855+`++lope` to translate this mark into the target mark.
1856+
1857+We'll first discuss the direct case of when one of our children is of
1858+the correct mark.
1859+
1860+ ++ lace :: load and check
1861+ |= [cof=cafe for=mark bem=beam arg=heel]
1862+ ^- (bolt (unit vase))
1863+ =+ bek=`beak`[p.bem q.bem r.bem]
1864+ %+ cope (lend cof bem)
1865+ |= [cof=cafe arc=arch]
1866+ ?^ q.arc
1867+ (cope (cope (liar cof bem) (lake for bek)) fest)
1868+ ?: (~(has by r.arc) %hook)
1869+ %+ cope (fade cof %hook bem)
1870+ |= [cof=cafe hyd=hood]
1871+ (cope (cope (abut:(meow bem arg) cof hyd) (lake for bek)) fest)
1872+ (fine cof ~)
1873+
1874+First, we get the arch at the given beam with `++lend`. If this is a
1875+file, we load the file with `++liar` and coerce the type with `++lake`.
1876+Otherwise, we check to see if we have a hook file here. If so, we parse
1877+it with `++fade`, compile it with `++abut:meow`, and coerce the type
1878+with `++lake`.
1879+
1880+Otherwise, there is no way to translate this, so we produce null.
1881+
1882+`++fest` is one line, so we'll get that one out of the way first.
1883+
1884+ ++ fest |*([a=cafe b=*] (fine a [~ u=b])) :: bolt to unit
1885+
1886+This is just `++some` for bolts.
1887+
1888+We've delayed the discussion of `++fade` far too many times. It's not
1889+complicated, we just wanted to spare a premature discussion of `++make`
1890+and the `%bake` silk. We 're now able to discuss everything in `++fade`
1891+with ease.
1892+
1893+ ++ fade :: compile to hood
1894+ |= [cof=cafe for=mark bem=beam]
1895+ ^- (bolt hood)
1896+ %+ cool |.(leaf/"ford: fade {<[(tope bem)]>}")
1897+ %+ cope (make cof [%bake for bem ~])
1898+ |= [cof=cafe cay=cage]
1899+ %+ (clef %hood) (fine cof bem cay)
1900+ ^- (burg (pair beam cage) hood)
1901+ |= [cof=cafe bum=beam cay=cage]
1902+ =+ rul=(fair bem)
1903+ ?. ?=(@ q.q.cay)
1904+ (flaw cof ~)
1905+ =+ vex=((full rul) [[1 1] (trip q.q.cay)])
1906+ ?~ q.vex
1907+ (flaw cof [%leaf "syntax error: {<p.p.vex>} {<q.p.vex>}"] ~)
1908+ (fine cof p.u.q.vex)
1909+
1910+We first push a line onto a stack trace to say that we're parsing into a
1911+hood file.
1912+
1913+We bake the given beam with the given mark and no heel. Recall that
1914+baking gate, core, door, hoon, and hook files produces simply an atom of
1915+the text. We check to make sure that our value is an atom, failing
1916+otherwise.
1917+
1918+The parsing step is run within `++clef` so that the result is cached. We
1919+call `++fair` with the current beam to generate the parsing rule, and we
1920+parse the file. If parsing fails, we fail giving a syntax error with the
1921+line and column number. Otherwise, we produce the value.
1922+
1923+ ++ liar :: load vase
1924+ |= [cof=cafe bem=beam]
1925+ ^- (bolt vase)
1926+ =+ von=(ska %cx (tope bem))
1927+ ?~ von
1928+ [p=*cafe q=[%1 [[bem ~] ~ ~]]]
1929+ ?~ u.von
1930+ (flaw cof (smyt (tope bem)) ~)
1931+ (fine cof ?^(u.u.von [%cell %noun %noun] [%atom %$]) u.u.von)
1932+
1933+This takes a beam and loads the file at that location. If our sky
1934+function produces null, that means the resource is currently
1935+unavailable, so we block on it. If it produces `[~ ~]`, that means our
1936+resource is permanently unavailable, so we produce an error. Otherwise,
1937+we produce the value there with a type of either a cell of two nouns or
1938+an atom, depending on whether the value is a cell or not.
1939+
1940+Back in `++lima`, recall that we call `++lion` to find a translation
1941+path.
1942+
1943+ ++ lion :: translation search
1944+ |= [cof=cafe too=@tas bek=beak fro=(list ,@tas)]
1945+ ^- (bolt (unit (list ,@tas)))
1946+ =| war=(set ,@tas)
1947+ =< -:(apex (fine cof fro))
1948+ |%
1949+ ++ apex
1950+ |= rof=(bolt (list ,@tas))
1951+ ^- [(bolt (unit (list ,@tas))) _+>]
1952+ ?. ?=(%0 -.q.rof) [rof +>.$]
1953+ ?~ q.q.rof
1954+ [[p.rof [%0 p.q.rof ~]] +>.$]
1955+ =^ orf +>.$ (apse cof i.q.q.rof)
1956+ ?. ?=(%0 -.q.orf)
1957+ [orf +>.$]
1958+ ?~ q.q.orf
1959+ $(cof p.orf, q.q.rof t.q.q.rof)
1960+ [[p.orf [%0 (grom p.q.rof p.q.orf) q.q.orf]] +>.$]
1961+ ::
1962+ ++ apse
1963+ |= [cof=cafe for=@tas]
1964+ ^- [(bolt (unit (list ,@tas))) _+>]
1965+ ?: =(for too)
1966+ [(fine cof [~ too ~]) +>.$]
1967+ ?: (~(has in war) for) [(fine cof ~) +>]
1968+ =. war (~(put in war) for)
1969+ =^ hoc +>.$ (apex (lily cof for bek))
1970+ :_ +>.$
1971+ %+ cope hoc
1972+ |= [cof=cafe ked=(unit (list ,@tas))]
1973+ (fine cof ?~(ked ~ [~ for u.ked]))
1974+ --
1975+
1976+At a high level, we have `++apex` and `++apse`. `++apex` takes a list of
1977+marks to try in succession until we find one that can be translated into
1978+the target mark. On each one, it calls `++apse`, which takes a single
1979+mark and tries to find a translation path from this mark to the target.
1980+To do this, it sees which marks we know how to directly translate to,
1981+and calls `++apex` on this list. The result of this mututal recursion is
1982+a depth-first search of the translation graph to find the target mark.
1983+Since the translation graph is not necessarily acyclic, we maintain a
1984+set of marks that we've already tried.
1985+
1986+We kick off our search in `++apex`, starting with the given initial list
1987+of marks that we know how to get to.
1988+
1989+If `++apex` is called with a bolt other than a `%0` value bolt, we
1990+simply produce it. Otherwise, we check to see if the list of available
1991+marks to investigate is null. If so, then we're done, so we produce a
1992+`%0` bolt with a null list of accessible marks.
1993+
1994+Otherwise, we process this next mark with `++apse`, which will produce a
1995+possible list of marks from this one to the target mark. If it fails to
1996+produce a `%0` bolt, we just produce that. Otherwise, if it produces
1997+null, we can't get to our target through this mark, so we move on to the
1998+next one.
1999+
2000+If it doesn't produce null, then we have successfully found a
2001+translation path, so we produce it.
2002+
2003+In `++apse`, we first test to see if we've arrived at the target path.
2004+If so, we're done, so we produce a list including just ourself.
2005+Otherwise, we check to see if we've already tried this mark. If so, we
2006+know we can't succeed here, so we produce null. Otherwise, we put
2007+ourselves in the set of already-tried marks, and we move on.
2008+
2009+We call `++lily` to get the list of marks we can translate this one
2010+into.
2011+
2012+ ++ lily :: translation targets
2013+ |= [cof=cafe for=mark bek=beak]
2014+ ^- (bolt (list ,@tas))
2015+ =+ raf=(fang cof for bek)
2016+ ?: =(%2 -.q.raf) (fine p.raf ~)
2017+ %+ cope raf
2018+ |= [cof=cafe vax=vase]
2019+ %+ fine cof
2020+ %+ weld
2021+ ^- (list ,@tas)
2022+ ?. (slab %garb p.vax) ~
2023+ =+ gav=((soft (list ,@tas)) q:(slap vax [%cnzy %garb]))
2024+ ?~(gav ~ u.gav)
2025+ ?. (slab %grow p.vax) ~
2026+ =+ gow=(slap vax [%cnzy %grow])
2027+ (sloe p.gow)
2028+
2029+We call `++fang` to get the mark definition door. This is documented
2030+under `%vale`. If getting the mark fails, we produce null because we
2031+can't translate a non-existent mark into anything.
2032+
2033+Otherwise, we examine the door. The door may have a `++garb`, which is
2034+simply a list of marks which know how to translate from the current one.
2035+There must be a corresponding `++grab` in the definition of the other
2036+mark, though we don't check that here.
2037+
2038+The door may also have a `++grow`, which defines how to translate this
2039+mark into another one. Each arm in `++grow` is the name of a mark we can
2040+translate into. The call to `++sloe` simply produces a list of arm names
2041+in `++grow`.
2042+
2043+Back in `++apse:lion`, we take the list of translation targets we just
2044+found and call `++apex` on it. If we got back a null, we produce a null;
2045+otherwise, we produce the list of marks we got back plus the current
2046+mark.
2047+
2048+This concludes our discussion of `++lion`.
2049+
2050+The final piece of `++lima` is `++lope`, which performs the actual
2051+translation along the path we just computed.
2052+
2053+ ++ lope :: translation pipe
2054+ |= [cof=cafe for=mark yaw=(list mark) bek=beak vax=vase]
2055+ ^- (bolt vase)
2056+ ?~ yaw (fine cof vax)
2057+ %+ cope (link cof i.yaw for bek vax)
2058+ |= [cof=cafe yed=vase]
2059+ ^$(cof cof, for i.yaw, yaw t.yaw, vax yed)
2060+
2061+We iterate through our list, calling `++link` on every adjacent pair of
2062+marks, translating from one mark to the next until we finish the list of
2063+marks. A call to `++link` is equivalent to a `%cast` silk, so we
2064+document it there. After we've called performed every step in the
2065+translation pipeline, we're done.
2066+
2067+Lifecycle of a `%boil`
2068+----------------------
2069+
2070+ %boil
2071+ %+ cool |.(leaf/"ford: boil {<p.kas>} {<(tope q.kas)>} {<r.kas>}")
2072+ %+ cope (lamp cof q.kas)
2073+ |= [cof=cafe bem=beam]
2074+ %+ cope (lime cof p.kas bem r.kas)
2075+ |= [cof=cafe vax=vase]
2076+ (fine cof `cage`[p.kas vax])
2077+
2078+At a high level, we try to bake at the given beam, and if it fails, we
2079+go up a level and try again. This is the usual semantics of ford, and
2080+this should nearly always be preferred over directly baking.
2081+
2082+First, we normalize the version case to a number with `++lamp`. This
2083+allows caching to be based on revision number rather than something more
2084+ephemeral like a particular time.
2085+
2086+ ++ lamp :: normalize version
2087+ |= [cof=cafe bem=beam]
2088+ ^- (bolt beam)
2089+ =+ von=(ska %cw (tope bem(s ~)))
2090+ ?~ von [p=cof q=[%1 [bem ~] ~ ~]]
2091+ (fine cof bem(r [%ud ((hard ,@) (need u.von))]))
2092+
2093+We call the sky function with `%cw`, asking clay for the revision number
2094+at this case. If the case refers to a revision that isn't there yet, we
2095+produce a `%1` blocking bolt. Otherwise, we require that the value exist
2096+and that it's a number, both of which are guaranteed by clay. We produce
2097+this number.
2098+
2099+Next for `%boil` we call `++lime` to try to load the beam.
2100+
2101+ ++ lime :: load beam
2102+ |= [cof=cafe for=mark bem=beam arg=heel]
2103+ =+ [mob=bem mer=(flop arg)]
2104+ |- ^- (bolt vase)
2105+ %+ cope (lima cof for mob (flop mer))
2106+ |= [cof=cafe vux=(unit vase)]
2107+ ?^ vux (fine cof u.vux)
2108+ ?~ s.mob
2109+ (flaw cof (smyt (tope bem)) ~)
2110+ ^$(s.mob t.s.mob, mer [i.s.mob mer])
2111+
2112+We start at the given beam and try to bake it. If it succeeds, we're
2113+good. Otherwise, we pop off the top level of the path and put it in our
2114+heel (virtual path extension). We do this recursively until either we
2115+find something we can bake or we've gone all the way up to the root path
2116+of the desk, in which case we fail.
2117+
2118+Lifecycle of a `%call`
2119+----------------------
2120+
2121+ %call
2122+ %+ cool |.(leaf/"ford: call {<`@p`(mug kas)>}")
2123+ %. [cof p.kas q.kas]
2124+ ;~ cope
2125+ ;~ coax
2126+ |=([cof=cafe p=silk q=silk] ^$(cof cof, kas p))
2127+ |=([cof=cafe p=silk q=silk] ^$(cof cof, kas q))
2128+ ==
2129+ ::
2130+ |= [cof=cafe gat=cage sam=cage]
2131+ (maul cof q.gat q.sam)
2132+ ::
2133+ |= [cof=cafe vax=vase]
2134+ (fine cof %noun vax)
2135+ ==
2136+
2137+This is slam for silks. We process both of the given silks in parallel
2138+with `++coax`. We then slam the two produced vases together with
2139+`++maul` and mark the produced vase with `%noun` since we don't know any
2140+more specific mark.
2141+
2142+`++coax` is documented under Lifecycle of a Cell.
2143+
2144+Lifecycle of a `%cast`
2145+----------------------
2146+
2147+ %cast
2148+ %+ cool |.(leaf/"ford: cast {<p.kas>}")
2149+ %+ cope $(kas q.kas)
2150+ |= [cof=cafe cay=cage]
2151+ %+ cope (link cof p.kas p.cay [our %main %da now] q.cay)
2152+ |= [cof=cafe vax=vase]
2153+ (fine cof [p.kas vax])
2154+
2155+This is a request to convert data of one mark to another mark directly.
2156+We evaluate the given silk and pass the result into `++link`, which
2157+performs the actual translation. Note that this will not search for
2158+indirect conversion paths, so the conversion must be defined either in
2159+the `++grow` of the given mark or the `++grab` of the target mark.
2160+
2161+ ++ link :: translate
2162+ |= [cof=cafe too=mark for=mark bek=beak vax=vase]
2163+ ^- (bolt vase)
2164+ ?: =(too for) (fine cof vax)
2165+ ?: |(=(%noun for) =(%$ for))
2166+ ((lake too bek) cof vax)
2167+ %+ cope (fang cof for bek)
2168+ |= [cof=cafe pro=vase]
2169+ ?: &((slab %grow p.pro) (slab too p:(slap pro [%cnzy %grow])))
2170+ %+ cope (keel cof pro [[%& 6]~ vax]~)
2171+ |= [cof=cafe pox=vase]
2172+ (maim cof pox [%tsgr [%cnzy %grow] [%cnzy too]])
2173+ %+ cope (fang cof too bek)
2174+ |= [cof=cafe pro=vase]
2175+ =+ ^= zat ^- (unit vase)
2176+ ?. (slab %grab p.pro) ~
2177+ =+ gab=(slap pro [%cnzy %grab])
2178+ ?. (slab for p.gab) ~
2179+ `(slap gab [%cnzy for])
2180+ ?~ zat
2181+ (flaw cof [%leaf "ford: no link: {<[for too]>}"]~)
2182+ (maul cof u.zat vax)
2183+
2184+This performs one step in the translation pipeline. If the given and
2185+target marks are the same, we're done. If we're translating from a noun
2186+or the empty mark, we coerce with `++lake` (documented in `%vale`).
2187+Otherwise, we're translating from a user-defined mark.
2188+
2189+We load the definition of the given mark with `++fang`, and we check to
2190+see if it has an arm in `++grow` named the target mark. If so, we place
2191+our data in the sample of the door with `++keel` and slap the arm.
2192+`++keel` is equivalent to a `%mute` silk, so we document it there.
2193+
2194+If there is no arm in `++grow` of the given mark named the target mark,
2195+we suppose there must be an arm in `++grab` of the target mark named the
2196+given mark. We get the definition of the target mark and check to see if
2197+it has the required arm, failing if it doesn't. Finally, we slam the
2198+data against the correct arm, producing the translated data.
2199+
2200+If you're confused as to why the handling of `++grow` and `++grab` look
2201+superficially so different, remember that the correct arm in `++grow`
2202+does not have a sample while the one in `++grab` does. This means they
2203+must be called rather differently.
2204+
2205+Lifecycle of a `%diff`
2206+----------------------
2207+
2208+ %diff
2209+ %+ cool |.(leaf/"ford: diff {<`@p`(mug p.kas)>} {<`@p`(mug q.kas)>}")
2210+ (diff cof p.kas q.kas)
2211+
2212+We push debug information onto the trace and go right to `++diff`.
2213+
2214+ ++ diff
2215+ |= [cof=cafe kas=silk kos=silk]
2216+ ^- (bolt cage)
2217+ %. [cof kas kos]
2218+ ;~ cope
2219+ ;~ coax
2220+ |=([cof=cafe p=silk q=silk] (make cof p))
2221+ |=([cof=cafe p=silk q=silk] (make cof q))
2222+ ==
2223+ |= [cof=cafe cay=cage coy=cage]
2224+
2225+First, we process the two given silks to get our arguments.
2226+
2227+ ?. =(p.cay p.coy)
2228+ %+ flaw cof :_ ~
2229+ leaf/"diff on data of different marks: {(trip p.cay)} {(trip p.coy)}"
2230+
2231+If the two cages have different marks, then we can't diff them, so we
2232+complain.
2233+
2234+ %+ cope (fang cof p.cay [our %main %da now])
2235+ |= [cof=cafe pro=vase]
2236+
2237+We pull in the relevant mark's definition.
2238+
2239+ ?. (slab %grad p.pro)
2240+ (flaw cof leaf/"no ++grad" ~)
2241+ =+ gar=(slap pro [%cnzy %grad])
2242+ ?. (slab %form p.gar)
2243+ ?. (slab %sted p.gar)
2244+ (flaw cof leaf/"no ++form:grad nor ++sted:grad" ~)
2245+ =+ for=((soft ,@tas) q:(slap gar [%cnzy %sted]))
2246+ ?~ for
2247+ (flaw cof leaf/"bad ++sted:grad" ~)
2248+ (make cof %diff [%cast u.for kas] [%cast u.for kos])
2249+
2250+If there's no `++grad`, we complain. If there's no `++form:grad`, then
2251+we look for a `++sted:grad`. If we can't find either, or if
2252+`++sted:grad` isn't a term, then we complain. If `++sted:grad` exists
2253+and is a term, then it represents the mark we should use as a proxy to
2254+get our diff. So, we cast both our given cages to the new mark and start
2255+the dance again.
2256+
2257+ ?. (slab %diff p.gar)
2258+ (flaw cof leaf/"no ++diff:grad" ~)
2259+
2260+Otherwise, we expect a `++diff:grad`.
2261+
2262+ %+ cope (keel cof pro [[%& 6]~ q.cay]~)
2263+ |= [cof=cafe pox=vase]
2264+
2265+We put the first cage's data into the sample of the given mark's
2266+definition.
2267+
2268+ %+ cope
2269+ %^ maul cof
2270+ (slap (slap pox [%cnzy %grad]) [%cnzy %diff])
2271+ q.coy
2272+ |= [cof=cafe dif=vase]
2273+
2274+We run `++diff:grad` with a sample of the second cage's data.
2275+
2276+ =+ for=((soft ,@tas) q:(slap gar [%cnzy %form]))
2277+ ?~ for
2278+ (flaw cof leaf/"bad ++form:grad" ~)
2279+ (fine cof u.for dif)
2280+ ==
2281+
2282+We check that `++form:grad` exists, and we tag the result with it to
2283+give the final cage.
2284+
2285+Lifecycle of a `%done`
2286+----------------------
2287+
2288+ %done [cof %0 p.kas q.kas]
2289+
2290+This is trivial. We simply produce the given cage with the given set of
2291+dependencies. This is used when we already have a cage that we want to
2292+insert into another silk that requires a silk argument. It's analogous
2293+to the return operator in a monad -- which makes it sound way more
2294+complicated than it is.
2295+
2296+Lifecycle of a `%dude`
2297+----------------------
2298+
2299+ %dude (cool |.(p.kas) $(kas q.kas))
2300+
2301+This simply puts a given tank on the stack trace if the given silk
2302+produces an error. This is implemented as a simple call to `++cool`.
2303+
2304+Lifecycle of a `%dune`
2305+----------------------
2306+
2307+ %dune
2308+ ?~ q.kas [cof [%2 [%leaf "no data"]~]]
2309+ $(kas [%done p.kas u.q.kas])
2310+
2311+This is a sort of a `++need` for silks. If there is no data in the unit
2312+cage, we produce an error. Else, we simply produce the data in the cage.
2313+
2314+Lifcycle of a `%mute`
2315+---------------------
2316+
2317+ %mute (kale cof p.kas q.kas)
2318+
2319+This mutates a silk by putting the values of other silks at particular
2320+axes. This is useful in, for example, replacing the sample of the door
2321+in a mark definition.
2322+
2323+ ++ kale :: mutate
2324+ |= [cof=cafe kas=silk muy=(list (pair wing silk))]
2325+ ^- (bolt cage)
2326+ %+ cope
2327+ |- ^- (bolt (list (pair wing vase)))
2328+ ?~ muy (fine cof ~)
2329+ %+ cope (make cof q.i.muy)
2330+ |= [cof=cafe cay=cage]
2331+ %+ cope ^$(muy t.muy)
2332+ |= [cof=cafe rex=(list (pair wing vase))]
2333+ (fine cof [[p.i.muy q.cay] rex])
2334+ |= [cof=cafe yom=(list (pair wing vase))]
2335+ %+ cope (make cof kas)
2336+ |= [cof=cafe cay=cage]
2337+ %+ cope (keel cof q.cay yom)
2338+ |= [cof=cafe vax=vase]
2339+ (fine cof p.cay vax)
2340+
2341+First, we process each of the silks by calling `++make` on them. We pass
2342+the resultant vase and list of pairs of wings and silks to `++keel` to
2343+do the actual mutation. We assume the mutation doesn't change the mark
2344+of the main silk, so we mark the produced vase with the original mark.
2345+
2346+ ++ keel :: apply mutations
2347+ |= [cof=cafe suh=vase yom=(list (pair wing vase))]
2348+ ^- (bolt vase)
2349+ %^ maim cof
2350+ %+ slop suh
2351+ |- ^- vase
2352+ ?~ yom [[%atom %n] ~]
2353+ (slop q.i.yom $(yom t.yom))
2354+ ^- twig
2355+ :+ %cncb [%& 2]~
2356+ =+ axe=3
2357+ |- ^- (list (pair wing twig))
2358+ ?~ yom ~
2359+ :- [p.i.yom [%$ (peg axe 2)]]
2360+ $(yom t.yom, axe (peg axe 3))
2361+
2362+We first put the vases together in one big tuple starting with the
2363+subject and going through the mutations. We slap against this tuple a
2364+`%_` twig we directly construct. Since a `%_` twig takes a list of pairs
2365+of wings and twigs, we simply have to generate twigs referring to the
2366+correct axes in the subject. This is very easy since we just recur on
2367+axis 3 of whatever axis we were already at.
2368+
2369+Note the use of `%_` instead of `%=` enforces that our mutations don't
2370+change the type of the subject, which justifies our use of the original
2371+mark.
2372+
2373+Lifecycle of a `%pact`
2374+----------------------
2375+
2376+ %pact
2377+ %+ cool |.(leaf/"ford: pact {<`@p`(mug p.kas)>} {<`@p`(mug q.kas)>}")
2378+ (pact cof p.kas q.kas)
2379+
2380+We push debug information onto the trace and go right to `++pact`.
2381+
2382+ ++ pact :: patch
2383+ |= [cof=cafe kas=silk kos=silk]
2384+ ^- (bolt cage)
2385+ %. [cof kas kos]
2386+ ;~ cope
2387+ ;~ coax
2388+ |=([cof=cafe p=silk q=silk] (make cof p))
2389+ |=([cof=cafe p=silk q=silk] (make cof q))
2390+ ==
2391+ |= [cof=cafe cay=cage coy=cage]
2392+
2393+First, we process the two given silks to get our arguments.
2394+
2395+ %+ cope (fang cof p.cay [our %main %da now])
2396+ |= [cof=cafe pro=vase]
2397+
2398+We pull in the relevant mark's definition.
2399+
2400+ ?. (slab %grad p.pro)
2401+ (flaw cof leaf/"no ++grad" ~)
2402+ =+ gar=(slap pro [%cnzy %grad])
2403+ ?. (slab %form p.gar)
2404+ ?. (slab %sted p.gar)
2405+ (flaw cof leaf/"no ++form:grad nor ++sted:grad" ~)
2406+ =+ for=((soft ,@tas) q:(slap gar [%cnzy %sted]))
2407+ ?~ for
2408+ (flaw cof leaf/"bad ++sted:grad" ~)
2409+ (make cof %cast p.cay %pact [%cast u.for kas] kos)
2410+
2411+If there's no `++grad`, we complain. If there's no `++form:grad`, then
2412+we look for a `++sted:grad`. If we can't find either, or if
2413+`++sted:grad` isn't a term, then we complain. If `++sted:grad` exists
2414+and is a term, then it represents the mark we should use as a proxy to
2415+get our diff. So, we cast the first argument to the new mark, then try
2416+to patch. Afterward, we cast the result back to the original mark.
2417+
2418+ =+ for=((soft ,@tas) q:(slap gar [%cnzy %form]))
2419+ ?~ for
2420+ (flaw cof leaf/"bad ++form:grad" ~)
2421+ ?. =(u.for p.coy)
2422+ %+ flaw cof :_ ~
2423+ =< leaf/"pact on data with wrong form: {-} {+<} {+>}"
2424+ [(trip p.cay) (trip u.for) (trip p.coy)]
2425+
2426+If `++form:grad` isn't a term, or else our second argument isn't of that
2427+mark, we complain.
2428+
2429+ ?. (slab %pact p.gar)
2430+ (flaw cof leaf/"no ++pact:grad" ~)
2431+
2432+If we don't have a `++pact:grad`, we complain.
2433+
2434+ %+ cope (keel cof pro [[%& 6]~ q.cay]~)
2435+ |= [cof=cafe pox=vase]
2436+
2437+We put the first cage's data into the sample of the given mark's
2438+definition.
2439+
2440+ %+ cope
2441+ %^ maul cof
2442+ (slap (slap pox [%cnzy %grad]) [%cnzy %pact])
2443+ q.coy
2444+ |= [cof=cafe pat=vase]
2445+
2446+We run `++pact:grad` with a sample of the second cage's data, which is
2447+the diff.
2448+
2449+ (fine cof p.cay pat)
2450+ ==
2451+
2452+We tag the result with the mark of our first argument.
2453+
2454+Lifecycle of a `%plan`
2455+----------------------
2456+
2457+ %plan
2458+ %+ cope (abut:(meow p.kas q.kas) cof r.kas)
2459+ |= [cof=cafe vax=vase]
2460+ (fine cof %noun vax)
2461+
2462+This is a direct request to compile a hood at a given beam with a heel
2463+of the given path. We comply by calling `++abut` with the given
2464+arguments and producing the vase with a mark of `%noun`.
2465+
2466+Lifecycle of a `%reef`
2467+----------------------
2468+
2469+ %reef (fine cof %noun pit)
2470+
2471+This is one of the simplest silks. We simply produce our context, which
2472+is zuse compiled against hoon. The mark is a `%noun`.
2473+
2474+Lifcycle of a `%ride`
2475+---------------------
2476+
2477+ %ride
2478+ %+ cool |.(leaf/"ford: ride {<`@p`(mug kas)>}")
2479+ %+ cope $(kas q.kas)
2480+ |= [cof=cafe cay=cage]
2481+ %+ cope (maim cof q.cay p.kas)
2482+ |= [cof=cafe vax=vase]
2483+ (fine cof %noun vax)
2484+
2485+This slaps evaluates the given silk, then it slaps the result against
2486+the given twig. Since we don't know what of what mark (if any) is the
2487+result, we give it a mark of `%noun`.
2488+
2489+Lifecycle of a `%vale`
2490+----------------------
2491+
2492+ %vale
2493+ %+ cool |.(leaf/"ford: vale {<p.kas>} {<q.kas>} {<`@p`(mug r.kas)>}")
2494+ %+ cope (lave cof p.kas q.kas r.kas)
2495+ |= [cof=cafe vax=vase]
2496+ (fine cof `cage`[p.kas vax])
2497+
2498+This checks whether given data is of the given mark. If we don't have
2499+the definition of the mark, we check the given ship for it.
2500+
2501+We call `++lave` to perform the check, producing a vase. We produce this
2502+vase tagged with the given mark.
2503+
2504+ ++ lave :: validate
2505+ |= [cof=cafe for=mark his=ship som=*]
2506+ ^- (bolt vase)
2507+ ((lake for [our %main [%da now]]) cof [%noun som])
2508+
2509+This is a thinly-veiled wrapper over `++lake`. Note that, contrary to
2510+documented opinion, we do not in fact check the other ship's definition
2511+of a mark. This is likely a bug.
2512+
2513+At any rate, `++lake` coerces a noun into the correct type for a mark.
2514+
2515+ ++ lake :: check/coerce
2516+ |= [for=mark bek=beak]
2517+ |= [cof=cafe sam=vase]
2518+ ^- (bolt vase)
2519+ %+ cool |.(leaf/"ford: check {<[for bek `@p`(mug q.sam)]>}")
2520+ ?: ?=(?(%gate %core %door %hoon %hook) for)
2521+ :: ~& [%lake-easy for bek]
2522+ (fine cof sam)
2523+ %+ cope (fang cof for bek)
2524+ |= [cof=cafe tux=vase]
2525+ =+ bob=(slot 6 tux)
2526+ ?: (~(nest ut p.bob) | p.sam)
2527+ (fine cof sam)
2528+ ?. (slab %grab p.tux)
2529+ (flaw cof [%leaf "ford: no grab: {<[for bek]>}"]~)
2530+ =+ gab=(slap tux [%cnzy %grab])
2531+ ?. (slab %noun p.gab)
2532+ (flaw cof [%leaf "ford: no noun: {<[for bek]>}"]~)
2533+ %+ cope (maul cof (slap gab [%cnzy %noun]) [%noun q.sam])
2534+ |= [cof=cafe pro=vase]
2535+ ?: =(+<.q.pro q.sam)
2536+ (fine cof (slot 6 pro))
2537+ (flaw cof [%leaf "ford: invalid content: {<[for bek]>}"]~)
2538+
2539+This is going to coerce the sample into the correct type for the mark.
2540+First, we push a line onto the stack trace saying that we're checking
2541+the type. If the requested mark is a gate, core, door, hoon, or hook,
2542+then we don't do any more type information than just saying it's a noun,
2543+so we're done.
2544+
2545+Otherwise, we get the mark definition from our `/=main=/mar` directory
2546+with `++fang`, which we'll describe below.
2547+
2548+We check to see if our sample type nests within the type of the sample
2549+to the door. If so, then we're already of the correct type, so we're
2550+done.
2551+
2552+Otherwise, we check to see if there's a `++grab` in the door, and a
2553+`++noun` in the `++grab`. If not, there's no way we can translate to
2554+this mark, so we fail.
2555+
2556+If we have everything we need, we slam our sample (typed as a noun)
2557+against the `++noun` in `++grab`. If the sample of the door is the same
2558+as our sample, then the check succeeded, so we produce the well-typed
2559+sample of the door. Otherwise, we fail.
2560+
2561+ ++ fang :: protocol door
2562+ |= [cof=cafe for=mark bek=beak]
2563+ ^- (bolt vase)
2564+ =+ pax=/door/[for]/mar
2565+ =+ ^= bem ^- beam
2566+ :_ pax
2567+ ?: =(p.bek our) bek
2568+ =+ oak=[our %main %da now]
2569+ ?. =(~ (ska %cy (tope [oak pax]))) oak
2570+ bek
2571+ (cope (fade cof %hook bem) abut:(meow bem ~))
2572+
2573+A mark's definition is generally in
2574+`/=main=/mar/[mark-name]/door/hook'. If we don't find it there, we look in`/[given-beak]/mar/[mark-name]/door/hook'.
2575+We parse the mark definition with `++fade` and assemble it with
2576+`++abut:meow`. `++fade` is defined under the `%bake` silk.