2022-12-17 10:22:55 ?EY6 2022-12-17 10:23:01 whoops 2022-12-17 13:25:56 Did some reading here last night: 2022-12-17 13:25:58 http://www.ultratechnology.com/aha.htm 2022-12-17 13:26:10 I've been through that before, but I don't think I followed it well the first time. 2022-12-17 13:26:30 I see what seems to be a near-obsession with source code size and compilation speed under the hood of those ideas. 2022-12-17 13:26:42 I wonder how that rose to such a high level of importance during that time period? 2022-12-17 13:27:12 To achieve it, he's introducing distinct "classes" of words, into Forth which starts out with every word pretty much unified into a single class. 2022-12-17 13:27:46 Machine instruction words are represented in the *source* one way, defined words another, compiler words yet another, etc. etc. etc. 2022-12-17 13:28:05 I'm not sure the benefits are really worth the "breaking" of the lnaguages's unity, but... I guess whatever floats your boat. 2022-12-17 13:28:25 Anyone know from history why they were so interested in source size and compile speed in that era? 2022-12-17 13:29:22 Was it just "what Chuck happened to get psyched about," or was there more to it, I wonder? 2022-12-17 13:31:26 There's a claim in there, or in some other article in that neighborhood, that ColorForth eliminates STATE. But I don't think it really does. Really using colors to guide handling of words is not that different from sticking [ and ] in whenever you want to change STATE. Those space characters that specify a color SET STATE. It's just thought of as a "prevailing color" instead of as "STATE." 2022-12-17 13:31:29 But it's the same thing. 2022-12-17 13:31:34 Just done in a different way. 2022-12-17 13:32:02 It's NOT the WORD that tells you how to handle it - it's the space character somewhere before the word, which means the handling is REMEMBERED, just like it is with STATE. 2022-12-17 13:33:00 Similarly, having a color for hex and a color for decimal isn't any different from just sticking HEX and DECIMAL in to manipulate global BASE. 2022-12-17 13:33:09 It's just a difference in rendering. 2022-12-17 13:33:56 Chuck claims that color perception engages the brain in a different way from symbol perception, and that may be true. I can certainly buy that the idea "works for him" - if he says so, I believe him. 2022-12-17 13:34:08 But I don't think it represents a fundamental revolution in the language. 2022-12-17 13:35:26 And I certainly think the things described in that aha article linked above put you in a position to do more work at edit or compile time instead of compile or edit time - I buy that too. But I think it's coming at a conceptual price; it's a more complicated appraoch by a considerable margin. 2022-12-17 13:35:54 The editor particularly, and the compiler to some degree, have to become a lot "smarter" to support that approach. 2022-12-17 13:36:32 All of this was closly adjacent to Chuck's work on his chip design system. 2022-12-17 13:37:01 I have long thought that he decided in that project that what he wanted was to (at least almost) rebuild the system completely every time he made any small change. 2022-12-17 13:37:11 And that would certainly put a premium on compile speed. 2022-12-17 13:37:52 And it also sounds like, based on what I've read, that at some point he decided he wanted a system that had 1kB source and 1kB compiled size. 2022-12-17 13:38:15 I.e., he set an arbitrary goal for himself that put a premium on shrinking the source and object code as much as he possibly could. 2022-12-17 13:38:36 If those are your goals, then everything in the aha write-up makes perfect sense. 2022-12-17 13:39:06 I once tried to go down that road, but after reading last night I see that I didn't fully understand what he was doing. 2022-12-17 13:39:17 And consequently I did a lot of work that I eventually abandoned. 2022-12-17 13:44:10 I realize that even just using blocks in the traditional way to some extent gives you source code you can't "just open" with a conventional editor - you have to have some little utility that goes through and puts in newlines in the right places. 2022-12-17 13:44:19 But at least that's a pretty trivial utility to write. 2022-12-17 13:44:35 The aha stuff takes the source light years away from any sort of external access. 2022-12-17 13:47:11 But at least Fox is very up front and overt about that - he says outright "you don't need to be able to view this source with emacs or whateer because those tools don't exist in this environment." 2022-12-17 13:47:23 It's very clear that he is building a CLOSED system. 2022-12-17 13:48:46 And I'll grant that one of the things that always fueled my love for embedded design was the ability to have that kind of focus. "Portability" just was not on the table. "Standards" were not on the table. There was a goal - you aimed at winding up with a device and associated software that *did the target job*. That constituted 100% success. 2022-12-17 13:49:17 Of course you had manufacturability requirements, serviceability requirements, and so on. But that was all. 2022-12-17 13:49:56 You can "play God" on an embedded project more than on projects that have to niche into some global infrastructure. 2022-12-17 14:11:34 If you think about it, make and other such tools also are oriented toward "speeding up compile." In that case you do ultimately have ASCII source, but you've defined an intermediate format (object files) that stay stable more reliably than the executable code does. And a strategy for rebuilding object code only when it's necessary. In some ways the aha "source code" is a mingling of conventional source, 2022-12-17 14:11:36 object, and executable formats at a more fine-grained level (i.e., not at the level of files). 2022-12-17 14:11:48 It's the same idea, just taken to an implementation extreme. 2022-12-17 14:19:06 The system described here seems to make the "source/object/executable" decision on a token-by-token basis, which I guess is as far as you can take it. 2022-12-17 14:20:22 The other extreme, I guess, would be to recompile the entire system from ASCII source every single time you compiled. So Forth gives us an intermediate position too - it's an ASCII source recompile each time, but you can choose where to start it. 2022-12-17 14:21:00 And since if you recompile A then you recompile everything defined after A, there's no need for an intermediate object format - you go straight from source to executable. 2022-12-17 14:25:50 I suspect tactics like those aha are "less beneficial" than they were at the time Fox wrote that up. Anyone do enough signficant Forth compilation to have a feel for how fast it is in today's systems? 2022-12-17 14:26:09 I've only worked with small amounts of code that compile faster than I can get my finger off of the Enter key. 2022-12-17 14:26:17 So I'm fairly uncalibrated. 2022-12-17 14:27:02 I did make some timing measuremnts a year ago or so, but I don't remember what they were. I want to think a few microseconds for words deep near the bottom of the dictionary. 2022-12-17 14:27:19 And gForth just blew that right out of the water - it was much faster. 2022-12-17 14:27:46 So I suspect even plain vanilla Forth would get several hundred thousand words per second. 2022-12-17 14:30:13 What's the name of that "delay perception metric"? It's some guys name, and it's 400 ms; apparently it's only when a command's response time exceeds that that we begin to feel like we're "waiting." They mentioned it in Halt And Catch Fire. 2022-12-17 14:32:17 Doherty. 2022-12-17 14:32:52 https://lawsofux.com/doherty-threshold/ 2022-12-17 14:39:18 So I suspect that unless your system rebuild involves 100k source words or not, then it's probably just not an issue even if you do it the conventional way. 2022-12-17 14:39:49 Of course Chuck also had that "1kB target," but that feels kind of arbitrary to me, and such things really also just don't matter much these days. 2022-12-17 14:44:26 what is the 1kB target? 2022-12-17 14:45:53 apps should be 1kb at most 2022-12-17 14:50:26 And also the SYSTEM - he wanted it to be 1kB too. 1kB compiled and 1kB source. 2022-12-17 14:50:39 So he was hard focused on source compression techniques. 2022-12-17 14:50:57 Which really isn't helping with "understandbility" at all - just saves a tad of storage. 2022-12-17 14:52:28 For a few years in there Chuck was trying to do without source code COMPLETELY, but he gave up on that idea after a while. 2022-12-17 14:53:20 Sounds like some of the OKAD work he did by starting in a debugger and poking the first bits of the system into RAM, until he had enough to help him move forward. 2022-12-17 14:55:44 I think changing the language so that you can pack more meaning into fewer words can be claimed to have a "mental advantage" for the programmer. But once you are using compression of any kind, the only benefit you can claim then is "less storage." That's not a very compelling thing these days. 2022-12-17 14:58:24 Oh, another thing mentioned in that article was that by knowing (from the color) what kind of thing you're typing, the editor can also do earlier error detection. Say your color is "hex number." Then the editor can refuse to accept characters that would make your word invalid as a hex number. Even more complexity in the editor. 2022-12-17 14:58:53 I do see, though, that that validity check has to happen SOMEWHERE, and I guess earlier is better. And in ColorForth you CAN do it in the editor, so why not, I guess. 2022-12-17 15:49:26 You know, this way I'm doing looping these days, with that (possibly conditional" "me" construct. I think if I wanted to implement that in a hardware Forth, I'd include a small hardware stack in the design. The programmer would never overtly see this stack. Every time you "nest" to a new definition level, the starting address of the new word would be pushed to that stack. Return operations would pop it. 2022-12-17 15:49:28 And I'd have an instruction that would copy the current IP to that top cell of that stack (replacing whatever was there previously). I'd call that word something like :~ and its purpose is to set a loop target somewhere WITHIN a word instead of at the beginning. 2022-12-17 15:49:50 Then the "me" words wouldn't need offsets / addresses compiled with them - they'd just transfer control to the location specified by the top of that stack. 2022-12-17 15:50:27 This stack would add no run-time overhead (except for calls to :~ instruction), since you could push and pop it in parallel with normal call/return operations. 2022-12-17 15:51:25 This arrangement would preclude having nested loops at a single definition level, but I don't tend to do that anyway - I look at that as a golden opportunity to factor. 2022-12-17 15:53:12 I suspect this would make unconditional loops "zero overhead" in the same way return operations can be zero overhead in such designs. 2022-12-17 15:53:47 You can see the return / unconditional jump instruction coming if you look for it, and nothing the current instruction does changes the fact that you're going to do that, so you can start it early. 2022-12-17 15:54:21 I'd think 6 or 8 cells deep for that looping stack would be plenty. 2022-12-17 15:54:54 I don't know if this idea is beneficial in a standard computer software Forth; I think you've got to use hardware to get its full payoff. 2022-12-17 15:55:23 In a software Forth the extra pushes to and pops from that stack would slow everything down, whether you intended to use the feature or not. 2022-12-17 15:56:58 The common approach Chuck took later on in his chips was to have definition cells contain either an address for a sub-word or a group of packed opcodes. So those designs "intermingle" machine code and definition addresses in a way that's very different from normal threaded designs. 2022-12-17 15:57:12 That has ramifications I don't think I've fully thought through yet. 2022-12-17 15:57:49 It's more like a code threaded Forth, and I don't have a lot of past experience with those. 2022-12-17 15:58:33 He generally didn't support looping back to the middle of a packed opcode cell, so that required some paying attention to what you were doing. 2022-12-17 15:58:59 Sometimes have to pack nop instructions into the lsat slots of a cell to get to a "valid jump target." 2022-12-17 15:59:18 If you're only jumping back to the start of a word that's not an issue, but the :~ thing brings it in. 2022-12-17 16:00:40 :~ would have to be the last "non-nop" slot of its cell. 2022-12-17 16:31:21 It seems likely to me that you could probably execute the :~ instruction itself in parallel with one of its neighbors. The only cost at all would be when actually taking the conditional jumps, and that's hard to avoid in any case. 2022-12-17 16:39:33 It would probably make sense to always do any pre-fetching in the "take the loop" direction, since that's the only thing you'll ever do more than once - once you "don't take it," it's gone and over. 2022-12-17 16:40:00 So you'd pay one pipeline dump (to whatever extent you had a pipeline) when you fell through the loop. 2022-12-17 16:43:44 And if you wanted to you would have had the opportunity to catch that fall-through address (you did have it at the output of your IP increment circuit earlier) and save it if you wanted to. 2022-12-17 16:49:37 I've also always had the notion that in a packed opcode system like that, as you found the opcodes you could cache them in some fashion. Then if you looped back you wouldn't need to fetch them again. 2022-12-17 16:50:11 I've even gone so far as to try to do separate fetch and execute units, with that cache between them. 2022-12-17 16:50:39 That changes the nature of the return stack, though; it would be owned by fetch and couldn't be touched by execute. 2022-12-17 16:50:53 And I suspect my conditional returns foul that separation up royally. 2022-12-17 16:51:16 The fetch unit wouldn't know whether the return would happen or not. 2022-12-17 16:51:55 I didn't do the conditional returns until long after I tinkered with that structure. 2022-12-17 19:02:07 You know, and interesting aspect of the "me" words and :~ is that it open the possibility we've previously discussed of looping on the interpreter line. 2022-12-17 19:02:12 Or within a source block. 2022-12-17 19:03:16 I don't see any reason why it wouldn't work, completely the way you would expect. I don't have any stellar use cases in mind, though. 2022-12-17 19:04:01 :~ would have to have an interpret action and a (normal) compile action, though. 2022-12-17 19:04:40 If you were interpreting, it would copy >in into some variable. 2022-12-17 19:04:52 Instead of manipulate that little stack I mentioned. 2022-12-17 19:05:26 All the "me" words would have to have interpret actions too. It would add a fair amount of extra code. 2022-12-17 19:05:40 I'm not jumping up and down over it or anything. 2022-12-17 20:46:49 Wow - it looks like in OK (the OKAD OS) Chuck doesn't actually TYPE. 2022-12-17 20:47:13 He moves the cursor to a location and SCROLLS the character there through the list of possible values. 2022-12-17 20:47:21 That would drive me insane in nothing flat. 2022-12-17 20:47:57 Trying to jettison the keyboard has always struck me as one of the more... "odd" things he did over the years. 2022-12-17 21:32:41 good evening. new here, just started poking around at Forth a few days ago. Reading through Starting Forth now. 2022-12-17 21:52:28 KipIngram: he’s using an (S)NES joypad instead of keyboard? 2022-12-17 21:53:03 probably for access to the Konami Code 2022-12-17 21:58:03 He's done several different keyboard evaluations. He used a 7-key keyboard, and at another time a 3-key thing he did "chords" on. 2022-12-17 21:59:05 The one advantage I could see offered by something like that is ease of interfacing. Keyboards aren't exactly "simple" if you're having to interface them all the way at the bottom (i.e., without an on-board keyboard controller). 2022-12-17 22:03:01 Well, I guess they're not THAT bad. You usually have the keys laid out on a row/column grid. Say the column wires are on an output port, and the row wires on an input port. Pushing a key connects that column to that row. 2022-12-17 22:03:23 So you roll an "on" bit across the column bits and see which row bits light up for each one. 2022-12-17 22:05:01 and debouncing, etc 2022-12-17 22:05:09 And debouncing, yes. 2022-12-17 22:05:25 Which can just be a short delay and match check. 2022-12-17 22:07:11 or use paralell in serial out daisy chainable 7400 series chips 2022-12-17 22:08:08 which gives n key rollover easily 2022-12-17 22:09:29 Well, yes - I was trying to describe the absolutely minimal hardware approach. 2022-12-17 22:10:26 On the other hand, your approach probably uses less processor I/O. 2022-12-17 22:12:00 Anyway, I suspect those were approaches that perhaps worked well for Chuck that just would never work well for me. I really do think it would just grind me down trying to get stuff done that way. 2022-12-17 22:12:17 Some things would just feel horribly slow to me. 2022-12-17 22:51:15 So, question. 2022-12-17 22:51:31 Chuck's OK/OKAD system ran on a 386 machine running DOS. 2022-12-17 22:52:14 You booted up DOS, put the OK/OKAD floppy in, and used a program on there to load OK into the RAM from 1 MB - 2 MB, and to load OKAD into 2 MB and up. 2022-12-17 22:52:33 Then you ran a program that basically turned off all of the interrupts and jumped into OK. 2022-12-17 22:52:59 And that was that - later you could drop back out, turn interrupts back on, drop back to DOS, and use DOS commands to save those RAM ranges again. 2022-12-17 22:53:41 The question is - is this even POSSIBLE in any sort of straightforward way anymore? Or do Windows and Linux so hopelessly bundle up all of your system resources that there's nothing left to work with? 2022-12-17 22:54:09 I get it that the goal back then was to use resources the OS didn't make available, and now it does make them available. 2022-12-17 22:54:16 So there's no "need" for an approach like that. 2022-12-17 22:54:49 But if one wanted to experiment with running with zero OS support, can it be done in a way that lets you gracefully return to the OS? 2022-12-17 22:55:11 Or would you need to just write something that would boot on its own from the jump? 2022-12-17 22:56:26 Oh, in addition to turning off interrupts it also switched into and later back out of protected mode. 2022-12-17 23:32:01 tetsuo9: run while you still can! 2022-12-17 23:33:13 rowing machines also work