discussion icon indicating copy to clipboard operation
discussion copied to clipboard

Forth beginner - anyone here?

Open qubit999 opened this issue 7 months ago • 16 comments

I stumbled upon Forth last year around this time because someone told me to look into it. Unfortunately, I didn't look into it until today.

I hope it's okay if I ask a few questions here. I usually program Python, sometimes Rust and lately C/C++ (mainly Arduino SDK with PlatformIO extension, but I also tried Pico SDK) using microcontrollers like the RP2350 or ATmega328P. I am familiar with the concept of object-oriented programming languages.

But I would like to dive into Forth programming language. After reading 10-15 minutes about it I understood some basic concepts about the language and I started to read some Forth code on Wikipedia and even though this concept was new to me, I started to realize that this language might fit my "thinking".

As a beginner in Forth, what should I focus on? What should I learn? What are best practices? Until now I always used C++ libraries to read sensors or steer devices connected via i2c, spi or one-wire since those libraries are available out-of-the-box by the manufacturer/3rd-party (I usually read the code examples and know what to do with it). I think creating Forth hardware libraries is essential for me to learn. I don't know this concept, any advice what I should look into?

I would like to start with this: https://github.com/tabemann/zeptoforth/tree/master (because I have a few RP2350 and several modules)

Separate: Also, which compiler should I use for macOS? Gforth?

Thank you so much in advance.

qubit999 avatar May 22 '25 13:05 qubit999

Welcome. If you are looking for some more reading material ...

All are available as PDFs. There are some others too, but theses are popular.

Hans Bezemer has a nice YouTube series Back & Forth that covers assorted Forth topics. I'm sure there others here might have additional suggestions.

I've not used GForth, though it is very popular version for a hosted Forth. I have of course my own implementation of a hosted Forth, Post4. Both should compile on MacOS with a stock C compiler. There are many others some for embedding or assorted CPUs. Else where on ForthHub you should find lists for many other implementations.

There is also the comp.lang.forth usenet (?) news group that is still very active.

Hope that helps get you going.

Anthony Howe

SirWumpus avatar May 22 '25 14:05 SirWumpus

Since you seem interested in embedded world, I can recommend the Mecrisp implementations. I think it was originally for TI processors, but there is a "Stellaris" variant for STM32 (others?), which I have been using. It is fast, written in assembler, and it compiles Forth to machine code and can place compiled code in RAM or FLASH.

Binaries are available for many of the STM32 variants, so you don't have to go through the effort to configure a particular variant.

HTH Niclas

On 2025-05-22 15:37, Alexander Slatina wrote:

qubit999 created an issue (ForthHub/discussion#196) [1]

I stumbled upon Forth last year around this time because someone told me to look into it. Unfortunately, I didn't look into it until today.

I hope it's okay if I can ask a few questions here. I usually program Python, sometimes Rust and lately C/C++ (mainly Arduino SDK with PlatformIO extension, but I also tried Pico SDK) using microcontrollers like the RP2350 or ATmega328P. I am familiar with the concept of object-oriented programming languages.

But I would like to dive into Forth programming language. After reading 10-15 minutes about it I understood some basic concepts about the language and I started to read some Forth code on Wikipedia and even though this concept was new to me, I started to realize that this language might fit my "thinking".

As a beginner in Forth, what should I focus on? What should I learn? What are best practices? Until now I always used C++ libraries to read sensors or steer devices connected via i2c, spi or one-wire since those libraries are available out-of-the-box by the manufacturer/3rd-party (I usually read the code examples and know what to do with it). I think creating Forth hardware libraries is essential for me to learn. I don't know this concept, any advice what I should look into?

I would like to start with this: https://github.com/tabemann/zeptoforth/tree/master (because I have a few RP2350 and several modules)

Also, which compiler should I use for macOS? Gforth?

Thank you so much in advance.

-- Reply to this email directly, view it on GitHub [1], or unsubscribe [2]. You are receiving this because you are subscribed to this thread.Message ID: @.***>

Links:

[1] https://github.com/ForthHub/discussion/issues/196 [2] https://github.com/notifications/unsubscribe-auth/AAA2BRM6TJHOWE7KRIZN3LL27XHLDAVCNFSM6AAAAAB5WDFBVCVHI2DSMVQWIX3LMV43ASLTON2WKOZTGA4DGNBRG4ZDCMQ

niclash avatar May 22 '25 14:05 niclash

Thank you. I am amazed by Forth. 👍🏻

This is my first code for testing hello.f:

include functions.f

variable result

5 10 CALC_SUM_PLUS_5_5
5 INCR RESULT
22 INCR CHECK_LARGER_THAN_20
22 WHILE_LOOP_TEST result !
result @ . ." Result from while loop" CR

This is functions.f:

variable x
5 x !
5 constant first

: <> = 0= ;

: RESULT { n1 -- } 
 ." Result: " n1 . CR 
;
: CALC_SUM_PLUS_5_5 { n1 n2 -- }
  n1 n2 + x @ + first + RESULT
;
: INCR { n1 -- }
  n1 1 + 
;
: CHECK_LARGER_THAN_20 { n1 -- }
  n1 20 >
  IF
    n1 . ." Larger than 20" CR
  ELSE
    n1 . ." Not larger than 20" CR
  THEN
;
variable counter
: WHILE_LOOP_TEST { n1 -- n2 }
  n1 counter !
    ." Starting while loop with: " counter @ . CR
  BEGIN
    counter @ 1 <>
  WHILE
    counter @ . CR
    counter @ 1 - counter !
  REPEAT
  ." Done" CR
  counter @ 
;

I never coded like this before but it's super cool.

qubit999 avatar May 22 '25 15:05 qubit999

Your naming conventions are exemplary for sharing code. Off to a good start, and YES Forth is your own languge and you make it fun for you to think in~!

Perhaps start looking at dictionairies to name / hide device peripheral base code, and share if you would.

cwpjr avatar May 22 '25 22:05 cwpjr

I'm a bit disappointed that GForth can't compile to a native binary format, so that I can ship software. Is there an alternative for macOS? I tried VFXForth which is capable of compiling but I always get a specific error indicating that a file is missing. In detail I get this error: SAVE hello Can't open stubosx64 -> SAVE hello.mo

I tried placing the stubosx64 directly into the path of the hello.fth program, I tried setting up my $PATH variable on macOS, I tried to symlink the stub into the bin folder of VFXForth. The forum is not active, I believe but I posted in the VFXForth forum, I will see if I get a response.

Now, I am trying 8th but this is not the original Forth "syntax".

EDIT: I figured out that VFXForth is not compatible with my architecture (arm64).

qubit999 avatar May 23 '25 16:05 qubit999

I'm a bit disappointed that GForth can't compile to a native binary format, so that I can ship software. Is there an alternative for macOS? I tried VFXForth which is capable of compiling but I always get a specific error indicating that a file is missing. In detail I get this error: SAVE hello Can't open stubosx64 -> SAVE hello.mo

Now, I am trying 8th but this is not the original Forth "syntax".

EDIT: I figured out that VFXForth is not compatible with my architecture (arm64).


Forth has been traditionally like LISP in that you save an image of the system to make a final program.

GForth can save an image of the entire system with "savesystem" Example is here: https://github.com/gnu-mirror-unofficial/gforth/blob/master/savesys.fs https://gforth.org/manual/Non_002dRelocatable-Image-Files.html#index-savesystem--_0022name_0022-_002d_002d--gforth Maybe that will get you over the hump?

Yes MPE is a small company and to port all their years of work from Intel to Arm is a big task. I have read that it is a project but status is unknown to me.

When people want to make a standalone program with Forth they would typically write and test in the Forth environment where everything is interactive and then use a cross-compiler to make a smaller program that excludes all the stuff that they don't need like the interpreter/compiler, dictionary etc.

Where does the cross-compiler come from. Many times people write their own. But fortunately Gforth has one. (I have never used it so caveat emptor) And... cross-compiler Forth must use special words to control the process so it is not "Forth" per se, but a domain specific language to do cross-compiling of Forth syntax. So a small learning curve is required.

https://gforth.org/manual/Using-the-Cross-Compiler.html

You are hitting the reason why so many people have written their own Forth compilers. It was how the language began. Chuck wanted a tool that was open-ended so he built one and then extended it. Your interest tells me that you will probably give that try some day. :-)

bfox9900 avatar May 23 '25 18:05 bfox9900

Forth has been traditionally like LISP in that you save an image of the system to make a final program. GForth can save an image of the entire system with "savesystem" Example is here: https://github.com/gnu-mirror-unofficial/gforth/blob/master/savesys.fs https://gforth.org/manual/Non_002dRelocatable-Image-Files.html#index-savesystem--_0022name_0022-_002d_002d--gforth Maybe that will get you over the hump?

This is not exactly what I was looking for but it's important to know. As far as I understood it's non-portable and it's more for like saving a machine state. Generating an image would be more closer to my goal but would still require GForth being installed on the computer for deployment, and this is not what I want at the moment.

Yes MPE is a small company and to port all their years of work from Intel to Arm is a big task. I have read that it is a project but status is unknown to me.

I've noticed that :) somewhere on the website they say that. The reason why I wanted to use VFXForth is because Apple was/is a customer. It's written on the website landing page.

When people want to make a standalone program with Forth they would typically write and test in the Forth environment >where everything is interactive and then use a cross-compiler to make a smaller program that excludes all the stuff that they >don't need like the interpreter/compiler, dictionary etc.

If it's comparable with CMake, I think I can handle it. I will read about it in a moment.

You are hitting the reason why so many people have written their own Forth compilers. It was how the language began. Chuck >wanted a tool that was open-ended so he built one and then extended it. Your interest tells me that you will probably give that try some day. :-)

Most likely, yes. I want to get deeper into hardware programming. But before I do so, I want to compile (as in really compile) my first Forth program on my Mac. :)

EDIT: Is it possible to cross-compile using GForth or any other software, from macOS system to macOS? So that I get an executable that can be shipped? I'm asking because I just read a little bit about it and now I'm not sure.

qubit999 avatar May 23 '25 20:05 qubit999

I love your enthusiasm.

You may have already got to this realization, but you are using local variables where none are required. That DATA stack is where Forth does simple operations. Why? Because it is more efficient than locals when you write in the Forth style of using many smallish functions.

For example Forth has an "incrementer" called 1+. It's typically 1 instruction on a CPU. It takes one argument on the data stack and returns an argument. So this would be better and just using 1+ of course would be even better.

: INCR  ( n -- n')  1+ ;  

Consider these versions of your functions without locals. They are almost the same and we don't need the counter variable.

VARIABLE x
5 CONSTANT first

first x !     \   :-)

: <> = 0= ;

: RESULT ( n1 -- )  ." Result: "  .  CR  ;
: CALC_SUM_PLUS_5_5 ( n1 n2 -- )
   + x @ + first + RESULT
;

: INCR ( n -- n')  1+  ;

: CHECK_LARGER_THAN_20 ( n1 -- )
  DUP 20 >
  IF
    .  ." Larger than 20" CR
  ELSE
    .  ." Not larger than 20" CR
  THEN
;

\ variable counter

: WHILE_LOOP_TEST ( n1 -- n2 )
    ." Starting while loop with: " DUP . CR
  BEGIN
     DUP 1 <>
  WHILE
     DUP . CR
     1-
  REPEAT
   ." Done" CR
;

bfox9900 avatar May 24 '25 02:05 bfox9900

EDIT: Is it possible to cross-compile using GForth or any other software, from macOS system to macOS? So that I get an executable that can be shipped? I'm asking because I just read a little bit about it and now I'm not sure.

You may want to take a look at Forth Inc. and there product line. I am a hobbyist theses days and have not kept up with their offerings, but they have always had a line of cross-compilers as well. When they first built for Intel Mac, they outsourced some of the code to a genius who lives on a island in the Atlantic if I heard it correctly. Apparently Apple is pretty hostile to language writers who don't use their dev sys. (still Xcode?) and Forth is written mostly in Forth...

Except when it isn't.

May be you should go the route of compiling a simple Forth in C using Xcode and writing your program in that Forth. PForth is making some noise.
https://github.com/philburk/pforth

There are many others on Github.

And you mentioned 8th. Aaron wrote that after decades using his own Forth and he wanted built-in features people come to expect including multi-OS compilation. Yes the Syntax is not ANS Forth but it is a VERY capable system.

bfox9900 avatar May 24 '25 02:05 bfox9900

Hi :) The reason why I wrote this so needlessly extensive was because I was trying out different concepts to see how it gets interpreted because I wasn't exactly sure about scopes for example, creating variables, how word parameters are working, etc.

I tried SwiftForth already but I get this message when trying to run SF:

Image

I will try to compile pforth now :)

qubit999 avatar May 24 '25 02:05 qubit999

From looking around to find a solution for you, I think I am seeing the Forth community is not a big enough crew to get things going on Apple silicon. :-(

There are embedded cross compilers for ARM but not for Mac O/S on M1 etc. Looks like you will have to lead the way.

Very sad because in the past MacForth was the first third party language and dev sys that was ready for Mac if I remember right.

bfox9900 avatar May 24 '25 03:05 bfox9900

I have a version written in C that you might find interesting. I don't have a Mac, but it is simple enough that it should port to Mac easily. As for creating an executable, you could embed your Forth code into the "sys-load.cpp" file and change the name to whatever you want. You can also easily provide access to other functionality by adding new primitives.

https://github.com/CCurl/c4

There is also a version for Arduino. It has more built into it so that it has more functionality out of the box.

https://github.com/CCurl/c4a

Full disclosure: they are NOT "ansi-standard"; they are inspired by ColorForth and Tachyon.

CCurl avatar May 24 '25 14:05 CCurl

@qubit999 wrote:

Is it possible to cross-compile using GForth or any other software, from macOS system to macOS? So that I get an executable that can be shipped? I'm asking because I just read a little bit about it and now I'm not sure.

MinForth provides Forth-to-C transpiler (used to build MinForth itself). In theory, it should be possible to use it to build a turnkey — a stripped executable of a Forth program, which contains only the necessary parts of the Forth system runtime.

ruv avatar May 24 '25 17:05 ruv

You can check out aMops. It supports Apple Silicon, at least.

pahihu

pahihu avatar May 24 '25 21:05 pahihu

Yes, MACFORTH was used by myself and Marc Cantor for his early prototypes for Macro Mind products, on the original Mac

On Fri, May 23, 2025 at 10:07 PM theBF @.***> wrote:

bfox9900 left a comment (ForthHub/discussion#196) https://github.com/ForthHub/discussion/issues/196#issuecomment-2906335407

From looking around to find a solution for you, I think I am seeing the Forth community is not a big enough crew to get things going on Apple silicon. :-(

There are embedded cross compilers for ARM but not for Mac O/S on M1 etc. Looks like you will have to lead the way.

Very sad because in the past MacForth was the first third party language and dev sys that was ready for Mac if I remember right.

— Reply to this email directly, view it on GitHub https://github.com/ForthHub/discussion/issues/196#issuecomment-2906335407, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABILVRJSBQMQ2WN2EIYORGD277O7PAVCNFSM6AAAAAB5WDFBVCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDSMBWGMZTKNBQG4 . You are receiving this because you commented.Message ID: @.***>

cwpjr avatar May 24 '25 21:05 cwpjr

Thanks to everyone!

I think I have a small surprise.

I rewrote some small parts of the MinForth-to-C transpiler mentioned by @ruv to support macOS (arm64 architecture). With the original transpiler I got errors on my Mac when I tried to compile the transpiled output.

I tested transpiling with my own minf2c and it gives me a .c file that I can compile to an executable standalone application.

The transpiler is now called "minf2c.c", the original file is "mf2c.c".

https://github.com/qubit999/MinForth2C

I will edit this post in a moment to share it.

Image

Executing the binary:

Image

qubit999 avatar May 25 '25 03:05 qubit999