dlang.org icon indicating copy to clipboard operation
dlang.org copied to clipboard

Improve Operator Overloading docs

Open dlangBugzillaToGithub opened this issue 7 years ago • 7 comments

Manu reported this on 2018-06-16T20:37:30Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=18998

CC List

  • Cristian Creteanu
  • Seb
  • Nick Treleaven (@ntrel)

Description

The language Operator Overloading document has devolved into chaos!

Picture that you don't know D, and you want to learn about operator overloading, and now read that document.

Press Ctrl-F and type "opSlice", scroll the highlighted text, try and understand how to implement a slicing operator properly. Note that the first contact you see looks like this:
  `-a[i..j]    a.opIndexUnary!("-")(a.opSlice(i, j))`  wat?!

I think this document needs a complete overhaul, starting with a list of special operators that exist, description of each special operator and example of how they work in **the most simple case**, and show complex compounds and aggregate rewrites towards the end, only after the basic meaning of all operators has been established.

This is a critical language document, and it's not terribly helpful to new users.

dlangBugzillaToGithub avatar Jun 16 '18 20:06 dlangBugzillaToGithub

turkeyman commented on 2018-06-16T21:12:45Z

I also suggest, for each operator as it is introduced, demonstrate the 'canonical' signature; what is the 'most standard/correct' way to specify these functions in their most simple cases.

Imagine you were writing a D equivalent of std::vector, nothing could be simpler in terms of API spec.
Read the section "Array Indexing and Slicing Operators Overloading" from the perspective you were writing std::vector...

What indexing type to use? size_t?
What about argument ref-ness? ref? byval? auto ref?
Argument const-ness?
What should assignment operators return? `void`? A reference to `this` like C++?
How to correctly handle the operators that receive strings?
  constraint:     int opBinary(string op) if (op == "+") { ... }
  specialisation: int opBinary(string op : "+") { ... }
  static-if:      int opBinary(string op) { static if (op == "+") { ... } }
Each have subtly different semantics with respect to overload selection, error messages, etc. Default choices should be suggested.

This information being clearly provided will ensure that development of D container classes will follow the same set of guidelines.

It's worth noting, the document is almost obsessed with 2-d slicing/indexing/op-assignment concepts.
Make a point that multi-dimensional indexing is even supported, and that it is a separate topic, and requires different handling than 1d.
Users might not imagine that multi-dimensional indexing/slicing is possible on first contact.

I suggest establishing all indexing/slicing operators with respect to their typical 1-d cases, and then have a specific section at the end relating n-d (or 2-d in this case) indexing/slicing mechanics.

dlangBugzillaToGithub avatar Jun 16 '18 21:06 dlangBugzillaToGithub

turkeyman commented on 2018-06-16T21:14:12Z

Convenience link: https://dlang.org/spec/operatoroverloading.html

dlangBugzillaToGithub avatar Jun 16 '18 21:06 dlangBugzillaToGithub

nick (@ntrel) commented on 2022-12-10T17:44:18Z

> Press Ctrl-F and type "opSlice", scroll the highlighted text, try and understand how to implement a slicing operator properly. Note that the first contact you see looks like this:
  `-a[i..j]    a.opIndexUnary!("-")(a.opSlice(i, j))`  wat?!

Tweaked unary operator docs so there's now a brief explanation and link to slice overloading above the lowering table for opIndexUnary:

https://github.com/dlang/dlang.org/pull/3463

dlangBugzillaToGithub avatar Dec 10 '22 17:12 dlangBugzillaToGithub

nick (@ntrel) commented on 2022-12-11T13:55:01Z

This one adds examples for opCmp, opOpAssign, s.opIndex(s.opSlice(...)).
https://github.com/dlang/dlang.org/pull/3467

dlangBugzillaToGithub avatar Dec 11 '22 13:12 dlangBugzillaToGithub

nick (@ntrel) commented on 2022-12-11T16:30:37Z

> try and understand how to implement a slicing operator properly. Note that the first contact you see looks like this:
>   `-a[i..j]    a.opIndexUnary!("-")(a.opSlice(i, j))`  wat?!

I think the docs for opIndexUnary, opIndexAssign and opIndexOpAssign should be moved to the Indexing and Slicing Operators section where they make more sense.

> Make a point that multi-dimensional indexing is even supported, and that it is a separate topic, 

With the 2nd pull I have tweaked the slicing docs to introduce 1D slicing first with an example, then move on to multidimensional.

> and requires different handling than 1d.

Well non-template opSlice(i, j) 'is discouraged', so they're not different really.

dlangBugzillaToGithub avatar Dec 11 '22 16:12 dlangBugzillaToGithub

dlang-bot commented on 2023-07-03T18:36:14Z

@ntrel updated dlang/dlang.org pull request #3652 "[spec] Improve opCast & `opCast!bool` docs" mentioning this issue:

- Part of
  Issue 18998 - Improve Operator Overloading docs

https://github.com/dlang/dlang.org/pull/3652

dlangBugzillaToGithub avatar Jul 03 '23 18:07 dlangBugzillaToGithub

dlang-bot commented on 2023-07-10T11:07:51Z

dlang/dlang.org pull request #3652 "[spec] Improve opCast & `opCast!bool` docs" was merged into master:

- a6cfd0db7b7f74ec27c2d908d017d82e5355023b by Nick Treleaven:
  Part of
  Issue 18998 - Improve Operator Overloading docs

https://github.com/dlang/dlang.org/pull/3652

dlangBugzillaToGithub avatar Jul 10 '23 11:07 dlangBugzillaToGithub