What happened to booleans?

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

What happened to booleans?

Ronaldo
In the stable version all that echo false:

echo(true==1);
echo((0==0)==1);
echo(false==0);
echo((0==1)==0);

In the version 2020.07.02, all echo true!

It seems that the identities true==1 and false==0 were valid in ancient versions.

Why the change? Is it intentional? 

That breaks some search() of my codes. 

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

Re: What happened to booleans?

Parkinbot
With 2019.12.21 I get:

echo(true==1);  // false
echo(true==0);  // false

this means not more and not less: a boolean is not a number (apples are no
pears) and you could also write:

echo(true=="1");  // false
echo(true=="0");  // false

Thus any code testing a condition like "true == x" imposes an implicit type
check. Changing this behavior can break such checks as well as reveal buggy
code written under the assumption Booleans are represented as numbers.
In my libs I have tons of code that uses some backward compatible testing
for lists like "a[0]!=undef". Obviously it has the pitfall:

a=[undef, 1,2,3];

But, I can live with it :-), since using is_list() will break even more code
as it hits people using older versions of OpenSCAD who are usally less
experienced programmers.
 
However, of course you are right: There is no obvious reason to drop the
Boolean data type and introduce old fashioned and error prone semantics in
OpenSCAD.




--
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: What happened to booleans?

thehans
This was part of a change to make comparisons more consistent in general.

See my comment here for more explanation:
https://github.com/openscad/openscad/pull/3164#issuecomment-569158586
(Basically try <= or >= operations between 0 / 1 and false / true on
your older versions, and tell me if that makes sense)

Can you provide a self contained example where the change causes a
problem in actual usage?

Boolean types are not "dropped", but there is type coercion which is
now applied consistently between numbers and bools.
is_bool() and is_num() can also be used to determine exact type if needed.


On Sat, Jul 25, 2020 at 9:01 AM Parkinbot <[hidden email]> wrote:

>
> With 2019.12.21 I get:
>
> echo(true==1);  // false
> echo(true==0);  // false
>
> this means not more and not less: a boolean is not a number (apples are no
> pears) and you could also write:
>
> echo(true=="1");  // false
> echo(true=="0");  // false
>
> Thus any code testing a condition like "true == x" imposes an implicit type
> check. Changing this behavior can break such checks as well as reveal buggy
> code written under the assumption Booleans are represented as numbers.
> In my libs I have tons of code that uses some backward compatible testing
> for lists like "a[0]!=undef". Obviously it has the pitfall:
>
> a=[undef, 1,2,3];
>
> But, I can live with it :-), since using is_list() will break even more code
> as it hits people using older versions of OpenSCAD who are usally less
> experienced programmers.
>
> However, of course you are right: There is no obvious reason to drop the
> Boolean data type and introduce old fashioned and error prone semantics in
> OpenSCAD.
>
>
>
>
> --
> 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: What happened to booleans?

Parkinbot
Hans,
with

echo(true>=1); // true
echo(true<=1); // true

it seems consequent to alter the result

echo(true==1); // false -> true

However, I would never try to use

echo(true <= 1);  // true

in user code. But if I was to implement this kind of logic, I would simply
always return "false" whenever the operands don't have the same data type.




--
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: What happened to booleans?

adrianv
In reply to this post by thehans
It seems that the motivation for the changes was a theoretical sorting
process that needs to sort items of different types.  The current dev
version behavior doesn't make much sense and is almost like dropping
booleans and just making "true" a synonym for 1.  Except for the fact that
"3" is true.  And this is a major inconsistency, not an improvement in
consistency as claimed.  

If I search a vector for true entries, e.g. with search([true], [....]) then
the new behavior makes no sense.  It gives me entries that are true and
entries that are 1.  The two defensible results are entries that are exactly
"true" (as happened in older version) or all entries that would be
interpreted as true in a boolean context, which means all strings, nonempty
lists, nonzero numbers, and so on should be returned.   There's no
conceivable reason a user would expect to get back all the "true" and "1"
entries.  It's just not a consistent return result.  Unless true isn't
really a separate boolean type but is just a synonym for 1.  

For relative comparisons it seems like the only reason to compare true to 3
(other than programmer error) is in the sorting context, which was suggested
in the github issue.  But does the choice to make true=1 and false=0
actually make sense?  I argue that it does not.  If I'm sorting a list of
objects I do not find the following to be a reasonable output from a sort
algorithm and can't conceive of a situation where it would be desirable:

[-1, -.5, 0, false, 0, false, .5, 1, true, 1, 1, true, 1.5, 2]

but this would be a legitimate "sorted" output if true==1 and false==0 and
the same for comparisons.  

I note that the same dubious logic has not bee applied to strings.  

echo(""==0);
echo(""<0);
echo("">0);

all give false in both the july dev and the stable version.  Similarly
comparison between lists and scalars also

echo([3]<3);
echo([3]>3);
echo([3]==3);

all give false.  So the user who wants to sort a list mixed with lists and
strings and numbers is still on their own to handle comparisons in a
reasonable manner.  

I can think of two behaviors that make sense for comparisons between types.
They should either be undef, or there should be a defined order OF TYPES, so
for example:

boolean < number < string < list

In this case the above sort example would presumably sort as

[false,false,true,true,-1, -.5, 0,0, .5, 1, 1, 1, 1.5, 2]

I don't think anybody interested in sorting mixed type lists would be happy
with the previous result, where false and 0 intermix and 1 and true
intermix, so such a user would have to write their own comparison operator
that uses is_bool to check the type to produce a reasonable output---either
with the old behavior or the dev behavior.  The updated behavior is
confusing, inconsistent, and hasn't actually helped anything.  Is there a
concrete example where the new behavior is actually useful?

So if you want a concrete example, with the updated behavior, search for
booleans becomes difficult to use because outputs from search must be
post-processed to select only the results with boolean output.  And the
result without such postprocessing is basically nonsense.  

And if I want to search for arrays containing booleans then it's really
painful to screen the return value from search for booleans.  Consider:

search([[true,1]], [[true,true],[true,1],[true,3], [1,true], [1,1], [1,3]],
0)

which returns [[1]] in the old version and [[0, 1, 3, 4]] in the new
version.  For a general search post-process we now need to scan the returned
entries from search and check whether isbool gives the same result on each
entry to identify which ones are valid returns.  What a mess!

I can also say that it's very unexpected to a user that

x==true

will return true when x is equal to 1.  And once this is absorbed,
particularly odd that it returns false when x==3.  In fact, one could argue
that the only reason a user would ever write "x==true" is to check whether x
is in fact exactly equal to the boolean true and not just a value that gets
cast to true in a boolean context.  


thehans wrote

> This was part of a change to make comparisons more consistent in general.
>
> See my comment here for more explanation:
> https://github.com/openscad/openscad/pull/3164#issuecomment-569158586
> (Basically try <= or >= operations between 0 / 1 and false / true on
> your older versions, and tell me if that makes sense)
>
> Can you provide a self contained example where the change causes a
> problem in actual usage?
>
> Boolean types are not "dropped", but there is type coercion which is
> now applied consistently between numbers and bools.
> is_bool() and is_num() can also be used to determine exact type if needed.
>
>
> On Sat, Jul 25, 2020 at 9:01 AM Parkinbot &lt;

> rudolf@

> &gt; wrote:
>>
>> With 2019.12.21 I get:
>>
>> echo(true==1);  // false
>> echo(true==0);  // false
>>
>> this means not more and not less: a boolean is not a number (apples are
>> no
>> pears) and you could also write:
>>
>> echo(true=="1");  // false
>> echo(true=="0");  // false
>>
>> Thus any code testing a condition like "true == x" imposes an implicit
>> type
>> check. Changing this behavior can break such checks as well as reveal
>> buggy
>> code written under the assumption Booleans are represented as numbers.
>> In my libs I have tons of code that uses some backward compatible testing
>> for lists like "a[0]!=undef". Obviously it has the pitfall:
>>
>> a=[undef, 1,2,3];
>>
>> But, I can live with it :-), since using is_list() will break even more
>> code
>> as it hits people using older versions of OpenSCAD who are usally less
>> experienced programmers.
>>
>> However, of course you are right: There is no obvious reason to drop the
>> Boolean data type and introduce old fashioned and error prone semantics
>> in
>> OpenSCAD.
>>
>>
>>
>>
>> --
>> 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: What happened to booleans?

thehans

In cases that expect a boolean such as conditional "if"s, ternary ( ? : ), or "not" ( ! ) operators, etc, numbers have *always* been coerced into bool.  
Where 0 (or -0) is false, and all other numbers are true.

This example has same results in any version including 2015.03 :
for (x=[-1,0,1,3,true,false, 1/0, -1/0, 0/0 ]) {
   if (x) echo(str(x," is 'true'"));
   else echo(str(x," is 'false'"));
   if (!x) echo(str("!",x," is 'true'"));
   else echo(str("!",x," is 'false'"));
}
echo();
for (x=[-1,0,1,3,true,false, 1/0, -1/0, 0/0 ]) {
   echo(str(x," is ", x ? "'true'" : "'false'"));
   echo(str("!",x," is ", !x ? "'true'" : "'false'"));
}

So to me, it seems consistent that if: "if(x)" is true, then "if (x==true)" should also be true.

> For relative comparisons it seems like the only reason to compare true to 3
> (other than programmer error) is in the sorting context, which was suggested
> in the github issue.  But does the choice to make true=1 and false=0
> actually make sense?  I argue that it does not.  If I'm sorting a list of
> objects I do not find the following to be a reasonable output from a sort
> algorithm and can't conceive of a situation where it would be desirable:
>
> [-1, -.5, 0, false, 0, false, .5, 1, true, 1, 1, true, 1.5, 2]
>
> but this would be a legitimate "sorted" output if true==1 and false==0 and
> the same for comparisons.
>

Yes I did mention this in the context of sorting mixed types, but mainly just to say that thinking more closely about how mixed types behave was what led me to discover the inconsistencies in comparison operators.
But I also acknowledged that such sorting would be a weird / rare case, so I'm not really too upset if it would require special handling for a library to support such things.

Also note that even though the sorting seems strange here, this is the exact behavior in Python for example:
Python 3.8.2 (default, Jul 16 2020, 14:00:26)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> x=[-1, -.5, 0, False, 0, False, .5, 1, True, 1, 1, True, 1.5, 2]
>>> y=[-1, -.5, 0, False, 0, False, .5, 1, True, 1, 1, True, 1.5, 2]
>>> x.sort()
>>> x==y
True
>>> x
[-1, -0.5, 0, False, 0, False, 0.5, 1, True, 1, 1, True, 1.5, 2]

If this is "old fashioned" as parkinbot says , then I would be curious to know what modern language(s) which allow mixed type collections, would serve a better role-model for OpenSCAD in this regard.

> So if you want a concrete example, with the updated behavior, search for
> booleans becomes difficult to use because outputs from search must be
> post-processed to select only the results with boolean output.  And the
> result without such postprocessing is basically nonsense.
>
> And if I want to search for arrays containing booleans then it's really
> painful to screen the return value from search for booleans.  Consider:
>
> search([[true,1]], [[true,true],[true,1],[true,3], [1,true], [1,1], [1,3]],
> 0)
>
> which returns [[1]] in the old version and [[0, 1, 3, 4]] in the new
> version.  For a general search post-process we now need to scan the returned
> entries from search and check whether isbool gives the same result on each
> entry to identify which ones are valid returns.  What a mess!

OK, so far I'm hearing that the main thing this actually breaks is certain usages of the builtin search() function, where the user is searching on "keys" of mixed boolean and number types.  Although WHY they would want to do this in a real script is not clear to me (outside of adversarially contrived test-cases).
If this is really wanted/needed for builtin search, then a quick fix could be to change search() so that it checks for strictly matching types in addition to "equivalence".

Hans


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

Re: What happened to booleans?

adrianv
thehans wrote
> In cases that expect a boolean such as conditional "if"s, ternary ( ? : ),
> or "not" ( ! ) operators, etc, numbers have *always* been coerced into
> bool.
> Where 0 (or -0) is false, and all other numbers are true.
>
>
> So to me, it seems consistent that if: "if(x)" is true, then "if
> (x==true)"
> should also be true.

This doesn't follow.  You are arguing that because 1 becomes true in a
boolean context that therefore true must be one in an integer context.
There is no reason this is true.  And actually there's *definitely* no
reason to expect any kind of typecasting to occur in an expression "if
(x==true)".  Why would the type of x get changed?  I expect x to be compared
as it is to "true" and the result to be false unless they are the same.  The
same type and the same value.  I don't think an equality test should *ever*
change the type of something.  

Also the argument above means that you need " if (5==true)" to also evaluate
to true.  As I said before, for consistency here, true should test as equal
to all nonzeros, nonempty strings and nonempty lists.  "if (3)" is true so
"if (3==true)" should be true.  "if ([false])" is true so "if
([false]==true)" should be true.  


>> For relative comparisons it seems like the only reason to compare true to
> 3
>> (other than programmer error) is in the sorting context, which was
> suggested
>> in the github issue.  But does the choice to make true=1 and false=0
>> actually make sense?  I argue that it does not.  If I'm sorting a list of
>> objects I do not find the following to be a reasonable output from a sort
>> algorithm and can't conceive of a situation where it would be desirable:
>>
>> [-1, -.5, 0, false, 0, false, .5, 1, true, 1, 1, true, 1.5, 2]
>>
>> but this would be a legitimate "sorted" output if true==1 and false==0
>> and
>> the same for comparisons.
>>
>
> Yes I did mention this in the context of sorting mixed types, but mainly
> just to say that thinking more closely about how mixed types behave was
> what led me to discover the inconsistencies in comparison operators.
> But I also acknowledged that such sorting would be a weird / rare case, so
> I'm not really too upset if it would require special handling for a
> library
> to support such things.
>
> Also note that even though the sorting seems strange here, this is the
> exact behavior in Python for example:
> Python 3.8.2 (default, Jul 16 2020, 14:00:26)
> [GCC 9.3.0] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>>>> x=[-1, -.5, 0, False, 0, False, .5, 1, True, 1, 1, True, 1.5, 2]
>>>> y=[-1, -.5, 0, False, 0, False, .5, 1, True, 1, 1, True, 1.5, 2]
>>>> x.sort()
>>>> x==y
> True
>>>> x
> [-1, -0.5, 0, False, 0, False, 0.5, 1, True, 1, 1, True, 1.5, 2]

Indeed.  This is because in Python, True and False are in fact integers.
The boolean type is a subclass of the integer type, so this behavior is an
unavoidable consequence of that.   This also means that the statement
(x==True) in python doesn't require a typecast if x is 1 because both types
are integers already.  As someone said earlier, the decision to make true
and false equal to 1 and 0 is basically getting rid of the boolean type and
making booleans into integers.  If that's what you want to do, shouldn't you
make it fully consistent the way it is in Python?  Namely that true+true=2,
true*false=0, etc?  And indexing works, so you can do foo[true]?  Which
might honestly be useful---probably THE only useful thing that comes out of
booleans actually being integers.  

If you define true and false to be integers then everything becomes
consistent and also well defined.  OpenSCAD is a long way from this, because
most integer operations fail on booleans.  Also, why do this?  I assume it
was done in Python because python didn't have a boolean type until version
2.3, and then they wanted to make it backward compatible with how people did
things before.   I don't think it makes sense to copy a feature of a
language that's basically a historical artifact of that language's
development path.  


> If this is "old fashioned" as parkinbot says , then I would be curious to
> know what modern language(s) which allow mixed type collections, would
> serve a better role-model for OpenSCAD in this regard.

Probably any strongly type language that has a real boolean type would be a
better role model.   Before the boolean type existed people did comparisons
using numbers.  But making the boolean type act half like an integer and
half not isn't old fashioned.  It's just inconsistent and confusing.  It
doesn't make sense, so users will be surprised.  And there's no
justification for the current inconsistent behavior that explains why
booleans are integers when you wish they wouldn't be but not when you might
want them to be.  


>> So if you want a concrete example, with the updated behavior, search for
>> booleans becomes difficult to use because outputs from search must be
>> post-processed to select only the results with boolean output.  And the
>> result without such postprocessing is basically nonsense.
>>
>> And if I want to search for arrays containing booleans then it's really
>> painful to screen the return value from search for booleans.  Consider:
>>
>> search([[true,1]], [[true,true],[true,1],[true,3], [1,true], [1,1],
> [1,3]],
>> 0)
>>
>> which returns [[1]] in the old version and [[0, 1, 3, 4]] in the new
>> version.  For a general search post-process we now need to scan the
> returned
>> entries from search and check whether isbool gives the same result on
>> each
>> entry to identify which ones are valid returns.  What a mess!
>
> OK, so far I'm hearing that the main thing this actually breaks is certain
> usages of the builtin search() function, where the user is searching on
> "keys" of mixed boolean and number types.  Although WHY they would want to
> do this in a real script is not clear to me (outside of adversarially
> contrived test-cases).
> If this is really wanted/needed for builtin search, then a quick fix could
> be to change search() so that it checks for strictly matching types in
> addition to "equivalence".

No, *any* use of booleans breaks with search, not just complicated ones.
It's just that the workaround is more awkward when it's a complicated
search.  

Here's the simple case.  What if I want to find the first true entry, which
does not seem like a contrived operation.  

Old way:

final_result = search([true], data, 1);

New way:

results = search([true], data, 0);
true_results = [for (entry=results[0]) if (is_bool(data[entry])) entry];
final_result2 = len(true_results)>0 ? [true_results[1]] : [[]];

So yeah, if you insist on keeping the new, inconsistent and confusing
behavior for booleans, then I changing search to reproduce the old behavior
seems advisable.  Would be nice to have a real equality operator while
you're at it that gives the true result of comparisons without unexpected
typecasting.  

What I'm really puzzled about is that this change seems to break things, and
it is counter-intuitive, and it offers NO BENEFIT.  Where is your example of
the advantage of this version.  As I see it:

Disadvantages of the new approach:

* Inconsistent behavior where true/false are sort of treated as integers
like in Python, but only sometimes.  
* Treating booleans as integers is not required or necessarily the best way
to do things.   OpenSCAD is not Python.  
* Counterintuitive results like "true==1" evaluates as true.  (Guess this
makes sense to Python users, but it does not make sense if booleans are
their own type.)  
* To test that x is true must write "x && is_bool(x)", decidedly
non-obvious.
* Makes search() hard to use with boolean inputs

Advantages of new approach:

* Consistency in treatment of booleans as integers in relative comparison
with integers

This isn't a real advantage.  Can you give any example of a real advantage,
where one can write better code with this?  When would I want to use
relative comparisons with booleans at all???  The argument for consistency
is basically taking the useful case of equality comparison and breaking it
to support consistency for the non-useful case of relative comparisons.  

The right way to address the consistency problem is to ban relative
comparisons between types, that is, a<b is undef if the operands are
different types.   In a strongly typed language this is the expected
outcome.  

But if you want to make booleans act like integers in the name of
consistency then you should get rid of the boolean type and just make them
integers, with true and false simply synonyms for 1 and 0.  This simplifies
the language a bit and then nobody is surprised by behavior once this
underlying definition is understood.  




--
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: What happened to booleans?

doug.moen
In reply to this post by thehans
> So to me, it seems consistent that if: "if(x)" is true, then "if (x==true)" should also be true.

OpenSCAD boolean operations treat [] as equivalent to false. For consistency, should [] == false?
OpenSCAD boolean operations treat 3 as equivalent to true. For consistency, should 3 == true?

OpenSCAD arithmetic operations do *not* treat booleans as equivalent to numbers. 1+true is undef, not 2.
For consistency, shouldn't true != 1?

I think that in general, a==b should return true if a and b are operationally equivalent in all contexts, and false otherwise. Another formulation that I like is: a == b should return true if and only if a and b have the same printed representation. Any exceptions to this general rule should be justified by interoperability concerns. For example, 0 == -0 can be justified to support interoperability with floating point algorithms ported from other programming languages, since the IEEE float standard requires 0 == -0 and almost all other programming languages follow that.

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

Re: What happened to booleans?

thehans
OK, I see your points and admit that my logic in that statement was flawed.  

I suppose I hadn't put a ton of thought into it and was attempting to post-rationalize, but upon reflection, really the main reason this behavior was chosen is that it is consistent **with C++**.
So it seemed natural to me, developing for OpenSCAD in C++, to treat double to bool comparisons in the same way (the code literally returns the result of the corresponding C++ operator between double and bool).  And as an aside, there are no integers in OpenSCAD.

Now everyone can balk that C++ is old fashioned with all its legacy quirks and OpenSCAD is not Python / C / C++ / Javascript / etc. but I honestly didn't think anyone would even consider this change controversial... and there was no input of other opinions at the time (nor in the 7months that the change has been in nightlies).

I only knew that the existing behavior (where <= and >= behaved C-like, but not other comparisons) made absolutely no sense, but I suppose the change could have just as easily gone the other way:  to make <= and >= always return false when comparing between numbers and bools.

If we can agree that's what our users want/expect in general, then personally I would be fine with changing it around.

As for the more drastic option of trying to make OpenSCAD strongly typed (which I don't believe anyone has ever claimed it to be), by having comparisons between any two different types returning undef instead of false... I have a feeling doing that would cause significantly more breakages to existing scripts, and general confusion, than the previous change.



On Sun, Jul 26, 2020 at 12:26 AM Doug Moen <[hidden email]> wrote:
> So to me, it seems consistent that if: "if(x)" is true, then "if (x==true)" should also be true.

OpenSCAD boolean operations treat [] as equivalent to false. For consistency, should [] == false?
OpenSCAD boolean operations treat 3 as equivalent to true. For consistency, should 3 == true?

OpenSCAD arithmetic operations do *not* treat booleans as equivalent to numbers. 1+true is undef, not 2.
For consistency, shouldn't true != 1?

I think that in general, a==b should return true if a and b are operationally equivalent in all contexts, and false otherwise. Another formulation that I like is: a == b should return true if and only if a and b have the same printed representation. Any exceptions to this general rule should be justified by interoperability concerns. For example, 0 == -0 can be justified to support interoperability with floating point algorithms ported from other programming languages, since the IEEE float standard requires 0 == -0 and almost all other programming languages follow that.
_______________________________________________
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: What happened to booleans?

Parkinbot
thehans wrote
> As for the more drastic option of trying to make OpenSCAD strongly typed
> (which I don't believe anyone has ever claimed it to be), by having
> comparisons between any two different types returning undef instead of
> false... I have a feeling doing that would cause significantly more
> breakages to existing scripts, and general confusion, than the previous
> change.

This is not an option for a boolean operation unless you identify "undef" as
"false" and get caught in the same pitfall. You could throw an error or at
least a warning, but this will break tons of legacy code.

I would opt for a clear and *consistent* implementation, which is neither
the new nor the old implementation.



--
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: What happened to booleans?

mondo
Hi,

I'm new to scad, this is just an opinion, but I wonder exactly what the
problem is that is being  discussed. Looking at
https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/Type_Test_Functions/is_bool 
   the 'is_bool' makes sense to me, i.e the only acceptable values for
bool is 'true' and 'false', any other value is false. Now it maybe that
within the computer memory, a bit set to 0 represents a true, but in
other computer systems, it could be a whole byte set to 0. You can read
bits and bytes and translate to whatever you want, but you have to stick
with that machine/language convention, to get the same output as input.

Going up a level, if a bool is defined as either true or false, then you
shouldn't think of it as anything else, no matter how your favourite
language handles the code. It should be strongly typed, else folk will
want to put there own interpretation on non conforming values. In the
same way, if we are talking about decimal numbers, we would expect that
something like '555bnh' would be handled differently in different
language interpretations of an integer, but '555' should always be
handled the same. An example of this woolly thinking, is found all over
window's programs, where programmers found undocumented short cuts
within the os, outside of the apis, and then when the OS was updated,
their software failed.

Is the next discussion going to be about how many angels can sit on a
pin head?

Best wishes,


Ray


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

Re: What happened to booleans?

jon_bondy
In reply to this post by thehans

I grew up on Pascal and Modula-2. In those languages, TRUE/FALSE have nothing to do with numbers: "IF (3)" is simply an error.  So to ME, all of this is nonsense.

Which demonstrates how differently we all feel about these issues


On 7/26/2020 2:44 AM, Hans L wrote:
OK, I see your points and admit that my logic in that statement was flawed.  

I suppose I hadn't put a ton of thought into it and was attempting to post-rationalize, but upon reflection, really the main reason this behavior was chosen is that it is consistent **with C++**.
So it seemed natural to me, developing for OpenSCAD in C++, to treat double to bool comparisons in the same way (the code literally returns the result of the corresponding C++ operator between double and bool).  And as an aside, there are no integers in OpenSCAD.

Now everyone can balk that C++ is old fashioned with all its legacy quirks and OpenSCAD is not Python / C / C++ / Javascript / etc. but I honestly didn't think anyone would even consider this change controversial... and there was no input of other opinions at the time (nor in the 7months that the change has been in nightlies).

I only knew that the existing behavior (where <= and >= behaved C-like, but not other comparisons) made absolutely no sense, but I suppose the change could have just as easily gone the other way:  to make <= and >= always return false when comparing between numbers and bools.

If we can agree that's what our users want/expect in general, then personally I would be fine with changing it around.

As for the more drastic option of trying to make OpenSCAD strongly typed (which I don't believe anyone has ever claimed it to be), by having comparisons between any two different types returning undef instead of false... I have a feeling doing that would cause significantly more breakages to existing scripts, and general confusion, than the previous change.



On Sun, Jul 26, 2020 at 12:26 AM Doug Moen <[hidden email]> wrote:
> So to me, it seems consistent that if: "if(x)" is true, then "if (x==true)" should also be true.

OpenSCAD boolean operations treat [] as equivalent to false. For consistency, should [] == false?
OpenSCAD boolean operations treat 3 as equivalent to true. For consistency, should 3 == true?

OpenSCAD arithmetic operations do *not* treat booleans as equivalent to numbers. 1+true is undef, not 2.
For consistency, shouldn't true != 1?

I think that in general, a==b should return true if a and b are operationally equivalent in all contexts, and false otherwise. Another formulation that I like is: a == b should return true if and only if a and b have the same printed representation. Any exceptions to this general rule should be justified by interoperability concerns. For example, 0 == -0 can be justified to support interoperability with floating point algorithms ported from other programming languages, since the IEEE float standard requires 0 == -0 and almost all other programming languages follow that.
_______________________________________________
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: What happened to booleans?

MichaelAtOz
Administrator
In reply to this post by thehans
thehans wrote
> I only knew that the existing behavior (where <= and >= behaved C-like,
> but
> not other comparisons) made absolutely no sense, but I suppose the change
> could have just as easily gone the other way:  to make <= and >= always
> return false when comparing between numbers and bools.
>
> If we can agree that's what our users want/expect in general, then
> personally I would be fine with changing it around.

wiki

> Booleans are truth values. There are two Boolean values, namely true and
> false. A Boolean is passed as the argument to conditional statement
> 'if()'. conditional operator '? :', and logical operators '!' (not), '&&'
> (and), and '||' (or). In all of these contexts, you can actually pass any
> quantity. Most values are converted to 'true' in a Boolean context, the
> values that count as 'false' are:
>
>     false
>     0 and -0
>     ""
>     []
>     undef
>
> Note that "false" (the string), [0] (a numeric vector), [ [] ] (a vector
> containing an empty vector), [false] (a vector containing the Boolean
> value false) and 0/0 (Not A Number) all count as true.

So much code is based on that. Why change?



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

* click on my MichaelAtOz label, there is a link to email me.

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.

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

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
OpenSCAD Admin - email* me if you need anything, or if I've done something stupid...
* on the Forum, click on my MichaelAtOz label, there is a link to email me.

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.
Reply | Threaded
Open this post in threaded view
|

Re: What happened to booleans?

adrianv
In reply to this post by Parkinbot
Note that the change under discussion may have been made a while ago, but I,
at least, don't run the nightly builds because I'm doing library development
and the library is meant to run under the stable release.  

In what way(s) is OpenSCAD not strongly typed?  Generally when I combine
types in an operation OpenSCAD returns undef.  This is why I suggested
OpenSCAD was strongly typed, since this is the OpenSCAD equivalent of
issuing an error.  
In what way would you say that OpenSCAD is not strongly type?  I have come
up with one example of weak typing: the automatic casting of non-booleans to
booleans in a boolean context.   Are there any others?  

test = [
        "string",
        [3],
        33,
        true];
result = [for(i=[0:1:3], j=[i+1:1:3]) test[i]+test[j]];
echo(result);

Testing for all types above, I get undef for every case.  In what way would
you say that OpenSCAD is not strongly type?  I have come up with one example
of weak typing: the automatic casting of non-booleans to booleans in a
boolean context.   Are there any others?  

In fact, the various weak-type behaviors I'd like to see are all absent.
I'm talking about things like array+scalar, or comparisons like array<scalar
or array&lt;array.  Note: I'm not requesting these things or saying we need
them.  I'm just saying they are weak type behaviors I'm used to from MATLAB
where OpenSCAD just returns undef--the strong type behavior.  

The only operations that I can find that doesn't return undef or return an
appropriate multi-type result (e.g. matrix times scalar) are the relative
comparisons.  If you really want to make things consistent it still seems to
me that the best way to do that is to make relative operations return undef
for mismatched types.  

I don't understand how this change would break code that is not also broken
by changing comparisons of booleans to return false.  

Parkinbot, I don't understand what you mean.  Right now undef is treated as
false in a boolean context, and nobody is suggesting that this change.  So
someone who does comparisons like &quot;if (true&lt;3)&quot; will get the
same result if such comparisons return false as if they return undef.   The
only difference would be if you store the result or explicitly check the
result like

(true&lt;3) == undef

or

(true&lt;3) == false

&lt;quote author=&quot;Parkinbot&quot;>
thehans wrote
> As for the more drastic option of trying to make OpenSCAD strongly typed
> (which I don't believe anyone has ever claimed it to be), by having
> comparisons between any two different types returning undef instead of
> false... I have a feeling doing that would cause significantly more
> breakages to existing scripts, and general confusion, than the previous
> change.

This is not an option for a boolean operation unless you identify "undef" as
"false" and get caught in the same pitfall. You could throw an error or at
least a warning, but this will break tons of legacy code.

I would opt for a clear and *consistent* implementation, which is neither
the new nor the old implementation.



--
Sent from: http://forum.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: What happened to booleans?

adrianv
In reply to this post by MichaelAtOz
MichaelAtOz wrote

> thehans wrote
>> I only knew that the existing behavior (where <= and >= behaved C-like,
>> but
>> not other comparisons) made absolutely no sense, but I suppose the change
>> could have just as easily gone the other way:  to make <= and >= always
>> return false when comparing between numbers and bools.
>>
>> If we can agree that's what our users want/expect in general, then
>> personally I would be fine with changing it around.
>
> wiki
>
>> Booleans are truth values. There are two Boolean values, namely true and
>> false. A Boolean is passed as the argument to conditional statement
>> 'if()'. conditional operator '? :', and logical operators '!' (not), '&&'
>> (and), and '||' (or). In all of these contexts, you can actually pass any
>> quantity. Most values are converted to 'true' in a Boolean context, the
>> values that count as 'false' are:
>>
>>     false
>>     0 and -0
>>     ""
>>     []
>>     undef
>>
>> Note that "false" (the string), [0] (a numeric vector), [ [] ] (a vector
>> containing an empty vector), [false] (a vector containing the Boolean
>> value false) and 0/0 (Not A Number) all count as true.
>
> So much code is based on that. Why change?

This doesn't relate to the current conversation about the behavior of
booleans in relative comparisons.  Nobody is suggesting that we change how
boolean contexts are handled, with the argument in such a context being cast
to a boolean following the above method.  

The question at hand is what should happen when you use the <, >, <=, =>, or
== operators with booleans.  Is there tons of code based on using relative
comparisons between numbers and booleans?  What is the use of such a thing?
It doesn't make sense.  Only equality testing makes sense, and the whole
issue at hand is that the latest development breaks equality testing.  

The wiki says this:

---------

If both operands are Booleans, true > false. In an inequality comparison
between a Boolean and a number true is treated as 1 and false is treated as
0. Other inequality tests involving Booleans return false.

Dissimilar types always test as unequal with '==' and '!='. Inequality
comparisons between dissimilar types, except for Boolean and numbers as
noted above, always result in false.

 --------

So the question is what should be behavior be for inequality tests between
dissimilar types.  I'm suggesting that it should be to return undef, since
that is consistent with how other operations behave when you combine
dissimilar types.  And this should rarely break anything since undef casts
to false in a boolean context.  In other words, changing 3<[3] from false to
undef won't change code that uses this in a boolean context, since undef is
false in that context.  The only real change would be to code that relies on
comparing booleans to numbers because the change would mean that true<4
would return undef instead of true, and that would test as false.    But if
we went with the other notion of returning false for this test it has the
same impact on existing code.  





--
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: What happened to booleans?

thehans
In reply to this post by adrianv
On Sun, Jul 26, 2020 at 5:15 AM Parkinbot <[hidden email]> wrote:
I would opt for a clear and *consistent* implementation, which is neither
the new nor the old implementation. 

OK, but saying this alone is not helpful without explicitly defining what *consistent* means to you.
So, would you be satisfied with what I proposed here (yes/no)? :

On Sun, Jul 26, 2020 at 1:44 AM Hans L <[hidden email]> wrote:
... the change could have just as easily gone the other way:  to make <= and >= always return false when comparing between numbers and bools.

If we can agree that's what our users want/expect in general, then personally I would be fine with changing it around.


On Sun, Jul 26, 2020 at 7:51 AM adrianv <[hidden email]> wrote:
Note that the change under discussion may have been made a while ago, but I,
at least, don't run the nightly builds because I'm doing library development
and the library is meant to run under the stable release. 

I can certainly understand the desire to support stable releases for libraries (i.e. not relying on experimental features).  But as a library developer it seems to me you also have a vested interest in future development of OpenSCAD.  
So while you may prefer to develop for (and on) the stable release, I would strongly encourage you and other library authors to, at least periodically, test against nightlies.  This would really help identify any possible breaking changes early on, before they become more permanently ingrained in the *next* stable release.
OpenSCAD has a fairly comprehensive test suite which helps identify many such regressions, but it's thoroughness is dependent on issues being raised on Github with reproducible test cases etc.
Also, as a library author, I would assume you are more likely to make use of esoteric / niche features of the language which more casual users may not be aware of, which makes them even more valuable as test cases.
 
In what way(s) is OpenSCAD not strongly typed? 

I don't care to dive deeply into semantic arguments here, since it seems that strong typing means different things, with various qualifications and exceptions, depending on who/what language you ask.
What I specifically said was "... I don't believe anyone has ever claimed [OpenSCAD] to be [strongly typed]"  (with the exception of you, now).  This means, to the best of my knowledge, none of the documentation nor project authors have made this claim.  
If you want to argue against that, then the burden of proof is on you to show otherwise.  In fact googling for ( "strongly typed" OpenSCAD ) has a first result of Doug Moen explicitly saying "OpenSCAD isn't designed to be a strongly typed language".  I don't consider myself an expert on programming linguistics by any means, but since Doug has previously put a lot of thought and effort into the (unfortunately now defunct/abandoned I guess) "OpenSCAD2" specification, I would defer to his knowledge on the subject.  Doug has replied in this thread already, though not specifically addressing whether or not (or to what degree) OpenSCAD may be considered strongly typed, but I would be all ears if he cares to elaborate any.
 
Generally when I combine
types in an operation OpenSCAD returns undef.  This is why I suggested
OpenSCAD was strongly typed, since this is the OpenSCAD equivalent of
issuing an error. 

OpenSCAD is perfectly capable of throwing errors and does so in many cases, so I don't agree that returning undef is "equivalent" to issuing an error.  
In the underlying implementation, undef *is* its own type, as is boolean, and we don't use tri-state booleans.  The very nature of returning undef sometimes and bool/number/vector etc at other times makes this not particularly strong in my opinion.  The strongest response would be to stop on error when two incompatible operands are used, but changing this fundamental behavior would likely break a whole lot of things.

Comparison operators are currently implemented such that they always return a boolean.  Returning undef would mean redefining all of these operators to return the variant (sum type) of "Value", making them weaker in that sense.
In cases where the result of comparison is not being used directly in the context of a condition, say it's assigned to a variable or a vector element, then returning undef only serves to further this muddling of types.



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

Re: What happened to booleans?

MostlyHarmless
Treating booleans as numbers where zero means False and everything else means True has served us well for decades in many programming laguages.

I understand the desire to treat booleans more special, but that doesn't mean that I would support their behavior to become completely randomized or non sensical. If you allow an expression of (one_bool EQ another_bool) and the result isn't True if both are True or both are False, then you create a huge footgun for no apparent reason whatsoever. Better make that throw an error at compile time.

There is no real sense in having GT, LE and so on operators for booleans. That should always throw an error early on. But equality and inequality operators even exist in very well defined and designed language standards. Being the oddball in this regard isn't going to serve us well.


Best Regards, Jan






On Sun, Jul 26, 2020 at 4:01 PM Hans L <[hidden email]> wrote:
On Sun, Jul 26, 2020 at 5:15 AM Parkinbot <[hidden email]> wrote:
I would opt for a clear and *consistent* implementation, which is neither
the new nor the old implementation. 

OK, but saying this alone is not helpful without explicitly defining what *consistent* means to you.
So, would you be satisfied with what I proposed here (yes/no)? :

On Sun, Jul 26, 2020 at 1:44 AM Hans L <[hidden email]> wrote:
... the change could have just as easily gone the other way:  to make <= and >= always return false when comparing between numbers and bools.

If we can agree that's what our users want/expect in general, then personally I would be fine with changing it around.


On Sun, Jul 26, 2020 at 7:51 AM adrianv <[hidden email]> wrote:
Note that the change under discussion may have been made a while ago, but I,
at least, don't run the nightly builds because I'm doing library development
and the library is meant to run under the stable release. 

I can certainly understand the desire to support stable releases for libraries (i.e. not relying on experimental features).  But as a library developer it seems to me you also have a vested interest in future development of OpenSCAD.  
So while you may prefer to develop for (and on) the stable release, I would strongly encourage you and other library authors to, at least periodically, test against nightlies.  This would really help identify any possible breaking changes early on, before they become more permanently ingrained in the *next* stable release.
OpenSCAD has a fairly comprehensive test suite which helps identify many such regressions, but it's thoroughness is dependent on issues being raised on Github with reproducible test cases etc.
Also, as a library author, I would assume you are more likely to make use of esoteric / niche features of the language which more casual users may not be aware of, which makes them even more valuable as test cases.
 
In what way(s) is OpenSCAD not strongly typed? 

I don't care to dive deeply into semantic arguments here, since it seems that strong typing means different things, with various qualifications and exceptions, depending on who/what language you ask.
What I specifically said was "... I don't believe anyone has ever claimed [OpenSCAD] to be [strongly typed]"  (with the exception of you, now).  This means, to the best of my knowledge, none of the documentation nor project authors have made this claim.  
If you want to argue against that, then the burden of proof is on you to show otherwise.  In fact googling for ( "strongly typed" OpenSCAD ) has a first result of Doug Moen explicitly saying "OpenSCAD isn't designed to be a strongly typed language".  I don't consider myself an expert on programming linguistics by any means, but since Doug has previously put a lot of thought and effort into the (unfortunately now defunct/abandoned I guess) "OpenSCAD2" specification, I would defer to his knowledge on the subject.  Doug has replied in this thread already, though not specifically addressing whether or not (or to what degree) OpenSCAD may be considered strongly typed, but I would be all ears if he cares to elaborate any.
 
Generally when I combine
types in an operation OpenSCAD returns undef.  This is why I suggested
OpenSCAD was strongly typed, since this is the OpenSCAD equivalent of
issuing an error. 

OpenSCAD is perfectly capable of throwing errors and does so in many cases, so I don't agree that returning undef is "equivalent" to issuing an error.  
In the underlying implementation, undef *is* its own type, as is boolean, and we don't use tri-state booleans.  The very nature of returning undef sometimes and bool/number/vector etc at other times makes this not particularly strong in my opinion.  The strongest response would be to stop on error when two incompatible operands are used, but changing this fundamental behavior would likely break a whole lot of things.

Comparison operators are currently implemented such that they always return a boolean.  Returning undef would mean redefining all of these operators to return the variant (sum type) of "Value", making them weaker in that sense.
In cases where the result of comparison is not being used directly in the context of a condition, say it's assigned to a variable or a vector element, then returning undef only serves to further this muddling of types.


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


--
Jan Wieck
Principal Database Engineer

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

Re: What happened to booleans?

doug.moen
In reply to this post by thehans
Since my name was mentioned, I better reply.

I understand "strongly typed" to mean that each function has a well defined contract, in terms of the types of arguments that it accepts, and that this contract is enforced either at compile time or run time. An error is reported if arguments have the wrong type. The goal is to stop the program from running and report a problem if function arguments appear to be garbage. The alternative being to keep running and produce garbage in the end, and you have no idea where the program went wrong.

The OpenSCAD2 project evolved into a brand new language called Curv, which is strongly typed, with dynamic types. For example, the boolean operators only accept the values true and false as arguments. If you pass non-boolean arguments, the program aborts with an error and a detailed stack trace. This is the way I wish OpenSCAD worked, because it makes programs easier to debug, so I created my own 3D modelling language that works this way.

For the most part, OpenSCAD functions silently return undef when passed bad arguments. For example, 1+true is undef. I don't consider this to be "strongly typed" behaviour. However, changing OpenSCAD to be strongly typed would break a lot of existing code, which would be undesirable.

Doug Moen.

On Sun, Jul 26, 2020, at 3:59 PM, Hans L wrote:
On Sun, Jul 26, 2020 at 5:15 AM Parkinbot <[hidden email]> wrote:
I would opt for a clear and *consistent* implementation, which is neither
the new nor the old implementation. 

OK, but saying this alone is not helpful without explicitly defining what *consistent* means to you.

So, would you be satisfied with what I proposed here (yes/no)? :

On Sun, Jul 26, 2020 at 1:44 AM Hans L <[hidden email]> wrote:
... the change could have just as easily gone the other way:  to make <= and >= always return false when comparing between numbers and bools.

If we can agree that's what our users want/expect in general, then personally I would be fine with changing it around.


On Sun, Jul 26, 2020 at 7:51 AM adrianv <[hidden email]> wrote:
Note that the change under discussion may have been made a while ago, but I,
at least, don't run the nightly builds because I'm doing library development
and the library is meant to run under the stable release. 

I can certainly understand the desire to support stable releases for libraries (i.e. not relying on experimental features).  But as a library developer it seems to me you also have a vested interest in future development of OpenSCAD.  
So while you may prefer to develop for (and on) the stable release, I would strongly encourage you and other library authors to, at least periodically, test against nightlies.  This would really help identify any possible breaking changes early on, before they become more permanently ingrained in the *next* stable release.
OpenSCAD has a fairly comprehensive test suite which helps identify many such regressions, but it's thoroughness is dependent on issues being raised on Github with reproducible test cases etc.
Also, as a library author, I would assume you are more likely to make use of esoteric / niche features of the language which more casual users may not be aware of, which makes them even more valuable as test cases.
 
In what way(s) is OpenSCAD not strongly typed? 

I don't care to dive deeply into semantic arguments here, since it seems that strong typing means different things, with various qualifications and exceptions, depending on who/what language you ask.

What I specifically said was "... I don't believe anyone has ever claimed [OpenSCAD] to be [strongly typed]"  (with the exception of you, now).  This means, to the best of my knowledge, none of the documentation nor project authors have made this claim.  
If you want to argue against that, then the burden of proof is on you to show otherwise.  In fact googling for ( "strongly typed" OpenSCAD ) has a first result of Doug Moen explicitly saying "OpenSCAD isn't designed to be a strongly typed language".  I don't consider myself an expert on programming linguistics by any means, but since Doug has previously put a lot of thought and effort into the (unfortunately now defunct/abandoned I guess) "OpenSCAD2" specification, I would defer to his knowledge on the subject.  Doug has replied in this thread already, though not specifically addressing whether or not (or to what degree) OpenSCAD may be considered strongly typed, but I would be all ears if he cares to elaborate any.


 
Generally when I combine
types in an operation OpenSCAD returns undef.  This is why I suggested
OpenSCAD was strongly typed, since this is the OpenSCAD equivalent of
issuing an error. 

OpenSCAD is perfectly capable of throwing errors and does so in many cases, so I don't agree that returning undef is "equivalent" to issuing an error.  
In the underlying implementation, undef *is* its own type, as is boolean, and we don't use tri-state booleans.  The very nature of returning undef sometimes and bool/number/vector etc at other times makes this not particularly strong in my opinion.  The strongest response would be to stop on error when two incompatible operands are used, but changing this fundamental behavior would likely break a whole lot of things.

Comparison operators are currently implemented such that they always return a boolean.  Returning undef would mean redefining all of these operators to return the variant (sum type) of "Value", making them weaker in that sense.
In cases where the result of comparison is not being used directly in the context of a condition, say it's assigned to a variable or a vector element, then returning undef only serves to further this muddling of types.


_______________________________________________
OpenSCAD mailing list



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

Re: What happened to booleans?

adrianv
In reply to this post by thehans
thehans wrote
> On Sun, Jul 26, 2020 at 5:15 AM Parkinbot &lt;

> rudolf@

> &gt; wrote:
>
>> I would opt for a clear and *consistent* implementation, which is neither
>> the new nor the old implementation.
>>
>
> OK, but saying this alone is not helpful without explicitly defining what
> *consistent* means to you.
> So, would you be satisfied with what I proposed here (yes/no)? :
>
> On Sun, Jul 26, 2020 at 1:44 AM Hans L &lt;

> thehans@

> &gt; wrote:
>
>> ... the change could have just as easily gone the other way:  to make <=
>> and >= always return false when comparing between numbers and bools.
>>
>> If we can agree that's what our users want/expect in general, then
>> personally I would be fine with changing it around.
>>

I'm not sure if you were asking me or Parkinbot (who you quoted).
Ultimately I don't particularly care what relative comparison operators do
when given booleans.  It's a pointless combination that should never be
used.  If you return false for all cases that's fine with me.   I think
returning undef for all relative compares between different types is better
and more consistent across the language.  But ultimately, it doesn't matter.  

What does matter is the behavior of equality testing, where I insist that
(x==true) is true only when x is the actual boolean true and not for any
other value.  And similarly (x==false) is true if and only if x is the
actual boolean value false.  


> On Sun, Jul 26, 2020 at 7:51 AM adrianv &lt;

> avm4@

> &gt; wrote:
>
>> Note that the change under discussion may have been made a while ago, but
>> I,
>> at least, don't run the nightly builds because I'm doing library
>> development
>> and the library is meant to run under the stable release.
>>
>
> I can certainly understand the desire to support stable releases for
> libraries (i.e. not relying on experimental features).  But as a library
> developer it seems to me you also have a vested interest in future
> development of OpenSCAD.
> So while you may prefer to develop for (and on) the stable release, I
> would
> strongly encourage you and other library authors to, at least
> periodically,
> test against nightlies.  This would really help identify any possible
> breaking changes early on, before they become more permanently ingrained
> in
> the *next* stable release.
> OpenSCAD has a fairly comprehensive test suite which helps identify many
> such regressions, but it's thoroughness is dependent on issues being
> raised
> on Github with reproducible test cases etc.
> Also, as a library author, I would assume you are more likely to make use
> of esoteric / niche features of the language which more casual users may
> not be aware of, which makes them even more valuable as test cases.

Indeed, this situation has made clear the need for testing against the
development versions.  We're building up regression tests for the functions
in the library, which should make it possible to catch problems created by
changes in OpenSCAD---if we write our regression tests well.   We don't have
any mechanism to test geometry.  


>> Generally when I combine
>> types in an operation OpenSCAD returns undef.  This is why I suggested
>> OpenSCAD was strongly typed, since this is the OpenSCAD equivalent of
>> issuing an error.
>>
>
> OpenSCAD is perfectly capable of throwing errors and does so in many
> cases,
> so I don't agree that returning undef is "equivalent" to issuing an error.

I would say that OpenSCAD may occasionally issue errors, but for most error
conditions it instead confounds the programmer by returning undef instead,
so that the error can propagate along ten functions more before finally
producing an obvious problem.   I've spent hours debugging code just
tracking down where errors occur because of this behavior, where an
immediate error would have directed me immediately to the problem.   This
has lead me to the philosophy that undef should never be intentionally
returned by any function.  It's kind of too bad since the notion of undef is
useful, e.g. for returning the intersection point of two parallel lines.  
But it seems more important to do as much as possible to distinguish
meaningful returns from programming errors.  


> Comparison operators are currently implemented such that they
> always return a boolean.  Returning undef would mean redefining all of
> these operators to return the variant (sum type) of "Value", making them
> weaker in that sense.
> In cases where the result of comparison is not being used directly in the
> context of a condition, say it's assigned to a variable or a vector
> element, then returning undef only serves to further this muddling of
> types.

The change that prompted this discussion had to do with establishing
consistency.   I maintain that consistency is maximized if comparisons
between different types return undef, which is kind of the "no type" type.
I don't think it particularly muddles types---certainly not any more than
the standard where x+y can be undef.  It sounds like this is an annoying
change in the code.  I don't really see that this consistency has much
practical value and would not want programmers to spend their time on this.
Returning false for all inter-type comparisons is reasonably consistent as
well.  




--
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: What happened to booleans?

Parkinbot
In reply to this post by adrianv
adrianv wrote
> Parkinbot, I don't understand what you mean.  Right now undef is treated
> as
> false in a boolean context, and nobody is suggesting that this change.  So
> someone who does comparisons like &amp;quot;if (true&amp;lt;3)&amp;quot;
> will get the
> same result if such comparisons return false as if they return undef.  

I think, I was very clear in what I wrote and what I am opting for:
1: Apples are no pears -> if operands have different types, "false" results
2: tertium non datur -> a boolean operation returns a boolean value, i.e.
"true" or "false" but nothing else.

identifying "undef" and "false" and allowing "undef" as result of an
apples/pears comparison would introduce a third value and thus allow for
implicit type checks, not more and not less. But with the new is_XXX()
functions we have means to do explicit type checks, why introduce/support
implicit ones?

if(undef != (op1 == op2))  // this would be a generic type check, if undef
is introduced





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

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