
Show HN: forthy2 – a higher level Forth-remix in C++ - codr7
https://github.com/codr7/forthy2
======
InternalCake
There was a burst of interest in concatenative languages a few years back -
essentially higher level variations on the features found in forth.
[https://en.wikipedia.org/wiki/Concatenative_programming_lang...](https://en.wikipedia.org/wiki/Concatenative_programming_language)

They're fascinating and one would hope (well, I did) that the structural
simplicity of them would yield something that's amenable to automatic
manipulations. In practice the lack of restrictions on what you can do to the
stack makes it almost impossible to reason about programs written in such
languages.

~~~
0xdeadbeefbabe
Forth has a data stack and return stack. Messing with the return stack seems
like a practical joke on the programmer sometimes. I guess we don't live with
the same constraints that made forth popular in the first place.

~~~
codr7
I'm curious, what kind of messing with the return stack are you talking about?

The only thing forthy2 does that is slightly out of the ordinary is TCO.

~~~
0xdeadbeefbabe
In eforth doVAR is R>

~~~
codr7
Ah yes, hardcore Forthers do seem to take pride in finding the absolute
smallest number of fundamental building blocks.

There comes a point, though; where pretending everything is the same
complicates rather than simplifies.

~~~
notduncansmith
While I would rather call it acknowledging than pretending, I agree
wholeheartedly with the sentiment and consider this one of the most prevalent
and pernicious fallacies of system design (though I may only feel that way
because it had such a strong hold on me for so long).

~~~
codr7
Rabbit holes, you can spot them in most projects. Where someone got carried
away with some sort of enlightenment. Oh, I know, everything is X. Well, no.
Everything is, and always will be.

------
garmaine
Why does pushing drop the stack you are pushing onto? Is there ever any reason
to push something onto a stack and then immediately drop the stack? Even if
there were, it doesn't seem like the option you'd want to optimize for.

~~~
codr7
I'm sorry, I'm not quite following. I don't get what you mean by dropping the
stack in this context. Could you point to where in the README you're having
trouble?

~~~
garmaine
Not from the README. I don't read READMEs. I read code.

The issue is this:

> (1 2 3) 4 push

My expectation is this should yield "(1 2 3 4)". It doesn't. For that you need
the following:

> (1 2 3) copy 4 push

Why is copy necessary here?

~~~
codr7
Stacks are reference types, the operation doesn't produce any new values. Half
the time you want it there to push more items, or to display it in the REPL
like in this case, but the other half you're going to drop it anyway.

I'm still undecided on the stack ops. There is one case in forthy2 where a
reference is left on the stack, and that is splicing values into forms [0],
where it's more likely you want to keep working with the same form. More
likely is not a very good heuristic for designing API's though, so I might
just go with the behavior you expected.

[0]
[https://github.com/codr7/forthy2#quoting](https://github.com/codr7/forthy2#quoting)

------
protomyth
The whole concept of a 'body' that isn't on a the stack when the word executes
would take a bit of getting used to.

~~~
codr7
The implementation is definitely less Forthy as a consequence of embedding in
C++ rather than aiming for rock bottom.

Bodies, or scopes, are first class though. You can take their references
and/or quote them.

~~~
protomyth
Postscript does the: _num {op} repeat_ form with the ability to take
references of the code blocks using _def_.

~~~
codr7
Nice.

I get the feeling that PostScript is close in spirit, they were also into
pimping Forth using Lisp as inspiration. I think some of the HP-calculators
also had similar languages, but never used them myself.

For me, generic methods (or words in Forth lingo) is the biggest deal.
Followed by scopes and compound literals such as stacks and scopes.

------
0xdeadbeefbabe

      CMake Error at CMakeLists.txt:6 (add_link_options):
        Unknown CMake command "add_link_options".

~~~
codr7
Aight, seems like I need to adjust the required CMake version. It would help
if I had any idea which version introduced add_link_options.

Anyways, the easiest way forward for you is most probably to upgrade your
CMake.

~~~
slavik81
It was added in v3.13. It would be nice the minimum version required to use a
function was directly stated in the CMake documentation. I just keep picking
older versions from the dropdown until the page disappears.

[https://cmake.org/cmake/help/v3.13/command/add_link_options....](https://cmake.org/cmake/help/v3.13/command/add_link_options.html)

~~~
codr7
Thank you, I'll update the file accordingly.

And I agree: once you have a directive for checking versions, knowing which
goes where is pretty critical information. Maybe someone should remind them?

------
0xdeadbeefbabe
Did you do anything special to make the CPU happy/efficient with forth
function calls? I heard a rumor that CPUs find it hard to predict branches
with code that doesn't do C calling conventions.

~~~
codr7
One of the main motivations in this case is embedding in C++, rather than
trying to replace it. So far the language is implemented as a high level
VM/interpreter, I'm planning to eventually emit C++ to get standalone
executables and a 20-30% speed up.

So no, I didn't do anything :) It's all C++, all the way.

I suspect most standard Forths don't give a crap about the CPU, they like to
implement everything themselves.

