V
vulcan_@mac.com
Tue, Aug 5, 2025 10:10 PM
ah .. that leads me to ask, why bother? if there is no geometry created by a module, thus no change to any part of a mesh that might already exist in the model, why retain anything of the operation that effectively did nothing?
ah .. that leads me to ask, why bother? if there is no geometry created by a module, thus no change to any part of a mesh that might already exist in the model, why retain anything of the operation that effectively did nothing?
NH
nop head
Tue, Aug 5, 2025 10:14 PM
An empty geometry object has to exist because some CGS operations may
result in one.
In the case of do_operation() make_shape();
do_operation() is instantiated, but it may or may not instantiate
make_shape();
On Tue, 5 Aug 2025 at 23:10, vulcan_--- via Discuss <
discuss@lists.openscad.org> wrote:
ah .. that leads me to ask, why bother? if there is no geometry created by
a module, thus no change to any part of a mesh that might already exist in
the model, why retain anything of the operation that effectively did
nothing?
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
An empty geometry object has to exist because some CGS operations may
result in one.
In the case of do_operation() make_shape();
do_operation() is instantiated, but it may or may not instantiate
make_shape();
On Tue, 5 Aug 2025 at 23:10, vulcan_--- via Discuss <
discuss@lists.openscad.org> wrote:
> ah .. that leads me to ask, why bother? if there is no geometry created by
> a module, thus no change to any part of a mesh that might already exist in
> the model, why retain anything of the operation that effectively did
> nothing?
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
V
vulcan_@mac.com
Tue, Aug 5, 2025 10:19 PM
thanks for patiently answering my incessant questions .. enlightenment is as hard a road for the teacher as the student.
i am grateful
thanks for patiently answering my incessant questions .. enlightenment is as hard a road for the teacher as the student.
i am grateful
NH
nop head
Tue, Aug 5, 2025 10:36 PM
if() is a module that may or may not invoke its child. If the expressions
is false then the child is never called and may even have errors in it. An
empty geometry object has to be return because it might be part of say a
difference() or a union().
On Tue, 5 Aug 2025 at 23:19, vulcan_--- via Discuss <
discuss@lists.openscad.org> wrote:
thanks for patiently answering my incessant questions .. enlightenment is
as hard a road for the teacher as the student.
i am grateful
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
if() is a module that may or may not invoke its child. If the expressions
is false then the child is never called and may even have errors in it. An
empty geometry object has to be return because it might be part of say a
difference() or a union().
On Tue, 5 Aug 2025 at 23:19, vulcan_--- via Discuss <
discuss@lists.openscad.org> wrote:
> thanks for patiently answering my incessant questions .. enlightenment is
> as hard a road for the teacher as the student.
>
> i am grateful
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
JB
Jordan Brown
Wed, Aug 6, 2025 3:44 AM
ah .. that leads me to ask, why bother? if there is no geometry created by a module, thus no change to any part of a mesh that might already exist in the model, why retain anything of the operation that effectively did nothing?
This is why the invention of the zero was so important. Mostly :-) but only mostly.
Let’s talk about lists.
Suppose that we have a list [a,b]. Now take away the last element; what is the result? You might reasonably say “a”, and I’ve seen environments that did that, but it’s a nuisance because list operations like iteration and concatenations may not work well on a non-list. (Or may do something totally unexpected if “a” itself is a list.) The answer really needs to be [a], a list of one element.
Now take away the first element of that list. What do you have? You might say “nothing” or “null” or “undefined”, and I have seen environments that do that, but again it’s inconvenient because list operations will not work. You want the answer to be [], the empty list. You can hand it around and you can do all of the usual list-y operations to it, and they work sensibly.
Now let’s go back to OpenSCAD shapes.
Suppose that we have this module:
module empty () {
}
What does it produce?
If you say that it produces nothing at all, not even emptiness, that things should work as if it was not even there, then what does this yield?
difference () {
empty ();
cube(10);
}
I would hope that the answer is never “a cube”.
Perhaps more real-world, consider this module:
module maybe_sphere(f) {
if (f) sphere (10);
}
If that didn’t always produce a shape, perhaps an empty shape, it would be very hard to use. There would be lots of cases where the caller would have to somehow know whether it was going to produce something, and treat it specially if not.
It only gets worse when you start introducing other OpenSCAD semantics.
What does this print?
module how_many_children() {
echo ($children);
}
how_many_children() {
maybe_sphere(rands(0,2,1)[0] > 1);
}
If maybe_sphere() should effectively disappear when it generates nothing, then the answer should be either zero or one, but (for very useful reasons) OpenSCAD doesn’t evaluate the children until the module calls children(), so the answer is not knowable.
Net, for the same basic reasons that zero, empty lists, empty sets, and empty strings are valuable and even essential, empty shapes are valuable and even essential.
> ah .. that leads me to ask, why bother? if there is no geometry created by a module, thus no change to any part of a mesh that might already exist in the model, why retain anything of the operation that effectively did nothing?
This is why the invention of the zero was so important. Mostly :-) but only mostly.
Let’s talk about lists.
Suppose that we have a list [a,b]. Now take away the last element; what is the result? You might reasonably say “a”, and I’ve seen environments that did that, but it’s a nuisance because list operations like iteration and concatenations may not work well on a non-list. (Or may do something totally unexpected if “a” itself is a list.) The answer really needs to be [a], a list of one element.
Now take away the first element of that list. What do you have? You might say “nothing” or “null” or “undefined”, and I have seen environments that do that, but again it’s inconvenient because list operations will not work. You want the answer to be [], the empty list. You can hand it around and you can do all of the usual list-y operations to it, and they work sensibly.
Now let’s go back to OpenSCAD shapes.
Suppose that we have this module:
module empty () {
}
What does it produce?
If you say that it produces nothing at all, not even emptiness, that things should work as if it was not even there, then what does this yield?
difference () {
empty ();
cube(10);
}
I would hope that the answer is never “a cube”.
Perhaps more real-world, consider this module:
module maybe_sphere(f) {
if (f) sphere (10);
}
If that didn’t *always* produce a shape, perhaps an empty shape, it would be very hard to use. There would be lots of cases where the caller would have to somehow know whether it was going to produce something, and treat it specially if not.
It only gets worse when you start introducing other OpenSCAD semantics.
What does this print?
module how_many_children() {
echo ($children);
}
how_many_children() {
maybe_sphere(rands(0,2,1)[0] > 1);
}
If maybe_sphere() should effectively disappear when it generates nothing, then the answer should be either zero or one, but (for very useful reasons) OpenSCAD doesn’t evaluate the children until the module calls children(), so the answer is not knowable.
Net, for the same basic reasons that zero, empty lists, empty sets, and empty strings are valuable and even essential, empty shapes are valuable and even essential.
JB
Jordan Brown
Wed, Aug 6, 2025 4:42 AM
In my experience the operation of making a polygonal version of the shapes in a model is “tessellation“
This usage of “tessellation” does not seem to appear in https://en.m.wikipedia.org/wiki/Tessellation .
Tessellation is the process of fitting shapes into other shapes - often, covering an infinite plane with a pattern of shapes. It has nothing to do with things like transformations and Boolean operations, which are what the OpenSCAD rendering process does. If the OpenSCAD rendering process does tessellation, it’s an implementation detail subject to change at any time for any reason or no reason.
I agree that “rendering” in the broader industry often means generating an image, though I think it usually means generating a final image - I don’t think that CGI people call it “rendering” when they generate stick-figure visualizations; they mean the compute-intensive process of producing the final image.
But, expect for the “producing the final result” connotation, that’s not what it means here, and for better or worse the local definition is unlikely to change.
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.
You do know that they are short cuts for the Preview and Render menu items, right?
(I might have the exact words wrong, because I’m not in front of a computer, but it’s something like that.)
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.
No, not at all. Again, if that happens it is an implementation detail subject to change at any time.
OpenSCAD rendering is the process of doing all of the operations required to yield a single (perhaps discontiguous) mesh. Concretely, given this script:
difference() {
cube(10);
translate ([5,5,5]) cube(10);
}
It is the process that turns those twenty-four edges and twelve faces into the resulting nine faces and fourteen edges. (If I’ve counted in my head correctly.)
It may, or may not, further divide those faces into triangles.
It may, in fact, do anything it feels like, as long as the result describes the correct closed shape.
(And, less commonly used but still entirely valid, given a 2D model it yields a set of polygons.)
I have learned that the result of running an scad script is a mesh
Maybe, maybe not. Sometimes it’s a mesh, sometimes it’s an image, sometimes it’s polygons, sometimes it’s text. It depends on the script and how it’s run.
If, and only if, you use the Render (F6) operation, or its CLI equivalent, the result is a mesh. (NB: not the render() module; that does not affect whether the final result is a mesh.) (Or, for a 2D model, a set of polygons.)
> In my experience the operation of making a polygonal version of the shapes in a model is “tessellation“
This usage of “tessellation” does not seem to appear in https://en.m.wikipedia.org/wiki/Tessellation .
Tessellation is the process of fitting shapes into other shapes - often, covering an infinite plane with a pattern of shapes. It has nothing to do with things like transformations and Boolean operations, which are what the OpenSCAD rendering process does. If the OpenSCAD rendering process does tessellation, it’s an implementation detail subject to change at any time for any reason or no reason.
I agree that “rendering” in the broader industry often means generating an image, though I think it usually means generating a *final* image - I don’t think that CGI people call it “rendering” when they generate stick-figure visualizations; they mean the compute-intensive process of producing the final image.
But, expect for the “producing the final result” connotation, that’s not what it means here, and for better or worse the local definition is unlikely to change.
> 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.
>
You do know that they are short cuts for the Preview and Render menu items, right?
(I might have the exact words wrong, because I’m not in front of a computer, but it’s something like that.)
> 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.
>
No, not at all. Again, if that happens it is an implementation detail subject to change at any time.
OpenSCAD rendering is the process of doing all of the operations required to yield a single (perhaps discontiguous) mesh. Concretely, given this script:
difference() {
cube(10);
translate ([5,5,5]) cube(10);
}
It is the process that turns those twenty-four edges and twelve faces into the resulting nine faces and fourteen edges. (If I’ve counted in my head correctly.)
It may, or may not, further divide those faces into triangles.
It may, in fact, do anything it feels like, as long as the result describes the correct closed shape.
(And, less commonly used but still entirely valid, given a 2D model it yields a set of polygons.)
> I have learned that the result of running an scad script is a mesh
>
Maybe, maybe not. Sometimes it’s a mesh, sometimes it’s an image, sometimes it’s polygons, sometimes it’s text. It depends on the script and how it’s run.
If, and only if, you use the Render (F6) operation, or its CLI equivalent, the result is a mesh. (NB: not the render() module; that does not affect whether the final result is a mesh.) (Or, for a 2D model, a set of polygons.)
JB
Jordan Brown
Wed, Aug 6, 2025 5:00 AM
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()
Yes. Give or take the discuss of “call” below.
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.
Yes, but there are important questions around what calls what, and when, and how that is described to the user.
For a beginning user, it is probably best to think of
rotate(45) cube(10);
as calling cube() to create a cube, and passing the result to rotate() to rotate it.
And you can use mental model for quite a while, even when you start to write modules that take children of their own.
But it’s false.
What actually happens is that it calls the rotate() module and passes the “cube(10)” statement to it, and rotate() evaluates that statement, rotates the result, and yields the rotated result.
But that’s a way more complex mental model than a beginner, or even an intermediate, really needs.
So the trick is in how to start out with the simpler mental model and eventually introduce the more complex and correct model, without totally confusing the user.
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.
That seems like a pretty serious failure of the tutorial matter, since that’s the most fundamental building block of the entire language. (You did read the tutorial matter before the reference manual, right?)
> 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()
>
Yes. Give or take the discuss of “call” below.
> 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.
>
Yes, but there are important questions around what calls what, and when, and how that is described to the user.
For a beginning user, it is probably best to think of
rotate(45) cube(10);
as calling cube() to create a cube, and passing the result to rotate() to rotate it.
And you can use mental model for quite a while, even when you start to write modules that take children of their own.
But it’s false.
What actually happens is that it calls the rotate() module and passes the “cube(10)” statement to it, and rotate() evaluates that statement, rotates the result, and yields the rotated result.
But that’s a way more complex mental model than a beginner, or even an intermediate, really needs.
So the trick is in how to start out with the simpler mental model and eventually introduce the more complex and correct model, without totally confusing the user.
> 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.
>
That seems like a pretty serious failure of the tutorial matter, since that’s the most fundamental building block of the entire language. (You did read the tutorial matter before the reference manual, right?)
P
pca006132
Wed, Aug 6, 2025 6:03 AM
After following the recent discussions and reading the current version of
the wiki, I have several major concerns here.
- One should not attempt to infer the API contract from the behavior.
Implementation is subject to changes and may be incorrect. If you learn the
API specification from the implementation behavior, you overfit. And you
will miss subtle behaviors like what Jordan mentioned, which affect how
special variable values are resolved.
- Terminologies are all messed up in the new version of the reference
manual. The term "object" can refer to anything in
https://en.m.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules.
In the old version of the language reference, it refers to geometries. The
"named object" naming rule thing is just a rule about valid identifiers, it
is not like we need a new name for it. And in
https://en.m.wikibooks.org/wiki/OpenSCAD_User_Manual/General at the start,
I have no idea what it means by "named operations". I don't think
"manipulate" or "modify" are good words either: we never modify things
in-place, we just get a new transformed version.
- I don't think the current version (or the old version) is an appropriate
language reference manual. They are too verbose and not detailed enough.
For example, for generating regular polygons using circle with $fn, what is
the orientation of the polygon? When are child geometries evaluated, i.e.
the thing Jordan mentioned above. What happen when we union 2D and 3D
objects together? What is a valid expression? These are not answered. Also,
for deprecation or experimental features, we should have a more uniform way
of showing them, such as the style in cppreference.
While I appreciate Vulcan's hard work, I don't think the current rewrite
works.
Best,
John
On Wed, Aug 6, 2025 at 1:01 PM Jordan Brown via Discuss <
discuss@lists.openscad.org> wrote:
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()
Yes. Give or take the discuss of “call” below.
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.
Yes, but there are important questions around what calls what, and when,
and how that is described to the user.
For a beginning user, it is probably best to think of
rotate(45) cube(10);
as calling cube() to create a cube, and passing the result to rotate() to
rotate it.
And you can use mental model for quite a while, even when you start to
write modules that take children of their own.
But it’s false.
What actually happens is that it calls the rotate() module and passes the
“cube(10)” statement to it, and rotate() evaluates that statement, rotates
the result, and yields the rotated result.
But that’s a way more complex mental model than a beginner, or even an
intermediate, really needs.
So the trick is in how to start out with the simpler mental model and
eventually introduce the more complex and correct model, without totally
confusing the user.
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.
That seems like a pretty serious failure of the tutorial matter, since
that’s the most fundamental building block of the entire language. (You did
read the tutorial matter before the reference manual, right?)
OpenSCAD mailing list
To unsubscribe send an email to discuss-leave@lists.openscad.org
After following the recent discussions and reading the current version of
the wiki, I have several major concerns here.
1. One should not attempt to infer the API contract from the behavior.
Implementation is subject to changes and may be incorrect. If you learn the
API specification from the implementation behavior, you overfit. And you
will miss subtle behaviors like what Jordan mentioned, which affect how
special variable values are resolved.
2. Terminologies are all messed up in the new version of the reference
manual. The term "object" can refer to anything in
https://en.m.wikibooks.org/wiki/OpenSCAD_User_Manual/User-Defined_Functions_and_Modules.
In the old version of the language reference, it refers to geometries. The
"named object" naming rule thing is just a rule about valid identifiers, it
is not like we need a new name for it. And in
https://en.m.wikibooks.org/wiki/OpenSCAD_User_Manual/General at the start,
I have no idea what it means by "named operations". I don't think
"manipulate" or "modify" are good words either: we never modify things
in-place, we just get a new transformed version.
3. I don't think the current version (or the old version) is an appropriate
language reference manual. They are too verbose and not detailed enough.
For example, for generating regular polygons using circle with $fn, what is
the orientation of the polygon? When are child geometries evaluated, i.e.
the thing Jordan mentioned above. What happen when we union 2D and 3D
objects together? What is a valid expression? These are not answered. Also,
for deprecation or experimental features, we should have a more uniform way
of showing them, such as the style in cppreference.
While I appreciate Vulcan's hard work, I don't think the current rewrite
works.
Best,
John
On Wed, Aug 6, 2025 at 1:01 PM Jordan Brown via Discuss <
discuss@lists.openscad.org> wrote:
>
>
> 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()
>
>
> Yes. Give or take the discuss of “call” below.
>
> 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.
>
>
> Yes, but there are important questions around what calls what, and when,
> and how that is described to the user.
>
> For a beginning user, it is probably best to think of
>
> rotate(45) cube(10);
>
> as calling cube() to create a cube, and passing the result to rotate() to
> rotate it.
>
> And you can use mental model for quite a while, even when you start to
> write modules that take children of their own.
>
> But it’s false.
>
> What actually happens is that it calls the rotate() module and passes the
> “cube(10)” statement to it, and rotate() evaluates that statement, rotates
> the result, and yields the rotated result.
>
> But that’s a way more complex mental model than a beginner, or even an
> intermediate, really needs.
>
> So the trick is in how to start out with the simpler mental model and
> eventually introduce the more complex and correct model, without totally
> confusing the user.
>
> 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.
>
>
> That seems like a pretty serious failure of the tutorial matter, since
> that’s the most fundamental building block of the entire language. (You did
> read the tutorial matter before the reference manual, right?)
> _______________________________________________
> OpenSCAD mailing list
> To unsubscribe send an email to discuss-leave@lists.openscad.org
>
V
vulcan_@mac.com
Wed, Aug 6, 2025 6:41 AM
correct, my usage of “tessellation“ comes from talking about rendering issues in long sequence animations for the movie industry with the folks developing / maintaining the render engines for Alias|wavefront Power Animator, Maya and the wavefront tool chain .. all of whom gleefully plucked the word from its correct use as a math term and applied it to
mean “Map all the NURBs in a model into their equivalent mesh so that we can make pictures with it”
The wiki page you cite is correct in another context. And it is even possible that the render gods of A|w were simplifying things in their explanations of the many things that could produce unwanted artifacts in a rendered image to me and so i may have misunderstood what they meant by “tessellation“ too.
—-
about “calling” a subroutine, with ref to your kind reply:
rotate(45) cube(10);
as calling cube() to create a cube, and passing the result to rotate() to rotate it.
if we could agree that the term “call a module” to mean: ( using cube(10) as the example)
jump to the chunk of code labeled cube() passing its defined argument list with default values except size=45
execute that code and then return
in your example cube() is not in the parameter list of the call to rotate(), so i do not like to say it is “passed” to rotate()
My new understanding of the module’s syntax is that it includes a following child module, thus the definition of a statement’s syntax when a module is being called is (hacking BNF brutally) :
module <name>( <arg>* ) [ | child_module()* | {<statement>* } ];
meaning that the following child can be omitted, a call to another module, or a block of code within braces (using ‘|’ to separate alternatives). Textually this parallels how a procedural language builds a program’s structure in preparation for execution .. and no, the tutorials do not do enough to help a guy from that sort of background learn the very different approach of 1. a functional language and 2. scad’s use of a sequence of module calls and blocks in a statement to define an element of a model
and finally, no - of course i did not read the tutorials. I need to 3D print some small gears and google found me some FreeCAD extensions, websites, stand-alone programs, and several OpenSCAD libraries .. so i took a look at the ones that seemed to do what i needed .. one of the most accessible was an scad script that had been adapted (upgraded?) from the original version on Thingverse, which was in German. So what does any Real Programmer do? That is right!
One downloads the code to start hacking it to understand it, “improving it” as i go, translating to english and studying up on gear terminology and when the bits i touched broke .. being dissatisfied with the scad docs so that of course i had to write a few dozen text and example scripts to test the details of syntax etc.
Finding BOSL2 too complex for what i was trying to do .. so finding stuff i could used in the relativity library .. but not really understanding some things its code was doing .. more experimenting revealed flaws in the docs .. which as a Wikiverse contributor i could actually fix
well and truly a rabbit hole into which i jumped. I think you know how that happens, yes?
Hi Jordan
you said this:
> This usage of “tessellation” does not seem to appear in <https://en.m.wikipedia.org/wiki/Tessellation> .
correct, my usage of “tessellation“ comes from talking about rendering issues in long sequence animations for the movie industry with the folks developing / maintaining the render engines for Alias|wavefront Power Animator, Maya and the wavefront tool chain .. all of whom gleefully plucked the word from its correct use as a math term and applied it to\
mean “Map all the NURBs in a model into their equivalent mesh so that we can make pictures with it”
The wiki page you cite is correct in another context. And it is even possible that the render gods of A|w were simplifying things in their explanations of the many things that could produce unwanted artifacts in a rendered image to me and so i may have misunderstood what they meant by “tessellation“ too.
—-
about “calling” a subroutine, with ref to your kind reply:
> rotate(45) cube(10);
>
> as calling cube() to create a cube, and passing the result to rotate() to rotate it.
if we could agree that the term “call a module” to mean: ( using cube(10) as the example)
> jump to the chunk of code labeled cube() passing its defined argument list with default values except size=45\
> execute that code and then return
in your example cube() is not in the parameter list of the call to rotate(), so i do not like to say it is “passed” to rotate()
My new understanding of the module’s syntax is that it includes a following child module, thus the definition of a statement’s syntax when a module is being called is (hacking BNF brutally) :
> module <name>( <arg>\* ) \[ | child_module()\* | {<statement>\* } \];
meaning that the following child can be omitted, a call to another module, or a block of code within braces (using ‘|’ to separate alternatives). *Textually* this parallels how a procedural language builds a program’s structure in preparation for execution .. and no, the tutorials do not do enough to help a guy from that sort of background learn the very different approach of 1. a functional language and 2. scad’s use of a sequence of module calls and blocks in a statement to define an element of a model
and finally, no - *of course* i did *not* read the tutorials. I need to 3D print some small gears and google found me some FreeCAD extensions, websites, stand-alone programs, and several OpenSCAD libraries .. so i took a look at the ones that seemed to do what i needed .. one of the most accessible was an scad script that had been adapted (upgraded?) from the original version on Thingverse, which was in German. So what does any Real Programmer do? That is right!
One downloads the code to start hacking it to understand it, “improving it” as i go, translating to english and studying up on gear terminology and when the bits i touched broke .. being dissatisfied with the scad docs so that *of course* i had to write a few dozen text and example scripts to test the details of syntax etc.
Finding BOSL2 too complex for what i was trying to do .. so finding stuff i could used in the relativity library .. but not really understanding some things its code was doing .. more experimenting revealed flaws in the docs .. which as a Wikiverse contributor i could actually fix
well and truly a rabbit hole into which i jumped. I think you know how that happens, yes?
V
vulcan_@mac.com
Wed, Aug 6, 2025 7:51 AM
After following the recent discussions and reading the current version of
the wiki, I have several major concerns here.
you are giving me the feedback i crave PCA, thanks
- One should not attempt to infer the API contract from the behavior.
umm .. then how better to understand it? the docs and tutorials did not do enough so i started to experiment to see how things worked. I have dozens of test and example code snippets to back up what i write about how scad works ..
that said: feedback from you and others has already led me closer to the One True Way of SCAD and i continue to enshrine the revealed wisdom in updates to the docs
i am not at all clear what overfit means .. if you mean i try to understand scad in the context of my own experience but not knowing enough in the context of SCAD i get things wrong .. yep, that is why we write in a wiki, and have this forum - for you folks to educate me. I am happy to do the grunt work of docs updates .. i enjoy getting an explanation correct and helping others along the road to enlightenment.
special variable values are resolved.
Yeah, specials are still a fuzzy thing for me .. even after Jordan’s diligent attempt to educate me on how they work i am not at all clear on what they bring to the language that is any different from having global variables at the top level of scope
- Terminologies are all messed up in the new version of the reference manual. The term "object" can refer to anything in … "manipulate" or "modify" are good words either: we never modify things in-place, we just get a new transformed version.
- I don't think the current version (or the old version) is an appropriate
language reference manual.
if you take a look at the new pages i am happiest with you will see that i am trying to answer the questions you raised. I too found the old docs imprecise and in a few places contradictory
for instance, i spent time to make this update to the page on 2D primitives
and i had done a complete rewrite of the page on operators in my sandbox to incorporate input i had from others, notably Jordan, and my observations of how they work.
While I appreciate Vulcan's hard work, I don't think the current rewrite
works.
how we move forward is up to the community - if you folks are willing to keep giving me feedback on what is broken / wrong / needs improving then i will keep working to make it all come good.
If not .. it is a wiki .. everyone is free to correct what they find to be wrong .. or even just revert it all back to early April when i started
Thanks John, for your input
pca006132 wrote:
> After following the recent discussions and reading the current version of
> the wiki, I have several major concerns here.
you are giving me the feedback i crave PCA, thanks
> 1. One should not attempt to infer the API contract from the behavior.
umm .. then how better to understand it? the docs and tutorials did not do enough so i started to experiment to see how things worked. I have dozens of test and example code snippets to back up what i write about how scad works ..
that said: feedback from you and others has already led me closer to the One True Way of SCAD and i continue to enshrine the revealed wisdom in updates to the docs
> you overfit.
i am not at all clear what overfit means .. if you mean i try to understand scad in the context of my own experience but not knowing enough in the context of SCAD i get things wrong .. yep, that is why we write in a wiki, and have this forum - for you folks to educate me. I am happy to do the grunt work of docs updates .. i enjoy getting an explanation correct and helping others along the road to enlightenment.
> special variable values are resolved.
Yeah, specials are still a fuzzy thing for me .. even after Jordan’s diligent attempt to educate me on how they work i am not at all clear on what they bring to the language that is any different from having global variables at the top level of scope
> 1. Terminologies are all messed up in the new version of the reference manual. The term "object" can refer to anything in … "manipulate" or "modify" are good words either: we never modify things in-place, we just get a new transformed version.
I am in the process of fixing these terminology issues .. in a previous post i [published the glossary i am now working with](https://en.wikibooks.org/wiki/User:VulcanWikiEdit/sandbox/SCADGlossary)
> 1. I don't think the current version (or the old version) is an appropriate
> language reference manual.
if you take a look at the new pages i am happiest with you will see that i am trying to answer the questions you raised. I too found the old docs imprecise and in a few places contradictory
for instance, i spent time to make this [update to the page on 2D primitives](https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Using_the_2D_Subsystem)
and i had done a complete rewrite of [the page on operators in my sandbox](https://en.wikibooks.org/wiki/User:VulcanWikiEdit/sandbox/Operators_Discussion) to incorporate input i had from others, notably Jordan, and my observations of how they work.
> While I appreciate Vulcan's hard work, I don't think the current rewrite
> works.
how we move forward is up to the community - if you folks are willing to keep giving me feedback on what is broken / wrong / needs improving then i will keep working to make it all come good.
If not .. it is a wiki .. everyone is free to correct what they find to be wrong .. or even just revert it all back to early April when i started
> Best,
> John
Thanks John, for your input