I particularly enjoyed this section from the template renderer which made me think... Return stack manipulation - that's playing with fire. And also - wow Forth is not much higher level than assembly, and gosh, I don't think I could have written that without writing some stack diagrams!
2dup s" $>" search if \ Check to see if there's a closing tag $>.
2 - \ Add the close tag to the search result.
nip \ Save the end position of $>.
dup >r
- \ Reduce the string to <$ ... $>.
evaluate \ Run user's code (maybe a bad idea?).
r> \ Retrieve our saved end position of $>.
r> r> \ Retrive the addr u from start of loop iter.
rot \ Bring end $> to stack top.
over >r \ Store the real string's length.
- \ Subtract end $> from u to get the pos from top
r> swap \ that we'd like to strip away. Restore saved u.
/string \ Drop top of the string until the end of $>.
0 \ Keep looping.
The beauty of Forth is that you can write at as low or as high a level as you'd like. I think most Forth programmers would factor out some of these operations into their own words rather than writing such a low-level definition, but there's nothing preventing you from writing your web server like it's assembly code.
The rstack is just a temporary second stack with the caveat that you have to be a bit careful about cleaning it up after you're finished with it. (Unless you intend to do something fun and exotic like : goto r> drop >r ;)
Usually I'm more tense about code that uses rot/-rot; a little harder to keep track of in my head.
The only sucky things about VB6 was threading wasn't a regular language feature. You could get to it through the WinAPI but that's not organic enough for most VB programmers. One thing I do miss about VB6 is that you didn't need an entire runtime to build a GUI.
I wouldn’t say that was the only thing...error handling was a mess and I don’t even want to remember what I had to do to make a hash table - there were definitely low level calls to RtlMoveMemory and such.
I never did find out the real reason - I suspect (as it was a relatively small business that had been acquired) that it was because they were too cheap to pay for a server edition of Windows.
As someone with a similarly retro web framework ( https://fortran.io ), as far as I know, no one has switched to it. I have gotten a few serious inquiries from coders in the sciences or who are making use of their old Fortran skills... but only a very few in two years.
> Hence developers working on new projects while still coding in decades-old text editors. They write the future in the past and are made present in so doing.
I really like the commitment to retro aesthetics. Last weekend I made an "imaginary astronomy" web app with nearly pixel-perfect Windows 95 theming. :-) http://steveasleep.com/keplverse/
Forth still seems like a language worth learning, not for practical reasons, but for technohistorical context. Maybe my first project should be a sqlite library?
Forth must be lightning fast albeit single-threaded... has there been any work on a multithreaded Forth? Compiling to BEAM VM might be an option for (not fast) implementation...
Considering that some Forth implementations were custom hardware that directly implemented the language semantics, it was often quite fast, yes. Most of the bigger Forth systems (gForth, WinForth, BigForth) have some form of threading/task management. The smaller ones, which are often the ones expecting to run natively on microcontrollers with no operating system, expect you to write your own if you need it.
A naive (ie. threaded[1]) Forth implementation will be slow because the jump between each instruction is a very effective way to defeat branch prediction. Of course this doesn't apply to "real Forth" which is compiled into machine code or even less naive Forths which can do inlining, but there are many hobbyist Forth implementations (because they're so easy to write) where this will still be true.
Some years ago, I ported ngaro (the retroForth vm) to Go, and made it possible to launch goroutines and use channels. It was very cool.
However, it was Go pre-1.0, so it won't work now. For a while, it was maintained by Charles Childers - the original retroForth author - but I do not think the Go version is still available.
If you want to give it a try (making it work with the latest Go version shouldn't be difficult), have a look at:
One process, one HTTP request at a time, buffering excess requests in a queue of up to 255 requests. Here's the main "event loop":
: start-server { server client }
begin
server 255 listen
server accept-socket to client
client read-request prepare-response client send-response
again ;
I think this word's definition should be fairly easy to follow even if you aren't familiar with Forth.
I think entirely procedural languages are a nice fit for this domain since they make order of operations apparent. Going for something Forth-like was obvious, since it's terse, trivial to implement and makes factoring easy.
That said, I think the documentation of this project is a bit out of date, that the overall architecture is flawed and that stack juggling can be a bit distracting when working with more complex algorithms. I intend to rewrite it some day.
I particularly enjoyed this section from the template renderer which made me think... Return stack manipulation - that's playing with fire. And also - wow Forth is not much higher level than assembly, and gosh, I don't think I could have written that without writing some stack diagrams!
Thanks for the trip down memory lane!