HJ
Hugo Jackson
Mon, Oct 28, 2019 4:24 AM
To start, I would propose an extension of the "dot"
notation, that would allow one to refer to a value
declaration and/or function or module component of
another module with a dot.
Yes, having access to a nested data structure is
definitely something that would help a lot. The
core changes to the parser implementation that are
required for this are now done and merged to the
development snapshot.
But I don't think it will be possible to link to
the existing function and/or module definitions.
Slightly modified example, just adding a parameter
to module foo():
module foo(offset) {
valueA = 7 + offset;
function myFunc(num) = valueA + num;
}
module bar() {
valueB = 8;
valueC = foo.valueA + foo.myFunc(valueB);
}
foo(10);
translate([10, 10, 0]) foo(20);
bar(); // <- now what is valueC ?
Good point… for my part I don’t usually code modules with parameters, but I appreciate that isn’t how the real world works. :)
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
provide the call for valueC in bar would need to be:
valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
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
proposed ‘dot’ syntax would lead to more insightful coding that would tend to mitigate the damage that might occur.
The second extension would be the election of three
operations as 'reserved' functions, union, difference
and intersection such that one could explicitly call
that part of a module without calling the others:
I'm not sure I understand how this will work. Why
select specifically those 3 special cases?
Is that meant just as names or would that also mean
intersection() { bar(); foo(); } a bit like operator
overloading?
foo(); // would execute intersection(){difference(){union(){<union code>}<difference code>}<intersection code>}
Where's the nesting coming from? From the order of
the definitions?
Please let me know… I didn’t want to bog this
proposal down with details if it’s obvious, but in
doing that I have taken the risk that the improvement
And benefits of such extensions may not be evident.
I often code modules using a special varialble I name $e and a skeleton module that looks like this:
module foo($e = -1) {
module _union() {
// code that primarily builds the object
}
module _diff() {
// code that primarily subtracts geometry from _union()
}
difference() {
if($e == -1 || $e == 0)
_union();
if($e == -1 || $e == 1)
_diff();
}
}
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
With this approach, when I just want the foo object I simply write:
foo();
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:
module bar() {
difference() {
union() {
foo($e = 0);
cylinder(d = 5, h = 10);
}
foo($e = 1);
}
}
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.
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…
difference() {
union() {
// add some stuff
}
// take some stuff away
}
construct in them?
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:
module foo() {
union : {
// code that primarily builds the object
}
diff : {
// code that primarily subtracts geometry from union()
}
// code that follows executes only if foo is called
}
Now when I want the foo object to be combined with other objects, I would just have to write:
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
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.
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.
> On Oct 27, 2019, at 5:13 PM, Torsten Paul <Torsten.Paul@gmx.de> wrote:
>
> First note that the function literals are now
> implemented, so the snapshot version of OpenSCAD
> has functions as first class values which means
> support for higher order functions.
> (https://github.com/openscad/openscad/pull/3077)
>
> I hope to find some time to collect notes and post
> an article about it. Meanwhile the minimalist docu
> can be found at
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules#Function_Literals
>
> On 28.10.19 00:09, Hugo Jackson wrote:
>> To start, I would propose an extension of the "dot"
>> notation, that would allow one to refer to a value
>> declaration and/or function or module component of
>> another module with a dot.
>
> Yes, having access to a nested data structure is
> definitely something that would help a lot. The
> core changes to the parser implementation that are
> required for this are now done and merged to the
> development snapshot.
>
> But I don't think it will be possible to link to
> the existing function and/or module definitions.
>
> Slightly modified example, just adding a parameter
> to module foo():
>
> module foo(offset) {
> valueA = 7 + offset;
>
> function myFunc(num) = valueA + num;
> }
>
> module bar() {
> valueB = 8;
>
> valueC = foo.valueA + foo.myFunc(valueB);
> }
>
> foo(10);
> translate([10, 10, 0]) foo(20);
>
> bar(); // <- now what is valueC ?
>
Good point… for my part I don’t usually code modules with parameters, but I appreciate that isn’t how the real world works. :)
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
provide the call for valueC in bar would need to be:
valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
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
proposed ‘dot’ syntax would lead to more insightful coding that would tend to mitigate the damage that might occur.
>
>> The second extension would be the election of three
>> operations as 'reserved' functions, union, difference
>> and intersection such that one could explicitly call
>> that part of a module without calling the others:
>
> I'm not sure I understand how this will work. Why
> select specifically those 3 special cases?
>
> Is that meant just as names or would that also mean
> intersection() { bar(); foo(); } a bit like operator
> overloading?
>
>> foo(); // would execute intersection(){difference(){union(){<union code>}<difference code>}<intersection code>}
>
> Where's the nesting coming from? From the order of
> the definitions?
>
>> Please let me know… I didn’t want to bog this
>> proposal down with details if it’s obvious, but in
>> doing that I have taken the risk that the improvement
>> And benefits of such extensions may not be evident.
I often code modules using a special varialble I name $e and a skeleton module that looks like this:
module foo($e = -1) {
module _union() {
// code that primarily builds the object
}
module _diff() {
// code that primarily subtracts geometry from _union()
}
difference() {
if($e == -1 || $e == 0)
_union();
if($e == -1 || $e == 1)
_diff();
}
}
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
With this approach, when I just want the foo object I simply write:
foo();
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:
module bar() {
difference() {
union() {
foo($e = 0);
cylinder(d = 5, h = 10);
}
foo($e = 1);
}
}
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.
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…
difference() {
union() {
// add some stuff
}
// take some stuff away
}
construct in them?
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:
module foo() {
union : {
// code that primarily builds the object
}
diff : {
// code that primarily subtracts geometry from union()
}
// code that follows executes only if foo is called
}
Now when I want the foo object to be combined with other objects, I would just have to write:
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
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.
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.
NH
nop head
Mon, Oct 28, 2019 8:51 AM
Instead of
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
Why don't you simply define two modules foo_union() and foo_diff()?
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.
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).
If there is common positioning between foo() and foo_holes() then I would
have foo_hole_positions(type) that positions children().
On Mon, 28 Oct 2019 at 04:25, Hugo Jackson hugo@apres.net wrote:
On Oct 27, 2019, at 5:13 PM, Torsten Paul Torsten.Paul@gmx.de wrote:
First note that the function literals are now
implemented, so the snapshot version of OpenSCAD
has functions as first class values which means
support for higher order functions.
(https://github.com/openscad/openscad/pull/3077)
I hope to find some time to collect notes and post
an article about it. Meanwhile the minimalist docu
can be found at
On 28.10.19 00:09, Hugo Jackson wrote:
To start, I would propose an extension of the "dot"
notation, that would allow one to refer to a value
declaration and/or function or module component of
another module with a dot.
Yes, having access to a nested data structure is
definitely something that would help a lot. The
core changes to the parser implementation that are
required for this are now done and merged to the
development snapshot.
But I don't think it will be possible to link to
the existing function and/or module definitions.
Slightly modified example, just adding a parameter
to module foo():
module foo(offset) {
valueA = 7 + offset;
function myFunc(num) = valueA + num;
}
module bar() {
valueB = 8;
valueC = foo.valueA + foo.myFunc(valueB);
}
foo(10);
translate([10, 10, 0]) foo(20);
bar(); // <- now what is valueC ?
Good point… for my part I don’t usually code modules with parameters, but
I appreciate that isn’t how the real world works. :)
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
provide the call for valueC in bar would need to be:
valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or
literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
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
proposed ‘dot’ syntax would lead to more insightful coding that would tend
to mitigate the damage that might occur.
The second extension would be the election of three
operations as 'reserved' functions, union, difference
and intersection such that one could explicitly call
that part of a module without calling the others:
I'm not sure I understand how this will work. Why
select specifically those 3 special cases?
Is that meant just as names or would that also mean
intersection() { bar(); foo(); } a bit like operator
overloading?
foo(); // would execute intersection(){difference(){union(){<union
code>}<difference code>}<intersection code>}
Where's the nesting coming from? From the order of
the definitions?
Please let me know… I didn’t want to bog this
proposal down with details if it’s obvious, but in
doing that I have taken the risk that the improvement
And benefits of such extensions may not be evident.
I often code modules using a special varialble I name $e and a skeleton
module that looks like this:
module foo($e = -1) {
module _union() {
// code that primarily builds the object
}
module _diff() {
// code that primarily subtracts geometry from _union()
}
difference() {
if($e == -1 || $e == 0)
_union();
if($e == -1 || $e == 1)
_diff();
}
}
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
With this approach, when I just want the foo object I simply write:
foo();
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:
module bar() {
difference() {
union() {
foo($e = 0);
cylinder(d = 5, h = 10);
}
foo($e = 1);
}
}
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.
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…
difference() {
union() {
// add some stuff
}
// take some stuff away
}
construct in them?
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:
module foo() {
union : {
// code that primarily builds the object
}
diff : {
// code that primarily subtracts geometry from union()
}
// code that follows executes only if foo is called
}
Now when I want the foo object to be combined with other objects, I would
just have to write:
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
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.
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.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Instead of
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
Why don't you simply define two modules foo_union() and foo_diff()?
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.
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).
If there is common positioning between foo() and foo_holes() then I would
have foo_hole_positions(type) that positions children().
On Mon, 28 Oct 2019 at 04:25, Hugo Jackson <hugo@apres.net> wrote:
>
>
> > On Oct 27, 2019, at 5:13 PM, Torsten Paul <Torsten.Paul@gmx.de> wrote:
> >
> > First note that the function literals are now
> > implemented, so the snapshot version of OpenSCAD
> > has functions as first class values which means
> > support for higher order functions.
> > (https://github.com/openscad/openscad/pull/3077)
> >
> > I hope to find some time to collect notes and post
> > an article about it. Meanwhile the minimalist docu
> > can be found at
> >
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules#Function_Literals
> >
> > On 28.10.19 00:09, Hugo Jackson wrote:
> >> To start, I would propose an extension of the "dot"
> >> notation, that would allow one to refer to a value
> >> declaration and/or function or module component of
> >> another module with a dot.
> >
> > Yes, having access to a nested data structure is
> > definitely something that would help a lot. The
> > core changes to the parser implementation that are
> > required for this are now done and merged to the
> > development snapshot.
> >
> > But I don't think it will be possible to link to
> > the existing function and/or module definitions.
> >
> > Slightly modified example, just adding a parameter
> > to module foo():
> >
> > module foo(offset) {
> > valueA = 7 + offset;
> >
> > function myFunc(num) = valueA + num;
> > }
> >
> > module bar() {
> > valueB = 8;
> >
> > valueC = foo.valueA + foo.myFunc(valueB);
> > }
> >
> > foo(10);
> > translate([10, 10, 0]) foo(20);
> >
> > bar(); // <- now what is valueC ?
> >
>
> Good point… for my part I don’t usually code modules with parameters, but
> I appreciate that isn’t how the real world works. :)
> 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
> provide the call for valueC in bar would need to be:
>
> valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or
> literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
>
> 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
> proposed ‘dot’ syntax would lead to more insightful coding that would tend
> to mitigate the damage that might occur.
>
> >
> >> The second extension would be the election of three
> >> operations as 'reserved' functions, union, difference
> >> and intersection such that one could explicitly call
> >> that part of a module without calling the others:
> >
> > I'm not sure I understand how this will work. Why
> > select specifically those 3 special cases?
> >
> > Is that meant just as names or would that also mean
> > intersection() { bar(); foo(); } a bit like operator
> > overloading?
> >
> >> foo(); // would execute intersection(){difference(){union(){<union
> code>}<difference code>}<intersection code>}
> >
> > Where's the nesting coming from? From the order of
> > the definitions?
> >
> >> Please let me know… I didn’t want to bog this
> >> proposal down with details if it’s obvious, but in
> >> doing that I have taken the risk that the improvement
> >> And benefits of such extensions may not be evident.
>
>
>
> I often code modules using a special varialble I name $e and a skeleton
> module that looks like this:
>
> module foo($e = -1) {
> module _union() {
> // code that primarily builds the object
> }
>
> module _diff() {
> // code that primarily subtracts geometry from _union()
> }
>
> difference() {
> if($e == -1 || $e == 0)
> _union();
> if($e == -1 || $e == 1)
> _diff();
> }
> }
>
> 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
>
> With this approach, when I just want the foo object I simply write:
>
> foo();
>
> 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:
>
> module bar() {
> difference() {
> union() {
> foo($e = 0);
> cylinder(d = 5, h = 10);
> }
> foo($e = 1);
> }
> }
>
> 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.
> 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…
>
> difference() {
> union() {
> // add some stuff
> }
> // take some stuff away
> }
>
> construct in them?
>
> 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:
>
> module foo() {
>
> union : {
> // code that primarily builds the object
> }
> diff : {
> // code that primarily subtracts geometry from union()
> }
>
> // code that follows executes only if foo is called
> }
>
> Now when I want the foo object to be combined with other objects, I would
> just have to write:
>
> module bar() {
> union : {
> foo.union();
> _cylinder(d = 5, h = 10);
> }
> diff : {
> foo.diff();
> }
> }
>
> 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.
>
> 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.
>
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
R
Robin2
Mon, Oct 28, 2019 9:12 AM
Instead of "Node editing system", I would suggest the more general term
"Visual programming language".
I would prefer "Visual Programming System" rather than "Visual Programming
Language".
I don't think Graphscad, Blockscad or my ClikScad are languages. They are
just graphical systems to make programming easier with the OpenSCAD
language.
On the other hand I would consider SolidPython and OpenPyscad to be
languages as they are essentially extensions to the Python language and you
would need to be familiar with regular Python programming to use them. And
they are not really "visual" systems.
...R
--
Sent from: http://forum.openscad.org/
doug.moen wrote
> Instead of "Node editing system", I would suggest the more general term
> "Visual programming language".
I would prefer "Visual Programming System" rather than "Visual Programming
Language".
I don't think Graphscad, Blockscad or my ClikScad are languages. They are
just graphical systems to make programming easier with the OpenSCAD
language.
On the other hand I would consider SolidPython and OpenPyscad to be
languages as they are essentially extensions to the Python language and you
would need to be familiar with regular Python programming to use them. And
they are not really "visual" systems.
...R
--
Sent from: http://forum.openscad.org/
HJ
Hugo Jackson
Mon, Oct 28, 2019 9:42 AM
On Oct 28, 2019, at 1:51 AM, nop head nop.head@gmail.com wrote:
Instead of
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
Why don't you simply define two modules foo_union() and foo_diff()?
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.
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).
If there is common positioning between foo() and foo_holes() then I would have foo_hole_positions(type) that positions children().
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.
I think my current direction is shaped by my experience with object oriented programming… indeed, in OpenSCAD I’m primarily creating actual objects :)
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.
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.
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.
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.
To start, I would propose an extension of the "dot"
notation, that would allow one to refer to a value
declaration and/or function or module component of
another module with a dot.
Yes, having access to a nested data structure is
definitely something that would help a lot. The
core changes to the parser implementation that are
required for this are now done and merged to the
development snapshot.
But I don't think it will be possible to link to
the existing function and/or module definitions.
Slightly modified example, just adding a parameter
to module foo():
module foo(offset) {
valueA = 7 + offset;
function myFunc(num) = valueA + num;
}
module bar() {
valueB = 8;
valueC = foo.valueA + foo.myFunc(valueB);
}
foo(10);
translate([10, 10, 0]) foo(20);
bar(); // <- now what is valueC ?
Good point… for my part I don’t usually code modules with parameters, but I appreciate that isn’t how the real world works. :)
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
provide the call for valueC in bar would need to be:
valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
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
proposed ‘dot’ syntax would lead to more insightful coding that would tend to mitigate the damage that might occur.
The second extension would be the election of three
operations as 'reserved' functions, union, difference
and intersection such that one could explicitly call
that part of a module without calling the others:
I'm not sure I understand how this will work. Why
select specifically those 3 special cases?
Is that meant just as names or would that also mean
intersection() { bar(); foo(); } a bit like operator
overloading?
foo(); // would execute intersection(){difference(){union(){<union code>}<difference code>}<intersection code>}
Where's the nesting coming from? From the order of
the definitions?
Please let me know… I didn’t want to bog this
proposal down with details if it’s obvious, but in
doing that I have taken the risk that the improvement
And benefits of such extensions may not be evident.
I often code modules using a special varialble I name $e and a skeleton module that looks like this:
module foo($e = -1) {
module _union() {
// code that primarily builds the object
}
module _diff() {
// code that primarily subtracts geometry from _union()
}
difference() {
if($e == -1 || $e == 0)
_union();
if($e == -1 || $e == 1)
_diff();
}
}
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
With this approach, when I just want the foo object I simply write:
foo();
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:
module bar() {
difference() {
union() {
foo($e = 0);
cylinder(d = 5, h = 10);
}
foo($e = 1);
}
}
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.
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…
difference() {
union() {
// add some stuff
}
// take some stuff away
}
construct in them?
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:
module foo() {
union : {
// code that primarily builds the object
}
diff : {
// code that primarily subtracts geometry from union()
}
// code that follows executes only if foo is called
}
Now when I want the foo object to be combined with other objects, I would just have to write:
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
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.
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.
OpenSCAD mailing list
Discuss@lists.openscad.org mailto:Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
> On Oct 28, 2019, at 1:51 AM, nop head <nop.head@gmail.com> wrote:
>
> Instead of
>
> module bar() {
> union : {
> foo.union();
> _cylinder(d = 5, h = 10);
> }
> diff : {
> foo.diff();
> }
> }
>
> Why don't you simply define two modules foo_union() and foo_diff()?
>
> 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.
>
> 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).
>
> If there is common positioning between foo() and foo_holes() then I would have foo_hole_positions(type) that positions children().
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.
I think my current direction is shaped by my experience with object oriented programming… indeed, in OpenSCAD I’m primarily creating actual objects :)
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.
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.
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.
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.
>
> On Mon, 28 Oct 2019 at 04:25, Hugo Jackson <hugo@apres.net <mailto:hugo@apres.net>> wrote:
>
>
> > On Oct 27, 2019, at 5:13 PM, Torsten Paul <Torsten.Paul@gmx.de <mailto:Torsten.Paul@gmx.de>> wrote:
> >
> > First note that the function literals are now
> > implemented, so the snapshot version of OpenSCAD
> > has functions as first class values which means
> > support for higher order functions.
> > (https://github.com/openscad/openscad/pull/3077 <https://github.com/openscad/openscad/pull/3077>)
> >
> > I hope to find some time to collect notes and post
> > an article about it. Meanwhile the minimalist docu
> > can be found at
> > https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules#Function_Literals <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules#Function_Literals>
> >
> > On 28.10.19 00:09, Hugo Jackson wrote:
> >> To start, I would propose an extension of the "dot"
> >> notation, that would allow one to refer to a value
> >> declaration and/or function or module component of
> >> another module with a dot.
> >
> > Yes, having access to a nested data structure is
> > definitely something that would help a lot. The
> > core changes to the parser implementation that are
> > required for this are now done and merged to the
> > development snapshot.
> >
> > But I don't think it will be possible to link to
> > the existing function and/or module definitions.
> >
> > Slightly modified example, just adding a parameter
> > to module foo():
> >
> > module foo(offset) {
> > valueA = 7 + offset;
> >
> > function myFunc(num) = valueA + num;
> > }
> >
> > module bar() {
> > valueB = 8;
> >
> > valueC = foo.valueA + foo.myFunc(valueB);
> > }
> >
> > foo(10);
> > translate([10, 10, 0]) foo(20);
> >
> > bar(); // <- now what is valueC ?
> >
>
> Good point… for my part I don’t usually code modules with parameters, but I appreciate that isn’t how the real world works. :)
> 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
> provide the call for valueC in bar would need to be:
>
> valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
>
> 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
> proposed ‘dot’ syntax would lead to more insightful coding that would tend to mitigate the damage that might occur.
>
> >
> >> The second extension would be the election of three
> >> operations as 'reserved' functions, union, difference
> >> and intersection such that one could explicitly call
> >> that part of a module without calling the others:
> >
> > I'm not sure I understand how this will work. Why
> > select specifically those 3 special cases?
> >
> > Is that meant just as names or would that also mean
> > intersection() { bar(); foo(); } a bit like operator
> > overloading?
> >
> >> foo(); // would execute intersection(){difference(){union(){<union code>}<difference code>}<intersection code>}
> >
> > Where's the nesting coming from? From the order of
> > the definitions?
> >
> >> Please let me know… I didn’t want to bog this
> >> proposal down with details if it’s obvious, but in
> >> doing that I have taken the risk that the improvement
> >> And benefits of such extensions may not be evident.
>
>
>
> I often code modules using a special varialble I name $e and a skeleton module that looks like this:
>
> module foo($e = -1) {
> module _union() {
> // code that primarily builds the object
> }
>
> module _diff() {
> // code that primarily subtracts geometry from _union()
> }
>
> difference() {
> if($e == -1 || $e == 0)
> _union();
> if($e == -1 || $e == 1)
> _diff();
> }
> }
>
> 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
>
> With this approach, when I just want the foo object I simply write:
>
> foo();
>
> 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:
>
> module bar() {
> difference() {
> union() {
> foo($e = 0);
> cylinder(d = 5, h = 10);
> }
> foo($e = 1);
> }
> }
>
> 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.
> 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…
>
> difference() {
> union() {
> // add some stuff
> }
> // take some stuff away
> }
>
> construct in them?
>
> 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:
>
> module foo() {
>
> union : {
> // code that primarily builds the object
> }
> diff : {
> // code that primarily subtracts geometry from union()
> }
>
> // code that follows executes only if foo is called
> }
>
> Now when I want the foo object to be combined with other objects, I would just have to write:
>
> module bar() {
> union : {
> foo.union();
> _cylinder(d = 5, h = 10);
> }
> diff : {
> foo.diff();
> }
> }
>
> 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.
>
> 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.
>
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org <mailto:Discuss@lists.openscad.org>
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org <http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
NH
nop head
Mon, Oct 28, 2019 11:07 AM
Well I consider my way of working more object oriented. A class normally
has lots of different methods named Class::method and with an implicit
this pointer or self reference. I just do this explicitly with
class_method(type).
I don't see any connection between adding and subtracting objects with
constructors and destructors. The latter are about object lifetime and
there is no such concept in OpenSCAD because it is a static description.
I also don't see your point about a proliferation of modules. I think of a
used OpenSCAD file as a class and the modules and functions as methods. You
seem to be treating a module as a class and trying to access things inside
of it. I consider the internals of my modules private and expose and
interface to my objects with functions.
On Mon, 28 Oct 2019 at 09:43, Hugo Jackson hugo@apres.net wrote:
On Oct 28, 2019, at 1:51 AM, nop head nop.head@gmail.com wrote:
Instead of
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
Why don't you simply define two modules foo_union() and foo_diff()?
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.
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).
If there is common positioning between foo() and foo_holes() then I would
have foo_hole_positions(type) that positions children().
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.
I think my current direction is shaped by my experience with object
oriented programming… indeed, in OpenSCAD I’m primarily creating actual
objects :)
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.
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.
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.
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.
On Mon, 28 Oct 2019 at 04:25, Hugo Jackson hugo@apres.net wrote:
On Oct 27, 2019, at 5:13 PM, Torsten Paul Torsten.Paul@gmx.de wrote:
First note that the function literals are now
implemented, so the snapshot version of OpenSCAD
has functions as first class values which means
support for higher order functions.
(https://github.com/openscad/openscad/pull/3077)
I hope to find some time to collect notes and post
an article about it. Meanwhile the minimalist docu
can be found at
On 28.10.19 00:09, Hugo Jackson wrote:
To start, I would propose an extension of the "dot"
notation, that would allow one to refer to a value
declaration and/or function or module component of
another module with a dot.
Yes, having access to a nested data structure is
definitely something that would help a lot. The
core changes to the parser implementation that are
required for this are now done and merged to the
development snapshot.
But I don't think it will be possible to link to
the existing function and/or module definitions.
Slightly modified example, just adding a parameter
to module foo():
module foo(offset) {
valueA = 7 + offset;
function myFunc(num) = valueA + num;
}
module bar() {
valueB = 8;
valueC = foo.valueA + foo.myFunc(valueB);
}
foo(10);
translate([10, 10, 0]) foo(20);
bar(); // <- now what is valueC ?
Good point… for my part I don’t usually code modules with parameters, but
I appreciate that isn’t how the real world works. :)
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
provide the call for valueC in bar would need to be:
valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or
literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
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
proposed ‘dot’ syntax would lead to more insightful coding that would
tend to mitigate the damage that might occur.
The second extension would be the election of three
operations as 'reserved' functions, union, difference
and intersection such that one could explicitly call
that part of a module without calling the others:
I'm not sure I understand how this will work. Why
select specifically those 3 special cases?
Is that meant just as names or would that also mean
intersection() { bar(); foo(); } a bit like operator
overloading?
foo(); // would execute intersection(){difference(){union(){<union
code>}<difference code>}<intersection code>}
Where's the nesting coming from? From the order of
the definitions?
Please let me know… I didn’t want to bog this
proposal down with details if it’s obvious, but in
doing that I have taken the risk that the improvement
And benefits of such extensions may not be evident.
I often code modules using a special varialble I name $e and a skeleton
module that looks like this:
module foo($e = -1) {
module _union() {
// code that primarily builds the object
}
module _diff() {
// code that primarily subtracts geometry from _union()
}
difference() {
if($e == -1 || $e == 0)
_union();
if($e == -1 || $e == 1)
_diff();
}
}
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
With this approach, when I just want the foo object I simply write:
foo();
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:
module bar() {
difference() {
union() {
foo($e = 0);
cylinder(d = 5, h = 10);
}
foo($e = 1);
}
}
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.
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…
difference() {
union() {
// add some stuff
}
// take some stuff away
}
construct in them?
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:
module foo() {
union : {
// code that primarily builds the object
}
diff : {
// code that primarily subtracts geometry from union()
}
// code that follows executes only if foo is called
}
Now when I want the foo object to be combined with other objects, I would
just have to write:
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
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.
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.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Well I consider my way of working more object oriented. A class normally
has lots of different methods named Class::method and with an implicit
*this* pointer or *self* reference. I just do this explicitly with
class_method(type).
I don't see any connection between adding and subtracting objects with
constructors and destructors. The latter are about object lifetime and
there is no such concept in OpenSCAD because it is a static description.
I also don't see your point about a proliferation of modules. I think of a
used OpenSCAD file as a class and the modules and functions as methods. You
seem to be treating a module as a class and trying to access things inside
of it. I consider the internals of my modules private and expose and
interface to my objects with functions.
On Mon, 28 Oct 2019 at 09:43, Hugo Jackson <hugo@apres.net> wrote:
>
>
> On Oct 28, 2019, at 1:51 AM, nop head <nop.head@gmail.com> wrote:
>
> Instead of
>
> module bar() {
> union : {
> foo.union();
> _cylinder(d = 5, h = 10);
> }
> diff : {
> foo.diff();
> }
> }
>
> Why don't you simply define two modules foo_union() and foo_diff()?
>
> 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.
>
> 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).
>
> If there is common positioning between foo() and foo_holes() then I would
> have foo_hole_positions(type) that positions children().
>
>
> 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.
>
> I think my current direction is shaped by my experience with object
> oriented programming… indeed, in OpenSCAD I’m primarily creating actual
> objects :)
>
> 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.
>
> 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.
>
> 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.
>
> 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.
>
>
>
> On Mon, 28 Oct 2019 at 04:25, Hugo Jackson <hugo@apres.net> wrote:
>
>>
>>
>> > On Oct 27, 2019, at 5:13 PM, Torsten Paul <Torsten.Paul@gmx.de> wrote:
>> >
>> > First note that the function literals are now
>> > implemented, so the snapshot version of OpenSCAD
>> > has functions as first class values which means
>> > support for higher order functions.
>> > (https://github.com/openscad/openscad/pull/3077)
>> >
>> > I hope to find some time to collect notes and post
>> > an article about it. Meanwhile the minimalist docu
>> > can be found at
>> >
>> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules#Function_Literals
>> >
>> > On 28.10.19 00:09, Hugo Jackson wrote:
>> >> To start, I would propose an extension of the "dot"
>> >> notation, that would allow one to refer to a value
>> >> declaration and/or function or module component of
>> >> another module with a dot.
>> >
>> > Yes, having access to a nested data structure is
>> > definitely something that would help a lot. The
>> > core changes to the parser implementation that are
>> > required for this are now done and merged to the
>> > development snapshot.
>> >
>> > But I don't think it will be possible to link to
>> > the existing function and/or module definitions.
>> >
>> > Slightly modified example, just adding a parameter
>> > to module foo():
>> >
>> > module foo(offset) {
>> > valueA = 7 + offset;
>> >
>> > function myFunc(num) = valueA + num;
>> > }
>> >
>> > module bar() {
>> > valueB = 8;
>> >
>> > valueC = foo.valueA + foo.myFunc(valueB);
>> > }
>> >
>> > foo(10);
>> > translate([10, 10, 0]) foo(20);
>> >
>> > bar(); // <- now what is valueC ?
>> >
>>
>> Good point… for my part I don’t usually code modules with parameters, but
>> I appreciate that isn’t how the real world works. :)
>> 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
>> provide the call for valueC in bar would need to be:
>>
>> valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or
>> literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
>>
>> 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
>> proposed ‘dot’ syntax would lead to more insightful coding that would
>> tend to mitigate the damage that might occur.
>>
>> >
>> >> The second extension would be the election of three
>> >> operations as 'reserved' functions, union, difference
>> >> and intersection such that one could explicitly call
>> >> that part of a module without calling the others:
>> >
>> > I'm not sure I understand how this will work. Why
>> > select specifically those 3 special cases?
>> >
>> > Is that meant just as names or would that also mean
>> > intersection() { bar(); foo(); } a bit like operator
>> > overloading?
>> >
>> >> foo(); // would execute intersection(){difference(){union(){<union
>> code>}<difference code>}<intersection code>}
>> >
>> > Where's the nesting coming from? From the order of
>> > the definitions?
>> >
>> >> Please let me know… I didn’t want to bog this
>> >> proposal down with details if it’s obvious, but in
>> >> doing that I have taken the risk that the improvement
>> >> And benefits of such extensions may not be evident.
>>
>>
>>
>> I often code modules using a special varialble I name $e and a skeleton
>> module that looks like this:
>>
>> module foo($e = -1) {
>> module _union() {
>> // code that primarily builds the object
>> }
>>
>> module _diff() {
>> // code that primarily subtracts geometry from _union()
>> }
>>
>> difference() {
>> if($e == -1 || $e == 0)
>> _union();
>> if($e == -1 || $e == 1)
>> _diff();
>> }
>> }
>>
>> 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
>>
>> With this approach, when I just want the foo object I simply write:
>>
>> foo();
>>
>> 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:
>>
>> module bar() {
>> difference() {
>> union() {
>> foo($e = 0);
>> cylinder(d = 5, h = 10);
>> }
>> foo($e = 1);
>> }
>> }
>>
>> 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.
>> 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…
>>
>> difference() {
>> union() {
>> // add some stuff
>> }
>> // take some stuff away
>> }
>>
>> construct in them?
>>
>> 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:
>>
>> module foo() {
>>
>> union : {
>> // code that primarily builds the object
>> }
>> diff : {
>> // code that primarily subtracts geometry from union()
>> }
>>
>> // code that follows executes only if foo is called
>> }
>>
>> Now when I want the foo object to be combined with other objects, I would
>> just have to write:
>>
>> module bar() {
>> union : {
>> foo.union();
>> _cylinder(d = 5, h = 10);
>> }
>> diff : {
>> foo.diff();
>> }
>> }
>>
>> 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.
>>
>> 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.
>>
>>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss@lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
AC
A. Craig West
Mon, Oct 28, 2019 11:56 AM
I know that in my library, I created a draw module, with a large number of
arguments to control how it rendered the children. It was a wrapper around
what was essentially a large switch case, so you could control things like
the % operator with boolean flags,as well as things like colour and alpha.
The code is terrible from a programmers point of view, but it makes it much
easier to turn on and off multiple sections of the display by only editing
a few variables. Most of my designs were intended for the thingiverse
customiser, so this method of working makes a lot of sense
On Mon, 28 Oct 2019, 07:09 nop head, nop.head@gmail.com wrote:
Well I consider my way of working more object oriented. A class normally
has lots of different methods named Class::method and with an implicit
this pointer or self reference. I just do this explicitly with
class_method(type).
I don't see any connection between adding and subtracting objects with
constructors and destructors. The latter are about object lifetime and
there is no such concept in OpenSCAD because it is a static description.
I also don't see your point about a proliferation of modules. I think of a
used OpenSCAD file as a class and the modules and functions as methods. You
seem to be treating a module as a class and trying to access things inside
of it. I consider the internals of my modules private and expose and
interface to my objects with functions.
On Mon, 28 Oct 2019 at 09:43, Hugo Jackson hugo@apres.net wrote:
On Oct 28, 2019, at 1:51 AM, nop head nop.head@gmail.com wrote:
Instead of
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
Why don't you simply define two modules foo_union() and foo_diff()?
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.
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).
If there is common positioning between foo() and foo_holes() then I would
have foo_hole_positions(type) that positions children().
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.
I think my current direction is shaped by my experience with object
oriented programming… indeed, in OpenSCAD I’m primarily creating actual
objects :)
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.
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.
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.
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.
On Mon, 28 Oct 2019 at 04:25, Hugo Jackson hugo@apres.net wrote:
On Oct 27, 2019, at 5:13 PM, Torsten Paul Torsten.Paul@gmx.de wrote:
First note that the function literals are now
implemented, so the snapshot version of OpenSCAD
has functions as first class values which means
support for higher order functions.
(https://github.com/openscad/openscad/pull/3077)
I hope to find some time to collect notes and post
an article about it. Meanwhile the minimalist docu
can be found at
On 28.10.19 00:09, Hugo Jackson wrote:
To start, I would propose an extension of the "dot"
notation, that would allow one to refer to a value
declaration and/or function or module component of
another module with a dot.
Yes, having access to a nested data structure is
definitely something that would help a lot. The
core changes to the parser implementation that are
required for this are now done and merged to the
development snapshot.
But I don't think it will be possible to link to
the existing function and/or module definitions.
Slightly modified example, just adding a parameter
to module foo():
module foo(offset) {
valueA = 7 + offset;
function myFunc(num) = valueA + num;
}
module bar() {
valueB = 8;
valueC = foo.valueA + foo.myFunc(valueB);
}
foo(10);
translate([10, 10, 0]) foo(20);
bar(); // <- now what is valueC ?
Good point… for my part I don’t usually code modules with parameters,
but I appreciate that isn’t how the real world works. :)
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
provide the call for valueC in bar would need to be:
valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or
literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
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
proposed ‘dot’ syntax would lead to more insightful coding that would
tend to mitigate the damage that might occur.
The second extension would be the election of three
operations as 'reserved' functions, union, difference
and intersection such that one could explicitly call
that part of a module without calling the others:
I'm not sure I understand how this will work. Why
select specifically those 3 special cases?
Is that meant just as names or would that also mean
intersection() { bar(); foo(); } a bit like operator
overloading?
foo(); // would execute intersection(){difference(){union(){<union
code>}<difference code>}<intersection code>}
Where's the nesting coming from? From the order of
the definitions?
Please let me know… I didn’t want to bog this
proposal down with details if it’s obvious, but in
doing that I have taken the risk that the improvement
And benefits of such extensions may not be evident.
I often code modules using a special varialble I name $e and a skeleton
module that looks like this:
module foo($e = -1) {
module _union() {
// code that primarily builds the object
}
module _diff() {
// code that primarily subtracts geometry from _union()
}
difference() {
if($e == -1 || $e == 0)
_union();
if($e == -1 || $e == 1)
_diff();
}
}
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
With this approach, when I just want the foo object I simply write:
foo();
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:
module bar() {
difference() {
union() {
foo($e = 0);
cylinder(d = 5, h = 10);
}
foo($e = 1);
}
}
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.
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…
difference() {
union() {
// add some stuff
}
// take some stuff away
}
construct in them?
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:
module foo() {
union : {
// code that primarily builds the object
}
diff : {
// code that primarily subtracts geometry from union()
}
// code that follows executes only if foo is called
}
Now when I want the foo object to be combined with other objects, I
would just have to write:
module bar() {
union : {
foo.union();
_cylinder(d = 5, h = 10);
}
diff : {
foo.diff();
}
}
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.
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.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
I know that in my library, I created a draw module, with a large number of
arguments to control how it rendered the children. It was a wrapper around
what was essentially a large switch case, so you could control things like
the % operator with boolean flags,as well as things like colour and alpha.
The code is terrible from a programmers point of view, but it makes it much
easier to turn on and off multiple sections of the display by only editing
a few variables. Most of my designs were intended for the thingiverse
customiser, so this method of working makes a lot of sense
On Mon, 28 Oct 2019, 07:09 nop head, <nop.head@gmail.com> wrote:
> Well I consider my way of working more object oriented. A class normally
> has lots of different methods named Class::method and with an implicit
> *this* pointer or *self* reference. I just do this explicitly with
> class_method(type).
>
> I don't see any connection between adding and subtracting objects with
> constructors and destructors. The latter are about object lifetime and
> there is no such concept in OpenSCAD because it is a static description.
>
> I also don't see your point about a proliferation of modules. I think of a
> used OpenSCAD file as a class and the modules and functions as methods. You
> seem to be treating a module as a class and trying to access things inside
> of it. I consider the internals of my modules private and expose and
> interface to my objects with functions.
>
> On Mon, 28 Oct 2019 at 09:43, Hugo Jackson <hugo@apres.net> wrote:
>
>>
>>
>> On Oct 28, 2019, at 1:51 AM, nop head <nop.head@gmail.com> wrote:
>>
>> Instead of
>>
>> module bar() {
>> union : {
>> foo.union();
>> _cylinder(d = 5, h = 10);
>> }
>> diff : {
>> foo.diff();
>> }
>> }
>>
>> Why don't you simply define two modules foo_union() and foo_diff()?
>>
>> 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.
>>
>> 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).
>>
>> If there is common positioning between foo() and foo_holes() then I would
>> have foo_hole_positions(type) that positions children().
>>
>>
>> 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.
>>
>> I think my current direction is shaped by my experience with object
>> oriented programming… indeed, in OpenSCAD I’m primarily creating actual
>> objects :)
>>
>> 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.
>>
>> 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.
>>
>> 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.
>>
>> 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.
>>
>>
>>
>> On Mon, 28 Oct 2019 at 04:25, Hugo Jackson <hugo@apres.net> wrote:
>>
>>>
>>>
>>> > On Oct 27, 2019, at 5:13 PM, Torsten Paul <Torsten.Paul@gmx.de> wrote:
>>> >
>>> > First note that the function literals are now
>>> > implemented, so the snapshot version of OpenSCAD
>>> > has functions as first class values which means
>>> > support for higher order functions.
>>> > (https://github.com/openscad/openscad/pull/3077)
>>> >
>>> > I hope to find some time to collect notes and post
>>> > an article about it. Meanwhile the minimalist docu
>>> > can be found at
>>> >
>>> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules#Function_Literals
>>> >
>>> > On 28.10.19 00:09, Hugo Jackson wrote:
>>> >> To start, I would propose an extension of the "dot"
>>> >> notation, that would allow one to refer to a value
>>> >> declaration and/or function or module component of
>>> >> another module with a dot.
>>> >
>>> > Yes, having access to a nested data structure is
>>> > definitely something that would help a lot. The
>>> > core changes to the parser implementation that are
>>> > required for this are now done and merged to the
>>> > development snapshot.
>>> >
>>> > But I don't think it will be possible to link to
>>> > the existing function and/or module definitions.
>>> >
>>> > Slightly modified example, just adding a parameter
>>> > to module foo():
>>> >
>>> > module foo(offset) {
>>> > valueA = 7 + offset;
>>> >
>>> > function myFunc(num) = valueA + num;
>>> > }
>>> >
>>> > module bar() {
>>> > valueB = 8;
>>> >
>>> > valueC = foo.valueA + foo.myFunc(valueB);
>>> > }
>>> >
>>> > foo(10);
>>> > translate([10, 10, 0]) foo(20);
>>> >
>>> > bar(); // <- now what is valueC ?
>>> >
>>>
>>> Good point… for my part I don’t usually code modules with parameters,
>>> but I appreciate that isn’t how the real world works. :)
>>> 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
>>> provide the call for valueC in bar would need to be:
>>>
>>> valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) … or
>>> literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
>>>
>>> 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
>>> proposed ‘dot’ syntax would lead to more insightful coding that would
>>> tend to mitigate the damage that might occur.
>>>
>>> >
>>> >> The second extension would be the election of three
>>> >> operations as 'reserved' functions, union, difference
>>> >> and intersection such that one could explicitly call
>>> >> that part of a module without calling the others:
>>> >
>>> > I'm not sure I understand how this will work. Why
>>> > select specifically those 3 special cases?
>>> >
>>> > Is that meant just as names or would that also mean
>>> > intersection() { bar(); foo(); } a bit like operator
>>> > overloading?
>>> >
>>> >> foo(); // would execute intersection(){difference(){union(){<union
>>> code>}<difference code>}<intersection code>}
>>> >
>>> > Where's the nesting coming from? From the order of
>>> > the definitions?
>>> >
>>> >> Please let me know… I didn’t want to bog this
>>> >> proposal down with details if it’s obvious, but in
>>> >> doing that I have taken the risk that the improvement
>>> >> And benefits of such extensions may not be evident.
>>>
>>>
>>>
>>> I often code modules using a special varialble I name $e and a skeleton
>>> module that looks like this:
>>>
>>> module foo($e = -1) {
>>> module _union() {
>>> // code that primarily builds the object
>>> }
>>>
>>> module _diff() {
>>> // code that primarily subtracts geometry from _union()
>>> }
>>>
>>> difference() {
>>> if($e == -1 || $e == 0)
>>> _union();
>>> if($e == -1 || $e == 1)
>>> _diff();
>>> }
>>> }
>>>
>>> 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
>>>
>>> With this approach, when I just want the foo object I simply write:
>>>
>>> foo();
>>>
>>> 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:
>>>
>>> module bar() {
>>> difference() {
>>> union() {
>>> foo($e = 0);
>>> cylinder(d = 5, h = 10);
>>> }
>>> foo($e = 1);
>>> }
>>> }
>>>
>>> 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.
>>> 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…
>>>
>>> difference() {
>>> union() {
>>> // add some stuff
>>> }
>>> // take some stuff away
>>> }
>>>
>>> construct in them?
>>>
>>> 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:
>>>
>>> module foo() {
>>>
>>> union : {
>>> // code that primarily builds the object
>>> }
>>> diff : {
>>> // code that primarily subtracts geometry from union()
>>> }
>>>
>>> // code that follows executes only if foo is called
>>> }
>>>
>>> Now when I want the foo object to be combined with other objects, I
>>> would just have to write:
>>>
>>> module bar() {
>>> union : {
>>> foo.union();
>>> _cylinder(d = 5, h = 10);
>>> }
>>> diff : {
>>> foo.diff();
>>> }
>>> }
>>>
>>> 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.
>>>
>>> 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.
>>>
>>>
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> Discuss@lists.openscad.org
>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>>
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss@lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss@lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
TP
Torsten Paul
Mon, Oct 28, 2019 5:54 PM
On 28.10.19 05:24, Hugo Jackson wrote:
valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) …
or literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
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 proposed ‘dot’ syntax would lead to more
insightful coding that would tend to mitigate the damage that
might occur.
I guess that would make it also impossible to change, so
that's not a good solution.
That does not mean the 'dot' syntax can't be used though.
It simply means we need to find a way to access the
instantiated modules and functions, not the declaration.
The incomplete/proposed object literals would allow that
this way with functions:
o = {
var = 3;
func = function(x) x + var;
};
Now we have a nested structure named o which has both a
variable 'var' and a function 'func'.
Accessing both can go via the common 'dot' notation:
echo(o.var); // ECHO: 3
echo(o.func(5)); // ECHO: 8
and that works just as expected when passing this thing
called 'o' to a module:
module mod(thing) {
echo(thing.var);
echo(thing.func(1));
}
mod(o);
The current struggle is how to fit modules and therefor
the geometry generation into that design.
ciao,
Torsten.
On 28.10.19 05:24, Hugo Jackson wrote:
> valueC = foo(offset = 7).valueA + foo(offset = 7).myFunc(valueB) …
> or literally valueC = foo(7).valueA + foot(7).myFunc(valueB)
>
> 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 proposed ‘dot’ syntax would lead to more
> insightful coding that would tend to mitigate the damage that
> might occur.
I guess that would make it also impossible to change, so
that's not a good solution.
That does not mean the 'dot' syntax can't be used though.
It simply means we need to find a way to access the
instantiated modules and functions, not the declaration.
The incomplete/proposed object literals would allow that
this way with functions:
o = {
var = 3;
func = function(x) x + var;
};
Now we have a nested structure named o which has both a
variable 'var' and a function 'func'.
Accessing both can go via the common 'dot' notation:
echo(o.var); // ECHO: 3
echo(o.func(5)); // ECHO: 8
and that works just as expected when passing this thing
called 'o' to a module:
module mod(thing) {
echo(thing.var);
echo(thing.func(1));
}
mod(o);
The current struggle is how to fit modules and therefor
the geometry generation into that design.
ciao,
Torsten.
TP
Torsten Paul
Mon, Oct 28, 2019 6:04 PM
On 28.10.19 09:51, nop head wrote:
Why don't you simply define two modules foo_union()
and foo_diff()?
That's of cause possible but means there's no way
to automatically select those.
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.
True, but if we can find a way to hide that extra
logic in a sensible way, that could make objects
easier to compose. People have asked for that all
the time.
The main question is probably if this kind of
relation can be expressed in a general, independent
from a specific design.
ciao,
Torsten.
On 28.10.19 09:51, nop head wrote:
> Why don't you simply define two modules foo_union()
> and foo_diff()?
That's of cause possible but means there's no way
to automatically select those.
> 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.
True, but if we can find a way to hide that extra
logic in a sensible way, that could make objects
easier to compose. People have asked for that all
the time.
The main question is probably if this kind of
relation can be expressed in a general, independent
from a specific design.
ciao,
Torsten.
NH
nop head
Mon, Oct 28, 2019 6:11 PM
Why do you need to automatic select between drawing an object and making a
hole for it? To me they are completely separate operations and I am quite
happy to code two separate modules and call them from different places.
E.g. I normally subtract the holes from a panel and then later on I add
the object to the panel to make an assembly. If the panel is part of a 3D
printed object then the hole subtraction is done in 3D but if it is a
milled sheet then the the subtraction is done in 2D and extruded for the
assembly view.
On Mon, 28 Oct 2019 at 18:05, Torsten Paul Torsten.Paul@gmx.de wrote:
On 28.10.19 09:51, nop head wrote:
Why don't you simply define two modules foo_union()
and foo_diff()?
That's of cause possible but means there's no way
to automatically select those.
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.
Why do you need to automatic select between drawing an object and making a
hole for it? To me they are completely separate operations and I am quite
happy to code two separate modules and call them from different places.
E.g. I normally subtract the holes from a panel and then later on I add
the object to the panel to make an assembly. If the panel is part of a 3D
printed object then the hole subtraction is done in 3D but if it is a
milled sheet then the the subtraction is done in 2D and extruded for the
assembly view.
On Mon, 28 Oct 2019 at 18:05, Torsten Paul <Torsten.Paul@gmx.de> wrote:
> On 28.10.19 09:51, nop head wrote:
> > Why don't you simply define two modules foo_union()
> > and foo_diff()?
>
> That's of cause possible but means there's no way
> to automatically select those.
>
> > 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.
>
> True, but if we can find a way to hide that extra
> logic in a sensible way, that could make objects
> easier to compose. People have asked for that all
> the time.
> The main question is probably if this kind of
> relation can be expressed in a general, independent
> from a specific design.
>
> ciao,
> Torsten.
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
TP
Torsten Paul
Mon, Oct 28, 2019 6:27 PM
On 28.10.19 19:11, nop head wrote:
Why do you need to automatic select between drawing
an object and making a hole for it?
To give all those people asking for it a solution
that works? I don't know if it's possible but if it
is, I think that would help people who just want
to combine a couple of modules from a library they
did not write themselves.
To me they are completely separate operations and
I am quite happy to code two separate modules and
call them from different places.
That's fine, nobody is going to take that away. But
please consider there's a large number of users who
have quite different use cases, specifically much
simpler ones. If we can make the life of those users
easier, that's a good thing.
ciao,
Torsten.
On 28.10.19 19:11, nop head wrote:
> Why do you need to automatic select between drawing
> an object and making a hole for it?
To give all those people asking for it a solution
that works? I don't know if it's possible but if it
is, I think that would help people who just want
to combine a couple of modules from a library they
did not write themselves.
> To me they are completely separate operations and
> I am quite happy to code two separate modules and
> call them from different places.
That's fine, nobody is going to take that away. But
please consider there's a large number of users who
have quite different use cases, specifically much
simpler ones. If we can make the life of those users
easier, that's a good thing.
ciao,
Torsten.