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

Reply via email to