foreach iterator with closure
Ali Çehreli
acehreli at yahoo.com
Sun Jun 28 18:47:41 UTC 2020
On 6/28/20 9:07 AM, Denis wrote:
> * foreach is the actual iterator,
Yes. foreach is "lowered" to the following equivalent:
for ( ; !range.empty; range.popFront()) {
// Use range.front here
}
A struct can support foreach iteration through its opCall() member
function as well. opCall() takes the body of the foreach as a delegate.
Because it's a function call, it can take full advantage of the function
call stack. This may help with e.g. writing recursive iteration algorithms.
http://ddili.org/ders/d.en/foreach_opapply.html#ix_foreach_opapply.opApply
> the instantiation of a struct is the
> range.
Yes.
> * 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).
Yes, that is a very practical struct feature. I write my structs with as
little as needed and provide a constructor only when it is necessary as
in your case.
> * When a constructor is used, the member variables in the struct
> definition are in essence private.
Not entirely true. You can still make them public if you want.
http://ddili.org/ders/d.en/encapsulation.html
> The arguments in the call to
> instantiate the range are now mapped directly to the parameters in the
> definition of the "this" function.
Yes.
> * The syntax and conventions for constructors is difficult and
> non-intuitive for anyone who hasn't learned Java (or a derivative).
C++ uses the name of the class as the constructor:
// C++ code
struct S {
S(); // <-- Constructor
S(int); // <-- Another one
};
The problem with that syntax is having to rename more than one thing
when the name of struct changes e.g. to Q:
struct Q {
Q();
Q(int);
};
And usually in the implementation:
Q::Q() {}
Q::Q(int) {}
D's choice of 'this' is productive.
> 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.
I like searching for keywords in my index. The "this, constructor" here
links to the constructor syntax:
http://ddili.org/ders/d.en/ix.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".)
Yes but it competes with another goal: Change as little code as possible
when one thing needs to be changed. This is not only practical but helps
with correctness.
> However, it does need to be learned,
> because it is common in D source code.
I like D. :p
> 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?
Because one needs to come up with names like "param7", "str_", "_str",
"s", etc. I like and follow D's standard here.
> One possible reason that occurred to me is that "str = param1" might
> require additional GC, because they are different names.
Not at all because there is not memory allocation at all. strings are
implemented as the equivalent of the following struct:
struct __D_native_string {
size_t length_;
char * ptr;
// ...
}
So, the "str = param1" assignment is nothing but two 64 bit data
transfer, which can easily by optimized away by the compiler in many cases.
> But I wouldn't
> think it'd make any difference to the compiler.
Yes. :)
>
> Denis
Ali
More information about the Digitalmars-d-learn
mailing list