<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Oct 28, 2019, at 1:51 AM, nop head <<a href="mailto:nop.head@gmail.com" class="">nop.head@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Instead of <div class=""><br class=""><div class="">module bar() {<br class="">        union : {<br class="">                foo.union();<br class="">                _cylinder(d = 5, h = 10);<br class="">        }<br class="">        diff : {<br class="">                foo.diff();<br class="">        }<br class="">}<br class=""></div><div class=""><br class=""></div><div class="">Why don't you simply define two modules foo_union() and foo_diff()? </div></div><div class=""><br class=""></div><div class="">In conventional programming it is bonkers to have combine two completely different bits of code in one function and pass a global variable to decide which one is executed.</div><div class=""><br class=""></div><div class="">In my case I would have foo(type), foo_holes(type) where type is a list with all the parameters and I have accessor functions such as foo_width(type).</div><div class=""><br class=""></div><div class="">If there is common positioning between foo() and foo_holes() then I would have foo_hole_positions(type) that positions children().</div></div></div></blockquote><div><br class=""></div><div>I take your point, and the distributed functionality of the modules you recommend is something I have tried and eventually abandoned… I think I just found the proliferation of modules a little unsatisfying.</div><div><br class=""></div><div>I think my current direction is shaped by my experience with object oriented programming… indeed, in OpenSCAD I’m primarily creating actual objects :)</div><div><br class=""></div><div>So to my way of thinking, and I’d be the first to concede that I may not have the experience to really warrant an opinion, some adoption of object oriented philosophy would improve the OpenSCAD programming experience even if its not an object oriented language.</div><div><br class=""></div><div>So while in a conventional imperative language it may be insane to combine two bits of code whose execution is selected by a passed parameter, what I’m trying to do is get at least some feel for a more oo like environment even though the language doesn’t support it, and my proposal to do that is part of that goal, and that’s the reason for my proposal of extended dot notation… the ability to call the ‘methods’ of OpenSCAD objects seems natural to me.</div><div><br class=""></div><div>The second part of the proposal whether it’s accomplished with labels or ‘reserved’ methods is just my attempt to suggest something that might feel something like the constructor/destructor functions of an oo object. With ‘real’ objects like in OpenSCAD I liken the union method to a constructor and the difference/intersection functionality to a destructor and my proposal was aimed at incorporating the benefits of that kind of structure to an OpenSCAD program.</div><div><br class=""></div><div>Anyway, thanks for you feedback, it's helping me to develop a better understanding of what I’m wishing for, even if that desire is unrealistic, impractical or unachievable.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 28 Oct 2019 at 04:25, Hugo Jackson <<a href="mailto:hugo@apres.net" class="">hugo@apres.net</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br class="">
<br class="">
> On Oct 27, 2019, at 5:13 PM, Torsten Paul <<a href="mailto:Torsten.Paul@gmx.de" target="_blank" class="">Torsten.Paul@gmx.de</a>> wrote:<br class="">
> <br class="">
> First note that the function literals are now<br class="">
> implemented, so the snapshot version of OpenSCAD<br class="">
> has functions as first class values which means<br class="">
> support for higher order functions.<br class="">
> (<a href="https://github.com/openscad/openscad/pull/3077" rel="noreferrer" target="_blank" class="">https://github.com/openscad/openscad/pull/3077</a>)<br class="">
> <br class="">
> I hope to find some time to collect notes and post<br class="">
> an article about it. Meanwhile the minimalist docu<br class="">
> can be found at<br class="">
> <a href="https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules#Function_Literals" rel="noreferrer" target="_blank" class="">https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules#Function_Literals</a><br class="">
> <br class="">
> On 28.10.19 00:09, Hugo Jackson wrote:<br class="">
>> To start, I would propose an extension of the "dot"<br class="">
>> notation, that would allow one to refer to a value<br class="">
>> declaration and/or function or module component of<br class="">
>> another module with a dot.<br class="">
> <br class="">
> Yes, having access to a nested data structure is<br class="">
> definitely something that would help a lot. The<br class="">
> core changes to the parser implementation that are<br class="">
> required for this are now done and merged to the<br class="">
> development snapshot.<br class="">
> <br class="">
> But I don't think it will be possible to link to<br class="">
> the existing function and/or module definitions.<br class="">
> <br class="">
> Slightly modified example, just adding a parameter<br class="">
> to module foo():<br class="">
> <br class="">
> module foo(offset) {<br class="">
>       valueA = 7 + offset;<br class="">
> <br class="">
>       function myFunc(num) = valueA + num;<br class="">
> }<br class="">
> <br class="">
> module bar() {<br class="">
>       valueB = 8;<br class="">
> <br class="">
>       valueC = foo.valueA + foo.myFunc(valueB);<br class="">
> }<br class="">
> <br class="">
> foo(10);<br class="">
> translate([10, 10, 0]) foo(20);<br class="">
> <br class="">
> bar(); // <- now what is valueC ?<br class="">
> <br class="">
<br class="">
Good point… for my part I don’t usually code modules with parameters, but I appreciate that isn’t how the real world works. :)<br class="">
But I would think that calling any module part or function would require an enumeration of all needed values in the parameter arguments, e.g. for the example you<br class="">
provide the call for valueC in bar would need to be:<br class="">
<br class="">
valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or literally valueC = foo(7).valueA + foot(7).myFunc(valueB)<br class="">
<br class="">
Perhaps that would lead to a preponderance of code that would only serve to make code look more tortuous than it already does. Yet I think the<br class="">
proposed ‘dot’ syntax would lead to more insightful coding that would tend to mitigate the damage that might occur. <br class="">
<br class="">
> <br class="">
>> The second extension would be the election of three<br class="">
>> operations as 'reserved' functions, union, difference<br class="">
>> and intersection such that one could explicitly call<br class="">
>> that part of a module without calling the others:<br class="">
> <br class="">
> I'm not sure I understand how this will work. Why<br class="">
> select specifically those 3 special cases?<br class="">
> <br class="">
> Is that meant just as names or would that also mean<br class="">
> intersection() { bar(); foo(); } a bit like operator<br class="">
> overloading?<br class="">
> <br class="">
>> foo(); // would execute intersection(){difference(){union(){<union code>}<difference code>}<intersection code>}<br class="">
> <br class="">
> Where's the nesting coming from? From the order of<br class="">
> the definitions?<br class="">
> <br class="">
>> Please let me know… I didn’t want to bog this<br class="">
>> proposal down with details if it’s obvious, but in<br class="">
>> doing that I have taken the risk that the improvement<br class="">
>> And benefits of such extensions may not be evident.<br class="">
<br class="">
<br class="">
<br class="">
I often code modules using a special varialble I name $e and a skeleton module that looks like this:<br class="">
<br class="">
module foo($e = -1) {<br class="">
        module _union() {<br class="">
                // code that primarily builds the object<br class="">
        }<br class="">
<br class="">
        module _diff() {<br class="">
                // code that primarily subtracts geometry from _union()<br class="">
        }<br class="">
<br class="">
        difference() {<br class="">
                if($e == -1 || $e == 0)<br class="">
                        _union();<br class="">
                if($e == -1 || $e == 1)<br class="">
                        _diff();<br class="">
        }               <br class="">
}<br class="">
<br class="">
I then get to call foo and either get just the _union code or just the _diff code or have the object definition run completely when $e == -1<br class="">
<br class="">
With this approach, when I just want the foo object I simply write:<br class="">
<br class="">
foo();<br class="">
<br class="">
But if I want the foo object to be united with some other objects before any difference is applied I could do it like this:<br class="">
<br class="">
module bar() {<br class="">
        difference() {<br class="">
                union() {<br class="">
                        foo($e = 0);<br class="">
                        cylinder(d = 5, h = 10);<br class="">
                }<br class="">
                foo($e = 1);<br class="">
        }<br class="">
}<br class="">
<br class="">
I find that this kind of approach helps with the overall flow and data abstraction, but the addition of a special variable and the requirement for the difference(){union() {}} code to make it work detracts from what I feel is overall a more elegant approach, and I find it particularly helpful for code reuse.<br class="">
So that’s really what my suggestion for ’reserved’ functions is about.. following the logic that you would execute union functionality before difference because you need to have first constructed an object before you remove anything from it. Don’t almost all modules have the…<br class="">
<br class="">
difference() {<br class="">
        union() {<br class="">
                // add some stuff<br class="">
        }<br class="">
        // take some stuff away<br class="">
}<br class="">
<br class="">
construct in them?<br class="">
<br class="">
So that’s why I was thinking that a syntax that supported what I have at least found to be the most common code construction would make code more readable, so that I would just write:<br class="">
<br class="">
module foo() {<br class="">
<br class="">
        union : {<br class="">
                // code that primarily builds the object<br class="">
        }<br class="">
        diff : {<br class="">
                // code that primarily subtracts geometry from union()<br class="">
        }<br class="">
<br class="">
        // code that follows executes only if foo is called<br class="">
}<br class="">
<br class="">
Now when I want the foo object to be combined with other objects, I would just have to write:<br class="">
<br class="">
module bar() {<br class="">
        union : {<br class="">
                foo.union();<br class="">
                _cylinder(d = 5, h = 10);<br class="">
        }<br class="">
        diff : {<br class="">
                foo.diff();<br class="">
        }<br class="">
} <br class="">
<br class="">
Perhaps there may be a more elegant way of structuring things, but I was aiming at a syntax that while not backwards compatible, wouldn’t break anything that was already working.<br class="">
<br class="">
Thanks for the heads up on the availability of function literals… that should make life more fun and exciting. And thanks for the links to the discussion lists.<br class="">
<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
OpenSCAD mailing list<br class="">
<a href="mailto:Discuss@lists.openscad.org" target="_blank" class="">Discuss@lists.openscad.org</a><br class="">
<a href="http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org" rel="noreferrer" target="_blank" class="">http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org</a><br class="">
</blockquote></div>
_______________________________________________<br class="">OpenSCAD mailing list<br class=""><a href="mailto:Discuss@lists.openscad.org" class="">Discuss@lists.openscad.org</a><br class="">http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org<br class=""></div></blockquote></div><br class=""></body></html>