Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
One exit per procedure/function/codeblock to what purpos
Message
De
11/10/2003 20:15:57
 
 
À
11/10/2003 00:43:44
Mike Yearwood
Toronto, Ontario, Canada
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Divers
Thread ID:
00835552
Message ID:
00837868
Vues:
48
Snipped selectively where we seem to be in agreement.

>>*** SECTION 1 ***
>>>Hi Al
>>>
>>>I think we'd all do better to remove style from such discussions.
>>
>>I don't know what you mean by "style" - programming style (isn't the whole thread about this?) or posting style? If the latter, do you have a specific complaint?
>
>I'm referring to programming style. I'm perfectly willing to consider changing my current style, if someone can convince me of a better way. I have changed my style to match others' styles on several occasions. If we all refuse to leave this possibility open, there is little point to continuing the discussion of standards.

Thanks for the clarification. I mostly agree, but I still think one can discuss the pros and cons of various approaches without having to change one's own approach.

>>>I also think we'd do better to approach this with the belief that someone certainly has a better way to do things.
>>
>>I don't know what you're getting at here, but if we take this literally it's not true. In some things it can be proven there is an optimal solution which can't be improved further. Take linear programming in mathematics, for example.
>
>I've asked for opinions on possible improvements to my routines. In every instance, this board has provided a better version of my routine. Keeping an open mind as to the possibility that a better way exists, should help this discussion move forward. I'm leaving room for the possibility that your approach is better than mine.

Thanks for the clarification.

>>>It used to be we'd try to be efficient, now we're letting faster computers make us lazy.
>>
>>It's not true of me. You're casting aspersions on the practitioners of this profession.
>
>That is a matter of opinion. I want more value, yet I hear the argument that today's computers are so fast that speed is not significant too often.

I was objecting to the use of the royal "we". Your statement does not apply to me, that is *not* a matter of opinion. "We" can speak only for ourselves.

As for the "fast computer" argument, it may pay to keep an open mind there, too. It may be less expensive for a client to invest in new hardware than to try to improve code.

The argument you object to is rooted in the old "Andy Grove giveth, Bill Gates taketh away" concept. For most of the history of the PC you needed a "fast" (by the standards of the day) computer to run "typical" applications "well". A corollary saying to this was by one of the PC Magazine columnists (Machrone or Dvorak, I can't remember which) who said, "The computer you really want always costs $5,000 (US)". Both of these ideas held true up to about 2 or 3 years ago, when CPU speeds started ramping up rapidly from the 500MHz range. Since then there has been a great increase in what Andy Grove has given us, and Bill Gates' larger OSs and apps have not used up all of this extra capacity. Fact is, the cheapest new computer you can buy from Dell these days (~CAN$500 including monitor!) can run Windows XP and MS Office *well*.

One result is, if I can spend less time optimizing code but still deliver acceptable performance, my clients can get their software for a lower price.

>>*** SECTION 2 ***
>>
>>>>>You're not saying that
FOR x = 1 TO 10
>>>>>    ...some code
>>>>>    x = 11
>>>>>    ...some more code
>>>>>NEXT x
>>>>>is better than
FOR x = 1 TO 10
>>>>>    ...some code
>>>>>    EXIT
>>>>>    ...some more code
>>>>>NEXT x
are you?
>>>>
>>>>No, they're both bad ;-)
llDone = .F.
>>>>x = 1
>>>>
>>>>DO WHILE x < 11 AND NOT llDone
>>>>  ...some code
>>>>  * Set llDone appropriately
>>>>
>>>>  x = x + 1
>>>>
>>>>ENDDO
>>>
>>>I'm guessing you were kidding. Would a discussion of the reasons why this example might be used as a joke be OK?
>>
>>No, I wasn't kidding and I'll try to forget you consider my opinion a joke.
>
>You did put a wink after saying they are both bad. I interpreted the wink as indicating you were joking. Since you were serious, we have a communication problem. I did say I was guessing, which you seem to have taken as "consider my opinion a joke".

Unfortunate miscommunication. I put the "wink" because Jim might have taken it personally if I hadn't; without it, it looks a little harsh. Still, if someone presented some code and I wasn't 100% sure, I would try to treat it seriously by default. You've been on this board a while, I thought you might have known the vast majority of my posts are serious. My apologies if not.

>>My code above reformulated slightly below, followed by further discussion.
m.llDoneEarly = .F.
>>m.x = 1
>>
>>DO WHILE m.x <= 10 AND NOT m.llDoneEarly
>>  ...some code
>>  * Set m.llDoneEarly appropriately
>>
>>  m.x = m.x + 1
>>
>>ENDDO
>>>FOR X = 1 TO 10 clearly indicates the range of the loop.
>>
>>The problem I have with this whole FOR approach is that the first, defining line is a lie. The FOR statement says the loop will be executed 10 times. Really, the loop is going to be executed 10 times unless it's finished early. Your approach lies by omission; mine is crystal-clear, explicitly alerting the reader to watch out for special conditions later in the code.
>
>I wouldn't call this my approach. I didn't invent FOR...NEXT ;).

My apologies, I should have said "Jim's".

>I agree that "your approach" now says the loop will run to a maximum of ten if it doesn't end early. However, I have to read two lines of code to see the start and end values.
>
>Perhaps this can be dealt with by ...
>
>
DO WHILE m.x >=1 AND m.x<=10 AND NOT m.llDoneEarly
>
>The FOR NEXT construct supports an EXIT. It should be recognized that an early exit is always possible.

Well, it supports LOOP as well, and there's no reason you couldn't RETURN from within one either. But using any of them means the main, defining line of the loop is incomplete or misleading.

>
>>
>>>Efficiency: The m.llDone variable requires extra code to create and update.
>>
>>To create the variable, yes. To update, maybe not:
* Within the loop:
>>* Your way:
>>IF SomeLogicalCondition()
>>  EXIT
>>
>>ENDIF
>>
>>* My way:
>>m.llDoneEarly = SomeLogicalCondition()
>>
>>One advantage to having the variable is in debugging and future code enhancement. At the end of the loop you can find out if it went the whole distance or if it finished early. In my real life code I find I need this kind of information *all the time*.
>
>Hmmmm. That is an interesting point. However, I can determine that FOR NEXT also has ended early by comparing the highest value of x with the maximum value of x. I admit this requires either ...
>
>
FOR x = 1 TO 1000
>  IF x = 10
>    llDoneEarly = .T.
>    EXIT
>  ENDIF
>ENDFOR
>?m.x
>
>OR
>
>
FOR x = 1 TO 1000
>  IF x = 10
>    EXIT
>  ENDIF
>ENDFOR
>m.llDoneEarly = (m.x <> 1000)
It's worth pointing out your first example will give you a result you might not expect, and your second example has a bug. Note, that if the loop runs to completion the value of x will be 1001, not 1000. In a real-world situation the second approach would have already cost you some debugging time. You'd have to fix it by using the awkward-looking constant of 1001 or generic value of (MaxLoopValue + 1). By using the explicitly declared llDoneEarly variable and setting it within the loop, this type of bug doesn't happen.

Another subtle effect is that if you don't explicitly declare the variable beforehand, FOR will create x as PRIVATE, not LOCAL as you might expect.

>>>The use of the do while...enddo versus the for...endfor involves an extra line x = m.x + 1. x would have to be declared as 1 before the loop.
>>
>>The FOR loop has to declare, initialize, and increment the x variable as well. It might be more efficient in doing so, but if so, how much? Is it significant? We'd need real-world tests to tell for sure. I've been surprised by test results too often to rely on theoretical discussions on how anyone thinks VFP *should* work anymore.
>
>There is that significance argument. I'm trying for as much value as possible. If one approach meets more of the readable-maintainable-speed criteria than another, I want to use that approach.
>
>You have to write code to create and update x, where the for next takes care of that. That leaves more code to test, and possibly room for more bugs. It is a fact that executing a line of code takes time.
>
>Why do we need real-world tests? Do other disciplines not test things in labs to see if they will be able to move into the real world? If we are to create real-world tests, shall we use code from my current project? Do I then have to give you my client's data to prove one approach is faster than another. That is not possible. So we're back to the lab, but you suggest that is not reliable.

By "real-world" I meant real tests with real code on a real computer, not just people theorizing that because one approach needs more lines of code than another, it must be slower. The best tests might make use of real data on real computers in real networks/environments, and certainly should make use of the widest possible range of test parameters but I see no problem with well-designed synthetic benchmarks.

>It is documented that FOR NEXT/ENDFOR should be used when the number of iterations is known in advance. Do you suggest using DO WHILE for everything and never using FOR NEXT/ENDFOR and that this be a standard?

Of course not - I don't know where you get this idea. As you point out, FOR is ideal when the number of iterations *is known in advance*. I'm arguing that if it isn't, DO WHILE has advantages.

FOR is compact and syntactically elegant for things like array and list processing, and its cousin FOR EACH... is invaluable for processing collections. I use them both from time to time.

>Many interesting points. Thank you for taking the time to discuss this!

Likewise!

*** SECTION 3 ***
Another thought has just occurred to me, about why I don't like multiple exit points in general. Continuing with the FOR example containing an EXIT, it has to do with what VFP has to do in setting up and breaking down a loop structure internally. If EXIT was not supported, the loop could always reliably be broken down by the FOR statement once the iteration count is exceeded. However, EXIT transfers control to the line immediately following ENDFOR/NEXT. This complicates interpreter design as an implicit loop breakdown must be executed before the transfer of control. Otherwise, undesirable side effects such as memory leaks may occur.

I imagine it would be enlightening to talk to the Fox Team about this kind of issue. One thing we can be sure of, though, is that anything that complicates the interpreter is a chance for bugs to creep in, and also consumes more of their limited time.

Over the years I'm sure the vast majority of these sorts of issues have been ironed out pretty smooth, but I still feel more comfortable exercising the interpreter in the "expected" fashion. Like driving on a paved thoroughfare rather than a gravel back road.
Regards. Al

"Violence is the last refuge of the incompetent." -- Isaac Asimov
"Never let your sense of morals prevent you from doing what is right." -- Isaac Asimov

Neither a despot, nor a doormat, be

Every app wants to be a database app when it grows up
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform