## Temperature conversion

In this worked example, we look at temperature conversion between Celsius, Kelvin and Fahrenheit. In our last example we mentioned the star ket |*>, which defines an operator with respect to all kets. Well, this time we have a variant of the star ket, one where we also specify a "category". So |K: *> is used to define an operator with respect to only kets that have the category "K". Likewise |C: *> defines an operator with respect to all kets with the category "C". Where we are using K as the category for Kelvin temperatures, C for Celsius temperatures, and F for Fahrenheit temperatures. Next feature we need to describe is the #=> learn rule. This learn rule has the property that the RHS is only calculated at invoke time, not at definition time, as is the case with the standard learn rule =>. And unlike the memoizing learn rule !=> we don't store the results of the computation. Next, we have __ which is an infix operator that concatenates the labels of the given pair of kets, with a single space char between them. In contrast to the _ infix operator that concatenates the labels without a space char between the labels. Eg:

```sa: |string1> __ |string2>
|string1 string2>

sa: |string1> _ |string2>
|string1string2>
```

round[n] rounds the value in the ket label to n decimal places. minus[n] subtracts n from the ket label it is applied to. plus[n] adds n to the given ket. extract-value removes the category from the given ket. And times-by[n] multiplies by n. And that is all we need to define our temperature conversion operators. Using the star ket and the stored-rule learn rule, we also provide some alias's. So the to-K operator just invokes the to-Kelvin operator, and so on for to-C and to-F.

Here is the code:

```-- Convert between Kelvin, Celsius and Fahrenheit:

to-Kelvin |K: *> #=> |_self>
to-Celsius |K: *> #=> |C:> __ round[2] minus[273.15] extract-value |_self>
to-Fahrenheit |K: *> #=> |F:> __ round[2] minus[459.67] times-by[9/5] extract-value |_self>

to-Kelvin |C: *> #=> |K:> __ round[2] plus[273.15] extract-value |_self>
to-Celsius |C: *> #=> |_self>
to-Fahrenheit |C: *> #=> |F:> __ round[2] plus[32] times-by[9/5] extract-value |_self>

to-Kelvin |F: *> #=> |K:> __ round[2] times-by[5/9] plus[459.67] extract-value |_self>
to-Celsius |F: *> #=> |C:> __ round[2] times-by[5/9] minus[32] extract-value |_self>
to-Fahrenheit |F: *> #=> |_self>

to-K |*> #=> to-Kelvin |_self>
to-C |*> #=> to-Celsius |_self>
to-F |*> #=> to-Fahrenheit |_self>

table[Celsius, to-Kelvin, to-Fahrenheit] range(|C: 0>, |C: 100>, |5>)
```

Here is the output from the code:

```+---------+-----------+---------------+
| Celsius | to-Kelvin | to-Fahrenheit |
+---------+-----------+---------------+
| C: 0    | K: 273.15 | F: 32         |
| C: 5    | K: 278.15 | F: 41         |
| C: 10   | K: 283.15 | F: 50         |
| C: 15   | K: 288.15 | F: 59         |
| C: 20   | K: 293.15 | F: 68         |
| C: 25   | K: 298.15 | F: 77         |
| C: 30   | K: 303.15 | F: 86         |
| C: 35   | K: 308.15 | F: 95         |
| C: 40   | K: 313.15 | F: 104        |
| C: 45   | K: 318.15 | F: 113        |
| C: 50   | K: 323.15 | F: 122        |
| C: 55   | K: 328.15 | F: 131        |
| C: 60   | K: 333.15 | F: 140        |
| C: 65   | K: 338.15 | F: 149        |
| C: 70   | K: 343.15 | F: 158        |
| C: 75   | K: 348.15 | F: 167        |
| C: 80   | K: 353.15 | F: 176        |
| C: 85   | K: 358.15 | F: 185        |
| C: 90   | K: 363.15 | F: 194        |
| C: 95   | K: 368.15 | F: 203        |
| C: 100  | K: 373.15 | F: 212        |
+---------+-----------+---------------+
|table>
```

Raw file here.