J
jon
Wed, Sep 27, 2023 11:57 PM
Adrian:
Nicely said, and very helpful. Thank you.
Jon
On 9/27/2023 7:00 PM, Adrian Mariano wrote:
Lazy union is a feature you can enable in the nightly build dev
versions. It's actually been available for a year or two.
As noted earlier, it should be called no-implicit-union. When you
write a for() you get an implicit union of the objects generated in
each iteration of the loop. So code like:
parent() for(i=[0:9]) {mything(i)};
will pass a single object to parent, the union of ten copies of
mything. The parent was hoping to see ten children and do something
different with them you're out of luck.
If we get rid of implicit unions by turning "lazy union" on then the
same code should pass ten separate instances of mything to the
parent. The parent will have ten children. It can union them if it
wants to, but could also do something else.
My understanding, as noted earlier, is that "lazy union" isn't
actually fully implemented, so even with it on, you still get implicit
unions for children passed to user-written modules. But in the case
of hull you can avoid the union, which, before the "manifold" option
was available, meant your code could run 100x faster. Now it's just
6x faster.
One thing that does happen with the current implementation is that at
the top level there is an implicit union normally so the output STL
file contains one, single object. If you enable lazy union then the
output can contain multiple, possibly intersecting, objects.
Adrian:
Nicely said, and very helpful. Thank you.
Jon
On 9/27/2023 7:00 PM, Adrian Mariano wrote:
> Lazy union is a feature you can enable in the nightly build dev
> versions. It's actually been available for a year or two.
>
> As noted earlier, it should be called no-implicit-union. When you
> write a for() you get an implicit union of the objects generated in
> each iteration of the loop. So code like:
>
> parent() for(i=[0:9]) {mything(i)};
>
> will pass a single object to parent, the union of ten copies of
> mything. The parent was hoping to see ten children and do something
> different with them you're out of luck.
>
> If we get rid of implicit unions by turning "lazy union" on then the
> same code should pass ten separate instances of mything to the
> parent. The parent will have ten children. It can union them if it
> wants to, but could also do something else.
>
> My understanding, as noted earlier, is that "lazy union" isn't
> actually fully implemented, so even with it on, you still get implicit
> unions for children passed to user-written modules. But in the case
> of hull you can avoid the union, which, before the "manifold" option
> was available, meant your code could run 100x faster. Now it's just
> 6x faster.
>
> One thing that does happen with the current implementation is that at
> the top level there is an implicit union normally so the output STL
> file contains one, single object. If you enable lazy union then the
> output can contain multiple, possibly intersecting, objects.
>
BC
Bob Carlson
Thu, Sep 28, 2023 12:15 AM
Thanks. I agree, no-implicit-union is much better. Lazy union does not seem apropos at all.
So, the option applies to for loops and the top level. Are there any other places where there are implied unions?
I have long assumed that since {} does not imply a union, only union() {} produced a union. Since I don’t program with children often (hardly ever) I haven’t noticed.
-Bob
Tucson AZ
On Sep 27, 2023, at 16:00, Adrian Mariano avm4@cornell.edu wrote:
Lazy union is a feature you can enable in the nightly build dev versions. It's actually been available for a year or two.
As noted earlier, it should be called no-implicit-union. When you write a for() you get an implicit union of the objects generated in each iteration of the loop. So code like:
parent() for(i=[0:9]) {mything(i)};
will pass a single object to parent, the union of ten copies of mything. The parent was hoping to see ten children and do something different with them you're out of luck.
If we get rid of implicit unions by turning "lazy union" on then the same code should pass ten separate instances of mything to the parent. The parent will have ten children. It can union them if it wants to, but could also do something else.
My understanding, as noted earlier, is that "lazy union" isn't actually fully implemented, so even with it on, you still get implicit unions for children passed to user-written modules. But in the case of hull you can avoid the union, which, before the "manifold" option was available, meant your code could run 100x faster. Now it's just 6x faster.
One thing that does happen with the current implementation is that at the top level there is an implicit union normally so the output STL file contains one, single object. If you enable lazy union then the output can contain multiple, possibly intersecting, objects.
On Wed, Sep 27, 2023 at 5:08 PM Bob Carlson <bob@rjcarlson.com mailto:bob@rjcarlson.com> wrote:
I’m still not up to speed apparently. lazy-union is a feature that can be enabled or disabled? What precisely is the semantics of this feature? And the semantics of its absence?
-Bob
Tucson AZ
On Sep 27, 2023, at 08:45, Jordan Brown <openscad@jordan.maileater.net mailto:openscad@jordan.maileater.net> wrote:
On 9/27/2023 2:57 AM, nop head wrote:
Lazy union enables a for loop to generate multiple children so if you pass the result to a module that uses children() it can index them individually. Similarly it lets a module return multiple children so they can be indexed. It is a semantic change, but not just for performance.
Maybe I just don't understand, but I don't think it does. (And it really can't, without huge changes in semantics.)
With 2023.09.25, with lazy-union on, manifold on or off:
module c() {
echo($children);
children(0);
children(1);
}
c() {
for(i=[1:9]) cube(i);
}
yields
ECHO: 1
WARNING: Children index (1) out of bounds (1 children) in file , line 4
... which it kind of has to, because child modules aren't executed until you call children(). For for() and other modules to be able to return individually accessible children would require that the child modules all be executed before the parent is executed.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org mailto:discuss-leave@lists.openscad.org
Thanks. I agree, no-implicit-union is much better. Lazy union does not seem apropos at all.
So, the option applies to for loops and the top level. Are there any other places where there are implied unions?
I have long assumed that since {} does not imply a union, only union() {} produced a union. Since I don’t program with children often (hardly ever) I haven’t noticed.
-Bob
Tucson AZ
On Sep 27, 2023, at 16:00, Adrian Mariano <avm4@cornell.edu> wrote:
Lazy union is a feature you can enable in the nightly build dev versions. It's actually been available for a year or two.
As noted earlier, it should be called no-implicit-union. When you write a for() you get an implicit union of the objects generated in each iteration of the loop. So code like:
parent() for(i=[0:9]) {mything(i)};
will pass a single object to parent, the union of ten copies of mything. The parent was hoping to see ten children and do something different with them you're out of luck.
If we get rid of implicit unions by turning "lazy union" on then the same code should pass ten separate instances of mything to the parent. The parent will have ten children. It can union them if it wants to, but could also do something else.
My understanding, as noted earlier, is that "lazy union" isn't actually fully implemented, so even with it on, you still get implicit unions for children passed to user-written modules. But in the case of hull you can avoid the union, which, before the "manifold" option was available, meant your code could run 100x faster. Now it's just 6x faster.
One thing that does happen with the current implementation is that at the top level there is an implicit union normally so the output STL file contains one, single object. If you enable lazy union then the output can contain multiple, possibly intersecting, objects.
On Wed, Sep 27, 2023 at 5:08 PM Bob Carlson <bob@rjcarlson.com <mailto:bob@rjcarlson.com>> wrote:
> I’m still not up to speed apparently. lazy-union is a feature that can be enabled or disabled? What precisely is the semantics of this feature? And the semantics of its absence?
>
> -Bob
> Tucson AZ
>
>
>
> On Sep 27, 2023, at 08:45, Jordan Brown <openscad@jordan.maileater.net <mailto:openscad@jordan.maileater.net>> wrote:
>
> On 9/27/2023 2:57 AM, nop head wrote:
>> Lazy union enables a for loop to generate multiple children so if you pass the result to a module that uses children() it can index them individually. Similarly it lets a module return multiple children so they can be indexed. It is a semantic change, but not just for performance.
>
> Maybe I just don't understand, but I don't think it does. (And it really can't, without huge changes in semantics.)
>
> With 2023.09.25, with lazy-union on, manifold on or off:
> module c() {
> echo($children);
> children(0);
> children(1);
> }
>
> c() {
> for(i=[1:9]) cube(i);
> }
> yields
>
> ECHO: 1
> WARNING: Children index (1) out of bounds (1 children) in file , line 4
>
> ... which it kind of has to, because child modules aren't executed until you call children(). For for() and other modules to be able to return individually accessible children would require that the child modules all be executed before the parent is executed.
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org>
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org <mailto:discuss-leave@lists.openscad.org>
_______________________________________________
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
JB
Jordan Brown
Thu, Sep 28, 2023 3:38 AM
On 9/27/2023 9:14 AM, pca006132 wrote:
I think openscad is purely functional with no side effects (except
echo?), so different evaluation order should not affect the result?
I'm not enough of a theorist to talk about what "purely functional" means.
However, from a practical standpoint, $ variables in the parent are
visible in the child, and obviously can only be set if the parent
executes before the child.
module c() {
children($n=3);
translate([10,0,0]) children($n=4);
}
c() {
circle($fn=$n);
}
(I don't think that works in 2021.01, but similar constructs do.)
Also, rands() can yield different results on each run, so
module c() {
children();
translate([10,0,0]) children();
}
c() {
circle($fn=floor(rands(3,7,1)[0]));
}
would yield different results if the circle() was only executed once.
One way to look at it is that child module invocations are not arguments
to the parent, per se. Rather, they are sort of executable snippets,
akin to what other languages might call closures or lambda functions,
that the parent can invoke at points that it chooses.
Note: $ variable behavior is subtly different in 2021.01 than in the
development snapshot. In 2021.01, child-block assignments are executed
before the parent is executed. In the development snapshot, they are
executed at each children() call.
On 9/27/2023 9:14 AM, pca006132 wrote:
> I think openscad is purely functional with no side effects (except
> echo?), so different evaluation order should not affect the result?
I'm not enough of a theorist to talk about what "purely functional" means.
However, from a practical standpoint, $ variables in the parent are
visible in the child, and obviously can only be set if the parent
executes before the child.
module c() {
children($n=3);
translate([10,0,0]) children($n=4);
}
c() {
circle($fn=$n);
}
(I don't think that works in 2021.01, but similar constructs do.)
Also, rands() can yield different results on each run, so
module c() {
children();
translate([10,0,0]) children();
}
c() {
circle($fn=floor(rands(3,7,1)[0]));
}
would yield different results if the circle() was only executed once.
One way to look at it is that child module invocations are not arguments
to the parent, per se. Rather, they are sort of executable snippets,
akin to what other languages might call closures or lambda functions,
that the parent can invoke at points that it chooses.
Note: $ variable behavior is subtly different in 2021.01 than in the
development snapshot. In 2021.01, child-block assignments are executed
before the parent is executed. In the development snapshot, they are
executed at each children() call.
JB
Jordan Brown
Thu, Sep 28, 2023 3:51 AM
On 9/27/2023 9:41 AM, pca006132 wrote:
Maybe this will make me sound like a jerk, but from a programming
language point of view I think it would be much better to create
something like a OpenSCAD2, put the old behavior in a compatibility
mode, and redesign the language (if users still think it is desirable
to have a domain specific language for 3D modelling, instead of using
general purpose languages). It seems to me that there are so many
design issues and limitations that we cannot fix without breaking some
existing code.
There's a good argument for that. I keep thinking about it. There are
in my mind two key problems:
- Minimum boilerplate. The minimum OpenSCAD program is "cube();".
Strive to make the minimum be similarly simple. In particular,
ideally (but very difficult in standard languages), mentioning a
shape name should add the shape to the model, without any additional
operations on it.
- Sandbox. Absent implementation bugs, an OpenSCAD program cannot
modify the system you run it on. It simply doesn't have the
operations required. This means that it's relatively safe to
download even a complex OpenSCAD program or library and run it.
Most general languages have file manipulation mechanisms, that would
need to be disabled somehow... and that can be remarkably difficult.
This is something of a religious topic. There are those who say, not
unreasonably, "that wouldn't be OpenSCAD; if you want to do it then
please go somewhere else to talk about it". My personal opinion is that
the real religion is programmatic CAD (versus click and drag), and
that language bindings are all just different sects of that religion.
And: what is "OpenSCAD"? If you have the OpenSCAD viewer, editor, et
cetera, and you're doing Constructive Solid Geometry, but the language
is different, is that still OpenSCAD?
If the Python work goes much further, I think it'll make sense to fork
off a different mailing list for it, so that it doesn't clutter the
"traditional OpenSCAD" mailing list.
On 9/27/2023 9:41 AM, pca006132 wrote:
> Maybe this will make me sound like a jerk, but from a programming
> language point of view I think it would be much better to create
> something like a OpenSCAD2, put the old behavior in a compatibility
> mode, and redesign the language (if users still think it is desirable
> to have a domain specific language for 3D modelling, instead of using
> general purpose languages). It seems to me that there are so many
> design issues and limitations that we cannot fix without breaking some
> existing code.
There's a good argument for that. I keep thinking about it. There are
in my mind two key problems:
* Minimum boilerplate. The minimum OpenSCAD program is "cube();".
Strive to make the minimum be similarly simple. In particular,
ideally (but very difficult in standard languages), mentioning a
shape name should add the shape to the model, without any additional
operations on it.
* Sandbox. Absent implementation bugs, an OpenSCAD program cannot
modify the system you run it on. It simply doesn't have the
operations required. This means that it's relatively safe to
download even a complex OpenSCAD program or library and run it.
Most general languages have file manipulation mechanisms, that would
need to be disabled somehow... and that can be remarkably difficult.
This is something of a religious topic. There are those who say, not
unreasonably, "that wouldn't be OpenSCAD; if you want to do it then
please go somewhere else to talk about it". My personal opinion is that
the *real* religion is programmatic CAD (versus click and drag), and
that language bindings are all just different sects of that religion.
And: what is "OpenSCAD"? If you have the OpenSCAD viewer, editor, et
cetera, and you're doing Constructive Solid Geometry, but the language
is different, is that still OpenSCAD?
If the Python work goes much further, I think it'll make sense to fork
off a different mailing list for it, so that it doesn't clutter the
"traditional OpenSCAD" mailing list.
JB
Jordan Brown
Thu, Sep 28, 2023 3:56 AM
On 9/27/2023 5:15 PM, Bob Carlson wrote:
So, the option applies to for loops and the top level. Are there any
other places where there are implied unions?
I have long assumed that since {} does not imply a union, only union()
{} produced a union. Since I don’t program with children often (hardly
ever) I haven’t noticed.
Most of the built-in modules that take children have an implied union:
for, if, translate, rotate, scale, hull, multmatrix, linear_extrude,
rotate_extrude, offset, et cetera. Offhand, the only ones that don't
are difference, intersection, and minkowski.
I have never understood why naked {} doesn't introduce a new scope and
imply a union.
On 9/27/2023 5:15 PM, Bob Carlson wrote:
> So, the option applies to for loops and the top level. Are there any
> other places where there are implied unions?
>
> I have long assumed that since {} does not imply a union, only union()
> {} produced a union. Since I don’t program with children often (hardly
> ever) I haven’t noticed.
Most of the built-in modules that take children have an implied union:
for, if, translate, rotate, scale, hull, multmatrix, linear_extrude,
rotate_extrude, offset, et cetera. Offhand, the only ones that don't
are difference, intersection, and minkowski.
I have never understood why naked {} doesn't introduce a new scope and
imply a union.
NH
nop head
Thu, Sep 28, 2023 8:38 AM
In 2021.01, child-block assignments are executed before the parent is
executed.
I don't think that can be true as I often use $variables in a child set by
the parent and I use the last release for all my command line work.
I think the change was far more subtle. One can't copy the $variable to
another variable in the child with a normal block level assignment but you
can with a let() statement.
On Thu, 28 Sept 2023 at 04:57, Jordan Brown openscad@jordan.maileater.net
wrote:
On 9/27/2023 5:15 PM, Bob Carlson wrote:
So, the option applies to for loops and the top level. Are there any other
places where there are implied unions?
I have long assumed that since {} does not imply a union, only union() {}
produced a union. Since I don’t program with children often (hardly ever) I
haven’t noticed.
Most of the built-in modules that take children have an implied union:
for, if, translate, rotate, scale, hull, multmatrix, linear_extrude,
rotate_extrude, offset, et cetera. Offhand, the only ones that don't are
difference, intersection, and minkowski.
I have never understood why naked {} doesn't introduce a new scope and
imply a union.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
> In 2021.01, child-block assignments are executed before the parent is
executed.
I don't think that can be true as I often use $variables in a child set by
the parent and I use the last release for all my command line work.
I think the change was far more subtle. One can't copy the $variable to
another variable in the child with a normal block level assignment but you
can with a let() statement.
On Thu, 28 Sept 2023 at 04:57, Jordan Brown <openscad@jordan.maileater.net>
wrote:
> On 9/27/2023 5:15 PM, Bob Carlson wrote:
>
> So, the option applies to for loops and the top level. Are there any other
> places where there are implied unions?
>
> I have long assumed that since {} does not imply a union, only union() {}
> produced a union. Since I don’t program with children often (hardly ever) I
> haven’t noticed.
>
>
> Most of the built-in modules that take children have an implied union:
> for, if, translate, rotate, scale, hull, multmatrix, linear_extrude,
> rotate_extrude, offset, et cetera. Offhand, the only ones that don't are
> difference, intersection, and minkowski.
>
> I have never understood why naked {} doesn't introduce a new scope and
> imply a union.
>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
AM
Adrian Mariano
Thu, Sep 28, 2023 10:31 AM
No, Jordan is correct. You are restating the behavior in a less complete
and accurate way.
The reason you can't copy the $variable to another variable normally, e.g.
by writing foo=$variable, is that ASSIGNMENTS in the child run before the
parent, so the $variable isn't defined yet when the assignment runs. The
reason let(foo=$var) works is that let() is a MODULE and modules in the
child run AFTER the parent, so when let() runs, the $var has been assigned
by the parent. It also works to do union(){ foo=$variable; ....} in the
child because the union, being a module, runs after the parent.
On Thu, Sep 28, 2023 at 4:39 AM nop head nop.head@gmail.com wrote:
In 2021.01, child-block assignments are executed before the parent is
executed.
I don't think that can be true as I often use $variables in a child set by
the parent and I use the last release for all my command line work.
I think the change was far more subtle. One can't copy the $variable to
another variable in the child with a normal block level assignment but you
can with a let() statement.
On Thu, 28 Sept 2023 at 04:57, Jordan Brown openscad@jordan.maileater.net
wrote:
On 9/27/2023 5:15 PM, Bob Carlson wrote:
So, the option applies to for loops and the top level. Are there any
other places where there are implied unions?
I have long assumed that since {} does not imply a union, only union() {}
produced a union. Since I don’t program with children often (hardly ever) I
haven’t noticed.
Most of the built-in modules that take children have an implied union:
for, if, translate, rotate, scale, hull, multmatrix, linear_extrude,
rotate_extrude, offset, et cetera. Offhand, the only ones that don't are
difference, intersection, and minkowski.
I have never understood why naked {} doesn't introduce a new scope and
imply a union.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
No, Jordan is correct. You are restating the behavior in a less complete
and accurate way.
The reason you can't copy the $variable to another variable normally, e.g.
by writing foo=$variable, is that ASSIGNMENTS in the child run before the
parent, so the $variable isn't defined yet when the assignment runs. The
reason let(foo=$var) works is that let() is a MODULE and modules in the
child run AFTER the parent, so when let() runs, the $var has been assigned
by the parent. It also works to do union(){ foo=$variable; ....} in the
child because the union, being a module, runs after the parent.
On Thu, Sep 28, 2023 at 4:39 AM nop head <nop.head@gmail.com> wrote:
> > In 2021.01, child-block assignments are executed before the parent is
> executed.
> I don't think that can be true as I often use $variables in a child set by
> the parent and I use the last release for all my command line work.
>
> I think the change was far more subtle. One can't copy the $variable to
> another variable in the child with a normal block level assignment but you
> can with a let() statement.
>
> On Thu, 28 Sept 2023 at 04:57, Jordan Brown <openscad@jordan.maileater.net>
> wrote:
>
>> On 9/27/2023 5:15 PM, Bob Carlson wrote:
>>
>> So, the option applies to for loops and the top level. Are there any
>> other places where there are implied unions?
>>
>> I have long assumed that since {} does not imply a union, only union() {}
>> produced a union. Since I don’t program with children often (hardly ever) I
>> haven’t noticed.
>>
>>
>> Most of the built-in modules that take children have an implied union:
>> for, if, translate, rotate, scale, hull, multmatrix, linear_extrude,
>> rotate_extrude, offset, et cetera. Offhand, the only ones that don't are
>> difference, intersection, and minkowski.
>>
>> I have never understood why naked {} doesn't introduce a new scope and
>> imply a union.
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
NH
nop head
Thu, Sep 28, 2023 12:05 PM
But if you don't copy it, you just repeatedly use the $variable it all
works fine. How can it if the child is executed before the parent has set
the $variable?
On Thu, 28 Sept 2023 at 12:51, Adrian Mariano avm4@cornell.edu wrote:
No, Jordan is correct. You are restating the behavior in a less complete
and accurate way.
The reason you can't copy the $variable to another variable normally, e.g.
by writing foo=$variable, is that ASSIGNMENTS in the child run before the
parent, so the $variable isn't defined yet when the assignment runs. The
reason let(foo=$var) works is that let() is a MODULE and modules in the
child run AFTER the parent, so when let() runs, the $var has been assigned
by the parent. It also works to do union(){ foo=$variable; ....} in the
child because the union, being a module, runs after the parent.
On Thu, Sep 28, 2023 at 4:39 AM nop head nop.head@gmail.com wrote:
In 2021.01, child-block assignments are executed before the parent is
executed.
I don't think that can be true as I often use $variables in a child set
by the parent and I use the last release for all my command line work.
I think the change was far more subtle. One can't copy the $variable to
another variable in the child with a normal block level assignment but you
can with a let() statement.
On Thu, 28 Sept 2023 at 04:57, Jordan Brown <
openscad@jordan.maileater.net> wrote:
On 9/27/2023 5:15 PM, Bob Carlson wrote:
So, the option applies to for loops and the top level. Are there any
other places where there are implied unions?
I have long assumed that since {} does not imply a union, only union()
{} produced a union. Since I don’t program with children often (hardly
ever) I haven’t noticed.
Most of the built-in modules that take children have an implied union:
for, if, translate, rotate, scale, hull, multmatrix, linear_extrude,
rotate_extrude, offset, et cetera. Offhand, the only ones that don't are
difference, intersection, and minkowski.
I have never understood why naked {} doesn't introduce a new scope and
imply a union.
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
But if you don't copy it, you just repeatedly use the $variable it all
works fine. How can it if the child is executed before the parent has set
the $variable?
On Thu, 28 Sept 2023 at 12:51, Adrian Mariano <avm4@cornell.edu> wrote:
> No, Jordan is correct. You are restating the behavior in a less complete
> and accurate way.
>
> The reason you can't copy the $variable to another variable normally, e.g.
> by writing foo=$variable, is that ASSIGNMENTS in the child run before the
> parent, so the $variable isn't defined yet when the assignment runs. The
> reason let(foo=$var) works is that let() is a MODULE and modules in the
> child run AFTER the parent, so when let() runs, the $var has been assigned
> by the parent. It also works to do union(){ foo=$variable; ....} in the
> child because the union, being a module, runs after the parent.
>
>
>
> On Thu, Sep 28, 2023 at 4:39 AM nop head <nop.head@gmail.com> wrote:
>
>> > In 2021.01, child-block assignments are executed before the parent is
>> executed.
>> I don't think that can be true as I often use $variables in a child set
>> by the parent and I use the last release for all my command line work.
>>
>> I think the change was far more subtle. One can't copy the $variable to
>> another variable in the child with a normal block level assignment but you
>> can with a let() statement.
>>
>> On Thu, 28 Sept 2023 at 04:57, Jordan Brown <
>> openscad@jordan.maileater.net> wrote:
>>
>>> On 9/27/2023 5:15 PM, Bob Carlson wrote:
>>>
>>> So, the option applies to for loops and the top level. Are there any
>>> other places where there are implied unions?
>>>
>>> I have long assumed that since {} does not imply a union, only union()
>>> {} produced a union. Since I don’t program with children often (hardly
>>> ever) I haven’t noticed.
>>>
>>>
>>> Most of the built-in modules that take children have an implied union:
>>> for, if, translate, rotate, scale, hull, multmatrix, linear_extrude,
>>> rotate_extrude, offset, et cetera. Offhand, the only ones that don't are
>>> difference, intersection, and minkowski.
>>>
>>> I have never understood why naked {} doesn't introduce a new scope and
>>> imply a union.
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>>
>> _______________________________________________
>> OpenSCAD mailing list
>> To unsubscribe send an email to discuss-leave@lists.openscad.org
>>
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
WF
William F. Adams
Thu, Sep 28, 2023 12:39 PM
On Wednesday, September 27, 2023 at 11:52:14 PM EDT, Jordan Brown openscad@jordan.maileater.net wrote:
There's a good argument for that. I keep thinking about it. There are in my mind two key problems:
-
Minimum boilerplate. The minimum OpenSCAD program is "cube();". Strive to make the minimum be similarly simple. In particular, ideally (but very difficult in standard languages), mentioning a shape name should add the shape to the model, without any additional operations on it.
-
Sandbox. Absent implementation bugs, an OpenSCAD program cannot modify the system you run it on. It simply doesn't have the operations required. This means that it's relatively safe to download even a complex OpenSCAD program or library and run it. Most general languages have file manipulation mechanisms, that would need to be disabled somehow... and that can be remarkably difficult.
This is something of a religious topic. There are those who say, not unreasonably, "that wouldn't be OpenSCAD; if you want to do it then please go somewhere else to talk about it". My personal opinion is that the real religion is programmatic CAD (versus click and drag), and that language bindings are all just different sects of that religion. And: what is "OpenSCAD"? If you have the OpenSCAD viewer, editor, et cetera, and you're doing Constructive Solid Geometry, but the language is different, is that still OpenSCAD?
If the Python work goes much further, I think it'll make sense to fork off a different mailing list for it, so that it doesn't clutter the "traditional OpenSCAD" mailing list.
As someone who has been both frustrated by OpenSCAD's limitations, and successful because of them, that is a concise and accurate summation.
Rather than a separate mailing list, I'd like to see a server-side filtering where folks sign up based on their interests:
- "Pure [OpenSCAD]" (the current list) - "[OSPython] in OpenSCAD" (new discussions of Python in OpenSCAD only) - "[OpenSCAD] and [OSPython]" (both discussions)
Everyone should be set to the former by default and the other two would be opt-in --- new messages would have their bracketed descriptions set appropriate to the interest of the poster, while responses could have the Subject line edited to restrict or redirect them.
I suspect there will be a lot of folks who would sign up for both lists and a lot of discussion back and forth.
William
On Wednesday, September 27, 2023 at 11:52:14 PM EDT, Jordan Brown <openscad@jordan.maileater.net> wrote:
There's a good argument for that. I keep thinking about it. There are in my mind two key problems:
- Minimum boilerplate. The minimum OpenSCAD program is "cube();". Strive to make the minimum be similarly simple. In particular, ideally (but very difficult in standard languages), mentioning a shape name should add the shape to the model, without any additional operations on it.
- Sandbox. Absent implementation bugs, an OpenSCAD program cannot modify the system you run it on. It simply doesn't have the operations required. This means that it's relatively safe to download even a complex OpenSCAD program or library and run it. Most general languages have file manipulation mechanisms, that would need to be disabled somehow... and that can be remarkably difficult.
This is something of a religious topic. There are those who say, not unreasonably, "that wouldn't be OpenSCAD; if you want to do it then please go somewhere else to talk about it". My personal opinion is that the *real* religion is programmatic CAD (versus click and drag), and that language bindings are all just different sects of that religion. And: what is "OpenSCAD"? If you have the OpenSCAD viewer, editor, et cetera, and you're doing Constructive Solid Geometry, but the language is different, is that still OpenSCAD?
If the Python work goes much further, I think it'll make sense to fork off a different mailing list for it, so that it doesn't clutter the "traditional OpenSCAD" mailing list.
As someone who has been both frustrated by OpenSCAD's limitations, and successful because of them, that is a concise and accurate summation.
Rather than a separate mailing list, I'd like to see a server-side filtering where folks sign up based on their interests:
- "Pure [OpenSCAD]" (the current list) - "[OSPython] in OpenSCAD" (new discussions of Python in OpenSCAD only) - "[OpenSCAD] and [OSPython]" (both discussions)
Everyone should be set to the former by default and the other two would be opt-in --- new messages would have their bracketed descriptions set appropriate to the interest of the poster, while responses could have the Subject line edited to restrict or redirect them.
I suspect there will be a lot of folks who would sign up for both lists and a lot of discussion back and forth.
William
JB
Jordan Brown
Thu, Sep 28, 2023 3:55 PM
On 9/28/2023 5:05 AM, nop head wrote:
But if you don't copy it, you just repeatedly use the $variable it all
works fine. How can it if the child is executed before the parent has
set the $variable?
You say "the child is executed" like that's a simple and straightforward
concept :-)
OpenSCAD executes all of the assignments - as Adrian says, not counting
let() as an assignment, just plain name=value assignments - before
executing all of the modules.
Try this:
module foo() {
x = echo("foo assignment 1") 0;
echo("foo module 1");
y = echo("foo assignment 2") 0;
echo("foo module 2");
}
foo();
In a conventional language, you would get assignment 1, module 1,
assignment 2, module 2, right? In OpenSCAD:
ECHO: "foo assignment 1"
ECHO: "foo assignment 2"
ECHO: "foo module 1"
ECHO: "foo module 2"
This means, incidentally, that an assert() statement won't protect you
against assignment-time problems, because the assignments run before the
assert module. You have to use the assert pseudo-function to protect
assignments.
Now let's bring children into play:
module c() {
x = echo("c assignment 1") 0;
echo("c module 1");
children();
children();
y = echo("c assignment 2") 0;
echo("c module 2");
}
c() {
z = echo("child assignment 1");
echo("child module 1");
a = echo("child assignment 2");
echo("child module 2");
}
In 2021.01, you get:
ECHO: "child assignment 1"
ECHO: "child assignment 2"
ECHO: "c assignment 1"
ECHO: "c assignment 2"
ECHO: "c module 1"
ECHO: "child module 1"
ECHO: "child module 2"
ECHO: "child module 1"
ECHO: "child module 2"
ECHO: "c module 2"
Note that the child assignments happen once only, before anything in
the parent runs, then the parent assignments, then the parent module
invocations, including the child modules once for each children() call.
In 2023.09.25:
ECHO: "c assignment 1"
ECHO: "c assignment 2"
ECHO: "c module 1"
ECHO: "child assignment 1"
ECHO: "child assignment 2"
ECHO: "child module 1"
ECHO: "child module 2"
ECHO: "child assignment 1"
ECHO: "child assignment 2"
ECHO: "child module 1"
ECHO: "child module 2"
ECHO: "c module 2"
The parent assignments are now first, then parent modules, and for each
children() call you get the child assignments and then the child modules.
The new behavior is still strange compared to conventional languages,
but it's less strange than the old behavior, notably with respect to $
variables set in the parent.
On 9/28/2023 5:05 AM, nop head wrote:
> But if you don't copy it, you just repeatedly use the $variable it all
> works fine. How can it if the child is executed before the parent has
> set the $variable?
You say "the child is executed" like that's a simple and straightforward
concept :-)
OpenSCAD executes all of the assignments - as Adrian says, not counting
let() as an assignment, just plain name=value assignments - before
executing all of the modules.
Try this:
module foo() {
x = echo("foo assignment 1") 0;
echo("foo module 1");
y = echo("foo assignment 2") 0;
echo("foo module 2");
}
foo();
In a conventional language, you would get assignment 1, module 1,
assignment 2, module 2, right? In OpenSCAD:
ECHO: "foo assignment 1"
ECHO: "foo assignment 2"
ECHO: "foo module 1"
ECHO: "foo module 2"
This means, incidentally, that an assert() statement won't protect you
against assignment-time problems, because the assignments run before the
assert module. You have to use the assert pseudo-function to protect
assignments.
Now let's bring children into play:
module c() {
x = echo("c assignment 1") 0;
echo("c module 1");
children();
children();
y = echo("c assignment 2") 0;
echo("c module 2");
}
c() {
z = echo("child assignment 1");
echo("child module 1");
a = echo("child assignment 2");
echo("child module 2");
}
In 2021.01, you get:
ECHO: "child assignment 1"
ECHO: "child assignment 2"
ECHO: "c assignment 1"
ECHO: "c assignment 2"
ECHO: "c module 1"
ECHO: "child module 1"
ECHO: "child module 2"
ECHO: "child module 1"
ECHO: "child module 2"
ECHO: "c module 2"
Note that the child assignments happen once only, before *anything* in
the parent runs, then the parent assignments, then the parent module
invocations, including the child modules once for each children() call.
In 2023.09.25:
ECHO: "c assignment 1"
ECHO: "c assignment 2"
ECHO: "c module 1"
ECHO: "child assignment 1"
ECHO: "child assignment 2"
ECHO: "child module 1"
ECHO: "child module 2"
ECHO: "child assignment 1"
ECHO: "child assignment 2"
ECHO: "child module 1"
ECHO: "child module 2"
ECHO: "c module 2"
The parent assignments are now first, then parent modules, and for each
children() call you get the child assignments and then the child modules.
The new behavior is still strange compared to conventional languages,
but it's less strange than the old behavior, notably with respect to $
variables set in the parent.