Lesson 1 – The (Bare) Naked Generator

Introduction


In this lesson, we will learn several basic runes, enough Hoon syntax to stitch them together, and build our first generator.

In Urbit-speak, a generator is a simple program that can be called from the dojo, taking some input and producing some result.

Naked generators are the simplest generators available. They have access only to the information passed by the user explicitly.

In this lesson, we're going to write our first naked generator, a very simple program, and talk through what parts are required to make it work. We'll lay out our goal, break down the runes required, wax a bit on key concepts, and finally go through the program itself in detail. Here we go!

Goal

Write a program that takes your planet name and creates a cell of your planet's number and your planet's name (for instance [1.035.281.574 ~rabsef-bicrym]).

Let's look to the Rune List for some tools we'll use to achieve this.

Note: Available to you are a series of flash cards to help you study the runes, atomic auras, and phonetic pronunciation of Hoon you’ll be using across Hoon 001

Hoon Runes in Plain English

Hoon Atomic Auras

Hoon Phonetic Pronunciation Guide

Runeset


|= bar·tis

SyntaxSummary
|= spec hoonproduce a gate: a one-armed core with a sample.

|= creates a gate — a special type of core which

  • Takes a sample
  • Has only one arm, named $ (buc)
  • Immediately computes its one arm upon creation

|= takes two children:

  • The first child is the spec for the generator’s sample.
  • The second child is some hoon
  • This is the code which will be computed and whose product will be returned.
Documentation on urbit.org

Exercise

Try this in dojo:

=foo |=(me=@p me)
(foo ~sampel-palnet)
~sampel-palnet


^- ket·hep

SyntaxSummary
^-  type  hoonCast some value to a specified type.
`type`hoon

^- returns some hoon code or value, expressed in an explicitly declared type, if possible.

Often, ^- will be the first rune at the start of a Hoon block, telling the compiler,

“Whatever is produced by the rest of the code should be returned as this specified type.

Explanation

^- takes two children:

The first child is an explicit type definition. This can be a simple aura or any complex type.

The second child is some hoon.

The hoon may be either a static value, or some code which will produce a value.

Documentation on urbit.org

Recall: All data in urbit, at the lowest level, is stored as arbitrarily large binary trees of integers. Without explicitly casting data to a particular type, the language interpreter will not know if we're dealing with numbers or letters, %terms, or some totally custom data type. It is extremely important to cast your program's output.

Exercise

Try this in dojo:

^-(@ud (add 'hep' 'cat'))
14.993.099

Explain what was done and what we learned from it

^- Irregular form

Syntax:  `type`hoon

Many runes have irregular forms, which do not follow the spacing/parsing rules of the regular form. `type` is the irregular form of ^-. The target type is sandwiched between a pair of tics, followed without space by the hoon to be cast.

There is a key difference with this irregular form.  In the case of casting an atom between auras, the value is first cast to raw atom before being cast to our target aura.

`@ud`~marzod is  ^-  @ud  ^-  @  ~marzod

The irregular form of ^- is especially useful when casting simple expressions to simple types. As with all runes with irregular syntax options, actual usage/selection will depend largely on style, readability and/or programmer preference..

Try casting to various auras in the dojo:

`@`~zod

`@`~marzod

`@ux"@`~marzod

`@ud`(foo ~sampel-palnet)

1.624.961.343

You may notice here that “foo”, our simple gate from our prior work above is still around.  Hoon is a subject-oriented language and values/faces/code added to the dojo’s subject will persist until we remove it.

We’ve left `foo` mapped to our gate in the subject - let us tidy up.

To remove foo, do this in dojo:

=foo

To see everything in your current subject, do this in dojo:

.

We’ll talk later about everything that you see when you do  .  (pronounced dot) in dojo.

:- col·hep

SyntaxSummary
:-  hoon  hoonproduce a cell: a pair of two nouns

:- takes two children and produces one cell.

Explanation

:- creates a cell from any two nouns

A cell is any pair of two nouns.

Since all data in Hoon in are nouns, a cell is a pair of any two values, expressions, functions, or any other possible data structures.

:- takes two children

The first child will become the head of the cell produced.

The second child will become the tail of the cell produced.

Documentation on urbit.org

Exercise

Try these in dojo:

:-(1 2)
[1 2]
:-  1  2
[1 2]

IRREGULAR FORM: A cell can be irregularly written as simply [1 2], now try this in dojo:

[1 2]
[1 2]


New Concepts

Running a Generator

Assuming you have already mounted your urbit filesystem to the host filesystem, your pier will have a folder mirroring your urbit files.

Save your generator in the [pier]/home/gen folder.

You must run |commit %home to load the changed file into your urbit’s filesystem so that it can be used.

Now, in dojo, you can type  +<generator name> <argument>  or if there are multiple arguments: +<generator name> [<arg 1> <arg 2>...<arg n>]

Arms / Cores

We’ve seen that all Hoon nouns/data structures are binary trees.  Each branch or wing of a noun is either static data (legs) or hoon code for performing some computation (arms).

The use of these terms will make more sense later.  Important for now is that core is a data structure containing one or more computational methods (arms), and a gate is a special case of core, having only one arm, named $(buc).

Children / Arguments

Children are hoon expressions required for a rune to be evaluated.

Children vary in length and complexity, depending on what they need to do.

Familiarity with the expected input to each of Hoon’s runes will be critical in order to tell where the children begin and end within any hoon code.

In many programming languages, parentheses, semicolons and other syntax tell the reader and the computer where children begin and end.

Hoon is parsed primarily by whitespace.

Hoon runes take a fixed number of arguments, or “children”, and once that number has been satisfied, they are closed automatically.

Learning to properly parse runes and hoons is critical for the Hoon learner. Towards that end,  we will begin by using non-standard style which is easier to visually parse.

Style: Backstep Indentation

The Hoon styleguide recommends “backstep indentation” which allows for Hoon code to be written and read vertically without constantly walking to the right.  Given the functional nature of Hoon, walking right is unavoidable without backstep indentation.

We strongly recommend reading the Hoon Style Guide at https://urbit.org/docs/tutorials/hoon/style/

Having said that, walking/standard indentation is much easier for new hoon learners to parse. We will show both styles for the first few lessons.

Backstep Indentation (Proper) Walking Indentation (Improper)
|=  my-name=@p
^-  [@ud @p]
:-  `@ud`my-name
my-name
|=
  my-name=@p
  ^-
    [@ud @p]
    :-
      `@ud`my-name
      my-name

Demo:

+nakedgenerator ~rabsef-bicrym
[1.035.281.574 ~rabsef-bicrym]

Walkthrough

  • |=
    |= creates a gate that requests an argument with a face (something like a name for some hoon - either a value or some code) of “myname”, that should be a @p (pronounced pat-p), which is the type that will represent atoms (numbers) as planet names. |= will have two children

    • myname=@p
      The argument from our gate, which is also called the sample (user inputted information is a planet name - @p and this will be assigned to the face “myname”: myname=@p)
    • ^-
      ^- casts the following expression to the given type.

      • [@ud @p]
        We know our goal is to create a cell of our planet's number and name. The type [@ud @p] defines just that — a cell of a number and a @p or planet name. (a list of these types can be found here)
      • :-
        :- creates a cell of the immediate next two values (i.e. colhep takes two children, each of which is one of the next two values).

        • `@ud`myname
          The first child and first part of that cell, is myname (our @p value entered by the user) cast as @ud (unsigned decimal), or our number
        • myname
          myname is the face of our @p, and also the second child of :-, the second element in the produced cell.
          This value completes the children of colhep and closes out that rune
          This is also the last part of the last child of |=  (the hoon that does something with the input value requested by |=); as a complete thought and with all runes sufficiently populated with their children, your urbit is ready to produce output - in this case, our cell.  Your deterministic urbit is smart enough to know that it is done with all of the work that has been asked of it. The information is output to the dojo, and the generator ends.

Putting it together:

|=    Create a gate which requests an @p input.

^-    Specify that your output will be a cell of [@ud @p]

:-     Create a cell of our atom rendered as @ud and rendered as @p

Additional Reading for this lesson:

Homework

Please submit your work to us by the deadline on the Schedule (see schedule in the dropdown menu above) via this form.  Please submit your homework with all exercises from one week (two lessons) as a single pastebin or code-sharing platform of your choice.

 

  1. Find your number by casting your ship’s name as an @ud, then write a generator that takes an @ud and produces a ship name(@p).  Make sure it works by entering your number, and getting your name.  Send us this generator.
  2. Create a “duple” a “triple” and an “n-tuple” cell using what you’ve learned from the : Rune family reading, in dojo. Note that this does not need to be a generator, just use the : runes directly in the dojo. Send us what you entered, and what the product was.
  3. Write any ‘cord’, cast it as an @ud value (see 1.2 The Noun).  Write a generator that takes a cord, and produces a cell of a) that cord, b) that cord as a number and c) that cord as a knot.