Logical operators in VFP, in their order of precedence are:
Operator | Description |
---|---|
( ) | Parentheses, groups expressions |
NOT, ! | Logically negate the expression. NOT or ! has no difference. |
AND | Logically AND the expressions |
OR | Logically OR the expressions |
<>, !=, # | Check for inequality. Thus same as logical exlusive OR - XOR |
Historically, NOT, AND, OR are written as .NOT., .AND., .OR. You can still use them if you like to, but AND, OR, NOT is simpler and cleaner.
For false and true, you have to use .F. and .T. literals respectively. You cannot choose to use F and T instead.
* Some logical variables
local llOld, llEmail && any variable declaration implicitly initializes the variable as .F. - false
? m.llOld, m.llEmail && Prints .F. .F.
llOld = .T.
llEmail = .F.
if ( m.llOld AND m.llEmail )
? 'Old AND should be emailed to'
endif
if ( m.llOld OR m.llEmail )
? 'Old OR should be emailed to'
endif
if ( m.llOld AND !m.llEmail ) && Same as (m.llOld AND NOT m.llEmail)
? 'Old BUT should NOT be emailed to'
endif
* Above code outputs
Old OR should be emailed to
Old BUT should NOT be emailed to
In VFP, logical expresssions are evaluated in a shortcut fashion. That is, if the first part of the check satisfies the whole result, rest of the expression is not even interpreted. A sample follows:
? 1 = '2' && An obvious error. It would complain operator/operand type mismatch.
* However we could use such an expression in an if and get no error
* because it is not interpreted at all
* (VFP is dynamic and there is no compile time check)
local llProcess
llProcess = .T.
if (m.llProcess OR (1='2'))
? 'Should do processing'
endif
* Would output
Should do processing
* without any error because m.llProcess true means
* the whole expression would be true, thus the expression after OR
* is not interpreted at all.
One pitfall that catches newbies is that, sometimes you might need multiple checks, say in an SQL query, which are connected with AND, OR operators. When there are many of them, one might ignore the fact that operators have a precedence (in order (), NOT, AND, OR) and think the interpretation would be done left to right in a chain. Consider a sample:
select * from myTable where !isCustomer AND debit > 5000 OR discount > 5
what is the intention of this query? If we make it explicit using grouping parentheses it says:
((NOT isCustomer) AND debit > 5000) OR discount > 5
simplified it looks like "firstExpression" OR (discount > 5). Whatever the intention was, because of this OR it would select:
all the rows that have (discount > 5) - and also those where it is a customer with over 5000 debit.
Probably the intention was "give me those where it is NOT a customer AND (debit is over 5000 OR discount is over 5)". It would be clear from the start if we used parentheses:
select * from myTable where !isCustomer AND (debit > 5000 OR discount > 5)
You may use but not worth to have parentheses for the initial NOT operator, when its operand is a single expression its readable enough with its precedence - !isCustomer is clearly read as (NOT isCustomer).