UFCS is a key feature of D and enables code reusability and scalability through well-defined encapsulation.
UFCS allows any call to a free function
fun(a)
to be written as a member function call a.fun()
.
If a.fun()
is seen by the compiler and the type doesn't
have a member function called fun()
, it tries to find a
global function whose first parameter matches that of a
.
This feature is especially useful when chaining complex function calls. Instead of writing
foo(bar(a))
It is possible to write
a.bar().foo()
Moreover in D it is not necessary to use parentheses for functions without arguments, which means that any function can be used like a property:
import std.uni : toLower;
"D rocks".toLower; // "d rocks"
UFCS is especially important when dealing with ranges where several algorithms can be combined to perform complex operations, making it easier to write clear and manageable code.
import std.algorithm : group;
import std.range : chain, retro, front, dropOne;
[1, 2].chain([3, 4]).retro; // 4, 3, 2, 1
[1, 1, 2, 2, 2].group.dropOne.front; // tuple(2, 3u)
std.range