Basics of Forth
Forth is a tiny programming language which can run interactively even on the smallest, cheapest, low-power microcontrollers. It is a REPL (Read–eval–print loop) system, which means it gives you a prompt where you type your commands in and it gets executed as soon as you press the ENTER key. If you want to learn Forth you will have to get used to its cryptic syntax and the consequences of the stack-handling to be able to use this programming language most efficiently. I was looking for some simple programming tasks and found this:
“Write a function which checks whether a number is even.”
My solution
lambda import
: 2MOD 2 mod ;
: IS_EVEN?
0=
[: cr ." yes, it is even! " ;]
[: cr ." nope, it is odd! " ;] qifelse
;
: TEST 2MOD IS_EVEN? ;
Lets go trough it line-by-line:
lambda import
We will use the qifelse
word which is available in the lambda package, so lets import it before we use it.
: 2MOD 2 mod ;
-
starts a new word 2MOD is a name of our new word 2 we store this integer on the stack, we will use this to modulo the number the user typed in. ; closes our new word
This word takes a number and divides it by 2. We know every even number can be divided by 2 without a remainder. So our word returns 0 if the number is even.
Then our next word:
: IS_EVEN?
0=
[: cr ." yes, it is even! " ;]
[: cr ." nope, it is odd! " ;] qifelse
;
: starts a word IS_EVEN? is the name of our new word 0= compares if a number is equal to zero [: cr .” yes, it is even! “ ;] if the previous check is TRUE, then write the given text in a new line [: cr .” nope, it is odd! “ ;] qifelse or write it is not. The qifelse handles the IF/ELSE pair. ; closes our new word
- Then our main word:
-
TEST 2MOD IS_EVEN? ;
-
starts a new word TEST the name of the new word 2MOD and IS_EVEN? call the previously defined words
Test
- lambda import ok
- 2MOD 2 mod ; ok
- IS_EVEN? ok 0= ok [: cr .” yes, it is even! “ ;] ok [: cr .” nope, it is odd! “ ;] qifelse ok ; ok
- TEST 2MOD IS_EVEN? ; ok ok 1 TEST nope, it is odd! ok 2 TEST yes, it is even! ok 14444444 TEST yes, it is even! ok 2134346457434223 TEST nope, it is odd! ok
Or let’s look at this one:
( Exercise 001 )
( Write a program which will find all such numbers which are divisible by )
( 7 but are not a multiple of 5, between 2000 and 3200 [both included]. )
( The numbers obtained should be printed in a comma-separated )
( sequence on a single line. )
: in_range 3201 2000 ;
: divisible? ( n z -- n true/false )
over ( n z -- n z n )
swap ( n z n -- n n z )
mod ( n n z -- n remainder of n/z )
0 = if ( divisible, because the remainder is 0 )
true ( n remainder of n/z -- n true )
else ( non divisible)
false ( n remainder of n/z -- n false )
then
;
: comma 44 emit 32 emit ;
: test
cr
in_range do
i
7 divisible?
false = if
drop
else
5 divisible?
true = if
drop
else
. comma
then
then
loop ;
This second one should be easy to read.