[Gambas-user] static const?

Doriano Blengino doriano.blengino at ...1909...
Thu Apr 15 10:46:02 CEST 2010


Fabián Flores Vadell ha scritto:
> 2010/4/14 Doriano Blengino <doriano.blengino at ...1909...>:
>   
>
>> First example. I store some bookmarks...
>> ...
>>
>> I could break out the loop using a logic variable, but this way I save a
>> variable. Or I could test the variable in the loop construct, like this:
>>     
> I don't agree the criteria for saving one variable or one expresion if
> it is not justified.
>   
Well, perhaps my daily work with little CPUs (some have 32 bytes of 
ram!) drives me to professional bias, but why use a variable if can be 
avoided? There is more than one reason for this (reported without an 
order). One: variables have to be declared at the beginning of a block; 
when I write code, if I want to use a variable I must go back to the 
start of the code and add the declaration, leaving the old "road of my 
mind". Then I must go back to the relevant part and concentrate again on 
the code. Two: saving a state to later break a loop is less 
straightforward than doing it "in place". If the logic of an algorithm 
is "concentrated" in a single point, instead of being spread around, it 
is easier to revise - at least for me. Three: I think that fast 
algorithms are always better than slow ones. It is the duty of a good 
programmer to write good code: and good code is fast and easy to read. 
Perhaps, if I was a teacher, I would say different things. But teachers 
sometimes are a little distant from the reality; and scholars will face 
it later - when they will be programmers. Speed *is* important, the 
battle on computer hardware and software is all around performances. 
That said, using a variable is a cost (even more for interpreted 
languages like gambas). Well - we must understand each other. By no mean 
I want to say that using variables is awful - is a technique with pros 
and cons.

>
> Now, image an hypothetical case in that you have to do several
> conditional actions inside the loop. If you resolves it in that way,
> the code become hard to understand.
>
> Catch the joke:
>
>   FOR tries = 1 TO 2    ' to search again from the top
>     DO
>       IF Upper(Left(ME.item.Text, i)) = searchstring THEN
>         ' found item
>         RETURN
>       ENDIF
>       IF ME.MoveBelow() THEN BREAK
>       IF (YOU DONT LIKE) THEN RETURN
>       IF (YOU WANT) THEN RETURN
>       IF (NOT ME ..). THEN BREAK
>       IF (YOU DONT...) THEN BREAK
>       IF (YOU WRITE IN C) THEN RETURN
>       ...
>     LOOP
>     ME.MoveFirst
>   NEXT
>
> Ok, I know you wouldn't write something like that. Just I want to
> serve to show what I mean.
>   
Ah ah ah! You are wrong... this is my preferred style. I actually 
*write* things like that, especially when conditions are related. I mean 
- suppose you want to test the caption of a tabstrip (oh! what a 
coincidence...). You must read Tabstrip[i].Caption, but first you have 
to make sure that Tabstrip[i] really exists. So the test becomes:

    if (i<TabStrip.count) and (tabstrip[i].caption blahblahblah) THEN 
blahblahblah

This is a logical mislead, because it puts together two unrelated 
concepts: the test on the relevant thing (we look for caption), and a 
"good precaution" which has little to do with the algorithm. In fact, I 
would rewrite it as

    if i<tabstrip.count then if tabstrip[i].caption...

There is no difference in the final (machine) code, but the second 
statement looks to me more explanatory. And, to be sincere, there is 
more. The ambiguity of the first statement is well stressed in other 
languages (sorry, they exist), where sometimes there is no warranty 
about the order of evaluation of expressions. For whatever reason, a 
compiler could evaluate tabstrip[i].caption *before* tabstrip.count. 
And, of course, the compiler is right - the AND operation is commutative 
(the two terms can be swapped), like addition and multiplication. Back 
to gambas - I don't know if the documentation says anything about 
short-circuit and things like that. May be we can assume it as a 
standard, that modern languages always do short-circuit, but the concept 
remains. This is why in many cases I could write, especially in a cycle:

    if i>=tabstrip.count then break
    if tabstrip[i].caption ... then ...

Here, the focus about the counter "i", and the usage of ".caption" is 
even more separated - two statements instead of one - because they are 
at two different levels. This is only an example I stretched beyond the 
reality, but you got it.
>
> If you have to do tests (like unit tests) and you have routines with
> multiple exit points, maybe you will have some coverage problems. What
> do you think?
>   
I think that it is exactly the same thing. If you use a variable to 
break a loop, or return from a function, then that variable "is" an exit 
point. With an additional problem - that the variable can be changed 
later... a RETURN is always a RETURN instead.
At this point, I would add that "single return points" are, for me, 
worse than multiple exit point. Excuse me again if I pull in other 
languages, but now they are very useful. Modern Pascal can use the 
variable RESULT to hold the returned result of a function. This sub:

    function doit as integer
       return 1
    end

can be written (in "pascalized" gambas) as

    function doit as integer
       result = 1
    end

Now I will write a subroutine to move a file. The result is TRUE if the 
operation is successful, and false if it is not. Pseudocode, single exit 
point:

  function movefile(src, dst as string) as boolean
  DIM ok as boolean

    ok = false
    if exists(src) then
      if open_and_read(src) then
        close(src)
        if open_and_write(dst) then
          close(dst)
          ok = true
        endif
      endif
    endif
    return ok
  end
     
Pseudocode, using "result pascalism", multiple exit point:

  function movefile(src, dst as string) as boolean
    result = false
    if not exists(src) then return
    if not open_and_read(src) then return
    close(src)
    if not open_and_write(dst) then return
    close(dst)
    result = true
  end

Now comes personal taste. The second routine, for you, is a joke. For 
me, it looks simpler, shorter, and faster. The only problem I see are 
those repeated "not" and "return". They are ugly to see, but very clear 
in saying "if this operation fails, then stop". The code coverage should 
be simpler to do, but I am not really sure.

>
> I would say that, "if" the speed is important, "and" code not become
> unclear, you can do efforts to not add one test more (or to keep
> worried about performance).
>   
Ok, these are two opposite point of view that can meet in a region 
called "personal style".
>
>> After citing "other languages", I came back to
>> gambas saying "in other languages this is not stressed the same way
>> (basic, for example)". I wanted to say that in basic, and hence in
>> gambas too, it is possible to modify the value of the control variable.
>> Who thinks this is ugly, simply has to abstain from it...
>>     
>
> Except that often isn't a good thing for the students. Someone could
> say that everybody can use the sentence GOTO, and if you are a good
> programmer you will haven't problems.
>
> I think that the subject here is identify practices that have
> potential to bring problems.
>   
Yes. And about GOTOs, I use them too. Here we come to the basics of many 
arts and sciences... one must learn the rules and use them. When one is 
really a master, he is entitled to break them - then he turns (perhaps) 
into a genius.
What is the differences in breaking rules, between a stupid and a 
genius? The first does not know what he is doing, the second does know 
very very well...
GOTOs were the only mean to control the program flow, once upon a time. 
When some genius broke the rules and invented structural programming, 
GOTOs were rewarded as evil, and we are still in the long wave of this 
thought.
But Pascal (and C, - sorry - the most important language of all times, 
until now), still retained GOTOs. Strange... may be that they are, after 
all, not so evil? We don't want spaghetti outside our food, but there is 
a way in between - ok for a GOTO, when you have a reason for that. 
Practices that have potential to bring problems are not simple things 
like "using GOTO", or "using object oriented programming". The issue is 
far more complicated. Going on, I would say that, in certain cases, it 
*is* an error to not use GOTOs. In some situations, it is an error to 
use objects. And so on. Nothing is perfect, and nothing is totally bad.

Well. I really enjoyed to discuss with you. Because I feel that we both 
have slightly changed our mind - we have had an improvement. Even If we 
didn't change our thought, it seems to me that we, at least, had 
understand each other. Not a bad thing.

Regards, and best wishes for your teacher job. We need good teachers.

Doriano





More information about the User mailing list