A
adrian
Sun, Jan 25, 2015 5:50 PM
When debugging, it would be valuable if I could say something like:
- function fn(x) = assert(dim(x) == 1) 2. let(result = 3.
[for(i=[1:len(x)]) 4. if(i!=len(x)-1) 5. assert(x[i] > x[i-1],
str("@i==",i,". Was ", x[i], " > ", x[i-1], ".")) 6. x[i]-x[i-1] 7.
]) 8. assert(result[0] == 0) assert(len(x) == len(result)+1) result;
Please note that this is quite contrived example, but it demonstrates a
function's precondition, postcondition and an interior straight up
assertion. Also, I've placed line numbers prior to each line of code and
we'll pretend that all lines shown here are in a file called x.scad.
This function shows that it takes only a one dimensional array, where each
element must be less than the one before it and the result must have a first
element be equal to 0 and have one less element then the array passed in.
The result itself is an array where the next element is subtracted from the
current.
If the assert's first parameter is equivalent to false, then it should the
file and line where the assertion occurred, as well as the caller's line all
the way up the stack. Variables are substituted for the parameters with
their values to help in the debugging process. This would be great to be
able to trace back where the problem came from. It would also write out the
1st parameter as a string as well as the result that it gave back. This is
because false can be represented in many different ways and may be useful
when debugging. Something like:
- x=1;21. y=fn(x);
Would output:
ASSERTION FAILURE -> from file x.scad:21 while calling: fn(1) -> in file
x.scad:1 (dim(x) == 1) == false
If an assert has a 2nd parameter, it should evaluate and output that as well
as the programmer can drop a more explicit hint as to what the user of their
function did wrong. So something like this:
- fn([4,undef,3]);
Would output:
ASSERTION FAILURE -> from x.scad:2 while calling: fn([4,undef,3]) -> in
file x.scad:5 (x[i] < x[i+1]) == undef @i==0. Was 4 < undef.
An assert can be placed anywhere prior to an expression and if false, then
should stop the execution in its tracks. An assert is not an expression, it
doesn't return any value and must be bound to an expression. That said,
multiple asserts can be placed next to each other, so they all would be
bound to the expression to the right of the rightmost assert.
Alternatives would be to have specific pre and postcondition constraints as
well as assertions, but I don't think that it would be that great of a gain.
Also, instead of just using the 2nd parameter, we could just use the 2nd on
and treat them as if they were parameters to the str(...) function which
would remove the need for the call to str(...) which might reduce the
typing, but may increase the noise as assert value and assert message can
run together. If done this way, one could still do it the other way and
could be left up to the preference of the programmer of the .scad file.
I think the usefulness to the programmer and user of any .scad library would
benefit. What do you ppl think?
A
--
View this message in context: http://forum.openscad.org/Would-be-nice-to-have-constraints-assertions-on-functions-modules-tp11237.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
When debugging, it would be valuable if I could say something like:
1. function fn(x) = assert(dim(x) == 1) 2. let(result = 3.
[for(i=[1:len(x)]) 4. if(i!=len(x)-1) 5. assert(x[i] > x[i-1],
str("@i==",i,". Was ", x[i], " > ", x[i-1], ".")) 6. x[i]-x[i-1] 7.
]) 8. assert(result[0] == 0) assert(len(x) == len(result)+1) result;
Please note that this is quite contrived example, but it demonstrates a
function's precondition, postcondition and an interior straight up
assertion. Also, I've placed line numbers prior to each line of code and
we'll pretend that all lines shown here are in a file called x.scad.
This function shows that it takes only a one dimensional array, where each
element must be less than the one before it and the result must have a first
element be equal to 0 and have one less element then the array passed in.
The result itself is an array where the next element is subtracted from the
current.
If the assert's first parameter is equivalent to false, then it should the
file and line where the assertion occurred, as well as the caller's line all
the way up the stack. Variables are substituted for the parameters with
their values to help in the debugging process. This would be great to be
able to trace back where the problem came from. It would also write out the
1st parameter as a string as well as the result that it gave back. This is
because false can be represented in many different ways and may be useful
when debugging. Something like:
20. x=1;21. y=fn(x);
Would output:
ASSERTION FAILURE -> from file x.scad:21 while calling: fn(1) -> in file
x.scad:1 (dim(x) == 1) == false
If an assert has a 2nd parameter, it should evaluate and output that as well
as the programmer can drop a more explicit hint as to what the user of their
function did wrong. So something like this:
34. fn([4,undef,3]);
Would output:
ASSERTION FAILURE -> from x.scad:2 while calling: fn([4,undef,3]) -> in
file x.scad:5 (x[i] < x[i+1]) == undef @i==0. Was 4 < undef.
An assert can be placed anywhere prior to an expression and if false, then
should stop the execution in its tracks. An assert is not an expression, it
doesn't return any value and must be bound to an expression. That said,
multiple asserts can be placed next to each other, so they all would be
bound to the expression to the right of the rightmost assert.
Alternatives would be to have specific pre and postcondition constraints as
well as assertions, but I don't think that it would be that great of a gain.
Also, instead of just using the 2nd parameter, we could just use the 2nd on
and treat them as if they were parameters to the str(...) function which
would remove the need for the call to str(...) which might reduce the
typing, but may increase the noise as assert value and assert message can
run together. If done this way, one could still do it the other way and
could be left up to the preference of the programmer of the .scad file.
I think the usefulness to the programmer and user of any .scad library would
benefit. What do you ppl think?
A
--
View this message in context: http://forum.openscad.org/Would-be-nice-to-have-constraints-assertions-on-functions-modules-tp11237.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
A
adrian
Sun, Jan 25, 2015 5:56 PM
BTW, when I said bound to an expression, I'm not really sure if that is how
you do it for let(...) but it would be the same idea as that.
A
--
View this message in context: http://forum.openscad.org/Would-be-nice-to-have-constraints-assertions-on-functions-modules-tp11237p11238.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
BTW, when I said bound to an expression, I'm not really sure if that is how
you do it for let(...) but it would be the same idea as that.
A
--
View this message in context: http://forum.openscad.org/Would-be-nice-to-have-constraints-assertions-on-functions-modules-tp11237p11238.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
TP
Torsten Paul
Mon, Jan 26, 2015 4:17 AM
On 01/25/2015 06:50 PM, adrian wrote:
I think the usefulness to the programmer and user of any .scad library
would benefit. What do you ppl think?
Maybe add this to https://github.com/openscad/openscad/issues/381
It might not be easy to cover all in the first go as the line
number tracking is very limited currently. That's a big issue
that needs to be solved in itself.
Why tie it to an expression, just to make it usable at any place
where an expression can be used right now? It probably is useful
in a module context too, e.g.
module m() {
assert(...);
...
}
ciao,
Torsten.
On 01/25/2015 06:50 PM, adrian wrote:
> I think the usefulness to the programmer and user of any .scad library
> would benefit. What do you ppl think?
>
Maybe add this to https://github.com/openscad/openscad/issues/381
It might not be easy to cover all in the first go as the line
number tracking is very limited currently. That's a big issue
that needs to be solved in itself.
Why tie it to an expression, just to make it usable at any place
where an expression can be used right now? It probably is useful
in a module context too, e.g.
module m() {
assert(...);
...
}
ciao,
Torsten.
TA
Taahir Ahmed
Mon, Jan 26, 2015 7:00 PM
Sort of a shameless plug --- this patch is still floating around, but has not
made it into mainline.
http://forum.openscad.org/PATCH-Add-function-pre-and-post-conditions-td9493.html
Taahir
Sort of a shameless plug --- this patch is still floating around, but has not
made it into mainline.
http://forum.openscad.org/PATCH-Add-function-pre-and-post-conditions-td9493.html
Taahir
A
adrian
Tue, Jan 27, 2015 12:23 AM
Sort of a shameless plug --- this patch is still floating around, but has
not made it into
mainline.http://forum.openscad.org/PATCH-Add-function-pre-and-post-conditions-td9493.htmlTaahir
This is interesting. I would like your __pre(), __post(), __doc() and
__test() decorators to be implemented. However, the assert() that I propose
/should/ be easier to implement as it probably could piggyback off of how
let() was done and could be used in the interim for the pre and post
decorator conditions you propose without being as big as a discussion.
A
--
View this message in context: http://forum.openscad.org/Would-be-nice-to-have-constraints-assertions-on-functions-modules-tp11237p11247.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Taahir Ahmed wrote
> Sort of a shameless plug --- this patch is still floating around, but has
> not made it into
> mainline.http://forum.openscad.org/PATCH-Add-function-pre-and-post-conditions-td9493.htmlTaahir
This is interesting. I would like your __pre(), __post(), __doc() and
__test() decorators to be implemented. However, the assert() that I propose
/*should*/ be easier to implement as it probably could piggyback off of how
let() was done and could be used in the interim for the pre and post
decorator conditions you propose without being as big as a discussion.
A
--
View this message in context: http://forum.openscad.org/Would-be-nice-to-have-constraints-assertions-on-functions-modules-tp11237p11247.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
A
adrian
Tue, Jan 27, 2015 12:41 AM
On 01/25/2015 06:50 PM, adrian wrote:
I think the usefulness to the programmer and user of any .scad library
would benefit. What do you ppl think?
Sure, I'll do that.
tp3 wrote
It might not be easy to cover all in the first go as the line
number tracking is very limited currently. That's a big issue
that needs to be solved in itself.
Really? Hmmm. Ok, then that could be postponed for a later time. How about
the rest of the output that I stated? Would that be possible? And the text
that an assert outputs could be still used for a person to do a find in the
code at least.
tp3 wrote
Why tie it to an expression, just to make it usable at any place
where an expression can be used right now? It probably is useful
in a module context too, e.g.
Tieing it to an expression was meant for coding simplicity (of modifying the
SCAD parser) since there is already a let() function, it could be
implemented in the same manner which is known to work.
This would still allow it to be put into a module (abit somewhat hackily) by
putting it in the first or in a fake assignment. The assert() idea I had
was mostly for testing near the point of need, but it could be expanded to a
module scope as well. In fact, if we have it as I suggest, one could make a
module that is called assert() and use the hack. I.e.
A
--
View this message in context: http://forum.openscad.org/Would-be-nice-to-have-constraints-assertions-on-functions-modules-tp11237p11249.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
tp3 wrote
> On 01/25/2015 06:50 PM, adrian wrote:
>> I think the usefulness to the programmer and user of any .scad library
> > would benefit. What do you ppl think?
>>
> Maybe add this to https://github.com/openscad/openscad/issues/381
Sure, I'll do that.
tp3 wrote
> It might not be easy to cover all in the first go as the line
> number tracking is very limited currently. That's a big issue
> that needs to be solved in itself.
Really? Hmmm. Ok, then that could be postponed for a later time. How about
the rest of the output that I stated? Would that be possible? And the text
that an assert outputs could be still used for a person to do a find in the
code at least.
tp3 wrote
> Why tie it to an expression, just to make it usable at any place
> where an expression can be used right now? It probably is useful
> in a module context too, e.g.
Tieing it to an expression was meant for coding simplicity (of modifying the
SCAD parser) since there is already a let() function, it could be
implemented in the same manner which is known to work.
This would still allow it to be put into a module (abit somewhat hackily) by
putting it in the first or in a fake assignment. The assert() idea I had
was mostly for testing near the point of need, but it could be expanded to a
module scope as well. In fact, if we have it as I suggest, one could make a
module that is called assert() and use the hack. I.e.
A
--
View this message in context: http://forum.openscad.org/Would-be-nice-to-have-constraints-assertions-on-functions-modules-tp11237p11249.html
Sent from the OpenSCAD mailing list archive at Nabble.com.