Hello,

Marco van de Voort schrieb:
you could write:

x : TSomeElement;
someCollection : TSomeCollection;

[...]
foreach elem in someCollection do begin
        << do something with elem >>
end;
[...]

True, BUT... hmm, I actually have 3 BUTS

It is some sort of syntactic sugar, so all your but's are valid at least in some way. Nobody ever doubted this.


BUT 1: some form shorter syntax can be thought up for _each_ _and_
[...]

BUT 2: The whole purpose of iterators is that you can have multiple orders
on the same object, and get a different iterator to get a different order.

I disagree, the main purpose of iterators is to provide uniform iteration over containers (e.g. to use the same code to iterate over different collections).
That there are different types of iterators (forward, backward, and random access, readonly, writeable, ...) is definitely a feature of a specific iterator imo.


If you have to program differently for every container (for i := low(x) to ..; for i := 0 to count-1 ...; etc. etc.) only makes code harder to understand and error prone without additional gain.

Additionally if you examine code, _far_ the most applications do simple forward (and maybe backward) iteration over a collection (also because there are not that much collections where random access makes sense runtime-wise).

So maybe it is feasible to enhance the syntax to the following (BNF this time):

foreachstatement ::=
  "foreach" element "in" container ["forwards" | "backwards"] "do"
  statement.

or:

foreachstatement ::=
  "foreach" element "in" typed-range-expression "do"
  statement.

typed-range-expression ::=
  container "'" range-expression.

range-expression ::= first-element-spec ".." last-element-spec.

and first-element and last-element being a specification of those. This can be for arrays: bottom and last element (greetings from e.g. VHDL/ADA?, see for more details there), for OO containers a specification of two iterators indicating position, see STL.
But this may be total overkill for the typical application.


*ducks into cover, awaiting flames* =)

The syntax does not allow this. Typical ss.

You are right, it _is_ syntactic sugar. Never doubted it. But iterators may be an important tool in programming which may justify inclusion into the language.


BUT 3: I myself currently use iterators at work (modeled after decal,
except without the variant-interface stuff, because of performance) and
your example looks overly verbose;

var iter:dlightmapiterator;

iter:=lightmapstartiter(collection);
while lightmapiterateover(iter) do
<< do something with getobject(iter)>>
// no finalisation of iter necessary.
Is this so bad ? I don't see the problem

I'm not sure that I'm interpreting your code sequence correctly, but I don't consider this design as very good either (maybe driven by implementation considerations though) - you lost abstraction over the container type which forces the programmer to learn the correct commands for every type of container (which isn't too hard assuming that they are pretty similar - but there is no real *gain* for doing that. And you don't lose anything when you do it the other way)


The finalization is a pure design issue, depending on the capabilities of the container (thread safety, safe for container modification, ...) which may be needed to properly release used resources. This is an option.

Additionally you lost type safety (e.g. missing the typecast of the retrieved object =).

Taking all that into account there isn't much difference in typing between the two proposals, isn't there?

which is imo far easier to read. (Please don't mind the word "foreach", I think it's only because it's already used in other languages for that purposes).

IMHO it sucks. Write a code template for your IDE if you really want to spare out those 10 key strokes.

:-)

Regards,
  Thomas



_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to