[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