Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading external function for use in a separate module

Tags:

d

I want to do this (supported by this), but I'm hitting a tiny issue (watered down for your less-headachy-non-displeasure).

Let's say I'm a library writer, and I have these functions in a D file:

module mod_a;
import std.stdio;
void run(T)(T v) { writeln("Jigglypuff!"); }
void runrun(T)(T v) { run(v); }

And I have client code in another module in which I attempt to overload run and call runrun:

import mod_a;
void run(T:double)(T v) { writeln("Wigglytuff!"); }
void main() { runrun(1.0); }

This code results in 'Jigglypuff!' being printed rather than 'Wigglytuff!', which makes sense, because the definition of runrun can only see the unevolved unspecialized form available to it in its module. I (and client code), however, would like to be seeing a 'Wigglytuff' rather than a 'Jigglypuff'.

In C++ I'd throw a namespace mod_a { ... } around the specialization of run to show that the client code's run should be examined alongside my library code when trying to determine what the definition of runrun calls, welcoming the can of worms that came along with such behavior.

Is there an idiomatic D-way to organize this such that the function run may be intentionally hijacked? Specifically, I'd like to mimic the way C++'s global functions behave with ad-hoc specializations.

like image 824
user Avatar asked Aug 19 '13 18:08

user


2 Answers

//untested

module mod_a;
import std.stdio;
void run(T)(T v) if (!is(T : double)) { writeln("Jigglypuff!"); }
void runrun(T)(T v) { run(v); }

import mod_a;
void run(T)() if (is(T : double)) { writeln("Wigglytuff!"); }
void main() { runrun(1.0); }
like image 188
Andrei Alexandrescu Avatar answered Oct 14 '22 06:10

Andrei Alexandrescu


In this example you are the authoring the library mod_a so it would be relatively easy to modify it. But I can't help but think about the situation where you aren't the author of the library.

In which case the actual author of the library would probably either be happy that you cannot just do what you are trying to do... or actively wants to support what you are trying to do.

lets assume the library writer wants you to be able to "hijack" a function that he/she uses in his implementation. He or she would probably go about it differently; I would.

This is one area where I believe the encapsulation stories you linked and I just read describe exactly how to achieve the opposite situation of what you want here. This type of thing screams that it needs contract programming.

As a library author, I'd probably offer you an interface and possibly an abstract class, maybe even one or two concrete implementations, that you could use to do your thing. Someone else might give add a template or runtime parameter requiring a specific implementation as an argument. Yet someone else could add a lazy string delegate to the mix.

(my) conclusion: As a library author, there are options to make what you want possible. If it's not possible with your preferred library you'll probably end up filing a feature request.

like image 33
Kris Avatar answered Oct 14 '22 07:10

Kris