discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Assignments using $ variables: why do they fail sometimes?

AM
Adrian Mariano
Mon, Jan 30, 2023 9:42 PM

In BOSL2, many of the modules that create multiple copies of children set $
variables so that your children can vary their behavior.  Consider this
example:

include<BOSL2/std.scad>
xcopies(n=10,spacing=10)  union(){
mytext = str($idx);
text(mytext);
}

It prints the ten digits spread out on the X axis.  But why do I have
"union()" in there?  The reason is that if I remove the union, the code
fails.

WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20
<20,/home/adrian/scad/test9.scad>

<20,/home/adrian/scad/test9.scad>That's strange. Why is $idx unknown? You
can obviously simplify this to

xcopies(n=10,spacing=10)
text(str($idx));

and this version also fails! The simplest obvious scheme tells me that $idx
is undefined. So what's the magic of union?

Another way to fail is to try to assign to a $ variable:

xcopies(n=10,spacing=10) {
$mytext = str($idx);
text($mytext);
}

And another way to succeed is to use let:

xcopies(n=10,spacing=10)
let(mytext = str($idx))
text(mytext);

And this also works:

xcopies(n=10,spacing=10)
echo(sin($idx));

So what's going on here?

In BOSL2, many of the modules that create multiple copies of children set $ variables so that your children can vary their behavior. Consider this example: include<BOSL2/std.scad> xcopies(n=10,spacing=10) union(){ mytext = str($idx); text(mytext); } It prints the ten digits spread out on the X axis. But why do I have "union()" in there? The reason is that if I remove the union, the code fails. WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20 <20,/home/adrian/scad/test9.scad> <20,/home/adrian/scad/test9.scad>That's strange. Why is $idx unknown? You can obviously simplify this to xcopies(n=10,spacing=10) text(str($idx)); and this version also fails! The simplest obvious scheme tells me that $idx is undefined. So what's the magic of union? Another way to fail is to try to assign to a $ variable: xcopies(n=10,spacing=10) { $mytext = str($idx); text($mytext); } And another way to succeed is to use let: xcopies(n=10,spacing=10) let(mytext = str($idx)) text(mytext); And this also works: xcopies(n=10,spacing=10) echo(sin($idx)); So what's going on here?
NH
nop head
Mon, Jan 30, 2023 9:54 PM

It is a long standing bug. I have exactly the same work arounds when I use
my own layout function, although I hadn't seen union() before. You can use
the $ variable in an expression but not in an assignment, unless you use
let.

On Mon, 30 Jan 2023 at 21:46, Adrian Mariano avm4@cornell.edu wrote:

In BOSL2, many of the modules that create multiple copies of children set
$ variables so that your children can vary their behavior.  Consider this
example:

include<BOSL2/std.scad>
xcopies(n=10,spacing=10)  union(){
mytext = str($idx);
text(mytext);
}

It prints the ten digits spread out on the X axis.  But why do I have
"union()" in there?  The reason is that if I remove the union, the code
fails.

WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20
http://20,/home/adrian/scad/test9.scad

http://20,/home/adrian/scad/test9.scadThat's strange. Why is $idx
unknown? You can obviously simplify this to

xcopies(n=10,spacing=10)
text(str($idx));

and this version also fails! The simplest obvious scheme tells me that
$idx is undefined. So what's the magic of union?

Another way to fail is to try to assign to a $ variable:

xcopies(n=10,spacing=10) {
$mytext = str($idx);
text($mytext);
}

And another way to succeed is to use let:

xcopies(n=10,spacing=10)
let(mytext = str($idx))
text(mytext);

And this also works:

xcopies(n=10,spacing=10)
echo(sin($idx));

So what's going on here?


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

It is a long standing bug. I have exactly the same work arounds when I use my own layout function, although I hadn't seen union() before. You can use the $ variable in an expression but not in an assignment, unless you use let. On Mon, 30 Jan 2023 at 21:46, Adrian Mariano <avm4@cornell.edu> wrote: > In BOSL2, many of the modules that create multiple copies of children set > $ variables so that your children can vary their behavior. Consider this > example: > > include<BOSL2/std.scad> > xcopies(n=10,spacing=10) union(){ > mytext = str($idx); > text(mytext); > } > > It prints the ten digits spread out on the X axis. But why do I have > "union()" in there? The reason is that if I remove the union, the code > fails. > > WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20 > <http://20,/home/adrian/scad/test9.scad> > > <http://20,/home/adrian/scad/test9.scad>That's strange. Why is $idx > unknown? You can obviously simplify this to > > xcopies(n=10,spacing=10) > text(str($idx)); > > and this version also fails! The simplest obvious scheme tells me that > $idx is undefined. So what's the magic of union? > > Another way to fail is to try to assign to a $ variable: > > xcopies(n=10,spacing=10) { > $mytext = str($idx); > text($mytext); > } > > And another way to succeed is to use let: > > xcopies(n=10,spacing=10) > let(mytext = str($idx)) > text(mytext); > > And this also works: > > xcopies(n=10,spacing=10) > echo(sin($idx)); > > > So what's going on here? > > > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
AM
Adrian Mariano
Mon, Jan 30, 2023 9:57 PM

What do you mean by "in expressions"?  It failed to do "text(str($idx))"
for example.

On Mon, Jan 30, 2023 at 4:54 PM nop head nop.head@gmail.com wrote:

It is a long standing bug. I have exactly the same work arounds when I use
my own layout function, although I hadn't seen union() before. You can use
the $ variable in an expression but not in an assignment, unless you use
let.

On Mon, 30 Jan 2023 at 21:46, Adrian Mariano avm4@cornell.edu wrote:

In BOSL2, many of the modules that create multiple copies of children set
$ variables so that your children can vary their behavior.  Consider this
example:

include<BOSL2/std.scad>
xcopies(n=10,spacing=10)  union(){
mytext = str($idx);
text(mytext);
}

It prints the ten digits spread out on the X axis.  But why do I have
"union()" in there?  The reason is that if I remove the union, the code
fails.

WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20
http://20,/home/adrian/scad/test9.scad

http://20,/home/adrian/scad/test9.scadThat's strange. Why is $idx
unknown? You can obviously simplify this to

xcopies(n=10,spacing=10)
text(str($idx));

and this version also fails! The simplest obvious scheme tells me that
$idx is undefined. So what's the magic of union?

Another way to fail is to try to assign to a $ variable:

xcopies(n=10,spacing=10) {
$mytext = str($idx);
text($mytext);
}

And another way to succeed is to use let:

xcopies(n=10,spacing=10)
let(mytext = str($idx))
text(mytext);

And this also works:

xcopies(n=10,spacing=10)
echo(sin($idx));

So what's going on here?


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


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

What do you mean by "in expressions"? It failed to do "text(str($idx))" for example. On Mon, Jan 30, 2023 at 4:54 PM nop head <nop.head@gmail.com> wrote: > It is a long standing bug. I have exactly the same work arounds when I use > my own layout function, although I hadn't seen union() before. You can use > the $ variable in an expression but not in an assignment, unless you use > let. > > On Mon, 30 Jan 2023 at 21:46, Adrian Mariano <avm4@cornell.edu> wrote: > >> In BOSL2, many of the modules that create multiple copies of children set >> $ variables so that your children can vary their behavior. Consider this >> example: >> >> include<BOSL2/std.scad> >> xcopies(n=10,spacing=10) union(){ >> mytext = str($idx); >> text(mytext); >> } >> >> It prints the ten digits spread out on the X axis. But why do I have >> "union()" in there? The reason is that if I remove the union, the code >> fails. >> >> WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20 >> <http://20,/home/adrian/scad/test9.scad> >> >> <http://20,/home/adrian/scad/test9.scad>That's strange. Why is $idx >> unknown? You can obviously simplify this to >> >> xcopies(n=10,spacing=10) >> text(str($idx)); >> >> and this version also fails! The simplest obvious scheme tells me that >> $idx is undefined. So what's the magic of union? >> >> Another way to fail is to try to assign to a $ variable: >> >> xcopies(n=10,spacing=10) { >> $mytext = str($idx); >> text($mytext); >> } >> >> And another way to succeed is to use let: >> >> xcopies(n=10,spacing=10) >> let(mytext = str($idx)) >> text(mytext); >> >> And this also works: >> >> xcopies(n=10,spacing=10) >> echo(sin($idx)); >> >> >> So what's going on here? >> >> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JG
Jonathan Gilbert
Mon, Jan 30, 2023 10:10 PM

To be fair, it doesn't fail that last example, BTW:

include <BOSL2/std.scad>
xcopies(n=10,spacing=10) {
text(str($idx));
}

...yields exactly what you'd expect (a string of digits in the scene), no
warnings. Trying to capture the return of str() when its input is $idx
while in the context of xcopies clearly fails though.

I don't immediately see the bug nophead is referring to in Openscad's
github issues, but clearly something's happening with attempting to pass a
$var to str() (possibly other built-in functions)? Two standalone examples
such as:

$x = 1;
m = str($x);
echo(m);

...and:

for (i=[0:9]) {
$l = i;
m = str($l);
echo(m);
}

...both seem to work fine, so perhaps there's something particular about
BOSL2's loop construct?

On Mon, Jan 30, 2023 at 1:58 PM Adrian Mariano avm4@cornell.edu wrote:

What do you mean by "in expressions"?  It failed to do "text(str($idx))"
for example.

On Mon, Jan 30, 2023 at 4:54 PM nop head nop.head@gmail.com wrote:

It is a long standing bug. I have exactly the same work arounds when I
use my own layout function, although I hadn't seen union() before. You can
use the $ variable in an expression but not in an assignment, unless you
use let.

On Mon, 30 Jan 2023 at 21:46, Adrian Mariano avm4@cornell.edu wrote:

In BOSL2, many of the modules that create multiple copies of children
set $ variables so that your children can vary their behavior.  Consider
this example:

include<BOSL2/std.scad>
xcopies(n=10,spacing=10)  union(){
mytext = str($idx);
text(mytext);
}

It prints the ten digits spread out on the X axis.  But why do I have
"union()" in there?  The reason is that if I remove the union, the code
fails.

WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20
http://20,/home/adrian/scad/test9.scad

http://20,/home/adrian/scad/test9.scadThat's strange. Why is $idx
unknown? You can obviously simplify this to

xcopies(n=10,spacing=10)
text(str($idx));

and this version also fails! The simplest obvious scheme tells me that
$idx is undefined. So what's the magic of union?

Another way to fail is to try to assign to a $ variable:

xcopies(n=10,spacing=10) {
$mytext = str($idx);
text($mytext);
}

And another way to succeed is to use let:

xcopies(n=10,spacing=10)
let(mytext = str($idx))
text(mytext);

And this also works:

xcopies(n=10,spacing=10)
echo(sin($idx));

So what's going on here?


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


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


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

To be fair, it doesn't fail that last example, BTW: include <BOSL2/std.scad> xcopies(n=10,spacing=10) { text(str($idx)); } ...yields exactly what you'd expect (a string of digits in the scene), no warnings. Trying to capture the return of str() when its input is $idx while in the context of xcopies clearly fails though. I don't immediately see the bug nophead is referring to in Openscad's github issues, but clearly something's happening with attempting to pass a $var to str() (possibly other built-in functions)? Two standalone examples such as: $x = 1; m = str($x); echo(m); ...and: for (i=[0:9]) { $l = i; m = str($l); echo(m); } ...both seem to work fine, so perhaps there's something particular about BOSL2's loop construct? On Mon, Jan 30, 2023 at 1:58 PM Adrian Mariano <avm4@cornell.edu> wrote: > What do you mean by "in expressions"? It failed to do "text(str($idx))" > for example. > > On Mon, Jan 30, 2023 at 4:54 PM nop head <nop.head@gmail.com> wrote: > >> It is a long standing bug. I have exactly the same work arounds when I >> use my own layout function, although I hadn't seen union() before. You can >> use the $ variable in an expression but not in an assignment, unless you >> use let. >> >> On Mon, 30 Jan 2023 at 21:46, Adrian Mariano <avm4@cornell.edu> wrote: >> >>> In BOSL2, many of the modules that create multiple copies of children >>> set $ variables so that your children can vary their behavior. Consider >>> this example: >>> >>> include<BOSL2/std.scad> >>> xcopies(n=10,spacing=10) union(){ >>> mytext = str($idx); >>> text(mytext); >>> } >>> >>> It prints the ten digits spread out on the X axis. But why do I have >>> "union()" in there? The reason is that if I remove the union, the code >>> fails. >>> >>> WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20 >>> <http://20,/home/adrian/scad/test9.scad> >>> >>> <http://20,/home/adrian/scad/test9.scad>That's strange. Why is $idx >>> unknown? You can obviously simplify this to >>> >>> xcopies(n=10,spacing=10) >>> text(str($idx)); >>> >>> and this version also fails! The simplest obvious scheme tells me that >>> $idx is undefined. So what's the magic of union? >>> >>> Another way to fail is to try to assign to a $ variable: >>> >>> xcopies(n=10,spacing=10) { >>> $mytext = str($idx); >>> text($mytext); >>> } >>> >>> And another way to succeed is to use let: >>> >>> xcopies(n=10,spacing=10) >>> let(mytext = str($idx)) >>> text(mytext); >>> >>> And this also works: >>> >>> xcopies(n=10,spacing=10) >>> echo(sin($idx)); >>> >>> >>> So what's going on here? >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org > -- - Jon Gilbert jong@jong.org / jgilbertsjc@gmail.com
NH
nop head
Mon, Jan 30, 2023 10:10 PM

Actually I don't seem to need the work arounds in OpenSCAD
2021.10.19.ci9029. So maybe it is fixed, or a regression if you are using a
more recent version.

On Mon, 30 Jan 2023 at 21:58, Adrian Mariano avm4@cornell.edu wrote:

What do you mean by "in expressions"?  It failed to do "text(str($idx))"
for example.

On Mon, Jan 30, 2023 at 4:54 PM nop head nop.head@gmail.com wrote:

It is a long standing bug. I have exactly the same work arounds when I
use my own layout function, although I hadn't seen union() before. You can
use the $ variable in an expression but not in an assignment, unless you
use let.

On Mon, 30 Jan 2023 at 21:46, Adrian Mariano avm4@cornell.edu wrote:

In BOSL2, many of the modules that create multiple copies of children
set $ variables so that your children can vary their behavior.  Consider
this example:

include<BOSL2/std.scad>
xcopies(n=10,spacing=10)  union(){
mytext = str($idx);
text(mytext);
}

It prints the ten digits spread out on the X axis.  But why do I have
"union()" in there?  The reason is that if I remove the union, the code
fails.

WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20
http://20,/home/adrian/scad/test9.scad

http://20,/home/adrian/scad/test9.scadThat's strange. Why is $idx
unknown? You can obviously simplify this to

xcopies(n=10,spacing=10)
text(str($idx));

and this version also fails! The simplest obvious scheme tells me that
$idx is undefined. So what's the magic of union?

Another way to fail is to try to assign to a $ variable:

xcopies(n=10,spacing=10) {
$mytext = str($idx);
text($mytext);
}

And another way to succeed is to use let:

xcopies(n=10,spacing=10)
let(mytext = str($idx))
text(mytext);

And this also works:

xcopies(n=10,spacing=10)
echo(sin($idx));

So what's going on here?


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


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


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

Actually I don't seem to need the work arounds in OpenSCAD 2021.10.19.ci9029. So maybe it is fixed, or a regression if you are using a more recent version. On Mon, 30 Jan 2023 at 21:58, Adrian Mariano <avm4@cornell.edu> wrote: > What do you mean by "in expressions"? It failed to do "text(str($idx))" > for example. > > On Mon, Jan 30, 2023 at 4:54 PM nop head <nop.head@gmail.com> wrote: > >> It is a long standing bug. I have exactly the same work arounds when I >> use my own layout function, although I hadn't seen union() before. You can >> use the $ variable in an expression but not in an assignment, unless you >> use let. >> >> On Mon, 30 Jan 2023 at 21:46, Adrian Mariano <avm4@cornell.edu> wrote: >> >>> In BOSL2, many of the modules that create multiple copies of children >>> set $ variables so that your children can vary their behavior. Consider >>> this example: >>> >>> include<BOSL2/std.scad> >>> xcopies(n=10,spacing=10) union(){ >>> mytext = str($idx); >>> text(mytext); >>> } >>> >>> It prints the ten digits spread out on the X axis. But why do I have >>> "union()" in there? The reason is that if I remove the union, the code >>> fails. >>> >>> WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20 >>> <http://20,/home/adrian/scad/test9.scad> >>> >>> <http://20,/home/adrian/scad/test9.scad>That's strange. Why is $idx >>> unknown? You can obviously simplify this to >>> >>> xcopies(n=10,spacing=10) >>> text(str($idx)); >>> >>> and this version also fails! The simplest obvious scheme tells me that >>> $idx is undefined. So what's the magic of union? >>> >>> Another way to fail is to try to assign to a $ variable: >>> >>> xcopies(n=10,spacing=10) { >>> $mytext = str($idx); >>> text($mytext); >>> } >>> >>> And another way to succeed is to use let: >>> >>> xcopies(n=10,spacing=10) >>> let(mytext = str($idx)) >>> text(mytext); >>> >>> And this also works: >>> >>> xcopies(n=10,spacing=10) >>> echo(sin($idx)); >>> >>> >>> So what's going on here? >>> >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
AM
Adrian Mariano
Mon, Jan 30, 2023 10:17 PM

Hmmm.  When I revisited text(str($idx)) it worked.

Note that in the examples Jonathan posted, the $ variable is set in the
same scope and then immediately used.  That's perhaps not the same as
having it set in a parent that then invokes a child that uses the $
variable.

I normally run in the "stable" version,2021.01, since that's what BOSL2 is
supposed to work with.  But I tried in the nightly build and indeed, the
problem has gone away.

On Mon, Jan 30, 2023 at 5:12 PM nop head nop.head@gmail.com wrote:

Actually I don't seem to need the work arounds in OpenSCAD
2021.10.19.ci9029. So maybe it is fixed, or a regression if you are using
a more recent version.

On Mon, 30 Jan 2023 at 21:58, Adrian Mariano avm4@cornell.edu wrote:

What do you mean by "in expressions"?  It failed to do "text(str($idx))"
for example.

On Mon, Jan 30, 2023 at 4:54 PM nop head nop.head@gmail.com wrote:

It is a long standing bug. I have exactly the same work arounds when I
use my own layout function, although I hadn't seen union() before. You can
use the $ variable in an expression but not in an assignment, unless you
use let.

On Mon, 30 Jan 2023 at 21:46, Adrian Mariano avm4@cornell.edu wrote:

In BOSL2, many of the modules that create multiple copies of children
set $ variables so that your children can vary their behavior.  Consider
this example:

include<BOSL2/std.scad>
xcopies(n=10,spacing=10)  union(){
mytext = str($idx);
text(mytext);
}

It prints the ten digits spread out on the X axis.  But why do I have
"union()" in there?  The reason is that if I remove the union, the code
fails.

WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20
http://20,/home/adrian/scad/test9.scad

http://20,/home/adrian/scad/test9.scadThat's strange. Why is $idx
unknown? You can obviously simplify this to

xcopies(n=10,spacing=10)
text(str($idx));

and this version also fails! The simplest obvious scheme tells me that
$idx is undefined. So what's the magic of union?

Another way to fail is to try to assign to a $ variable:

xcopies(n=10,spacing=10) {
$mytext = str($idx);
text($mytext);
}

And another way to succeed is to use let:

xcopies(n=10,spacing=10)
let(mytext = str($idx))
text(mytext);

And this also works:

xcopies(n=10,spacing=10)
echo(sin($idx));

So what's going on here?


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


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


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


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

Hmmm. When I revisited text(str($idx)) it worked. Note that in the examples Jonathan posted, the $ variable is set in the same scope and then immediately used. That's perhaps not the same as having it set in a parent that then invokes a child that uses the $ variable. I normally run in the "stable" version,2021.01, since that's what BOSL2 is supposed to work with. But I tried in the nightly build and indeed, the problem has gone away. On Mon, Jan 30, 2023 at 5:12 PM nop head <nop.head@gmail.com> wrote: > Actually I don't seem to need the work arounds in OpenSCAD > 2021.10.19.ci9029. So maybe it is fixed, or a regression if you are using > a more recent version. > > On Mon, 30 Jan 2023 at 21:58, Adrian Mariano <avm4@cornell.edu> wrote: > >> What do you mean by "in expressions"? It failed to do "text(str($idx))" >> for example. >> >> On Mon, Jan 30, 2023 at 4:54 PM nop head <nop.head@gmail.com> wrote: >> >>> It is a long standing bug. I have exactly the same work arounds when I >>> use my own layout function, although I hadn't seen union() before. You can >>> use the $ variable in an expression but not in an assignment, unless you >>> use let. >>> >>> On Mon, 30 Jan 2023 at 21:46, Adrian Mariano <avm4@cornell.edu> wrote: >>> >>>> In BOSL2, many of the modules that create multiple copies of children >>>> set $ variables so that your children can vary their behavior. Consider >>>> this example: >>>> >>>> include<BOSL2/std.scad> >>>> xcopies(n=10,spacing=10) union(){ >>>> mytext = str($idx); >>>> text(mytext); >>>> } >>>> >>>> It prints the ten digits spread out on the X axis. But why do I have >>>> "union()" in there? The reason is that if I remove the union, the code >>>> fails. >>>> >>>> WARNING: Ignoring unknown variable '$idx' in file test9.scad, line 20 >>>> <http://20,/home/adrian/scad/test9.scad> >>>> >>>> <http://20,/home/adrian/scad/test9.scad>That's strange. Why is $idx >>>> unknown? You can obviously simplify this to >>>> >>>> xcopies(n=10,spacing=10) >>>> text(str($idx)); >>>> >>>> and this version also fails! The simplest obvious scheme tells me that >>>> $idx is undefined. So what's the magic of union? >>>> >>>> Another way to fail is to try to assign to a $ variable: >>>> >>>> xcopies(n=10,spacing=10) { >>>> $mytext = str($idx); >>>> text($mytext); >>>> } >>>> >>>> And another way to succeed is to use let: >>>> >>>> xcopies(n=10,spacing=10) >>>> let(mytext = str($idx)) >>>> text(mytext); >>>> >>>> And this also works: >>>> >>>> xcopies(n=10,spacing=10) >>>> echo(sin($idx)); >>>> >>>> >>>> So what's going on here? >>>> >>>> >>>> _______________________________________________ >>>> OpenSCAD mailing list >>>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> To unsubscribe send an email to discuss-leave@lists.openscad.org >>> >> _______________________________________________ >> OpenSCAD mailing list >> To unsubscribe send an email to discuss-leave@lists.openscad.org >> > _______________________________________________ > OpenSCAD mailing list > To unsubscribe send an email to discuss-leave@lists.openscad.org >
JB
Jordan Brown
Tue, Jan 31, 2023 2:07 AM

I think this is probably the relevant test program:

module foo() {
    a = echo("foo assignments") 0;
    echo("foo modules");
    children();
}

c = echo("top level assignments") 0;
echo("top level modules");

foo() {
    b = echo("child assignments");
    echo("child modules");
}

In 2021.01 that produces:

ECHO: "top level assignments"
ECHO: "top level modules"
ECHO: "child assignments"
ECHO: "foo assignments"
ECHO: "foo modules"
ECHO: "child modules" 

That makes the behavior that you observe totally obvious:  the child
assignments are executed before anything in foo itself is executed.

In a more or less current development tip, the result is:

ECHO: "top level assignments"
ECHO: "top level modules"
ECHO: "foo assignments"
ECHO: "foo modules"
ECHO: "child assignments"
ECHO: "child modules"

Other special cases:

In 2021.01, the child assignments are evaluated exactly once, whether or
not foo calls children().  Kind of unsurprising, since they are
evaluated before anything in foo is evaluated.

In the development tip, child assignments are evaluated once for each
call to children().  Note that this includes zero times if foo never
calls children().

In all versions, all assignments are evaluated before all module calls.

The development tip behavior does seem better, except that multiple
evaluations of the child assignments may be redundant - and, if they
include randomness, may be inconsistent.  (Which means that it wasn't a
strictly compatible change.)

I don't know what the rationale was for the change.  I could research it
if somebody really wanted to know.

I think this is probably the relevant test program: module foo() { a = echo("foo assignments") 0; echo("foo modules"); children(); } c = echo("top level assignments") 0; echo("top level modules"); foo() { b = echo("child assignments"); echo("child modules"); } In 2021.01 that produces: ECHO: "top level assignments" ECHO: "top level modules" ECHO: "child assignments" ECHO: "foo assignments" ECHO: "foo modules" ECHO: "child modules" That makes the behavior that you observe totally obvious:  the child assignments are executed before anything in foo itself is executed. In a more or less current development tip, the result is: ECHO: "top level assignments" ECHO: "top level modules" ECHO: "foo assignments" ECHO: "foo modules" ECHO: "child assignments" ECHO: "child modules" Other special cases: In 2021.01, the child assignments are evaluated exactly once, whether or not foo calls children().  Kind of unsurprising, since they are evaluated before anything in foo is evaluated. In the development tip, child assignments are evaluated once for each call to children().  Note that this includes zero times if foo never calls children(). In all versions, all assignments are evaluated before all module calls. The development tip behavior does seem better, except that multiple evaluations of the child assignments may be redundant - and, if they include randomness, may be inconsistent.  (Which means that it wasn't a strictly compatible change.) I don't know what the rationale was for the change.  I could research it if somebody really wanted to know.
JB
Jordan Brown
Tue, Jan 31, 2023 2:38 AM

For super extra fun, I realized that I should compare when arguments and
defaults were executed.

a = echo("top level assignments");
echo("top level modules");

module foo(arg1 = echo("foo defaults 1") 0, arg2 = echo("foo defaults 2") 0) {
    b = echo("foo assignments");
    echo("foo modules");
    children();
}

foo(echo("top level arguments") 0) {
    c = echo("child assignments") 0;
    echo("child modules");
}

2021.01 says:

ECHO: "top level assignments"
ECHO: "top level modules"
ECHO: "child assignments"
ECHO: "foo defaults 1"
ECHO: "foo defaults 2"
ECHO: "top level arguments"
ECHO: "foo assignments"
ECHO: "foo modules"
ECHO: "child modules"

so note that the defaults are evaluated before the arguments, which
necessarily means that defaults are evaluated and then discarded if the
argument is supplied.

The development tip is more sensible:

ECHO: "top level assignments"
ECHO: "top level modules"
ECHO: "top level arguments"
ECHO: "foo defaults 2"
ECHO: "foo assignments"
ECHO: "foo modules"
ECHO: "child assignments"
ECHO: "child modules"

Note that defaults are evaluated after arguments, and not evaluated if
unused.

For super extra fun, I realized that I should compare when arguments and defaults were executed. a = echo("top level assignments"); echo("top level modules"); module foo(arg1 = echo("foo defaults 1") 0, arg2 = echo("foo defaults 2") 0) { b = echo("foo assignments"); echo("foo modules"); children(); } foo(echo("top level arguments") 0) { c = echo("child assignments") 0; echo("child modules"); } 2021.01 says: ECHO: "top level assignments" ECHO: "top level modules" ECHO: "child assignments" ECHO: "foo defaults 1" ECHO: "foo defaults 2" ECHO: "top level arguments" ECHO: "foo assignments" ECHO: "foo modules" ECHO: "child modules" so note that the defaults are evaluated before the arguments, which necessarily means that defaults are evaluated and then discarded if the argument is supplied. The development tip is more sensible: ECHO: "top level assignments" ECHO: "top level modules" ECHO: "top level arguments" ECHO: "foo defaults 2" ECHO: "foo assignments" ECHO: "foo modules" ECHO: "child assignments" ECHO: "child modules" Note that defaults are evaluated *after* arguments, and not evaluated if unused.
JB
Jordan Brown
Tue, Jan 31, 2023 2:45 AM

The fun just never stops.

module foo(x = echo("defaults") $y) {
    echo(x);
}

$y = 1;
foo($y = echo("arguments") 2);

In 2021.01:

ECHO: "defaults"
ECHO: "arguments"
ECHO: 1

Not what you might want, but unsurprising given the previous results.

In the development tip, drum roll please...

ECHO: "arguments"
ECHO: "defaults"
ECHO: 1
The fun just never stops. module foo(x = echo("defaults") $y) { echo(x); } $y = 1; foo($y = echo("arguments") 2); In 2021.01: ECHO: "defaults" ECHO: "arguments" ECHO: 1 Not what you might want, but unsurprising given the previous results. In the development tip, drum roll please... ECHO: "arguments" ECHO: "defaults" ECHO: 1