3 ms·
I suspect what we don't have is the ability for Forth words to act as symbols that can be given a completely different meaning. Can we have: oof dup rot swa
by kazinator 2y ago
I suspect what we don't have is the ability for Forth words to act as symbols that can be given a completely different meaning.
Can we have:
oof dup rot swap foo
where oof is a delimiter pairing with foo, both of which we developed? It causes dup, rot and swap not to execute but somehow be accumulated as just symbols; then foo interprets them in such a way that they are unrelated to duplicating, rotating and swapping stack elements.
Word definitions do something like this. There is a : (colon) word which causes the next word to be interpreted as a name for a new definition and then subsequent words until a semicolon are shored up into the definition.
But that's a fixed thing, built into the language. It's not defined in the Forth standard as a symbolic quoting mechanism.
- alexisread 2y agoLots of forths can quote, which is kind of what you are asking here - https://retroforth.org/Handbook-Latest.txt https://retroforth.org/Handbook-Latest.txt Retro uses operators on the quote. Similarly, Freeforth (anonymous definitions) and Able Forth (same) can do this. You also have aliasing and hooks in the languages as other tools. The way Rebol and derivatives (Red, Rye) treat blocks and dialects [myword yourword] executedword is similar, though they are all interpreted, not compiled.
- kragen 2y agoi think you've misunderstood what kaz was asking retroforth quotes are just anonymous definitions, and the words inside of them have the same meaning they would have in any other definition. as far as i can tell, you can't even index into them or query their length the way you can with {executable arrays} in postscript. i think the same is true of anonymous definitions in freeforth and able forth ansi standard forth has :noname https://forth-standard.org/standard/core/ColonNONAME https://forth-standard.org/standard/core/ColonNONAME which is the same thing as retroforth quotes, except that it doesn't nest within other definitions, so you can't use it to define properly nesting control structures, the way retroforth does but kaz was asking if it's possible to construct a context that gives the words inside it a completely different meaning, so that you can interpret dup, rot, and swap in a way that is unrelated to duplicating, rotating and swapping stack elements. this is in fact possible in ansi forth and in most other forths (my comment sibling to yours explains how), although i don't know if it's possible in the forths you've mentioned
- kragen 2y agoi think this is three lines of code in ansi standard forth. in more detail: you can do this by having oof parse words from the input stream until it parses foo, and all the facilities for doing that are included in the ansi standard (i.e., it doesn't require knowledge of theoretically private implementation details of a given forth). there aren't any standard words that work this way, although, as you're probably aware, \ " .( ( char [char] c" s" and ." do consume data from the input stream in various ways (but without parsing it into words), and in particular ' ['] create value variable constant marker parse-name to defer is and postpone all read a single word from the input and do various things with it i'm no forth expert but i think you can define your desired oof as follows in ans forth: : roof begin parse-name \ read oof 2dup s" foo" compare 0= if 2drop exit then spoof again ; : oof immediate goof roof proof ; what this does is determined by pre-existing definitions for goof, spoof, and proof. spoof somehow accumulates a word, while goof and proof are invoked at the beginning and end of the string of words. the simplest interesting thing to do is to concatenate them in a buffer and type them out, which can be accomplished by providing the following definitions before compiling the above: create boof 256 allot 0 value poof \ buffer and pointer for oof : proof boof poof type ; : goof 0 to poof ; \ print oof, gone oof : spoof >r poof boof + r@ move r> poof + to poof ; \ string put for poof if you defer goof, spoof, and proof, you can change what they do without recompiling oof and roof i can't swear that this is ansi-compliant forth but i did test it in gforth and pfe. i also tried testing it in yforth and jonesforth but couldn't get them to run on this amd64 linux the one debatable thing here is that you said 'symbols', but spoof's arguments are just a string pointer and a length, probably in some kind of input buffer. forth doesn't natively have symbols in the lisp sense, but it does have something very similar, which is a dictionary of words. spoof can look up a word in the dictionary in the same way ' or ['] would, by using the word find†, which returns a pointer to the word's dictionary entry (a so-called 'execution token') this may sound suspiciously like symbol interning in lisp, and if the naming of ' in forth isn't inspired by the lisp readmacro of the same name, it's at least a damned suspicious coincidence. but the semantics are different from interning in an important way, which is why i didn't use find in my definition of roof above: if the word you're searching for hasn't been defined, find doesn't add it to the dictionary. for dup, rot, and swap, you'd be fine, but if you stuck a bar or a quux in there, find would return 0 (and the original string). also, in forth, you can have more than one word with the same spelling, and find will only find the latest one that's still in scope, which is a different behavior from lisp symbols if you want the lisp symbol behavior, you'd have to define your own obarray and intern, which is not too hard ______ † the standard word find wants a counted string, and that's enough hassle that many implementations like gforth provide a find-name which takes a string in the format provided by parse-name instead, and define find in terms of find-name. but find-name isn't in the ans standard, and you can define it in terms of find if you have to