Console Mandelbrot in FORTH

The Mandelbrot Set printed out in a console with text.

I really like to play around with FORTH. It's a "weird" programming language compared to all the other ones I've learned over time. There are already many articles out there about why you should give it a try, the best probably being this one at Hackaday.

One little program that is often demonstrate on old computers is a BASIC program to compute the Mandelbrot Set in the console. I thought I'd try my hand in "converting" the program to FORTH.

Here's my version, taken from a gist I wrote earlier this year.

\ from proposal http://www.forth200x.org/fvalue.htmlvariable %var: to 1 %var ! ;: fvalue create f, does> %var @ if f! else f@ then 0 %var ! ;0e0 fvalue i30e0 fvalue r359 value x121 value y1-1e0 fvalue i1 1e0 fvalue i2-2e0 fvalue r11e0 fvalue r2r2 r1 f- x1 s>f f/ fvalue s1 \ L30i2 i1 f- y1 s>f f/ fvalue s2 \ L310e0 fvalue a0e0 fvalue b: single_iter { F: z1 F: z2 } ( F: z1 F: z2 -- F: z1' F: z2' F: mag )  z1 fdup f* to a \ L90  z2 fdup f* to b \ L91  a b f- r3  f+ \ z1 \ L111  2e0 z1 z2 f* f* i3 f+ \ z2 L110  a b f+ \ mag \ line 100;: print_char ( F: x F: y -- )  30 \ push the max in case we don't exit early  30 0 do                          \ L80    single_iter    4e0 f> if drop i leave then  loop                             \ L120  fdrop fdrop \ clean z1 and z2  62 swap - emit                   \ L130;: calc_i3 { y }  i1 s2 y s>f f* f+ to i3 \ L50;: calc_r3 { x }  r1 s1 x s>f f* f+ to r3 \ L70;: mandelcr \ always start on a fresh clean liney1 0 do                         \ L40  i calc_i3  x1 0 do                       \ L60    i calc_r3    r3 i3 print_char  loop                            \ L140  cr                              \ L150loop                              \ L160;mandel

That prints out something like the screenshot at the top of this post.

The "L##" comments roughly refer to the lines in the BASIC version, if you'd like to compare the two. I tried to keep the memory usage and general complexity as equal as possible - that's why there are so many value and fvalue variables. I've seen some examples that use the stack more but are harder to read and have to recompute a lot of things that the BASIC version doesn't.

Here's the original BASIC version:

10 x1=5911 y1=2120 i1=-1.021 i2=1.022 r1=-2.023 r2=1.030 s1=(r2-r1)/x131 s2=(i2-i1)/y140 for y=0  to y150 i3=i1+s2*y60 for x=0 to x170 r3=r1+s1*x71 z1=r372 z2=i380 for n=0 to 2990 a=z1*z191 b=z2*z2100 if a+b>4.0 goto 130110 z2=2*z1*z2+i3111 z1=a-b+r3120 next n130 print chr$(62-n);140 next x150 print160 next y170 end

I'm consistently intrigued by FORTH, so I'll probably be sharing more programs and thoughts. I wrote a short explanation of the "polyfill" in the first four lines of the FORTH version is actually a great dive into the language's extensibility.