Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
The m. variable thing, the sequel
Message
From
10/01/2005 09:07:41
 
 
To
10/01/2005 03:04:24
Walter Meester
HoogkarspelNetherlands
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Environment versions
Database:
Visual FoxPro
Miscellaneous
Thread ID:
00969478
Message ID:
00975628
Views:
84
Hi Walter,

I've always recognized that FP/VFP's DO CASE differed from the "traditional" CASE found in other languages and feel that it is yet another small advantage of VFP over other languages. It is rare that I restrict a CASE to a single variable being tested for different values.
So I certainly have no problem at all with your first example below.

My objection comes from one factor in particular, which is usually justified (as you do here) by "I hate nested IFs".

I will try to precisely describe what I find objectionable:

I say that 100% of programmers expect that the "work" of any CASE statement of a DO CASE is to make some decision, whether it is simple or complex.
When it is simple then the factors can be coded right in the CASE, but more complex DECISIONS might need a function call or two.

When a function call in a CASE statement does more "work" than simply make a decision then I believe that you are betraying the expectations of 95% of VFP programmers. And when you deliberately preceed that worker function with a little "!" so that the tests will continue to later CASEs then you confound them even further.
Is that worth it just because **you** hate nested IFs? My answer is no, it is not, WHEN IT IS PREDICTABLE THAT OTHERS WILL MAINTAIN THE CODE.
For the sake of YOUR distaste of nested IFs you will significantly extend the maintenance time of some other programmer to enhance or fix the code!

From a 'readability' point of view your second example is really off-putting to me. You've had to use "!" in 4 of your CASE statements to assure execution of the next in most cases. While it's perfectly readable on the second CASE the "!" in the first, third and fourth instances hurt readability badly. Remember, the only "work" expected to be done is to make a decision or to provide a decision factor. Yours are doing more than that.

I believe that most (95%+) programmers start reading a DO CASE with the mindset that they don't really need to examine each function in detail because only a decision (factor) is being provided so they can readily assess its impact on their problem at hand by simply reading the whole DO CASE. So they will quickly move on from here because they see nothing that might impact their problem at hand.
Once they learn **YOUR** chosen usage then of course they now know that they have to carefully examine each and every function call's code too. That is decidedly not "helpful".

There are certain things in VFP programming (and any other) that "personal preference" ought not to overrule. Some that come to mind are abbreviating everything to save typing, coding a 8+ function expression to show one's coding prowess, avoiding the use of nested IFs by employing a 'corruption' of DO CASE just because one hates nested IFs. These are things that may satisfy the originator but they surely hamper the NEXT programmer's work in that code.

The ultimate purpose for "readability" is to serve the NEXT programmer. Your second CASE construct fails that for 95%+ of programmers.
cheers

>Hi Jim,
>
>I agree that the most traditional and simple usage of DO CASE is the construct that is simular to the switch case structure found in several other languages:
>
>
DO CASE
>    CASE x = 1
>        .....
>    CASE x = 2
>        .....
>    CASE x = 3
>        .....
>    CASE x = 4
>        .....
>    CASE x = 5
>        .....
>    OTHERWISE
>        .....
>ENDCASE
>
>However you can do more with it. In the above example the order of the casing does not matter. However You can also use the ordering to rule out certain conditions.
>
>
DO CASE
>    CASE DELETED()
>        ... Do nothing
>
>    CASE OLDVAL("MyField") == EVAL("Myfield")
>        ... Do nothing
>
>    CASE OLDVAL("MyField") > EVAL("Myfield")
>        && Increase stock
>
>    OTHERWISE
>        && IOW, OLDVAL("MyField") < EVAL("Myfield")
>        && Decrease stock
>ENDCASE
>
>In the above the ordering is fixed. You cannot change the ordering without changing the behaviour.
>
>The thing you are objecting against is the use of functions to perform a certain action.
>
>
DO CASE
>    CASE THISFORM.RecordHasChanges() AND !THISFORM.SaveChanges()
>        && Failed to save the changes
>
>    CASE !SEEK(cItem,"Items")
>        && Item does not exist
>
>    CASE Items.Discontinued
>        && Item has been dicontinued and thus cannot be ordered
>
>    CASE nOrderCount = 0
>
>    CASE nOrderCount > 0 AND !oBizOrders.Order(cItem, nOrderCount)
>        && Could not order
>
>    CASE nOrderCount < 0 AND !oBizOrders.Order(cItem, nOrderCount)
>        && Could not return order
>
>    OTHERWISE
>        && Order has succeeded
>ENDCASE
>
>I am well aware of that developpers comming from another language and see the DO CASE as a replacement of the switch case statement (or another simular construct in other languages) might get confused at first sight. However the last example above atually simulates a flow diagram where the CASEs are implementations of decision points.
>
>IMO, this implemenation is more readable than the implementation with IF statements:
>
>
>IF !THISFORM.RecordHasChanges() OR THISFORM.SaveChanges()
>   IF SEEK(cItem,"Items")
>       IF !Items.Discontinued
>          DO CASE
>             CASE nOrderCount = 0
>
>             CASE nOrderCount > 0
>                 IF !oBizOrders.Order(cItem, nOrderCount)
>                     && Could not be ordered
>                 ENDIF
>
>             CASE nOrderCound < 0
>                 IF !oBizOrders.Order(cItem, nOrderCount)
>                     && Could not be returned
>                 ENDIF
>          ENDCASE
>       ELSE
>          && The item has been discontimued
>       ENDIF
>   ELSE
>      && Item does not exist
>   ENDIF
>ELSE
>   && Item could not be saved
>ENDIF
>
>While I do recognize that nested IFs cannot always be avoided, reading through a nested if is always troublesome (at least for me). It takes me a rewrite to figure out what it exactly is supposed to do and draw a process flow diagram out of it. a DO CASE in this instance would give me a better structure to give this overview. Its a more high level of implementation a process flow IMO.
>
>The problem with the nested IFs is that the ELSE of the same condition could be a few pages away. In the past I had to deal with a lot of clipper programs that were written in the JSP style exactly doing this (a DO WHILE .T. with EXITS, LOOPS and a lot of nested IF conditions and a lot of repetitive code in a lots of ELSE conditions: a real maintenance nightmare.
>
>Somethimes I may drift too far in my desire to capture everything into a do case. In a nested IF construct like the following..
>
>
IF x
>   IF y
>      DO SomeThing
>      IF z
>
>      ELSE
>
>      ENDIF
>   ELSE
>   ENDIF
>ELSE
>
ENDIF
>
>The 'do something' is not a function, but does just perform a certain algorithm. It is not a part of the decisions in the nested IF. This does not fit well into a do case. In very exceptional cases were my urge to capture this into a DO CASE is stronger than my will to write a nested IF, I will do the following:
>
>
DO CASE
>    CASE !x
>
>    CASE !y
>
>    CASE Something() <B>AND .F.</B>
>        && Just a trick to execute the function something uncunditionally.
>
>    CASE z
>
>    OTHERWISE
>
>ENDCASE
>
>So, yes, I am aware that people not used to the DO CASE usages might find it odd at first, but IMO it is not that hard to get used to it, and in the end it might prove more readable and maintainable. So yes, I think people should be aware that DO CASE is not an implementation of switch .. case but a construct that has a wider application.
>
>Walter,
>
>
>
>
>
>
>
>
>
>
>
>>SNIP
>>>
>>>Also in this case, performance is not the factor that determines the place of a CASE statement in a DO CASE. The performance differences is in most cases negligible. Personally I use the order of the CASE to rule out certain conditions. I take advantage of the CASE ordering. While not regarded as best practise by many, its a practise I'm very comfortable with.
>>
>>I just **had** to make a comment here, Walter...
>>While you yourself are very comfortable with that practise, you seem to neglect the fact that others who might read such code do not even expect such a usage and so might be led quite astray by such coding.
>>
>>I dare say, for instance, that most VFP developers do not expect a CASE construct to be written such that every (or most) CASEs WILL *each* perform an important part of a task. Most readers, I contend, expect a single CASE to come into play in a DO CASE block.
>>
>>So while you are very "comfortable" you seem to be making no allowance for who will read the code next. To me this is the single most important part of programming that has known production/maintenance requirements.
>>>
>>>I want to take the opportunity to point out, that seeking performance improvements in this kind of issues is useless. Most of the time the performance issue is related to database access or the algorithm or design of the system. Focusing on these kind of things to improve performance is non productive IMO.
>>
>>I agree fully. However, there is a difference between "focusing" and just plain coding practises that help to maintain high performance.
>>cheers
>>
>>
>>>
>>>>Just my $0.02
>>>
>>>My € 0.02
>>>
>>>Walter,
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform