2024-09-02 14:38:14 hahaha, : roll dup 0<= if drop else swap >r 1- roll r> swap then ; 2024-09-02 14:38:31 hope you didn't expect roll to be fast! 2024-09-02 14:39:16 oof it's recursive 2024-09-02 14:41:14 roll being arbitrary depth rot? 2024-09-02 14:41:19 yeah 2024-09-02 14:42:17 seems like you could do it with some stack pointer nonsense 2024-09-02 14:42:43 and whatever your version of memcpy is called 2024-09-02 15:00:16 I didn't notice that see was giving me a version that actually wouldn't compile; you could say : roll recursive dup 0<= if drop else swap >r 1- roll r> swap then ; or : roll dup 0<= if drop else swap >r 1- recurse r> swap then ; but not the way see represented it 2024-09-02 15:01:42 I don't think recursive has ever been standardized (Gforth lists it as "gforth" https://www.complang.tuwien.ac.at/forth/gforth/Docs-html/Calls-and-returns.html#index-recursive-_0040var_007b-compilation-_002d_002d-_003b-run_002dtime-_002d_002d---_007d--gforth-1140) but it was present in F83 2024-09-02 15:01:51 with the comment that the authors liked it better than recurse 2024-09-02 15:02:39 (a comment the Gforth authors echo!) 2024-09-02 15:04:43 "These words are in the reference word sets, and are only include [sic] for completeness. We prefer to use RECURSIVE rather than RECURSE. ( See RECURSIVE )" is the F83 shadow screen for recursive 2024-09-02 15:06:23 F83 does implement roll the way you would expect. The shadow screen says, "Similar to SHAKE and RATTLE. Should be avoided." 2024-09-02 15:08:42 the only way you could implement roll to reliably be fast would be to use something like ropes for the operand stack. But then everything else would be slow 2024-09-02 15:18:53 it's the same as move-to-front 2024-09-02 17:32:34 xentrac: Yeah, pay the piper one way or another. I'm firmly in the "ROLL is bad" camp. I don't mind PICK nearly as much - it doesn't have the same sort of performance issue. It's just "philosophically disliked." 2024-09-02 17:33:13 I have a slightly different mechanism I use for the occasional times I need to dig deeper than normal into the stack. 2024-09-02 17:34:00 I try to use it as infrequently as possible - mostly just when I can't suss out a way to avoid it without a lot of pain. 2024-09-02 17:54:38 I keep thinking all the discouragements in forth are just for the novices to get good habits 2024-09-02 17:54:55 once you know what you are doing you can be your own judge 2024-09-02 17:55:23 I never know what I do, so I try to listen when a language community discourages something 2024-09-02 18:54:40 Is it better to avoid defining parsing words if possible? 2024-09-02 18:56:45 I was looking at this https://adventofcode.com/2021/day/3 and thought hm, maybe I can make it look neat. I know the simple solution is just to hard-code it. 2024-09-02 18:57:41 So the first step would be scanning the input matrix. Would you do it by line or by character? 2024-09-02 19:11:47 Er, I was typing what I wanted to do but then it hit me how to do it. What a wild rubber duck chase :| 2024-09-02 19:11:50 BINARY or 2 BASE ! is how you might parse that 2024-09-02 19:23:38 That's what I was aiming for with the parsing words, more or less: http://0x0.st/Xw8Z.forth 2024-09-02 23:06:12 KipIngram: yeah, pick makes your code hard to read 2024-09-02 23:08:28 because you have to count the items on the stack to figure out which one is being picked. it's a lot like writing machine code with raw memory addresses instead of assembly with labels. except, in machine code, normally your variables stay at the same memory location instead of moving every instruction 2024-09-02 23:10:21 unfortunately I don't think we really have much of a continuing community to give advice on things like parsing words and pick. we're not the folks who used Forth to build production systems in the 80s. We're pretty much a bunch of beginners 2024-09-02 23:10:42 in many cases, beginners who have written our own Forth systems, to be sure 2024-09-02 23:22:14 better to be an eternal/perpetual beginner than a non-starter though 2024-09-02 23:27:32 xentrac: Right. The mechanism I did up circumvents that inconvenience by setting up an extra register - a "frame pointer." Once you open a frame things are at fixed offsets until you close it, even if the normal stack pointer changes. 2024-09-02 23:27:39 MUCH easier to keep up with what's going on. 2024-09-02 23:28:38 It turned out to have a fringe benefit I hadn't expected - it offers a really clean way to get the stack cleaned up, even if multiple code paths that leave different amounts of remnant stuff converge. 2024-09-02 23:28:57 That turns out to be useful more often than indexint into the stack does. 2024-09-02 23:30:40 i mean you can tell exactly which item is being picked if you chuck a comment in there 2024-09-02 23:31:04 Sure - you CAN. It's just tedious and potentially error prone. 2024-09-02 23:31:19 have you ever read about em-1 2024-09-02 23:31:37 The frame setup gains nothing but convenience, really. Except that "stack cleanup" perk is awfully nice. 2024-09-02 23:31:47 where do you keep the pointer 2024-09-02 23:31:50 the return stack? 2024-09-02 23:32:08 Yeah, I stow the old one on the return stack so I can restore it when I close the frame. 2024-09-02 23:32:25 oh it's a register yeah 2024-09-02 23:32:27 clever 2024-09-02 23:34:37 I've thought about eventually giving the compiler the capability to parse stack comments and associate names with the offsets from the frame pointer. Sort of a locals mechanism. The extra overhead would all be at compile time. 2024-09-02 23:34:43 Likely will never get around to that, though. 2024-09-02 23:34:50 Like I said earlier, I try not to use it too often. 2024-09-02 23:34:59 and that means not every function needs a frame pointer 2024-09-02 23:35:08 Right. 2024-09-02 23:35:13 my sister actually came up with some ideas for locals 2024-09-02 23:35:23 not sure if she ever actually implemented them though 2024-09-02 23:42:06 I wish my sister was into Forth. Or my wife or any of my kids - it would be neat to have another Forth nut in the family. :-) 2024-09-02 23:43:47 she's only really into forth because i am 2024-09-02 23:43:54 she's more into lisp 2024-09-02 23:43:58 on the weird languages front 2024-09-02 23:49:31 unjust: yes, I love being a beginner at things. But it would be nice if there were grizzled veterans to learn from 2024-09-02 23:49:36 maybe I'll email hackers-l 2024-09-02 23:49:56 KipIngram: ha, yes, that sounds familiar ;) 2024-09-02 23:51:21 aside from the obvious comparison with languages like C and Pascal, PostScript has a thing sort of like your frame-pointer, but on the *operand* stack, for building and returning variable-sized data structures 2024-09-02 23:51:47 it's called the "stack mark" 2024-09-02 23:52:21 so, for example, to build a PostScript dict, << pushes a stack mark, and >> turns everything on the stack above that mark into a dictionary 2024-09-02 23:53:47 so for example you can say <> >> 2024-09-02 23:54:24 this actually pushes *three* stack marks onto the PostScript stack, because [ also pushes a stack mark, and ] turns everything on the stack above that mark into an array 2024-09-02 23:54:49 oh thats clever 2024-09-02 23:55:13 (in Forth you would need an extra couple of spaces, and Forth doesn't have /) 2024-09-02 23:55:18 you could implement the PostScript operator that tells you how many things are above the mark by linearly searching the stack 2024-09-02 23:55:51 but you can also implement it in constant time, by having a current-stack-mark register which gets saved in the previous mark every time a new mark is pushed 2024-09-02 23:57:22 the upshot of this is that, IIRC, you can implement all of PostScript Level 1, with its flexible array and dictionary data structures, without ever having to implement resizing of them. You never have to grow a hash table or an array; there isn't an operator in the language that allows this 2024-09-02 23:57:34 all your resizing happens on the parameter stack 2024-09-02 23:58:08 there's also a cleartomark operator which just discards everything above the top stack mark. So a subroutine can say, for example, [ 3 4 2024-09-02 23:58:22 in order to return a variable number of things on the stack, in this case two of them 2024-09-02 23:58:40 which the caller can discard after using, without ever copying them onto the heap 2024-09-02 23:59:28 later on I think they did add the ability to expand dictionaries by adding more stuff to them, but in PostScript Level 1 you have to specify the capacity of a dictionary when you create it