2 ms·
> Oh, it it's not homoiconic Is it as homoiconic as it needs to be? It's been a while since I've played with it in any real way, but, as I recall, Forth repres
by mumblemumble 6y ago
> Oh, it it's not homoiconic
Is it as homoiconic as it needs to be? It's been a while since I've played with it in any real way, but, as I recall, Forth represents both data and code in exactly the same way: Blobs of data with no associated type information, that you're allowed to fiddle in any way you want, with no guard rails.
So it seems like there's no reason you couldn't write some words for manipulating code every bit as easily as you could write some words for manipulating any other data.
Lisp gives you a lot more out of the box, of course. But Lisp gives you a lot more of everything out of the box.
- astrobe_ 6y agoIt depends on the implementation. With Indirect Threaded Code (ITC), "functions" are represented more or less as a list of other functions or primitives to call. But there are also classic bytecode-based Forth implementations, subroutine threaded code implementation (which is a simple form of native code generation), etc. In my experience, Forth's "immediate" words, which let you execute code at compile time, combined with the availability of some (or most) of the compiler's part, let you do quite a lot of things. In other words, you don't manipulate code, you directly generate code. For instance, if your implementation does not have 1+ (silly example), you can make a word "1+" that compiles "1 +" inline (or increment the top of stack if you interpret stuff from the REPL). To answer your question, I use a dialect of Forth that has, I think, less capabilities than standard Forth in this area and rarely felt the need to implement them. At the risk of showing I am a blub programmer, I think homoiconicity is overrated - for the user (for language implementers maybe it's another story).
- mikewarot 6y agoLisp can take a chunk of lisp code and operate on it directly... forth can't do the same. The big difference with forth is the inability to do things other than variables (fixed allocations) and use the stack. The handling of lists and garbage collected larger things on the heap are a huge advantage for the Lisper.
- RodgerTheGreat 6y agoForth doesn't need an abstraction for operating on threaded code; forth programmers routinely write their own words for control structures with an awareness of the internal structure of dictionary entries. You're operating on code-as-data, it's just an entirely different mechanism for doing so. It's entirely possible to work with dynamically allocated memory in a Forth that runs on top of some other operating system, like GForth. When you're on metal, you can build whatever kind of allocator you want. The primitives "create"/"allot" are just that- primitives. Here's a trivial example of building a cons-pair heap in Forth: https://gist.github.com/JohnEarnest/4522067 https://gist.github.com/JohnEarnest/4522067