discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

why not a warning?

RW
Raymond West
Thu, Oct 31, 2024 10:16 AM

module test(){
cube(50);
cube(10);
}

difference()test();

module test(){ cube(50); cube(10); } difference()test();
NH
nop head
Thu, Oct 31, 2024 10:36 AM

Because difference() with one child is useful when the second child is
conditional.

So you can do

difference() {
cube(50);
if(something)
cube(10);
}

Instead of

if(something)
difference() {
cube(50);
cube(10);
}
else
cube(50);

On Thu, 31 Oct 2024 at 10:16, Raymond West via Discuss <
discuss@lists.openscad.org> wrote:

module test(){
cube(50);
cube(10);
}

difference()test();


OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org

Because difference() with one child is useful when the second child is conditional. So you can do difference() { cube(50); if(something) cube(10); } Instead of if(something) difference() { cube(50); cube(10); } else cube(50); On Thu, 31 Oct 2024 at 10:16, Raymond West via Discuss < discuss@lists.openscad.org> wrote: > module test(){ > cube(50); > cube(10); > } > > difference()test(); > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
RW
Rogier Wolff
Thu, Oct 31, 2024 12:36 PM

On Thu, Oct 31, 2024 at 10:16:16AM +0000, Raymond West via Discuss wrote:

module test(){
cube(50);
cube(10);
}

difference()test();

Because
module test(){
cube(50);
translate ([-1,-1,-1]) cube(10);
}

difference() {
test();
if (0) cylinder (d=10,h=51);
}

is a very valid program, and to the parser looks very similar to what
you had.

Roger. 

--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
f equals m times a. When your f is steady, and your m is going down
your a** is going up.  -- Chris Hadfield about flying up the space shuttle.
**  'a' for accelleration.

On Thu, Oct 31, 2024 at 10:16:16AM +0000, Raymond West via Discuss wrote: > module test(){ > cube(50); > cube(10); > } > > difference()test(); Because module test(){ cube(50); translate ([-1,-1,-1]) cube(10); } difference() { test(); if (0) cylinder (d=10,h=51); } is a very valid program, and to the parser looks very similar to what you had. Roger. -- ** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 ** ** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 ** f equals m times a. When your f is steady, and your m is going down your a** is going up. -- Chris Hadfield about flying up the space shuttle. ** 'a' for accelleration.
RW
Raymond West
Thu, Oct 31, 2024 2:01 PM

On 31/10/2024 12:36, Rogier Wolff via Discuss wrote:

On Thu, Oct 31, 2024 at 10:16:16AM +0000, Raymond West via Discuss wrote:

module test(){
cube(50);
cube(10);
}

difference()test();

Because
module test(){
cube(50);
translate ([-1,-1,-1]) cube(10);
}

difference() {
test();
if (0) cylinder (d=10,h=51);
}

is a very valid program, and to the parser looks very similar to what
you had.

Thanks. the test module has unioned the two cubes, and it is then
unwindable outside of the module, of course... But the way it was written,
it looked to me that they should have been differenced. Maybe I need
more or less coffee.

On 31/10/2024 12:36, Rogier Wolff via Discuss wrote: > On Thu, Oct 31, 2024 at 10:16:16AM +0000, Raymond West via Discuss wrote: >> module test(){ >> cube(50); >> cube(10); >> } >> >> difference()test(); > Because > module test(){ > cube(50); > translate ([-1,-1,-1]) cube(10); > } > > difference() { > test(); > if (0) cylinder (d=10,h=51); > } > > is a very valid program, and to the parser looks very similar to what > you had. Thanks. the test module has unioned the two cubes, and it is then unwindable outside of the module, of course... But the way it was written, it looked to me that they should have been differenced. Maybe I need more or less coffee.
RW
Raymond West
Thu, Oct 31, 2024 2:10 PM

Thanks. I'd forgotten? that items were not passed from modules. The way
I had it written, I expected it to difference the two cubes, then
realised it couldn't, so thought at least a warning would be generated.

On 31/10/2024 10:36, nop head via Discuss wrote:

Because difference() with one child is useful when the second child is
conditional.

So you can do

difference() {
   cube(50);
   if(something)
      cube(10);
}

Instead of

if(something)
    difference() {
        cube(50);
        cube(10);
    }
else
     cube(50);

On Thu, 31 Oct 2024 at 10:16, Raymond West via Discuss
discuss@lists.openscad.org wrote:

 module test(){
 cube(50);
 cube(10);
 }

 difference()test();
 _______________________________________________
 OpenSCAD mailing list
 To unsubscribe send an email to discuss-leave@lists.openscad.org

OpenSCAD mailing list
To unsubscribe send an email todiscuss-leave@lists.openscad.org

Thanks. I'd forgotten? that items were not passed from modules. The way I had it written, I expected it to difference the two cubes, then realised it couldn't, so thought at least a warning would be generated. On 31/10/2024 10:36, nop head via Discuss wrote: > Because difference() with one child is useful when the second child is > conditional. > > So you can do > > difference() { >    cube(50); >    if(something) >       cube(10); > } > > Instead of > > if(something) >     difference() { >         cube(50); >         cube(10); >     } > else >      cube(50); > > > > > On Thu, 31 Oct 2024 at 10:16, Raymond West via Discuss > <discuss@lists.openscad.org> wrote: > > module test(){ > cube(50); > cube(10); > } > > difference()test(); > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email todiscuss-leave@lists.openscad.org
RW
Rogier Wolff
Thu, Oct 31, 2024 2:40 PM

On Thu, Oct 31, 2024 at 02:01:57PM +0000, Raymond West via Discuss wrote:

On 31/10/2024 12:36, Rogier Wolff via Discuss wrote:

On Thu, Oct 31, 2024 at 10:16:16AM +0000, Raymond West via Discuss wrote:

module test(){
cube(50);
cube(10);
}

difference()test();

Because
module test(){
cube(50);
translate ([-1,-1,-1]) cube(10);
}
difference() {
test();
if (0) cylinder (d=10,h=51);
}

is a very valid program, and to the parser looks very similar to what
you had.

Thanks. the test module has unioned the two cubes, and it is then
unwindable outside of the module, of course... But the way it was written,
it looked to me that they should have been differenced. Maybe I need
more or less coffee.

A choice that "openscad" has made is that a module always returns ONE
object, never a "list of objects". That's a decision that had to be
made at one point in time and as there are arguments going both ways
the choice is more or less arbitrary. A choice was made and due to
backwards compatibility it is hard-to-impossible to change. You'll
have to "memorize" the choice that was made and act
accordingly. That's the way it works.

I do think the right choice has been made: If I say have a module that
in the first implementation is just one call to an elementary shape,
but then gets refined to multiple shapes, the behaviour of programs
using this module would change dramatically. You get less "surprises"
this way.

example:
module roundedcube (size, r) cube (size);
standin implementation...
module roundedcube (size, r) hull () {....};
That's how I now implement it. But in the past I've done:
module roundedcube (size, r)
{
translate ([        r,r,0]) cylinder (r,h=size[2]);
translate ([size[0]-r,r,0]) cylinder (r,h=size[2]);
translate ([r,0,0]) cube ([size[0]-2r, 2r, size[2]]);
}
(for brevity currently only implementding bars that are
exactly 2*r in the Y direction). If the "other" choice had
been made, the third implementation would work quite differently.
Software-engineering dictates that callers shouldn't have to know
about the implementation details of what you're calling.

(about 40 years a go as a teenager without-access-to-a-computer I
wrote my first program I thought
x = 123
a = "x"
$a = 234

would work (= assign 234 to x). It doesn't. "That's just not the way
things work!" and everybody has such things memorized. Different
level,agreed, but same principle.)

Roger. 

--
** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 **
**    Delftechpark 11 2628 XJ  Delft, The Netherlands.  KVK: 27239233    **
f equals m times a. When your f is steady, and your m is going down
your a** is going up.  -- Chris Hadfield about flying up the space shuttle.
**  'a' for accelleration.

On Thu, Oct 31, 2024 at 02:01:57PM +0000, Raymond West via Discuss wrote: > > On 31/10/2024 12:36, Rogier Wolff via Discuss wrote: > > On Thu, Oct 31, 2024 at 10:16:16AM +0000, Raymond West via Discuss wrote: > > > module test(){ > > > cube(50); > > > cube(10); > > > } > > > > > > difference()test(); > > Because > > module test(){ > > cube(50); > > translate ([-1,-1,-1]) cube(10); > > } > > difference() { > > test(); > > if (0) cylinder (d=10,h=51); > > } > > > > is a very valid program, and to the parser looks very similar to what > > you had. > > Thanks. the test module has unioned the two cubes, and it is then > unwindable outside of the module, of course... But the way it was written, > it looked to me that they should have been differenced. Maybe I need > more or less coffee. A choice that "openscad" has made is that a module always returns ONE object, never a "list of objects". That's a decision that had to be made at one point in time and as there are arguments going both ways the choice is more or less arbitrary. A choice was made and due to backwards compatibility it is hard-to-impossible to change. You'll have to "memorize" the choice that was made and act accordingly. That's the way it works. I do think the right choice has been made: If I say have a module that in the first implementation is just one call to an elementary shape, but then gets refined to multiple shapes, the behaviour of programs using this module would change dramatically. You get less "surprises" this way. example: module roundedcube (size, r) cube (size); standin implementation... module roundedcube (size, r) hull () {....}; That's how I now implement it. But in the past I've done: module roundedcube (size, r) { translate ([ r,r,0]) cylinder (r,h=size[2]); translate ([size[0]-r,r,0]) cylinder (r,h=size[2]); translate ([r,0,0]) cube ([size[0]-2*r, 2*r, size[2]]); } (for brevity currently only implementding bars that are exactly 2*r in the Y direction). If the "other" choice had been made, the third implementation would work quite differently. Software-engineering dictates that callers shouldn't have to know about the implementation details of what you're calling. (about 40 years a go as a teenager without-access-to-a-computer I wrote my first program I thought x = 123 a = "x" $a = 234 would work (= assign 234 to x). It doesn't. "That's just not the way things work!" and everybody has such things memorized. Different level,agreed, but same principle.) Roger. -- ** R.E.Wolff@BitWizard.nl ** https://www.BitWizard.nl/ ** +31-15-2049110 ** ** Delftechpark 11 2628 XJ Delft, The Netherlands. KVK: 27239233 ** f equals m times a. When your f is steady, and your m is going down your a** is going up. -- Chris Hadfield about flying up the space shuttle. ** 'a' for accelleration.
JB
Jordan Brown
Thu, Oct 31, 2024 6:45 PM

On 10/31/2024 7:40 AM, Rogier Wolff via Discuss wrote:

A choice that "openscad" has made is that a module always returns ONE
object, never a "list of objects".

Yes, exactly.  Always one.  Never two or more.

Never zero.

In

difference() {
    cube();
    if (false) sphere();
}

the difference gets two children.

Well, at least in some sense. difference() certainly can see the
failing if.  Consider:

module countChildren() {
    echo ($children);
}

countChildren() {
    cube();
    if (false) sphere();
}

... prints 2.

However, difference() does magic that a user module can't do:  it
disregards children that in some sense generate no geometry. (It's
because people freaked out when echo() was considered to be a child -
which it is, for user modules.)  I think this is Bad, because it yields
difficult-to-understand results.

Quick, what will these generate?

difference() {
    if (false) cube();
    sphere();
}

module iftrue(b) {
    if (b) children();
}

difference() {
    iftrue(false) cube();
    sphere();
}

difference() {
        union();
        sphere();
}

start=1;  // won't let you do this with constants
end=0;
difference() {
        for (i=[start:1:end]) cube();
        sphere();
}

(No peeking.)

The answer is that the first generates a sphere, and the rest generate
nothing.

Anyhow, net, difference() could certainly warn if it had fewer than two
children, in the usual sense.  Using that test, it would not warn if
it had two failing ifs, or if it had two echoes, et cetera.

In fact, one can readily write a wrapper module with those semantics:

module safeDifference() {
    assert($children >= 2);
    difference() {
        children(0);
        children([1:$children-1]);
    }
}

Note that safeDifference() will treat everything as a "real" child: 
normal objects, empty objects, failing ifs, echoes, asserts, et cetera.

On 10/31/2024 7:40 AM, Rogier Wolff via Discuss wrote: > A choice that "openscad" has made is that a module always returns ONE > object, never a "list of objects". Yes, exactly.  Always one.  Never two or more. Never zero. In difference() { cube(); if (false) sphere(); } the difference gets two children. Well, at least in some sense. difference() certainly *can* see the failing if.  Consider: module countChildren() { echo ($children); } countChildren() { cube(); if (false) sphere(); } ... prints 2. However, difference() does magic that a user module can't do:  it disregards children that in some sense generate no geometry. (It's because people freaked out when echo() was considered to be a child - which it is, for user modules.)  I think this is Bad, because it yields difficult-to-understand results. Quick, what will these generate? difference() { if (false) cube(); sphere(); } module iftrue(b) { if (b) children(); } difference() { iftrue(false) cube(); sphere(); } difference() { union(); sphere(); } start=1; // won't let you do this with constants end=0; difference() { for (i=[start:1:end]) cube(); sphere(); } (No peeking.) The answer is that the first generates a sphere, and the rest generate nothing. Anyhow, net, difference() could certainly warn if it had fewer than two children, in the usual sense.  Using that test, it would *not* warn if it had two failing ifs, or if it had two echoes, et cetera. In fact, one can readily write a wrapper module with those semantics: module safeDifference() {     assert($children >= 2);     difference() {         children(0);         children([1:$children-1]);     } } Note that safeDifference() will treat everything as a "real" child:  normal objects, empty objects, failing ifs, echoes, asserts, et cetera.