Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2009-11

Forin Test

8 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

darekm

I've play with forin construction. To my work I need more than one per collection.
In attach is one of example program.
Can someone review it. is this proper construction.

Darek
Paul Ishenin
to darekm
darekm wrote
I've play with forin construction. To my work I need more than one per collection. In attach is one of example program. Can someone review it. is this proper construction.
operator enumerator (AEnumerator: TEnumerator): TEnumerator;
begin
  Result := AEnumerator
end;

It is a bit hackish but I see problems with it.

  for i in List.up do
    WriteLn(i);

will be possible to transform into

  for i in List using Up do
    WriteLn(i);

or

for i in List using GetEnumerator(DoUpArgument)

current "for i in List" will be just short form of "for i in List using GetEnumerator"

Best regards,
Paul Ishenin.

Dariusz Mazur
to Paul Ishenin

Paul Ishenin pisze:

Show quoted text 11 lines
darekm wrote: > I've play with forin construction. To my work I need more than one > per collection. > In attach is one of example program. > Can someone review it. is this proper construction. operator enumerator (AEnumerator: TEnumerator): TEnumerator; begin Result := AEnumerator end; It is a bit hackish but I see problems with it.

Where?
Its work now with current compilator. Are You plan to disable this?

Show quoted text 15 lines
for i in List.up do WriteLn(i); will be possible to transform into for i in List using Up do WriteLn(i); or for i in List using GetEnumerator(DoUpArgument) current "for i in List" will be just short form of "for i in List using GetEnumerator"

But this complicate both: source and compilator.
And second: You cant pass enumerator as param.

procedure MyProc(aEnum: tObject);
var
   i : integer;
begin
  for i in aEnum do
   writeln(i);
end;
MyProc(List.up);
MyProc(List)
Darek
Paul Ishenin
to Dariusz Mazur
Dariusz Mazur wrote
Where? Its work now with current compilator. Are You plan to disable this?

I made a typo: read 'I see *no* problems with this'.

Show quoted text 5 lines
> for i in List using GetEnumerator(DoUpArgument) > > current "for i in List" will be just short form of "for i in List > using GetEnumerator" But this complicate both: source and compilator.

Why compilcate? I thought vice versa it will simplify the user source code.

And second: You cant pass enumerator as param.

Maybe you understood me wrong? I proposed the 'using' keyword as an extension to the current implementation. It would not be required. If not used then it will work as now but if used then compiler will search for the given identifier and use it instead of operator/GetEnumerator method.

Best regards,
Paul Ishenin.

Dariusz Mazur
to Paul Ishenin

Paul Ishenin pisze:

Show quoted text 11 lines
Dariusz Mazur wrote: > Where? > Its work now with current compilator. Are You plan to disable this? I made a typo: read 'I see *no* problems with this'. >> for i in List using GetEnumerator(DoUpArgument) >> >> current "for i in List" will be just short form of "for i in List >> using GetEnumerator" > But this complicate both: source and compilator. Why compilcate? I thought vice versa it will simplify the user source code.

Can You give example of this:
where
for i in List using GetEnumerator
is better than
for i in List.GetEnumerator

Show quoted text 6 lines
> And second: You cant pass enumerator as param. Maybe you understood me wrong? I proposed the 'using' keyword as an extension to the current implementation. It would not be required. If not used then it will work as now but if used then compiler will search for the given identifier and use it instead of operator/GetEnumerator method.

this is third method,
Should be good point to implement this (pascal always has very simple semantic and very strong type checking)
Of course you then you can use any enumerator with any collection, but it will be better?
How many errors we then invoke?

Darek
Paul Ishenin
to Dariusz Mazur
Dariusz Mazur wrote 5 lines
Can You give example of this: where for i in List using GetEnumerator is better than for i in List.GetEnumerator

Of course. for-in loop expect to have a collection not an enumerator. What enumerator should for-in loop to choose in the next case:

[example]
TMyListEnumerator = class
public
  function GetEnumerator: TMyListEnumeratorEnumerator;
  function MoveNext: Boolean;
  property Current: something;
end;
TMyList = class
public
  function GetEnumerator: TMyListEnumerator;
  function GetAnotherEnumerator: TMyListAnotherEnumerator;
end;
var
  List: TMyList;
begin
  for i in List.GetEnumerator do
end;
[/example]

Loop will choose TMyListEnumeratorEnumerator, but is it desired?

'using' keyword solves this ambiguity very easy:

for CollectionElement in Collection using CollectionEnumerator do
Show quoted text 12 lines
>> And second: You cant pass enumerator as param. > Maybe you understood me wrong? I proposed the 'using' keyword as an > extension to the current implementation. It would not be required. If > not used then it will work as now but if used then compiler will > search for the given identifier and use it instead of > operator/GetEnumerator method. this is third method, Should be good point to implement this (pascal always has very simple semantic and very strong type checking) Of course you then you can use any enumerator with any collection, but it will be better? How many errors we then invoke?

Much less.

Best regards,
Paul Ishenin.

Dariusz Mazur
to Paul Ishenin

Paul Ishenin pisze:

Show quoted text 29 lines
Of course. for-in loop expect to have a collection not an enumerator. What enumerator should for-in loop to choose in the next case: [example] TMyListEnumerator = class public function GetEnumerator: TMyListEnumeratorEnumerator; function MoveNext: Boolean; property Current: something; end; TMyList = class public function GetEnumerator: TMyListEnumerator; function GetAnotherEnumerator: TMyListAnotherEnumerator; end; var List: TMyList; begin for i in List.GetEnumerator do end; [/example] Loop will choose TMyListEnumeratorEnumerator, but is it desired? 'using' keyword solves this ambiguity very easy: for CollectionElement in Collection using CollectionEnumerator do
with hack with trivial operator we receive the same:
  for CollectionElement in Collection.CollectionEnumerator do

but what about

  for CollectionElement in Collection using TreeEnumerator do

where TreeEnumerator cant traverse thought Collection

Show quoted text 14 lines
>>> And second: You cant pass enumerator as param. >> Maybe you understood me wrong? I proposed the 'using' keyword as an >> extension to the current implementation. It would not be required. >> If not used then it will work as now but if used then compiler will >> search for the given identifier and use it instead of >> operator/GetEnumerator method. > this is third method, > Should be good point to implement this (pascal always has very simple > semantic and very strong type checking) > Of course you then you can use any enumerator with any collection, > but it will be better? > How many errors we then invoke? Much less.

I can't resist.
But I have another proposition. Because we add so many variants to forin construction, can be added once more.
[example]
for list do ....
[/example]

where we omit in keywords and iteration variable
That will be nice solution for some expression or in some transactional patterns like:
[example]
initfun;
while stopfun do begin
end;

try
  lock;
 ...
finally
 unlock;
end;
[example]
I think its not break any current behavior. Of course I can do the same
today, but I need variable, which would not be used.
In below example we can omit declaration of i variable;
[example]
var
  i : integer;
begin
  for i in lock do begin
    procedureNotUseI;
  end;
end;
[/example]
Darek
Paul Ishenin
to Dariusz Mazur
Dariusz Mazur wrote
with hack with trivial operator we receive the same: for CollectionElement in Collection.CollectionEnumerator do

yes, but it is still the hack

but what about for CollectionElement in Collection using TreeEnumerator do where TreeEnumerator cant traverse thought Collection

Well, TreeEnumerator must be a method of Collection instance to do this of course. If it exists then it is used.

Show quoted text 7 lines
But I have another proposition. Because we add so many variants to forin construction, can be added once more. [example] for list do .... [/example] where we omit in keywords and iteration variable

If we ommit the 'in' keywork then it is not a 'for-in' loop, so I am not responsible :)

Best regards,
Paul Ishenin.