2022-05-04 04:25:05 MrMobius: "i thought about keeping the last few words in ram before writing any to the dictionary to do some peepholing" 2022-05-04 04:25:25 My plan is to keep the entire def separate to what's actually compiled 2022-05-04 04:25:49 I'm going to have pretty much an old-fasioned indirect threaded word, or tokenised word, alongside the compiled result 2022-05-04 04:26:07 Rather that gets 'compiled' first and then at `;` it actually generates machine code 2022-05-04 04:26:41 And the advantage is for simpler words that can be inlined I can inline the tokens straight into the token representation for more peep-holing 2022-05-04 04:27:57 It sounds 'heavy' but the right representation would be quite small, especially if I'm doing constant folding in advance of writing the tokens 2022-05-04 08:43:02 That sounds like it could give a nice "cost-benefit" payoff. 2022-05-04 08:44:26 So, would your regular definitions and your code go in different memory regions? 2022-05-04 08:50:29 If code is separate then yes 2022-05-04 08:51:23 So for me then yes, machine code will go in an executable area, the indirect threaded code will go in data area 2022-05-04 08:53:06 I aim to keep machine code separate because of the performance penalty of writing to an executable cache line (can cause instruction cache line invalidate on x86) 2022-05-04 08:53:25 Specifically the concern is a worst-case scenario may arise where you've got a hot variable next to the code that uses it 2022-05-04 08:53:43 So I'm avoiding that possibility, it's not something the programmer should have to worry about 2022-05-04 09:04:07 Good - sounds write. 2022-05-04 09:04:10 Ugh. 2022-05-04 09:04:12 Right. 2022-05-04 09:06:03 So, that's something I've wondered about re: the x86. I know it has various levels of cache, with L0 being the fastest. But does the cache management differentiate between code and data, or does it bring either into the L0 cache? 2022-05-04 09:06:25 I.e., is there actually an INSTRUCTION cache, or is it just a cache? 2022-05-04 09:07:20 KipIngram: afaict x86 is now usually implemented as a modified Harward architecture 2022-05-04 09:07:20 Matters in my case because an *instruction* cache wouldn't get any of my "Forth" code, because it all looks like data to the processor. 2022-05-04 09:07:50 Primitves are actual code - definitions are "data." 2022-05-04 09:07:56 But for Forth they're code. 2022-05-04 09:08:14 meaning the caches nearest a cpu core are split into i-cache and d-cache 2022-05-04 09:08:41 Ok. 2022-05-04 09:08:51 instructions cache and data cache 2022-05-04 09:09:55 recall my musing on implementing Forth VMs via SIMD, in that implementation the whole shebang is mostly data 2022-05-04 09:10:30 Right. In direct or indirect threading, there's relatively little actual code. 2022-05-04 09:10:30 primitives would be implemented in that SIMD loop 2022-05-04 09:12:04 That's one of the reasons I was wishing the other day that Linux offered a way to gain exclusivity to a core. That way other threads wouldn't be constantly mashing your cache content. 2022-05-04 09:12:20 Caches are big enough these days that an entire Forth system can fit in them. 2022-05-04 09:12:39 Get a core, run a little bit to bring everything into the cache, and then just scream. 2022-05-04 09:13:02 instead of having addresses of native code of primitives I prefer to allocate last few bits of an cell to primitive selector iff the other bits are zero 2022-05-04 09:14:00 if the other bits of the cell arent zero then it is a Forth call to that address 2022-05-04 09:14:02 Yeah, when I've mused over hardware / FPGA based Forth I've usually used a packed opcode approach, with one bit indicating either "address" or "set of opcodes." 2022-05-04 09:14:36 Works nice in 16-bits; it's either a 15-bit address or three opcodes. 2022-05-04 09:15:00 why? well it makes that Forth ultra portable 2022-05-04 09:15:06 That's the main reason it looked my fetch unit could pull out ahead of the execute unit, since once it found opcodes it got 'em three at a pop. 2022-05-04 09:15:44 I've never tried those ideas on a software implementation, though. 2022-05-04 09:15:57 Mine have all been pretty traditional at the guts level. 2022-05-04 09:16:28 I been mulling over a BitGrid block addition to my fcpu16 design 2022-05-04 09:17:07 :-) 2022-05-04 09:17:52 I need to think more about that. Once I noticed how similar it is to a "sea of gates" it's been hard for me to get out of that model. I imagine there are other clever ways of using it, though. 2022-05-04 09:19:07 well, I wrote quite a few moons ago an .c impl of fcpu32 which consisted of the forth image in a statically allocated and initialized array and a loop switch construct in the main func 2022-05-04 09:19:53 it ran fast enough 2022-05-04 09:20:40 and I was delighted to see that the c compiler emitted a jump table 2022-05-04 09:21:48 Speaking of the C compiler, I was really intrigued by the way those Mill CPU guys use the standard C++ compiler as an element of their synthesis toolchain. 2022-05-04 09:22:15 I want to look more into that - I bet there are a lot of interesting ways it could be leveraged. 2022-05-04 09:23:00 KipIngram: I look at BitGrid as an bit level systolic array, and as asynchronus cellular automata, and as like the old AVR mini fpga I found 2022-05-04 09:23:15 Apparently they do the lion's share of the creation of a new family member using a chain of open source tools, then "hardware guys" step in for the last phases of placing and routing and so on. 2022-05-04 09:25:01 as I understand how the Mill folks do it is that they use C++ as macro assembler and verilog which when compile gives an program that when is run produces the real verilog vhdl and such files 2022-05-04 09:25:22 Right; it is something like that. 2022-05-04 09:26:44 then these verilog vhdl files get translated into register to register nets, then into gate nets 2022-05-04 09:28:30 then or concurrently route and place tools plus manifacturers ruleset checks and cell libs come in 2022-05-04 09:29:02 Yes. 2022-05-04 09:29:20 the latter changes usually with every manifacturing-node/min-feature-size 2022-05-04 09:29:30 They start more or less with a list of "features" the family member should have. 2022-05-04 09:31:45 the idea I have on how to integrate a BitGrid block into fcpu16 is to have one side connected to TOS, another to NOS, and the other two sides are still tbd 2022-05-04 09:32:22 Oh, that's slick. Yeah. 2022-05-04 09:33:36 and mapping the BitGrid config space into the address space of that fcpu16 2022-05-04 09:34:40 then just have an function selection prim/instr to select the output from the BitGrid 2022-05-04 09:35:43 that way I basically have an way to have redefinable function unit 2022-05-04 09:36:09 Yes - I like it. 2022-05-04 09:37:05 I recon that instead of having just 16 primitives, I can go up to 32 or 64 2022-05-04 09:37:42 That FPGA Forth I tinkered with had 32. 2022-05-04 09:38:01 5 bits, three packed - those numbers worked well together. 2022-05-04 09:38:26 one primitive to say, "I want BitGrid TOS side output be written to TOS register" 2022-05-04 09:39:18 one to say "I want BitGrid NOS side to written to TOS" 2022-05-04 09:39:51 and one another to say for both 2022-05-04 09:41:06 one idea for the other sides of that BitGrid block is memory port to same memory as the fcpu16 uses 2022-05-04 09:42:23 another idea to use part of one side for small i/o and interrupt line into the fcpu16 2022-05-04 09:44:27 I am still sceptical of packing three primitives to a cell as it complicates the fetch-execute a bit 2022-05-04 09:44:54 Remember I was working with hardware. 2022-05-04 09:45:02 It's a lot easier to deal with there. 2022-05-04 09:45:45 I had a fifo between my fetch and execute units anyway - that fifo was just 15 bits in, 5 bits at a time out. 2022-05-04 09:45:46 microcoded or hardwired instruction handling? 2022-05-04 09:46:01 Hardwired - gates for everything. 2022-05-04 09:46:03 oh, I see 2022-05-04 09:47:42 I am using basically a bit modified ROM logic as the main sequencer and instruction decode and execution 2022-05-04 09:48:05 in the fcpu16 logisim evolution design 2022-05-04 09:48:17 Cool - I've never done a microcoded design of any kind. 2022-05-04 09:48:54 have done ROM logic though? 2022-05-04 09:49:02 have you* 2022-05-04 09:49:18 Mine had a side pipe that opcodes could be parallel routed into for "micro loops." It just looped over the opcodes - didn't have to fetch them again. 2022-05-04 09:49:56 No, not per se. I've worked primarily with gates, registers, and so on. 2022-05-04 09:51:50 it is really simple: you have one register whose output feeds into some of the address lines of a rom, the other address lines are inputs. Then you feed some of the data lines of the rom into the register and the rest is outputs 2022-05-04 09:53:43 That side pipe was a little bit like the Mill "belt." It was just a short pipe of already executed opcodes, and if you didn't use them they "fell off" the end. 2022-05-04 09:55:51 The Mill pipe is just for data, though - I think. 2022-05-04 09:56:15 one application of ROM logic I saw in an old logic&computing book used a punched card for the ROM 2022-05-04 09:56:21 Its main purpose seemed to be to eliminate the need for register renaming and providing an "immutable" source of recent results. 2022-05-04 09:57:07 Some of those early machines are pretty cool. Some of the earliest "programmed" work was in the textile industry, where the "program" controlled the weaving pattern. 2022-05-04 09:57:34 Wasn't "cards," but it was the same kind of idea. 2022-05-04 09:59:07 the thing used a bunch of diodes. The select lines were rows with them on one side and the columns on the other side of the clamp were the card went in 2022-05-04 10:00:03 I suppose it just made through connections where there were holes? 2022-05-04 10:00:21 the application? numpad lock in two parts that needed the code changed every week 2022-05-04 10:00:30 yebb 2022-05-04 10:02:16 and it had two codes, one for office hours and one for non office hours 2022-05-04 10:05:34 and on what was this numpad lock on? a supply room 2022-05-04 10:08:58 Crown jewels. :-) 2022-05-04 10:09:08 Can't let people steal pencils. 2022-05-04 10:10:14 no, just a department that got sick of other departments niking their office supplies too much 2022-05-04 10:11:04 Well, little things like that can become damn annoying. 2022-05-04 10:11:18 hence the weekly code change because it invariably got out but it took a bit more than a week to spread 2022-05-04 10:11:29 Right. 2022-05-04 10:11:38 Reasonable solution. 2022-05-04 10:12:20 it was purely 'home made' solution 2022-05-04 10:49:10 I said I thought in terms of gates on that FPGA design. That's not quite true. I did - when I was figuring out functionality I was thinking "gates." But what I actually did was think in terms of Xilinx six-input LUT terms - my goal was to have only two levels of combinational LUTs between register outputs and register inputs, so I'd be able to use the fastest possible clock. 2022-05-04 10:49:24 I was able to do that, including the decode and execution of all of those 5-bit opcodes. 2022-05-04 10:50:03 That did mean the opcode-to-operation assignment wasn't in any way "arbitrary" there was some thought behind it, to enable two-level decode. 2022-05-04 10:50:25 Somewhere upstairs there's a notebook with that opcode assignment in it. 2022-05-04 10:50:48 But it wasn't totally AND/OR/NOT gate thinking - it was "What can a LUT do?" 2022-05-04 10:51:15 I believe each LUT provided four arbitrary functions of six inputs. 2022-05-04 10:51:37 May have been two instead of four - can't remember for sure. 2022-05-04 10:51:49 But there were six inputs in that Xilinx family (Spartan). 2022-05-04 10:53:25 It used hardware data and return stacks - just stacks of registers. Which would have been terrible for power, since every register would change whenever an item entered the stack, and all but one when an item leaves. 2022-05-04 11:04:52 I just used normal memories for the stacks (block mems in Spartan 6) and drove their addresses with up down counter registers 2022-05-04 11:04:55 bbl 2022-05-04 12:14:57 https://gist.github.com/zarutian/0833e83a219ac6ca94e49166f571dd21 2022-05-04 13:12:13 hi all, I was just wondering if anybody had heard of this new systems programming language, and if it might be relevant as a foundation for Forth running on bare hardware 2022-05-04 13:12:17 https://harelang.org/blog/2022-04-25-announcing-hare/ 2022-05-04 13:13:09 like, implement the Forth primitives in Hare, and some forth words using the opengl bindings 2022-05-04 13:21:50 not really advocating for it, but just wondering, since Forth is certainly bootstrappable on bare hardware, which has been done alot, but then nobody ever gets around to writing the file system and graphics libraries and such 2022-05-04 13:43:41 And if nobody said it yet - may the FORTH be with you! :) 2022-05-04 13:57:52 ACTION switches his terminal to aurobesh 2022-05-04 14:01:57 lispmacs[work]: some this is hare brained idea! 2022-05-04 14:19:00 say, I completely Oprahed that verb 2022-05-04 15:11:59 Zarutian_HTC: okay, for thank you your thoughts 2022-05-04 15:19:21 I do hope to eventually "get around" to writing a file system. I've thought about it a good bit; hashed out some data structures and so on. 2022-05-04 16:09:08 KipIngram: I wrote a very simple filesystem at work, I might do something similar at home and open source it 2022-05-04 16:09:19 Hopefully not too similar that I could get in trouble lol 2022-05-04 16:09:30 Sucks when my good ideas come out at work :P 2022-05-04 16:10:11 lispmacs[work]: My opinion as I said on HN is if I wanted C with slightly more features I would have been working in a nice C++ subset years ago 2022-05-04 16:10:45 And there are a lot of C-replacement languages out there, this one doesn't have really compelling syntax 2022-05-04 16:11:00 IMO if you're doing a new C-replacement language today it should have less syntax, not more 2022-05-04 16:11:10 Like closer to B in appearance 2022-05-04 16:12:03 hare doesnt have anything compelling 2022-05-04 16:12:08 If anyone's interested in writing a C replacement you are welcome to pick my brains on this in detail, I have actually thought about it a lot 2022-05-04 16:12:26 I have some good ideas, probably some bad ideas, I'm not all critique though I can be constructive 2022-05-04 16:13:20 But practically speaking you will never win the market because C already exists and is frankly good enough for what it does, any C-replacement will always have this problem 2022-05-04 16:17:16 Last update on my Forth LCD driver project: 2022-05-04 16:17:18 https://portal.mozz.us/gemini/gem.librehacker.com/gemlog/tech/20220504-0.gmi?inline=1 2022-05-04 16:17:26 Mecrisp Forth + RP2040 2022-05-04 16:24:41 Hey, cool. 2022-05-04 16:26:04 Those eight customizable char codes - six is enough to draw boxes - the four corner chars, and the horizontal and vertical straight chars. 2022-05-04 16:26:15 Those chars are also available, though, via ansi sequences. 2022-05-04 16:26:26 And I'm sure via UTF-8 as well. 2022-05-04 16:27:34 I like how you've set that site up. 2022-05-04 16:27:40 Nice and orderly and clean. 2022-05-04 16:37:28 KipIngram: Thanks, that Web site is actually a proxy mirror of my Gemini site using gemtext pages, which are by nature simple and clean 2022-05-04 16:37:40 how do Forths that compile to native binaries handle e.g. VARIABLE foo : foo@ [ foo ] LITERAL @ ; 2022-05-04 16:38:51 binaries that aren't just unexec()s, I mean 2022-05-04 16:39:36 In my design the answer is ... it doesn't handle that 2022-05-04 16:39:54 And I think that's probably how other forths that compile handle it too 2022-05-04 16:40:24 So you are a bit more restricted in operation... which makes sense to me 2022-05-04 16:40:52 hm, okay 2022-05-04 16:47:36 Why can't that be compiled as a literal followed by a fetch? 2022-05-04 16:47:45 I must be missing something. 2022-05-04 16:47:52 the address might be different from inside the compiler vs in the final binary 2022-05-04 16:47:59 That's it 2022-05-04 16:48:24 Oh - I see. I overlooked the "native" part. 2022-05-04 16:48:28 I get it. 2022-05-04 16:48:36 You can choose a non-relocatable binary and map fixed addresses but it's not portable 2022-05-04 16:51:09 Yeah, I see the difference. I was just thinking in terms of "compiled in the system" Compiled Forth def. 2022-05-04 16:51:42 But yeah - I see the problem. The executable has to make it possible to map things to whereever it gets loaded - that can't be compiled as "just a literal." 2022-05-04 16:52:03 can simply disallow things like that 2022-05-04 16:52:12 Yes. 2022-05-04 16:52:30 Provide a way to declare variables - provide a way to work with literals. The two don't HAVE to be interchangeable. 2022-05-04 16:52:57 Yes and by 'disallow' I mean it will crash when you run it 2022-05-04 16:53:10 To some extent that code in the example is deliberately obtuse. 2022-05-04 16:53:20 It's not really how you'd ever naturally do a variable reference. 2022-05-04 16:53:37 mark4's forths use fixed map addresses 2022-05-04 16:53:39 Though I imagine there are other cases that get at the same thing that might be reasonable seeming. 2022-05-04 16:54:00 Yeah an array of addresses would fail for instance 2022-05-04 16:54:07 That's less contrived 2022-05-04 16:54:33 But mark4's forth didn't run on my system! I had to change the map 2022-05-04 16:54:49 Yeah - that's basically what a jump table is. 2022-05-04 16:54:49 And there are not 'correct' addresses to try mapping to, so it does indeed have portability issues 2022-05-04 16:55:01 I guess you could have an "array of relocatble things" entity. 2022-05-04 16:55:12 But it couldn't be just a number array. 2022-05-04 16:55:16 Much like an ELF 2022-05-04 16:55:22 :-) Right. 2022-05-04 16:55:50 You are going to have an array like that or whatever ELF does if you're compiling binaries, yes 2022-05-04 16:57:28 Apple's MACH0 exec format is particularly restrictive. 2022-05-04 16:57:51 It just insists that everything be relative to load point. 2022-05-04 16:58:00 Yeah I was going to say I would guess future OS's, ABI's will disallow fixed addresses entirely 2022-05-04 16:58:26 So really you want to figure out how to work with relative addressing 2022-05-04 16:58:51 That what my "rrBB" register holds - it's got the base address of the whole system. 2022-05-04 16:58:54 yeah, my ABI already does this b/c I only care about aarch64 2022-05-04 16:59:10 so I can do everything pc-relative 2022-05-04 16:59:11 Sorry - no. It's the address at which the "text" section is loaded. 2022-05-04 16:59:23 That's the block code and definitions are in. 2022-05-04 16:59:46 The "data" section is pointed to by r14, which I call rrHB (head base). 2022-05-04 16:59:55 And everything is in one or the other. 2022-05-04 17:00:21 Consequently I'm really only able to have one thread run smoothly right now. 2022-05-04 17:00:37 I'm going to have to work in a way to know your own "base as a thread." 2022-05-04 17:00:57 If I want to have anything thread-specific other than the stacks. 2022-05-04 17:01:17 remexre: So in my head I want to document the word that adds a relative symbol, so you can make anything relative explicitly if it isn't something trivial like a variable 2022-05-04 17:01:19 So I've got to keep at least one register available for that. 2022-05-04 17:01:43 It'll probably wind up being rbx. 2022-05-04 17:01:46 I think any good builds-to-executable forth should document that word because you never know what won't work 2022-05-04 17:01:57 but like 2022-05-04 17:02:32 a builds to executable forth should be different entirely 2022-05-04 17:02:54 veltas: like a special version of LITERAL? yeah, that shouldn't be too hard in my design, since I only start making the binary after all the definitions I want to compile have been made 2022-05-04 17:02:56 why try and emulate the interface of a normal forth 2022-05-04 17:03:12 remexre: Yeah, for example 2022-05-04 17:03:47 eris: I don't know - I could imagine wanting to write a word and test in in system, and then just say "make an exec." 2022-05-04 17:03:52 eris[m]: Do you mean it should be like a cross-forth? 2022-05-04 17:03:59 I'd want it to write out only the bits of the system that were needed for that exec. 2022-05-04 17:04:26 I think there are advantages either way, for what I care about it's better to keep the interpreter 2022-05-04 17:04:27 But maybe that is an entirely different thing - that follows the word around the dictionary and builds something totally different. 2022-05-04 17:04:53 I can't think of an app I wouldn't want the forth interpreter to be there "just in case" i.e. for debugging or advanced features 2022-05-04 17:05:33 The thing is, if your exec is going to offer command input, then it's going to need an awful lot of the system. I'm not sure I see what you gain in that case. 2022-05-04 17:05:51 "an awful lot of the system" yeah but forth is small 2022-05-04 17:06:02 But if it's a controller for a gadget or something - that could be pretty minimal. 2022-05-04 17:06:29 Yeah that's when you want a cross forth 2022-05-04 17:06:44 And it would probably be a lot easier to compile it from source (in which case yeah - it would be like a cross forth). 2022-05-04 17:06:55 Instead of trying to "convert" the already dictionary compiled thing. 2022-05-04 17:07:21 It really depends, right now I'm more focused on desktop forth (and also these days embedded is essentially as powerful as a small desktop from 20 years ago) 2022-05-04 17:07:31 Well some embedded socs are 2022-05-04 17:07:47 Some are still toasters 2022-05-04 17:07:51 I haven't thought much about general cross forth - themain thing I've thought about is meta-recompilation of the whole system. 2022-05-04 17:10:02 That's a goal for sure - to be able to have Forth source in my Forth system I can use to rebuild the whole thing. Then I'll be able to cut the nasm umbilical. 2022-05-04 17:11:04 Then instead of using the OS to load my executable, I'll have a little program I run that loads an image out of my blk.dat file and hands control to it. 2022-05-04 17:11:40 Give the little program the block # to find the image at. 2022-05-04 17:11:50 I don't mind nasm but yeah it's compelling to be able to go 100% Forth 2022-05-04 17:11:52 Have a golden image in there too, for when I stub my toe. 2022-05-04 17:12:04 Definitely not a priority IMO 2022-05-04 17:12:11 I'm actually quite happy with nasm, but this just seems like the logical path to me. 2022-05-04 22:59:25 I've implemented colon words as strings with a pointer and the return stack is one array of those strings 2022-05-04 22:59:34 it's weird, but I think it can work 2022-05-04 22:59:47 https://termbin.com/xmpya 2022-05-04 23:20:06 Hi vms14 2022-05-04 23:21:31 What's the pointer in the string struct for? Is that how you link words together? 2022-05-04 23:21:56 Or is it an offset into the word? 2022-05-04 23:22:01 the offset 2022-05-04 23:22:07 Into the string, I mean. 2022-05-04 23:22:09 read_word manipulates this pointer 2022-05-04 23:22:17 So, like a program counter for each one? 2022-05-04 23:22:22 well read_char does 2022-05-04 23:22:40 every time read_char is called it increments this pointer 2022-05-04 23:22:47 this is why it wants a reference 2022-05-04 23:22:50 I see. 2022-05-04 23:23:08 the thing is, a colon word can be represented as this 2022-05-04 23:23:25 even "recurse" can be implemented by just resetting this pointer xd 2022-05-04 23:25:12 if you run this example the output is "oh is my" 2022-05-04 23:25:22 Right. We've noted a couple of times recently that you can do that in the text input buffer of most Forths. There's a variable called >in that notes how far into the text you are. 2022-05-04 23:25:31 If you reset that to 0, it will start the line over. 2022-05-04 23:25:47 So, you better do it intelligently, with a way to stop, or you just hung your system. 2022-05-04 23:25:59 Unless you have a ctrl-c break or something like that. 2022-05-04 23:26:39 I've used it to time some of the internal activities, like searching the dictionary, converting numbers, and so on. 2022-05-04 23:27:02 I wonder if a colon word can really be represented as a string 2022-05-04 23:27:26 Well, a colon word is a string of addresses. 2022-05-04 23:27:39 If you have a way of interpreting bytes as primitives, then sure. 2022-05-04 23:28:36 Usually there's one central instruction pointer - not one per word. but there's no particular reason why one per word wouldn't work. Seems to me it would make your words non-reentrant, though. 2022-05-04 23:28:44 yes, I can have function pointers for primitives 2022-05-04 23:29:13 If you're in the middle of executing one, it can't be called again as part of that. Except as a full recursion (from the tail end). 2022-05-04 23:29:32 I was thinking in reading the whole file or line and make this a colon word, then put that in the return stack 2022-05-04 23:30:05 the thing is, as is a string is raw code, so there is no need for literal 2022-05-04 23:30:21 the drawback is it means you'll be always "reading" 2022-05-04 23:30:43 but it makes the code serializable, at least the colon words 2022-05-04 23:34:30 Not sure what you are calling "raw code." You don't mean machine code, do you? 2022-05-04 23:35:57 I mean being a colon word as a string you don't have any kind of bytecode, the colon word is actually raw code 2022-05-04 23:36:27 the compiler for example translates a 1 to a literal word 2022-05-04 23:37:18 in this case the compiler can have immediate words and alike, but when executing a colon word is the same as reading code from the input 2022-05-04 23:38:45 it's much slower, for example for every word listed in a colon word you'll have to search it in the dictionary 2022-05-04 23:39:19 this is done once when compiling, but in this case will be done every time you execute a word 2022-05-04 23:40:45 When Chuck first ever wrote about Forth, before it was really Forth, my take on his book was that he did something like that. There didn't seem to be any compiled definitions at first. It was more like what I think you just described - "executing" a word was more like subsitution a string for a symbol. 2022-05-04 23:40:54 And yes - slower. 2022-05-04 23:41:30 the book he didn't know why he wrote? 2022-05-04 23:48:11 Yeah.