Hoon is the programming language used to develop applications on Urbit. To fulfill its role, Hoon has some characteristics that make it ideal for a decentralized operating system project. In reality, the language responsible for Urbit’s architecture is Nock.
Hoon exists to serve as an easier and more intuitive language than Nock, being then compiled to Nock.
The idea of using Hoon for applications in Urbit was taken so seriously that the Urbit operating system itself (Arvo) was written in Hoon.
Before showing some code in practice, let’s talk a little about the features of this language:
- Unique syntax: Hoon has a very different syntax from conventional programming languages (like Python). It uses a tree-based notation to represent code and data. This syntax may seem strange at first, but it was designed to be simple and easy to parse.
- Strong typing: Hoon is a strongly typed language, meaning it does not allow a value to be treated or implicitly converted to another type (for example, treating int as float). This helps prevent errors and ensures greater security and robustness in the code.
- Functional programming: Hoon follows the functional programming paradigm, which emphasizes immutability and the absence of side effects. Functional programming results in pure functions and avoids state changes or mutable data.
- Custom type system: Hoon has its own type system called “nouns”, which includes two basic types: “atoms” and “cells”. This approach simplifies type handling and the construction of complex data structures.
Where is functional programming used?
Functional programming languages are particularly well suited for a variety of applications and domains.
Some areas where functional languages are particularly effective include:
- Data processing and analysis: Functional languages are excellent for manipulating and transforming large datasets, thanks to their emphasis on pure functions and immutability. This also facilitates parallelization and distribution of tasks.
- Concurrent and parallel programming: Immutability and the absence of side effects in functional languages make it easier to manage shared state and avoid common concurrency issues, such as race conditions.
- Compiler development and language interpretation: The recursive nature and the ability to express complex transformations with ease make functional languages ideal for developing compilers and interpreters.
- Reactive programming and user interface (UI) development: Functional languages can simplify user interface development and help manage application state more predictably.
- Development of high-performance and reliable systems: Due to the emphasis on correctness and predictability, functional languages can be used to create critical and high-reliability systems, such as financial and aerospace systems.
Hoon in practice
To make it less abstract, let’s show some Hoon code so you can get a better understanding of the language’s syntax.
First, understand that variables in Hoon do not change. This means that if a variable was created with the value of 3, I cannot subsequently assign another value to it. For those familiar with Python, think of tuples here.
To add two numbers in Hoon:
The result of this expression would be 3.
You can test this code in your dojo. Just copy and paste each command in order, one at a time, pressing ENTER before placing each new command. Your dojo will be like this:
In the same way, we could use the same syntax to execute functions:
++div (integer division, no remainder)
++pow (power or exponentiation)
++mod (modulus, remainder after integer division)
++dvr (integer division with remainder)
++max (maximum of two numbers)
++min (minimum of two numbers)
Now let’s create a conditional function that checks if the number entered by the user is 5:
!: =/ check-value |* a=@ ?: =(a 5) "The number is 5" "The number is not 5"
Explaining the code:
- !: =/ check-value: This defines a name (check-value) for the function that will be created. The function will accept an argument, which will be a number.
- |* a=@: This line is the function signature. The |* indicates that the function will receive an argument, and the a=@ means that the argument a will be of the atom type, which is an unsigned integer.
- ?: =(a 5): This line starts with a ternary operator ?:. This operator checks a condition and returns one of the two subsequent results, depending on whether the condition is true or false. The condition here is =(a 5), which tests whether the argument a is equal to 5. If the condition is true, the expression after the condition will be evaluated and returned; otherwise, the other expression will be evaluated and returned.
- “The number is 5”: This is the expression that will be returned if the condition =(a 5) is true (that is, if a is equal to 5).
- “The number is not 5”: This is the expression that will be returned if the condition =(a 5) is false (that is, if a is not equal to 5).
If you copy and paste the code above into your Dojo, you will be creating the check-value function. Now you can call this function with an argument to check the result, by entering in your Dojo:
The output should be “The number is 5”.
Where to learn Hoon
This website has documentation and lessons for those interested in developing applications on Urbit: https://developers.urbit.org/guides/core/hoon-school
To learn more about the Urbit platform, continue reading the articles: