Salta al contenuto principale


#BabelOfCode 2024
Week 2
Language: Forth

Confidence level: Low

PREV WEEK: mastodon.social/@mcc/113743302…
NEXT WEEK: mastodon.social/@mcc/113867584…
RULES: mastodon.social/@mcc/113676228…

So today's challenge looks *absurdly* easy, to the point I'm mostly just suspicious that part 2 will get hard. I figure this is an okay time to burn Forth.

I'm wanting to save Fortran for a week I can use the matrix ops. This puzzle looks suspiciously like part 2 will turn into a 2-dimensional array problem.


#BabelOfCode 2024
Week 1
Language: Applesoft BASIC

NEXT WEEK: mastodon.social/@mcc/113783248…

"Advent of Code" is an online event where you're given 25 two-part code puzzles, which you're supposed to solve in 25 days in December. I was busy so instead I'm doing a slow-motion, 1-puzzle-per-week version over the course of 2025, but with an added restriction: I have to do it in a different language each week.

@unjello proposed a hashtag, so maybe there are two of us on this
mastodon.gamedev.place/@unjell…
(1/2)


Questa voce è stata modificata (9 mesi fa)
in reply to mcc

I *think* I'm doing this in pforth, for the simple reason that gforth, uh, isn't maintained anymore it seems, and so got dropped out of Debian Testing (which I have now)? I *think* I'd be *happier* using RetroForth, which is a "modern" Forth, but I guess it's better to learn the standardized, ANS Forth first. Even though everyone hates ANS Forth? Including the inventor of Forth…?

My biggest fear is there appears to be no way to read numbers written in ASCII from a file. We're predating ASCII

Oblomov reshared this.

in reply to mcc

First problem I hit is comments don't work. The documentation specifically says text in parenthesis are comments, but it isn't accepted.

After some staring at the docs, I realize in all the examples, there are spaces. It turns out (Comment) is not a comment, but ( Comment ) is a comment. Because ( isn't a pure operator built in the language, rather there's a FORTH word ( that eats all words until ) is found. Holy crap. I never thought I'd say this but maybe it IS possible to self-host too hard

Oblomov reshared this.

in reply to mcc

the same thing goes for strings, at least in a lot of forths I've used 😩
in reply to mcc

Forth is from an age when even macro assemblers cost money (and didn't support your arch anyway). Having a medium-level REPL you can write in a few hundred instructions is nothing to sneeze at. Does make for some weirdness though... I can't wait for you to make it do matrix ops.
Questa voce è stata modificata (9 mesi fa)
in reply to mcc

I've never looked at pforth but some pretty much define nothing. It might also define \ as to end of line comment.
in reply to mcc

oh oh. If you’re still open to language ideas and you want to get a sense of what a forth-like language would feel like if it were “modern”: have you heard of factorcode.org ?

It’s as if Common Lisp, Smalltalk, Forth, and Haskell had an unholy union. It was developed by two of the Swift devs!

Questa voce è stata modificata (9 mesi fa)
in reply to Kat Marchán 🐈

@zkat I was thinking about picking Uiua for my "modern forth" slot, would factor be different/better for this?
in reply to mcc

@zkat factor's probably more in the lineage of forth imo. uiua feels a lot like a more modern, stack based APL instead
in reply to mcc

So this documentation is kinda very bad!

Lacunae I have noticed:

- They define a `KEY` operator for taking a character from STDIN, but don't explain what happens if `KEY` receives an EOF (experimentally: I seem to get a -1?)

- They explain a special syntax `CHAR n` for inserting the ASCII value of n directly into the code, but don't explain how the fuck you're supposed to represent the ASCII value for a non-character symbol such as a space or newline

Questa voce è stata modificata (9 mesi fa)

Oblomov reshared this.

in reply to mcc

More pforth documentation horrors

- The pforth tutorial is not a tutorial for pforth but rather a general forth tutorial, and therefore hedges itself frequently. For example, notice this section where it explains that "many forths" have a CASE statement. "Many forths"? What about THIS forth I'm reading the documentation to RIGHT NOW?

- ABORT not documented. The documentation lists it as a reserved word but not what it does

Oblomov reshared this.

in reply to mcc

There you go again, you silly goose, pretending programming is an exact science.
in reply to mcc

"Many Forths" is my favorite Madeline L'Engle book.

(Alternative joke: "Many Forths" is a pretty good newspaper comic)

in reply to mcc

the book to use for "I don't know enough Forth yet to understand this Forth" is Starting Forth forth.com/starting-forth/

The word to use for "I don't understand what this Forth system is doing with this word" is SEE, which disassembles the word into its components(and in more developed systems, goes all the way down to the assembly instructions). pForth does have SEE, fortunately.

in reply to mcc

Wrote a version 1.0 of my program, testing it. All I've got so far is the character parser, reading the numbers in and decoding ASCII and that's it.

This is… bad. I would describe this as bad behavior for a programming language interpreter

Oblomov reshared this.

in reply to mcc

The forth interpreter isn't completely busted, my test.f screenshot above worked. A simple "echo ascii values" program I wrote ( BEGIN KEY DUP . CR 0< UNTIL ) worked. But my 32 line, mildly more sophisticated program just… signal 11s. I do not know how to proceed. I am using "Debian Testing", which is TECHNICALLY a beta OS, so maybe the pforth is broken *subtly*. gforth isn't in dpkg. I don't… I don't know what to do next if the compiler crashes.

Maybe I ssh into a VPS and run gforth there? 🙁

in reply to mcc

Forth isn't an interpreted language, though. It's compiled. (Granted, almost all of the compiled code is branch instructions to the definitions of words, but it's still compiled).
in reply to mcc

It's probably a stack underflow. That's where most of my segfaults come from.

I usually stick in a metric shitload of `.S` and see if the stack is actually what I think it should be, and where it might be underflowing.

in reply to mcc

This is a language developed in the 1970s. You can't waste precious clock cycles on bounds checking every time you pop something off the stack! What sort of profligate fool are you?!
in reply to mcc

A segfault in a generally memory safe language would suggest a stack overflow to me. Any chance of that? Can you debug printing to see if anything is going on before the segfault?
in reply to mcc

@porglezomp @unlambda A `VARIABLE` is literally just a word that puts an address onto the stack, so that you can use `!` and `@` on it...
in reply to mcc

So here's my *current* code, which crashes in pforth:

github.com/mcclure/aoc2024/blo…

I run it in gforth:

cat "data/sample-2.txt" | gforth src/puzzle.f

I get:

in file included from *OS command line*:-1
src/puzzle.f:13: Interpreting a compile-only word
>>>BEGIN<<< ( Line )
Backtrace:
$7F5C6D55EB30 throw

Line 13 is indeed the word "BEGIN". According to the tutorial, that is how you open a UNTIL loop.

fuck the in What?

in reply to mcc

control flow words like BEGIN, UNTIL, IF, ELSE, THEN, etc should only be used inside a word definition. they are "compile-only" words, can't be used in interpreter mode.

Some forths have ways to handle these, but it's not standard.

in reply to azul

so, if you wrap the BEGIN loop in a word definition and then call it, you should be good to go.

: my-loop
BEGIN
...
UNTIL
;
my-loop

Questa voce è stata modificata (9 mesi fa)
in reply to azul

@typeswitch It's wild that the failure mode for that is a segfault rather than an error message.
@azul
in reply to Cassandra is only carbon now

@xgranade in simpler forths these words will be executed as if they were in compile mode anyway. in general this will have some truly awful consequences ... like IF will not test anything, it will emit a conditional branch instructian and push an address on the stack, ELSE and THEN will take an address off the stack and write to that address, etc. so a segfault is the best you can hope for really.
in reply to mcc

the mode of the interpreter is still in the "interpreting" state(what you use at the repl) - if you place that code inside a word definition it will now be in compiler mode
in reply to mcc

FORTH is basically a macro assembler. or uh, macro code generator, really. tho there is an "interpreter" that recognizes words and immediately executes them.

if you call certain words, it corrupts the interpreter state. so they can only be called from compiled words.

or at least that's how it used to be done. we don't know about modern forths.

in reply to mcc

Most of the useful stuff for actual programming (like conditionals, loops) can only be executed once compiled. That's usually done with : to create a new word with the compiled code in it.

(Also, that code's massively non-idiomatic, with a massive C accent; The Forth way is effectively about building a DSL with words that you can use to solve your problem: I've seen it described as "language-oriented programming".)

in reply to mcc

Okay. So some updates.

It turns out loops (BEGIN..UNTIL) are a "premium" Forth feature and are only available inside functions. So I need to wrap the whole program in a : function ; . Well not the whole program, not the VARIABLEs, and I don't think you can nest the functions, and… never mind. I do the nest. New code:

github.com/mcclure/aoc2024/tre…

gforth fails with :

src/puzzle.f:38: Invalid memory address

I wrapped my program in a : run [code here] ; run . Line 38 is "run".

I'm still lost.

in reply to mcc

A thing worth noting here is if you read my posts carefully above, you'll find I successfully executed a BEGIN .. UNTIL program in pforth. So pforth just relaxes the requirements of gforth. I don't think I've hit what is causing pforth to crash yet. I'm just trying to satisfy gforth's requirements for running the software at all. Maybe I should have read gforth's manual instead of assuming pforth's is adequate 🙁
in reply to mcc

This raises an interesting problem. I could have used a "nice" Forth like RetroForth or Factor(?) but I wanted to learn ANS Forth before I moved on to specializations. However, now I realize there are *only* specializations. Pforth is apparently giving me all kinds of niceties, the premium DLC is included at the toplevel. And I know for a fact gforth (of course, because that stands for GNU Forth) contains GNU extensions. So there are two standard Forths in Linux, neither actually standard.
in reply to mcc

you're starting to see how forth is more of a "way of life" than a programming language. the community convention is that you write your own forth instead of buying one off the shelf, lol
in reply to mcc

Okay. So this explains my segfault! I can now run in pforth.

xoxo.zone/@clarity/11378379402…

I accidentally wrote on one line `partial TRUE !` ; correct would be `TRUE partial !`. All variable assignments in Forth are done with pointer dereferences, so the wrong order was like trying to write to memory address TRUE (-1). It is as if C++ allowed you to write "true = x;" by accident instead of "x = true;" and write the address of x to 0x1

I am unblocked, but still can't do jack shit in gforth


you have `partial TRUE ![url=https://infosec.exchange/users/1njection]`[/url] and `TRUE partial ![url=https://infosec.exchange/users/1njection]`[/url], I forget which, but one of those is wrong (I think the latter is correct?). This is your invalid memory access (you're trying to set the data stored at 0x01)

in reply to mcc

Sorry, I kinda disappeared in the middle of asking a question. Me and @spookysquid were doing something extremely normal
in reply to mcc

I need a modem so I can hack my N64, and Miguel thought he might have a modem for his old Compaq Portable III, so we're trying to see if the Compaq will boot. You see.
Questa voce è stata modificata (9 mesi fa)
in reply to mcc

At least it's not the Compaq Portable I. It's the only vintage computing purchase I regret. The foam pads on the keyboard have rotted on almost all still-existing specimens. Mine too.

The KB requires 12V, and drops 7V through a linear regulator that becomes as hot as the sun if not attached to the combo heat sink/KB enclosure. I need to 3D print some broken KB parts. The PCB is warped; the KB randomly types characters.

I should probably sell it to someone who is willing to fix it.

in reply to mcc

I have fond memories of that device.
With the modem program that had p2p mode, we had work-from-home 3-4 days a week, could share patch-files MORE easily from home.

The Herc monitor wasn't my favorite.
4 colors, all of them shades & tints of orange.
But it was amazing for the day.

in reply to mcc

*kicking and throwing things*

The tutorial for pforth softsynth.com/pforth/pf_tut.ph… says if you want an ASCII constant you write: CHAR A

I want to print an A. I write CHAR A EMIT. I get:

A ? - unrecognized word!
INCLUDE error on line #18 , level = 1
CHAR A EMIT
^^^^^^

I write CHAR 'A' EMIT. This works. The documentation lies! The documentation lies!!

I'm getting unexpected results for .S. Wait, what results do I expect? Like ABORT, PFORTH DOCUMENTS .S EXISTS, BUT NOT WHAT IT DOES.

#18
in reply to mcc

I cannot work under these conditions. I now see why everyone writes their own Forth interpreter instead of using a prepackaged one. BECAUSE IT'S THE ONLY WAY TO KNOW WHAT ANYTHING DOES.

Oblomov reshared this.

in reply to mcc

I love Forth (JForth on the Amiga was a revelation to me in 1995) but…yeah.
in reply to mcc

I asked a while back how Forth is for text parsing. I was thinking like… structured text parsing. I did not think that "input a sequence of space-separated ASCII numbers" was going to turn out to be basically a workday and then I wouldn't have it working at the end
in reply to mcc

The number 101 is somehow poisoning my stack. I don't know why but the longer the program run the more instances of the number 101 show up on my stack. I don't know why. Once it begins the logic spirals out of control because 101 shouldn't be there. That's ASCII 'e' but I can't imagine why ASCII 'e' would wind up on my stack. This would be so much easier if I felt COMPLETELY SURE I knew what all the builtin words do, but it's lying to me about CHAR, so what else could it be lying about.
in reply to mcc

I think what I really need here is some kind of live debugger that steps ONE WORD AT A TIME and prints the stack out after EVERY word executes. I'm trying to put in debug prints, but SOMETHING IS PUTTING JUNK ON MY STACK and I don't know how to tell if it's my debug prints that are creating the stack clutter
in reply to mcc

UPDATE: I have found a Forth debugger of the type I was looking for, but it only runs in DOS

holonforth.com/debugforth.html

EDIT: Before anyone asks, no, the Compaq Portable III does not help here, it boots but we have no way to get data on or off of it

Questa voce è stata modificata (9 mesi fa)
in reply to mcc

The shortcut key is "alt+F4". The screenshot shows it running under Windows 98. That's cursed!
in reply to mcc

pforth has TRACE (this may not display well on Mastodon):

: ABCD CHAR 0 DUP . EMIT ;
ok
Stack<10>
TRACE ABCD
<< ABCD +0 <10:0> || CHAR >> ok
s
<< ABCD +4 <10:1> 0 || (LITERAL) 0 >> ok
s
<< ABCD +12 <10:2> 0 0 || DUP >> ok
s
<< ABCD +16 <10:3> 0 0 0 || . >> ok
s
0
<< ABCD +20 <10:2> 0 0 || EMIT >> ok
s

<< ABCD +24 <10:1> 0 || EXIT >> ok
s
Finished.
ok

in reply to mcc

Oh, this helps with understanding some FORTH idioms:

rickcarlino.com/2017/common-fo…

The square brackets are "Bring compiler into and out of immediate mode". That's kind of what I expected; you use them to run this command now, which is what's needed from CHAR because it's a function that will just grab the next character from input (after any spaces) and give you its ASCII value. So you need it run before compilation.

Parentheses are a valid part of a word name, and they are conventionally for a low-level implementation detail.

in reply to Brian Campbell

OK, yeah, if I try in gforth, I get the behavior you're seeing; 'A' (or just 'A the closing quote is unnecessary) gives the character value.

This doesn't work in my version of pforth, where I need to use CHAR or [CHAR] if I'm in compilation context.

in reply to Brian Campbell

@unlambda CHAR 'A'
and
[CHAR] A

Do not do the same thing!! CHAR in compiled mode is dropping 82 on the stack and it's why my program is failing

in reply to mcc

Hmmm ... zForth is very simple, is written in C and has a "trace" option:

github.com/zevv/zForth

#Forth

in reply to mcc

Alright! Progress.

While I was on the bus, @unlambda looked it up and pforth *has* a symbol-by-symbol trace (it's called… TRACE). Unlike most things in pforth, *this* feature is well documented. Now it also requires me to use INCLUDE, which *isn't* documented, and which I couldn't get to work, but n/m, I just pasted the whole program into the terminal each time.

What I found: Remember me not getting `CHAR A` to work, and experimentally finding `CHAR 'A'` as substitute?

…It's not a substitute.

in reply to mcc

I jokingly referred to a Forth "premium" mode before. Non-jokingly, this is called "compiled" mode. Inside a function is "compiled"; outside is "interpreted". Apparently running CHAR in compiled mode puts the number 82 on the stack. Why? I don't know. That's ASCII "R". I don't get it. Then 'A' *separately* puts 64 (ASCII A) on the stack.

@unlambda also found the solution here: I need to say `[CHAR] A`. The brackets mean "use the interpreted-mode version, not the compiled-mode version". (1/2)

in reply to mcc

Should the tutorial have mentioned this? Should the reference manual have? Should the "Starting Forth" book I read a big chunk of, with the friendly cartoons, have mentioned it? Should, for that matter, the spec— which defines separate interpreted and compiled semantics for *many* words, but not CHAR ( forth-standard.org/standard/co… )— have mentioned it? None of them did. I found out by word of mouth on Mastodon that CHAR (and possibly some other stuff?) needs square brackets to act normal. (2/2).
in reply to mcc

Once I got inside of TRACE, and was watching the code execute word by word, suddenly Forth was the "elegant", clear, mechanically-precise machine I had assumed I would find Forth to be coming in. I understood what each word did, and if something went wrong I understood what. This is interesting, as when working with full programs Forth has felt like sentient jello. (1/2)
in reply to mcc

My takeaway here is that Forth is a chaotic system. Small changes in initial conditions lead to large differences in outcomes. The stack means the meaning of any one statement is dependent on the entire history of the program to that point! That means Forth is precise if you understand exactly what you're doing, but if your understanding is even a *little* off— say, because the documentation for just one keyword in the whole program is unclear— you get chaotic behavior and all is lost. (2/2)
in reply to mcc

i agree, this is why i like a little type system in my forth : )
in reply to azul

I'd be very curious about that; are there any extant forths you have in mind that work this way?

I've talked to Ramsey Nasser who was trying to describe something about each word in a concatenative language being like a mapping from one stack state to another, and this means we can impose types on that stack transformation.

Questa voce è stata modificata (9 mesi fa)
in reply to mcc

for full static types, there is kitten: kittenlang.org/

and mirth (my project): github.com/mirth-lang/mirth

factor does do some stack depth checking but it doesn't have static type checking.

i don't know of anything more minimal & more forth-like, but then again type system is kind of a non-minimal addition and it always implies a redesign of the APIs because forth was not designed with type checking in mind.

in reply to azul

@typeswitch *thinks* there's a terminal emulator named kitty now. i could run kitten in kitty
@azul
in reply to mcc

@typeswitch also i think if i'm looking for a strongly typed forth i'm no longer looking for minimal. anyway thanks for the refs!
@azul
in reply to mcc

@typeswitch in a parallel direction, there's also postscript, which doesn't have types but is "safe" in the sense of having a GC and dynamically-typed objects, without being quite as extravagant as Factor
@azul
in reply to mcc

@typeswitch hmm, hadn't thought about that angle honestly. is even ghostscript IP-encumbered?
@azul
in reply to azul

@typeswitch i'd been hanging back as to not muddy the water, but i can recommend trying mirth. it's a far better experience than ieee1275 and maybe other forth like things.
@azul
in reply to mcc

Quit bad mouthing forth. It does exactly what you tell it to do. That just might not align with what you thought you were asking for or what you might have expected
in reply to mcc

Anyway here's my 45-line code for a harness that reads in lines of ASCII numbers and prints and dumps the stack after each.

github.com/mcclure/aoc2024/blo…

It's… awkward in places. It would have helped to have else-if, character literals for whitespace (like '\t' and '\r'), and a better story for complex boolean exps
(`DUP DUP DUP 9 = SWAP 13 = OR SWAP 32 = OR`. Ouch.) Parts feel nice and parts feel real bad.

I expect the ACTUAL PROGRAM will be a few lines long, and possibly only take mere minutes.

in reply to mcc

So functions in ANS forth, as far as I can tell, can't have locally-scoped variables…

…but there's no restrictions on what characters you can put in a variable name, so I can just store the variables in paths *cackles evilly*

in reply to mcc

Examples of valid comments in ANS Rust:

( You )
( You can (not) redo )
( You (can not) advance )

Examples of invalid comments in ANS Rust:

(You)
( You can ( not ) redo )
( You ( can not ) advance )

in reply to mcc

@onelson Now, there's one important thing to note here. Which is that although the builtin comment operator does not support balanced nested comment parenthesis. The builtin comment operator is actually just a function that throws away all its arguments. Which means, in principle, I could write my *own* implementation of the ( comment operator, a better one supporting nesting, and replace the default ( with it. Whether this is very cool or only makes things worse you will have to judge yourself.

mcc reshared this.

in reply to mcc

@onelson A corollary of my conclusion above— which I'm not completely sure about, but mostly sure about— is that if someone decided they just didn't *dig* comments, comments are slowing them down, I think they could simply FORGET the comment operator and then there would be no comment support in their program

mcc reshared this.

in reply to mcc

@onelson I don't think you can, because FORGET will forget everything after the definition you're forgetting as well. This may have... unintended consequences.

(The canonical data structure for the dictionary is a linked list; FORGET just rewrites the location of the head of the dictionary).

in reply to mcc

No, no, I'm sorry. I was fooled by my syntax highlighter. In testing with the actual pforth executable it appears literally all of the above examples are invalid uses of Forth comments except ( You ) .

( You can ( not ) nest comments. )

in reply to Owen Nelson

@onelson To summarize, in Forth, comments are any text between ( Parenthesis ) . However, there are two rules:

- There must be a space after the opening parenthesis, and a space before the closing parenthesis.
- Parenthesis may not be nested.

in reply to mcc

Bluh

github.com/mcclure/aoc2024/blo…

Well, it didn't take minutes. And it wasn't "a few" lines, it was 48, about the same length as the input code. But I will say once I was doing "forthy things" (pure computation) instead of stuff Forth's bad at (regular programming) it was way quicker, easier. It did occasionally feel like flying. Some of these lines have a real clarity to them.

It's now very important I don't try to do part 2 tonight. In fact, I shouldn't even read it, so I don't *reads it* dammit

Questa voce è stata modificata (9 mesi fa)
in reply to mcc

I have to get up SO early tomorrow, y'all
in reply to mcc

*Head in hands after unwisely reading part 2* Part 2 is basically one big chunk of Regular Programming. Hey uh. Does anyone know if there's a way in Forth to copy THE ENTIRE STACK somewhere and then recall it later? I can think of a way to *destructively* back up the stack (move it to the return stack temporarily) but *copying* the stack… I got nothing.
in reply to mcc

UGGGH no i think i can do this with DEPTH CELLS ALLOT ( forth.com/starting-forth/8-var… ) and then… and then some other nonsense. I think. Okay I absolutely have to stop thinking about this now. This may not have been the wisest of all possible uses of my Monday
in reply to mcc

U spel it rong. hyperboleandahalf.blogspot.com…
in reply to mcc

my suggestion with forth is always: consider linked lists as an option
in reply to clarity flowers

@clarity thanks. for reasons i will not explain, your suggestion instantly makes sense to me because i have written a lot of ML
in reply to mcc

So there's a keyword in Forth named CELLS and it's actually very useful, for a variable x it's like saying "x *= sizeof(void *);" which is something that would be *very* useful to have a shortcut in C but we don't have one, so in part 2 of my Forth program I'm finding myself writing lots of lines like
CELLS
CELLS
CELLS

and the thing I want to say is not completely coming together in my head but, I know I want to write a Forth program containing defined words WITHIN and INTERLINKED

in reply to mcc

What is this keyword good for? Only use I can think of is for pointer arithmetics, but there C does that implicitly.

I.e.

int * foo = &bar;
foo += 2;
// foo has now had 2 * sizeof(int) added to it.

Am I misunderstanding what this does?

in reply to mcc

The catch is, unlike Forth (or BCPL), C doesn't have a single 'cell' size.

For a while, people thought they would be able to get away with 16-bit cells. Then, larger computers came around.

For a while, people thought they would be able to get away with 32-bit cells. Then, larger computers came around.

For a while, people thought they would be able to get away with ...

in reply to Alaric Snell-Pym

@kitten_tech But if your Common Pointer and Common Integer have different sizes, there's no platform's cell size.

@mcc

in reply to Riley S. Faelan

@riley @kitten_tech Apparently in Forth these do not separate. pforth on my 64 bit system appears to be limited to a 32 bit heap.
in reply to mcc

@riley yep. FORTH assumes that pointers and ints are the same size, which was pretty fair until 64 bit systems became mainstream!
in reply to Riley S. Faelan

@riley @kitten_tech it seems like we are describing to you the way Forth works and you are responding by providing arguments as to why the way Forth works is a bad idea. But this does not help as the way Forth works is the way Forth works.

I assume if the Forth standard fundamentally doesn't work on an architecture, the implementor simply violates the standard. Certainly every Forth implementation I've used so far violates the standard.

in reply to mcc

@riley @kitten_tech … actually, as a correction to the above, it appears CELLS on my copy of pforth is multiplying by 8, so either a cell is actually 64-bit, or integers are limited to 32 bits but they're allocating 64 bits per 32 bit integer so they can store pointers if they want, or the documentation lies. It is hard to tell!
in reply to mcc

No, I'm explaining why the abstraction of 'cells' doesn't make sense in a C-like language.

(But BCPL, the Dawn C, did have it. Its cell was whatever the word of its target machine was.)

@kitten_tech

in reply to Riley S. Faelan

@riley @kitten_tech Oh, I see! Then you are correct. However, I would still appreciate a shorthand for "size of pointer in bytes", as I find myself typing *sizeof(void*) with frustrating frequency.

Oblomov reshared this.

in reply to mcc

There have been a bunch of weird machines with weird and/or variable pointer sizes. (Such as i8086's far pointers and near pointers.)

If you don't care about them, you might want to either define a macro such as PTR_SIZE of your own, possibly as sizeof(intptr_t). (Which is not the size of an integer pointer, but the size of an integer that is big enough to also fit a full pointer.)

@kitten_tech

in reply to Riley S. Faelan

Although, there's, perhaps, some philosophical difficulty in what a 'full pointer' means in a system that doesn't, like i8086, shorten pointers, but extends them, with, say, a memory bank index.

@kitten_tech

in reply to mcc

Okay!

github.com/mcclure/aoc2024/blo…

That was rewarding in ways I did not expect and also deeply painful in ways I did not expect, ending with a not-that-long but nonetheless grueling debugging session at the end when I felt very emotionally Done, but had One Last Bug (the bug: "DUP 1+" should have been "1+ DUP", an error that would have been easy to catch with… variable names).

Final ratios

App code — 53%
<=> — 4%
Clone and restore stack — 28%
Load numbers from stdin — 15%

47% coulda been stdlib.

in reply to mcc

Final Forth observations:

1. Something that a lot of people kept telling me when I was having problems/segfaults with Forth is I should think of Forth "like a macro assembler". Well, that's clearly not true, as doing this in assembly would have taken a fraction of the time. You know why? BECAUSE ASSEMBLY HAS REGISTERS. I did find myself wondering what Forth with registers would feel like; I strongly suspected *that* language, whatever it is, I'd enjoy more than Forth.

in reply to mcc

I think forth with registers is forth with liberal usage of cells.
in reply to Paul Khuong

@pkhuong OK but surely variable cells are kept in RAM? They have addresses. So I do not get the benefit of registers which I otherwise would have got in assembly (that I do not have to touch RAM)
in reply to mcc

I hope to make time to work on a small low level language with some guarantees that globals aren't randomly overwritten by stray pointers.
in reply to mcc

Now *also*, an observation at least two people without any prompting ( one @TomF ) made was that on 6502, there actually *are* no registers, except for the ones that are required to run the Forth runtime itself, and so Forth is unusually aptly fit for this particular processor. Okay. Okay, fine, you've convinced me. If I ever write a piece of software for the 1983 Nintendo Entertainment System, I'll consider doing it in Forth.
in reply to mcc

I tried Forth on the Sinclair Spectrum in 1983, but it was seriously slow and clunky
I can't recall encountering anything ever being written in Forth

@TomF

in reply to mcc

2. It's pretty clear much of the pain I experienced here was a result of my initial decision to use ANS Forth. I did get something like six recommendations for better Forths/concatenative languages over the course of the thread, and I'm curious about all of them. I'm tempted to peruse them all as part of the AOC project. The last two weeks went well enough I'm seriously considering change my rules from "do 25 puzzles in 25 different programming languages" to "…in 25 languages I've never used".
in reply to mcc

Alternately, because what's the point of this if I'm not amusing myself, I could intentionally arrange things so I do puzzles 1-24 in languages I've never¹ used and then write the 25th puzzle solution in Rust, like dunking a basketball.

¹ Incidentally, I am counting AppleSoft BASIC in this list despite my extensive use of the language when I was 6-7, because at that time I didn't know enough of the language for it to be turing-complete, meaning it was arguably not a programming language.

EOM

in reply to mcc

Usually day 25 is a bit easier than 24. Obviously people don't agree on difficulty but that may be worth considering.
in reply to Roger BW 😷

@RogerBW Thanks, yeah, I noticed this when I did AOC in 2022. But that just makes it all the funnier that this would be the day I do in my currently strongest language.
in reply to mcc

thanks I found this interesting and brought up memories. How exciting Forth was in its day. But that was compared with languages that were awful and machines with tiny memory. So a system that reduced down to something so simple made so much sense. I loved it until I tried it and then realised it could never be used for anything useful. I came to this conclusion right before it became the entire basis of desktop publishing, typography, and enterprise computing
in reply to mcc

Note: I have now been informed about this extension which reeeally woulda helped, and is designed in a way it can nicely register spill forth-standard.org/standard/lo…
in reply to mcc

By the way I am taking this week off from Babel of Code but! There's actually a second contestant, @unjello , doing the challenge at the same time/pace. Here are his threads:

Week 1: Microsoft Macro Assembler (1981 - 1991) mastodon.gamedev.place/@unjell…

Week 2: WATCOM C++ (1988 - present) mastodon.gamedev.place/@unjell…

in reply to mcc

@TomF I'm kind of confused by this? The 6502 definitely has registers, and while it doesn't have many you can also use the "zero page" as kind of a very large pseudo-register file.

At any rate I think you'd still be happier writing a game in assembly on the 6502. Writing a game in forth sounds like hell.

in reply to Meg

Per my understanding, the basic operation of the Forth interpreter requires the accumulator to do math, a register to store the stack pointer, and a register to store the return stack pointer. So per my understanding of the 6502 registers, that consumes the accumulator, the stack pointer, and index register A… leaving B… except also Forth cells are supposed to be 16-bit, meaning we're not only using both index pointers to store a 16-bit pointer but we're in fact register-starved.
Questa voce è stata modificata (9 mesi fa)
in reply to mcc

@megmac @TomF I was attempting to phrase the above post not as "the 6502 does not have registers" but "the forth interpreter/compiler uses all registers on the 6502, and therefore there are none left for arbitrary use by the programmer."
in reply to mcc

@megmac @TomF 6502 is definitely register starved, but the counter to that is the view that zero-page is effectively 256 registers. I was writing my 6502 Forth based on a book that used Z80 as its reference. Many of the things that were trivial for the Z80 there required a completely different approach on the 6502, and I wound up using a lot of zero-page to make it workable.
in reply to Howard Chu @ Symas

@hyc @megmac @TomF I feel like either these replies wildly misunderstand my post or my post was very unclearly written. The thing that would change Forth about "adding registers" is that registers are non-addressable and often faster. The zero page is addressable so I assume you can access it with @ and ! and no Forth extensions are needed, and if it is "as fast as" a register, then this seems like it bolsters my earlier supposition that the 6502 is unusually nice to use with Forth.
in reply to mcc

@hyc @megmac I get what you're saying, and I think I agree.

The other way to say it is that the 6502 is not unduly crippled by programming it in Forth versus assembly or C.

Whereas e.g. on the Z80, a simple Forth implementation doesn't use half the registers, so the temptation is to try to do a clever compile to map the top few items in the stack to those registers, which gets very ugly. Thus, the perf penalty of Forth-vs-asm is higher on these CPUs.

in reply to mcc

@hyc @megmac @TomF I think the distinction I would make is that in 6502 asm you can do ex:
lda x_pos
add x_vel
sta x_pos

Which while it technically only uses one register, gives you a bunch of named locations that you can use like registers even if they are just global variables. My experience with globals in forth is that they are really confusing to use correctly.

in reply to mcc

@TomF you're right. Removing registers and local variables from a language is stupid. But maybe less stupid if the language will never be directly programmed by a human
in reply to mcc

I wonder if you could do that destructively, save it to disk and then continue later. You could hibernate or checkpoint slow processes 🤔🤔
in reply to mcc

This sounds remarkably like my experience learning PostScript. I ultimately did AoC 2022 entirely in PostScript. I'm still not entirely sure why.
in reply to mcc

Your devotion to AoC-ing with defunct old languages is a bit of a inspiration.

I’ve thought about doing similar before, but obviously never followed through. 🤔

in reply to slembcke

my goal was just to do *a lot of* languages and i'm putting the old, defunct ones first because i know this year the early AOC days are the easy ones and i don't want to have to do a HARD one in an overly primitive language. but it's going well enough I'm *considering* changing the challenge from "different language each time" to "different language i've never tried each time". i've now got like six post-Forth stack languages suggested to me and i wanna try at least one or two
Questa voce è stata modificata (9 mesi fa)
in reply to mcc

@slembcke I'm curious what you might say about Ada 2022 (or 2012). For extra credit, GNAT supports SPARK 2014 mode, a subset of Ada 2012 for high-integrity software that lets you use "GNATprove" to statically verify your contracts and bounds.

en.wikipedia.org/wiki/SPARK_(p…

The version of GNAT built by distros doesn't have all the features, but there's a community version with a cargo-like package manager.

adacore.com/community

AdaCore also supports an IDE, written in Ada, called GNAT Studio.

in reply to jhamby

@jhamby @slembcke Ada is on my list! I am a little confused about whether there is a difference between Ada and Spark. It seems like Ada:Spark as JavaScript:TypeScript? Except that Ada was already typed so Spark makes it Double Typed
in reply to mcc

The exact "syntax" of that Forth comment construct is that the first "( " - a left paren followed by a space - starts the comment and the first right paren ends it.

So "(You" does not start a comment. "( You can ( not )" starts with the "( " and ends with the ") after "not ". The Forth parser is quite primitive and there are some undefined cases. MOAR FOOTGUNS.

in reply to Lawful Regime Change Now! 🇺🇦

@AlgoCompSynth But then why does ( you (can) not ) terminate at the (can) rather than the lone ). I would have expected it to be scanning entire symbols rather than characters.
in reply to mcc

I haven't read the rest of the thread yet, but from a friend who insisted on writing a forth interpreter in pdp11 and telling me all details all the time, I understood that that is why forth programs are typically written bottom-up in small pieces. Do you miss a notation for a character value? Define one! Else If? Define one! Etc etc...
in reply to mcc

that's accurate, that's why most people add some level of introspection and type checking to their forths to tame that chaos 😀
Questa voce è stata modificata (9 mesi fa)
in reply to Seitan Lu Linvegan

It's not exactly the case that I regret my decision to try doing one program in pure ANS Forth to see what it's like… but if I do Forth again it will DEFINITELY not be the ANS Forth generation D:
Questa voce è stata modificata (9 mesi fa)
in reply to mcc

I think if you find a way to get comfy in that, you can weather anything at all after that haha. Well done btw : ) It takes courage to leap into a whole new programming paradigm like you did.
in reply to Seitan Lu Linvegan

@neauoire I've been, over the course of the day, recommended Retroforth, Factor, and "Uiua". The most recs seemed to be for Factor. If I were looking to try out "Forth, but not broken" what would you suggest I look at?
in reply to mcc

@neauoire (I understand your answer might be "uxn"… that would be a legitimate answer)
in reply to mcc

Try retro, it's really quite nice. It's as if forth and ruby had a baby, the docs are well written, there's lots of examples out there. I find it's easier to wrangle than gforth and the likes(esp when dealing with files, argh), it's a bit more modern, the runtime is minuscule. You can read Starting Forth, and follow along with most basic examples with Retro.

Factor is not .. unbroken. But it's an altogether different thing, it's functional programming, so it's more like lisp, and it's really kind of a mess(docs are broken, IDE will randomly close, lots of the examples don't work with the latest version), I tried it a few times, it wasn't for me. Although, its arity checker is really useful when learning about RPN programming for the first time.

Uiua is very interesting but not a forth, if you're interested in going down that route, I'd go for BQN first, then go back to Uiua.

Uxn is not going to help you here, it's a little bit like forth but everything will feel like absolute sheer pain coming from algols, I'd stick to the bigger languages, for learning at least.

Questa voce è stata modificata (9 mesi fa)
in reply to mcc

This is exactly the thing that makes me look at Forth and go "Oh, that's clever, I will never touch this in my life".
in reply to mcc

you didn't even need CHAR, just 'A' to put that on the stack.
in reply to mcc

... I think Forth might not be a very good programming language.
in reply to Dan Cassidy 🦌

@whimsy So it appears one of the problems here is during the period all the forth interpreters are being written, nobody could afford a copy of the language spec, and so literally it appears there has never been an interpreter written conformantly to the specification?
in reply to mcc

this sounds like most programming languages before about 2010 to be fair
in reply to mcc

Sadly the only good reason to use Forth is if you're writing a compiler for it - because it's incredibly simple to do that. I like it for that reason.

Actually trying to get things done in it - I would rate that as significantly worse than just writing raw assembly.

Oblomov reshared this.

in reply to mcc

there should be an Advent of Code but where every day you have to use a new language to read structured data.
in reply to Ted Mielczarek

@tedmielczarek i mean every advent of code problem is effectively this. i created myself the rule where i can run a script to reformat input data as code literals, but code literals in forth would be backward, so what does that accomplish
in reply to mcc

Hmm. Forth treats the input as space-separated words. They are looked up in the dictionary and if not found, they get pushed onto the stack. Maybe just use that to push the input onto the stack and then process that? You'd be using the built-in parsing by treating the input as Forth code.
in reply to mcc

oh I missed that this is your AoC. Would have suggested starting with PostScript. There at least multiple engineering teams had to agree how it would work. Except that they're printer and Adobe engineers...
in reply to mcc

And what language would you use to write your own FORTH engine? Why, PostScript, of course...
in reply to mcc

I spend way too much time thinking about building forths. Building forths and thinking about building forths is, I think, the primary attraction of Forth 😉.
in reply to mcc

Greenspun's 10th Law:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Of course, for some people Forth is an alternative.

en.wikipedia.org/wiki/Greenspu…

Questa voce è stata modificata (9 mesi fa)
in reply to mcc

I wrote one long ago for the Sharp MZ80K because I was using Forth at work and the only other option was Basic.
There are at least two clues here as to how long ago that was!
in reply to mcc

Have you met BASIL, my Boolean Algebra / Signed Integer Language?
in reply to mcc

It's not stupid. It's advanced! youtu.be/inR02pEesCQ?si=_iSHRO…
in reply to mcc

Huh, weird:

$ pforth
PForth V21
pForth loading dictionary from file /usr/lib/pforth/pforth.dic
File format version is 8
Name space size = 120000
Code space size = 300000
Entry Point = 0
Little Endian Dictionary
Begin AUTO.INIT ------
CHAR A DUP . EMIT
65 A ok
Stack<10>

in reply to Brian Campbell

Oh, and your changed version does not:

CHAR 'A' DUP . EMIT
39 ' ok
Stack<10>

in reply to Brian Campbell

@unlambda *sigh* this is about compile context vs inteprpreted context it turns out.

CHAR A EMIT CR A
ok
Stack<10>
: abcd CHAR A EMIT CR ; A ? - unrecognized word!
Stack<10>
THROW code = -13
Undefined word!

Why would that be a difference!!!

mcc reshared this.

in reply to mcc

Oh, wow:

: foo CHAR A DUP . EMIT ;
FOO already defined.
A ? - unrecognized word!
: abcd CHAR A DUP . EMIT ;
A ? - unrecognized word!
: ABCD CHAR 'A' DUP . EMIT ;
'A' ? - unrecognized word!
: ABCD [CHAR] A DUP . EMIT ;
ok
Stack<10>
ABCD
65 A ok
Stack<10>

I don't understand why, but you need to wrap CHAR in square brackets. Found here: forth.com/starting-forth/1-for…

in reply to Brian Campbell

@unlambda WHAT

also although it accepts CHAR 'A' it does NOT accept CHAR '\t'

in reply to Brian Campbell

Oh, starting to come up with a mental model that might explain this: Forth is interpreting tokens as you see them; pushing values to the stack, popping them from the stack when a command consumes them and pushes results to the stack.

But special keywords like CHAR instead do something different; they put the parser in a different mode, that consumes later symbols. So for example, : puts it in a mode that consumes later symbols to define a new word.

But in compilation mode, these special symbols don't work. The compiler would understand the value 65, but it doesn't run the CHAR command to consume a next value; it wants to compile a value that's already there.

The square brackets then say "no, actually I want you to execute this special command before compiling, don't try to compile it".

I'm learning this along with you, so I'm forming the mental model as we go and might be wrong, but I feel like that might be what's going on.

in reply to Brian Campbell

@unlambda I can't replicate what you're seeing. "CHAR 0" is allowed and prints the number 0. "CHAR '0'" gives me the ascii for 0.
in reply to mcc

That documentation was written some time between Amiga days and a port of the whole HMSL infrastructure to Java. IIRC it's not in the repo (github.com/PhilBurk/pforth).
in reply to mcc

Hold up, what?

I was reading along and thinking I too was cut from a similar clothe from the folks who were doing asm coding on 8bit CPUs back when I was doing Forth stuff in the 1980s.

But I am head scratching now: why do you need a modem so you can hack your N64?

What kind of N64 hacking are you planning to do that wouldn't be better facilitated by something like a Krikzz flashcart (since it's the 21st century) or if going more retro with something like a Dr. V64 (whoa CD-R drive!) or Bung Dr. V64Jr. (whoa up to 512MBits of RAM depending on the model and way too many AA batteries that still benefit from having a power supply plugged in too!)? There was that other Mr. Backup Z64 with different Endian choices too.

I mean, maybe there was an N64 modem too (was there? I don't remember anymore) but generally an EPP/ECP parallel port was more than sufficient for tools contemporaneous with N64 "scene" stuff.

in reply to ティージェーグレェ

@teajaygrey

1. cturt.github.io/shogihax.html

2. I am going to be getting the Analogue 3D analogue.co/3d . This is not a perfect reproduction of the N64, so first off I do not know yet which flashcarts will be compatible, so I can't currently get one; and second off I am VERY CURIOUS whether the modem exploit works (i.e.: i want to use the modem exploit to test if the Analogue 3D is "bug compatible")

in reply to mcc

Whoa!

TIL: "Morita Shogi 64, the only official N64 game to include a modem built-into the cartridge to support its unique online-play functionality"

(Now I am wondering, was there any "unofficial" N64 hardware with modems built into the cartridges? Similar to how there was the official SEGA Ethernet module for the Dreamcast, but there were also unofficial Dreamcast Ethernet hardware [which typically could only be used with specific things like NetBSD because they used different chip sets than the official SEGA one IIRC]).

Let us know how #2 goes! The Analogue stuff is kind of interesting to me, sort of; but mostly only their PCエンジン stuff and lucky me, I still have a SuperGrafx, a TurboExpress, a Core GrafxII and some sundry other NEC originals for such things and don't need to worry about bug compatible FPGA reproductions.

For some reason my mind is now gravitating towards making the comparison that Analogue is sort of like the Behringer for video game consoles. I used to have a very low opinion of Behringer, but given what after market prices for original synthesizers are these days and that they're producing contemporary clones of things like the LinnDrum, maybe more recent clones aren't so bad? (They were certainly pretty bad back in the day when such hardware was being contemporaneously produced and sold though).

in reply to mcc

that orange screen 👌
Questa voce è stata modificata (9 mesi fa)
in reply to mcc

skimming through the code:

partial TRUE !

is writing to the memory address TRUE, it should be TRUE partial !

also the conditionals seem wrong, e.g. this isn't doing what you think:
DUP DUP DUP 9 <> 13 <> 20 <> AND AND

in reply to mcc

you have `partial TRUE !` and `TRUE partial !`, I forget which, but one of those is wrong (I think the latter is correct?). This is your invalid memory access (you're trying to set the data stored at 0x01)
Questa voce è stata modificata (9 mesi fa)
in reply to clarity flowers

@clarity TRUE is -1 btw, so you were actually trying to set the data at address 0xFFFFFFFFFFFFFFFF i think
in reply to mcc

Yeah, "Forth" covers a huge variety of languages. The early versions were absolutely abysmal. Programs were on separate pages - a page is literally 80x25 characters. So if you wanted to jump somewhere, it had to start on a certain page, and you supplied the page number. Absolutely WTF time.
in reply to mcc

to learn #forth I can highly recommend "Starting Forth" (forth.com/starting-forth/) by Leo Brodie.
in reply to mcc

I'm guessing (I haven't tried it) that `CHAR n` will take *any* character that's written after the CHAR, other than space (or possibly newline) and give you the ASCII code for it.

That is, CHAR parses the next word for itself and works on that. (Much like `"` and `(` do).

Just a guess, though.

in reply to mcc

BL gives you the character code for a space. I thought that CR did the same for end-of-line, but that prints one.
in reply to Hugo "Dark Satanic" Mills

@darkling So there's just no way to represent a space, '\t', '\r' ,or '\n' in RUST code other than to type the decimal ASCII values?
in reply to mcc

honestly tho this is my favorite part of forth. You have to wrap your head around building your own ad-hoc compiler as you go along, perfectly tailored to the needs of the specific program.
in reply to mcc

Yes, Forth has even less inherent global syntax than Lisp.
This can be very good or very bad!
Tokenizing is very very simple. Space Tab Newline can't be part of a word, so a word is whatever jumble is between whitespace.
Contrary to every instinct formed by all prior experience,
special characters interspersed in a string of letters or numbers is not an expression to be further handled by the tokenizer, is a single word.

Which for an embedded bootstrap is fine.

in reply to mcc

Same goes for strings.
." This is a string."
."This is not a string"
Questa voce è stata modificata (9 mesi fa)
in reply to mcc

You did zero research about how forth works, don't seem to have read any forth texts and you are slagging off the language? Wow, so mindful.
in reply to mcc

(strictly, gforth is not in testing because it fails to build from source (bugs.debian.org/1067376), but there's a patch ready since 2024-03-31, so in many ways it /is/ because it's unmaintained)
in reply to наб

((okay, apparently the gforth maintainer has requested an adopter bugs.debian.org/1039051, so if you use gforth you may want to adopt it 😀))
Questa voce è stata modificata (9 mesi fa)
in reply to наб

@nabijaczleweli I don't think I'd contribute to a forth but if I did I probably wouldn't pick a GPL one.
in reply to mcc

(reading Retroforth docs) oh, this is *nice*. might try playing with this next instead of Self.
in reply to mcc

for a very modern variant of forth, also having features of Common Lisp, have a look at factor (factorcode.org/).
in reply to mcc

oh Forth, that was a mind-changing *experience*. Connect via serial and write code directly inside the machine, bypassing compilers&fancy IDEs. This is how I got first money, as someone left an exposed RS-232 on a 4-color printing line I used it to bypass the vendor lock making business owner happy.
Unknown parent

mastodon - Collegamento all'originale
mcc
@limot "We are predating the concept of files containing ASCII text", a statement which I feel confident making because some of the docs I'm referring are making specific reference to disk sectors
in reply to mcc

@limot oh no, this is an intentional design decision, Forth systems like to work in terms of “blocks” because most of them are designed assuming you do not have a file system. Even much more modern ones. Most Forth seems to want to be the entire computer?
Unknown parent

mastodon - Collegamento all'originale
mcc
@limot I have heard of computers, yes, but was using casual speech in my post above. This said, "and always was in all files containing text" is rather an exaggeration, I have heard the mournful cries of the pour souls who had to support EBCDIC
Unknown parent

mastodon - Collegamento all'originale
mcc
@limot Apparently it's bad and was never fully documented outside IBM
Unknown parent

mastodon - Collegamento all'originale
mcc
@dysfun Well, my guess is it exits the program with an error code.
Unknown parent

mastodon - Collegamento all'originale
mcc

@AlgoCompSynth Given the specific problem, I have trouble imagining what the thing I'd file is 🙁

I got gforth, it's in ubuntu

Unknown parent

mastodon - Collegamento all'originale
mcc

@multisn8 I don't know what modifies the stack or doesn't. BECAUSE THE DOCUMENTATION LIES TO ME.

However, you would expect print statements to modify the stack because they consume their own arguments.

Unknown parent

mastodon - Collegamento all'originale
mcc
@AlgoCompSynth What mechanism is it using to scan? Is it a mechanism available to end-user code?
in reply to mcc

Probably not. The whole "core" word set is very poorly factored. There have been some efforts by the standards committee to "make it make sense" but it doesn't. You just have to remember what happens.

If you want to read the standard, it's here: forth-standard.org/standard/wo…. But TBH you're better off working though "Starting Forth" and then reading the standard.

in reply to Lawful Regime Change Now! 🇺🇦

@AlgoCompSynth Okay. As it happens I have read both of those documents today (starting forth and the standard), each about halfway through, and there are still major questions i have about some of the material covered by one or both documents >_>
Unknown parent

mastodon - Collegamento all'originale
mcc
@unjello it appears if you use RetroForth (or maybe ColorForth or Factor) it will be a lot less painful and a lot more apt for Regular Programming Things.
in reply to mcc

Starting Forth is much better written, but it describes a typical threaded code implementation, not the supposedly more abstract language the standard attempts to specify. The standards process has been going on since 1979, when things were pretty much low-level machine-code implementations. It's a thankless job, trying to turn Forth into an abstract computer science object.

uxn makes more sense; so does 6502 assembly language.

Unknown parent

mastodon - Collegamento all'originale
mcc
@AlgoCompSynth Integer divide is asking a lot on some of the platforms I use!!
in reply to Lawful Regime Change Now! 🇺🇦

The sweet spot for Forth is 16-bit minicomputers with hardware integer multiply and divide. More powerful machines perform acceptably in Python or Ruby, and less powerful machines will run Forth, but slowly.
in reply to mcc

Yeah, the RP2040 has a co-processor for it. Not bad for a $4US board.
Unknown parent

mastodon - Collegamento all'originale
mcc
@scrottie hm but I could already move the stack aside by pop-pushing it onto the return stack, the hard thing is copying. Anyway thanks
Unknown parent

mastodon - Collegamento all'originale
mcc
@dysfun the problem is there's more than one reason you want registers and one is performance. Forth variables are per my read all global and therefore an implementation would struggle to promote them to registers. There is an extension I was not aware of when I made that above post called locals which does not have this issue.