News for hackers. Stuff that matters.
Re:Implementing UFCS for C++ in Clang by simias on Monday August 03, 2020 @02:54PM (#24041819)
I wish the article included some real-world practical example of when that would be useful because as it stands I'm very confused. Why not just make your Extension an other class that would be inherited? Or more simply, why not make it a member method to begin with?
Re:Implementing UFCS for C++ in Clang by SolarNet on Monday August 03, 2020 @04:41PM (#24043130)
> Or more simply, why not make it a member method to begin with?

You may not be the author/maintainer of that class.

> Why not just make your Extension an other class that would be inherited?

Because now I have a down casting issue (especially when talking about non-heap "objects"). Which means implementing and forwarding dozens of methods, and/or sloppy bug-prone (when some other developer puts variables on the class without noticing) implicit casts.

> I wish the article included some real-world practical example of when that would be useful

The classic one is interface helpers. Methods which smooth out the usage of an interface but are not relevant to the implementation of it. Yes one can put those methods on the interface's definition. But this allows separating where the interface is declared (some header some where) and where the code for it is defined (some code file), potentially across libraries (e.g. a header only "library" of interfaces, and a utility library of methods for making it nice to use). Notably this also avoids some frustrating header shenanigans and allows writing interface helpers against concrete types to come up with a more natural library organization.

The next one is it much easier to write "literate programming" style code in C++ (which is nice because they often make types "disappear" in their usage, and many argue provide more readable code as a consequence). A problem many developers currently solve with operator overload (see `<<` for the C++ standard printing library). This also makes it way way easier for such literate programming to be extensible (believe me I wrote the templates for extensible literate programming once, it's insanely painful).

Also, depending on how these implement templates, they might be a much more appreciated method of adding optional class methods to templates by making the method a compile error to call in the first place ("missing method") rather than a substitution failure error ("<massive call stack>").

Re:Implementing UFCS for C++ in Clang by dataflow on Monday August 03, 2020 @03:00PM (#24041894)
You might not be the author of that class to be able to add a method to it.
Re:Implementing UFCS for C++ in Clang by mhh__ on Monday August 03, 2020 @03:11PM (#24042036)
Re:Implementing UFCS for C++ in Clang by 1ris on Monday August 03, 2020 @03:04PM (#24041949)
Too much inheritance is widely considered bad OOP. Cross component inheritance is considered a non-non for some. (e.g. inheriting from QValueList<T>). Most OOP languages offer a "sealed" of some kind to prevent inheritance because of this.

Also these functions do not have access to private or protected fields.

It's a way to argument a existing API for your use case without too thight coupling, whatever that means.

Re:Implementing UFCS for C++ in Clang by mehrdadn on Monday August 03, 2020 @04:05PM (#24042689)
This isn't really true in every language. Not every use of inheritance is a case of OOP. Inheritance is a mechanism used for multiple purposes (especially in C++) and OOP is merely one of them. It's also just a way to do mixins, and it's frequently used for that in C++.
Re:Implementing UFCS for C++ in Clang by crazypython on Monday August 03, 2020 @07:38PM (#24044789)
Joining an iterable of strings into a single string. Python does:

  seperator.join(iterable)
  "".join(["foo", "bar", "hello"]) # => "foobarhello"
  ", ".join(["Hacker News", "Twitter"]) # => "Hacker News, Twitter
Many people have complained about this strange syntax:

https://mail.python.org/archives/list/[email protected]... https://mail.python.org/archives/list/[email protected]... https://mail.python.org/archives/list/[email protected]... https://mail.python.org/archives/list/[email protected]...

`["a", "b", "c"].join(iterable)` was rejected because it forces every iterable to implement iterable functions.

Additionally some iterables, like generators, are mutated when you iterate over them:

  ", ".join(streaming_api.fetch_names())
UFCS let's you write join as a free function and still use "".join(iterable)

NaN guarding:

  import std.traits;
  auto unwrap(T)(T input) if (isFloatingPoint!T) {
      // Asserts cost nothing when turned off with -check=assert=off
      // The compiler can fully inline this function, so it isn't expensive
      assert(input !== input.nan);
      return input;
  }
Use like this:

  if (objSize.unwrap < cellSize) {
     // Allocate a new cell for the object
  } else {
     // Insert into current cell
  }
The parentheses are omitted because Dlang has https://dlang.org/spec/function.html#optional-parenthesis. The above compiles into this:

  if (objSize.unwrap() < cellSize) {
     // Allocate a new cell for the object
  } else {
     // Insert into current cell
  }