discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Re: [OpenSCAD] Discuss Digest, Vol 65, Issue 2

NH
nop head
Sun, Apr 5, 2020 2:31 PM

You can find all the code for it my library here:
https://github.com/nophead/NopSCADlib

On Sun, 5 Apr 2020 at 14:32, Ron Wheeler via Discuss <
discuss@lists.openscad.org> wrote:

Very interesting idea. I will give that a shot.

Thanks

Ron

On 2020-04-05 3:53 a.m., nop head wrote:

I generate BOMs using modules that echo and then process the output stream
with Python scripts that generate BOMs and assembly diagrams and
instructions.

On Sun, 5 Apr 2020 at 01:42, Ron Wheeler via Discuss <
discuss@lists.openscad.org> wrote:

Not sure that your example is a "normal use case" where variables might
be helpful.
I can not even visualize what you are trying to make.

In my case, I only need the variables to persist from start to end and be
acted on at some time during that period whenever an operation is requested
that adds a component.
If I add bunch of purchased or printed parts or a number of pipes of a
certain length, I would like to generate a BOM
24 part A
47 part B
3  Part C (custom part to print from a separate OpenSCAD used in the
assembly)
2    10 foot pipes
20  2 foot pipes
16  3 foot pipes
and so on.

When your project gets into the dozens of each part and there are 100+
parts, the effort of redoing the count from a picture and the chance of
missing a part both get high.

Is there another/better way to tag objects created to enable a BOM to be
generated at the end?
If so, I could get a list of all tags created during the execution and
then loop through the list and write ECHO "A count of all getTagName(i) is
getTagCount(i)"; at the end.
During the creation of objects I would have to code something to say
"Tag this group of commands as a "Part A", "Tag this group as
"Pipe_1.25_Inch-36" where 36 is some local value (length, width,
diameter, etc.) used in the creation of the object.

It does not solve all of the parametric design issues but would solve the
BOM problem.

Ron

On 2020-04-04 7:26 p.m., Jordan Brown wrote:

On 4/4/2020 3:49 PM, ken@volksswitch.org wrote:

  1. provide a Lint like feature () to help me identify modules that are never called and variables that are never used

Note that as in lint itself there would need to be a way to mark a file
as containing a library, since it's normal not to use all of the features
exported by the library.

  1. allow a variable to be assigned a new value after it has already been assigned a value
  2. allow for a variable to be assigned a value in an if statement and then have that value preserved when the if completes

I'm not one of the developers, but this is easy to answer:  not going to
happen.  OpenSCAD doesn't execute anything like a conventional language.
It does not execute lines in the order that you expect. (And some
features, like the children() feature, depend on that fact.)

For fun, try this program.  Try to predict this output, then run it, then
try to understand the results.

module foo() {
a = echo("foo assignment 1") 0;
children(1);
children(0);
b = echo("foo assignment 2") 0;
}

foo() {
x = echo("assignment 1") 0;
echo("child 1");
echo("child 2");
echo("child 3");
y = echo("assignment 2") 0;
}

For extra fun, try throwing $ variables into the mix.


OpenSCAD mailing listDiscuss@lists.openscad.orghttp://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

--
Ron Wheeler
Artifact Software
438-345-3369rwheeler@artifact-software.com


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org


OpenSCAD mailing listDiscuss@lists.openscad.orghttp://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

--
Ron Wheeler
Artifact Software
438-345-3369rwheeler@artifact-software.com


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

You can find all the code for it my library here: https://github.com/nophead/NopSCADlib On Sun, 5 Apr 2020 at 14:32, Ron Wheeler via Discuss < discuss@lists.openscad.org> wrote: > Very interesting idea. I will give that a shot. > > Thanks > > Ron > > On 2020-04-05 3:53 a.m., nop head wrote: > > I generate BOMs using modules that echo and then process the output stream > with Python scripts that generate BOMs and assembly diagrams and > instructions. > > On Sun, 5 Apr 2020 at 01:42, Ron Wheeler via Discuss < > discuss@lists.openscad.org> wrote: > >> Not sure that your example is a "normal use case" where variables might >> be helpful. >> I can not even visualize what you are trying to make. >> >> In my case, I only need the variables to persist from start to end and be >> acted on at some time during that period whenever an operation is requested >> that adds a component. >> If I add bunch of purchased or printed parts or a number of pipes of a >> certain length, I would like to generate a BOM >> 24 part A >> 47 part B >> 3 Part C (custom part to print from a separate OpenSCAD used in the >> assembly) >> 2 10 foot pipes >> 20 2 foot pipes >> 16 3 foot pipes >> and so on. >> >> When your project gets into the dozens of each part and there are 100+ >> parts, the effort of redoing the count from a picture and the chance of >> missing a part both get high. >> >> Is there another/better way to tag objects created to enable a BOM to be >> generated at the end? >> If so, I could get a list of all tags created during the execution and >> then loop through the list and write ECHO "A count of all getTagName(i) is >> getTagCount(i)"; at the end. >> During the creation of objects I would have to code something to say >> "Tag this group of commands as a "Part A", "Tag this group as >> "Pipe_1.25_Inch-36" where 36 is some local value (*length*, width, >> diameter, etc.) used in the creation of the object. >> >> >> It does not solve all of the parametric design issues but would solve the >> BOM problem. >> >> >> Ron >> >> On 2020-04-04 7:26 p.m., Jordan Brown wrote: >> >> On 4/4/2020 3:49 PM, ken@volksswitch.org wrote: >> >> 1) provide a Lint like feature () to help me identify modules that are never called and variables that are never used >> >> >> Note that as in lint itself there would need to be a way to mark a file >> as containing a library, since it's normal not to use all of the features >> exported by the library. >> >> 2) allow a variable to be assigned a new value after it has already been assigned a value >> 3) allow for a variable to be assigned a value in an if statement and then have that value preserved when the if completes >> >> >> I'm not one of the developers, but this is easy to answer: not going to >> happen. OpenSCAD doesn't execute anything like a conventional language. >> It does *not* execute lines in the order that you expect. (And some >> features, like the children() feature, depend on that fact.) >> >> For fun, try this program. Try to predict this output, then run it, then >> try to understand the results. >> >> module foo() { >> a = echo("foo assignment 1") 0; >> children(1); >> children(0); >> b = echo("foo assignment 2") 0; >> } >> >> foo() { >> x = echo("assignment 1") 0; >> echo("child 1"); >> echo("child 2"); >> echo("child 3"); >> y = echo("assignment 2") 0; >> } >> >> For extra fun, try throwing $ variables into the mix. >> >> _______________________________________________ >> OpenSCAD mailing listDiscuss@lists.openscad.orghttp://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> >> -- >> Ron Wheeler >> Artifact Software >> 438-345-3369rwheeler@artifact-software.com >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> > > _______________________________________________ > OpenSCAD mailing listDiscuss@lists.openscad.orghttp://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > > > -- > Ron Wheeler > Artifact Software > 438-345-3369rwheeler@artifact-software.com > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
JB
Jordan Brown
Sun, Apr 5, 2020 5:26 PM

On 4/4/2020 5:41 PM, Ron Wheeler via Discuss wrote:

Not sure that your example is a "normal use case" where variables
might be helpful.
I can not even visualize what you are trying to make.

It isn't intended as a use case.  It's intended to demonstrate parts of
the order of execution, and that OpenSCAD doesn't execute in an order
that you would expect.

Here's another.

a = echo("assign a") 123; if (echo("compare") a == b) { echo("a and
b are equal"); } b = echo("assign b") 123;

When you run this, you'll see that the two assignments occur before the
condition and body of the "if" run.

One could debate whether this language structure is a good thing, but
it is what it is and I assume that it would be a major redesign to
change it.

On 4/4/2020 5:41 PM, Ron Wheeler via Discuss wrote: > Not sure that your example is a "normal use case" where variables > might be helpful. > I can not even visualize what you are trying to make. It isn't intended as a use case.  It's intended to demonstrate parts of the order of execution, and that OpenSCAD doesn't execute in an order that you would expect. Here's another. a = echo("assign a") 123; if (echo("compare") a == b) { echo("a and b are equal"); } b = echo("assign b") 123; When you run this, you'll see that the two assignments occur before the condition and body of the "if" run. One could debate whether this language structure is a *good* thing, but it is what it is and I assume that it would be a major redesign to change it.
JB
Jordan Brown
Sun, Apr 5, 2020 7:22 PM

On 4/4/2020 4:54 PM, Ron Wheeler via Discuss wrote:

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables
seems to suggest that user defined variables actually might do this
but it appears that the documentation is wrong or misleading.

Special variables - the ones beginning with $ - are constant too, just
with different scope.

Regular variables have scopes that follow the block structure of the
program:

a = 1;
module foo() {
    b = 2;
    if (a==b) {
        a = 4;
        c = 3;
    }
}

The scope of the first "a" is the whole file, except the body of the
"if".  The scope of "b" is the module.  The scope of "c" is the body of
the "if" block.  The scope of the "a" in the "if" block is the body of
the if block, overriding/hiding/shadowing the file-scope "a".

This scoping is pretty typical for any block-structured language.

Special variables are scoped according to the execution tree.

$a = 1;

module foo() {
    echo($a);
}

module bar() {
    $a = 2;
    foo();
}

foo();
bar();
foo($a=3);

For the first invocation of "foo", the top-level definition of $a is in
scope, so the value is 1.

For the invocation of "bar", "bar" overrides the definition of $a, and
so when it executes "foo" the value is 2.

For the final invocation of "foo", the value of $a is overridden for
that one call, and so the value is 3.

Error messages should be less about the way a programmer sees an
internal function failing and more about what the designer/user might
have done. This might require a bit of work to suggest issues that
started in earlier lines but some might be easy - too many or too few
"}" could be explained "Missing closing bracket" "More closing
brackets than opening brackets" This would seem to be easy to detect
and report.

I agree that improving the messages would be helpful.  Whether or not
it's easy depends on what kind of compilation infrastructure they're
using.  The compilation infrastructure might not report anything other
than "I wasn't able to match the defined syntax".

Missing closing ";" might be suggested when it is easy to guess that
the syntax would be correct if the earlier line had been closed
properly. That is, the parser sees a token that is legal but not in
the right context. This would only be a suggestion to the designer as
a place to look. 'Did you forget a ";"?'

Note that some of the most obvious missing-semicolon cases are not
actually syntax errors.

module foo()
{
    echo("foo");
}

module bar()
{
    echo("bar");
}

foo()
bar()
if (true) {
    echo("hello");
}

is syntactically completely legal.  Doesn't do what you probably expect,
but it's legal.

(The built-in modules detect this error at run time.  It would be cool
if user-defined modules could get similar detection.  It wouldn't be as
simple as "was children() called"; it would have to involve remembering
whether there are any calls to children() or $children in the module.)

On 4/4/2020 4:54 PM, Ron Wheeler via Discuss wrote: > https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables > seems to suggest that user defined variables actually might do this > but it appears that the documentation is wrong or misleading. Special variables - the ones beginning with $ - are constant too, just with different scope. Regular variables have scopes that follow the block structure of the program: a = 1; module foo() { b = 2; if (a==b) { a = 4; c = 3; } } The scope of the first "a" is the whole file, except the body of the "if".  The scope of "b" is the module.  The scope of "c" is the body of the "if" block.  The scope of the "a" in the "if" block is the body of the if block, overriding/hiding/shadowing the file-scope "a". This scoping is pretty typical for any block-structured language. Special variables are scoped according to the execution tree. $a = 1; module foo() { echo($a); } module bar() { $a = 2; foo(); } foo(); bar(); foo($a=3); For the first invocation of "foo", the top-level definition of $a is in scope, so the value is 1. For the invocation of "bar", "bar" overrides the definition of $a, and so when it executes "foo" the value is 2. For the final invocation of "foo", the value of $a is overridden for that one call, and so the value is 3. > Error messages should be less about the way a programmer sees an > internal function failing and more about what the designer/user might > have done. This might require a bit of work to suggest issues that > started in earlier lines but some might be easy - too many or too few > "}" could be explained "Missing closing bracket" "More closing > brackets than opening brackets" This would seem to be easy to detect > and report. I agree that improving the messages would be helpful.  Whether or not it's easy depends on what kind of compilation infrastructure they're using.  The compilation infrastructure might not report anything other than "I wasn't able to match the defined syntax". > Missing closing ";" might be suggested when it is easy to guess that > the syntax would be correct if the earlier line had been closed > properly. That is, the parser sees a token that is legal but not in > the right context. This would only be a suggestion to the designer as > a place to look. 'Did you forget a ";"?' Note that some of the most obvious missing-semicolon cases are not actually syntax errors. module foo() { echo("foo"); } module bar() { echo("bar"); } foo() bar() if (true) { echo("hello"); } is syntactically completely legal.  Doesn't do what you probably expect, but it's legal. (The built-in modules detect this error at run time.  It would be cool if user-defined modules could get similar detection.  It wouldn't be as simple as "was children() called"; it would have to involve remembering whether there are *any* calls to children() or $children in the module.)
A
adrianv
Sun, Apr 5, 2020 7:33 PM

JordanBrown wrote

(The built-in modules detect this error at run time.  It would be cool
if user-defined modules could get similar detection.  It wouldn't be as
simple as "was children() called"; it would have to involve remembering
whether there are any calls to children() or $children in the module.)

I assume that built-in modules just know that they don't take children, so
the presence of children is suspicious.  They don't do some kind of internal
code analysis to decide whether children are OK.  This effect is easily
achieved with user-defined modules.  Just tag modules that don't use
children with "no_children($children)" as shown below:

module foo() {
no_children($children);
echo("hello world");
// no children used here
}

module no_children(count)
{
assert(count==0, str("Module ",parent_module(1),"() does not support child
modules"));
}

--
Sent from: http://forum.openscad.org/

JordanBrown wrote > > (The built-in modules detect this error at run time.  It would be cool > if user-defined modules could get similar detection.  It wouldn't be as > simple as "was children() called"; it would have to involve remembering > whether there are *any* calls to children() or $children in the module.) I assume that built-in modules just know that they don't take children, so the presence of children is suspicious. They don't do some kind of internal code analysis to decide whether children are OK. This effect is easily achieved with user-defined modules. Just tag modules that don't use children with "no_children($children)" as shown below: module foo() { no_children($children); echo("hello world"); // no children used here } module no_children(count) { assert(count==0, str("Module ",parent_module(1),"() does not support child modules")); } -- Sent from: http://forum.openscad.org/
JB
Jordan Brown
Sun, Apr 5, 2020 8:56 PM

On 4/5/2020 12:33 PM, adrianv wrote:

JordanBrown wrote

(The built-in modules detect this error at run time.  It would be cool
if user-defined modules could get similar detection.  It wouldn't be as
simple as "was children() called"; it would have to involve remembering
whether there are any calls to children() or $children in the module.)

I assume that built-in modules just know that they don't take children, so
the presence of children is suspicious.

Yes.

They don't do some kind of internal code analysis to decide whether children are OK. This effect is easily achieved with user-defined modules.

Sure.  As you show, you can trivially do this check yourself.  But it
would be cool if the infrastructure did it for you, so that a newcomer
who doesn't even know what children() does will get the protection.

On 4/5/2020 12:33 PM, adrianv wrote: > JordanBrown wrote >> (The built-in modules detect this error at run time.  It would be cool >> if user-defined modules could get similar detection.  It wouldn't be as >> simple as "was children() called"; it would have to involve remembering >> whether there are *any* calls to children() or $children in the module.) > I assume that built-in modules just know that they don't take children, so > the presence of children is suspicious. Yes. > They don't do some kind of internal code analysis to decide whether children are OK. This effect is easily achieved with user-defined modules. Sure.  As you show, you can trivially do this check yourself.  But it would be cool if the infrastructure did it for you, so that a newcomer who doesn't even know what children() does will get the protection.
RW
Ron Wheeler
Mon, Apr 6, 2020 4:37 AM

Someone suggested a way to solve my BOM problem with echo and a script.
I am working on that.
I am still not convinced that it is impossible to reliably describe a
"real" global variable.

The missing ";" error message problem is not that OpenSCAD can not
recognize that it is missing but does not give any indication about how
it knew that it was missing.
It seems that it knows that it found a keyword in a context where it was
not allowed.

It would be a bit of work to test that if a ";" had been inserted before
the keyword, the previous block and the current block would be legal and
suggest to the script-writer to look to see if adding the ";" would be
the right thing to do.

This is a common problem in writing scripts but this is clearly an
additional usability feature rather than a functional demand.

Ron

On 2020-04-05 3:22 p.m., Jordan Brown wrote:

On 4/4/2020 4:54 PM, Ron Wheeler via Discuss wrote:

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables
seems to suggest that user defined variables actually might do this
but it appears that the documentation is wrong or misleading.

Special variables - the ones beginning with $ - are constant too, just
with different scope.

Regular variables have scopes that follow the block structure of the
program:

 a = 1;
 module foo() {
      b = 2;
      if (a==b) {
          a = 4;
          c = 3;
      }
 }

The scope of the first "a" is the whole file, except the body of the
"if".  The scope of "b" is the module.  The scope of "c" is the body
of the "if" block.  The scope of the "a" in the "if" block is the body
of the if block, overriding/hiding/shadowing the file-scope "a".

This scoping is pretty typical for any block-structured language.

Special variables are scoped according to the execution tree.

 $a = 1;

 module foo() {
      echo($a);
 }

 module bar() {
      $a = 2;
      foo();
 }

 foo();
 bar();
 foo($a=3);

For the first invocation of "foo", the top-level definition of $a is
in scope, so the value is 1.

For the invocation of "bar", "bar" overrides the definition of $a, and
so when it executes "foo" the value is 2.

For the final invocation of "foo", the value of $a is overridden for
that one call, and so the value is 3.

Error messages should be less about the way a programmer sees an
internal function failing and more about what the designer/user might
have done. This might require a bit of work to suggest issues that
started in earlier lines but some might be easy - too many or too few
"}" could be explained "Missing closing bracket" "More closing
brackets than opening brackets" This would seem to be easy to detect
and report.

I agree that improving the messages would be helpful.  Whether or not
it's easy depends on what kind of compilation infrastructure they're
using.  The compilation infrastructure might not report anything other
than "I wasn't able to match the defined syntax".

Missing closing ";" might be suggested when it is easy to guess that
the syntax would be correct if the earlier line had been closed
properly. That is, the parser sees a token that is legal but not in
the right context. This would only be a suggestion to the designer as
a place to look. 'Did you forget a ";"?'

Note that some of the most obvious missing-semicolon cases are not
actually syntax errors.

 module foo()
 {
      echo("foo");
 }

 module bar()
 {
      echo("bar");
 }

 foo()
 bar()
 if (true) {
      echo("hello");
 }

is syntactically completely legal.  Doesn't do what you probably
expect, but it's legal.

(The built-in modules detect this error at run time.  It would be cool
if user-defined modules could get similar detection.  It wouldn't be
as simple as "was children() called"; it would have to involve
remembering whether there are any calls to children() or $children
in the module.)

--
Ron Wheeler
Artifact Software
438-345-3369
rwheeler@artifact-software.com

Someone suggested a way to solve my BOM problem with echo and a script. I am working on that. I am still not convinced that it is impossible to reliably describe a "real" global variable. The missing ";" error message problem is not that OpenSCAD can not recognize that it is missing but does not give any indication about how it knew that it was missing. It seems that it knows that it found a keyword in a context where it was not allowed. It would be a bit of work to test that if a ";" had been inserted before the keyword, the previous block and the current block would be legal and suggest to the script-writer to look to see if adding the ";" would be the right thing to do. This is a common problem in writing scripts but this is clearly an additional usability feature rather than a functional demand. Ron On 2020-04-05 3:22 p.m., Jordan Brown wrote: > On 4/4/2020 4:54 PM, Ron Wheeler via Discuss wrote: >> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables >> seems to suggest that user defined variables actually might do this >> but it appears that the documentation is wrong or misleading. > > Special variables - the ones beginning with $ - are constant too, just > with different scope. > > Regular variables have scopes that follow the block structure of the > program: > > a = 1; > module foo() { > b = 2; > if (a==b) { > a = 4; > c = 3; > } > } > > The scope of the first "a" is the whole file, except the body of the > "if".  The scope of "b" is the module.  The scope of "c" is the body > of the "if" block.  The scope of the "a" in the "if" block is the body > of the if block, overriding/hiding/shadowing the file-scope "a". > > This scoping is pretty typical for any block-structured language. > > Special variables are scoped according to the execution tree. > > $a = 1; > > module foo() { > echo($a); > } > > module bar() { > $a = 2; > foo(); > } > > foo(); > bar(); > foo($a=3); > > For the first invocation of "foo", the top-level definition of $a is > in scope, so the value is 1. > > For the invocation of "bar", "bar" overrides the definition of $a, and > so when it executes "foo" the value is 2. > > For the final invocation of "foo", the value of $a is overridden for > that one call, and so the value is 3. > > >> Error messages should be less about the way a programmer sees an >> internal function failing and more about what the designer/user might >> have done. This might require a bit of work to suggest issues that >> started in earlier lines but some might be easy - too many or too few >> "}" could be explained "Missing closing bracket" "More closing >> brackets than opening brackets" This would seem to be easy to detect >> and report. > > I agree that improving the messages would be helpful.  Whether or not > it's easy depends on what kind of compilation infrastructure they're > using.  The compilation infrastructure might not report anything other > than "I wasn't able to match the defined syntax". > >> Missing closing ";" might be suggested when it is easy to guess that >> the syntax would be correct if the earlier line had been closed >> properly. That is, the parser sees a token that is legal but not in >> the right context. This would only be a suggestion to the designer as >> a place to look. 'Did you forget a ";"?' > > Note that some of the most obvious missing-semicolon cases are not > actually syntax errors. > > module foo() > { > echo("foo"); > } > > module bar() > { > echo("bar"); > } > > foo() > bar() > if (true) { > echo("hello"); > } > > is syntactically completely legal.  Doesn't do what you probably > expect, but it's legal. > > (The built-in modules detect this error at run time.  It would be cool > if user-defined modules could get similar detection.  It wouldn't be > as simple as "was children() called"; it would have to involve > remembering whether there are *any* calls to children() or $children > in the module.) > > -- Ron Wheeler Artifact Software 438-345-3369 rwheeler@artifact-software.com
NH
nop head
Mon, Apr 6, 2020 8:26 AM

The parser is automatically generated by yacc, so I don't know if it is
possible to get better syntax error messages. If you load the file into the
editor and hit F5 it will position the cursor where the parser thinks the
error is.

The are no variables in OpenSCAD, global or otherwise, only named
constants, apart from in for loops.

On Mon, 6 Apr 2020 at 05:38, Ron Wheeler via Discuss <
discuss@lists.openscad.org> wrote:

Someone suggested a way to solve my BOM problem with echo and a script. I
am working on that.
I am still not convinced that it is impossible to reliably describe a
"real" global variable.

The missing ";" error message problem is not that OpenSCAD can not
recognize that it is missing but does not give any indication about how it
knew that it was missing.
It seems that it knows that it found a keyword in a context where it was
not allowed.

It would be a bit of work to test that if a ";" had been inserted before
the keyword, the previous block and the current block would be legal and
suggest to the script-writer to look to see if adding the ";" would be the
right thing to do.

This is a common problem in writing scripts but this is clearly an
additional usability feature rather than a functional demand.

Ron

On 2020-04-05 3:22 p.m., Jordan Brown wrote:

On 4/4/2020 4:54 PM, Ron Wheeler via Discuss wrote:

https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables
seems to suggest that user defined variables actually might do this but it
appears that the documentation is wrong or misleading.

Special variables - the ones beginning with $ - are constant too, just
with different scope.

Regular variables have scopes that follow the block structure of the
program:

a = 1;
module foo() {
b = 2;
if (a==b) {
a = 4;
c = 3;
}
}

The scope of the first "a" is the whole file, except the body of the
"if".  The scope of "b" is the module.  The scope of "c" is the body of the
"if" block.  The scope of the "a" in the "if" block is the body of the if
block, overriding/hiding/shadowing the file-scope "a".

This scoping is pretty typical for any block-structured language.

Special variables are scoped according to the execution tree.

$a = 1;

module foo() {
echo($a);
}

module bar() {
$a = 2;
foo();
}

foo();
bar();
foo($a=3);

For the first invocation of "foo", the top-level definition of $a is in
scope, so the value is 1.

For the invocation of "bar", "bar" overrides the definition of $a, and so
when it executes "foo" the value is 2.

For the final invocation of "foo", the value of $a is overridden for that
one call, and so the value is 3.

Error messages should be less about the way a programmer sees an internal
function failing and more about what the designer/user might have done.
This might require a bit of work to suggest issues that started in earlier
lines but some might be easy - too many or too few "}" could be explained
"Missing closing bracket" "More closing brackets than opening brackets"
This would seem to be easy to detect and report.

I agree that improving the messages would be helpful.  Whether or not it's
easy depends on what kind of compilation infrastructure they're using.  The
compilation infrastructure might not report anything other than "I wasn't
able to match the defined syntax".

Missing closing ";" might be suggested when it is easy to guess that the
syntax would be correct if the earlier line had been closed properly. That
is, the parser sees a token that is legal but not in the right context.
This would only be a suggestion to the designer as a place to look. 'Did
you forget a ";"?'

Note that some of the most obvious missing-semicolon cases are not
actually syntax errors.

module foo()
{
echo("foo");
}

module bar()
{
echo("bar");
}

foo()
bar()
if (true) {
echo("hello");
}

is syntactically completely legal.  Doesn't do what you probably expect,
but it's legal.

(The built-in modules detect this error at run time.  It would be cool if
user-defined modules could get similar detection.  It wouldn't be as simple
as "was children() called"; it would have to involve remembering whether
there are any calls to children() or $children in the module.)

--
Ron Wheeler
Artifact Software
438-345-3369rwheeler@artifact-software.com


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

The parser is automatically generated by yacc, so I don't know if it is possible to get better syntax error messages. If you load the file into the editor and hit F5 it will position the cursor where the parser thinks the error is. The are no variables in OpenSCAD, global or otherwise, only named constants, apart from in for loops. On Mon, 6 Apr 2020 at 05:38, Ron Wheeler via Discuss < discuss@lists.openscad.org> wrote: > Someone suggested a way to solve my BOM problem with echo and a script. I > am working on that. > I am still not convinced that it is impossible to reliably describe a > "real" global variable. > > The missing ";" error message problem is not that OpenSCAD can not > recognize that it is missing but does not give any indication about how it > knew that it was missing. > It seems that it knows that it found a keyword in a context where it was > not allowed. > > It would be a bit of work to test that if a ";" had been inserted before > the keyword, the previous block and the current block would be legal and > suggest to the script-writer to look to see if adding the ";" would be the > right thing to do. > > This is a common problem in writing scripts but this is clearly an > additional usability feature rather than a functional demand. > > Ron > > > On 2020-04-05 3:22 p.m., Jordan Brown wrote: > > On 4/4/2020 4:54 PM, Ron Wheeler via Discuss wrote: > > > https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables > seems to suggest that user defined variables actually might do this but it > appears that the documentation is wrong or misleading. > > > Special variables - the ones beginning with $ - are constant too, just > with different scope. > > Regular variables have scopes that follow the block structure of the > program: > > a = 1; > module foo() { > b = 2; > if (a==b) { > a = 4; > c = 3; > } > } > > The scope of the first "a" is the whole file, except the body of the > "if". The scope of "b" is the module. The scope of "c" is the body of the > "if" block. The scope of the "a" in the "if" block is the body of the if > block, overriding/hiding/shadowing the file-scope "a". > > This scoping is pretty typical for any block-structured language. > > Special variables are scoped according to the execution tree. > > $a = 1; > > module foo() { > echo($a); > } > > module bar() { > $a = 2; > foo(); > } > > foo(); > bar(); > foo($a=3); > > For the first invocation of "foo", the top-level definition of $a is in > scope, so the value is 1. > > For the invocation of "bar", "bar" overrides the definition of $a, and so > when it executes "foo" the value is 2. > > For the final invocation of "foo", the value of $a is overridden for that > one call, and so the value is 3. > > > Error messages should be less about the way a programmer sees an internal > function failing and more about what the designer/user might have done. > This might require a bit of work to suggest issues that started in earlier > lines but some might be easy - too many or too few "}" could be explained > "Missing closing bracket" "More closing brackets than opening brackets" > This would seem to be easy to detect and report. > > > I agree that improving the messages would be helpful. Whether or not it's > easy depends on what kind of compilation infrastructure they're using. The > compilation infrastructure might not report anything other than "I wasn't > able to match the defined syntax". > > Missing closing ";" might be suggested when it is easy to guess that the > syntax would be correct if the earlier line had been closed properly. That > is, the parser sees a token that is legal but not in the right context. > This would only be a suggestion to the designer as a place to look. 'Did > you forget a ";"?' > > > Note that some of the most obvious missing-semicolon cases are not > actually syntax errors. > > module foo() > { > echo("foo"); > } > > module bar() > { > echo("bar"); > } > > foo() > bar() > if (true) { > echo("hello"); > } > > is syntactically completely legal. Doesn't do what you probably expect, > but it's legal. > > (The built-in modules detect this error at run time. It would be cool if > user-defined modules could get similar detection. It wouldn't be as simple > as "was children() called"; it would have to involve remembering whether > there are *any* calls to children() or $children in the module.) > > > -- > Ron Wheeler > Artifact Software > 438-345-3369rwheeler@artifact-software.com > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
JB
Jordan Brown
Mon, Apr 6, 2020 5:02 PM

On 4/5/2020 9:37 PM, Ron Wheeler wrote:

Someone suggested a way to solve my BOM problem with echo and a
script. I am working on that.

Another possibility that I think some have used is to write a program in
another language, that emits OpenSCAD as an intermediate form.

I am still not convinced that it is impossible to reliably describe a
"real" global variable.

They don't exist.  There is no way to change the value of a "variable". 
Of course the language could have been designed with conventional
variables and a conventional control flow, but it wasn't.

Moreover, there is no way to get information out of a block or a module,
back to the main body of the program.  (Of course the geometry comes
out, and echo() output comes out, but neither of those is available to
the rest of the program.)

nop head says:

The are no variables in OpenSCAD, global or otherwise, only named
constants, apart from in for loops.

I'd actually argue with even that last exception.  Just as when you
enter a block a second time the "variables" can have different values,
I'd say that each iteration through a for loop has a new instance of the
variable with a new value.  That is,

for (i=[1:3]) {
    foo(i);
}

is equivalent to

group() {
    i = 1;
    foo(i);
}
group() {
    i = 2;
    foo(i);
}
group() {
    i = 3;
    foo(i);
}

Now, that's my mental model, not knowledge of the implementation, but I
think it's consistent.  (I can't think of any way that you can
distinguish the behaviors under the two models, but I prefer the model
that consistently says that you can't change the value of a  variable.)

Sometimes I think of it as a macro language, not a conventional
programming language at all.  Everything that looks like a control
structure is expanded into zero or more instances of its argument.

Most of the time I think of it as a programming language that emits
geometry, but the macro processor model is probably more accurate.

On 4/5/2020 9:37 PM, Ron Wheeler wrote: > Someone suggested a way to solve my BOM problem with echo and a > script. I am working on that. Another possibility that I think some have used is to write a program in another language, that emits OpenSCAD as an intermediate form. > I am still not convinced that it is impossible to reliably describe a > "real" global variable. They don't exist.  There is no way to change the value of a "variable".  Of course the language could have been designed with conventional variables and a conventional control flow, but it wasn't. Moreover, there is no way to get information out of a block or a module, back to the main body of the program.  (Of course the geometry comes out, and echo() output comes out, but neither of those is available to the rest of the program.) nop head says: > The are no variables in OpenSCAD, global or otherwise, only named > constants, apart from in for loops. I'd actually argue with even that last exception.  Just as when you enter a block a second time the "variables" can have different values, I'd say that each iteration through a for loop has a new instance of the variable with a new value.  That is, for (i=[1:3]) {     foo(i); } is equivalent to group() { i = 1; foo(i); } group() { i = 2; foo(i); } group() { i = 3; foo(i); } Now, that's my mental model, not knowledge of the implementation, but I think it's consistent.  (I can't think of any way that you can distinguish the behaviors under the two models, but I prefer the model that consistently says that you can't change the value of a  variable.) Sometimes I think of it as a macro language, not a conventional programming language at all.  Everything that looks like a control structure is expanded into zero or more instances of its argument. Most of the time I think of it as a programming language that emits geometry, but the macro processor model is probably more accurate.
TP
Torsten Paul
Mon, Apr 6, 2020 5:08 PM

On 06.04.20 19:02, Jordan Brown wrote:

On 4/5/2020 9:37 PM, Ron Wheeler wrote:

Someone suggested a way to solve my BOM problem with
echo and a script. I am working on that.

Another possibility that I think some have used is to
write a program in another language, that emits OpenSCAD
as an intermediate form.

True, and there are some use cases where it makes a lot
of sense.

I think it would be still nice to have things like BOM
covered without that. I believe the way to go is what
was already mentioned in a previous post: tagging parts
of the design with meta data.

I've collected some ideas in:
https://github.com/openscad/openscad/wiki/Meta-Data-Use-Cases

This kind of annotations is widely adopted in other
languages and is used to also control external/separate
applications or generators.

ciao,
Torsten.

On 06.04.20 19:02, Jordan Brown wrote: > On 4/5/2020 9:37 PM, Ron Wheeler wrote: >> Someone suggested a way to solve my BOM problem with >> echo and a script. I am working on that. > > Another possibility that I think some have used is to > write a program in another language, that emits OpenSCAD > as an intermediate form. True, and there are some use cases where it makes a lot of sense. I think it would be still nice to have things like BOM covered without that. I believe the way to go is what was already mentioned in a previous post: tagging parts of the design with meta data. I've collected some ideas in: https://github.com/openscad/openscad/wiki/Meta-Data-Use-Cases This kind of annotations is widely adopted in other languages and is used to also control external/separate applications or generators. ciao, Torsten.
WF
William F. Adams
Mon, Apr 6, 2020 5:16 PM

Put me down as another person hoeing this row.
I'd like to see a better option for this sort of thing, but thus far my best first approximation of this is:
 - model in OpenSCAD using Customizer - preserve preset parameters in a JSON file - parse JSON file and act on those numbers in a separate programming tool
Wrote up a bit on this in an article in TUGboat:
http://tug.org/TUGboat/tb40-2/tb125adams-3d.pdf
and beginning to work through it in more detail at:
https://willadams.gitbook.io/design-into-3d/3d-project
I'd be glad of any feedback and commentary (or corrections/suggestions)
William

Put me down as another person hoeing this row. I'd like to see a better option for this sort of thing, but thus far my best first approximation of this is:  - model in OpenSCAD using Customizer - preserve preset parameters in a JSON file - parse JSON file and act on those numbers in a separate programming tool Wrote up a bit on this in an article in TUGboat: http://tug.org/TUGboat/tb40-2/tb125adams-3d.pdf and beginning to work through it in more detail at: https://willadams.gitbook.io/design-into-3d/3d-project I'd be glad of any feedback and commentary (or corrections/suggestions) William