Urbit Developers
  • Lightning Tutorials

    • Introduction
    • Build a Groups App
    • Build a Chat App
    • Build a Voting App
    • Core Curriculum

      • Hoon School

        • Introduction
        • 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

          • Introduction
          • 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)

            • Introduction
            • 1. Types
            • 2. Agent
            • 3. JSON
            • 4. Marks
            • 5. Eyre
            • 6. React app setup
            • 7. React app logic
            • 8. Desk and glob
            • 9. Summary
          • Environment Setup
          • Additional Guides

            • Hoon Workbook

              • Competitive Programming
              • Gleichniszahlenreihe
              • Rhonda Numbers
              • Roman Numerals
              • Solitaire Cipher
              • App Workbook

                • %ahoy Ship Monitoring
                • %dbug Debugging Wrapper
                • %flap JS Client
                • %feature Page Hosting
                • Threads

                  • Fundamentals
                  • Bind
                  • Input
                  • Output
                  • Summary
                • Aqua Tests
                • Command-Line Apps
                • HTTP API
                • JSON
                • Parsing Text
                • Sail (HTML)
                • Software Distribution
                • Strings
                • Unit Tests
                • Vases
                Urbit Developers
                • Lightning Tutorials

                  • Introduction
                  • Build a Groups App
                  • Build a Chat App
                  • Build a Voting App
                  • Core Curriculum

                    • Hoon School

                      • Introduction
                      • 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

                        • Introduction
                        • 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)

                          • Introduction
                          • 1. Types
                          • 2. Agent
                          • 3. JSON
                          • 4. Marks
                          • 5. Eyre
                          • 6. React app setup
                          • 7. React app logic
                          • 8. Desk and glob
                          • 9. Summary
                        • Environment Setup
                        • Additional Guides

                          • Hoon Workbook

                            • Competitive Programming
                            • Gleichniszahlenreihe
                            • Rhonda Numbers
                            • Roman Numerals
                            • Solitaire Cipher
                            • App Workbook

                              • %ahoy Ship Monitoring
                              • %dbug Debugging Wrapper
                              • %flap JS Client
                              • %feature Page Hosting
                              • Threads

                                • Fundamentals
                                • Bind
                                • Input
                                • Output
                                • Summary
                              • Aqua Tests
                              • Command-Line Apps
                              • HTTP API
                              • JSON
                              • Parsing Text
                              • Sail (HTML)
                              • Software Distribution
                              • Strings
                              • Unit Tests
                              • Vases
                              Guides/Core Curriculum/App School II (Full-Stack)

                              4. Marks

                              In this section we'll write the mark files for our agent. We'll need two marks, one for poke $actions and one for subscription updates and scry results, both of which are $updates. Our $action mark will be called %journal-action and our $update mark will be called %journal-update. These will be located at /mar/journal/action.hoon and /mar/journal/update.hoon.

                              Note that a mark called %foo-bar will first be looked for in /mar/foo-bar.hoon, and if it's not there it will be looked for in /mar/foo/bar.hoon. That's why we can have a single name like %journal-action but have it in /mar/journal/action.hoon

                              %journal-action

                              Click to expand

                              /- *journal
                              /+ *journal
                              |_ act=action
                              ++ grow
                              |%
                              ++ noun act
                              --
                              ++ grab
                              |%
                              ++ noun action
                              ++ json dejs-action
                              --
                              ++ grad %noun
                              --

                              First we import our /sur/journal.hoon structure file and also our /lib/journal.hoon library (containing our $json conversion functions). The sample of our mark door is just our $action structure. The ++grow arm of a mark core, if you recall, contains methods for converting from our mark to another mark. Actions only ever come inwards in pokes, so we don't need to worry about converting an $action to $json. The ++grow arm can therefore just handle the generic %noun case, simply returning our mark door's sample without doing anything.

                              ++grab, conversely, defines methods for converting to our mark from another mark. Since $actions will come in from the front-end as $json, we need to be able to convert $json data to our $action structure. Our /lib/journal.hoon library contains the ++dejs-action function for performing this conversion, so we can just specify that function for the %json case. We'll also define a standard %noun method, which will just "clam" (or "mold") the incoming noun with the $action mold. Clamming/molding coerces a noun to a type and is done by calling a mold as a function.

                              Lastly, ++grad defines revision control methods, but can be delegated to another mark. Since this mark will never be used for actually storing files in Clay, we can just delegate it to the generic %noun mark rather than writing a proper set of ++grad methods.

                              %journal-update

                              Click to expand

                              /- *journal
                              /+ *journal
                              |_ upd=update
                              ++ grow
                              |%
                              ++ noun upd
                              ++ json (enjs-update upd)
                              --
                              ++ grab
                              |%
                              ++ noun update
                              --
                              ++ grad %noun
                              --

                              Next we have our %journal-update mark file. The sample of our mark door is our $update structure. Our $updates are always outbound, never inbound, so we only need to define a method for converting our $update structure to $json in the ++grow arm, and not the opposite direction in ++grad. Our /lib/journal.hoon library contains the ++enjs-update function for performing this conversion, so we can call it with the sample $update as its argument. We can add %noun conversion methods and delegate revision control to the %noun mark in the same manner as our %journal-action mark above.

                              Resources

                              • The Marks section of the Clay documentation - This section of the Clay vane documentation covers mark files comprehensively.

                              • The mark file section of the Gall Guide - This part of App School goes through the basics of mark files.

                              • The JSON Guide - This also covers writing mark files to convert to/from JSON.

                              <-

                              3. JSON

                              5. Eyre

                              ->

                              Edit this page on GitHub

                              Last modified March 17, 2023