IF NOT AVAILABLE(tableX) OR tableX.FieldY = "somevalue&

Posted by OctavioOlguin on 16-Jan-2016 15:30

For 20 years I've used:

FIND sometable NO-LOCK NO-ERROR.
IF NOT available(someForm)
  OR (Available(someForm) AND (somefield1 EQ NO) AND somefield2 = 3 AND some...) 
THEN
     MESSAGE "Case of something".
ELSE 
     MESSAGE "Another case".

now  few days back I saw a post somewhere around here that used the syntax on the title of post..

I know that the order of operators and logic of complex expresion are to be taken on account.

But wonder, what's the logic of the compiler or runtime AVL (whichever one involved).

In:    "IF NOT AVAILABLE(tableX) OR tableX.FieldY = "somevalue" THEN..."

the OR part should be evaluated even in the case that AVAILABLE() is false, but at this point the FIND was unsuccesful, so:

why on earth won't be a NOT AVAILABLE BUFFER error for the tableX.FieldY = "somevalue" evaluation????


Just  realized the very few knowledge of 4gl I got.

All Replies

Posted by GregHiggins on 16-Jan-2016 20:57

If the record is not available the first part of the OR expression is true, hence the entire OR expression is true hence no need to evaluate the second expression. This is called short circuiting and it has been a part of the language since V5. In V4 this would have generated an error.

Posted by OctavioOlguin on 18-Jan-2016 12:22

I've done several experiments, and the syntax i've bee using it's what should be used.  So the snipet I saw here somewhere it's wrong in this aspect, as the folowing snipet would show a Record not available as expected.

FIND FIRST Table1 WHERE Field1 = 12312312123 NO-ERROR.  // it wouldn't find anything
IF FALSE 
    OR ( Table1.Field2 = "C")
THEN DO:
   MESSAGE "No"
      VIEW-AS ALERT-BOX.
END.

So, rest my case,

Posted by Peter Judge on 18-Jan-2016 12:26

your comparison is slightly off. in the first example "NOT AVAILABLE <table" is TRUE, so it evaulates close to

IF TRUE OR ( Viaje.statusviaje = "C")

In the second example you are always going to evaluate the expression after the OR since FALSE is never able to be TRUE.

Posted by pliscki on 20-Jan-2016 10:22

The syntax, or better saying, the logic you've been using is redundant. Therefore, there's no need to use it.

The snippet you saw is completely RIGHT.  Your example, on the other hand, is logically wrong as the left side of the OR clause will always be false, thus, ABL will evaluate the right side and since the record is not available, ABL will throw an error.

Now, why this snippet is right? 

1º ABL evaluate OR from left to right

2º "AVAILABLE" is an ABL function the returns TRUE if the record is available and FALSE if not

Therefore considering the TableX is not available:

/* record not available */
FIND FIRST tableX NO-ERROR.

/* Output false */
DISP AVAILABLE TableX.

/* Output true because of NOT */

DISP NOT AVAILABLE TableX.

You're misunderstanding things because you didn't understand the usage of NOT.

Posted by GregHiggins on 20-Jan-2016 10:50

Let's observe that the AVM evaluates expression clauses from LEFT to RIGHT, not the other way around.

The original snippet was NOT AVAILABLE(tableX) OR tableX.FieldY = "somevalue" I would have written this as AVAILABLE(tableX) AND tableX.FieldY = "somevalue", but the original syntax is fine for the coders purpose.

Note that AVAILABLE(tableX) is a precondition of tableX.FieldY = "somevalue". Hence my preference for the latter syntax.

Posted by pliscki on 20-Jan-2016 11:21

Indeed Greg,

It was my bad, I swapped all rights for lefts in my whole answer. But in my mind I meant the opposite. LOL

I've edited the post. Thanks.

And I agree with you, using AND is better.

Posted by OctavioOlguin on 21-Jan-2016 12:26

Hi...

I saw the aswers yesterday while on the run, and prepared to came with my sword unsheathed today.  But I see that someone commented on the left to right  issue.

My point is the following.  In the next sentence, if for some reason the first condition fails then AVM will check the SECOND part of the OR clause.  and being that the record could be available (OR not)  i'll test some condition on it, so I have to make sure that it is available.

IF (NOT AVAILABLE(X1))  OR (AVAILABLE(X1) AND X1.Field1 = "1")

this is simple.  I have to do something in case the record wont' exis,  or if it exists, do something only if it is some special kind of record (as stated by the Field! being "1").  I use that for a case where customer won't exists, or it exists, but for conditions like addres or so, don't have to be taken on account.

I ended doing this way instead of:

IF NOT AVAILABLE X1 THEN DO:

  RUN proc1.

END.

ELSE  IF AVAILABLE(1) AND X1.Field1 = "1" THEN

               run proc1.

Posted by Marian Edu on 21-Jan-2016 12:34

Octavio,

what is the point in checking if record is available, you're already on the else branch where you can trust the record is available :)

if not available(x1) or x1.field1 = '1' then run proc1.

Posted by Brian K. Maher on 21-Jan-2016 12:48

In that code snippet you actually don't need the do/end block.  64 bytes of wasted r-code.  :-)

Posted by OctavioOlguin on 23-Jan-2016 16:03

Hi Marian... Yes you nailed a little (big) error.

It came from trying to de-compose (factoring) the MPP (modus ponendo pones) clause that originally took me to the first sintax.

Any way...

What i try to expose, was the fact that a clause like

IF NOT AVAILABLE(x1) THEN DO: ...

END.

ELSE

   IF X1.Field1 = "something" THEN DO something else for a case where the record falls outside some use case....

could be expressed like

IF (NOT AVAILABLE(X1)) OR (AVAILABLE(x1) AND X1.Field1 = "something") THEN .....

as the AVM will discard the first condition but to be a able to test for Field1 = "something" ther should be a record on buffer, otherwise it will cast a Record not available....

I'm very sorry for not being able to "think in english", and create this missunderstanding...  sorry...

Posted by OctavioOlguin on 23-Jan-2016 16:10

Hi Brian....

You put me to think...

more often than not, I use DO: END. just to help the syntax formatter to format correctly the {&OPEN-QUERY-...} code here and there.

If I left them free, the formatter scrambles the tabbing of following lines...  

I'll give it a second tought from now on...

Thanks!

Greetings

Posted by ske on 25-Jan-2016 02:32

> IF (NOT AVAILABLE(X1)) OR (AVAILABLE(x1) AND X1.Field1 = "something") THEN .....

> as the AVM will discard the first condition but to be a able to test for Field1 = "something" ther should be a

> record on buffer, otherwise it will cast a Record not available....

You don't need the second AVAILABLE(x1) after OR, because if the record is not available, the left side of OR will already be TRUE and the right side of OR will not be tried at all! And since it will not be tried, you will not get "Record not available". (Like GregHiggins told you already.) Try it out and see for yourself...

Posted by Lieven De Foor on 25-Jan-2016 08:39

In short: TRUE OR whatever_expression_here = TRUE /* And the right side doesn't get evaluated */

Same for: FALSE AND whatever_here = FALSE

See -> en.wikipedia.org/.../Short-circuit_evaluation

This thread is closed