Expanded "IF" Functionality

General discussion for topics related to the FreeBASIC project or its community.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Expanded "IF" Functionality

Post by Dinosaur »

Hi all

I tried to post this as a feature request, but got an error saying basically that you cant enter a request without logging in / signing up.
I am already in overload on passwords and username's so will post here and see what you guys think.

Basicall I get tired of Typing the same code multiple times for "IF" tests.

Code: Select all

If IOCtrl.PortBit(Settings.InSkip1Pos(Xq)) = Value1 Or IOCtrl.PortBit(Settings.InSkip1Pos(Xq)) = Value2 Then .....
To me the best solution to this is:

Code: Select all

If IOCtrl.PortBit(Settings.InSkip1Pos(Xq)) = Value1 Or = Value2 Then .....
Besides taking less time to type (or Copy / Paste) it is a lot more readable.

Maybe this has been raised before, but it seems such a obvious improvement.

REgards
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

The obvious flaw is that binary operations are binary operations. Consider using Select Case instead.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Post by Dinosaur »

Hi all

Select Case is good when the possible cases are multiple.
Unless of course you allow a Select case within a Select Case.
The obvious flaw is that binary operations are binary operations.
The task of the compiler is to make sense of the code.
So any time "OR" or "AND" in a "IF" test is followed by an "=" the original IF test is substituted.

You are doing the same at the moment with "With"

REgards
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Post by vdecampo »

Dinosaur wrote:Select Case is good when the possible cases are multiple.
I agree. This looks better suited for a Select Case Structure.

Code: Select all

Select Case IOCtrl.PortBit(Settings.InSkip1Pos(Xq)) 
   Case  Value1,Value2
        'Do Something
End Select
IMO

-Vince
Mysoft
Posts: 836
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Post by Mysoft »

Contragctulations.... "or =" makes sense...

that seems to be BASIC cuz it makes sense when you talk... and since that or= there will cause syntax error.... it can be used like with is...

so yeah, i use the select case too... but the amount of lines that it waste is and the "mess" it cause for simple tasks is more than making that or= reality... so i agree! :P
TheMG
Posts: 376
Joined: Feb 08, 2006 16:58

Post by TheMG »

What about this syntax to avoid confusion:

Code: Select all

if case(x, y, z) then
would be equivelent to:

Code: Select all

if x = y or x = z
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Post by Dinosaur »

Hi all

I am already a huge user of select case, but I cant use it where I want to.
The program design:

Main Loop calls about 40 routines that each control a piece of equipment.
Each of these 40 Routines has ONLY a Select Case in it.

A sequential Step decides which case I am upto.
Select Case jumps to that step, and performs the logical checks in that Case ,before deciding if it can increment the CaseNumber.
End Select is the end of the Sub.

So, if I could use a Select Case within a Case of Select Case I would. The logical tests that happen are very quick, and as a result my main loop time is < 100 micro Sec's.

Expanding on the suggestion:
If A = B or = (C/2)
Edit: Maybe if the original Test is enclosed in brackets.
If (A) = B or = C
I agree with Mysoft, it reads like Basic.

Regards
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

TheMG wrote:What about this syntax to avoid confusion:

Code: Select all

if case(x, y, z) then
would be equivelent to:

Code: Select all

if x = y or x = z
You could make a Case function. ;)

The or= idea actually seems like a good addition, whichever syntax is used. :)
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

Dinosaur wrote:Hi all
[...] if I could use a Select Case within a Case of Select Case I would. [...]
I'm not quite sure I understand your description of the problem, but what's stopping you from doing this ?
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Post by vdecampo »

How about this...

Code: Select all

#Define CaseOr(x,y,z)  IIf(x=y Or x=z,1,0)

Dim a As Integer = 7

If CaseOr(a,10,7) Then
   Print "The case is true"
EndIf

sleep
-Vince
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Post by MichaelW »

The syntax “or =” is too close to “or=”. How about using a macro to do something like this:

Code: Select all

#macro eoe(ex,v1,v2)
  ex=v1 or ex=v2
#endmacro

If eoe(IOCtrl.PortBit(Settings.InSkip1Pos(Xq)), Value1, Value2) Then
Other possibilities: eae, non, nan, noe, nae, eon, ean
counting_pine
Site Admin
Posts: 6323
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Post by counting_pine »

Actually, a macro could give you a lot of power, for example:

Code: Select all

#Define OR2( l, r1, r2) ( (l r1) orelse  (l r2) )
#Define OR3( l, r1, r2, r3) ( (l r1) orelse  OR2( l, r2, r3) )
#Define OR4( l, r1, r2, r3, r4) ( OR2(l, r1, r2) orelse OR2(l, r3, r4) )

#Define AND2(l, r1, r2) ( (l r1) andalso (l r2) )
#Define AND3(l, r1, r2, r3) ( (l r1) andalso AND2(l, r2, r3) )
#Define AND4(l, r1, r2, r3, r4) ( AND2(l, r1, r2) andalso AND2(l, r3, r4) )

dim as integer a
input "Enter a number: "; a

if AND2(a, >=0, <10) then
	print "0 <= " & a & " < 10"
	if OR4(a=, 2, 3, 5, 7) then print a & " is prime"
end if
Just be aware of the usual macro-expanding hazards, where expressions may be evaluated multiple times, so don't expect consistent results if the first parameter uses rnd or something.
Dinosaur
Posts: 1481
Joined: Jul 24, 2005 1:13
Location: Hervey Bay (.au)

Post by Dinosaur »

Hi all

Stylin, the last time I tried Select Case within a Case was many versions ago.
But have just tested and it seems to compile without error.
That is now stored in my memory bank for future use.
It doesnt detract from my suggestion though.

The idea of a macro to test 2 ,3, or more cases is to be investigated, but remember it is all about readability and not typing repeated statements.

Regards
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

Here's a quick set of macros for comparing a value against multiple (1 through 256) other values (uses ext/Preprocessor). It uses counting_pine's suggestion as a primary behavior pattern. Other helper macros could be added, like IsNotEqualTo or IsLessThanAny, but most of the comparison operations probably have little value.

Code: Select all

# include once "ext/preprocessor.bi"

'' ( ( LHS opRHS0 ) andalso ( LHS opRHS1 ) ... )
# define AndAlsoMulti( LHS, opRHSs ) _
    ( fbextPP_SeqForEachI( AndAlsoMulti_M, LHS, opRHSs ) )
# define AndAlsoMulti_M( LHS, i, opRHS ) _
    fbextPP_ExprIf( i, andalso ) ( (LHS) opRHS )

'' ( ( LHS opRHS0 ) orelse ( LHS opRHS1 ) ... )
# define OrElseMulti( LHS, opRHSs ) _
    ( fbextPP_SeqForEachI( OrElseMulti_M, LHS, opRHSs ) )
# define OrElseMulti_M( LHS, i, opRHS ) _
    fbextPP_ExprIf( i, orelse ) ( (LHS) opRHS )

'' ( ( LHS = RHS0 ) andalso ( LHS = RHS1 ) ... )
# define IsEqualTo( LHS, RHSs ) _
    AndAlsoMulti( LHS, fbextPP_SeqTransform( IsEqualTo_T, __, RHSs ) )
# define IsEqualTo_T(__, RHS ) = (RHS)

'' ( ( LHS = RHS0 ) orelse ( LHS = RHS1 ) ... )
# define IsEqualToAny( LHS, RHSs ) _
    OrElseMulti( LHS, fbextPP_SeqTransform( IsEqualToAny_T, __, RHSs ) )
# define IsEqualToAny_T(__, RHS ) = (RHS)

ASSERT( AndAlsoMulti( 1, (>0)(=1)(<2) ) )
ASSERT( not IsEqualToAny( 0, (1)(2)(3)(4) ) )
Regarding adding more quirk behavior in the language, I really don't like the idea. Either "verbose" code, Select Case or macros can be used to accomplish the same goal, and many of the syntaxes in this thread look confusing, IMHO.
VirusScanner
Posts: 775
Joined: Jul 01, 2005 18:45

Post by VirusScanner »

When you compare things like

Code: Select all

if somefn() = a orelse somefn() = b
somefn is evaluated twice (as long as its result is not equal to a), which is sometimes not desirable. If we eliminated the need to retype it, you would not be able to see that as clearly in the code. As it is, if you don't want it to be evaluated twice, use

Code: Select all

var x = somefn()
if x = a orelse x = b ...
I'm not sure if select case evaluates things for each case, but I think it's misleading to have too many shortcuts like that (plus in languages like C you can actually use the &= and |= operators in expressions, so it would be confusing to people coming from those languages).
Post Reply