web/contents/learn.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
<article> <h2>The Tutorial</h2> <ul> <li><a href="#hey">Hey!</a></li> <li><a href="#setting-things-up">Setting things up</a></li> <li><a href="#working-with-things">Working with things</a></li> <li><a href="#the-stack">The Stack</a></li> <li><a href="#the-registry">The Registry</a></li> <li><a href="#hexxing-all-the-way">Hexxing all the way!</a></li> </ul> <h3 id="hey">Hey!<a href="#top"></a></h3> <p>So you want to learn <em>hex</em> huh? Well, you are in the right place.</p> <p><em>hex</em> is...</p> <ul> <li>...<strong>tiny</strong>: a single executable, just a few hundreds KBs in size.</li> <li>...<strong>minimalist</strong>: just integers, strings, arrays, and symbols. No statements, no expressions, and (almost) no variables.</li> <li>...<strong>concatenative</strong>: think <em>reverse Polish notation</em>, postfix syntax, stack-based.</li> <li>...<strong>slightly-esoteric</strong>. It definitely got quirks: hexadecimal-only integers, global-only symbols, ...things like that.</li> </ul> <p>In a word: <em>magical</em>! Hence the name. Really. And the hexadecimal integer thing of course, that too.</p> <h3 id="setting-things-up">Setting things up<a href="#top"></a></h3> <p>Now that you know what <em>hex</em> is, you have to <a href="/get">get</a> it, <em>then</em> you can run it. Or not really, you can just go <a href="/play">here</a> and play with it.</p> <p><em>If</em> you got hex, it's just a single executable. You can run it with options, or without, as explained on the <a href="/get">Get</a> page. </p> <p>You can even double-click it, especially if you are on Windows. That will bring up the REPL, which well... reads from input, evaluates what you enter, prints the result (or better, the first item on <em>The Stack</em>), and then loops again.</p> <h3 id="working-with-things">Working with things<a href="#top"></a></h3> <p><em>hex</em> is tiny. I may have said that already. It is also <em>simple</em>. As such, it doesn't really have fancy things like objects, or... floating-point numbers, for example.</p> <p>Instead, it focuses on making do with just a few things, or better, <em>data types</em>.</p> <p>It understands <strong>integers</strong> like 27 or -19, except that if you type any of those in the REPL (go on, <a href="/play">try it</a>!) and press ENTER, you'll get something like this: </p> <pre><code>[error] Invalid symbol: 27</code></pre> <p>Right, because <em>hex</em> only understands integers in hexadecimal format. </p> <p>Now, if you type <code>$0x1b$$</code> instead... well, at least it doesn't complain, right? You can try entering <code>$0xffffffed$$</code> now (that's -19 in hexadecimal format using <a href="https://en.wikipedia.org/wiki/Two%27s_complement">two's complement</a>), and that works too.</p> <p>Now what just happened is that you pushed two values (integers, even) on <em>The Stack</em> (more on this later). Since you have two numbers on The Stack already, you may as well enter {{sym-+}} to add them up, and that gives you: </p> <pre><code>0x8</code></pre> <p>Jolly good. </p> <p>Now... <code>$:+$$</code> is actually a <strong>symbol</strong>; and symbols... well, they do tricks, those symbols, every time you try to push them on the stack. </p> <p>For example, <code>$:+$$</code> takes the first two items on the stack, adds them together, and puts the result on the stack. </p> <p>You can now enter <code>"eight"</code> in the REPL. See the double quotes? That's a <strong>string</strong>. Strings work in the same way as in other programming languages. Nothing weird, I promise. Of course strings can only be delimited via double quotes, not single, angular, circular, or whatever quotes. Just <em>double</em> quotes. </p> <p>Next... let's see. You can type {{sym-:}} (which is another symbol), and... nothing happens! </p> <p>Or better, nothing gets pushed back on The Stack. <code>$::$$</code> is a greedy, selfish symbol that just eats a value (any literal) and a string, and doesn't put anything back on The Stack.</p> <p>Now type <code>$:eight$$</code> (with no quotes) and press ENTER:</p> <pre><code>0x8</code></pre> <p>Aha! It turns out that our <code>$::$$</code> friend works for <em>The Registry</em>. The Registry likes to keep things for itself. Values don't just get pushed and popped from The Registry, no sir! It ain't like The Stack. Once you are in, you are in, and you can't get out that easily (unless you are <a href="/spec#free-symbol">freed</a>).</p> <p>Clear? No? Well, you'll get there kid, eventually. </p> <p>What's missing? Let's see, we talked about <em>integers</em>, <em>strings</em>, and even a little bit about <em>symbols</em>... Ah! Right: <strong>quotations</strong>, of course!</p> <p>A quotation is a fancy name for an array, or a list. In <em>hex</em> quotations have no internal separators between items, and are delimited by ~~square~~ round brackets, like this:</p> <pre><code>($0x1$$ $"two"$$ $:three$$ $:!$$)</code></pre> <p>Oh my! You really can put <em>anything</em> in quotations, right? Assuming that it's a valid literal, a known native symbol (like {{sym-!}}), or a syntactically-valid user-defined symbol (even if it doesn't exist, like <code>$:three$$</code>). You can even nest a quotation in another quotation, and another, and another... </p> <p>...And nothing will happen by the way: quotations sit neatly on the stack like other literals. Until some pesky symbol decides to dequote them, like {{sym-.}}, which strips a quotation and puts all its items on the stack! Oi! The naughty boy!</p> <h3 id="the-stack">The Stack<a href="#top"></a></h3> <p>We had to mention The Stack earlier, it was unavoidable. See, The Stack is where the magic happens! But what is it, you ask? Well, let's try a simple example and try to use hex to subtract 3 from 5, and take it reeeally slow.</p> <p>Fiiiirst we start a hex REPL.</p> <p>Then, we enter <code>$0x5$$</code> and press <code>ENTER</code>. <code>$0x5</code> gets <em>pushed on The Stack</em>, like this:</p> <pre><code> +-----------+ | 0x5 | +-----------+</code></pre> <p>Then, we enter <code>$0x3$$</code> on The Stack. Now there are two items on The Stack, like this:</p> <pre><code> +-----------+ | 0x3 | +-----------+ | 0x5 | +-----------+</code></pre> <p>Great, and finally, we are going to push the symbol {{sym--}} on the stack, because that's how postfix notation (a.k.a. <a href="https://en.wikipedia.org/wiki/Reverse_Polish_notation">Reverse Polish Notation</a>) works: <em>first</em> the operands, and <em>then</em> the operators. </p> <p>Anyhow, what happens to The Stack now? Waait... wait...</p> <pre><code> * * - * +-----------+ | 0x3 | +-----------+ | 0x5 | +-----------+</code></pre> <p>...magic! Real quick, <code>$:-$$</code> takes two items from The Stack, performs the subtraction, aaaand pushes the result back on The Stack, that now looks like this:</p> <pre><code> +-----------+ | 0x2 | +-----------+</code></pre> <p>Symbols ain't that bad after all. And yes, The Stack is AWESOME! Did you know that if you use postfix notation you will NEVER ever need to use parenthesis when performing math operations to tweak operator preference? No? Let's try it. Let's calculate <code>(3 + 2) * 7</code>:</p> <p>First, the sum, right? so:</p> <pre><code>$0x3$$ $0x2$$ $:+$$</code></pre> <p>...then we simply add the multiplication, and so we have it:</p> <pre><code>$0x3$$ $0x2$$ $:+$$ $0x7$$ $:*$$</code></pre> <p>If we take this further, you can use The Stack as an accumulator for your program state, and <em>never, ever use a variable</em>.</p> <p>Whaaaaaaat?</p> <p>Yeah, mind blown. That's how purists of concatenative programming languages would write programs huh? Well, the problem with it is that programs written like that tend to become a wee bit hard to read (but definitely not for purists of concatenative programming languages).</p> <p>Sooooo that's why next to <em>The Stack</em>, we also have... <em>The Registry</em>!</p> <h3 id="the-registry">The Registry<a href="#top"></a></h3> <p><em>The Registry</em> knows everything. It is the place that contains all the definitions of all <em>hex</em> symbols, both the 64 native symbols that are built-in, and also any symbol that you may want to create.</p> <p>The one thing to remember about The Registry is that it is only one. You can't have more than one, no sir, so anything you put in there will become available <em>anywhere</em> within an hex program. Yes you read it right: </p> <p><strong>every symbol in hex is global</strong></p> <p>Let that sink in. </p> <p>Sure, it's not the best design in the world, but it has the advantage of being a very simple thing to implement and use. You have to know it, and you have to be very careful with it.</p> <p>Now... to add a new symbol to The Registry, you use the {{sym-:}} symbol. That can also be used to overwrite existing symbols with new values, but not native symbols.</p> <p>Say we want to teach hex some Roman numerals... we could do this:</p> <pre><code> $0x1$$ $"I"$$ $::$$ $0x2$$ $"II"$$ $::$$ $0x3$$ $"III"$$ $::$$ $0x4$$ $"IV"$$ $::$$ $; ...$$</code></pre> <p>Then, you could use them like ordinary symbols:</p> <pre><code>$:I$$ $:IV$$ $:+$$ $; Pushes 0x5 on the stack</code></pre> <p>If you don't need a symbol anymore, you can use the {{sym-#}} symbol to free it from The Registry. See? Simple. </p> <p>Of course The Registry is smart enough to stop you from freeing native symbols!</p> <p>So if you try to remove $:+$$...</p> <pre><code>$"+"$$ $:#$$</code></pre> <p>...you'll get:</p> <pre><code>[error] Cannot free native symbol '+'</code></pre> <h3 id="hexxing-all-the-way">Hexxing all the way!<a href="#top"></a></h3> <p>An there you have it! Now technically you know everything you need about hex, and you can go off hexxing away on your own! Off you go then!</p> <p>...What? You don't even know how to implement a loop or a condition? But it's all the same! It's always values pushed and popped from the stack using symbols!</p> <p>Alright, let's do something actually useful. I know: let's implement a new operator to implement the <em>factorial</em> of an integer! You never know when you'll need a factorial these days.</p> <p>Here goes:</p> <pre><code>( $"_n"$$ $:$$ ($:_n$$ $0x0$$ $:<=$$) ($0x1$$) ($:_n$$ $:_n$$ $0x1$$ $:-$$ $:factorial$$ $:*$$) $:if$$ $"_n"$$ $:#$$ ) $"_factorial"$$ $:::$$ $0x5$$ $:factorial$$ $:dec$$ $:puts$$ $; Prints 120 $$ </code></pre> <p>Woah! That was a mouthful, wasn't it? Before breaking it down, look at the very end of the program: see that {{sym-::}}? That's the symbol to store <em>operator</em> symbols in The Registry. Operator symbols are defined using a quotation, but unlike ordinary quotations (stored using {{sym-:}}), they will be <em>immediately dequoted</em> when pushed on the stack. In other words, our $:factorial$$ operator symbols will behave exactly like one of the built-in native symbol.</p> <p>Let's see what is happening inside the quotation:</p> <ul> <li>First, we are storing a symbol "_n" in the registry. Wait, but there's no value? Correct, the value will be provided when the symbol is used, so like $0x5$$ $:factorial$$. It's like saying that we are <em>expecting</em> a value on the stack (and here we are assuming it's an integer, but that's ok for this example).</li> <li>Then three (!) quotations and the symbol {{sym-if}} will be pushed on the stack. Yep, you got that right: that's a good old if clause. The first quotation is the condition to be checked, then the <em>then</em> quotation, and finally the <em>else</em> quotation. Note how we can recursively call the $:factorial$$ operator that we are just defining... mind-blowing, I am sure.</li> <li>Finally, we need to free the temporary symbol $:_n$$ using {{sym-#}}. It is always good practice to do so, otherwise The Registry will be littered with stale symbols nobody uses anymore... quite a sore sight, believe me! Plus they take up precious memory.</li> </ul> <p>OK! Now you gotta have enough.</p> <p>What?! Still no loops huh? Go read about it in the specification {{sym-while}} symbol... takes two quotations... one for the condition and the other for the body of the loop. Really not rocket science once you get used to The Stack and The Registry.</p> <p>And this concludes our brief but dense tour of <em>hex</em>, the slightly-esoteric concatenative programming language. I hope you enjoyed our time together. If not, tough luck, no refunds, go learn a lisp next time instead! ;)</p> <p><em>Happy hexxing!</em></p> </article> |