discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

children() and extra unwanted evaluations

N
Neon22
Mon, Mar 7, 2016 5:08 AM

Thanks everyone for the info and examination. I'll go and digest.

Some notes:

  1. @nophead. yes all this is so I can force the children(0) to be the same
    when its evaluated twice. So @kintel indicates it probbaly a bug. If that
    bug is fixed my problem would go away. which is great :)
    However in the meantime it has raised this usse about rands() concept... and
    until its fixed(maybe not) I need to move ahead.

  2. @nophead the $seed varible seems like the right fix for that problem.
    looking into it now. Thanks for the info.

  3. Maybe $seed could be added to the cheatsheet ?

  4. rands() seems to me like its ok for OpenSCAD because its really designed
    to produce a list of numbers.
    E.g. rands(0,100,50); gives a list of 50 random numbers back.
    Its just that usually we want only one, and so we go:
    rands(0,100,1)[0]
    and just ask for one and pick it off the list.

So rands() itself seems quite openscaddy(?)... but picking a specific value
out of rands in a deterministic way becomes tricky because of the way
openSCAD is really a scene description language with a different evaluation
criteria than a general purpose language (as doug points out).

  1. How doug descibes using echo to report the seed - is exactly how I was
    intending to do it.

--
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16311.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Thanks everyone for the info and examination. I'll go and digest. Some notes: 1. @nophead. yes all this is so I can force the children(0) to be the same when its evaluated twice. So @kintel indicates it probbaly a bug. If that bug is fixed my problem would go away. which is great :) However in the meantime it has raised this usse about rands() concept... and until its fixed(maybe not) I need to move ahead. 2. @nophead the $seed varible seems like the right fix for that problem. looking into it now. Thanks for the info. 3. Maybe $seed could be added to the cheatsheet ? 4. rands() seems to me like its ok for OpenSCAD because its really designed to produce a list of numbers. E.g. rands(0,100,50); gives a list of 50 random numbers back. Its just that usually we want only one, and so we go: rands(0,100,1)[0] and just ask for one and pick it off the list. So rands() itself seems quite openscaddy(?)... but picking a specific value out of rands in a deterministic way becomes tricky because of the way openSCAD is really a scene description language with a different evaluation criteria than a general purpose language (as doug points out). 5. How doug descibes using echo to report the seed - is exactly how I was intending to do it. -- View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16311.html Sent from the OpenSCAD mailing list archive at Nabble.com.
M
MichaelAtOz
Mon, Mar 7, 2016 6:12 AM

Neon22 wrote

  1. Maybe $seed could be added to the cheatsheet ?

$seed is not special it is just an example of  $special_variables
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables
which have special scope.
He could have used $hiccups.


Admin - PM me if you need anything, or if I've done something stupid...

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.

The TPP is no simple “trade agreement.”  Fight it! http://www.ourfairdeal.org/  time is running out!

View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16312.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Neon22 wrote > 3. Maybe $seed could be added to the cheatsheet ? $seed is not special it is just an example of $special_variables <https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Other_Language_Features#Special_variables> which have special scope. He could have used $hiccups. ----- Admin - PM me if you need anything, or if I've done something stupid... Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above. The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out! -- View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16312.html Sent from the OpenSCAD mailing list archive at Nabble.com.
N
Neon22
Mon, Mar 7, 2016 7:10 AM

@MichaelAtOz - yeah - I worked that out eventually :)

So I tried @nophead's approach and while it works, it means all random
numbers are the same number which unfortunately also means some boring
results :)
Like this if symmetry (and therefore only 1 value used everywhere):
http://i68.tinypic.com/n5o29w.jpg
http://forum.openscad.org/file/n16313/n5o29w.jpg

or like this when non-symmetrical - and with a random sequence of values:
http://forum.openscad.org/file/n16313/icofo0.jpg

I guess I'll hope for a bugfix and an incremental release :)
Cheers...

--
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

@MichaelAtOz - yeah - I worked that out eventually :) So I tried @nophead's approach and while it works, it means all random numbers are the same number which unfortunately also means some boring results :) Like this if symmetry (and therefore only 1 value used everywhere): http://i68.tinypic.com/n5o29w.jpg <http://forum.openscad.org/file/n16313/n5o29w.jpg> or like this when non-symmetrical - and with a random sequence of values: <http://forum.openscad.org/file/n16313/icofo0.jpg> I guess I'll hope for a bugfix and an incremental release :) Cheers... -- View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Mon, Mar 7, 2016 10:09 AM

Did you try the version where I did $seed+n for the nth call? Another
possibility is rands(a,b,n,$seed)[n - 1] for the nth call.

I think it is possible to code Doug's hash system in user space with the
current OpenScad. I have used hashes for pseudo random but repeatable
results before.

On 7 March 2016 at 07:10, Neon22 mschafer@wireframe.biz wrote:

@MichaelAtOz - yeah - I worked that out eventually :)

So I tried @nophead's approach and while it works, it means all random
numbers are the same number which unfortunately also means some boring
results :)
Like this if symmetry (and therefore only 1 value used everywhere):
http://i68.tinypic.com/n5o29w.jpg
http://forum.openscad.org/file/n16313/n5o29w.jpg

or like this when non-symmetrical - and with a random sequence of values:
http://forum.openscad.org/file/n16313/icofo0.jpg

I guess I'll hope for a bugfix and an incremental release :)
Cheers...

--
View this message in context:
http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

Did you try the version where I did $seed+n for the nth call? Another possibility is rands(a,b,n,$seed)[n - 1] for the nth call. I think it is possible to code Doug's hash system in user space with the current OpenScad. I have used hashes for pseudo random but repeatable results before. On 7 March 2016 at 07:10, Neon22 <mschafer@wireframe.biz> wrote: > @MichaelAtOz - yeah - I worked that out eventually :) > > So I tried @nophead's approach and while it works, it means all random > numbers are the same number which unfortunately also means some boring > results :) > Like this if symmetry (and therefore only 1 value used everywhere): > http://i68.tinypic.com/n5o29w.jpg > <http://forum.openscad.org/file/n16313/n5o29w.jpg> > > or like this when non-symmetrical - and with a random sequence of values: > <http://forum.openscad.org/file/n16313/icofo0.jpg> > > I guess I'll hope for a bugfix and an incremental release :) > Cheers... > > > > -- > View this message in context: > http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html > Sent from the OpenSCAD mailing list archive at Nabble.com. > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
RP
Ronaldo Persiano
Mon, Mar 7, 2016 2:31 PM

As I mentioned before, if you use the same seed each time you call rands
you get the same sequence. That is the seed is for.
In both codes, the original Neon 22's code and in the nop head's code, the
rands in randcyl is called with the same seed  every time and it will
return the very same result. Try this:

echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);

and then this:

echo(rands(0,1,4,seed_value=10));

2016-03-07 7:09 GMT-03:00 nop head nop.head@gmail.com:

Did you try the version where I did $seed+n for the nth call? Another
possibility is rands(a,b,n,$seed)[n - 1] for the nth call.

I think it is possible to code Doug's hash system in user space with the
current OpenScad. I have used hashes for pseudo random but repeatable
results before.

On 7 March 2016 at 07:10, Neon22 mschafer@wireframe.biz wrote:

@MichaelAtOz - yeah - I worked that out eventually :)

So I tried @nophead's approach and while it works, it means all random
numbers are the same number which unfortunately also means some boring
results :)
Like this if symmetry (and therefore only 1 value used everywhere):
http://i68.tinypic.com/n5o29w.jpg
http://forum.openscad.org/file/n16313/n5o29w.jpg

or like this when non-symmetrical - and with a random sequence of values:
http://forum.openscad.org/file/n16313/icofo0.jpg

I guess I'll hope for a bugfix and an incremental release :)
Cheers...

--
View this message in context:
http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

As I mentioned before, if you use the same seed each time you call rands you get the same sequence. That is the seed is for. In both codes, the original Neon 22's code and in the nop head's code, the rands in randcyl is called with the same seed every time and it will return the very same result. Try this: echo(rands(0,1,1,seed_value=10)[0]); echo(rands(0,1,1,seed_value=10)[0]); echo(rands(0,1,1,seed_value=10)[0]); echo(rands(0,1,1,seed_value=10)[0]); and then this: echo(rands(0,1,4,seed_value=10)); 2016-03-07 7:09 GMT-03:00 nop head <nop.head@gmail.com>: > Did you try the version where I did $seed+n for the nth call? Another > possibility is rands(a,b,n,$seed)[n - 1] for the nth call. > > I think it is possible to code Doug's hash system in user space with the > current OpenScad. I have used hashes for pseudo random but repeatable > results before. > > On 7 March 2016 at 07:10, Neon22 <mschafer@wireframe.biz> wrote: > >> @MichaelAtOz - yeah - I worked that out eventually :) >> >> So I tried @nophead's approach and while it works, it means all random >> numbers are the same number which unfortunately also means some boring >> results :) >> Like this if symmetry (and therefore only 1 value used everywhere): >> http://i68.tinypic.com/n5o29w.jpg >> <http://forum.openscad.org/file/n16313/n5o29w.jpg> >> >> or like this when non-symmetrical - and with a random sequence of values: >> <http://forum.openscad.org/file/n16313/icofo0.jpg> >> >> I guess I'll hope for a bugfix and an incremental release :) >> Cheers... >> >> >> >> -- >> View this message in context: >> http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html >> Sent from the OpenSCAD mailing list archive at Nabble.com. >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> > > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
R
Ronaldo
Mon, Mar 7, 2016 3:28 PM

Doug,

I don't believe your proposal would solve the Neon22's question. I
understood that he would like to have distinct results for every call to
randcyl(). And that module m_mirror() calls randcyl() just once.

This latter issue is supposed to be a bug by kintel. And the former is not
solved by your proposal of random().

I would have a similar proposal but with other behaviour. The signature you
suggest would identify a whole series of random numbers starting from the
seed resulting from hashing $seed together the signature. However, each time
random() is called with the same signature it will return the next random
number in the series identified by the signature.

As an example, suppose you have two places in the code where random numbers
are needed and you create two functions to generate them:

sign1 = ["randcyl"];
sign2 = ["randcube"];
function random1() = random(sign1) * 77;
function random2() = random(sign2) * 55;

Each of those function would generate a new random number at each call. The
whole series generated by the first function random1() would change if the
signature sign1 is changed: the signature is part of the seed of that
series. If you want the same series for all the runs it is enough to add as
first line:

$seed = 10: // or any other number

If you want that just the random2() function generates new series at each
run, change sign2 to something like:

sign2 = random(["sign2"]);

I don't know if this proposal is either an imperative or a declarative
solution but it would solve a lot issues in a flexible way.

--
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16316.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

Doug, I don't believe your proposal would solve the Neon22's question. I understood that he would like to have distinct results for every call to randcyl(). And that module m_mirror() calls randcyl() just once. This latter issue is supposed to be a bug by kintel. And the former is not solved by your proposal of random(). I would have a similar proposal but with other behaviour. The signature you suggest would identify a whole series of random numbers starting from the seed resulting from hashing $seed together the signature. However, each time random() is called with the same signature it will return the next random number in the series identified by the signature. As an example, suppose you have two places in the code where random numbers are needed and you create two functions to generate them: sign1 = ["randcyl"]; sign2 = ["randcube"]; function random1() = random(sign1) * 77; function random2() = random(sign2) * 55; Each of those function would generate a new random number at each call. The whole series generated by the first function random1() would change if the signature sign1 is changed: the signature is part of the seed of that series. If you want the same series for all the runs it is enough to add as first line: $seed = 10: // or any other number If you want that just the random2() function generates new series at each run, change sign2 to something like: sign2 = random(["sign2"]); I don't know if this proposal is either an imperative or a declarative solution but it would solve a lot issues in a flexible way. -- View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16316.html Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Mon, Mar 7, 2016 4:09 PM

On 7 March 2016 at 14:31, Ronaldo Persiano rcmpersiano@gmail.com wrote:

As I mentioned before, if you use the same seed each time you call rands
you get the same sequence. That is the seed is for.
In both codes, the original Neon 22's code and in the nop head's code, the
rands in randcyl is called with the same seed  every time and it will
return the very same result. Try this:

echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);
echo(rands(0,1,1,seed_value=10)[0]);

and then this:

echo(rands(0,1,4,seed_value=10));

In my example I generated a new random $seed in m_mirror that is then
passed to its children to use as a seed so each child generates the same
random numbers. If the child wants say three then can used rands(a,b,1,
$seed)[0], rands(c,d,2,$seed)[1] and rands(e,f,3,$seed)[2]. That seems to
work fine in this example

$fn = 32;
module m_mirror() {
$seed = rands(0,1000000,1)[0];
children(0);
mirror([1,0,0])
children(0);
}
module cut_in_half(size)  {
intersection() {
translate([0, -size/2.0, -size/2.0])
cube(size=size, center=false);
children(0);
}
}

module randcyl() {
// use of rands in here shows this object being called twice
echo("randcyl called");
rotate([rands(0,77,1, $seed)[0],45,0])
cylinder(h=rands(4,8,2, $seed)[1], d = rands(.1,5,3,
$seed)[2], center=true);
}

m_mirror() cut_in_half(100) render() randcyl();
translate([0, 5, 0])
m_mirror() cut_in_half(100) render() randcyl();

unless I misunderstand the problem. It isn't very efficient as it is
generating the same sub-sequences over and over again, but I doubt it is a
significant overhead compared to geometry evaluation.

There is still an issue between F5 and F6. I think OpenScad should generate
a new seed each time F5 is run but should save it so F6 always generates
the same sequence as the last F5.

2016-03-07 7:09 GMT-03:00 nop head nop.head@gmail.com:

Did you try the version where I did $seed+n for the nth call? Another
possibility is rands(a,b,n,$seed)[n - 1] for the nth call.

I think it is possible to code Doug's hash system in user space with the
current OpenScad. I have used hashes for pseudo random but repeatable
results before.

On 7 March 2016 at 07:10, Neon22 mschafer@wireframe.biz wrote:

@MichaelAtOz - yeah - I worked that out eventually :)

So I tried @nophead's approach and while it works, it means all random
numbers are the same number which unfortunately also means some boring
results :)
Like this if symmetry (and therefore only 1 value used everywhere):
http://i68.tinypic.com/n5o29w.jpg
http://forum.openscad.org/file/n16313/n5o29w.jpg

or like this when non-symmetrical - and with a random sequence of values:
http://forum.openscad.org/file/n16313/icofo0.jpg

I guess I'll hope for a bugfix and an incremental release :)
Cheers...

--
View this message in context:
http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html
Sent from the OpenSCAD mailing list archive at Nabble.com.


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

On 7 March 2016 at 14:31, Ronaldo Persiano <rcmpersiano@gmail.com> wrote: > As I mentioned before, if you use the same seed each time you call rands > you get the same sequence. That is the seed is for. > In both codes, the original Neon 22's code and in the nop head's code, the > rands in randcyl is called with the same seed every time and it will > return the very same result. Try this: > > echo(rands(0,1,1,seed_value=10)[0]); > echo(rands(0,1,1,seed_value=10)[0]); > echo(rands(0,1,1,seed_value=10)[0]); > echo(rands(0,1,1,seed_value=10)[0]); > > and then this: > > echo(rands(0,1,4,seed_value=10)); > In my example I generated a new random $seed in m_mirror that is then passed to its children to use as a seed so each child generates the same random numbers. If the child wants say three then can used rands(a,b,1, $seed)[0], rands(c,d,2,$seed)[1] and rands(e,f,3,$seed)[2]. That seems to work fine in this example $fn = 32; module m_mirror() { $seed = rands(0,1000000,1)[0]; children(0); mirror([1,0,0]) children(0); } module cut_in_half(size) { intersection() { translate([0, -size/2.0, -size/2.0]) cube(size=size, center=false); children(0); } } module randcyl() { // use of rands in here shows this object being called twice echo("randcyl called"); rotate([rands(0,77,1, $seed)[0],45,0]) cylinder(h=rands(4,8,2, $seed)[1], d = rands(.1,5,3, $seed)[2], center=true); } m_mirror() cut_in_half(100) render() randcyl(); translate([0, 5, 0]) m_mirror() cut_in_half(100) render() randcyl(); unless I misunderstand the problem. It isn't very efficient as it is generating the same sub-sequences over and over again, but I doubt it is a significant overhead compared to geometry evaluation. There is still an issue between F5 and F6. I think OpenScad should generate a new seed each time F5 is run but should save it so F6 always generates the same sequence as the last F5. > 2016-03-07 7:09 GMT-03:00 nop head <nop.head@gmail.com>: > >> Did you try the version where I did $seed+n for the nth call? Another >> possibility is rands(a,b,n,$seed)[n - 1] for the nth call. >> >> I think it is possible to code Doug's hash system in user space with the >> current OpenScad. I have used hashes for pseudo random but repeatable >> results before. >> >> On 7 March 2016 at 07:10, Neon22 <mschafer@wireframe.biz> wrote: >> >>> @MichaelAtOz - yeah - I worked that out eventually :) >>> >>> So I tried @nophead's approach and while it works, it means all random >>> numbers are the same number which unfortunately also means some boring >>> results :) >>> Like this if symmetry (and therefore only 1 value used everywhere): >>> http://i68.tinypic.com/n5o29w.jpg >>> <http://forum.openscad.org/file/n16313/n5o29w.jpg> >>> >>> or like this when non-symmetrical - and with a random sequence of values: >>> <http://forum.openscad.org/file/n16313/icofo0.jpg> >>> >>> I guess I'll hope for a bugfix and an incremental release :) >>> Cheers... >>> >>> >>> >>> -- >>> View this message in context: >>> http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16313.html >>> Sent from the OpenSCAD mailing list archive at Nabble.com. >>> >>> _______________________________________________ >>> OpenSCAD mailing list >>> Discuss@lists.openscad.org >>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >>> >> >> >> _______________________________________________ >> OpenSCAD mailing list >> Discuss@lists.openscad.org >> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >> >> > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org > >
DM
doug moen
Mon, Mar 7, 2016 4:21 PM

@Ronaldo, my proposed random() function is a declarative interface which
provides the following guarantees: it doesn't matter if your function or
module is called more times than you expect, and it doesn't matter if they
are called in a different order than you expect, the results will be the
same. Those guarantees are necessary if we want to keep OpenSCAD as a pure
declarative language. The "bug" where modules are called a different number
of times than expected will not affect the behaviour of random().

But this means you have to write your code differently. The existing
rands() function relies on hidden state, so that successive calls to
rands() with the same arguments will return different results. That kind of
behaviour can only exist in an imperative language, and random() doesn't
work that way. With random(), you have to explicitly construct a signature
argument that is different for each unique random number you want to
generate.

In the example code that I gave, randcyl() will always return the same
results, unless the dynamically scoped $seed variable is different for
different calls.

Let's say you want to call randcyl() 6 times, with a different random
number generated for each call. Then you could do this:

for (i=[1:6])
translate([i*10,0,0]) randcyl($seed=random(["row of randcyl", i]));

Each seed value passed to randcyl is different because they are generated
from different signature lists passed to random().

Once you wrap your head around the coding style, this interface is actually
more powerful, since it gives you precise control over when random number
sequences are different, and when they are the same.

@Ronaldo, my proposed random() function is a declarative interface which provides the following guarantees: it doesn't matter if your function or module is called more times than you expect, and it doesn't matter if they are called in a different order than you expect, the results will be the same. Those guarantees are necessary if we want to keep OpenSCAD as a pure declarative language. The "bug" where modules are called a different number of times than expected will not affect the behaviour of random(). But this means you have to write your code differently. The existing rands() function relies on hidden state, so that successive calls to rands() with the same arguments will return different results. That kind of behaviour can only exist in an imperative language, and random() doesn't work that way. With random(), you have to explicitly construct a signature argument that is different for each unique random number you want to generate. In the example code that I gave, randcyl() will always return the same results, *unless* the dynamically scoped $seed variable is different for different calls. Let's say you want to call randcyl() 6 times, with a different random number generated for each call. Then you could do this: for (i=[1:6]) translate([i*10,0,0]) randcyl($seed=random(["row of randcyl", i])); Each seed value passed to randcyl is different because they are generated from different signature lists passed to random(). Once you wrap your head around the coding style, this interface is actually more powerful, since it gives you precise control over when random number sequences are different, and when they are the same.
DM
doug moen
Mon, Mar 7, 2016 4:56 PM

@Ronaldo wrote:

I would have a similar proposal but with other behaviour. The signature you

suggest would identify a whole series of random numbers starting from the
seed resulting from hashing $seed together the signature. However, each
time random() is called with the same signature it will return the next
random number in the series identified by the signature.

This is still an imperative interface, because it relies on a hidden
mutable global variable that keeps track of the state of each random number
sequence.

The imperative interface is more convenient, especially for simple
examples, because you don't need to construct unique signatures for each
distinct random number.

But the imperative interface also creates more problems, in the context of
a declarative language.

An imperative random number interface can lead to fragile code that breaks
when you try to change it. For example, suppose there is a model that uses
random() to generate an entire family of randomly generated shapes, based
on the $seed. You've experimentally explored this family of shapes by
hitting F5 repeatedly until you got a shape you like. Then you select this
specific shape by fixing the value of $seed. At this point, if the code
relies on an imperative random number generator, then the code is fragile
and hard to change, because moving code around, adding or removing code may
change the random numbers generated in other code that you didn't want to
change, and then you lose the specific shape that you had chosen. With a
declarative random number generator, the code isn't fragile: each random
number is chosen deterministically based on a signature and seed.

The other problem is that an imperative random number generator prevents
OpenSCAD from using standard optimization techniques that work for
declarative languages. Here are two techniques that Marius and I would like
to try out. One is lazy evaluation, where we delay evaluating expressions
and module calls until the result is needed: this is a win if the result is
never needed. This makes the evaluation order hard to predict. Another is
parallel evaluation, where expressions and module calls are evaluated in an
unpredictable order, using multiple cores.

@Ronaldo wrote: I would have a similar proposal but with other behaviour. The signature you > suggest would identify a whole series of random numbers starting from the > seed resulting from hashing $seed together the signature. However, each > time random() is called with the same signature it will return the next > random number in the series identified by the signature. > This is still an imperative interface, because it relies on a hidden mutable global variable that keeps track of the state of each random number sequence. The imperative interface is more convenient, especially for simple examples, because you don't need to construct unique signatures for each distinct random number. But the imperative interface also creates more problems, in the context of a declarative language. An imperative random number interface can lead to fragile code that breaks when you try to change it. For example, suppose there is a model that uses random() to generate an entire family of randomly generated shapes, based on the $seed. You've experimentally explored this family of shapes by hitting F5 repeatedly until you got a shape you like. Then you select this specific shape by fixing the value of $seed. At this point, if the code relies on an imperative random number generator, then the code is fragile and hard to change, because moving code around, adding or removing code may change the random numbers generated in other code that you didn't want to change, and then you lose the specific shape that you had chosen. With a declarative random number generator, the code isn't fragile: each random number is chosen deterministically based on a signature and seed. The other problem is that an imperative random number generator prevents OpenSCAD from using standard optimization techniques that work for declarative languages. Here are two techniques that Marius and I would like to try out. One is lazy evaluation, where we delay evaluating expressions and module calls until the result is needed: this is a win if the result is never needed. This makes the evaluation order hard to predict. Another is parallel evaluation, where expressions and module calls are evaluated in an unpredictable order, using multiple cores.
R
Ronaldo
Mon, Mar 7, 2016 4:59 PM

nop head,

It seems I disregarded the $seed assignment in the beginning of  module
m_mirror() of your code. Sorry.
But that code solves just one of Neon22's issue: randcyl() will generate the
same two solids by m_mirror(). However, I don't see anyway to reproduce the
same result twice which is the random function seed is meant to. If you
comment the $seed assignment in m_mirror(), all m_mirror() calls will
produce the very same solid.

--
View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16320.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

nop head, It seems I disregarded the $seed assignment in the beginning of module m_mirror() of your code. Sorry. But that code solves just one of Neon22's issue: randcyl() will generate the same two solids by m_mirror(). However, I don't see anyway to reproduce the same result twice which is the random function seed is meant to. If you comment the $seed assignment in m_mirror(), all m_mirror() calls will produce the very same solid. -- View this message in context: http://forum.openscad.org/children-and-extra-unwanted-evaluations-tp16291p16320.html Sent from the OpenSCAD mailing list archive at Nabble.com.