Urbit Docs
  • What is Urbit?
  • Get on Urbit
  • Build on Urbit
    • Contents
    • Environment Setup
    • Hoon School
      • 1. Hoon Syntax
      • 2. Azimuth (Urbit ID)
      • 3. Gates (Functions)
      • 4. Molds (Types)
      • 5. Cores
      • 6. Trees and Addressing
      • 7. Libraries
      • 8. Testing Code
      • 9. Text Processing I
      • 10. Cores and Doors
      • 11. Data Structures
      • 12. Type Checking
      • 13. Conditional Logic
      • 14. Subject-Oriented Programming
      • 15. Text Processing II
      • 16. Functional Programming
      • 17. Text Processing III
      • 18. Generic and Variant Cores
      • 19. Mathematics
    • App School I
      • 1. Arvo
      • 2. The Agent Core
      • 3. Imports and Aliases
      • 4. Lifecycle
      • 5. Cards
      • 6. Pokes
      • 7. Structures and Marks
      • 8. Subscriptions
      • 9. Vanes
      • 10. Scries
      • 11. Failure
      • 12. Next Steps
      • Appendix: Types
    • App School II (Full-Stack)
      • 1. Types
      • 2. Agent
      • 3. JSON
      • 4. Marks
      • 5. Eyre
      • 6. React app setup
      • 7. React app logic
      • 8. Desk and glob
      • 9. Summary
    • Core Academy
      • 1. Evaluating Nock
      • 2. Building Hoon
      • 3. The Core Stack
      • 4. Arvo I: The Main Sequence
      • 5. Arvo II: The Boot Sequence
      • 6. Vere I: u3 and the Serf
      • 7. Vere II: The Loom
      • 8. Vanes I: Behn, Dill, Kahn, Lick
      • 9. Vanes II: Ames
      • 10. Vanes III: Eyre, Iris
      • 11. Vanes IV: Clay
      • 12. Vanes V: Gall and Userspace
      • 13. Vanes VI: Khan, Lick
      • 14. Vanes VII: Jael, Azimuth
    • Runtime
      • U3
      • Conn.c Guide
      • How to Write a Jet
      • API Overview by Prefix
      • C in Urbit
      • Cryptography
      • Land of Nouns
    • Tools
      • Useful Links
      • JS Libraries
        • HTTP API
      • Docs App
        • File Format
        • Index File
        • Suggested Structure
    • Userspace
      • Command-Line App Tutorial
      • Remote Scry
      • Unit Tests
      • Software Distribution
        • Software Distribution Guide
        • Docket File
        • Glob
      • Examples
        • Building a CLI App
        • Debugging Wrapper
        • Host a Website
        • Serving a JS Game
        • Ship Monitoring
        • Styled Text
  • Urbit ID
    • What is Urbit ID?
    • Azimuth Data Flow
    • Life and Rift
    • Urbit HD Wallet
    • Advanced Azimuth Tools
    • Custom Roller Tutorial
    • Azimuth.eth Reference
    • Ecliptic.eth Reference
    • Layer 2
      • L2 Actions
      • L2 Rollers
      • L2 Roller HTTP RPC-API
      • L2 Transaction Format
  • Urbit OS
    • What is Urbit OS?
    • Base
      • Hood
      • Threads
        • Basics Tutorial
          • Bind
          • Fundamentals
          • Input
          • Output
          • Summary
        • HTTP API Guide
        • Spider API Reference
        • Strandio Reference
        • Examples
          • Child Thread
          • Fetch JSON
          • Gall
            • Poke Thread
            • Start Thread
            • Stop Thread
            • Take Facts
            • Take Result
          • Main-loop
          • Poke Agent
          • Scry
          • Take Fact
    • Kernel
      • Arvo
        • Cryptography
        • Move Trace
        • Scries
        • Subscriptions
      • Ames
        • Ames API Reference
        • Ames Cryptography
        • Ames Data Types
        • Ames Scry Reference
      • Behn
        • Behn API Reference
        • Behn Examples
        • Behn Scry Reference
      • Clay
        • Clay API Reference
        • Clay Architecture
        • Clay Data Types
        • Clay Examples
        • Clay Scry Reference
        • Filesystem Hierarchy
        • Marks
          • Mark Examples
          • Using Marks
          • Writing Marks
        • Using Clay
      • Dill
        • Dill API Reference
        • Dill Data Types
        • Dill Scry Reference
      • Eyre
        • EAuth
        • Eyre Data Types
        • Eyre External API
        • Eyre Internal API
        • Eyre Scry Reference
        • Low-Level Eyre Guide
        • Noun channels
      • Gall
        • Gall API Reference
        • Gall Data Types
        • Gall Scry Reference
      • Iris
        • Iris API Reference
        • Iris Data Types
        • Iris Example
      • Jael
        • Jael API Reference
        • Jael Data Types
        • Jael Examples
        • Jael Scry Reference
      • Khan
        • Khan API Reference
        • Khan Data Types
        • Khan Example
      • Lick
        • Lick API Reference
        • Lick Guide
        • Lick Examples
        • Lick Scry Reference
  • Hoon
    • Why Hoon?
    • Advanced Types
    • Arvo
    • Auras
    • Basic Types
    • Cheat Sheet
    • Cryptography
    • Examples
      • ABC Blocks
      • Competitive Programming
      • Emirp
      • Gleichniszahlenreihe
      • Islands
      • Luhn Number
      • Minimum Path Sum
      • Phone Letters
      • Restore IP
      • Rhonda Numbers
      • Roman Numerals
      • Solitaire Cipher
      • Water Towers
    • Generators
    • Hoon Errors
    • Hoon Style Guide
    • Implementing an Aura
    • Irregular forms
    • JSON
    • Limbs and wings
      • Limbs
      • Wings
    • Mips (Maps of Maps)
    • Parsing Text
    • Runes
      • | bar · Cores
      • $ buc · Structures
      • % cen · Calls
      • : col · Cells
      • . dot · Nock
      • / fas · Imports
      • ^ ket · Casts
      • + lus · Arms
      • ; mic · Make
      • ~ sig · Hints
      • = tis · Subject
      • ? wut · Conditionals
      • ! zap · Wild
      • Constants (Atoms and Strings)
      • --, == · Terminators
    • Sail (HTML)
    • Serialization
    • Sets
    • Standard Library
      • 1a: Basic Arithmetic
      • 1b: Tree Addressing
      • 1c: Molds and Mold-Builders
      • 2a: Unit Logic
      • 2b: List Logic
      • 2c: Bit Arithmetic
      • 2d: Bit Logic
      • 2e: Insecure Hashing
      • 2f: Noun Ordering
      • 2g: Unsigned Powers
      • 2h: Set Logic
      • 2i: Map Logic
      • 2j: Jar and Jug Logic
      • 2k: Queue Logic
      • 2l: Container from Container
      • 2m: Container from Noun
      • 2n: Functional Hacks
      • 2o: Normalizing Containers
      • 2p: Serialization
      • 2q: Molds and Mold-Builders
      • 3a: Modular and Signed Ints
      • 3b: Floating Point
      • 3c: Urbit Time
      • 3d: SHA Hash Family
      • 3e: AES encryption (Removed)
      • 3f: Scrambling
      • 3g: Molds and Mold-Builders
      • 4a: Exotic Bases
      • 4b: Text Processing
      • 4c: Tank Printer
      • 4d: Parsing (Tracing)
      • 4e: Parsing (Combinators)
      • 4f: Parsing (Rule-Builders)
      • 4g: Parsing (Outside Caller)
      • 4h: Parsing (ASCII Glyphs)
      • 4i: Parsing (Useful Idioms)
      • 4j: Parsing (Bases and Base Digits)
      • 4k: Atom Printing
      • 4l: Atom Parsing
      • 4m: Formatting Functions
      • 4n: Virtualization
      • 4o: Molds
      • 5a: Compiler Utilities
      • 5b: Macro Expansion
      • 5c: Compiler Backend & Prettyprinter
      • 5d: Parser
      • 5e: Molds and mold builders
      • 5f: Profiling support
    • Strings
    • The Engine Pattern
    • Udon (Markdown-esque)
    • Vases
    • Zuse
      • 2d(1-5): To JSON, Wains
      • 2d(6): From JSON
      • 2d(7): From JSON (unit)
      • 2e(2-3): Print & Parse JSON
      • 2m: Ordered Maps
  • Nock
    • What is Nock?
    • Decrement
    • Definition
    • Fast Hints and Jets
    • Implementations
    • Specification
  • User Manual
    • Contents
    • Running Urbit
      • Cloud Hosting
      • Home Servers
      • Runtime Reference
      • Self-hosting S3 Storage with MinIO
    • Urbit ID
      • Bridge Troubleshooting
      • Creating an Invite Pool
      • Get an Urbit ID
      • Guide to Factory Resets
      • HD Wallet (Master Ticket)
      • Layer 2 for planets
      • Layer 2 for stars
      • Proxies
      • Using Bridge
    • Urbit OS
      • Basics
      • Configuring S3 Storage
      • Dojo Tools
      • Filesystem
      • Shell
      • Ship Troubleshooting
      • Star and Galaxy Operations
      • Updates
Powered by GitBook

GitHub

  • Urbit ID
  • Urbit OS
  • Runtime

Resources

  • YouTube
  • Whitepaper
  • Awesome Urbit

Contact

  • X
  • Email
  • Gather
On this page
  • $vase
  • Create a $vase
  • Extract data from $vase
  • $mark
  • $cage
  • +quip
  • $path
  • $wire
Edit on GitHub
  1. Build on Urbit
  2. App School I

Appendix: Types

This document explains a few of the types commonly used in Gall agents. In addition to these, the Data Types section of the Gall vane documentation is a useful reference. In particular, the whole agent subsection, as well as $bowl, boat, and bitt.

$vase

Vases are used to encapsulate dynamically typed data - they let typed data be moved around in contexts where you can't know the type ahead of time, and therefore can't have a static type.

Vases are used extensively - almost all data your agent will send and received is wrapped in a vase.

A $vase is just a cell with data in the tail and the type of the data in the head. Its formal definition is:

+$  vase  [p=type q=*]

Here's what it looks like if we bunt a $vase in the dojo:

> *vase
[#t/* q=0]

There are two simple runes used to create and unpack vases. We'll look at each of these next.

Create a $vase

The zapgar rune (!>) takes a single argument of any noun, and wraps it in a vase. For example, in the dojo:

> !>([1 2 3])
[#t/[@ud @ud @ud] q=[1 2 3]]

> !>('foo')
[#t/@t q=7.303.014]

> !>([[0xdead 0xb33f] 'foo'])
[#t/[[@ux @ux] @t] q=[[57.005 45.887] 7.303.014]]

> !>(foo='bar')
[#t/foo=@t q=7.496.034]

You would typically use !> as part of a $cage when you're constructing a $card like a poke or a %fact $gift to be sent off.

Extract data from $vase

The zapgal rune (!<) takes two arguments: A mold specifying the type to try and extract the data as, and the $vase to be extracted.

Let's look at an example in the dojo. First, let's create a $vase of [@t @ux @ud]:

> =myvase !>(['foo' 0xabcd 123])
> myvase
[#t/[@t @ux @ud] q=[7.303.014 43.981 123]]

Next, let's try extracting our vase:

> !<  [@t @ux @ud]  myvase
['foo' 0xabcd 123]

Now let's try asking for a @p rather than @t:

> !<  [@p @ux @ud]  myvase
-need.@p
-have.@t
nest-fail

As you can see, it will crash if the type does not nest. Note that rather than using !<, you can also just clam the tail of the $vase like:

> ((trel @t @ux @ud) +.myvase)
[p='foo' q=0xabcd r=123]

The only problem is that you can't tell if the auras were wrong:

> ((trel @p @ud @ux) +.myvase)
[p=~sibtel-tallyd q=43.981 r=0x7b]

You'd typically use !< on the data in $cards that come in from other ships, agents, etc.

$mark

The $mark type is just a @tas like %foo, and specifies the Clay filetype of some data. The $mark corresponds to a mark file in the /mar directory, so a $mark of %foo corresponds to /mar/foo/hoon. Mark files are used for saving data in Clay, validating data sent between agents or over the network, and converting between different data types. For more information about mark files, you can refer to the Marks section of the Clay documentation.

$cage

A $cage is a cell of a $mark and a $vase, like [%foo !>('bar')]. The data in the $vase should match the data type of the specified mark.

Most data an agent sends will be in a $cage, and most data it receives will arrive in a $cage. The $mark may be used to validate or convert the data in the $vase, depending on the context.

+quip

+quip is a mold-builder. A (quip a b) is equivalent to [(list a) b], it's just a more convenient way to specify it. Most arms of an agent return a (quip card _this), which is a list of effects and a new state.

$path

The $path type is formally defined as:

+$  path  (list knot)

A knot is a @ta text atom (see the Strings guide for details), so a $path is just a list of text. Rather than having to write [~.foo ~.bar ~.baz ~] though, it has its own syntax which looks like /foo/bar/baz.

A $path is similar to a filesystem path in Unix, giving data a location in a nested hierarchy. In Arvo though, they're not only used for files, but are a more general type used for several different purposes. Its elements have no inherent significance, it depends on the context. In a Gall agent, a $path is most commonly a subscription path - you might subscribe for updates to /foo/bar on another agent, or another agent might subscribe to /baz on your agent.

A $path might just be a series of fixed @ta like /foo/bar, but some elements might also be variable and include encoded atoms, or some other datum. For example, you might like to include a date in the path like /updates/~2021.10.31..07.24.27..db68. Other agents might create the path by doing something like:

/update/(scot %da now.bowl)

Then, when you get a subscription request, you might do something like:

?+    path  !!
    [%updates @ ~]
  =/  date=@da  (slav %da i.t.path)
  ...(rest of code)...

See the Encoding in text and Decoding from text sections of the Strings guide for more information on dealing with atoms encoded in strings.

Aside from using function calls when constructing a $path as demonstrated above, you can also insert text you're previously stored with =/ or what have you, simply by enclosing them in brackets. For example, in the dojo:

> =const ~.bar
> `$path`/foo/[const]/baz
/foo/bar/baz

$wire

The type of a wire is formally defined as:

+$  wire  path

So, a $wire is just a $path, type-wise they're exactly the same. The reason there's a separate $wire type is just to differentiate their purpose. A $wire is a path for responses to requests an agent initiates. If you subscribe to the $path /some/path on another agent, you also specify /some/wire. Then, when that agent sends out updates to subscribers of /some/path, your agent receives them on /some/wire.

More formally, $wires are used by Arvo to represent an event cause, and therefore return path, in a call stack called a $duct. Inter-vane communications happen over $ducts as $moves, and Gall converts the $cards produced by agents into such $moves behind the scenes. A detailed understanding of this system is not necessary to write Gall agents, but if you're interested it's comprehensively documented in the Arvo overview and move trace tutorial.

For agents, the $wire is specified in the second argument of a %pass $card. It's used for anything you can %pass, such as %pokes, %watches, and %arvo notes. For example:

[%pass /this/is/wire %agent [~zod %foobar] %watch /this/is/path]
::
[%pass /this/is/wire %agent [~zod %foobar] %poke %foo !>('hello')]
::
[%pass /this/is/wire %arvo %b %wait (add now.bowl ~m1)]

The +on-agent and +on-arvo arms of the agent core include a $wire in their respective sample. Responses from agents come in to the former, and responses from vanes come in to the latter.

Previous12. Next StepsNextApp School II (Full-Stack)

Last updated 1 day ago