bearophile wrote: > More little tasks for your module: > http://rosettacode.org/wiki/Fractal_tree#Python
This one's use of recursion caused me to hit what I think is a compiler bug. Not in the recursion itself, but in a struct's copy constructor when it had a significant mixin. I worked around it by declaring a private struct and using a pointer to it rather than mixing in the implementation directly. I believe this will be a net-positive too, since ScreenPainter is now referenced counted. Here's the implementation: ==== import simpledisplay; import std.math; void main() { // auto image = new Image(600, 600); auto window = new SimpleWindow(600, 600, "Fractal Tree"); void drawTree(ScreenPainter p, in int x1, in int y1, in real angle, in int depth) { if(depth == 0) return; immutable x2 = x1 + cast(int) (cos(angle) * depth * 10); immutable y2 = y1 + cast(int) (sin(angle) * depth * 10); p.drawLine(Point(x1, y1), Point(x2, y2)); drawTree(p, x2, y2, angle - 0.35, depth - 1); drawTree(p, x2, y2, angle + 0.35, depth - 1); } drawTree(window.draw, 300, 550, -PI / 2, 9); window.eventLoop(0, (dchar) { window.close(); }); // displayImage(image); } === The reason Image is there, but commented out, is that such things might be better done as images, then displayed once finished. But, since we don't have drawing lines to images yet*, I went direct to screen instead. (well, I do have my implementation of Bresenham's algorithm, but I want to see Mathias' code before falling back on mine. Mine worked well for DOS, but better anti-aliasing is expected nowadays.) DrawTree takes an existing ScreenPainter so I can limit it's scope to only where it's used. The new reference counting under the hood means that while the struct is copied several times here, it isn't wasteful. The eventLoop inline delegate allows you to close the window by pressing any key as well as using the button in the corner. I don't think the Python version on rosetta code would allow this. Comparing to the Python version, mine is a little shorter, primarily due to the much simpler initialization. The Python one took three lines to do what SimpleWindow's constructor does in one. I also put the "get_surface" kind of thing that allows drawing inline to the drawTree line. Like I said above, this was for reasons of scope, but it coincidentally shaves a line too. As does the struct destructor doing the job of display.flip(). The last place where I save a couple lines is the event loop, doing all that in one place instead of a separate function, loop, and fetcher. (Note: the delegate in there is not strictly necessary! It handles quit events sanely by default.) All in all, I'm very happy with this approach so far. It's simple, it's short, it's readable, it's reasonably efficient, and the implementation is moderately lean. Everything I was hoping for!