Extend types with free functions as methods

Paul Backus snarwin at gmail.com
Mon Dec 20 02:10:39 UTC 2021


On Sunday, 19 December 2021 at 21:53:09 UTC, Quirin Schroll wrote:
> Someone asked about that and I cannot find the thread anymore. 
> The goal was to write something so that one can pass an object 
> of some type to a function that expects it to have certain 
> methods. Sometimes, the functionality of the methods can be 
> implemented using free functions, but if the function to be 
> called lies in another module, how would it know of those free 
> functions? UFCS only works with the functions in scope.

I implemented something like this a while ago and put it up on 
code.dlang.org as `addle`:

https://code.dlang.org/packages/addle

Example usage, from the README:

```d
import addle;
import std.range;

// Import a type from another module
import mylib: MyStruct;

// Define range primitives for MyStruct
bool empty(MyStruct a) { return false; }
string front(MyStruct a) { return "ok"; }
void popFront(MyStruct a) {}

// MyStruct isn't considered an input range, because
// std.range can't see our UFCS methods.
static assert(isInputRange!MyStruct == false);

// ...but extending it makes those methods visible.
static assert(isInputRange!(Extended!MyStruct));

void main()
{
     import std.range: take, only;
     import std.algorithm: equal;

     MyStruct myStruct;

     // Now we can use all of the standard range algorithms
     assert(
         myStruct.extended
         .take(3)
         .equal(only("ok", "ok", "ok"))
     );
}
```


More information about the Digitalmars-d mailing list