www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - When to opCall instead of opIndex and opSlice?

reply =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
Is implementing opCall(size_t) for structures such as array 
containers that already define opIndex and opSlice deprecated?

I can't find any documentation on the subject on when opCall 
should be defined to enable foreach (isIterable).
Oct 02 2017
parent reply Jacob Carlborg <doob me.com> writes:
On 2017-10-02 17:57, Nordlöw wrote:
 Is implementing opCall(size_t) for structures such as array containers 
 that already define opIndex and opSlice deprecated?
 
 I can't find any documentation on the subject on when opCall should be 
 defined to enable foreach (isIterable).
opCall is not related to foreach. It's used to overload the call operator, i.e. (). struct Foo { void opCall() {}; } Foo foo; foo(); Are you thinking of opApply [1]? [1] https://dlang.org/spec/statement.html#foreach_over_struct_and_classes -- /Jacob Carlborg
Oct 02 2017
parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Monday, 2 October 2017 at 18:14:24 UTC, Jacob Carlborg wrote:
 On 2017-10-02 17:57, Nordlöw wrote:
 Is implementing opCall(size_t) for structures such as array 
 containers that already define opIndex and opSlice deprecated?
 
 I can't find any documentation on the subject on when opCall 
 should be defined to enable foreach (isIterable).
opCall is not related to foreach. It's used to overload the call operator, i.e. (). struct Foo { void opCall() {}; } Foo foo; foo(); Are you thinking of opApply [1]? [1] https://dlang.org/spec/statement.html#foreach_over_struct_and_classes
Ahh, yes of course. It seems like defining opIndex anf opSlice is enough in the array container case. Why do we have opApply as well? Non-random access?
Oct 02 2017
next sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, October 02, 2017 18:31:23 Per Nordlöw via Digitalmars-d-learn 
wrote:
 On Monday, 2 October 2017 at 18:14:24 UTC, Jacob Carlborg wrote:
 On 2017-10-02 17:57, Nordlöw wrote:
 Is implementing opCall(size_t) for structures such as array
 containers that already define opIndex and opSlice deprecated?

 I can't find any documentation on the subject on when opCall
 should be defined to enable foreach (isIterable).
opCall is not related to foreach. It's used to overload the call operator, i.e. (). struct Foo { void opCall() {}; } Foo foo; foo(); Are you thinking of opApply [1]? [1] https://dlang.org/spec/statement.html#foreach_over_struct_and_classes
Ahh, yes of course. It seems like defining opIndex anf opSlice is enough in the array container case. Why do we have opApply as well? Non-random access?
opApply was the original way to implement the ability to use foreach with user defined types. Later, when ranges were added to the language, foreach was made to try slicing the type, and if that resulted in a range, then that was used with foreach. So, opSlice made it possible to use foreach (but only if the result was a range), and later opIndex was altered to also do what opSlice does. opApply is kept around in part to avoid breaking any code and in part because there are cases where implementing foreach that way rather than with a range is more efficient. IMHO, it also makes more sense in cases where you're dealing with a transitive front - e.g. if std.stdio's byLine were implemented via opApply and you _had_ to use byLineCopy when you wanted a range, then we'd have avoided a lot of problems with byLine - though at least we do now have byLineCopy instead of just byLine, even if byLine still returns a range. Random access has nothing to do with foreach in any of those cases, because random access isn't ever used with foreach and user-defined types. The closest you get is when you use index with foreach, and that works with arrays (but not ranges) and with opApply. So, it's probably using random access on arrays when iterating over them, but it doesn't with ranges in general, and it doesn't with opApply unless the underlying implementation happens to use random access inside of opApply; opApply itself isn't designed to use random access any more than front and popFront are. - Jonathan M Davis
Oct 02 2017
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/2/17 2:31 PM, Per Nordlöw wrote:
 On Monday, 2 October 2017 at 18:14:24 UTC, Jacob Carlborg wrote:
 On 2017-10-02 17:57, Nordlöw wrote:
 Is implementing opCall(size_t) for structures such as array 
 containers that already define opIndex and opSlice deprecated?

 I can't find any documentation on the subject on when opCall should 
 be defined to enable foreach (isIterable).
opCall is not related to foreach. It's used to overload the call operator, i.e. (). struct Foo {     void opCall() {}; } Foo foo; foo(); Are you thinking of opApply [1]? [1] https://dlang.org/spec/statement.html#foreach_over_struct_and_classes
Ahh, yes of course. It seems like defining opIndex anf opSlice is enough in the array container case. Why do we have opApply as well? Non-random access?
First, it should be front, popFront, and empty, not opIndex and opSlice. Second, opApply has existed forever (even in D1). Ranges are more recent. Third, opApply has some characteristics that are difficult to implement via ranges. -Steve
Oct 02 2017