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
Edit on GitHub
  1. Urbit OS
  2. Kernel
  3. Clay

Marks

Clay is a typed filesystem, and we call these file types marks. When talking about Hoon and Arvo we'll often talk of types like @ud, (list @t), etc. A mark will specify such a type for its files, but it does more than just that - it also defines conversion routines to and from other marks, as well as diff, patch, and merge routines.

For example, a %txt mark defines the type of a %txt file as a $wain (a (list @t). It defines a conversion function to a %mime mark to allow it to be serialized and sent to a browser or to the Unix filesystem. It also includes Hunt-McIlroy) diff, patch, and merge algorithms. Conversion functions will be different for different marks, as will things like diff algorithms. An image mark like %png, for example, just replaces the old blob of data with the new one rather than implementing a complex binary diff and patch algorithm, so how these functions are implemented depends on the file type and use case.

mark files are stored in the /mar directory. The path of the %txt mark, for example, is /mar/txt/hoon.

A mark is a door (a core with a sample) with three arms: +grab, +grow, and +grad. The door's sample defines its type. In +grab is a series of functions to convert from other marks to the given mark. In +grow is a series of functions to convert from the given mark to other marks. In +grad is +diff, +pact, +join, +mash, and +form.

Here's its basic structure in an informal pseudocode:

|_  <mark-type>
++  grab
  ++  noun <noun> -> <mark-type>
  ++  mime <mime> -> <mark-type>
  ++  txt <txt> -> <mark-type>
  ::  ...
++  grow
  ++  noun <mark-type> -> <noun>
  ++  mime <mark-type> -> <mime>
  ++  txt <mark-type> -> <txt>
  ::  ...
++  grad
  ++  form <diff-mark>
  ++  diff (<mark-type>, <mark-type>) -> <diff-type>
  ++  pact (<mark-type>, <diff-type>) -> <mark-type>
  ++  join (<diff-type>, <diff-type>) -> <diff-type> or NULL
  ++  mash (<diff-type>, <diff-type>) -> <diff-type>

These types are basically what you would expect. In +grab, only a +noun arm is mandatory, the rest are optional. The +grow arm itself is optional, as are any arms within it. In +grad, all arms are mandatory unless revision control is delegated to another mark, which we'll discuss later.

In general, for a particular mark, the +grab and +grow entries should be inverses of each other. They needn't be symmetrical though: you may want to be able to convert from your mark to %json but not from %json to your mark, for example.

In +grad, +diff takes two instances of a mark and produces a diff of them whose mark is given by +form. +pact takes an instance of a mark and patches it with the given diff. In general, if +diff called with A and B produces diff D, then +pact called with A and D should produce B.

+join takes two diffs and attempts to merge them into a single diff. If there are conflicts, it produces null. +mash takes two diffs and forces a merge, even if there are conflicts. How your +mash function force-merges conflicting diffs is up to you. The %txt mark annotates any conflicts, for example, but there may be other ways. If +join of two diffs does not produce null, then +mash of the same diffs should produce the same result. Note that +mash is not used by Clay in its ordinary filesystem operations, so you may wish to leave it as a dummy arm that crashes if called.

Alternately, instead of +form, +diff, +pact, +join, and +mash, a mark can provide the same functionality by defining +grad to be the name of another mark to which we wish to delegate the revision control responsibilities. Then, before running any of those functions, Clay will convert to the other mark, and convert back afterward. For example, the %hoon mark is revision-controlled in the same way as %txt, so its +grad is simply ++ grad %txt. Of course, +txt must be defined in +grow and +grab as well.

We mentioned that +noun is the only mandatory arm in +grab, but there are a couple of others that, while not mandatory, are of particular interest.

The first is a +mime arm for converting to and from the %mime mark. When you |commit a file to a desk mounted to Unix, Clay will receive the data as a %mime mark, and then convert it to the mark matching the file extension. It will perform the same operation in reverse when mounting a desk to Unix. For this reason, any mark you wish to be able to access from the Unix filesystem should have %mime conversion routines. In certain cases (such as the scry interface), Eyre will also need to convert your mark to a %mime in order to encode it in an HTTP response, so you may require a +mime arm for that reason as well.

The second case of interest is the +json arm for converting to and from a %json mark. If, for example, you want to write a Gall agent to which you can subscribe through Eyre's channel system, it must produce data with a mark containing %json conversion routines. If it doesn't, Eyre will not be able to deliver the data to the subscribed HTTP client in the SSE stream.

Sections

  • Writing Marks - A practical walkthrough of writing a mark file.

  • Using Marks - Details of using mark conversion gates and mark cores in your own code.

  • Examples - The example code used in the Writing Marks guide.

PreviousFilesystem HierarchyNextMark Examples

Last updated 1 day ago