JB
Jordan Brown
Sun, Jun 21, 2020 12:04 AM
On 6/20/2020 4:43 PM, Hans L wrote:
The answer is actually very simple.
Function or module arguments are not guaranteed to be evaluated in
any particular order
You write: polygon(test(),$fa=0.1,$fs=0.1);
But, you seem to be expecting test() to be evaluated after
assignment of $fa and $fs, which to me is more bizarre than if they
were actually done in order.
The solution is to not write code where any one argument is dependent
on another from the same call being assigned first, and you'll not
have any problems.
My expectation was actually that the $fa and $fs assignments would not
affect the test() invocation, no matter what order they were processed
in, that they would affect only the polygon() invocation.
If you view the $ variables as being sort of like globals, that can
affect the other arguments, then yes, order would matter. But even then
you'd expect it to be either left-to-right or right-to-left. It might
not be something you could rely on, but you'd expect that it would be
one way or the other. But it's not.
(And yes, of course you shouldn't do this in real life. But it's still
interesting to experiment with, to better understand what's happening.)
On 6/20/2020 4:43 PM, Hans L wrote:
> The answer is actually very simple.
> Function or module arguments are not guaranteed to be evaluated in
> any particular order
>
> You write: polygon(test(),$fa=0.1,$fs=0.1);
> But, you seem to be expecting test() to be evaluated *after*
> assignment of $fa and $fs, which to me is more bizarre than if they
> were actually done in order.
>
> The solution is to not write code where any one argument is dependent
> on another from the same call being assigned first, and you'll not
> have any problems.
My expectation was actually that the $fa and $fs assignments would not
affect the test() invocation, no matter what order they were processed
in, that they would affect *only* the polygon() invocation.
If you view the $ variables as being sort of like globals, that can
affect the other arguments, then yes, order would matter. But even then
you'd expect it to be either left-to-right or right-to-left. It might
not be something you could rely on, but you'd expect that it would be
one way or the other. But it's not.
(And yes, of course you shouldn't do this in real life. But it's still
interesting to experiment with, to better understand what's happening.)
HL
Hans L
Sun, Jun 21, 2020 12:12 AM
Also note that if you do require sequential assignment, that is
specifically the purpose of "let()".
It can be used either as a module or part of an expression.
On Sat, Jun 20, 2020 at 7:04 PM Jordan Brown openscad@jordan.maileater.net
wrote:
On 6/20/2020 4:43 PM, Hans L wrote:
The answer is actually very simple.
Function or module arguments are not guaranteed to be evaluated in any
particular order
You write: polygon(test(),$fa=0.1,$fs=0.1);
But, you seem to be expecting test() to be evaluated after assignment of
$fa and $fs, which to me is more bizarre than if they were actually done in
order.
The solution is to not write code where any one argument is dependent on
another from the same call being assigned first, and you'll not have any
problems.
My expectation was actually that the $fa and $fs assignments would not
affect the test() invocation, no matter what order they were processed in,
that they would affect only the polygon() invocation.
If you view the $ variables as being sort of like globals, that can affect
the other arguments, then yes, order would matter. But even then you'd
expect it to be either left-to-right or right-to-left. It might not be
something you could rely on, but you'd expect that it would be one way or
the other. But it's not.
(And yes, of course you shouldn't do this in real life. But it's still
interesting to experiment with, to better understand what's happening.)
Also note that if you *do* require sequential assignment, that is
specifically the purpose of "let()".
It can be used either as a module or part of an expression.
On Sat, Jun 20, 2020 at 7:04 PM Jordan Brown <openscad@jordan.maileater.net>
wrote:
> On 6/20/2020 4:43 PM, Hans L wrote:
>
> The answer is actually very simple.
> Function or module arguments are not guaranteed to be evaluated in any
> particular order
>
> You write: polygon(test(),$fa=0.1,$fs=0.1);
> But, you seem to be expecting test() to be evaluated *after* assignment of
> $fa and $fs, which to me is more bizarre than if they were actually done in
> order.
>
> The solution is to not write code where any one argument is dependent on
> another from the same call being assigned first, and you'll not have any
> problems.
>
>
> My expectation was actually that the $fa and $fs assignments would not
> affect the test() invocation, no matter what order they were processed in,
> that they would affect *only* the polygon() invocation.
>
> If you view the $ variables as being sort of like globals, that can affect
> the other arguments, then yes, order would matter. But even then you'd
> expect it to be either left-to-right or right-to-left. It might not be
> something you could rely on, but you'd expect that it would be one way or
> the other. But it's not.
>
> (And yes, of course you shouldn't do this in real life. But it's still
> interesting to experiment with, to better understand what's happening.)
>
A
adrianv
Sun, Jun 21, 2020 12:20 AM
Your explanation clarified everything for me. Somehow I hadn't thought about
this as an order of evaluation issue. It does mean it's a little clumsy to
propagate $ variables down into functions.
Can you elaborate on what you said below? Do you just mean that I can like
someone suggested earlier in the thread do this:
let($fa=0.1, $fs=0.1) polygon(test());
Or is there some other thing you had in mind?
thehans wrote
Also note that if you do require sequential assignment, that is
specifically the purpose of "let()".
It can be used either as a module or part of an expression.
Your explanation clarified everything for me. Somehow I hadn't thought about
this as an order of evaluation issue. It does mean it's a little clumsy to
propagate $ variables down into functions.
Can you elaborate on what you said below? Do you just mean that I can like
someone suggested earlier in the thread do this:
let($fa=0.1, $fs=0.1) polygon(test());
Or is there some other thing you had in mind?
thehans wrote
> Also note that if you *do* require sequential assignment, that is
> specifically the purpose of "let()".
> It can be used either as a module or part of an expression.
--
Sent from: http://forum.openscad.org/
HL
Hans L
Sun, Jun 21, 2020 1:32 AM
Can you elaborate on what you said below?
OK first, the general distinction between expressions/functions and modules:
functions and expressions result in Values which can be assigned to
variables.
modules (wiki also generally calls these "statements" as opposed to
"expressions") result in Geometry, which is sent to preview/render, but not
assignable to variables*
modules can also have "children", while expressions cannot.
*Not yet anyways, though it's been discussed as a possible future feature.
Wiki references:
Let statement (aka module)
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Let_Statement
"The parameters are evaluated sequentially and may depend on each other"
Let expression
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let
"Sequential assignment of variables inside an expression"
There's even a section about using let() inside of list comprehensions, but
I consider that more or less just another case of let as an expression:
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let_2
Here's a modified example showing how one might user either, and how the
sequence of assignment affects things:
function test(x) =
echo(x,$fn=$fn, $fa=$fa, $fs=$fs)
[[0,0],[1,0],[1,1],[0,1]];
// "let" as a module
// The thing after let(...) is a module: "polygon()", which is a "child"
of the let module.
let(
pv1 = test("1"),
$fa=0.1,
$fs=0.1,
pv2 = test("2")
) polygon(pv1);
// "let" as an expression:
// The thing after let(...) is an expression.
// Can be useful in defining "multi-line" functions.
function other_test() = let(
pv1 = test("3"),
$fa=0.1,
$fs=0.1,
pv2 = test("4")
) pv1;
echo(other_test());
On Sat, Jun 20, 2020 at 7:21 PM adrianv avm4@cornell.edu wrote:
Your explanation clarified everything for me. Somehow I hadn't thought
about
this as an order of evaluation issue. It does mean it's a little clumsy to
propagate $ variables down into functions.
Can you elaborate on what you said below? Do you just mean that I can like
someone suggested earlier in the thread do this:
let($fa=0.1, $fs=0.1) polygon(test());
Or is there some other thing you had in mind?
thehans wrote
Also note that if you do require sequential assignment, that is
specifically the purpose of "let()".
It can be used either as a module or part of an expression.
> Can you elaborate on what you said below?
OK first, the general distinction between expressions/functions and modules:
functions and expressions result in Values which can be assigned to
variables.
modules (wiki also generally calls these "statements" as opposed to
"expressions") result in Geometry, which is sent to preview/render, but not
assignable to variables*
modules can also have "children", while expressions cannot.
*Not yet anyways, though it's been discussed as a possible future feature.
Wiki references:
Let statement (aka module)
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Let_Statement
"The parameters are evaluated sequentially and may depend on each other"
Let expression
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let
"Sequential assignment of variables inside an expression"
There's even a section about using let() inside of list comprehensions, but
I consider that more or less just another case of let as an expression:
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let_2
Here's a modified example showing how one might user either, and how the
sequence of assignment affects things:
function test(x) =
echo(x,$fn=$fn, $fa=$fa, $fs=$fs)
[[0,0],[1,0],[1,1],[0,1]];
// "let" as a module
// The thing after let(...) is a module: "polygon()", which is a "child"
of the let module.
let(
pv1 = test("1"),
$fa=0.1,
$fs=0.1,
pv2 = test("2")
) polygon(pv1);
// "let" as an expression:
// The thing after let(...) is an expression.
// Can be useful in defining "multi-line" functions.
function other_test() = let(
pv1 = test("3"),
$fa=0.1,
$fs=0.1,
pv2 = test("4")
) pv1;
echo(other_test());
On Sat, Jun 20, 2020 at 7:21 PM adrianv <avm4@cornell.edu> wrote:
> Your explanation clarified everything for me. Somehow I hadn't thought
> about
> this as an order of evaluation issue. It does mean it's a little clumsy to
> propagate $ variables down into functions.
>
> Can you elaborate on what you said below? Do you just mean that I can like
> someone suggested earlier in the thread do this:
>
> let($fa=0.1, $fs=0.1) polygon(test());
>
> Or is there some other thing you had in mind?
>
>
> thehans wrote
> > Also note that if you *do* require sequential assignment, that is
> > specifically the purpose of "let()".
> > It can be used either as a module or part of an expression.
>
>
>
>
>
> --
> Sent from: http://forum.openscad.org/
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
HL
Hans L
Sun, Jun 21, 2020 2:00 AM
Also I should have probably been more clear that I meant "function calls"
and "module instantiations" in the above explanation, to distinguish from
the definitions of modules or functions.
The explanation gets slightly muddier still if you consider the
experimental "function-literals" feature, where the function
definition itself can be an expression.
On Sat, Jun 20, 2020 at 8:32 PM Hans L thehans@gmail.com wrote:
Can you elaborate on what you said below?
OK first, the general distinction between expressions/functions and
modules:
functions and expressions result in Values which can be assigned to
variables.
modules (wiki also generally calls these "statements" as opposed to
"expressions") result in Geometry, which is sent to preview/render, but not
assignable to variables*
modules can also have "children", while expressions cannot.
*Not yet anyways, though it's been discussed as a possible future feature.
Wiki references:
Let statement (aka module)
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Let_Statement
"The parameters are evaluated sequentially and may depend on each
other"
Let expression
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let
"Sequential assignment of variables inside an expression"
There's even a section about using let() inside of list comprehensions,
but I consider that more or less just another case of let as an expression:
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let_2
Here's a modified example showing how one might user either, and how the
sequence of assignment affects things:
function test(x) =
echo(x,$fn=$fn, $fa=$fa, $fs=$fs)
[[0,0],[1,0],[1,1],[0,1]];
// "let" as a module
// The thing after let(...) is a module: "polygon()", which is a "child"
of the let module.
let(
pv1 = test("1"),
$fa=0.1,
$fs=0.1,
pv2 = test("2")
) polygon(pv1);
// "let" as an expression:
// The thing after let(...) is an expression.
// Can be useful in defining "multi-line" functions.
function other_test() = let(
pv1 = test("3"),
$fa=0.1,
$fs=0.1,
pv2 = test("4")
) pv1;
echo(other_test());
On Sat, Jun 20, 2020 at 7:21 PM adrianv avm4@cornell.edu wrote:
Your explanation clarified everything for me. Somehow I hadn't thought
about
this as an order of evaluation issue. It does mean it's a little clumsy
to
propagate $ variables down into functions.
Can you elaborate on what you said below? Do you just mean that I can
like
someone suggested earlier in the thread do this:
let($fa=0.1, $fs=0.1) polygon(test());
Or is there some other thing you had in mind?
thehans wrote
Also note that if you do require sequential assignment, that is
specifically the purpose of "let()".
It can be used either as a module or part of an expression.
Also I should have probably been more clear that I meant "function calls"
and "module instantiations" in the above explanation, to distinguish from
the *definitions* of modules or functions.
The explanation gets slightly muddier still if you consider the
experimental "function-literals" feature, where the function
definition itself can be an expression.
On Sat, Jun 20, 2020 at 8:32 PM Hans L <thehans@gmail.com> wrote:
> > Can you elaborate on what you said below?
>
> OK first, the general distinction between expressions/functions and
> modules:
> functions and expressions result in Values which can be assigned to
> variables.
> modules (wiki also generally calls these "statements" as opposed to
> "expressions") result in Geometry, which is sent to preview/render, but not
> assignable to variables*
> modules can also have "children", while expressions cannot.
> *Not yet anyways, though it's been discussed as a possible future feature.
>
> Wiki references:
>
> Let statement (aka module)
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Let_Statement
> "The parameters are evaluated sequentially and may depend on each
> other"
>
> Let expression
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let
> "Sequential assignment of variables inside an expression"
>
> There's even a section about using let() inside of list comprehensions,
> but I consider that more or less just another case of let as an expression:
>
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let_2
>
> Here's a modified example showing how one might user either, and how the
> sequence of assignment affects things:
>
> function test(x) =
> echo(x,$fn=$fn, $fa=$fa, $fs=$fs)
> [[0,0],[1,0],[1,1],[0,1]];
>
> // "let" as a module
> // The thing after let(...) is a module: "polygon()", which is a "child"
> of the let module.
> let(
> pv1 = test("1"),
> $fa=0.1,
> $fs=0.1,
> pv2 = test("2")
> ) polygon(pv1);
>
> // "let" as an expression:
> // The thing after let(...) is an expression.
> // Can be useful in defining "multi-line" functions.
> function other_test() = let(
> pv1 = test("3"),
> $fa=0.1,
> $fs=0.1,
> pv2 = test("4")
> ) pv1;
>
> echo(other_test());
>
>
> On Sat, Jun 20, 2020 at 7:21 PM adrianv <avm4@cornell.edu> wrote:
>
>> Your explanation clarified everything for me. Somehow I hadn't thought
>> about
>> this as an order of evaluation issue. It does mean it's a little clumsy
>> to
>> propagate $ variables down into functions.
>>
>> Can you elaborate on what you said below? Do you just mean that I can
>> like
>> someone suggested earlier in the thread do this:
>>
>> let($fa=0.1, $fs=0.1) polygon(test());
>>
>> Or is there some other thing you had in mind?
>>
>>
>> thehans wrote
>> > Also note that if you *do* require sequential assignment, that is
>> > specifically the purpose of "let()".
>> > It can be used either as a module or part of an expression.
>>
>>
>>
>>
>>
>> --
>> Sent from: http://forum.openscad.org/
>>
>> _______________________________________________
>> OpenSCAD mailing list
>> Discuss@lists.openscad.org
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>
A
adrianv
Sun, Jun 21, 2020 3:15 AM
I've written thousands of lines of OpenSCAD code, so I've used let() plenty.
My problem was not understanding what let() does but muddy thinking about $
variables and what it means when you put a $ variable assignment into a
module or function argument.
I do feel concerned that the new function literals with no shorthand
mechanism for converting a function into a function literal mean that I'll
have to abandon using functions and use only function literals. Either
that or use function literals sometimes and functions other times and it
will be confusing. Or double-define anything you might want to use as an
argument as a function literal. It seems a little bit of a mess.
thehans wrote
Also I should have probably been more clear that I meant "function calls"
and "module instantiations" in the above explanation, to distinguish from
the definitions of modules or functions.
The explanation gets slightly muddier still if you consider the
experimental "function-literals" feature, where the function
definition itself can be an expression.
On Sat, Jun 20, 2020 at 8:32 PM Hans L <
Can you elaborate on what you said below?
OK first, the general distinction between expressions/functions and
modules:
functions and expressions result in Values which can be assigned to
variables.
modules (wiki also generally calls these "statements" as opposed to
"expressions") result in Geometry, which is sent to preview/render, but
not
assignable to variables*
modules can also have "children", while expressions cannot.
*Not yet anyways, though it's been discussed as a possible future
feature.
Wiki references:
Let statement (aka module)
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Let_Statement
"The parameters are evaluated sequentially and may depend on each
other"
Let expression
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let
"Sequential assignment of variables inside an expression"
There's even a section about using let() inside of list comprehensions,
but I consider that more or less just another case of let as an
expression:
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let_2
Here's a modified example showing how one might user either, and how the
sequence of assignment affects things:
function test(x) =
echo(x,$fn=$fn, $fa=$fa, $fs=$fs)
[[0,0],[1,0],[1,1],[0,1]];
// "let" as a module
// The thing after let(...) is a module: "polygon()", which is a "child"
of the let module.
let(
pv1 = test("1"),
$fa=0.1,
$fs=0.1,
pv2 = test("2")
) polygon(pv1);
// "let" as an expression:
// The thing after let(...) is an expression.
// Can be useful in defining "multi-line" functions.
function other_test() = let(
pv1 = test("3"),
$fa=0.1,
$fs=0.1,
pv2 = test("4")
) pv1;
echo(other_test());
On Sat, Jun 20, 2020 at 7:21 PM adrianv <
Your explanation clarified everything for me. Somehow I hadn't thought
about
this as an order of evaluation issue. It does mean it's a little clumsy
to
propagate $ variables down into functions.
Can you elaborate on what you said below? Do you just mean that I can
like
someone suggested earlier in the thread do this:
let($fa=0.1, $fs=0.1) polygon(test());
Or is there some other thing you had in mind?
thehans wrote
Also note that if you do require sequential assignment, that is
specifically the purpose of "let()".
It can be used either as a module or part of an expression.
I've written thousands of lines of OpenSCAD code, so I've used let() plenty.
My problem was not understanding what let() does but muddy thinking about $
variables and what it means when you put a $ variable assignment into a
module or function argument.
I do feel concerned that the new function literals with no shorthand
mechanism for converting a function into a function literal mean that I'll
have to abandon using functions and use only function literals. Either
that or use function literals sometimes and functions other times and it
will be confusing. Or double-define anything you might want to use as an
argument as a function literal. It seems a little bit of a mess.
thehans wrote
> Also I should have probably been more clear that I meant "function calls"
> and "module instantiations" in the above explanation, to distinguish from
> the *definitions* of modules or functions.
>
> The explanation gets slightly muddier still if you consider the
> experimental "function-literals" feature, where the function
> definition itself can be an expression.
>
> On Sat, Jun 20, 2020 at 8:32 PM Hans L <
> thehans@
> > wrote:
>
>> > Can you elaborate on what you said below?
>>
>> OK first, the general distinction between expressions/functions and
>> modules:
>> functions and expressions result in Values which can be assigned to
>> variables.
>> modules (wiki also generally calls these "statements" as opposed to
>> "expressions") result in Geometry, which is sent to preview/render, but
>> not
>> assignable to variables*
>> modules can also have "children", while expressions cannot.
>> *Not yet anyways, though it's been discussed as a possible future
>> feature.
>>
>> Wiki references:
>>
>> Let statement (aka module)
>> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Let_Statement
>> "The parameters are evaluated sequentially and may depend on each
>> other"
>>
>> Let expression
>> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let
>> "Sequential assignment of variables inside an expression"
>>
>> There's even a section about using let() inside of list comprehensions,
>> but I consider that more or less just another case of let as an
>> expression:
>>
>> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let_2
>>
>> Here's a modified example showing how one might user either, and how the
>> sequence of assignment affects things:
>>
>> function test(x) =
>> echo(x,$fn=$fn, $fa=$fa, $fs=$fs)
>> [[0,0],[1,0],[1,1],[0,1]];
>>
>> // "let" as a module
>> // The thing after let(...) is a module: "polygon()", which is a "child"
>> of the let module.
>> let(
>> pv1 = test("1"),
>> $fa=0.1,
>> $fs=0.1,
>> pv2 = test("2")
>> ) polygon(pv1);
>>
>> // "let" as an expression:
>> // The thing after let(...) is an expression.
>> // Can be useful in defining "multi-line" functions.
>> function other_test() = let(
>> pv1 = test("3"),
>> $fa=0.1,
>> $fs=0.1,
>> pv2 = test("4")
>> ) pv1;
>>
>> echo(other_test());
>>
>>
>> On Sat, Jun 20, 2020 at 7:21 PM adrianv <
> avm4@
> > wrote:
>>
>>> Your explanation clarified everything for me. Somehow I hadn't thought
>>> about
>>> this as an order of evaluation issue. It does mean it's a little clumsy
>>> to
>>> propagate $ variables down into functions.
>>>
>>> Can you elaborate on what you said below? Do you just mean that I can
>>> like
>>> someone suggested earlier in the thread do this:
>>>
>>> let($fa=0.1, $fs=0.1) polygon(test());
>>>
>>> Or is there some other thing you had in mind?
>>>
>>>
>>> thehans wrote
>>> > Also note that if you *do* require sequential assignment, that is
>>> > specifically the purpose of "let()".
>>> > It can be used either as a module or part of an expression.
>>>
>>>
>>>
>>>
>>>
>>> --
>>> Sent from: http://forum.openscad.org/
>>>
>>> _______________________________________________
>>> OpenSCAD mailing list
>>>
> Discuss@.openscad
>>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>>
>>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@.openscad
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
--
Sent from: http://forum.openscad.org/
RP
Ronaldo Persiano
Mon, Jun 29, 2020 4:02 AM
There are use cases of assert that require a further explanation.
I usually write much more functions than modules and use assert in
functions to check input data consistency. Typically :
function f(a) =
assert( is_list(a) )
let( b = len(a) )
b;
That works fine. But if I write a module the similar way:
module t(a) {
assert( is_list(a) );
b = len(a);
echo(b);
}
or even using it in a let like:
module t(a) {
let(x = assert( is_list(a) )) { b = 0; echo(b=b); };
b = len(a);
echo(b2=b);
}
and call for instance t(1), I get :
WARNING: len() parameter could not be converted, in file , line 9
ERROR: Assertion '(is_list(a)))' failed in file , line 8
TRACE: called by 'assert', in file , line 8.
TRACE: called by 't', in file , line 13.
That means the system tried to assign len(a) to b before the assert is
called.
To be sure the assert expression is evaluated before, I initialize
something with the assert expression:
module t(a) {
x = assert( is_list(a) );
b = len(a);
echo(b);
}
Is that correct? Is there any other alternative?
Em dom., 21 de jun. de 2020 às 02:33, Hans L <thehans@gmail.com> escreveu:
> OK first, the general distinction between expressions/functions and
> modules:
> functions and expressions result in Values which can be assigned to
> variables.
> modules (wiki also generally calls these "statements" as opposed to
> "expressions") result in Geometry, which is sent to preview/render, but not
> assignable to variables*
> modules can also have "children", while expressions cannot.
> *Not yet anyways, though it's been discussed as a possible future feature.
>
> Wiki references:
>
> Let statement (aka module)
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#Let_Statement
> "The parameters are evaluated sequentially and may depend on each
> other"
>
> Let expression
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let
> "Sequential assignment of variables inside an expression"
>
> There's even a section about using let() inside of list comprehensions,
> but I consider that more or less just another case of let as an expression:
>
> https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language#let_2
>
There are use cases of assert that require a further explanation.
I usually write much more functions than modules and use assert in
functions to check input data consistency. Typically :
function f(a) =
assert( is_list(a) )
let( b = len(a) )
b;
That works fine. But if I write a module the similar way:
module t(a) {
assert( is_list(a) );
b = len(a);
echo(b);
}
or even using it in a let like:
module t(a) {
let(x = assert( is_list(a) )) { b = 0; echo(b=b); };
b = len(a);
echo(b2=b);
}
and call for instance t(1), I get :
WARNING: len() parameter could not be converted, in file , line 9
ERROR: Assertion '(is_list(a)))' failed in file , line 8
TRACE: called by 'assert', in file , line 8.
TRACE: called by 't', in file , line 13.
That means the system tried to assign len(a) to b *before* the assert is
called.
To be sure the assert expression is evaluated before, I initialize
something with the assert expression:
module t(a) {
x = assert( is_list(a) );
b = len(a);
echo(b);
}
Is that correct? Is there any other alternative?
A
adrianv
Mon, Jun 29, 2020 6:52 PM
I asked about this behavior somewhat recently and was told that it had been
fixed in the latest OpenSCAD. Conceivably modules could execute in blocks
so that nothing after an assert runs before the assert. I haven't done
further investigations to see if the behavior has in fact changed. With
random execution order, assertions are basically useless in modules.
But I wonder how does assigning the assert to a variable force the assert to
run before the len evaluation in your example? The two lines remain
independent. It seems like you would need to do something like
x = assert(is_list(a)) 0;
b= x+len(a);
to ensure that the second line cannot run before the first one. Of course
in this simple case one can do
b = assert(is_list(a)) len(b);
but this isn't always possible.
Ronaldo wrote
and call for instance t(1), I get :
WARNING: len() parameter could not be converted, in file , line 9
ERROR: Assertion '(is_list(a)))' failed in file , line 8
TRACE: called by 'assert', in file , line 8.
TRACE: called by 't', in file , line 13.
That means the system tried to assign len(a) to b before the assert is
called.
To be sure the assert expression is evaluated before, I initialize
something with the assert expression:
module t(a) {
x = assert( is_list(a) );
b = len(a);
echo(b);
}
Is that correct? Is there any other alternative?
OpenSCAD mailing list
I asked about this behavior somewhat recently and was told that it had been
fixed in the latest OpenSCAD. Conceivably modules could execute in blocks
so that nothing after an assert runs before the assert. I haven't done
further investigations to see if the behavior has in fact changed. With
random execution order, assertions are basically useless in modules.
But I wonder how does assigning the assert to a variable force the assert to
run before the len evaluation in your example? The two lines remain
independent. It seems like you would need to do something like
x = assert(is_list(a)) 0;
b= x+len(a);
to ensure that the second line cannot run before the first one. Of course
in this simple case one can do
b = assert(is_list(a)) len(b);
but this isn't always possible.
Ronaldo wrote
> and call for instance t(1), I get :
>
> WARNING: len() parameter could not be converted, in file , line 9
>
> ERROR: Assertion '(is_list(a)))' failed in file , line 8
>
> TRACE: called by 'assert', in file , line 8.
>
> TRACE: called by 't', in file , line 13.
>
>
> That means the system tried to assign len(a) to b *before* the assert is
> called.
>
> To be sure the assert expression is evaluated before, I initialize
> something with the assert expression:
>
> module t(a) {
> x = assert( is_list(a) );
> b = len(a);
> echo(b);
> }
>
> Is that correct? Is there any other alternative?
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@.openscad
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
--
Sent from: http://forum.openscad.org/
NH
nop head
Mon, Jun 29, 2020 7:08 PM
But I wonder how does assigning the assert to a variable force the assert
to run before the len evaluation in your example?
I think it is simply that expressions are evaluated before modules are
instantiated, so the function version of assert runs before the module
version, just as the function version of echo runs before the module
version of echo.
The module version of assert doesn't make a lot of sense in this case where
you want it to guard against an error in an expression, rather than just
stopping broken geometry.
On Mon, 29 Jun 2020 at 19:53, adrianv avm4@cornell.edu wrote:
I asked about this behavior somewhat recently and was told that it had been
fixed in the latest OpenSCAD. Conceivably modules could execute in blocks
so that nothing after an assert runs before the assert. I haven't done
further investigations to see if the behavior has in fact changed. With
random execution order, assertions are basically useless in modules.
But I wonder how does assigning the assert to a variable force the assert
to
run before the len evaluation in your example? The two lines remain
independent. It seems like you would need to do something like
x = assert(is_list(a)) 0;
b= x+len(a);
to ensure that the second line cannot run before the first one. Of course
in this simple case one can do
b = assert(is_list(a)) len(b);
but this isn't always possible.
Ronaldo wrote
and call for instance t(1), I get :
WARNING: len() parameter could not be converted, in file , line 9
ERROR: Assertion '(is_list(a)))' failed in file , line 8
TRACE: called by 'assert', in file , line 8.
TRACE: called by 't', in file , line 13.
That means the system tried to assign len(a) to b before the assert is
called.
To be sure the assert expression is evaluated before, I initialize
something with the assert expression:
module t(a) {
x = assert( is_list(a) );
b = len(a);
echo(b);
}
Is that correct? Is there any other alternative?
OpenSCAD mailing list
> But I wonder how does assigning the assert to a variable force the assert
to run before the len evaluation in your example?
I think it is simply that expressions are evaluated before modules are
instantiated, so the function version of assert runs before the module
version, just as the function version of echo runs before the module
version of echo.
The module version of assert doesn't make a lot of sense in this case where
you want it to guard against an error in an expression, rather than just
stopping broken geometry.
On Mon, 29 Jun 2020 at 19:53, adrianv <avm4@cornell.edu> wrote:
> I asked about this behavior somewhat recently and was told that it had been
> fixed in the latest OpenSCAD. Conceivably modules could execute in blocks
> so that nothing after an assert runs before the assert. I haven't done
> further investigations to see if the behavior has in fact changed. With
> random execution order, assertions are basically useless in modules.
>
> But I wonder how does assigning the assert to a variable force the assert
> to
> run before the len evaluation in your example? The two lines remain
> independent. It seems like you would need to do something like
>
> x = assert(is_list(a)) 0;
> b= x+len(a);
>
> to ensure that the second line cannot run before the first one. Of course
> in this simple case one can do
>
> b = assert(is_list(a)) len(b);
>
> but this isn't always possible.
>
>
> Ronaldo wrote
> > and call for instance t(1), I get :
> >
> > WARNING: len() parameter could not be converted, in file , line 9
> >
> > ERROR: Assertion '(is_list(a)))' failed in file , line 8
> >
> > TRACE: called by 'assert', in file , line 8.
> >
> > TRACE: called by 't', in file , line 13.
> >
> >
> > That means the system tried to assign len(a) to b *before* the assert is
> > called.
> >
> > To be sure the assert expression is evaluated before, I initialize
> > something with the assert expression:
> >
> > module t(a) {
> > x = assert( is_list(a) );
> > b = len(a);
> > echo(b);
> > }
> >
> > Is that correct? Is there any other alternative?
> >
> > _______________________________________________
> > OpenSCAD mailing list
>
> > Discuss@.openscad
>
> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
>
>
>
> --
> Sent from: http://forum.openscad.org/
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
A
adrianv
Mon, Jun 29, 2020 8:59 PM
So is the order of evaluation of expressions at all limited, or it's
unspecified? Do they execute in the order they appear in the code?
In the example below, using an assignment means it's now an expression
evaluation instead of a module. Does that guarantee that in the code
dummy = assert(is_list(a));
b=len(a);
that the first line is run first?
It's hard for me to think of an example where you use assert and you want
the code after the assert to run, so the behavior of the assert module seems
to really limit its use.
nophead wrote
But I wonder how does assigning the assert to a variable force the assert
to run before the len evaluation in your example?
I think it is simply that expressions are evaluated before modules are
instantiated, so the function version of assert runs before the module
version, just as the function version of echo runs before the module
version of echo.
The module version of assert doesn't make a lot of sense in this case
where
you want it to guard against an error in an expression, rather than just
stopping broken geometry.
On Mon, 29 Jun 2020 at 19:53, adrianv <
I asked about this behavior somewhat recently and was told that it had
been
fixed in the latest OpenSCAD. Conceivably modules could execute in
blocks
so that nothing after an assert runs before the assert. I haven't done
further investigations to see if the behavior has in fact changed. With
random execution order, assertions are basically useless in modules.
But I wonder how does assigning the assert to a variable force the assert
to
run before the len evaluation in your example? The two lines remain
independent. It seems like you would need to do something like
x = assert(is_list(a)) 0;
b= x+len(a);
to ensure that the second line cannot run before the first one. Of
course
in this simple case one can do
b = assert(is_list(a)) len(b);
but this isn't always possible.
Ronaldo wrote
and call for instance t(1), I get :
WARNING: len() parameter could not be converted, in file , line 9
ERROR: Assertion '(is_list(a)))' failed in file , line 8
TRACE: called by 'assert', in file , line 8.
TRACE: called by 't', in file , line 13.
That means the system tried to assign len(a) to b before the assert
called.
To be sure the assert expression is evaluated before, I initialize
something with the assert expression:
module t(a) {
x = assert( is_list(a) );
b = len(a);
echo(b);
}
Is that correct? Is there any other alternative?
OpenSCAD mailing list
So is the order of evaluation of expressions at all limited, or it's
unspecified? Do they execute in the order they appear in the code?
In the example below, using an assignment means it's now an expression
evaluation instead of a module. Does that guarantee that in the code
dummy = assert(is_list(a));
b=len(a);
that the first line is run first?
It's hard for me to think of an example where you use assert and you want
the code after the assert to run, so the behavior of the assert module seems
to really limit its use.
nophead wrote
>> But I wonder how does assigning the assert to a variable force the assert
> to run before the len evaluation in your example?
>
> I think it is simply that expressions are evaluated before modules are
> instantiated, so the function version of assert runs before the module
> version, just as the function version of echo runs before the module
> version of echo.
>
> The module version of assert doesn't make a lot of sense in this case
> where
> you want it to guard against an error in an expression, rather than just
> stopping broken geometry.
>
>
> On Mon, 29 Jun 2020 at 19:53, adrianv <
> avm4@
> > wrote:
>
>> I asked about this behavior somewhat recently and was told that it had
>> been
>> fixed in the latest OpenSCAD. Conceivably modules could execute in
>> blocks
>> so that nothing after an assert runs before the assert. I haven't done
>> further investigations to see if the behavior has in fact changed. With
>> random execution order, assertions are basically useless in modules.
>>
>> But I wonder how does assigning the assert to a variable force the assert
>> to
>> run before the len evaluation in your example? The two lines remain
>> independent. It seems like you would need to do something like
>>
>> x = assert(is_list(a)) 0;
>> b= x+len(a);
>>
>> to ensure that the second line cannot run before the first one. Of
>> course
>> in this simple case one can do
>>
>> b = assert(is_list(a)) len(b);
>>
>> but this isn't always possible.
>>
>>
>> Ronaldo wrote
>> > and call for instance t(1), I get :
>> >
>> > WARNING: len() parameter could not be converted, in file , line 9
>> >
>> > ERROR: Assertion '(is_list(a)))' failed in file , line 8
>> >
>> > TRACE: called by 'assert', in file , line 8.
>> >
>> > TRACE: called by 't', in file , line 13.
>> >
>> >
>> > That means the system tried to assign len(a) to b *before* the assert
>> is
>> > called.
>> >
>> > To be sure the assert expression is evaluated before, I initialize
>> > something with the assert expression:
>> >
>> > module t(a) {
>> > x = assert( is_list(a) );
>> > b = len(a);
>> > echo(b);
>> > }
>> >
>> > Is that correct? Is there any other alternative?
>> >
>> > _______________________________________________
>> > OpenSCAD mailing list
>>
>> > Discuss@.openscad
>>
>> > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>>
>>
>>
>>
>> --
>> Sent from: http://forum.openscad.org/
>>
>> _______________________________________________
>> OpenSCAD mailing list
>>
> Discuss@.openscad
>> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>>
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@.openscad
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
--
Sent from: http://forum.openscad.org/