The use case for this sort of thing I like best is extending objects without touching the object.
E.g. in D to convert between different types you can use std.conv:
import std.conv;
"123".to!int;
123.to!string;
Ints don't need to understand string building and strings don't need to understand int parsing. The conversion code just needs to declare a couple functions taking the right arguments and it just works. To me the above is much more readable than
to!int("123")
to!string(123)
in any case. It's also quite nice when dealing with C APIs since it allows you to pretend they are OOP in quite a lot of cases. e.g. with SDL:
SDL_CreateRenderer(window, -1, 0);
turns into
window.SDL_CreateRenderer(-1, 0);
and say I'd like to have a function to initialize all the renderer stuff in one go? I can simply declare
void CreateRendererAndInitialize(SDL_Window* window){<snip>}
and now you can do the following:
window.CreateRendererAndInitialize();
It removes a
lot of pain from extending 3rd party types you see in other languages.