On 01.11.2015 16:38, Jonas Maebe wrote:
The basic issue is that you need extra context for supporting this extension. Normally, an enumerator is searched based on the class type. In your case, it's searched either based on the class type, or if the class is returned from a property with an "enumerator" specifier, based on that enumerator declaration.

Whether you do it via a temporary node, a global variable and/or node flags, does not change that. Extra context is always bad both for the compiler implementation/maintenance and for code readability/predictability by humans.

Yes, the context is new. Yes, every new feature adds maintenance efforts. But this is not an argument... Speaking from my point of view, I do expect to be able to enumerate over array properties just as I enumerate over array variables. It feels very natural.

I don't understand the design decisions you talk about below:

This leads to more design design decisions:
1) do you a) forbid an enumerator specification if the class already has an enumerator, b) hide the existing enumerator, or c) allow enumerating both via the property and the original class enumerator? If you all both, how do you differentiate? If b), first assigning the property to a variable and iterating over that will have a different result than directly iterating over the property, which is bad for understandability and code predictability. If c), how do you specify it. If a), that break orthogonality (and I'm sure some people will argue that iterating over a particular property may have to be done differently than over that class' contents in the general case)

The extension is completely orthogonal - there is no redundancy in the code. Again if I take the project1.lpr from the issue report:

*  for s in StringArray do**
**    Writeln(s);**
*
will never compile without the extension. The StringArray property cannot introduce/return an enumerator. In absolutely no case.

2) do you expose the "hidden/parent" enumerator of the class itself to the overriding enumerator in a property and if so, how? Maybe even iterating both at the same time via some kind of inheritance mechanism?

If you are talking about something like this:

  TTest = class
  //...
  public
    function *GetEnumerator*: TTestObjectEnumerator;
property StringArray[Index: Integer]: string read GetString enumerator *GetEnumerator*;
  end;

then this is again absolutely no problem. The code:

*  for s in Self do**
**    Writeln(s);**
*
and

*  for s in Self.StringArray do**
**    Writeln(s);**
*
will do the same thing. Again, this is very natural.

There are undoubtedly more.

I don't think so. Please be specific. "undoubtedly more" doesn't sound very scientific :)

Ondrej

_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to