Understanding What It's Like to Program in Forth (2008)
James Hague has a lot more Forth experience than I do.  But I would initially write this function something like this:<p><pre><code>    variable v1  variable v2  variable v3
    : vadd v3 ! v2 ! v1 !
      3 0 do  v1 @ i cells + @  v2 @ i cells + @  +  v3 @ i cells + !  loop ;
</code></pre>
Or, alternatively:<p><pre><code>    0 value v1  0 value v2  0 value v3
    : vvadd to v3 to v2 to v1
      3 0 do  v1 i cells + @  v2 i cells + @  +  v3 i cells + !  loop ;
</code></pre>
I mean, yes, you <i>can</i> make it a puzzle.  But you don&#x27;t <i>have</i> to.  These versions will be slower than Hague&#x27;s first working version and probably the second too, but all of Hague&#x27;s versions are slower (with any Forth compiler I&#x27;ve used) than what GCC will give you for the C version.  And what GCC will give you for the C version, even if it improbably manages to vectorize, is also a lot slower than what you&#x27;ll get if you do your vec3 math on your GPU.  So maybe when it comes time to rewrite the naïve Forth version above, because it <i>is</i> slow, you should just code an SSE assembly routine and skip the manual loop unrolling at the Forth level, or restructure the whole system to do the vector math on the GPU.<p>Or maybe not.  James Hague is a smart guy and he&#x27;s shipped a lot of code, in assembly, C, and Forth.  But I&#x27;d like to understand where my reasoning is going wrong, because I can&#x27;t see it.<p>My perspective on Forth is that it&#x27;s the thinnest possible layer on top of raw machine code that gives you all the fundamental mechanisms for improving your leverage.  You need structured control flow, so it has IF ELSE THEN, DO LOOP, BEGIN WHILE REPEAT, and a couple of others.  You need expressions, so it has an operand stack.  You need procedural abstraction, so it has a return stack, which also serves to store loop counters.  You need labels both to make your code readable and so that you can patch your code without overwriting parts of it with JMP instructions to wherever you have free space to put the patch code, so it has words.  You need metaprogramming, so it has IMMEDIATE.  You need run-time polymorphic procedure dispatch, so it has &#x27;, EXECUTE, DEFER, IS, and CREATE DOES&gt;.  You need namespace management, so new definitions hide old definitions with the same name, and you also have wordlists.<p>The problem with all these wonderful mechanisms is that they can become an attractive nuisance, as you futz around trying to find the perfect way to express your intent in the smallest, clearest amount of code, navigating the tradeoffs imposed by the sparse toolset.  But you don&#x27;t have to do it that way.  You can just write simple, straightforward code that gets the job done with no fuss, and move on to the next problem.  Forth lets you do that, too.<p>That said, I find it easier to get my code working in assembly language than in Forth, and I don&#x27;t know if that&#x27;s because I don&#x27;t know Forth well enough, because Forth is inherently less practical than assembly language, or just because Forth somehow fails to fit my brain.  My guess is that I fall for the attractive nuisances too often and waste my time with unproductive futzing.  And that&#x27;s what this blog post looks like to me.