Boolean Data Type in freebasic

General discussion for topics related to the FreeBASIC project or its community.
Post Reply
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Boolean Data Type in freebasic

Post by MrSwiss »

St_W wrote:I think that a programmer shouldn't rely on the internal implementation at all anyway. I would define FALSE=0 and TRUE as anything <> 0.
IMHO I'd also throw errors for any operations on boolean that just don't make sense in general. For specific implementation the operator could be overload-able so that the programmer can define what should happen (instead of an error).
When the programmer wants to convert boolean to integer rather often and use it like an integer for arithmetic operations etc. he/she should probably just use Integers instead of booleans.
I'll sign above any day ... could not have expressed it any better.

@Tourist Trap,
ENUM returns an Integer, at least ATM. I'd favor an option to force Int32 (Long), by specifying:

Code: Select all

ENUM As Type<32> or
ENUM As Long
but, that's not possible right now. (I don't like the MEM wasting, everybody seems to accept, unquestioned.)
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Boolean Data Type in freebasic

Post by Tourist Trap »

St_W wrote:When the programmer wants to convert boolean to integer rather often and use it like an integer for arithmetic operations etc. he/she should probably just use Integers instead of booleans.
But what if the return type of an operation that doesn't imply a boolean has for return type a boolean. Simplest example '<' . I would agree with you to leave the booleans live their own life and the integers their own, but when you write a<b where a and b are integers (or whatever) , booleans invites themselves. So they are somehow intrusive, and for that reason implicit conversion to the type that has been choosen by the user is a right balance (of course only if boolean are nested in an larger arithmetic operation and we don't force the result to a boolean variable). I can however admit that one may want only operate inside the booleans for some rare application like electronics, and then a compiler option to set a restrictive approach like "_boolean_strict" may be useful at the margin.

I dont even know if this is not the way that this will be done in the future (I have not even the dev version) and I may worry for nothing. But if we were about prepending a CType everywhere, it would compromise backward compatibility for functions that has been written assuming that a<b return is a numeric value when nested inside a calculation ( e.g c = 5*(a<b) ).

This would summarize the state of my (poor) knwoledge on the subject. It's partial but it will show hopefully that there shouldn't be any compilation error, just big warning in a rather unusal case.
Internal operations over numeric types, and boolean
--------------------------------------------------------------------------

Type: Operator set: Comparison set:
Boolean 'LOG' BOOLCOMP = { = , <> }
Numeric 'ARI' ARICOMP = COMP


where :
LOG = { NOT, AND, OR, NAND, NOR, XOR, ANDALSO, ORELSE ..etc..)
ARI = {+, -, *, /, \, MOD, ^ ..etc..)
COMP = {<, >, =, >=, <=, <> ..etc..}


boolean is the default return type of COMP(any, ...) or LOG(boolean,...)
numeric is the default return type of ARI(numeric, ...)
which means for instance :
Var x = COMP(any)
TypeOf(x) = TypeOf(Boolean)

* shown below the case of LOG(any, ...) or ARI(any, ...)

Conversion boolean<->numeric
--------------------------------------------
Boolean ----> Numeric
FALSE ----> int_0
TRUE -----> int_+1

Numeric -----> Boolean
0 ------> FALSE
anytype_nonzero ------> TRUE



External operations (combined boolean and numeric)
--------------------------------------------------------------------------

Clean
dim as Numeric n, n1, n2, n3, N = n ari COMP(n1, n2....n3)
any arithmetic combination of this form where booleans operations are insulated then casted to numeric to take part of numerical operations only is perfectly simple, not to say very useful.
Example : N = n + (n1 > n2)

Clean, even if more complicated
N = n ari LOG(COMP(n1, n2...n3))
Example : N = n * (n1 = n2 Or n1 < n3)

Easy to decypher
dim as Boolean b, B = b log ARI(a1, a2....an)
that's more exotic, but no reason here to banish if the coder knows what he is computing. The hard part is only that ARI(a1,a2, ...an) has to be casted to a boolean first. Just taking care of insulation with the help of parenthesis ensure easy going.
B = b OR (n1 - n2)

Complicated
dim as Boolean b1, b2
dim as Numeric n1
var x = b1 log n1 ari b2
example : var x = TRUE AND -37 + FALSE
Code reads from left to right so -37 has to be casted, the boolean result is TRUE. Returns TRUE. Then both TRUE and FALSE have to be casted to -1 and 0. Final result is -1. And TypeOf(x) is integer. Here the user may be warned, and would even thank for this, above all when all the values are hidden by the variable names. But the only thing that hurts is the lack of insulation, allowing the compiler to suppose the user may be mixing types by mistake. This will return a clear result anyway.
MrSwiss wrote:ENUM returns an Integer, at least ATM. I'd favor an option to force Int32 (Long)
Also what if we want a boolean as a constant in the enum, will it be converted, will it be prohibited? will it be a mixed case?

Ok it's my boolean day, I have a quote about this too:
Refresher on some Enum and boolean usages
--------------------------------------------------------------------------


LOGIC USAGE
One may use enums and boolean both for logic computation. Maybe not freebasic enums, but bitwise types so. Whatever this is rather clear for booleans we want to get the truth value of operation like :
a < b
Not (a or b)
...

For bitwise affair, it is about logical combinations of enum fields. For instance:
Enum _COMBINE
_green = ..
_yellow = ..
_yellowgreen = ..
End Enum '_COMBINE
We would like that (_green Or _yellow) gives _yellowgreen for instance. This said, this is not a matter I master.

ARITHMETIC USAGE
Just an example should be convincing :
dim as integer i, a, b
a = 1 : b = 1
If a>b then i = 1
If a=b then i = 2
If a<b then i = 3

Test can be replaced by single line yet easy to decypher:
i = -1*(a>b) -2*(a=b) -3*(a<b)

SEMANTIC USAGE
At last, booleans and enums are used to enrich code sense. TRUE and FALSE are often better answers than 0 or -1, for readability. Also Enums are used to link a numeric answer to a speech. Anyone who has taken a look at windows API has seen the use and abuse they have made there of named constants and enum like WS_OVERLAPPED, WS_EX_OVERLAPPEDWINDOW....

For this usage, mixing booleans with the other values inside an Enum seems properly consistent.
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Boolean Data Type in freebasic

Post by fxm »

fxm wrote:
coderJeff wrote:If some operators are not allowed with boolean (e.g. math operators), then yes, error would be generated, unless explicit conversion (e.g. CINT()) is used.
You speak of explicit conversion of boolean to integer by using Cint(), but have you really added the overload function:
Declare Function CInt ( ByVal As Boolean ) As Integer
or an overload Cast operator?
coderJeff
Site Admin
Posts: 4323
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Boolean Data Type in freebasic

Post by coderJeff »

With latest pushed to https://github.com/jayrm/fbc/tree/boolean2
Here is the kind of warnings and errors to expect:

Code: Select all

const c01 as boolean = 0             '' OK
const c02 as boolean = -1            '' OK
const c03 as boolean = 1             '' OK
const c04 as boolean = 2             '' warning: Overflow in constant conversion
const c05 as boolean = 1.1f          '' OK: float rounds to 1
const c06 as boolean = 1.5f          '' warning: Overflow in constant conversion
const c07 as boolean = sin(c01)      '' error: Invalid data type
const c08 as boolean = sgn(c02)      '' error: Invalid data type
const c09 as boolean = TRUE + TRUE   '' error: Type mismatch
const c10 as boolean = 1 + TRUE      '' error: Type mismatch  
const c11 as boolean = TRUE + 1      '' error: Type mismatch  
const c12 as boolean = TRUE < TRUE   '' error: Type mismatch  
const c13 as boolean = 1 < TRUE      '' error: Type mismatch  
const c14 as boolean = TRUE < 1      '' error: Type mismatch  
const c15 as boolean = TRUE and TRUE '' OK
const c16 as boolean = 1 and TRUE    '' warning: Mixing operand data types may have undefined results
const c17 as boolean = TRUE and 1    '' warning: Mixing operand data types may have undefined results
const c18 as boolean = abs(TRUE)     '' error: Invalid data type
const c19 as boolean = -TRUE         '' OK for now

dim as boolean a, b, c
dim as integer i, j
dim as single f

c = f '' OK: implicit conversion on assign, same as c = cbool(f)
c = i '' OK: implicit conversion on assign, same as c = cbool(f)

c = sin(b) '' Error: Invalid data type
c = sgn(b) '' Error: Invalid data type

c = a + b  '' Error: Type mismatch
c = i + b  '' Error: Type mismatch
c = a + i  '' Error: Type mismatch
c = i + j  '' OK: implicit conversion on assign, same as c = cbool(i + j)

c = a < b  '' Error: Type mismatch
c = i < b  '' Error: Type mismatch
c = a < i  '' Error: Type mismatch
c = i < j  '' OK: implicit conversion on assign, same as c = cbool(i < j)

c = a and b  '' OK
c = i and b  '' Warning: Mixing operand data types may have undefined results
c = a and i  '' Warning: Mixing operand data types may have undefined results
c = i and j  '' OK: implicit conversion on assign, same as c = cbool(i and j)

i = a and b  '' OK: implicit conversion on assign, same as i = cint(a and b)

'' At least one parameter must be a user-defined type
declare operator < (byref a as boolean, byref b as boolean) as boolean

c = -a '' OK for now, cunit.bi needs this to work, same as c = -cint(a)

sub x (arg as integer)
end sub

x(b) '' OK: implicit conversion, same as x(cint(b))

sub y(arg as boolean)
end sub

y(i) '' OK: implicit conversion, same as y(cbool(i))
Hopefully that gives an idea where this is headed. Also, there is a bug in 64-bit int to Bool conversion in the gas backend. I think it is fixed, but I need to revisit the x86 emitter (again).

EDIT: correction:
c = i < b '' Error: Type mismatch
c = a < i '' Error: Type mismatch
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Boolean Data Type in freebasic

Post by D.J.Peters »

Code: Select all

dim as boolean a,b,c
a = b = c =TRUE
print a,b,c
sleep
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Boolean Data Type in freebasic

Post by Tourist Trap »

D.J.Peters wrote:...

Code: Select all

dim as integer a, b, c
a = b = c = -1         '4
? a,b,c
sleep

Code: Select all

"returns -1  0  0         '0   0   0  for case=4
--->With integers, fbc1.03.
coderJeff wrote:Here is the kind of warnings and errors to expect
Seems this all will require some impressive amount of work.
Last edited by Tourist Trap on Jul 31, 2015 10:05, edited 3 times in total.
coderJeff
Site Admin
Posts: 4323
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Boolean Data Type in freebasic

Post by coderJeff »

in jayrm...boolean2 branch.

a = b = c = TRUE
returns "true, false, false"
(b=c) returns boolean true, because both are false.
(b=c)=TRUE then returns boolean true, and no warning about mixing operands because (boolean op boolean) returns boolean.

a = b = c = 4
returns "false, false, false"
with a warning
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Boolean Data Type in freebasic

Post by D.J.Peters »

fbc is clever ;-)
it knows isn't a asignment by value it's a asignment by compared condition.

Joshy

same as before:

Code: Select all

dim as boolean a,b,c
b = (c = TRUE) 
a = (a = b)
print a,b,c
sleep
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Boolean Data Type in freebasic

Post by Tourist Trap »

D.J.Peters wrote:fbc is clever ;-)
it knows isn't a asignment by value it's a asignment by compared condition.
...

Code: Select all

dim as integer a,b,c
b = (c = -1)    '0         '4
a = (a = b)
print a,b,c
sleep

Code: Select all

"return  -1  0  0      ' 0  -1  0     ' -1  0  0
Still integers 1.03. Does it return equivalently than booleans 1.04?
coderJeff
Site Admin
Posts: 4323
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Boolean Data Type in freebasic

Post by coderJeff »

joshy, programmer is much more clever ... every time, lol.

Tourist Trap, honestly, what user is going to use a logic system (no/yes, false/true, off/on), even if it is with integers, and test for equality with four?!? Anyway, a good test case for consistency, thanks. Yes, same results with booleans as integers.
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: Boolean Data Type in freebasic

Post by Tourist Trap »

coderJeff wrote: programmer is much more clever...
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨joshi = TRUE
programmer is much more clever...<
¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨tourist trap = ... 4 ?
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Boolean Data Type in freebasic

Post by SARG »

Hi,

I just made a test with St_w's 1.04 build.
Not sure that has been reported but Boolean type collides with boolean in Windows's includes. Without using booleans in the tested code, just compiling fbdebugger with its include files.

@dkl the gcc version changes boolean type into int8 (or uint8) type so no way to know that a variable is/was a boolean one (for debugging).
Maybe something like a typedef should be used to keep the type.
dkl
Site Admin
Posts: 3235
Joined: Jul 28, 2005 14:45
Location: Germany

Re: Boolean Data Type in freebasic

Post by dkl »

Hi,

There were some changes to the Windows API binding with regards to the BOOLEAN typedef in Git, it should work with those headers. With St_W's builds you may have to get the updated headers separately.

About the C backend and debug info - that makes sense; it's now changed to use a "boolean" typedef (it was an easy change).
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Boolean Data Type in freebasic

Post by SARG »

Hi,
dkl wrote:There were some changes to the Windows API binding with regards to the BOOLEAN typedef in Git, it should work with those headers. With St_W's builds you may have to get the updated headers separately.
For now I don't need boolean variable so I stay with 1.03 version. And just 1.04 for testing.
As I improve fbdebugger to handle booleans I use this trick to display the value of boolean variables : iif(*pbyte,"True","False").
dkl wrote:About the C backend and debug info - that makes sense; it's now changed to use a "boolean" typedef (it was an easy change).
I saw that thursday morning in github. Really easy. ;-) Quick changes, thanks.

However in the gas version there are at least 2 issues :
- booleans are typed as pchar
- boolean ptrs are typed as byte pointer

Code: Select all

Dim As boolean vbool
Dim As Byte Ptr pbool=@vbool

Code: Select all

.stabs "byte:t2=-6",128,0,0,0
.stabs "pchar:t15=*4;",128,0,0,0
.stabs "boolean:t16=@s8;-16",128,0,0,0 	
.stabs "VBOOL:15",128,0,0,-8 
.stabs "PBOOL:21=*2",128,0,0,-20
By the way do you know why that pchar line is generated as it's never used.

Using the gcc version, fbdebugger is already able to handle boolean (display, edit).
This week-end I'll upload a new version of fbdebugger which can handle booleans and be compiled in 64bit. ;-)

.
fxm
Moderator
Posts: 12106
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Boolean Data Type in freebasic

Post by fxm »

Code: Select all

Type UDT
  Dim As Boolean b1 = false
  Dim As Boolean b2 = true
  Dim As Boolean b3:1 = false
  Dim as Boolean b4:1 = true
End Type

Dim As UDT u
#print typeof(u.b1)
#print typeof(u.b2)
#print typeof(u.b3)
#print typeof(u.b4)

Print u.b1
Print u.b2
Print u.b3
Print u.b4

Sleep
Compiler output:
BOOLEAN
BOOLEAN
INTEGER
INTEGER

Code: Select all

false
true
 0
-1
Why 'b3:1' and 'b4:1' are defined as Integer and not as Boolean?
Yes I read about this at http://www.freebasic.net/forum/viewtopi ... 26#p209926, but could that be improved?
Post Reply