<commit_before>---
next: false
sort: 2
spam: true
title: Hoon 101.2: syntax
---
# Hoon 101.2: full-contact syntax

In [chapter 0](0-nouns), we read about nouns.  In [chapter 1](1-twigs), 
we discovered twigs and legs.

Up till now, we've done everything in the dojo, Hoon's shell /
REPL.  Now it's time to actually write a real Hoon source file,
and get a bit deeper into the syntax.

## How to use this tutorial

Ideally, you've installed an Urbit planet (if you have a ticket)
or comet (if you don't).  See the [user doc](../../../user).

We recommend opening up the dojo and just typing the examples;
you don't know a language until you know it in your fingers.
Also, make sure you've worked through the chapters in order.

## Building a simple generator

In Urbit there's a variety of source file roles, distinguished by
the magic paths they're loaded from: `/gen` for generators,
`/ape` for appliances, `/lib` for libraries, etc.

We'll start with a generator, the simplest kind of Urbit program.

### Create a sandbox desk

A desk is the Urbit equivalent of a `git` branch.  We're just
playing around here and don't intend to soil our `%home` desk with
test files.  So let's make a sandbox:
```
|sync %sandbox our %home
```

You just merged the `%home` desk on your own ship into a new
`%sandbox` desk.  `%sandbox` has everything in `%home`, but we'll
add more.  Future changes in `%home` (such as our over-the-air
updates) will also propagate into `%sandbox`.

> Desks are always born in merges; it makes no sense to create an
empty desk, because anything you do in a desk depends on other
files in the desk.  For instance, your file types (marks) are
defined by source files in the same desk.

### Mount the sandbox from Unix

Run the command
```
~tasfyn-partyv:dojo> |mount /=sandbox=/gen %gen
```
This mounts the `/gen` folder from the `%sandbox` desk in your Unix
directory  `~/tasfyn-partyv/gen`.

The mount is a two-way sync, "Dropbox style."  When you edit a
Unix file and save, your edit is automatically committed as a
change in the `%sandbox` desk.  If you change `%sandbox` files
from Urbit, these changes will also propagate to Unix.

### Execute from the sandbox

Let's set the dojo desk to `%sandbox`:
```
~tasfyn-partyv:dojo> =dir /=sandbox=
=% /~tasfyn-partyv/sandbox/~2015.11.13..02.49.37..9e6c/
```
Your prompt will change to:
```
~tasfyn-partyv:dojo/sandbox
```

### Write hello, world

Let's build the simplest possible kind of generator, a builder.

First, configure your favorite Unix text editor to work with
Hoon.  There are Hoon modes for vim, emacs and Sublime in the
`extras/` directory of the github repo.

Second, create the file `~/tasfyn-partyv/gen/test.hoon`.
Paste this text into it:
```
:-  %say  |=  *  :-  %noun
[%hello %world]
```
Get the spaces exactly right, please.  Hoon is not in general a
whitespace-sensitive language, but the difference between one space and
two-or-more matters.  And for the moment, think of
```
:-  %say  |=  *  :-  %noun
```
as gibberish boilerplate, like `#include "stdio.h"` at the start of a C
program. 

Now, run your builder:
```
~tasfyn-partyv:dojo/sandbox> +test
[%hello %world]
```
This is your first Hoon *program* per se.  Congrats!

## Hoon syntax 101

But what's up with this syntax?

### Some syntactic relatives

The relationship between ASCII and human programming languages
is like the relationship between the electric guitar and
rock-and-roll.  If it doesn't have a guitar, it's not rock.
If it doesn't use ASCII, it's not a programming language.

Some great rock guitarists play three chords, like <NAME>;
some shred it up, like <NAME>.  If Lisp is the Ramones of
syntax, Perl or APL is Led Zeppelin.  No one has any right to rag
on Perl or APL, but Hoon is a "metalhead" language that shreds
its ASCII very differently.

### The case for heavy metal

The philosophical case for a metalhead language is threefold.
One, human beings are much better at associating meaning with
symbols than they think they are.  Two, a programming language is
a professional tool and not a plastic beach shovel.

> "There's a guitar player, a harp player, a double-bass player,
all holding up their blisters. Imagine if you downloaded a
library off the internet... and it gave you blisters! Right? The
horror! And yet... every musician has overcome a barrier to entry
similar to this."  — <NAME>

And three, the alternative to heavy metal is keywords.  When you
use a keyword language, not only are you forcing the programmer
to tiptoe around a ridiculous maze of reserved words.  You're
expressing your program through two translation steps:
symbol->English and English->computation.

When you shred, you are going direct: symbol->computation.  A
pure-functional language with syntax on the metalhead principle
creates a sense of "seeing the function" which no keyword
language can quite duplicate.  Also, all the words you see on the
screen are actually meaningful terms in the program.

But a great metalhead language should *not* be user-extensible.
That way lies King Crimson.  (Maybe Haskell is King Crimson: the
prog-rock of programming languages.)  A language is a standard;
if users can do whatever with ASCII, there is no standard.  If a
metal language can work, it's only by rigorous consistency and
predictability.  No macros, operator overloading, etc, etc.

### A glyphic bestiary

Any metalhead language you don't yet know is line noise.  Let's
get you up to speed as fast as possible.

A programming language needs to be not just read but said.  But
no one wants to say "ampersand."  Therefore, we've taken the
liberty of assigning three-letter names to all ASCII glyphs.

Some of these bindings are obvious and some aren't.  You'll be
genuinely surprised at how easy they are to remember:
```
    ace [1 space]   gal <               pel (
    bar |           gap [>1 space, nl]  per )
    bas \           gar >               sel [
    buc $           hax #               sem ;
    cab _           hep -               ser ]
    cen %           kel {               soq '
    col :           ker }               tar *
    com ,           ket ^               tec `
    doq "           lus +               tis =
    dot .           pam &               wut ?
    fas /           pat @               zap !<commit_msg>Add sig to list of glyphs.<commit_after>---
next: false
sort: 2
spam: true
title: Hoon 101.2: syntax
---
# Hoon 101.2: full-contact syntax

In [chapter 0](0-nouns), we read about nouns.  In [chapter 1](1-twigs), 
we discovered twigs and legs.

Up till now, we've done everything in the dojo, Hoon's shell /
REPL.  Now it's time to actually write a real Hoon source file,
and get a bit deeper into the syntax.

## How to use this tutorial

Ideally, you've installed an Urbit planet (if you have a ticket)
or comet (if you don't).  See the [user doc](../../../user).

We recommend opening up the dojo and just typing the examples;
you don't know a language until you know it in your fingers.
Also, make sure you've worked through the chapters in order.

## Building a simple generator

In Urbit there's a variety of source file roles, distinguished by
the magic paths they're loaded from: `/gen` for generators,
`/ape` for appliances, `/lib` for libraries, etc.

We'll start with a generator, the simplest kind of Urbit program.

### Create a sandbox desk

A desk is the Urbit equivalent of a `git` branch.  We're just
playing around here and don't intend to soil our `%home` desk with
test files.  So let's make a sandbox:
```
|sync %sandbox our %home
```

You just merged the `%home` desk on your own ship into a new
`%sandbox` desk.  `%sandbox` has everything in `%home`, but we'll
add more.  Future changes in `%home` (such as our over-the-air
updates) will also propagate into `%sandbox`.

> Desks are always born in merges; it makes no sense to create an
empty desk, because anything you do in a desk depends on other
files in the desk.  For instance, your file types (marks) are
defined by source files in the same desk.

### Mount the sandbox from Unix

Run the command
```
~tasfyn-partyv:dojo> |mount /=sandbox=/gen %gen
```
This mounts the `/gen` folder from the `%sandbox` desk in your Unix
directory  `~/tasfyn-partyv/gen`.

The mount is a two-way sync, "Dropbox style."  When you edit a
Unix file and save, your edit is automatically committed as a
change in the `%sandbox` desk.  If you change `%sandbox` files
from Urbit, these changes will also propagate to Unix.

### Execute from the sandbox

Let's set the dojo desk to `%sandbox`:
```
~tasfyn-partyv:dojo> =dir /=sandbox=
=% /~tasfyn-partyv/sandbox/~2015.11.13..02.49.37..9e6c/
```
Your prompt will change to:
```
~tasfyn-partyv:dojo/sandbox
```

### Write hello, world

Let's build the simplest possible kind of generator, a builder.

First, configure your favorite Unix text editor to work with
Hoon.  There are Hoon modes for vim, emacs and Sublime in the
`extras/` directory of the github repo.

Second, create the file `~/tasfyn-partyv/gen/test.hoon`.
Paste this text into it:
```
:-  %say  |=  *  :-  %noun
[%hello %world]
```
Get the spaces exactly right, please.  Hoon is not in general a
whitespace-sensitive language, but the difference between one space and
two-or-more matters.  And for the moment, think of
```
:-  %say  |=  *  :-  %noun
```
as gibberish boilerplate, like `#include "stdio.h"` at the start of a C
program. 

Now, run your builder:
```
~tasfyn-partyv:dojo/sandbox> +test
[%hello %world]
```
This is your first Hoon *program* per se.  Congrats!

## Hoon syntax 101

But what's up with this syntax?

### Some syntactic relatives

The relationship between ASCII and human programming languages
is like the relationship between the electric guitar and
rock-and-roll.  If it doesn't have a guitar, it's not rock.
If it doesn't use ASCII, it's not a programming language.

Some great rock guitarists play three chords, like J<NAME>;
some shred it up, like <NAME>.  If Lisp is the Ramones of
syntax, Perl or APL is Led Zeppelin.  No one has any right to rag
on Perl or APL, but Hoon is a "metalhead" language that shreds
its ASCII very differently.

### The case for heavy metal

The philosophical case for a metalhead language is threefold.
One, human beings are much better at associating meaning with
symbols than they think they are.  Two, a programming language is
a professional tool and not a plastic beach shovel.

> "There's a guitar player, a harp player, a double-bass player,
all holding up their blisters. Imagine if you downloaded a
library off the internet... and it gave you blisters! Right? The
horror! And yet... every musician has overcome a barrier to entry
similar to this."  — <NAME>

And three, the alternative to heavy metal is keywords.  When you
use a keyword language, not only are you forcing the programmer
to tiptoe around a ridiculous maze of reserved words.  You're
expressing your program through two translation steps:
symbol->English and English->computation.

When you shred, you are going direct: symbol->computation.  A
pure-functional language with syntax on the metalhead principle
creates a sense of "seeing the function" which no keyword
language can quite duplicate.  Also, all the words you see on the
screen are actually meaningful terms in the program.

But a great metalhead language should *not* be user-extensible.
That way lies King Crimson.  (Maybe Haskell is King Crimson: the
prog-rock of programming languages.)  A language is a standard;
if users can do whatever with ASCII, there is no standard.  If a
metal language can work, it's only by rigorous consistency and
predictability.  No macros, operator overloading, etc, etc.

### A glyphic bestiary

Any metalhead language you don't yet know is line noise.  Let's
get you up to speed as fast as possible.

A programming language needs to be not just read but said.  But
no one wants to say "ampersand."  Therefore, we've taken the
liberty of assigning three-letter names to all ASCII glyphs.

Some of these bindings are obvious and some aren't.  You'll be
genuinely surprised at how easy they are to remember:
```
    ace [1 space]   gal <               pel (
    bar |           gap [>1 space, nl]  per )
    bas \           gar >               sel [
    buc $           hax #               sem ;
    cab _           hep -               ser ]
    cen %           kel {               soq '
    col :           ker }               tar *
    com ,           ket ^               tec `
    doq "           lus +               tis =
    dot .           pam &               wut ?
    fas /           pat @               zap !
    sig ~
{'fraction_non_alphanumeric': 0.08064005069708492, 'fraction_numerical': 0.005386565272496832, 'mean_word_length': 3.135276776940714, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7242518', 'n_tokens_mistral': 3943, 'n_tokens_neox': 3633, 'n_words': 1882}