Today, I decided to learn the basics of Forth so, I decided to make a π approximation in Forth!
How it Works
So, I know that Forth is not the most readable language there is, so I decided to give an overview on how this program works.
The Makefile
So, first, the makefile of this simply runs gforth to execute main.fth. I had to use a polygott repl since the normal Forth repl implementation does not support floating point numbers.
Main.fth
Now, for the actual code...
Variable Assignments
The first 3 lines simply define variables. Specifically, the variables p, s, and cntr. In this case, p is the variable used for pi, s is the sign of the specific iteration (this uses the Nilakantha Series), and cntr is a counter used in the Nilakantha Series.
Then, I simply define the original values for these variables. However, this all needs to be done in the floating point stack instead of the integer stack. If you were doing it in the integer stack, you'd do something like
3.0 p !
However, this does not work for a floating point. The 3.0 will just be rounded to 3 which is the same thing, but won't work for solving pi. For a floating point, you need to use
3.0e p f!
For floating points in Forth, you need to use e after every number and f before every operator, including variable assignment operators such as ! and variable reading operators such as @ and even the printing operator ..
Iteration Function
Now, starting in line 7 is our function for each iteration of the Nilakantha Series. First, I begin the function definition with : iter and add a new line for organization. Then, on line 8 is our main iteration code, but we'll get back to that.
On line 9, we multiply the variable s by -1. (I am going with line 9 before line 8 due to the complexity of line 8) However, Forth is stack-oriented, not object-oriented like most well-known languages such as Python, JavaScript, and C++. So, first, we read the variable s with s [email protected] and add it to the stack. Then, we use -1e to add -1 to the floating point stack. Then, we multiply them with f+ and replace both items in the stack with the product (to keep them in, the dup or over commands would be needed, but we won't get into those.). Then, we use s f! to assign the variable s to the product already in the stack to complete this simple operation.
Line 10 is much the same, but uses the cntr variable and adds 2 to it. Now, for line 8. To make this easier to read, I'm going to put this in a list...
Line 8 Steps 1. Add 4 to stack 2. Add the value of cntr to stack 3. Add 3 to stack 4. Add the last two items in the stack and replace those items with the sum (you always replace used items with the result in Forth operations) 5. Add the value of cntr to stack 6. Multiply last two items of stack 7. Add 2 to stack 8. Add last two items of stack 9. Add the value of cntr to stack 10. Multiply last two items of stack 11. Divide last two items of stack (divides 4 by the value from step 10) 12. Add value of s to stack 13. Multiply last two items of stack (applies sign of iteration to the result) 14. Add value of p to stack 15. Add last two items of stack (adds iteration value to pi) 16. Set p to last (and only) number in stack
Finally, on line 11, we add a semicolon to end the function definition.
Loop (l) Function
First, we define our function with : l and add a space to keep everything on the same line. Then, we start our for loop.
In Forth, a for loop of
10 0 do iter loop
is the same as
for(let i = 0; i < 10; i++) {
iter()
}
in JavaScript (replace "let" with "int" for the typed C-family languages) or
for i in range(0, 10):
iter()
in Python. In this for loop, we start at 0 and go to 100000, running the iter function each time.
Now that we have our for loop, we close the function definition with a semicolon.
Execution Code
Now, we have the code to execute our functions beginning on line 13 with its powerful one-letter command: l. This calls the function we just defined with the for loop to run everything.
Display Code
Now, on line 14, we display our result. First, we have a text display of ." pi = " which simply displays "pi = " and then, we display the value of p with p [email protected] f.. Finally, we close it off with a new line (or carriage return) with cr and everything is displayed, leaving our function complete.
Credits
This is inspired by @LizFoster 's many π approximation repls and a conversation between her and @Warhawk947 where @Warhawk947 recommended that @LizFoster create a pi approximation in every language and I joined the conversation and said "Imagine pi in LOLCODE or Emoticon or some other esolang..." and @Warhawk947 said not to even think about it, so I then created a LOLCODE pi approximation and then thought, why not do a pi approximation in Forth as well, although not an esolang?
@StudentFires Also, with the THAIL notes, the multiline comments don't even need to be multiple types. Once Adapt received some updates, we can just make it work as parentheses.
π in Forth
Today, I decided to learn the basics of Forth so, I decided to make a π approximation in Forth!
How it Works
So, I know that Forth is not the most readable language there is, so I decided to give an overview on how this program works.
The Makefile
So, first, the makefile of this simply runs
gforth
to execute main.fth. I had to use a polygott repl since the normal Forth repl implementation does not support floating point numbers.Main.fth
Now, for the actual code...
Variable Assignments
The first 3 lines simply define variables. Specifically, the variables
p
,s
, andcntr
. In this case,p
is the variable used for pi,s
is the sign of the specific iteration (this uses the Nilakantha Series), andcntr
is a counter used in the Nilakantha Series.Then, I simply define the original values for these variables. However, this all needs to be done in the floating point stack instead of the integer stack. If you were doing it in the integer stack, you'd do something like
However, this does not work for a floating point. The 3.0 will just be rounded to 3 which is the same thing, but won't work for solving pi. For a floating point, you need to use
For floating points in Forth, you need to use
e
after every number andf
before every operator, including variable assignment operators such as!
and variable reading operators such as@
and even the printing operator.
.Iteration Function
Now, starting in line 7 is our function for each iteration of the Nilakantha Series. First, I begin the function definition with
: iter
and add a new line for organization. Then, on line 8 is our main iteration code, but we'll get back to that.On line 9, we multiply the variable
s
by -1. (I am going with line 9 before line 8 due to the complexity of line 8) However, Forth is stack-oriented, not object-oriented like most well-known languages such as Python, JavaScript, and C++. So, first, we read the variables
withs [email protected]
and add it to the stack. Then, we use-1e
to add -1 to the floating point stack. Then, we multiply them withf+
and replace both items in the stack with the product (to keep them in, thedup
orover
commands would be needed, but we won't get into those.). Then, we uses f!
to assign the variables
to the product already in the stack to complete this simple operation.Line 10 is much the same, but uses the
cntr
variable and adds 2 to it. Now, for line 8. To make this easier to read, I'm going to put this in a list...Line 8 Steps
1. Add 4 to stack
2. Add the value of
cntr
to stack3. Add 3 to stack
4. Add the last two items in the stack and replace those items with the sum (you always replace used items with the result in Forth operations)
5. Add the value of
cntr
to stack6. Multiply last two items of stack
7. Add 2 to stack
8. Add last two items of stack
9. Add the value of
cntr
to stack10. Multiply last two items of stack
11. Divide last two items of stack (divides 4 by the value from step 10)
12. Add value of
s
to stack13. Multiply last two items of stack (applies sign of iteration to the result)
14. Add value of
p
to stack15. Add last two items of stack (adds iteration value to pi)
16. Set
p
to last (and only) number in stackFinally, on line 11, we add a semicolon to end the function definition.
Loop (
l
) FunctionFirst, we define our function with
: l
and add a space to keep everything on the same line. Then, we start our for loop.In Forth, a for loop of
is the same as
in JavaScript (replace "let" with "int" for the typed C-family languages) or
in Python. In this for loop, we start at 0 and go to 100000, running the iter function each time.
Now that we have our for loop, we close the function definition with a semicolon.
Execution Code
Now, we have the code to execute our functions beginning on line 13 with its powerful one-letter command:
l
. This calls the function we just defined with the for loop to run everything.Display Code
Now, on line 14, we display our result. First, we have a text display of
." pi = "
which simply displays "pi = " and then, we display the value ofp
withp [email protected] f.
. Finally, we close it off with a new line (or carriage return) withcr
and everything is displayed, leaving our function complete.Credits
This is inspired by @LizFoster 's many π approximation repls and a conversation between her and @Warhawk947 where @Warhawk947 recommended that @LizFoster create a pi approximation in every language and I joined the conversation and said "Imagine pi in LOLCODE or Emoticon or some other esolang..." and @Warhawk947 said not to even think about it, so I then created a LOLCODE pi approximation and then thought, why not do a pi approximation in Forth as well, although not an esolang?
@StudentFires Also, with the THAIL notes, the multiline comments don't even need to be multiple types. Once Adapt received some updates, we can just make it work as parentheses.