discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

is color an actual operator module ?

AM
Adrian Mariano
Thu, Jul 31, 2025 11:41 PM

First a few comments on your language.  In three you talk about "calling
children()".  Well, "children()" is a module that you can call any place a
module is allowed.  Another module can call it many times, and it need not
be at the end of anything.  Maybe you meant "children".

Another problem with the language is that modules may "call" other modules,
including children(), but they do that within the module definition, which
is not available to us for built-in modules.  When you are using a module
you write the modules name and then you give it a list of children, in
braces if there are more than one.  I would not describe this relationship
as "the module calling" the children.  It's more like the module "has"
children.  They are there for the module to use, which is can do any number
of times.    Also if you have an expression like

color("red")
translate([0,3,0])
sphere(r=4);

then color() is the first module.  It has one child which is
"translate([0.3,0])sphere(r=4)".  The notion that the child (children?) is
somehow last is mistaken.  Every module not followed immediately by a ";"
character has children.  Furthermore, you don't seem to be clearly
acknowledging that there might be more than 1 child.  For example:

color("red") { cube(5); translate([0,3,0]) sphere(r=4);}

Now the color module has 2 children.  Again, nothing is "called" they are
simply the children provided to the color module.

The problem is that your "real terms" aren't right because a module can
both draw geometry and call children.  Consider:

module both(size)
{
right(size*1.5) children();
cube(size);
}

both(10) sphere(4);

It draws a shape but also it acts on its children.  And both() can appear
anywhere in what you're calling a statement.  Based on your list it fails
2 because it can call children and it fails 3 because it need not call
children.  So it doesn't fit in your classification.  If your goal is to
classify ONLY the built-in modules in native OpenSCAD without any broader
applicability (no libraries or user written code) then I think it does
cover the (currently) available modules, but it's not fully general and it
also doesn't cover modules found in libraries or the range of what can be
written.  In other words, it's not a fundamental characteristic of modules
but more like a pragmatic division of the native modules.

In the BOSL2 library, for example, the cuboid() module draws geometry and
can be invoked without children, but it also optionally accepts children
and runs them.  There are very few modules in BOSL2 that satisfy condition
2 on your list because almost everything that creates geometry also accepts
children, and furthermore, BOSL2 redefines most of the native modules to
match BOSL2's general behavior.

So in BOSL2:

include<BOSL2/std.scad>
cuboid(10) attach(RIGHT,BOT) cyl(r=5,h=10);

produces this:
[image: image.png]

On Thu, Jul 31, 2025 at 7:02 PM vulcan_--- via Discuss <
discuss@lists.openscad.org> wrote:

while the underlying implementation may be the same for Operator Modules
and Object Modules in practice the differences are critical.

If one defines an Object Module it results in one or more shapes being
drawn. An Operator Module must end with a call to children() and cannot
itself draw shapes.

An operator at the end of a statement causes no error nor warning, but
also does nothing. .. at least in the 2025.07.20 i am using

An object can only be at the end of a statement .. sort of

color("red")
cube(5)
translate([0,3,0])
;

this will run but emits a warning: WARNING: module cube() does not support
child modules …

but it does draw the cube

This also draws the cube, with the warning, but does not draw the second
object, the sphere()

color("red")
cube(5)
translate([0,3,0])
sphere(r=4);

So in real terms, there are

1.

functions that return a value, can only be used in expressions, and
cannot draw geometry
2.

modules that draw geometry, must come last in a statement, and cannot
call children()
3.

modules that operate on objects can only call other operator modules
and must call children() as their last statement

and i have documented all of this after quite a lot of experimentation to
be sure i was writing true things about modules

If you folks can correct my understanding of modules where i might be in
error i would appreciate it so i can update the docs

thanks


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

First a few comments on your language. In three you talk about "calling children()". Well, "children()" is a module that you can call any place a module is allowed. Another module can call it many times, and it need not be at the end of anything. Maybe you meant "children". Another problem with the language is that modules may "call" other modules, including children(), but they do that within the module definition, which is not available to us for built-in modules. When you are using a module you write the modules name and then you give it a list of children, in braces if there are more than one. I would not describe this relationship as "the module calling" the children. It's more like the module "has" children. They are there for the module to use, which is can do any number of times. Also if you have an expression like color("red") translate([0,3,0]) sphere(r=4); then color() is the first module. It has one child which is "translate([0.3,0])sphere(r=4)". The notion that the child (children?) is somehow last is mistaken. Every module not followed immediately by a ";" character has children. Furthermore, you don't seem to be clearly acknowledging that there might be more than 1 child. For example: color("red") { cube(5); translate([0,3,0]) sphere(r=4);} Now the color module has 2 children. Again, nothing is "called" they are simply the children provided to the color module. The problem is that your "real terms" aren't right because a module can both draw geometry and call children. Consider: module both(size) { right(size*1.5) children(); cube(size); } both(10) sphere(4); It draws a shape but also it acts on its children. And both() can appear anywhere in what you're calling a statement. Based on your list it fails 2 because it can call children and it fails 3 because it need not call children. So it doesn't fit in your classification. If your goal is to classify ONLY the built-in modules in native OpenSCAD without any broader applicability (no libraries or user written code) then I think it does cover the (currently) available modules, but it's not fully general and it also doesn't cover modules found in libraries or the range of what can be written. In other words, it's not a fundamental characteristic of modules but more like a pragmatic division of the native modules. In the BOSL2 library, for example, the cuboid() module draws geometry and can be invoked without children, but it also optionally accepts children and runs them. There are very few modules in BOSL2 that satisfy condition 2 on your list because almost everything that creates geometry also accepts children, and furthermore, BOSL2 redefines most of the native modules to match BOSL2's general behavior. So in BOSL2: include<BOSL2/std.scad> cuboid(10) attach(RIGHT,BOT) cyl(r=5,h=10); produces this: [image: image.png] On Thu, Jul 31, 2025 at 7:02 PM vulcan_--- via Discuss < discuss@lists.openscad.org> wrote: > while the underlying implementation may be the same for Operator Modules > and Object Modules in practice the differences are critical. > > If one defines an Object Module it results in one or more shapes being > drawn. An Operator Module must end with a call to children() and cannot > itself draw shapes. > > An operator at the end of a statement causes no error nor warning, but > also does nothing. .. at least in the 2025.07.20 i am using > > An object can *only* be at the end of a statement .. sort of > > color("red") > cube(5) > translate([0,3,0]) > ; > > this will run but emits a warning: WARNING: module cube() does not support > child modules … > > but it does draw the cube > > This also draws the cube, with the warning, but does not draw the second > object, the sphere() > > color("red") > cube(5) > translate([0,3,0]) > sphere(r=4); > > So in real terms, there are > > 1. > > functions that return a value, can only be used in expressions, and > cannot draw geometry > 2. > > modules that draw geometry, must come last in a statement, and cannot > call children() > 3. > > modules that operate on objects can only call other operator modules > and must call children() as their last statement > > and i have documented all of this after quite a lot of experimentation to > be sure i was writing true things about modules > > > If you folks can correct my understanding of modules where i might be in > error i would appreciate it so i can update the docs > > thanks > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
V
vulcan_@mac.com
Sat, Aug 2, 2025 10:20 PM

thanks Adrian, for the feedback and guidance.

i first want to check a few things with you :

from you n other comments my breadth of language is a bit jarring for the reader .. ok

  1. object is now reserved for things made by the object() function .. unless .. is that also a module pretending to be a function ??

  2. i will use shape as the generic term for anything drawn into the model as lines or surfaces, and thus will not use “geometry” except when talking about math shapes that are geometrical concepts

  3. drawn will now be the word for making lines and surfaces appear in the model

  4. rendering will be the word for processing the shapes in the model into a human visible form, be that preview, generating an image or exporting a file

  5. is children() a placeholder for the objects that the operator module will be applied to at run-time? OR is it a funky function? or is it more of an object module ? or is it another of the funky operators let(), assert() etc.?

Now the discussion for thread:

the term “call” or “calling“ is time honored tradition to use when one chunk of code (program, subroutine whatever) makes a reference to another chunk of code .. be called a function, subroutine or method soo .

if there is something really truly NOT correct about using the term calling then i will change my approach

BUT

the appearance of the thing is that an openSCAD script can “call” modules, be they user defined or built-in and can “call” functions in the process of evaluating an expression with exactly the same meaning from when FORTRAN allowed the definition of subroutines .. actually i write an un-truth .. subroutines were available from the time the 8008 processor was built with a “call <address>” microcode that pushed the registers onto the stack, jumped to the <address> to continue processing until the “return” microcode when the stack was popped to reload the registers and the program counter reset to the instruction

so, most / many/ some people reading the scad docs and example code (especially!) will see modules and functions being “called“ so i propose to keep using that language to describe code calling code

That said; your comment raises a really valuable point .. the effect of some modules is to create shapes that get placed into a hierarchy .. thus creating parent-child relationships between shapes that have no connection to their underlying math, nor when in the process of execution they got created.

To return to the syntactical issue for a sec, most people reading code that uses braces will see them as creating lexical scope .. which is also true in scad, right? variables defined inside of a brace pair are local to that scope.

IN ADDITION scad is preserving the state of special variables on the stack to allow them to do .. well, something pretty nifty but that i don’t really have my head around yet.

AND IN FURTHER ADDITION braces are creating another generation of children

first .. is this all true? pretty close? where am i still going wrong?

back to children and parents .. so i am now planning to revise my text on object module versus operator module to say that they are variations on the single underlying module thing in the code. But i still feel strongly that the conceptual separation of operator versus object will help people coming new to the language get their head’s around it.

That a module can BOTH draw shapes AND operate on child objects via a call to children() is almost irrelevant to most users. There was no mention of this in the docs before i got into them  .. uhh .. at least not that i saw .. i could have missed it. There have already been a few tiny but important details that did get mention, but in places a bit hidden away.

But even so .. this ability can be covered as an exception to the general usages of modules, specifically user-defined modules, as the vast majority of these will be Either making objects or Operating on objects. A few folks have said stuff about BOSL2 and they way they have extended scad .. which is all to the good .. but it is hard to program anything really complex in scad because the fundamentals of the language are quite difference .. but use the same syntax as C, Java etc … by which i mean the same operators, the concept of stored routines that you call by name, functions that return values to stand in for complex calculations .. sure looks similar ..

i am trying to help two groups of readers

  1. expert scad coders that need a language reference

  2. people coming to scad from other programming traditions n tech

thanks Adrian, for the feedback and guidance. i first want to check a few things with you : from you n other comments my breadth of language is a bit jarring for the reader .. ok 1. object is now reserved for things made by the object() function .. unless .. is that also a module pretending to be a function ?? 2. i will use shape as the generic term for anything drawn into the model as lines or surfaces, and thus will not use “geometry” except when talking about math shapes that are geometrical concepts 3. drawn will now be the word for making lines and surfaces appear in the model 4. rendering will be the word for processing the shapes in the model into a human visible form, be that preview, generating an image or exporting a file 5. is children() a placeholder for the objects that the operator module will be applied to at run-time? OR is it a funky function? or is it more of an object module ? or is it another of the funky operators let(), assert() etc.? Now the discussion for thread: the term “call” or “calling“ is time honored tradition to use when one chunk of code (program, subroutine whatever) makes a reference to another chunk of code .. be called a function, subroutine or method soo . if there is something really truly NOT correct about using the term calling then i will change my approach BUT the *appearance* of the thing is that an openSCAD script can “call” modules, be they user defined or built-in and can “call” functions in the process of evaluating an expression with exactly the same meaning from when FORTRAN allowed the definition of subroutines .. actually i write an un-truth .. subroutines were available from the time the 8008 processor was built with a “call <address>” microcode that pushed the registers onto the stack, jumped to the <address> to continue processing until the “return” microcode when the stack was popped to reload the registers and the program counter reset to the instruction so, most / many/ some people reading the scad docs and example code (especially!) will see modules and functions being “called“ so i propose to keep using that language to describe code calling code That said; your comment raises a really valuable point .. the *effect* of some modules is to create shapes that get placed into a hierarchy .. thus creating parent-child relationships between shapes that have no connection to their underlying math, nor when in the process of execution they got created. To return to the syntactical issue for a sec, most people reading code that uses braces will see them as creating lexical scope .. which is also true in scad, right? variables defined inside of a brace pair are local to that scope. IN ADDITION scad is preserving the state of special variables on the stack to allow them to do .. well, something pretty nifty but that i don’t really have my head around yet. AND IN FURTHER ADDITION braces are creating another generation of children first .. is this all true? pretty close? where am i still going wrong? back to children and parents .. so i am now planning to revise my text on object module versus operator module to say that they are variations on the single underlying module thing in the code. But i still feel strongly that the conceptual separation of operator versus object will help people coming new to the language get their head’s around it. That a module can BOTH draw shapes AND operate on child objects via a call to children() is almost irrelevant to most users. There was no mention of this in the docs before i got into them .. uhh .. at least not that i saw .. i could have missed it. There have already been a few tiny but important details that did get mention, but in places a bit hidden away. But even so .. this ability can be covered as an exception to the general usages of modules, specifically user-defined modules, as the vast majority of these will be Either making objects or Operating on objects. A few folks have said stuff about BOSL2 and they way they have extended scad .. which is all to the good .. but it is hard to program anything really complex in scad because the fundamentals of the language are quite difference .. but use the same syntax as C, Java etc … by which i mean the same operators, the concept of stored routines that you call by name, functions that return values to stand in for complex calculations .. sure looks similar .. i am trying to help two groups of readers 1. expert scad coders that need a language reference 2. people coming to scad from other programming traditions n tech
NH
nop head
Sat, Aug 2, 2025 10:51 PM

An example of a module that creates geometry and places children is a
washer in NopSCADlib that draws a washer but if it has a child it places it
on top. The child could be a screw or a nut or a second washer.

On Sat, 2 Aug 2025, 23:20 vulcan_--- via Discuss, <
discuss@lists.openscad.org> wrote:

thanks Adrian, for the feedback and guidance.

i first want to check a few things with you :

from you n other comments my breadth of language is a bit jarring for the
reader .. ok

1.

object is now reserved for things made by the object() function ..
unless .. is that also a module pretending to be a function ??
2.

i will use shape as the generic term for anything drawn into the model
as lines or surfaces, and thus will not use “geometry” except when talking
about math shapes that are geometrical concepts
3.

drawn will now be the word for making lines and surfaces appear in the
model
4.

rendering will be the word for processing the shapes in the model into
a human visible form, be that preview, generating an image or exporting a
file
5.

is children() a placeholder for the objects that the operator module
will be applied to at run-time? OR is it a funky function? or is it more of
an object module ? or is it another of the funky operators let(), assert()
etc.?

Now the discussion for thread:

the term “call” or “calling“ is time honored tradition to use when one
chunk of code (program, subroutine whatever) makes a reference to another
chunk of code .. be called a function, subroutine or method soo .

if there is something really truly NOT correct about using the term
calling then i will change my approach

BUT

the appearance of the thing is that an openSCAD script can “call”
modules, be they user defined or built-in and can “call” functions in the
process of evaluating an expression with exactly the same meaning from when
FORTRAN allowed the definition of subroutines .. actually i write an
un-truth .. subroutines were available from the time the 8008 processor was
built with a “call <address>” microcode that pushed the registers onto the
stack, jumped to the <address> to continue processing until the “return”
microcode when the stack was popped to reload the registers and the program
counter reset to the instruction

so, most / many/ some people reading the scad docs and example code
(especially!) will see modules and functions being “called“ so i propose to
keep using that language to describe code calling code

That said; your comment raises a really valuable point .. the effect of
some modules is to create shapes that get placed into a hierarchy .. thus
creating parent-child relationships between shapes that have no connection
to their underlying math, nor when in the process of execution they got
created.

To return to the syntactical issue for a sec, most people reading code
that uses braces will see them as creating lexical scope .. which is also
true in scad, right? variables defined inside of a brace pair are local to
that scope.

IN ADDITION scad is preserving the state of special variables on the stack
to allow them to do .. well, something pretty nifty but that i don’t really
have my head around yet.

AND IN FURTHER ADDITION braces are creating another generation of children

first .. is this all true? pretty close? where am i still going wrong?

back to children and parents .. so i am now planning to revise my text on
object module versus operator module to say that they are variations on the
single underlying module thing in the code. But i still feel strongly that
the conceptual separation of operator versus object will help people coming
new to the language get their head’s around it.

That a module can BOTH draw shapes AND operate on child objects via a call
to children() is almost irrelevant to most users. There was no mention of
this in the docs before i got into them .. uhh .. at least not that i saw
.. i could have missed it. There have already been a few tiny but important
details that did get mention, but in places a bit hidden away.

But even so .. this ability can be covered as an exception to the general
usages of modules, specifically user-defined modules, as the vast majority
of these will be Either making objects or Operating on objects. A few folks
have said stuff about BOSL2 and they way they have extended scad .. which
is all to the good .. but it is hard to program anything really complex in
scad because the fundamentals of the language are quite difference .. but
use the same syntax as C, Java etc … by which i mean the same operators,
the concept of stored routines that you call by name, functions that return
values to stand in for complex calculations .. sure looks similar ..

i am trying to help two groups of readers

1.

expert scad coders that need a language reference
2.

people coming to scad from other programming traditions n tech

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

An example of a module that creates geometry and places children is a washer in NopSCADlib that draws a washer but if it has a child it places it on top. The child could be a screw or a nut or a second washer. On Sat, 2 Aug 2025, 23:20 vulcan_--- via Discuss, < discuss@lists.openscad.org> wrote: > thanks Adrian, for the feedback and guidance. > > i first want to check a few things with you : > > from you n other comments my breadth of language is a bit jarring for the > reader .. ok > > 1. > > object is now reserved for things made by the object() function .. > unless .. is that also a module pretending to be a function ?? > 2. > > i will use shape as the generic term for anything drawn into the model > as lines or surfaces, and thus will not use “geometry” except when talking > about math shapes that are geometrical concepts > 3. > > drawn will now be the word for making lines and surfaces appear in the > model > 4. > > rendering will be the word for processing the shapes in the model into > a human visible form, be that preview, generating an image or exporting a > file > 5. > > is children() a placeholder for the objects that the operator module > will be applied to at run-time? OR is it a funky function? or is it more of > an object module ? or is it another of the funky operators let(), assert() > etc.? > > Now the discussion for thread: > > the term “call” or “calling“ is time honored tradition to use when one > chunk of code (program, subroutine whatever) makes a reference to another > chunk of code .. be called a function, subroutine or method soo . > > if there is something really truly NOT correct about using the term > calling then i will change my approach > > BUT > > the *appearance* of the thing is that an openSCAD script can “call” > modules, be they user defined or built-in and can “call” functions in the > process of evaluating an expression with exactly the same meaning from when > FORTRAN allowed the definition of subroutines .. actually i write an > un-truth .. subroutines were available from the time the 8008 processor was > built with a “call <address>” microcode that pushed the registers onto the > stack, jumped to the <address> to continue processing until the “return” > microcode when the stack was popped to reload the registers and the program > counter reset to the instruction > > so, most / many/ some people reading the scad docs and example code > (especially!) will see modules and functions being “called“ so i propose to > keep using that language to describe code calling code > > That said; your comment raises a really valuable point .. the *effect* of > some modules is to create shapes that get placed into a hierarchy .. thus > creating parent-child relationships between shapes that have no connection > to their underlying math, nor when in the process of execution they got > created. > > To return to the syntactical issue for a sec, most people reading code > that uses braces will see them as creating lexical scope .. which is also > true in scad, right? variables defined inside of a brace pair are local to > that scope. > > IN ADDITION scad is preserving the state of special variables on the stack > to allow them to do .. well, something pretty nifty but that i don’t really > have my head around yet. > > AND IN FURTHER ADDITION braces are creating another generation of children > > first .. is this all true? pretty close? where am i still going wrong? > > back to children and parents .. so i am now planning to revise my text on > object module versus operator module to say that they are variations on the > single underlying module thing in the code. But i still feel strongly that > the conceptual separation of operator versus object will help people coming > new to the language get their head’s around it. > > That a module can BOTH draw shapes AND operate on child objects via a call > to children() is almost irrelevant to most users. There was no mention of > this in the docs before i got into them .. uhh .. at least not that i saw > .. i could have missed it. There have already been a few tiny but important > details that did get mention, but in places a bit hidden away. > > But even so .. this ability can be covered as an exception to the general > usages of modules, specifically user-defined modules, as the vast majority > of these will be Either making objects or Operating on objects. A few folks > have said stuff about BOSL2 and they way they have extended scad .. which > is all to the good .. but it is hard to program anything really complex in > scad because the fundamentals of the language are quite difference .. but > use the same syntax as C, Java etc … by which i mean the same operators, > the concept of stored routines that you call by name, functions that return > values to stand in for complex calculations .. sure looks similar .. > > i am trying to help two groups of readers > > 1. > > expert scad coders that need a language reference > 2. > > people coming to scad from other programming traditions n tech > > > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
AM
Adrian Mariano
Sun, Aug 3, 2025 12:37 AM

Vulcan,

Let me note that I'm involved in the BOSL2 project, which consumes a lot of
my time and effort and I don't have time to deeply review your
documentation effort for OpenSCAD.  I know OpenSCAD well and almost never
refer to its manual, so I'm not exactly the audience.  I'm not sure why
expert coders would need a language reference.  I only need to occasionally
look up how search() works or other things like that, mainly because the
way search() works is ridiculous.

I do have a bit of a concern that you seem to be trying to (re)write the
OpenSCAD manual while having a somewhat shallow and incomplete
understanding of OpenSCAD.

I think you do not understand how modules are defined and how children
work.  It is absolutely incorrect to describe modules as "calling"
children, in my opinion.  The best word would be that children are
"passed".

Users can define modules in their code, they aren't just magical things
provided by the language.  A module defined by a user can call other
modules in the normal sense of "calling".  That looks like this:

module foo(input)
{
other_module(3*input);
}

In this example, the module foo() has called the module other_module().
You would invoke foo by writing "foo(17);" in your code, perhaps.  And we
can see that foo() makes no use of children.

If you have a module that uses children, perhaps bar(), then when you call
it, you might write this:

bar(24) child();

In this case, bar() is being run and given one child.  I maintain that bar
does not "call" the child in this construction.  The most standard way to
describe the relationship is that the child is PASSED to bar as a
parameter, but it's a different kind of parameter than a variable.  It's a
parameter which is geometry, or I guess what you want to call "shape".
(I'm not a great fan of "shape" because geometry can be several
shapes...but I'm also used to calling it geometry.  That's what we call it
in the BOSL2 manual.)  So the other way to invoke bar() with children is
this:

bar(24)
{
child1();
child2();
child3();
}

Here I have passed three children to bar().  Again, in this code, no
children have been "called".  The children are parameters which are
geometry (shape) instead of data and they are being passed into bar which
can use them or ignore them as it chooses.

Now within bar() I may want to use the children.  The way to do that is to
call the children() module.  This is an ordinary module that invokes all of
the children of the current module().  I guess in your language it "draws
the shape" of the children.  The bar() module can call children() never,
or once, or as many times as it likes, just like with any other kind of
parameter.  It can also do children(0) which "draws the shape" of the first
child, which I called child1() above.

It MAY be a useful taxonomy for the native modules to split them apart into
shape modules and operator modules.  I don't know.  But it's important to
be aware that this doesn't apply to ALL modules, only the native ones
currently in existence.  But this is kind of like saying that in the C
language functions can either return a computed value or they can print
output.  It's an incomplete taxonomy of what functions in C can do.

Another thing to consider here is that a beginning user will be using the
modules provided by native OpenSCAD.  But as the user advances just a bit
they will start writing their own modules which may or may not fit into the
above framework.  Writing your own modules is not some kind of advanced
thing---it's a basic approach for creating readable code.  And if the user
chooses to use libraries like BOSL2 or NopSCADlib they will encounter
modules in those libraries that do not fit into the above framework.  As
previously noted, in BOSL2 every module that "draws a shape" also accepts
children---with very few exceptions.  It's probably a better dichotomy if
you say that there are modules that REQUIRE children and then modules that
do NOT require children.  I suggest that if you present a classification
of module types, make sure it is complete, in the sense that it covers
every possible kind of module and then indicate that the NATIVE modules all
fit into just these two classes, whereas modules defined by libraries or
that you define yourself may fit into this or these other classes.

I have no clue what you mean about preserving the state of special
variables on a stack.

An open brace actually does NOT create a new scope when used in isolation.
You can see this by doing

a=3;
{
a=2;
echo(a);
}

If a new scope was created, this would run without warnings, but it gives a
reassignment warning when a=2 is assigned.  There was talk in the past of
making isolated braces invalid, actually.

If the braces are used to pass children to a parent, then they create a new
scope.  Hence this works:

a=3;
assert(true)
{
a=2;
echo(a);
}

Now the stuff in braces forms children to the assert() module and it
creates a new scope.  When you open a new scope like this all previously
existing variables are preserved, and new variables---which may have the
same name and hence hide the old ones---can be created in the new scope.
The same thing happens with let().  This can make it appear that you can
redefine variables, like above where I "redefined" a, but it only works
because the "redefinition" is in a new scope.

On Sat, Aug 2, 2025 at 6:20 PM vulcan_--- via Discuss <
discuss@lists.openscad.org> wrote:

thanks Adrian, for the feedback and guidance.

i first want to check a few things with you :

from you n other comments my breadth of language is a bit jarring for the
reader .. ok

1.

object is now reserved for things made by the object() function ..
unless .. is that also a module pretending to be a function ??
2.

i will use shape as the generic term for anything drawn into the model
as lines or surfaces, and thus will not use “geometry” except when talking
about math shapes that are geometrical concepts
3.

drawn will now be the word for making lines and surfaces appear in the
model
4.

rendering will be the word for processing the shapes in the model into
a human visible form, be that preview, generating an image or exporting a
file
5.

is children() a placeholder for the objects that the operator module
will be applied to at run-time? OR is it a funky function? or is it more of
an object module ? or is it another of the funky operators let(), assert()
etc.?

Now the discussion for thread:

the term “call” or “calling“ is time honored tradition to use when one
chunk of code (program, subroutine whatever) makes a reference to another
chunk of code .. be called a function, subroutine or method soo .

if there is something really truly NOT correct about using the term
calling then i will change my approach

BUT

the appearance of the thing is that an openSCAD script can “call”
modules, be they user defined or built-in and can “call” functions in the
process of evaluating an expression with exactly the same meaning from when
FORTRAN allowed the definition of subroutines .. actually i write an
un-truth .. subroutines were available from the time the 8008 processor was
built with a “call <address>” microcode that pushed the registers onto the
stack, jumped to the <address> to continue processing until the “return”
microcode when the stack was popped to reload the registers and the program
counter reset to the instruction

so, most / many/ some people reading the scad docs and example code
(especially!) will see modules and functions being “called“ so i propose to
keep using that language to describe code calling code

That said; your comment raises a really valuable point .. the effect of
some modules is to create shapes that get placed into a hierarchy .. thus
creating parent-child relationships between shapes that have no connection
to their underlying math, nor when in the process of execution they got
created.

To return to the syntactical issue for a sec, most people reading code
that uses braces will see them as creating lexical scope .. which is also
true in scad, right? variables defined inside of a brace pair are local to
that scope.

IN ADDITION scad is preserving the state of special variables on the stack
to allow them to do .. well, something pretty nifty but that i don’t really
have my head around yet.

AND IN FURTHER ADDITION braces are creating another generation of children

first .. is this all true? pretty close? where am i still going wrong?

back to children and parents .. so i am now planning to revise my text on
object module versus operator module to say that they are variations on the
single underlying module thing in the code. But i still feel strongly that
the conceptual separation of operator versus object will help people coming
new to the language get their head’s around it.

That a module can BOTH draw shapes AND operate on child objects via a call
to children() is almost irrelevant to most users. There was no mention of
this in the docs before i got into them .. uhh .. at least not that i saw
.. i could have missed it. There have already been a few tiny but important
details that did get mention, but in places a bit hidden away.

But even so .. this ability can be covered as an exception to the general
usages of modules, specifically user-defined modules, as the vast majority
of these will be Either making objects or Operating on objects. A few folks
have said stuff about BOSL2 and they way they have extended scad .. which
is all to the good .. but it is hard to program anything really complex in
scad because the fundamentals of the language are quite difference .. but
use the same syntax as C, Java etc … by which i mean the same operators,
the concept of stored routines that you call by name, functions that return
values to stand in for complex calculations .. sure looks similar ..

i am trying to help two groups of readers

1.

expert scad coders that need a language reference
2.

people coming to scad from other programming traditions n tech

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

Vulcan, Let me note that I'm involved in the BOSL2 project, which consumes a lot of my time and effort and I don't have time to deeply review your documentation effort for OpenSCAD. I know OpenSCAD well and almost never refer to its manual, so I'm not exactly the audience. I'm not sure why expert coders would need a language reference. I only need to occasionally look up how search() works or other things like that, mainly because the way search() works is ridiculous. I do have a bit of a concern that you seem to be trying to (re)write the OpenSCAD manual while having a somewhat shallow and incomplete understanding of OpenSCAD. I think you do not understand how modules are defined and how children work. It is absolutely incorrect to describe modules as "calling" children, in my opinion. The best word would be that children are "passed". Users can define modules in their code, they aren't just magical things provided by the language. A module defined by a user can call other modules in the normal sense of "calling". That looks like this: module foo(input) { other_module(3*input); } In this example, the module foo() has called the module other_module(). You would invoke foo by writing "foo(17);" in your code, perhaps. And we can see that foo() makes no use of children. If you have a module that uses children, perhaps bar(), then when you call it, you might write this: bar(24) child(); In this case, bar() is being run and given one child. I maintain that bar does not "call" the child in this construction. The most standard way to describe the relationship is that the child is PASSED to bar as a parameter, but it's a different kind of parameter than a variable. It's a parameter which is geometry, or I guess what you want to call "shape". (I'm not a great fan of "shape" because geometry can be several shapes...but I'm also used to calling it geometry. That's what we call it in the BOSL2 manual.) So the other way to invoke bar() with children is this: bar(24) { child1(); child2(); child3(); } Here I have passed three children to bar(). Again, in this code, no children have been "called". The children are parameters which are geometry (shape) instead of data and they are being passed into bar which can use them or ignore them as it chooses. Now within bar() I may want to use the children. The way to do that is to call the children() module. This is an ordinary module that invokes all of the children of the current module(). I guess in your language it "draws the shape" of the children. The bar() module can call children() never, or once, or as many times as it likes, just like with any other kind of parameter. It can also do children(0) which "draws the shape" of the first child, which I called child1() above. It MAY be a useful taxonomy for the native modules to split them apart into shape modules and operator modules. I don't know. But it's important to be aware that this doesn't apply to ALL modules, only the native ones currently in existence. But this is kind of like saying that in the C language functions can either return a computed value or they can print output. It's an incomplete taxonomy of what functions in C can do. Another thing to consider here is that a beginning user will be using the modules provided by native OpenSCAD. But as the user advances just a bit they will start writing their own modules which may or may not fit into the above framework. Writing your own modules is not some kind of advanced thing---it's a basic approach for creating readable code. And if the user chooses to use libraries like BOSL2 or NopSCADlib they will encounter modules in those libraries that do not fit into the above framework. As previously noted, in BOSL2 every module that "draws a shape" also accepts children---with very few exceptions. It's probably a better dichotomy if you say that there are modules that REQUIRE children and then modules that do NOT require children. I suggest that if you present a classification of module types, make sure it is complete, in the sense that it covers every possible kind of module and then indicate that the NATIVE modules all fit into just these two classes, whereas modules defined by libraries or that you define yourself may fit into this or these other classes. I have no clue what you mean about preserving the state of special variables on a stack. An open brace actually does NOT create a new scope when used in isolation. You can see this by doing a=3; { a=2; echo(a); } If a new scope was created, this would run without warnings, but it gives a reassignment warning when a=2 is assigned. There was talk in the past of making isolated braces invalid, actually. If the braces are used to pass children to a parent, then they create a new scope. Hence this works: a=3; assert(true) { a=2; echo(a); } Now the stuff in braces forms children to the assert() module and it creates a new scope. When you open a new scope like this all previously existing variables are preserved, and new variables---which may have the same name and hence hide the old ones---can be created in the new scope. The same thing happens with let(). This can make it appear that you can redefine variables, like above where I "redefined" a, but it only works because the "redefinition" is in a new scope. On Sat, Aug 2, 2025 at 6:20 PM vulcan_--- via Discuss < discuss@lists.openscad.org> wrote: > thanks Adrian, for the feedback and guidance. > > i first want to check a few things with you : > > from you n other comments my breadth of language is a bit jarring for the > reader .. ok > > 1. > > object is now reserved for things made by the object() function .. > unless .. is that also a module pretending to be a function ?? > 2. > > i will use shape as the generic term for anything drawn into the model > as lines or surfaces, and thus will not use “geometry” except when talking > about math shapes that are geometrical concepts > 3. > > drawn will now be the word for making lines and surfaces appear in the > model > 4. > > rendering will be the word for processing the shapes in the model into > a human visible form, be that preview, generating an image or exporting a > file > 5. > > is children() a placeholder for the objects that the operator module > will be applied to at run-time? OR is it a funky function? or is it more of > an object module ? or is it another of the funky operators let(), assert() > etc.? > > Now the discussion for thread: > > the term “call” or “calling“ is time honored tradition to use when one > chunk of code (program, subroutine whatever) makes a reference to another > chunk of code .. be called a function, subroutine or method soo . > > if there is something really truly NOT correct about using the term > calling then i will change my approach > > BUT > > the *appearance* of the thing is that an openSCAD script can “call” > modules, be they user defined or built-in and can “call” functions in the > process of evaluating an expression with exactly the same meaning from when > FORTRAN allowed the definition of subroutines .. actually i write an > un-truth .. subroutines were available from the time the 8008 processor was > built with a “call <address>” microcode that pushed the registers onto the > stack, jumped to the <address> to continue processing until the “return” > microcode when the stack was popped to reload the registers and the program > counter reset to the instruction > > so, most / many/ some people reading the scad docs and example code > (especially!) will see modules and functions being “called“ so i propose to > keep using that language to describe code calling code > > That said; your comment raises a really valuable point .. the *effect* of > some modules is to create shapes that get placed into a hierarchy .. thus > creating parent-child relationships between shapes that have no connection > to their underlying math, nor when in the process of execution they got > created. > > To return to the syntactical issue for a sec, most people reading code > that uses braces will see them as creating lexical scope .. which is also > true in scad, right? variables defined inside of a brace pair are local to > that scope. > > IN ADDITION scad is preserving the state of special variables on the stack > to allow them to do .. well, something pretty nifty but that i don’t really > have my head around yet. > > AND IN FURTHER ADDITION braces are creating another generation of children > > first .. is this all true? pretty close? where am i still going wrong? > > back to children and parents .. so i am now planning to revise my text on > object module versus operator module to say that they are variations on the > single underlying module thing in the code. But i still feel strongly that > the conceptual separation of operator versus object will help people coming > new to the language get their head’s around it. > > That a module can BOTH draw shapes AND operate on child objects via a call > to children() is almost irrelevant to most users. There was no mention of > this in the docs before i got into them .. uhh .. at least not that i saw > .. i could have missed it. There have already been a few tiny but important > details that did get mention, but in places a bit hidden away. > > But even so .. this ability can be covered as an exception to the general > usages of modules, specifically user-defined modules, as the vast majority > of these will be Either making objects or Operating on objects. A few folks > have said stuff about BOSL2 and they way they have extended scad .. which > is all to the good .. but it is hard to program anything really complex in > scad because the fundamentals of the language are quite difference .. but > use the same syntax as C, Java etc … by which i mean the same operators, > the concept of stored routines that you call by name, functions that return > values to stand in for complex calculations .. sure looks similar .. > > i am trying to help two groups of readers > > 1. > > expert scad coders that need a language reference > 2. > > people coming to scad from other programming traditions n tech > > > > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jon Bondy
Sun, Aug 3, 2025 1:22 AM

I share this concern.  I welcome your helpful participation, but worry
that the result may require a lot of re-work.

On 8/2/2025 8:37 PM, Adrian Mariano via Discuss wrote:

I do have a bit of a concern that you seem to be trying to (re)write
the OpenSCAD manual while having a somewhat shallow and incomplete
understanding of OpenSCAD.

--
This email has been checked for viruses by AVG antivirus software.
www.avg.com

I share this concern.  I welcome your helpful participation, but worry that the result may require a lot of re-work. On 8/2/2025 8:37 PM, Adrian Mariano via Discuss wrote: > > I do have a bit of a concern that you seem to be trying to (re)write > the OpenSCAD manual while having a somewhat shallow and incomplete > understanding of OpenSCAD. > > -- This email has been checked for viruses by AVG antivirus software. www.avg.com
JB
Jordan Brown
Sun, Aug 3, 2025 6:10 PM

[ Sigh.  I hate being away from my desktop environment.  Sorry for the
duplicate. ]

On 8/2/2025 3:20 PM, vulcan_--- via Discuss wrote:

object is now reserved for things made by the object() function ..
unless .. is that also a module pretending to be a function ??

Modules are modules and functions are functions.  There is no such thing
as one pretending to be the other.

object() is a function, period.

rendering will be the word for processing the shapes in the model into
a human visible form, be that preview, generating an image or
exporting a file

No, absolutely not.  The word "render" is well-defined in OpenSCAD to
refer to the process of reducing a model to a mesh. It most specifically
does not refer to the process of previewing a model.  Yes, abstractly
that is a form of rendering, but it is not what the word means in OpenSCAD.

is children() a placeholder for the objects that the operator module
will be applied to at run-time? OR is it a funky function? or is it
more of an object module ? or is it another of the funky operators
let(), assert() etc.?

children() is a module that invokes the operations that were passed to
the current module as its children.

As previously discussed, "operator module" and "object module" are a
false dichotomy, perhaps useful as a simple mental distinction but not
useful for formally describing OpenSCAD modules.  OpenSCAD modules may
accept zero or more children.  They may add shapes of their own, or they
may not.  They always yield a shape, though that shape may be empty. 
children() does not neatly fall into either the "operator" or "object"
classification, because it does not accept children, and does not
produce shapes of its own; it invokes the children of the current module
instantiation.

There are only three "funky operators" - let, echo, and assert - and
they only apply in expression context, just as operators like + and -
only apply in expression context.

[ "calling" ]

The debate is over what to call the relationship between A and B in

A() B();

It is formally not correct to say that that line calls B.  Nor is it
truly correct to say that A calls B.  That line calls A, which might or
might not ... invoke ... the following statement that then calls B.

But how to say that in a way that is both technically correct and is
accessible to a newbie is difficult.

actually i write an un-truth .. subroutines were available from the
time the 8008 processor was built with a “call <address>” microcode

Long, long before that.  8008 is 1970s; FORTRAN is 1950s.  I don't know
what's before that, but something is.

That said; your comment raises a really valuable point .. the /effect/
of some modules is to create shapes that get placed into a hierarchy
.. thus creating parent-child relationships between shapes that have
no connection to their underlying math, nor when in the process of
execution they got created.

Actually, the resulting CSG tree is pretty closely tied to the execution
process.

To return to the syntactical issue for a sec, most people reading code
that uses braces will see them as creating lexical scope .. which is
also true in scad, right? variables defined inside of a brace pair are
local to that scope.

Not exactly.  It's really the parent module invocation that creates the
scope.  Braces by themselves do not create scopes (sigh).

It's a little hard to see this, but let() and for() demonstrate it; they
create a scope without needing braces to do it.

IN ADDITION scad is preserving the state of special variables on the
stack to allow them to do .. well, something pretty nifty but that i
don’t really have my head around yet.

$ variables are accessible to the scope that creates them and to all
scopes called by that scope.

AND IN FURTHER ADDITION braces are creating another generation of
children

No.  Braces do not themselves create children.  Braces group children. 
If you have only one child, braces are not required.

A() { B(); }

is exactly equivalent to

A() B();

That a module can BOTH draw shapes AND operate on child objects via a
call to children() is almost irrelevant to most users.

Increasingly untrue.  These days, pretty much as soon as somebody asks a
tricky question, the answer is "go look at BOSL2, it solves that
problem"... and for BOSL2, modules that create shapes and operate on
their children are almost universal.

There was no mention of this in the docs before i got into them .. uhh
.. at least not that i saw .. i could have missed it. There have
already been a few tiny but important details that did get mention,
but in places a bit hidden away.

The core set of modules doesn't include any that create shapes and
consume children.

That only arises from the implications of children(), that there is no
reason that you can't create shapes from a module that also calls
children().

but it is hard to program anything really complex in scad because the
fundamentals of the language are quite difference

I suppose that it depends on your definition of "hard", but I think
there are at least hundreds of thousands of lines of OpenSCAD programs
that would disagree.  (I mean, I can account for over over 10K in one
project alone, and BOSL2 is 77K...)

Is it different?  Sure.  And some aspects are really tricky, probably
trickier than other languages.  But you can do something moderately
complex without needing to explore the dark corners.

Writing documentation, on the other hand, is hard, because it needs to
both correctly describe those dark corners and be accessible to
beginners.  I think the answer to that is what's sometimes called
"progressive disclosure", where you present a simplified view, and then
introduce more advanced concepts as the user progresses.

That's pretty straightforward for tutorial matter, where you control the
intended order that the user reads the documentation. It's harder for
reference material, where you don't know in advance how deep the user
wants to go.  But even then you can take care to use language that is
simple but formally correct, and to introduce simpler aspects of a
particular topic before more advanced aspects.

Some documentation I read once - I dimly think it was the TeX manual -
specifically said in its introduction that it would lie to you, that it
would give you an incorrect but simplified and useful view of a topic,
and then would later correct it with more advanced concepts.  I think
that's a useful model.

i am trying to help two groups of readers

 expert scad coders that need a language reference
 people coming to scad from other programming traditions n tech

Mostly, group 1 doesn't look at the documentation because they already
have everything in their head.

But also there's group 3:  non-programmers.  They form a significant
fraction of the user base.

Many of the concepts in this discussion, especially those around the
"child" relationship, are easier to talk about if you talk about lambda
functions... but those are a fairly advanced programming concept that
you don't really need to get into as a beginner; you can use the
mechanisms without needing to dive into that level of detail.

[ Going dark for a couple of days, en route from Scotland to Iceland. ]

[ Sigh.  I hate being away from my desktop environment.  Sorry for the duplicate. ] On 8/2/2025 3:20 PM, vulcan_--- via Discuss wrote: > > object is now reserved for things made by the object() function .. > unless .. is that also a module pretending to be a function ?? > Modules are modules and functions are functions.  There is no such thing as one pretending to be the other. object() is a function, period. > rendering will be the word for processing the shapes in the model into > a human visible form, be that preview, generating an image or > exporting a file > No, absolutely not.  The word "render" is well-defined in OpenSCAD to refer to the process of reducing a model to a mesh. It most specifically does *not* refer to the process of previewing a model.  Yes, abstractly that is a form of rendering, but it is not what the word means in OpenSCAD. > is children() a placeholder for the objects that the operator module > will be applied to at run-time? OR is it a funky function? or is it > more of an object module ? or is it another of the funky operators > let(), assert() etc.? > children() is a module that invokes the operations that were passed to the current module as its children. As previously discussed, "operator module" and "object module" are a false dichotomy, perhaps useful as a simple mental distinction but not useful for formally describing OpenSCAD modules.  OpenSCAD modules may accept zero or more children.  They may add shapes of their own, or they may not.  They always yield a shape, though that shape may be empty.  children() does not neatly fall into either the "operator" or "object" classification, because it does not accept children, and does not produce shapes of its own; it invokes the children of the current module instantiation. There are only three "funky operators" - let, echo, and assert - and they only apply in expression context, just as operators like + and - only apply in expression context. > [ "calling" ] > The debate is over what to call the relationship between A and B in A() B(); It is formally *not* correct to say that that line calls B.  Nor is it truly correct to say that A calls B.  That line calls A, which might or might not ... invoke ... the following statement that then calls B. But how to say that in a way that is both technically correct and is accessible to a newbie is difficult. > actually i write an un-truth .. subroutines were available from the > time the 8008 processor was built with a “call <address>” microcode > Long, long before that.  8008 is 1970s; FORTRAN is 1950s.  I don't know what's before that, but something is. > That said; your comment raises a really valuable point .. the /effect/ > of some modules is to create shapes that get placed into a hierarchy > .. thus creating parent-child relationships between shapes that have > no connection to their underlying math, nor when in the process of > execution they got created. > Actually, the resulting CSG tree is pretty closely tied to the execution process. > To return to the syntactical issue for a sec, most people reading code > that uses braces will see them as creating lexical scope .. which is > also true in scad, right? variables defined inside of a brace pair are > local to that scope. > Not exactly.  It's really the parent module invocation that creates the scope.  Braces by themselves do *not* create scopes (sigh). It's a little hard to see this, but let() and for() demonstrate it; they create a scope without needing braces to do it. > IN ADDITION scad is preserving the state of special variables on the > stack to allow them to do .. well, something pretty nifty but that i > don’t really have my head around yet. > $ variables are accessible to the scope that creates them and to all scopes called by that scope. > AND IN FURTHER ADDITION braces are creating another generation of > children > No.  Braces do not themselves create children.  Braces group children.  If you have only one child, braces are not required. A() { B(); } is exactly equivalent to A() B(); > That a module can BOTH draw shapes AND operate on child objects via a > call to children() is almost irrelevant to most users. > Increasingly untrue.  These days, pretty much as soon as somebody asks a tricky question, the answer is "go look at BOSL2, it solves that problem"... and for BOSL2, modules that create shapes *and* operate on their children are almost universal. > There was no mention of this in the docs before i got into them .. uhh > .. at least not that i saw .. i could have missed it. There have > already been a few tiny but important details that did get mention, > but in places a bit hidden away. > The core set of modules doesn't include any that create shapes *and* consume children. That only arises from the implications of children(), that there is no reason that you can't create shapes from a module that also calls children(). > but it is hard to program anything really complex in scad because the > fundamentals of the language are quite difference > I suppose that it depends on your definition of "hard", but I think there are at least hundreds of thousands of lines of OpenSCAD programs that would disagree.  (I mean, I can account for over over 10K in one project alone, and BOSL2 is 77K...) Is it *different*?  Sure.  And some aspects are really tricky, probably trickier than other languages.  But you can do something moderately complex without needing to explore the dark corners. Writing documentation, on the other hand, is hard, because it needs to both correctly describe those dark corners *and* be accessible to beginners.  I think the answer to that is what's sometimes called "progressive disclosure", where you present a simplified view, and then introduce more advanced concepts as the user progresses. That's pretty straightforward for tutorial matter, where you control the intended order that the user reads the documentation. It's harder for reference material, where you don't know in advance how deep the user wants to go.  But even then you can take care to use language that is simple but formally correct, and to introduce simpler aspects of a particular topic before more advanced aspects. Some documentation I read once - I dimly think it was the TeX manual - specifically said in its introduction that it would lie to you, that it would give you an incorrect but simplified and useful view of a topic, and then would later correct it with more advanced concepts.  I think that's a useful model. > i am trying to help two groups of readers > > 1. > > expert scad coders that need a language reference > > 2. > > people coming to scad from other programming traditions n tech > Mostly, group 1 doesn't look at the documentation because they already have everything in their head. But also there's group 3:  non-programmers.  They form a significant fraction of the user base. Many of the concepts in this discussion, especially those around the "child" relationship, are easier to talk about if you talk about lambda functions... but those are a fairly advanced programming concept that you don't really need to get into as a beginner; you can use the mechanisms without needing to dive into that level of detail. [ Going dark for a couple of days, en route from Scotland to Iceland. ]
V
vulcan_@mac.com
Tue, Aug 5, 2025 9:39 PM

HI Jordan .. i know it will be a while before you see this, but i wanted to reply to one small issue you raised

No, absolutely not.  The word "render" is well-defined in OpenSCAD to
refer to the process of reducing a model to a mesh. It most specifically
does not refer to the process of previewing a model.  Yes, abstractly
that is a form of rendering, but it is not what the word means in OpenSCAD.

ah .. that scad assigns that specific meaning to “render” was not made clear to my until i read your message just now.

You know that my use of render, to process a model to create an image, is the standard use in the industry, yes?

In my experience the operation of making a polygonal version of the shapes in a model is “tessellation“

I did note that the terms, if you will, of “F5” and “F6” in the documentation seemed to carry more weight than just to indicate which function key to press. But after using them both i concluded that “F6” was a short form for “tessellation“ as its operation is to divide any face with more than 3 edges into triangles.

I have learned that the result of running an scad script is a mesh .. but, at least for primitives, drawn in n-gons .. so the term rendering does not seem to apply, to me. But i bow to the linguistic convention of the group.

er .. i hope that my readers understand that i am not being facetious saying this .. my career was based on my being able to establish good communications between my teams and those around us, and within the teams themselves, by creating and promoting language specific to each project and its corporate environment.

That was what i did in every job, so i am doing it here too

HI Jordan .. i know it will be a while before you see this, but i wanted to reply to one small issue you raised > No, absolutely not.  The word "render" is well-defined in OpenSCAD to \ > refer to the process of reducing a model to a mesh. It most specifically \ > does *not* refer to the process of previewing a model.  Yes, abstractly \ > that is a form of rendering, but it is not what the word means in OpenSCAD. ah .. that scad assigns that specific meaning to “render” was not made clear to my until i read your message just now. You know that my use of render, to process a model to create an image, is the standard use in the industry, yes? In my experience the operation of making a polygonal version of the shapes in a model is “tessellation“ I did note that the terms, if you will, of “F5” and “F6” in the documentation seemed to carry more weight than just to indicate which function key to press. But after using them both i concluded that “F6” was a short form for “tessellation“ as its operation is to divide any face with more than 3 edges into triangles. I have learned that the result of running an scad script is a mesh .. but, at least for primitives, drawn in n-gons .. so the term rendering does not seem to apply, to me. But i bow to the linguistic convention of the group. er .. i hope that my readers understand that i am not being facetious saying this .. my career was based on my being able to establish good communications between my teams and those around us, and within the teams themselves, by creating and promoting language specific to each project and its corporate environment. That was what i did in every job, so i am doing it here too
V
vulcan_@mac.com
Tue, Aug 5, 2025 9:50 PM

and .. this one

OpenSCAD modules may
accept zero or more children.  They may add shapes of their own, or they
may not.  They always yield a shape, though that shape may be empty. 

First, .. what is an “empty shape“ ?

on the face of it that makes little sense. If there is nothing displayed in the preview there was no mesh made, right?

I do get, now, that a module may create shape(s) itself, or be a parent to children that may create shapes. And that a module might perform only operations like color(), translate(), assert() and the like, thus defining what i have been calling an operator module, does not create any mesh, though its children might

so how can a module always yield a shape?

and .. this one > OpenSCAD modules may \ > accept zero or more children.  They may add shapes of their own, or they \ > may not.  They always yield a shape, though that shape may be empty.  First, .. what is an “empty shape“ ? on the face of it that makes little sense. If there is nothing displayed in the preview there was no mesh made, right? I do get, now, that a module may create shape(s) itself, or be a parent to children that may create shapes. And that a module might perform only operations like color(), translate(), assert() and the like, thus defining what i have been calling an operator module, does not create any mesh, though its children might so how can a module *always* yield a shape?
V
vulcan_@mac.com
Tue, Aug 5, 2025 10:05 PM

i hope to get to alignment on terminology with respect to the roles of functions and modules in a scad.

in this statement:

xx = do_something( 12 );

        ^ this is a call to a function, there are no children

do_operation() make_shape();

  ^ this and       ^  this are both calls to modules

 ^ this is the parent of ^ this child, by the syntax of it following the call to `do_operation()`

I am using the terms “call” and “calling“ to refer to the execution of a module during the execution of a script, which is industry standard as far as i know.

What was not clear to me was that a sequence of module calls in a single statement is the syntax for defining a nested parent-child shape that will be “rendered” as a mesh as a part of the model the script is drawing. But now it is and i am updating the docs to express my improved understanding

i hope to get to alignment on terminology with respect to the roles of functions and modules in a scad. in this statement: `xx = do_something( 12 );` ^ this is a call to a function, there are no children `do_operation() make_shape();` ^ this and ^ this are both calls to modules ^ this is the parent of ^ this child, by the syntax of it following the call to `do_operation()` I am using the terms “call” and “calling“ to refer to the execution of a module during the execution of a script, which is industry standard as far as i know. What was not clear to me was that a sequence of module calls in a single statement is the syntax for defining a nested parent-child shape that will be “rendered” as a mesh as a part of the model the script is drawing. But now it is and i am updating the docs to express my improved understanding
NH
nop head
Tue, Aug 5, 2025 10:05 PM

If you intersect two shapes that don't overlap or difference a shape that
completely overlaps the first operand, then you get an empty shape. It is
an empty geometry object.

All modules return a shape, but it may be empty.

On Tue, 5 Aug 2025, 22:51 vulcan_--- via Discuss, <
discuss@lists.openscad.org> wrote:

and .. this one

OpenSCAD modules may
accept zero or more children.  They may add shapes of their own, or they
may not.  They always yield a shape, though that shape may be empty.

First, .. what is an “empty shape“ ?

on the face of it that makes little sense. If there is nothing displayed
in the preview there was no mesh made, right?

I do get, now, that a module may create shape(s) itself, or be a parent to
children that may create shapes. And that a module might perform only
operations like color(), translate(), assert() and the like, thus defining
what i have been calling an operator module, does not create any mesh,
though its children might

so how can a module always yield a shape?


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

If you intersect two shapes that don't overlap or difference a shape that completely overlaps the first operand, then you get an empty shape. It is an empty geometry object. All modules return a shape, but it may be empty. On Tue, 5 Aug 2025, 22:51 vulcan_--- via Discuss, < discuss@lists.openscad.org> wrote: > and .. this one > > OpenSCAD modules may > accept zero or more children. They may add shapes of their own, or they > may not. They always yield a shape, though that shape may be empty. > > First, .. what is an “empty shape“ ? > > on the face of it that makes little sense. If there is nothing displayed > in the preview there was no mesh made, right? > > I do get, now, that a module may create shape(s) itself, or be a parent to > children that may create shapes. And that a module might perform only > operations like color(), translate(), assert() and the like, thus defining > what i have been calling an operator module, does not create any mesh, > though its children might > > so how can a module *always* yield a shape? > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >