[Lazarus] Easiest way to "case" strings

Alexander Klenin klenin at gmail.com
Thu Mar 26 11:29:42 CET 2009


On Thu, Mar 26, 2009 at 18:59, Marco van de Voort <marcov at stack.nl> wrote:
> On Thu, Mar 26, 2009 at 10:28:50AM +1000, Alexander Klenin wrote:
>> > What problem does "for in" really solve?
>>
>> Lack of iterators.
>
> No it doesn't IMHO.
This is really nice argument ;-) Well, it _should_ solve it.
If it does not, it must be extended of implemented differently.
I definitely do not argue in favor of blindly copying Delphi features.

> And I assume that by "lack of iterators" you mean in-language iterators?
Of course. What else?

> One can give this "handy" moniker to every randomly thought up with an
> example that shortens some random code fragment. IMHO it is meaningless.
As I said, I agree that the case for 'strict' visibility is rather weak.
However, it still has practical uses. For a recent example: Lazarus contains
some extremely overbloated source files, some more than 10000 lines long,
with dozens of classes.
The task of refactoring them into a reasonable set of units is daunting.
It would be made easier if I were able to first isolate classes inside the unit
with 'strict' visibility specifiers to make sure nothing breaks
when I move those classes away.

> I'm also not entirely happy with the way dynamic arrays are set up. They
> seem to be made mostly for COM use, the mandatory 0-basedness is unpascal
> like etc.
0-basedness, althout indeed "unpascal" is just a nuisance.
The real problem of dynamic arrays is O(n^2) growing time.
Is they, like TList, contained separate 'Length" and 'Capacity'
fields, they would be
much more useful -- to the point that TList could be totally superseded.

> I can live with such an argumentation. However, if I take the case of string
> as example, I see only very rare occasions, and I wouldn't even use case of
> string because it is so limited. If suddenly the cases wouldn't be
> compiletime anymore (because they become user configurable or localised
> values) you have to morph the entire block.
If they are not constants, the user should use 'if', this is obvious.
And of course cases should not be localised.
I am talking about such use cases as tokenizers and protocol handlers.

>> > What is the real use of duplicating const type and var as nested variants
>> > inside classes?
>>
>> Namespace management.
>
> They copied it from languages that have class as the only namespace. However
> the unit based Pascal concept already has units and the unit namespace to
> identify between similarly global symbols.

When the codebase becomes big enough, more than one level of hierarchy
becomes useful.

>> Like for ... in?
>
> I never used in under Delphi except to iterate over sets.

Well, you have missed some opportunities to enhance your code then ;-)
Consider following use cases:
1) Iterating over array property, where and item should be stored in a
temporary variable
  to avoid rereated calls to GetItem method inside the loop iteration:
var
  i: integer; item: TItem;
...
for i := 0 to obj.ItemCount do begin
  item := Items[i];
  ... item ... item ...
end;

versus

var
  item: TItem;
...
for item in obj.Items do begin
  ... item ... item ...
end;

the latter is safer, simpler and more clear code.

2) Iterating over characters in string -- at first, it seems no
different from any other array,
but consider UTF-8 strings. Using s[i] notation in a loop will lead to
O(n^2) time,
while 'for ... in' can generate linear-time code.

3) Iterating over hash, tree, dataset, or really anything more complex
than an array --
there is currently no language support for that, which leads to many
awkward, buggy and incompatible implementations.

[regarding 'case of string']
> Yes. But since this is not a simple type, but a complex type, it goes to a
> different class. If that is your argument, make sure it works for arrays, records,
> classes, interfaces and the other complex types too.
I definitely agree that 'case' should work for classes --
perhaps even more important than for strings. For records and static arrays
it could be implemented, but the value of such feature would be truly marginal.
For the other types, including class objects and dynamic arrays, 'case'
is useless since equality semantics for them involves reference comparison,
and the references will never be the same.

> I don't see string as a scalar type. It is an array or complex type IMHO.
It should be an 'array of char' then.
I agree that the latter would be a better design decision, but it is
too late to change.

-- 
Alexander S. Klenin



More information about the Lazarus mailing list