@@ -1,11 +1,14 @@
11+++
2−title = "Iron Polymorphism and Wet Polymorphism: ++fold Walkthrough"
3−weight = 0
2+title = "Walkthrough: Iron Polymorphism and Wet Polymorphism"
3+weight = 32
44template = "doc.html"
55+++
66
7−Polymorphism, the ability to have some piece of code use different types a different times, is a common technique used in many languages to create reusable code. Hoon also has polymorphism, though it is different from what you have probably experienced. Let us example a gate from the Hoon standard library as an example of a few types. This is an excerpt from `hoon.hoon` and as such, will not run as is by itself.
7+Polymorphism is a programming concept that allows a a piece of code to use different types at different times. It's a common technique in most languages to make code that can be reused for many different situations, and Hoon is no exception. Let's take a look at a gate from the Hoon standard library as an example; we'll be passing a few different types in. The code below is an excerpt from `hoon.hoon` and, as such, will not run as-is by itself.
88
9+`fold` is a _wet_ gate that takes two arguments and produces a _dry_ gate. But what are wet and dry gates?
10+
11+A dry gate (also simply a _gate_) is the kind that you're already familiar with by now: a one-armed core with a sample. A wet gate is also a one-armed core with a sample, but there is a difference. With a dry gate, when you pass in an argument and the code gets compiled, the type system will try to cast to the type specified by the gate; if you pass something that does not fit in the specified type, for example a `cord` instead of a `cell` you will get a nest failure. On the other hand, when you pass arguments to a wet gate, their types are preserved and type analysis is done at the definition site of the gate -- in our case, `fold` in `hoon.hoon` -- rather than the call site.
912
1013```
1114++ fold
@@ -17,19 +20,17 @@ Polymorphism, the ability to have some piece of code use different types a diffe
1720 $(xs t.xs, st (f st i.xs))
1821```
1922
20−`fold` is a wet gate that takes two arguments and produces a dry gate. What are wet and dry gates? A dry gate is the kind you have seen and written previously to this, a one armed core with a sample. A wet gate is also a one armed core with a sample but there is a difference. With a dry gate, when you pass in an argument and the code gets compiled the type system will try to cast to the type specified by the gate. If you pass something that does not fit in the specified type, for example a `cord` instead of a `cell` you will get a nest failure. On the other hand, when you pass arguments to a wet gate, their types are preserved and type analysis is done at the definition site of the gate rather than the call site. This can lead to some confusing errors so be aware of that when using wet gates.
21−
22−`state` and `elem` are both `mold` that is to say they are type definitions. We actually use this to define the types used in the dry gate.
23+On the first line of the arm, we use `|*` to create a wet gate, with two arguments: `state` and `elem`. These arguments are both `mold`s; that is to say, they are type definitions. We use this to define the types used in the dry gate.
2324
2425```
2526|= [[st=state xs=(list elem)] f=$-([state elem] state)]
2627```
2728
28−The first thing this gate takes is a cell `[st=state xs=(list elem)]`. `state` is the type we passed in first to our wet gate, and will be the type that is produced by the dry gate. `st` is a value of type `state` that will be used as an accumulator of some sort and will be the final value returned when the dry gate is called.
29+Here we begin to define our dry gate. The first thing the dry gate takes is a cell, `[st=state xs=(list elem)]`. `state` is the type we passed in first to our wet gate, and will be the type that is produced by the dry gate. `st` is a value of type `state` that will be used as an accumulator, and will be the final value returned when the dry gate is called.
2930
30−The second argument is `f=$-([state elem] state)`. `$-` is a rune that takes two type operands `[state elem]` and `state` and produces a `mold` of gate that maps from the first type operand to the second. This will match a gate we provide `fold` for how to map from both the `state`.
31+The second argument is `f=$-([state elem] state)`. `$-` is a rune that takes two type arguments, `[state elem]` and `state` in this case, and produces a `mold` of a gate that maps from the first type operand to the second. This will match a gate we provide `fold` for how to map from both the `state`.
3132
32−The rest of the gate is very straightforward.
33+The rest of the dry gate is straightforward:
3334
3435```
3536 ^- state
@@ -38,7 +39,7 @@ The rest of the gate is very straightforward.
3839 $(xs t.xs, st (f st i.xs))
3940```
4041
41−We ensure the output is of type `state`, check if `xs`, the list is empty, if it is we return st, otherwise we call `f` on `i.xs`, the head of the list, and set `xs` to be the tail of the list and repeat.
42+We ensure the output is of type `state`. Then we check if `xs`, the list, is empty. If it is, we return `st`. Otherwise, we call `f` on `i.xs`, the head of the list, and set `xs` to be the tail of the list and repeat.
4243
4344Lets look at two examples of using `fold`.
4445
@@ -53,7 +54,8 @@ Lets look at two examples of using `fold`.
5354
5455Here we have a call to `fold` that we can see will produce a `(list @)` from a list of `@`. The first argument is a cell of `~` and `~[1 2 3 4]`.
5556
56−The gate will simply add two to each element `e` and append that to the front of `s`. If we run this in the `dojo`
57+
58+The gate will simply add two to each element `e` and append that to the front of `s`. Let's run this in the `dojo`:
5759
5860```
5961> %+ (fold (list @) @)
@@ -63,12 +65,14 @@ The gate will simply add two to each element `e` and append that to the front of
6365 :_ s
6466 (add 2 e)
6567~[6 5 4 3]
66−~zod:dojo>
68+
69+~zod:dojo>
6770```
6871
69−The list is in reverse order simply because it's easier to add to the front of a list than the end. If you needed it in the same order you could simply `flop` it.
72+The list is in reverse order simply because it's easier to add to the front of a list than the end. If you needed it in the same order, you could just `flop` it.
73+
74+But `fold` does not have to produce a `list`. Let's look at another example:
7075
71−But `fold` does not have to produce a `list`. Let's look at another example.
7276
7377```
7478%+ (fold @ @)
@@ -77,6 +81,10 @@ But `fold` does not have to produce a `list`. Let's look at another example.
7781(add e s)
7882```
7983
80−Here `fold` will produce a gate that takes an `atom` and applies a gate to a `list` of `atoms`. The difference here is that this call will produce a sum of the elements of the list.
8184
82−The key thing to take away from both of these examples is that the gates provided are iron polymorphic with the definition of the type in `fold`. Their samples next under one another, `s` and `e` nest under the types `state` and `elem` in this case because when we provided those to `fold` was stated they were `@` and `@`. In the first case, we stated that `state` was `(list @)` and `elem` was `@`. In both cases the sample of each gate nest inside the types defined when we called the wet gate `fold`.
85+Here `fold` will produce a gate that takes an `atom` and applies a gate to a `list` of `atoms`. The difference here is that this call will produce a sum of the elements of the list, rather than the list itself.
86+
87+The key takeaway from both of these examples is that the gates provided are _iron polymorphic_ with respect to the definition of the type in `fold`. They are iron polymorphic because samples `s` and `e` nest under the types `state` and `elem`. In second case case, that's because when we provided those to `fold`, it was was stated they were `@` and `@`. In the first case, we stated that `state` was `(list @)` and `elem` was `@`. In both cases, the sample of each gate nest inside the types defined when we called the wet gate `fold`.
88+
89+
90+[Next Up: Reading -- Gall](../gall)