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
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel