load

load is the result of compiling a code.page

a load's ultimate aim is to become a $manx, because a code.page's job is to become the new data.page after a command is given.

but code.page does not have to compile directly to a manx, it can compile to an intermediate state which will “eventually” become a manx.

the $load type specifies the valid intermediate states.


in hoon

+$  load              :: intermediate state
  $%                  ::
  [%cons load load]   :: prepend a into b
  [%snoc load load]   :: append b into a
  [%join (list load)] :: compose many
  [%view =path]       :: overlay data
  [%twin =path]       :: overlay code
  [%call =path =card] :: overlay code w/card
  [%lens =path =hoon] :: recurse at path
  [%marx =marx =load] :: rewrite tag
  [%vase =vase]       :: pretty printer
  [%manx =manx]       :: final
  [%shed =shed:khan]  :: final w/sys-calls
  ==

the compile subject

all hawk-500 pages are compiled with the following subject

;:  slop
  ::
  ::  relavent context
  ::
  !>(the-card=card)    ::  $card: the command
  !>(the-file=file)    ::  $file: the current file
  !>(here=here)        ::  $path: the current location
  ::
  ::  bound engines
  ::
  !>(c=~(. iu card))
  !>(f=~(. fu file))
  ::
  ::  bound engines for the root file
  ::
  !>(d=~(. mx data:(~(git fu file) /)))
  !>(m=~(. iu meta:(~(git fu file) /)))
  ::
  ::  standard library
  ::
  !>(hawk)
  !>(hawk-utils)
  !>(html-utils)
  !>(mu=manx-utils)
  !>(strandio)
  !>(..zuse)

learn through action: in a new tab copy some of the following examples into a hawk-500 page and play around with them.


%manx

[%manx =manx]

the most fundamental $load.

::  hawk-500
|^
  :-  %manx
  ;div
    ;+  a
    ;+  b
  ==
++  a  ;div: some hoon
++  b  ;div: that resolves to $manx
--

if you only want to return a manx, you can ommit the head tag :- %manx and just return a manx.

example:

::  hawk-500
;div
  ; a standalone manx may
  ; omit the head tag
==

this is especially useful for document creation with ;>

example:

::  hawk-500
=;  m
  ;div.prose.page
    ;+  m
  ==
;>

# some document

using the micgar rune

%vase

[%vase =vase]

pretty print a hoon value

::  hawk-500
=/  =ship  ~migrev-dolseg
[%vase !>(`@ud`ship)]

the resulting data.page just stores the pretty-printed result of the vase, not the vase itself.


%shed

[%shed =shed:khan]

shed is the body of a hoon thread to be passed to the khan vane.

threads are very powerful. they can encode anything that your urbit can do:

  • http requests

  • reads and poke to any agent (app) on your urbit

  • reads and pokes across the urbit network

  • set timers

to use %shed powerfully, you'll need to be familiar with the strandio library.

because %shed can be asynchronous, it is not composable in the other load types.

it must be the final load in the composition chain.

the shed:khan should return a vase of manx.

:-  %shed
=/  m  (strand ,vase)
;<  =cord  bind:m  (fetch-cord "https://google.com")
%-  pure:m  !>
;div.page
  ; {(trip cord)}
==

%marx

[%marx =marx =load]

rewrite tag.

this load takes the result of another load and edits the marx of the manx.

this is useful for modifying css classes when doing namespace composition with %call and %twin.


%lens

[%lens =path =hoon]

recurse “as if at another path”

the hoon is the AST of a $load to evaluate on the subtree at some path.

when the subtree at path changes, this page will be passed an empty card so that it may stay up to date.

example: list the files in the manual

:+  %lens  /~/manual  !,  *hoon
:-  %manx
;div.page
  ;*
  %+  turn  tah:f
  |=  =path
  ;div: {(spud path)}
==

%lens is useful for doing searches on entire subtrees.

one useful way of think about it is that it allows you to reduce any subtree in your namespace into a single page.


%view

[%view =path]

use the data.page of another path.

a %view will mirror the data of another page and stay up to date as the other page changes.

you can use a %view of a %shed to make %shed's composable.


%twin

[%twin =path]

use the code.page of another path but run it on the current sub-tree.

this is a way to do simple templating.

if you have a simple hawk app that you want to exist in multiple spots in your namespace, you could simply copy the code to multiple pages.

but when you want to update the code, now you have to edit multiple places.

%twin solves this by programatically copying the the code from spots in your namespace and keepying them up to date when the master copy changes.

example: using the 'note' template

[%twin /~/system/templates/note]

%call

[%call =path =card]

%call is like %twin but with a hard-coded command.

this is useful for the class of templates that requires a bit of extra data to be meaningful.

example: calling the web-file template with an image url

:+  %call  /~/system/templates/web-file
%-  ~(gas of *card)
:~
:-    /type          tas/'image'
:-    /url           tas/'https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Hunt_in_the_forest_by_paolo_uccello.jpg/900px-Hunt_in_the_forest_by_paolo_uccello.jpg'
:-    /no-controls   *dime
==

%cons

[%cons load load]

%cons prepends the result of the first load into the result the second.

example

:+  %cons
  :-  %manx
  ;div.f-1: thing
:-  %manx
;div
  ;div: a
  ;div: b
  ;div: c
==

%snoc

%snoc is the word %cons in reverse.

it appends the result of the second load to the result of the first.

example

:+  %snoc
  :-  %manx
  ;div
    ;div: a
    ;div: b
    ;div: c
  ==
:-  %manx
;div.f-1: thing

%join

[%join (list load)]

%join wraps a list of loads in a ;div manx.

example

:-  %join
:~
  [%vase !>(1)]
  [%vase !>(2)]
  [%vase !>(3)]
==

it pairs well with the %marx load.

:+  %marx  [%div [%class "frw g3"]~]
:-  %join
:~
  [%vase !>(1)]
  [%vase !>(2)]
  [%vase !>(3)]
==