foreach iterator with closure

Denis noreply at noserver.lan
Sun Jun 28 16:07:35 UTC 2020


Many thanks: your post has helped me get past the initial 
stumbling blocks I was struggling with. I do have a followup 
question.

First, here are my conclusions up to this point, based on your 
post above, some additional experimentation, and further research 
(for future reference, and for any other readers).

* foreach is the actual iterator, the instantiation of a struct 
is the range.
* When a constructor is not used, the arguments in the call to 
instantiate the range (in this case, `hello` in letters(`hello`)) 
are mapped sequentially to the member variables in the struct 
definition (i.e. to letters.str).
* When a constructor is used, the member variables in the struct 
definition are in essence private. The arguments in the call to 
instantiate the range are now mapped directly to the parameters 
in the definition of the "this" function.
* The syntax and conventions for constructors is difficult and 
non-intuitive for anyone who hasn't learned Java (or a 
derivative). The linked document provides a simplified 
explanation for the "this" keyword, which is helpful for the 
first read: 
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html.
* In some respects, the Java syntax is not very D-like. (For 
example, it breaks the well-established convention of "Do not use 
the same name to mean two different things".) However, it does 
need to be learned, because it is common in D source code.

Here is the complete revised code for the example (in condensed 
form):

   import std.stdio;

   struct letters {

     string str;
     int pos = 1;		// Assign here or in this())

     this(string param1) {	// cf. shadow str
       str = param1;		// cf. this.str = param1 / this.str = str
       writeln(`BEGIN`); }

     char front() { return str[pos]; }
     void popFront() { pos ++; }
     bool empty() { return pos == str.length; }

     ~this() { writeln("\nEND"); }}

   void main() {
     foreach (letter; letters(`hello`)) {
       write(letter, ' '); }}

At this point, I do have one followup question:

Why is the shadow str + "this.str = str" the more widely used 
syntax in D, when the syntax in the code above is unambiguous?

One possible reason that occurred to me is that "str = param1" 
might require additional GC, because they are different names. 
But I wouldn't think it'd make any difference to the compiler.

Denis


More information about the Digitalmars-d-learn mailing list