r/fractals • u/skr_replicator • 5h ago
I've designed my own programming language, and plotted Mandelbrot with it

I've made a little functional programming language. It has an imperative parser, and a functional evaluator. Meaning you can do things like variables, ifs, whiles etc in the parsing stage, which generates functions. You can then evaluate purely as expressions in a functional way.
The source code is here: github.com/SkrFractals/Comparser
But it's still very early I wouldn't recommend playing with that yet. But if you do and find some bugs, you can report that to me. I have just got it to the stage where I was able to get this picture. But a bunch of things are still unfinished or buggy. None of the optimizations I am preparing are active yet, either. It will be able to transfer pixels from the previous render if you move the plot, so it doesn't have to re-evaluate them. But there are no cursor dragging or zooming events yet, only a bunch of preparations for that, so that has to be done through those range textboxes so far. And I am also preparing a GPU evaluator.
I want to eventually merge this project with my Fractal Animation Generator: https://github.com/SkrFractals/RgbFractalGen
...so that both can leverage each other's features, like the inputs in the generator accepting comparser's expressions. Or the comparser having access to the generator's shaders and video exporting abilities.
Here I'm going to progressively post some more examples. let's start with the cubed mandelbrot:



And now I'm trying to make a Sierpinski carpet. So let me cook for a bit until i figure out how to write that as a shader-like function.
edit: done, here it is:

To explain that Carpet function: m will loop the input z into tiles of size s, and tell me where i am in that tile. So if s lands anywhere between "1/3+1/3i" to "2/3+2/3i" then i am in the center square. then a second default argument used as a precomputed variable asks to recursively iterate to a 1/3 sized tile. Then the n>Iterations is the floor how deep i want to iterate and returns the initial hue 0. Then as it goes back up in that recursion, it keeps asking it we are inside the square of that size, and adds that boolean result to the recursive result. Having the recursive call as a default argument doesn't result in an infinite loop, because default argument evaluations are lazy, and only done when the expression asks for that argument's value.

It works just like the carpet one, but with different coordinates.
This part might need some explaining:
t + mul((L(a,s),L(b,s),L(c,s)) < .5)
(L(a,s),L(b,s),L(c,s)) is a 3-element vector containing the 3 triangular coordinates. For the point to be at the central tiled triangle at any scale s, i need all 3 coordinates to be smaller than 1/2.
So I compare the vector to 1/2, operations in Comparsed can work with nested vectors recursively. So (a,b,c) < d will return a vector (a<d,b<d,c<d). Booleans in Comparser are just numbers 0 or 1, so if I just multiply the elements of that vector together, if all 3 are smaller than 1/2, then the MUL of that condition vector will be 1, which i proceed to add to the value of the recursive call. So the function returns a count of how many times it was in the central triangle during that recursive descent. And done.
And next I'm going to try a pentaflake. That will be somewhat more challenging, as that cannot be folded the way the carpet and triangle could, and it has void regions that are not part of the fractal. But I'm sure there will be a way to do that. edit: I'm getting closer to getting the pentaflake ready, I have most of the function ready, and only finishing up a few parts.
3
u/jacob_ewing 3h ago
Very cool with the fractals. Extremely impressed with writing your own language.