4 ms·
So Lisp macros provide compile-time code generation, but in doing so, you have access not just to the code-generation instructions – which are just Lisp data –
by tygorius 16y ago
So Lisp macros provide compile-time code generation, but in doing so, you have access not just to the code-generation instructions – which are just Lisp data – but also to the entire Lisp language and environment.
The same can be said for classic Forth. Indeed, the enthusiastic way that Lispers describe macros I find eerily similar to how I used to hear Forthians describe their language. Except in Forth the relevant term isn't macro but "defining word". Indeed, I think programmers in both camps see the proper use of macros/defining words as a sign that one has passed the beginner stage of using the language.
A classic compiled Forth word (ie, function) would consist of the word's name followed a string of addresses to execute; how those addresses were laid down, where they pointed, etc. were totally open to programmer control -- both during compilation and afterwards. It's been a couple of decades since I looked at Forth code, but I don't think there's anything that could be done in Lisp macros that couldn't also be done easily in Forth as well.
I think the big difference between the two -- at least, so far as the macro topic goes -- is that Lisp starts with an assumption that code and data can and should be interchangeable while Forth was initially developed for the machine control (embedded systems before they were called embedded systems) and thus code was merely a vehicle for creating applications.
- eru 16y agoForth is almost the complete opposite of Lisp, and thus very similar.
- tygorius 16y agoYou're gotten a number of up-votes, yet this statement makes as much sense to me as saying bananas are the complete opposite of apples. You can make a case of similarity or dissimilarity depending on which language aspect you focus on. But, "opposite"? I have no idea what that means.
- Someone 16y agoLet me guess at some of what (s)he means: Forth is an interpreter that can be switched into compilation mode, Lisp is a compiler that can be switched into interpreter mode. [edit: thinking of that, this more reflects how I have used the two than what they are. Lisps start in an eval loop, too, yet they feel different to me] Forth is postfix, Lisp is prefix. Forth programmers know their stacks are the environment, but rarely think of it as an environment. Lisp programmers know their environment is in some stack-like data structures, but rarely think of those stacks.
- eru 16y agoLisp and Forth are both very simple systems in terms of basic concepts, and push them to their limits. Both are quite flexible. Forth often runs on the bare metal, and exposes everything below. Lispers are customarily more shielded. Both encourage code to be treated as data and vice versa (without even looking at macros), but Lisp builds on the lambda calculus to do that, while Forth just sees code and data as being contents of memory. In Forth if there's a bunch of data flowing into a word, you might put the number of arguments on the top of the stack and the other arguments below. Lispers would run away screaming from this manual and error-prone approach. Lispers like to build e.g. their their own object system, if necessary. And in Forth it's easy to tag on a garbage collector---from within the language. I hope that's some meat to back up my assertion. I hope I got some good examples. What I really want to say, is that the languages feel related in spirit. But less like brothers, more like to generals from opposing armies still respecting each other.
- tygorius 16y agoSorry for the belated response, but for a sense of closure, so to speak, I'll add that I agree with your general assessment. Both languages started with a simple core that allowed developers to take some basic ideas and see just how far they could go with them. It just didn't occur to me to describe that as "opposite". Interestingly, both languages wound up with a schism of framework enthusiasts (CLOS & "big Forths") vs. minimalists (Scheme & Moore loyalists (for want of a better term)). As an aside, your bunch of data example would run afoul of Forth catechism. The normal response would be to use a dictionary address or even address and offset to access a data structure. Antagonism to deep use of the data stack is so prevalent that Moore eventually reached the point with his chip designs of implementing the top of stack as a couple of on-chip registers -- if what you want isn't within the top couple of stack entries, so the logic goes, then you've failed to factor your design properly. Perhaps this preoccupation with very low level operations is an aspect where Forth programming might be considered the opposite of normal Lisp programming.
- eru 16y agoI wish HN would give me the option of bubbling up old threads that got new comments. And you are right about my example with the deep stack. I probably did not remember correctly. The variable array was probably something with passing around an address plus length on the stack---while Lispers prefer that as one object.