[Gambas-user] static const?

Doriano Blengino doriano.blengino at ...1909...
Wed Apr 14 23:00:48 CEST 2010


Fabián Flores Vadell ha scritto:
> 2010/4/14 Doriano Blengino<doriano.blengino at ...1909...>:
>
>    
>> Back to the beginning: a CONST declaration is something that uses no
>> memory, so it can not have instances, and hence it can not be STATIC.
>>      
> Thanks Doriano. I understand that. My question was caused by the fact
> that the compiler allows use the keyword STATIC in the declaration of
> constants, even though the online help and a very basic logical
> reasoning indicate that use the keyword STATIC is unnecesary in this
> situation
>    
And here we return on your idea about a good compiler - and it is mine 
idea too. A good compiler should be very precise about things that have 
sense, and can be done, and things that can not be done, or have no meaning.
In this respect, it is a nonsense to let the user write a "CONST 
STATIC". But compilers sometimes must keep compatibility with other, 
older, compilers. So, in this case, may be that VB(tm) was accepting 
this, and so does gambas. But I don't know VB(tm). Anyway, this issue is 
harmless, so I don't see it as a big problem.
>    
>> About the cycles WHILE, FOR, REPEAT and so on, I think the statements
>> BREAK and CONTINUE are very useful (I would add a third statement:
>> RESTART): they permit a finer control and many times they are clearer
>> than complex tests.
>>      
> You do not give arguments to support your opinion. Can you give me
> some examples? I think, that these can be obvious for you, but not for
> me.
>    
First of all, I must say that I see your point. May be that all the 
issue is about personal style. But I did a quick research in my sources 
to let you see some example. I have little code in gambas - I use a lot 
C, about which I could have many examples but, as stated by someone 
other, it is forbidden to talk about C...

First example. I store some bookmarks in a file by using the Settings 
class. Every bookmark is stored with a name like "Bmark1", "Bmark2" and 
so on, but I don't know how many of them are in the file. I know when 
there are no more values, instead. So the routine is the following:

   i = 1
   DO
     st = settings["Bmark" & i, ""]
     IF st = "" THEN BREAK
     men = NEW Menu(mnBooks) AS "chgBook"
     men.Caption = st
     INC i
   LOOP

Now, to understand if there are more bookmarks to read, I must try to 
read it. If the value is NULL, then the job is finished. Clearly, a 
FOR-NEXT is no good (or, one can write a for-next from 1 to 1000... 
misleading...).
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 = 1
   DO
     st = settings["Bmark" & i, ""]
     if st<>"" then
       men = NEW Menu(mnBooks) AS "chgBook"
       men.Caption = st
     ENDIF
     INC i
   while st<>""

but, as you see, there are TWO tests instead of one, and there is an 
added line of code. May be that I am missing something, but the BREAK 
instruction is really useful here.

The second example is a textual search on a treeview. If the user types 
some text, the selection is moved on the next item beginning with that 
text. If no more items satisfy the criterium, the search must start 
again at the top, but only once. So the code (there is a ME.MoveBelow() 
just before this code, I omitted it for simplicity):

   i = Len(searchstring)
   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
     LOOP
     ME.MoveFirst
   NEXT

Here, the FOR-NEXT is a quick way to execute some code for no more than 
two times...
Again, I could have used a variable to store the result of the test, but 
I saved it...
And again this is not, perhaps, the best code you can see around - but 
it works, and it is reasonably fast and short.


>    
>> Your example only has two test, against COUNT and
>> the CAPTION. What kind of test would you write if the conditions were
>> 15? Perhaps concatenated (I mean, some test are only meaningful when
>> other conditions are met).
>>      
> Assign the results of logical expressions to Boolean variables, it is
> often the way to manage the complexity of conditionals expressions.
> And in the loops, to use these variables instead of those logical
> expressions.
>
> But I think that you are knowing well this, and you points to the
> performance of programs. If so, my answer is that the performance
> isn't a priority in many types of programs, and the evaluation of
> logical expressions have a little cost in comparation with other
> operations (I/O, compression, among many others).
>    
I agree, and partly not.
I think that clearness and beatiful code is to prefer against speed, but 
only when speed is not an issue.
In the text-search example speed *is* an issue. Never tried to open a 
directory with some 30000 files in it, and perform a textual search? KDE 
solves elegantly... it does textual search *only* if the sort order is 
"by name". Ridicolous...

>    
>> Finally, your last lines of code do not work:
>>      
> Yes, it works.
>
>    
>>> PRIVATE FUNCTION ScanTab(IdCaption AS String) AS Byte
>>> DIM a AS Byte = 0
>>>
>>>     WHILE (a<    TabStrip1.Count - 1) AND (TabStrip1[a].Text<>    IdCaption)
>>>       INC a
>>>     WEND
>>>
>>>     RETURN IF(TabStrip1[a].Caption = IdCaption, a, -1)
>>> END
>>>        
>    
>> The third cycle does not get executed - "a" is 2, which is not less than
>> "3-1" (it is equal).
>>      
> That's irrelevant because the external comprobation (the logical
> expression in the return sentence)
>    
May be that I am missing something, but... how can you say that it works 
if it omits to test the last item?
>    
>> Moreover, your algorithm does a double test on caption, which could be
>> avoided.
>>      
> I think that the second test can't to be avoided. If it isn't put out
> the loop, you have to put into the loop. The reason for include the
> test (TabStrip1[a].Text<>   IdCaption) in conditional expression is
> only stop the loop if there's match before get the last item.
>
> I think that this code can to write in many ways, but with no
> significant variations. How would you do?
>    
I would do so:

PRIVATE FUNCTION ScanTab(IdCaption AS String) AS Byte
DIM a AS Byte = 0

   WHILE a<  TabStrip1.Count
      if TabStrip1[a].Text = IdCaption then return a
     INC a
   WEND
   return -1
END

-or-

PRIVATE FUNCTION ScanTab(IdCaption AS String) AS Byte
DIM a AS Byte

   for a = 0 to TabStrip1.Count-1
      if TabStrip1[a].Text = IdCaption then return a
   next
   return -1
END


>> Doing an additional test is not an important thing if the test
>> is quick and the routine is called not too much often. What if the
>> routine is called millions time, or the test is more heavy?
>>      
> I think that the computational cost of evaluate complex logical
> expressions, generally is insignificant. But if not, then the first
> thing to be considerated is the language to use, and I see few
> alternatives: assembler, C, C++, someone else; the second thing is the
> many optimizations to do. But, what kind the system would be? One that
> is not possible to do with Gambas.
>    
No, the issue is different. Giving any language and any cpu, every 
operation has a cost. Comparing two times the same two strings is a cost 
which can be avoided. *If* the speed is not important, *and* the code is 
more clear, *then* one can even do it [compare two times the same data].
>    
>> About not using RETURN or BREAK inside cycles, we must think at
>> different kind of cycles. The WHILE and alike, where no variables are
>> directly involved in the cycle declaration, never have problems - the
>> semantic of the declaration does not imply anything about variable
>> allocation. In the FOR cycles instead, other languages can do strange
>> things, both on allocation and code optimization, so it is effectively a
>> bad idea to fiddle with the loop control variable; in other languages
>> this is not stressed the same way (basic, for example), but actually is,
>> at least, ugly.
>>      
> Yep, but I not was thinking in possible collateral effects, derived
> from implementation of language. (To those, the corresponding compiler
> would let in evidence, or would become a logical error isn't very
> difficult to detect and correct). I was thinking in conceptuals
> implications.
>
> This conceptuals implications derives in to use of the language
> resources in any ways, instead to use them in the correct situations.
>    
I am not sure to understand what you are saying. Anyway, I cited "other 
languages" just for completeness. Why should be ugly to modify the 
control variable of a loop? Perhaps because, historically, it was 
forbidden... so the teachers say the scholars it is ugly (or wrong), and 
the scholars, when turned teachers themselves, continue to say that it 
is ugly, and so on. 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...

>> It seems to me that you have said that an exception would be the FOR
>> EACH cycle... why?
>>      
> FOR EACH really iterates through all items, so there's only way to
> stop the loop when it's goal is achieved, is by the BREAK sentence
> used in a conditonal sentence inside the loop. But it might think that
> if it is necessary to do this, then the iterative structure FOR EACH
> is not adequate.
>    
Yes, I follow your mind. It's your style, mostly pure... I try to be 
more pure - but often I choose the quick way; so, break and continue are 
welcome for me.


This is the kind of things I like to speak of - other people on this 
list have a different point of view about this. I beg for mercy in a 
pre-emptive, anticipative way.

Regards,
Doriano





More information about the User mailing list