undef and detecting invalid operations

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

undef and detecting invalid operations

adrianv
I briefly tested the dev version from Aug 8 and found that the feature
discussed in another thread appears there, but not quite in the form
described in that thread.  

The description in the other thread was that illegal operations that
currently produce undef would generate a warning, but not until the undef
was used in an operation.  It seems that in this version, invalid operations
such as illegal matrix or vector products immediately produce a warning.  

The one issue this raises is that it's not very easy to tell in advance that
an operation is illegal.   There's no obvious way to determine if a variable
is a vector, or a matrix, for example.  We used to detect vectors with

is_list(v) && is_num(0*(v*v))

but this produces an immediate warning now, and in fact simply v*v produces
an immediate warning for lists that aren't vectors.   So if this is staying
this way, then I'm wondering if we can have a mechanism for determining
validity of list data, like is_vector that is true only for a list of
numbers, or is_matrix that is true only for a matrix (list of lists of the
same length).  



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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

JordanBrown
On 8/16/2020 10:57 AM, adrianv wrote:
The one issue this raises is that it's not very easy to tell in advance that
an operation is illegal.   There's no obvious way to determine if a variable
is a vector, or a matrix, for example. [...]

Um... not obvious for whom?  And why?
X = [ 1,2,3 ];
Y = 7;

X is an array.  Y is a number.  X+1 is illegal.  Y[0] is illegal.  You know what types the variables are when you set them.  You need to keep track of types as they flow through the program.  At any given step, that's easy.  When you make a mistake, you get an error.

This is generally easy in a language that's got strong static typing; if you have a mismatch, the compiler complains, and it's checked at every reference.

It's harder in a language like OpenSCAD that I would describe as strongly typed (little automatic conversion) but dynamically typed (the type isn't checked until you actually try to execute an operation).  You need naming and commenting conventions, and you need to pay attention.[*]

If you're trying to detect an illegal operation... why?  If the inputs are the wrong type, then they are the wrong type and an error is appropriate.

I come up with two answers:

  • You want better or earlier errors.  Rather than getting an error from six levels down where the illegal operation finally happened, you want an error at the top that says "Hey, bozo, you passed a string for the length and it needs to be a number".  Pretty much, you want a type assertion; you would actually have been happier if there had been a static typing mechanism so that the infrastructure would do the check for you.
  • You want to implement polymorphism, where two or more types are allowed and yield different (though presumably similar) results.  For instance, rotate() is polymorphic - you can pass it either a single number (interpreted as a rotation around the Z axis) or an array of [x,y,z] rotations.  Note that this isn't about detecting an *illegal* operation - it's about determining the type of a value so as to process it in an appropriate way.

Exactly what problem are you trying to solve?

---

[*] <rant>This is why I think the current tendency towards dynamic typing and weak typing, as exemplified by languages like JavaScript, is simply awful in the long term.  (Python is better in simple cases, but no better in complex cases.)  Debugging large programs is very difficult and programmers need every bit of automated assistance that they can get.  Dynamic typing and weak typing make the language look simpler at the start, but cripple your ability to statically analyze it and detect bugs before actually executing the program.</rant>


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

thehans
In reply to this post by adrianv
These are still fairly simple functions to implement, and much clearer IMO to explicitly check your types than trying a possibly undefined operation to see if it sticks:

// check if a value is a list that contains only numbers (empty list doesn't count)
function is_vecnum(v) = is_list(v) && len(v) && len([for(x=v) if(!is_num(x)) 0]) == 0;

// check if a value is a list that is n elements long and all numbers:
function is_vecn(v,n) = is_list(v) && len(v)==n && len([for(x=v) if(!is_num(x)) 0]) == 0;

// check if a value is a list of lists of numbers, all the same length (again empty list, and list of empty lists don't count)
function is_matrix(m) = is_list(m) && len(m) && is_list(m[0]) && (let(n=len(m[0])) n && len([for(v=m) if(!is_vecn(v,n)) 0]) == 0);


On Sun, Aug 16, 2020 at 12:58 PM adrianv <[hidden email]> wrote:
I briefly tested the dev version from Aug 8 and found that the feature
discussed in another thread appears there, but not quite in the form
described in that thread. 

The description in the other thread was that illegal operations that
currently produce undef would generate a warning, but not until the undef
was used in an operation.  It seems that in this version, invalid operations
such as illegal matrix or vector products immediately produce a warning. 

The one issue this raises is that it's not very easy to tell in advance that
an operation is illegal.   There's no obvious way to determine if a variable
is a vector, or a matrix, for example.  We used to detect vectors with

is_list(v) && is_num(0*(v*v))

but this produces an immediate warning now, and in fact simply v*v produces
an immediate warning for lists that aren't vectors.   So if this is staying
this way, then I'm wondering if we can have a mechanism for determining
validity of list data, like is_vector that is true only for a list of
numbers, or is_matrix that is true only for a matrix (list of lists of the
same length).   



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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

RevarBat
In reply to this post by JordanBrown
First off, when writing a library, you must assume your users will pass you utter garbage sometimes, and you need to call them out on that. 

Second, yes polymorphism is also very useful. 

Third, these “type” checks need to be as fast as possible because some routines that call them may be called very very often themselves. 

-Revar



On Aug 16, 2020, at 11:42 AM, Jordan Brown <[hidden email]> wrote:


X = [ 1,2,3 ];
Y = 7;

X is an array.  Y is a number.  X+1 is illegal.  Y[0] is illegal.  You know what types the variables are when you set them.  You need to keep track of types as they flow through the program.  At any given step, that's easy.  When you make a mistake, you get an error.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

RevarBat
In reply to this post by thehans
We used to use something like the methods below. They were far slower. A LOT slower than (ab)using the built in dot and vector multiplication. 

Since these routines get called a lot in our higher level code, speed is important. 

-Revar


On Aug 16, 2020, at 11:58 AM, Hans L <[hidden email]> wrote:


These are still fairly simple functions to implement, and much clearer IMO to explicitly check your types than trying a possibly undefined operation to see if it sticks:

// check if a value is a list that contains only numbers (empty list doesn't count)
function is_vecnum(v) = is_list(v) && len(v) && len([for(x=v) if(!is_num(x)) 0]) == 0;

// check if a value is a list that is n elements long and all numbers:
function is_vecn(v,n) = is_list(v) && len(v)==n && len([for(x=v) if(!is_num(x)) 0]) == 0;

// check if a value is a list of lists of numbers, all the same length (again empty list, and list of empty lists don't count)
function is_matrix(m) = is_list(m) && len(m) && is_list(m[0]) && (let(n=len(m[0])) n && len([for(v=m) if(!is_vecn(v,n)) 0]) == 0);


On Sun, Aug 16, 2020 at 12:58 PM adrianv <[hidden email]> wrote:
I briefly tested the dev version from Aug 8 and found that the feature
discussed in another thread appears there, but not quite in the form
described in that thread. 

The description in the other thread was that illegal operations that
currently produce undef would generate a warning, but not until the undef
was used in an operation.  It seems that in this version, invalid operations
such as illegal matrix or vector products immediately produce a warning. 

The one issue this raises is that it's not very easy to tell in advance that
an operation is illegal.   There's no obvious way to determine if a variable
is a vector, or a matrix, for example.  We used to detect vectors with

is_list(v) && is_num(0*(v*v))

but this produces an immediate warning now, and in fact simply v*v produces
an immediate warning for lists that aren't vectors.   So if this is staying
this way, then I'm wondering if we can have a mechanism for determining
validity of list data, like is_vector that is true only for a list of
numbers, or is_matrix that is true only for a matrix (list of lists of the
same length).   



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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

adrianv
In reply to this post by JordanBrown
You're actually trivializing that task of determining if a variable holds a
vector.  How can I possibly know if

X = f(1,2,3);

leaves X set equal to a vector or not?  I may *think* I've done everything
right and f is a vector, but I could be wrong.   The function f could do all
sorts of complicated things.  It could have issues with its parameters which
might be out of bounds, causing it to produce a misformed answer.  It could
have a bug and produce by accident [[1,2],3,4]] instead of [1,2,3,4].  In
fact, technically speaking there is no algorithmic method to look at the
code and know that X is a vector, because that problem is equivalent to the
halting problem, which is undecidable.  

So what I'm talking about is validating the inputs to a module or function.
If I write a function and it needs a vector and some other person uses it
and they get a cryptic error when I try to use the vector it's not the best
result.  It's actually not the best result for me either: is it a bug in my
module or an error in how I called it?  So my module might look like

module foo(v) {
  assert(is_vector(v), "Parameter v must be a vector.");
   ...
}

Even in code I wrote myself, without this sort of error handling it is
significantly harder to debug complex code.  I say this from personal
experience.  But if someone else, who doesn't understand how the code works
internally, uses my code then it becomes a much greater challenge to debug
errors where you have passed mismatched parameters.  It's basically just
correct programming to actually check that inputs are valid before trying to
use them.  

Another thing is that my code may want to do something different if the
input is a vector or a matrix, which is another reason for wanting to
distinguish these from each other.  

So how do I write the is_vector() function in such a way that is efficient,
even if the vector has length 100k, for example?  Or if I call is_vector
many times?  If I can't use the v*v trick then I'm probably stuck with
something much slower like

function is_vector(v) =                                    // note code not
tested
let(bad = [for(entry=v) if !is_num(entry) 1])
bad==[];

And more difficult: how do you write is_matrix()?   The naive method is
going to be to loop over the list and call is_vector on every list entry and
also check that they are all the same length.  This is going to be slow.   A
faster method to test if A is a matrix is to compute A*A[0] and check that
it's a vector.  



JordanBrown wrote

> On 8/16/2020 10:57 AM, adrianv wrote:
>> The one issue this raises is that it's not very easy to tell in advance
>> that
>> an operation is illegal.   There's no obvious way to determine if a
>> variable
>> is a vector, or a matrix, for example. [...]
>
> Um... not obvious for whom?  And why?
>
>     X = [ 1,2,3 ];
>     Y = 7;
>
> X is an array.  Y is a number.  X+1 is illegal.  Y[0] is illegal.  You
> know what types the variables are when you set them.  You need to keep
> track of types as they flow through the program.  At any given step,
> that's easy.  When you make a mistake, you get an error.
>
> This is generally easy in a language that's got strong static typing; if
> you have a mismatch, the compiler complains, and it's checked at every
> reference.
>
> It's harder in a language like OpenSCAD that I would describe as
> strongly typed (little automatic conversion) but dynamically typed (the
> type isn't checked until you actually try to execute an operation).  You
> need naming and commenting conventions, and you need to pay attention.[*]
>
> If you're trying to detect an illegal operation... why?  If the inputs
> are the wrong type, then they are the wrong type and an error is
> appropriate.
>
> I come up with two answers:
>
>   * You want better or earlier errors.  Rather than getting an error
>     from six levels down where the illegal operation finally happened,
>     you want an error at the top that says "Hey, bozo, you passed a
>     string for the length and it needs to be a number".  Pretty much,
>     you want a type assertion; you would actually have been happier if
>     there had been a static typing mechanism so that the infrastructure
>     would do the check for you.
>   * You want to implement polymorphism, where two or more types are
>     allowed and yield different (though presumably similar) results. 
>     For instance, rotate() is polymorphic - you can pass it either a
>     single number (interpreted as a rotation around the Z axis) or an
>     array of [x,y,z] rotations.  Note that this isn't about detecting an
>     *illegal* operation - it's about determining the type of a value so
>     as to process it in an appropriate way.
>
> Exactly what problem are you trying to solve?
>
> ---
>
>     [*]
> <rant>
> This is why I think the current tendency towards dynamic
>     typing and weak typing, as exemplified by languages like JavaScript,
>     is simply awful in the long term.  (Python is better in simple
>     cases, but no better in complex cases.)  Debugging large programs is
>     very difficult and programmers need every bit of automated
>     assistance that they can get.  Dynamic typing and weak typing make
>     the language look simpler at the start, but cripple your ability to
>     statically analyze it and detect bugs before actually executing the
>     program.
> </rant>
>
> _______________________________________________
> OpenSCAD mailing list

> Discuss@.openscad

> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org





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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

thehans
Assuming the checks will be too slow sounds like premature optimization to me.

Do you have a real world use case (something actually used to create geometry and not just designed specifically to be difficult) where the functions I posted above for example are unacceptably slow?


On Sun, Aug 16, 2020 at 2:19 PM adrianv <[hidden email]> wrote:
You're actually trivializing that task of determining if a variable holds a
vector.  How can I possibly know if

X = f(1,2,3);

leaves X set equal to a vector or not?  I may *think* I've done everything
right and f is a vector, but I could be wrong.   The function f could do all
sorts of complicated things.  It could have issues with its parameters which
might be out of bounds, causing it to produce a misformed answer.  It could
have a bug and produce by accident [[1,2],3,4]] instead of [1,2,3,4].  In
fact, technically speaking there is no algorithmic method to look at the
code and know that X is a vector, because that problem is equivalent to the
halting problem, which is undecidable.   

So what I'm talking about is validating the inputs to a module or function.
If I write a function and it needs a vector and some other person uses it
and they get a cryptic error when I try to use the vector it's not the best
result.  It's actually not the best result for me either: is it a bug in my
module or an error in how I called it?  So my module might look like

module foo(v) {
  assert(is_vector(v), "Parameter v must be a vector.");
   ...
}

Even in code I wrote myself, without this sort of error handling it is
significantly harder to debug complex code.  I say this from personal
experience.  But if someone else, who doesn't understand how the code works
internally, uses my code then it becomes a much greater challenge to debug
errors where you have passed mismatched parameters.  It's basically just
correct programming to actually check that inputs are valid before trying to
use them. 

Another thing is that my code may want to do something different if the
input is a vector or a matrix, which is another reason for wanting to
distinguish these from each other. 

So how do I write the is_vector() function in such a way that is efficient,
even if the vector has length 100k, for example?  Or if I call is_vector
many times?  If I can't use the v*v trick then I'm probably stuck with
something much slower like

function is_vector(v) =                                    // note code not
tested
let(bad = [for(entry=v) if !is_num(entry) 1])
bad==[];

And more difficult: how do you write is_matrix()?   The naive method is
going to be to loop over the list and call is_vector on every list entry and
also check that they are all the same length.  This is going to be slow.   A
faster method to test if A is a matrix is to compute A*A[0] and check that
it's a vector. 



JordanBrown wrote
> On 8/16/2020 10:57 AM, adrianv wrote:
>> The one issue this raises is that it's not very easy to tell in advance
>> that
>> an operation is illegal.   There's no obvious way to determine if a
>> variable
>> is a vector, or a matrix, for example. [...]
>
> Um... not obvious for whom?  And why?
>
>     X = [ 1,2,3 ];
>     Y = 7;
>
> X is an array.  Y is a number.  X+1 is illegal.  Y[0] is illegal.  You
> know what types the variables are when you set them.  You need to keep
> track of types as they flow through the program.  At any given step,
> that's easy.  When you make a mistake, you get an error.
>
> This is generally easy in a language that's got strong static typing; if
> you have a mismatch, the compiler complains, and it's checked at every
> reference.
>
> It's harder in a language like OpenSCAD that I would describe as
> strongly typed (little automatic conversion) but dynamically typed (the
> type isn't checked until you actually try to execute an operation).  You
> need naming and commenting conventions, and you need to pay attention.[*]
>
> If you're trying to detect an illegal operation... why?  If the inputs
> are the wrong type, then they are the wrong type and an error is
> appropriate.
>
> I come up with two answers:
>
>   * You want better or earlier errors.  Rather than getting an error
>     from six levels down where the illegal operation finally happened,
>     you want an error at the top that says "Hey, bozo, you passed a
>     string for the length and it needs to be a number".  Pretty much,
>     you want a type assertion; you would actually have been happier if
>     there had been a static typing mechanism so that the infrastructure
>     would do the check for you.
>   * You want to implement polymorphism, where two or more types are
>     allowed and yield different (though presumably similar) results. 
>     For instance, rotate() is polymorphic - you can pass it either a
>     single number (interpreted as a rotation around the Z axis) or an
>     array of [x,y,z] rotations.  Note that this isn't about detecting an
>     *illegal* operation - it's about determining the type of a value so
>     as to process it in an appropriate way.
>
> Exactly what problem are you trying to solve?
>
> ---
>
>     [*]
> <rant>
> This is why I think the current tendency towards dynamic
>     typing and weak typing, as exemplified by languages like JavaScript,
>     is simply awful in the long term.  (Python is better in simple
>     cases, but no better in complex cases.)  Debugging large programs is
>     very difficult and programmers need every bit of automated
>     assistance that they can get.  Dynamic typing and weak typing make
>     the language look simpler at the start, but cripple your ability to
>     statically analyze it and detect bugs before actually executing the
>     program.
> </rant>
>
> _______________________________________________
> OpenSCAD mailing list

> Discuss@.openscad

> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org





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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

adrianv
In reply to this post by thehans
These functions get called a LOT in the library, so speed is important.  It
turns out that doing matrix operations is really fast in OpenSCAD, so
anything you can reframe as matrix operations will get faster.  (For
example, I redid bezier calculations using matrices and it got an order of
magnitude faster.)  

Our existing is_vector runs on a length 2000 vector in 0.03 ms.  The version
you propose below takes 1.57 ms.  So it's 52 times slower.  So what, you
say?  Well, this problem was brought to my attention because a certain short
example code produced thousands of warnings in the dev build from calls to
is_vector.  This means that it's going to be slower by several seconds, so
it has a real time impact.  


thehans wrote

> These are still fairly simple functions to implement, and much clearer IMO
> to explicitly check your types than trying a possibly undefined operation
> to see if it sticks:
>
> // check if a value is a list that contains only numbers (empty list
> doesn't count)
> function is_vecnum(v) = is_list(v) && len(v) && len([for(x=v)
> if(!is_num(x)) 0]) == 0;
>
> // check if a value is a list that is n elements long and all numbers:
> function is_vecn(v,n) = is_list(v) && len(v)==n && len([for(x=v)
> if(!is_num(x)) 0]) == 0;
>
> // check if a value is a list of lists of numbers, all the same length
> (again empty list, and list of empty lists don't count)
> function is_matrix(m) = is_list(m) && len(m) && is_list(m[0]) &&
> (let(n=len(m[0])) n && len([for(v=m) if(!is_vecn(v,n)) 0]) == 0);
>
>
> On Sun, Aug 16, 2020 at 12:58 PM adrianv &lt;

> avm4@

> &gt; wrote:
>
>> I briefly tested the dev version from Aug 8 and found that the feature
>> discussed in another thread appears there, but not quite in the form
>> described in that thread.
>>
>> The description in the other thread was that illegal operations that
>> currently produce undef would generate a warning, but not until the undef
>> was used in an operation.  It seems that in this version, invalid
>> operations
>> such as illegal matrix or vector products immediately produce a warning.
>>
>> The one issue this raises is that it's not very easy to tell in advance
>> that
>> an operation is illegal.   There's no obvious way to determine if a
>> variable
>> is a vector, or a matrix, for example.  We used to detect vectors with
>>
>> is_list(v) && is_num(0*(v*v))
>>
>> but this produces an immediate warning now, and in fact simply v*v
>> produces
>> an immediate warning for lists that aren't vectors.   So if this is
>> staying
>> this way, then I'm wondering if we can have a mechanism for determining
>> validity of list data, like is_vector that is true only for a list of
>> numbers, or is_matrix that is true only for a matrix (list of lists of
>> the
>> same length).
>>
>>
>>
>> --
>> 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/

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

Ronaldo
In reply to this post by adrianv
Curiously, that dev still adds vectors of different dimensions without complaints or undef returns! Is that legal? Isn't that idiosyncratic?

Em dom., 16 de ago. de 2020 às 18:58, adrianv <[hidden email]> escreveu:
I briefly tested the dev version from Aug 8 and found that the feature
discussed in another thread appears there, but not quite in the form
described in that thread. 

The description in the other thread was that illegal operations that
currently produce undef would generate a warning, but not until the undef
was used in an operation.  It seems that in this version, invalid operations
such as illegal matrix or vector products immediately produce a warning. 

The one issue this raises is that it's not very easy to tell in advance that
an operation is illegal.   There's no obvious way to determine if a variable
is a vector, or a matrix, for example.  We used to detect vectors with

is_list(v) && is_num(0*(v*v))

but this produces an immediate warning now, and in fact simply v*v produces
an immediate warning for lists that aren't vectors.   So if this is staying
this way, then I'm wondering if we can have a mechanism for determining
validity of list data, like is_vector that is true only for a list of
numbers, or is_matrix that is true only for a matrix (list of lists of the
same length).   


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

thehans
Yes I noticed that while making my changes Ronaldo.  Since it was not already returning undef, I did not change behavior or add a warning, since I figured someone was bound to complain of breaking changes in another important feature that they use thousands of times in their code for whatever reason.

Damned if you do and damned if you don't as always.  


On Sun, Aug 16, 2020 at 3:11 PM Ronaldo Persiano <[hidden email]> wrote:
Curiously, that dev still adds vectors of different dimensions without complaints or undef returns! Is that legal? Isn't that idiosyncratic?

Em dom., 16 de ago. de 2020 às 18:58, adrianv <[hidden email]> escreveu:
I briefly tested the dev version from Aug 8 and found that the feature
discussed in another thread appears there, but not quite in the form
described in that thread. 

The description in the other thread was that illegal operations that
currently produce undef would generate a warning, but not until the undef
was used in an operation.  It seems that in this version, invalid operations
such as illegal matrix or vector products immediately produce a warning. 

The one issue this raises is that it's not very easy to tell in advance that
an operation is illegal.   There's no obvious way to determine if a variable
is a vector, or a matrix, for example.  We used to detect vectors with

is_list(v) && is_num(0*(v*v))

but this produces an immediate warning now, and in fact simply v*v produces
an immediate warning for lists that aren't vectors.   So if this is staying
this way, then I'm wondering if we can have a mechanism for determining
validity of list data, like is_vector that is true only for a list of
numbers, or is_matrix that is true only for a matrix (list of lists of the
same length).   

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: undef and detecting invalid operations

JordanBrown
In reply to this post by adrianv
On 8/16/2020 12:18 PM, adrianv wrote:
You're actually trivializing that task of determining if a variable holds a
vector.

No, I'm not trivializing it.  Rather, I was asking why you want to do it.  And you've answered that (at least for parameters):  earlier and better error messages, and polymorphism.

How can I possibly know if

X = f(1,2,3);

leaves X set equal to a vector or not?

For function returns, I'm inclined to say "because that's what f is defined to return, and you've tested it and are confident that it's correct".  You need to be able to do that with most functions, or you will go insane checking their results.

Of course a test suite might do arbitrarily complex verification of a function's results - but that's not a production use case.


_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org