[fpc-devel] for-in-index loop
Sven Barth
pascaldragon at googlemail.com
Sat Jan 26 13:22:02 CET 2013
Rereading your mail now with what I wrote about tuples in mind:
On 25.01.2013 22:44, Alexander Klenin wrote:
> 2) Indeed, introducing tuples to Pascal might be an alternative
> solution. Below is a proposal:
> 2.1) Tuple definition. Tuple is an anonymous list of values, possibly
> of different types. It is impossible to explicitly declare tuple type,
> or store a tuple in a variable.
As Michael said Pascal is a declarative language (though this has been
forgotten some times) so I'd allow the declaration of tuple types using
something like "tuple of (type1, type2, etc.)"
> 2.2) Tuple construction: Tuple may be constructed by listing its
> elements in as a semicolon-separated list in parenthesis:
> (a; b; c). Also, any value of record or array type can be converted
> to a tuple by using built-in pseudo-function Tuple
> (or other some name, perhaps even a special character like ~ or @@).
> Semicolon is chosen to underline similarity with the record
> constants -- but perhaps comma is better.
> Alternatively, a square brackets may be used since they already
> represent similar semantics for "array of const" parameters.
As I said in my other mail I'm still not sure whether "(...)" is a good
idea, because there can be code like "i := (42)" (it's not forbidden and
thus it needs to be allowed with such an extension as well).
Nevertheless I'd prefer "," as a seperator.
Also I'd definitely prefer NOT to use special characters. Instead I'd
prefer the use of an instrinsic like "Tuple" (though - together with my
declaration proposal - one needs to pay special attention to the
difference of "Tuple(...)" and "tuple of (...)" in the parser)
> 2.3) Tuple assignment. Tuple may be assigned to a record, provided
> field types match. Most important, tuples may be used in
> deconstructing assignment by listing variables in the same syntax on
> the left side of assignment:
> (a; b) := (x; y);
> If the left side contains less variables then the tuple has values,
> extra values are ignored.
> If the right side contains more variables, it is an error.
I don't know whether we should use this "value ignoring". Maybe always
an error if the count differs is better... (and in the case of a Tuple
returned by the Tuple intrinsic we'd also need a new RunError and
Exception type)
> 2.4) Tuples as procedure arguments. Tuple may be passed to a procedure
> or function.
> In this case, deconstructing assignment is performed from the tuple to
> the actual arguments,
> as if they were listed on the left side of assignment in the previous point.
> Also, a tuple may be present inside square brackets representing
> "array of const" argument.
> In this case, it works as if tuple elements were listed instead.
>
Together with my "declaration" proposal this is a bad idea. So no
deconstructive assignments on procedure calls. Things like this can be
allowed though:
=== code begin ===
type
TTestTuple = (Integer, String);
procedure Test(aArg1: String; aArg2: TTestTuple; aArg3: Integer);
// somewhere else
Test('Foobar', (42, s), i);
=== code end ===
> 2.5) for-in loop accepts a list of variables after "for" keyword. In
> this case, it tries to convert the Current value to a tuple and
> perform tuple assignment.
It should not only be a list of variables, but a "tuple deconstructor":
=== code begin ===
for (key, data) in SomeContainer do
...
=== code end ===
The enumerator then of course needs to return a fitting tuple type.
This way one can keep the current enumerators (maybe except build in
ones): they just don't return a tuple type, but a "scalar" and thus
you'd continue to write
=== code begin ===
for data in SomeContainer do
...
=== code end ===
>
> With this proposal, following benefits are gained:
>
> 1) Group assignment:
> (x; y; z) := (0; 0; 0);
> (a; b) := (b; a);
> (first; second) := Tuple(SomeFunctionReturningArray());
>
Agreed.
> 2) Record literals without constructor functions:
> ARectangle.TopLeft := (100; 200);
>
I don't know whether this should be possible without an approbiate
intrinsic (the inverse of "Tuple"), but I'm open here...
> 3) Formatting complex values:
> s := Format('%d-%d', [Tuple(CenterPoint(ARectangle))]);
Format would need to be adjusted to support Tuple types, but ok...
>
> 4) Collecting default values for procedures:
> In some library:
> procedure WithManyParams(A, B, C, D, E, F: Integer);
> In user code:
> var
> p: record A, B, C, D, E, F: Integer; end;
>
> p := (default; values; for; params);
> ...
> p.E := 5;
> WithManyParams(Tuple(p));
As said above this is a no in my opinion.
>
> 5) Finally, for-in:
> for (v; i) in a do ...
> Compiler code for built-in types mostly the same as for-in-index --
> syntax difference only.
> User-defined iterators may return records with fields (value, key).
> In the case of
> for v in a
> v may now be either a record or just a value, depending on the type.
Basically agreed.
Regards,
Sven
More information about the fpc-devel
mailing list