Which LISP should I learn? Years ago I read about Scheme and wrote some hello world level code. I learned about lambda functions and currying. I also looked at racket. A few years ago, much of my day job involved the JVM and I was getting sick of Java so I got a book on Clojure, which is a very nice language, but I never wrote any.
A few days ago I downloaded and built the latest version of DrRacket.
Should I go straight to Haskell? Or what about other functional languages? Is Erlang worth a look?
I need something stimulating to distract my brain from the mundane nature of everyday life, and mediocre programming languages.
(Score: 2) by DannyB on Tuesday November 30 2021, @03:28PM
Write your own Mandelbrot explorer program. The first step is to simply generate the Mandelbrot set on a complex plane from +/-2.0 real axis and +/-2.0 imaginary axis. Then work on user interface to use the mouse to select a rectangular area and then pick a menu command to Zoom In causing the selected area to expand to fill the area previously occupied by the original graphic. It's not that you're solving a new problem. It's the fun and stretching your ability. Try to do something new and original.
Here is what I've worked on, put on hold, and hope to pick up on again. A Mandelbrot explorer in Java. You never have to set any iteration limit. Calculating the pixels to display any part of the Mandelbrot set is what is called an "embarrassingly parallel" problem. So do it multi threaded. Divide and conquer. Split the rectangle into two smaller rectangles, and keep recursing. Once you get down to a rectangle that is, say, 7x7 or smaller in either dimension, then brute force calculate each pixel in that small area. But . . . gigantic optimization . . . on every rectangle during the recursion, no matter the size of rectangle, do a quick check of the border to see if all pixels on the border of that rectangle are all the same "color" (or iteration count). If they are, then simply block fill that entire rectangle with that iteration count (eg, color). The observation about the Mandelbrot set is that there are large blocks of uniform color and also large areas of "fiddly bits" with chaotic colors.
Use separate cpu threads to brute calculate every 7x7 grid. (Or adjust the 7x7 threshold to achieve best cpu utilization.)
Do all your calculations as integers. BigIntegers. You have a variable that you call ONE, and set it to, say ten billion. In your calculations, simply tread that big integer ONE as the value 1.0. So if ONE is 10_000_000_000, then your axis is from +/-20_000_000_000. There is a method to my madness of using integers instead of some kind of gigantic floating point.
Make your program also offer a web server. Any arbitrary browser can connect to this port on your computer while the program is running. It displays a page that has JavaScript. The computer running a browser connected to your program is contributing its compute power. This makes it extremely easy to set up and tear down quick ad-hoc networks of several computers. JavaScript also has Big Integers (or packages for such). Thus you still get EXACT same results in a different language. When you program needs to calculate all of the "fiddly bits" of some rectangle, it farms that out to another cpu thread, or a connected slave computer connected via a browser contributing its cpu. Don't farm out 7x7 (or smaller) rectangles to a separate computer. Maybe not even to a thread. Farm out, say 100x100 (or smaller) rectangles to a separate computer. Measurement and tuning will achieve optimal results.
A next step would be to develop a program that runs as a background service (on Linux, Windows, etc) and can contribute its cpu, and is locally controlled by a separate user interface program to configure it. (Or an XML or JSON config file if you don't want to build a UI.)
Back in the 1990's I built a very fun Macintosh (classic) Mandelbrot explorer in C++. I had a couple friends looking over my shoulder on Sunday afternoons and we would then go out to eat lunch and discuss all sorts of various ideas which I would then implement. But we never got as far as multi threading let alone using multiple computers. But that 1990s project fired my imagination.
Oh, I mentioned that the user doesn't have to set an iteration limit, which I consider a major failing of most Mandelbrot explorer programs. How to do that? In your inner calculation loop, take all of the local variables and make them members of an object. Now that object preserves the entire state of where in the "loop" that calculation is. Have a large matrix of these objects, one object per pixel. Now calculate about 100 iterations on every pixel. Then do another 100 iterations on every pixel. You are doing the same calculation, but you're "advancing" each pixel a little bit, all of the pixels advancing together. Some pixels will "escape" and are now done. Others will iterate to infinity. For the entire imagine (not just the local rectangle you are calculating) keep track of some statistics of what the maximum iterations are for pixels that have been completed. Use a threshold of several times that as your "dwell limit". Now the dwell limit will be dynamic. As some "fiddly bits" take more and more iterations to complete, the dynamic "dwell limit" will increase. Thus the end user never has to manually guess what the maximum iterations should be before a pixel is considered to iterate to infinity.
In Java (or JavaScript, or C#, Python, etc) where GC is involved: always pre-allocate all data structures. Then do your calculations. In your inner loop you never allocate anything, thus no GC happens. Note how well this idea fits with having a large matrix of "saved inner loop variables" so you can advance all the pixels in a rectangle together in marching steps in small numbers of iterations per step.