IRC Log - 2025-03-23 - ##forth

Channel: ##forth
Total messages: 95
Time range: 00:30:54 - 22:26:23
Most active: xentrac (39), veltas (16), KipIngram (13)
00:30:54 ##forth <crc> MrMobius: prior to my current vm-based designs, I always just left it to the user to deal with, though on x86, it didn't really matter
00:32:06 ##forth <crc> if I was dealing with a system that faulted on unaligned access, I'd probably just have @ and ! do operations at the byte level behind the scenes
00:35:24 ##forth <thrig> apple amd64 made you do various alignment calls, but that may just have been apple being weird
03:29:07 ##forth <cleobuline> Local time for Paris, Île-de-France, Metropolitan France, France is: 2025-03-23 ​​03:21:44 (Time time: Europe/Paris)
03:39:07 ##forth <cleobuline> ForthBot: WORDS
03:39:07 ##forth <ForthBot> DP HELLO DOUBLE FACT POW FIBONACCI COUNTDOWN TUCK 2DROP SUM_SQUARE CUBE SUM_CUBES RECUNACCI CAT :D SOURCE PGCD PRIME? SEED RANDOM RAND DICE ROLLDICES 2DUP 3DUP NUMS STARS COUNT INIT-NUMS SHUFFLE-NUMS PICK-NUM NUM-TO-STR INIT-STARS SHUFFLE-STARS PICK-STAR PICK-2-STARS LOTO EURO foo TRIPLE POW2 TEST-CASE FACTLOOP INIT-RANDOM
03:39:41 ##forth <cleobuline> ForthBot: SEED @ .
03:39:42 ##forth <ForthBot> 15033073099093672470495
03:42:17 ##forth <cleobuline> ForthBot: INIT-RANDOM SEED @ .
03:42:17 ##forth <ForthBot> 1742697737
03:42:27 ##forth <cleobuline> ForthBot: INIT-RANDOM SEED @ .
03:42:27 ##forth <ForthBot> 1742697747
03:44:18 ##forth <cleobuline> next i will do ForthBot multiusers , with environnement for each users calling it , in a linked list it will be the best forthbot of the world :)
03:46:00 ##forth <cleobuline> ForthBot: DP @ .
03:46:00 ##forth <ForthBot> 44
10:29:52 ##forth <veltas> MrMobius: Personally if unaligned access raises an exception, then it depends a little whether the exception is trapped in your Forth
10:30:55 ##forth <veltas> But also for performance reasons I wouldn't check it, so yeah just throw
10:31:31 ##forth <veltas> And even I write code with correct alignment, just because the performance is better on x86, not even for stability on other platforms
10:31:45 ##forth <veltas> I think most Forth code is alignment safe, or can be with minor tweaks
10:33:19 ##forth <veltas> Even the Forth standard can conform to the hardware requirements here, so it seems safe to lean on the actual architecture restrictions, and require alignment
10:34:04 ##forth <veltas> My ZX Spectrum Forth has the alignment words, they're just identity/no-op words
10:42:06 ##forth <veltas> I've found the main pain point for alignment is packing strings alongside other data, e.g. dictionary headers
10:42:49 ##forth <veltas> Usually you can put strings last, but for dictionary header the parameter area comes after the name, so you can just pad to alignment
12:30:55 ##forth <KipIngram> That problem goes away if you separate headers from bodies.
12:32:06 ##forth <xentrac> create foo 3 allot create bar 3 cells allot still needs to worry about alignment even if headers are separate from bodies?
12:32:27 ##forth <KipIngram> My thinking on headers these days is to let the strings grow down from the top of the RAM region instead of up from the bottom. Then you don't need separate "link" and "count" fields - the first fields of each header are fixed, and then the string is last and its count byte tells you how to get to the next (earlier) header.
12:32:38 ##forth <xentrac> (but not on a Z80)
12:33:30 ##forth <KipIngram> Well, that's true, yes. Good point - names aren't the only strings.
12:34:22 ##forth <xentrac> you could put the count at the end of the string if you want the dictionary headers to grow up from the bottom of something. Won't work without separate headers in either case
12:36:28 ##forth <xentrac> like | cfa | dfa | f | o | o | 3 | or something?
12:38:50 ##forth <KipIngram> Yeah, that's true, but then you're kind of dealing with the "odd bits" elsewhere. I kind of like the idea of a "dictionary" being a RAM region with some management variables at the bottom and the strings growing down from the top. A low variable will point to the last item added, and that gets you the equivalent of a linked list search. But then if you want to you can OPTIONALLY add a low
12:38:53 ##forth <KipIngram> variable (which would be NULL when you're not doing this) that refers to a separately allocated hash table. So hashing is an optional feature you can add to any dictionary.
12:40:56 ##forth <KipIngram> It's not really quite a fully generic dictionary, though, because it's not so feasible to remove items.
12:41:24 ##forth <KipIngram> You could invalidate them, I guess, but then you'd accumulate cruft.
12:42:23 ##forth <KipIngram> For Forth's usually "last defined, first forgotten" mode, though, it works quite nicely.
12:42:53 ##forth <KipIngram> s/usually/usual/
12:48:47 ##forth <xentrac> you could remove items off the end and then rehash the whole dictionary
12:49:18 ##forth <xentrac> oh, you mean it's not generic in that it doesn't support non-LIFO deletion
12:52:20 ##forth <xentrac> if you want non-LIFO deletion with storage reclamation for strings you need a fairly complex allocator. not, you know, anything beyond what BASIC-80 had on the Altair
12:52:42 ##forth <xentrac> but more than just a bump pointer
12:53:50 ##forth <KipIngram> Yeah, adding that raises the complexity level a good bit.
12:53:57 ##forth <KipIngram> It's just so elegantly simnple otherwise.
12:54:32 ##forth <KipIngram> And yes - invalidation with occasional re-construction would likely be pretty practical.
12:55:21 ##forth <KipIngram> Dictionaries are pretty useful - I've used them in Python a good bit.
12:56:40 ##forth <xentrac> an alternative often used in old Lisps was property lists. You could imagine adding those to a Forth
12:57:38 ##forth <xentrac> you'd still need dynamic allocation, but almost just a freelist
12:58:32 ##forth <xentrac> the idea is that each "atom" or "symbol" (Forth "word") has a linked list of "properties" hung off it
12:58:46 ##forth <xentrac> each itself identified by a symbol
12:59:30 ##forth <xentrac> so the actual hashing step is done at read time when the symbol is interned
13:00:17 ##forth <xentrac> each property corresponds to a Python dict. it doesn't garbage-collect the properties or scale to a lot of them
13:01:06 ##forth <xentrac> but often that's okay
13:08:11 ##forth <veltas> xentrac: I put the count at the start and end, and I tend to write essentially ".align 4, count; .byte count"
13:08:30 ##forth <veltas> Sorry I mean ".byte count; .align 4, count"
13:08:43 ##forth <xentrac> veltas: hmm
13:08:47 ##forth <veltas> That guarantees that the area *ends* with the count
13:09:06 ##forth <xentrac> yes, that makes sense
13:09:06 ##forth <veltas> And you can recover the full aligned offset from the count
13:09:19 ##forth <veltas> But yeah on Z80 it makes no difference
13:09:46 ##forth <xentrac> although, wouldn't you want the end of the count byte to be aligned rather than the beginning?
13:09:57 ##forth <xentrac> like, assuming 4-byte alignment:
13:10:52 ##forth <xentrac> | @ | | | 1 |
13:10:52 ##forth <xentrac> | > | r | | 2 |
13:11:03 ##forth <xentrac> | s | w | a | p | | | | 4 |
13:11:13 ##forth <xentrac> not, for example
13:11:30 ##forth <xentrac> | @ | | | | 1 | | | |
13:11:51 ##forth <veltas> Yes that's why I do ".byte count; .align 4, count", i.e. it fills the alignment padding with counts too
13:12:04 ##forth <xentrac> oh, I misunderstood
13:12:06 ##forth <xentrac> thanks!
13:12:14 ##forth <veltas> Guarantees it finishes aligned, because .align comes last, and .byte comes first to ensure there's at least one
13:12:24 ##forth <veltas> No problem, it's subtle
16:24:00 ##forth <MrMobius> actually, just masking out the bottom bits is probably easiest
16:42:10 ##forth * xentrac masks his bottom bits
22:17:58 ##forth <cleobuline> ForthBot: 1 16 POW2
22:17:58 ##forth <ForthBot> 1
22:18:30 ##forth <xentrac> ForthBot: 2 5 POW2 . . .
22:18:31 ##forth <ForthBot> 32
22:18:46 ##forth <xentrac> oh, you really need to fix that multiline output
22:18:53 ##forth <xentrac> ForthBot: . . .
22:18:53 ##forth <ForthBot> Stack empty
22:19:03 ##forth <xentrac> ForthBot: . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22:19:03 ##forth <ForthBot> Stack empty
22:19:09 ##forth <cleobuline> lol
22:19:24 ##forth <xentrac> ForthBot: . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22:19:24 ##forth <ForthBot> Stack empty
22:19:28 ##forth <xentrac> not fixed yet
22:19:43 ##forth <xentrac> not fixed yet
22:19:45 ##forth <xentrac> ForthBot: . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22:19:45 ##forth <ForthBot> Stack empty
22:19:50 ##forth <xentrac> still not fixed
22:20:20 ##forth <xentrac> it shouldn't be possible for one line of chat to provoke multiple lines of output, ever
22:21:55 ##forth <xentrac> because if it is people will do it by accident and annoy others
22:23:25 ##forth <cleobuline> i am working on a multiusers forthbot
22:23:30 ##forth <cleobuline> now
22:23:46 ##forth <cleobuline> this version wil be obsolète :)
22:26:23 ##forth <xentrac> a multiuser stateful interpreter is exciting!