October 18, 2012 Extending library functions | ||||
---|---|---|---|---|

| ||||

Hi. I want to extend math library functions to work with my own type. However, the definition for my own type seems to prevent automated access to the original function. How can I fix this unexpected behavior? Simplified example: -------------------- import std.math; int exp2(int x) { return 1 >> x; } void main() { assert(exp2(0.0) == 1.0); // <= why does not this work anymore? //assert(std.math.exp2(0.0) == 1.0); // <= this works } -------------------- |

October 18, 2012 Re: Extending library functions | ||||
---|---|---|---|---|

| ||||

Posted in reply to tn | On Thursday, 18 October 2012 at 11:31:47 UTC, tn wrote: > Hi. > > I want to extend math library functions to work with my own type. However, the definition for my own type seems to prevent automated access to the original function. How can I fix this unexpected behavior? > > Simplified example: > -------------------- > import std.math; > > int exp2(int x) { > return 1 >> x; > } > > void main() { > assert(exp2(0.0) == 1.0); // <= why does not this work anymore? > //assert(std.math.exp2(0.0) == 1.0); // <= this works > } > -------------------- You need to manually add std.math.exp2 to the overload set so importing external methods doesn't hijack your methods: http://dlang.org/function.html#overload-sets alias std.math.exp2 exp2; |

October 18, 2012 Re: Extending library functions | ||||
---|---|---|---|---|

| ||||

Posted in reply to simendsjo | ```
On Thursday, 18 October 2012 at 11:43:40 UTC, simendsjo wrote:
> On Thursday, 18 October 2012 at 11:31:47 UTC, tn wrote:
>> Hi.
>>
>> I want to extend math library functions to work with my own type. However, the definition for my own type seems to prevent automated access to the original function. How can I fix this unexpected behavior?
>>
>> Simplified example:
>> --------------------
>> import std.math;
>>
>> int exp2(int x) {
>> return 1 >> x;
>> }
>>
>> void main() {
>> assert(exp2(0.0) == 1.0); // <= why does not this work anymore?
>> //assert(std.math.exp2(0.0) == 1.0); // <= this works
>> }
>> --------------------
>
> You need to manually add std.math.exp2 to the overload set so importing external methods doesn't hijack your methods:
> http://dlang.org/function.html#overload-sets
>
> alias std.math.exp2 exp2;
Thanks, that clarifies quite a lot. Unfortunately my example was too simplified, as my type is a template.
This still does not work:
--------------------
import std.math;
struct Lognum(T) {
T lx;
}
T log(T)(Lognum!T x) {
return x.lx;
}
alias std.math.log log;
void main() {
//assert(std.math.log(1.0) == 0.0);
assert(log(1.0) == 0.0);
Lognum!double x;
x.lx = 0.0;
assert(log(x) == 0.0);
}
--------------------
``` |

October 18, 2012 Re: Extending library functions | ||||
---|---|---|---|---|

| ||||

Posted in reply to tn | ```
On Thursday, 18 October 2012 at 12:10:17 UTC, tn wrote:
> On Thursday, 18 October 2012 at 11:43:40 UTC, simendsjo wrote:
>> On Thursday, 18 October 2012 at 11:31:47 UTC, tn wrote:
>> (...)
>> You need to manually add std.math.exp2 to the overload set so importing external methods doesn't hijack your methods:
>> http://dlang.org/function.html#overload-sets
>>
>> alias std.math.exp2 exp2;
>
> Thanks, that clarifies quite a lot. Unfortunately my example was too simplified, as my type is a template.
>
> This still does not work:
> --------------------
> import std.math;
>
> struct Lognum(T) {
> T lx;
> }
>
> T log(T)(Lognum!T x) {
> return x.lx;
> }
>
> alias std.math.log log;
>
> void main() {
> //assert(std.math.log(1.0) == 0.0);
> assert(log(1.0) == 0.0);
> Lognum!double x;
> x.lx = 0.0;
> assert(log(x) == 0.0);
> }
> --------------------
I don't think you can overload template methods with non-template methods:
void f(string i) {}
void f(T)(T i) if (is(T == double)) {}
void main(string[] args) {
f(2.2);
}
Error: template ol.f(T) if (is(T == double)) conflicts with function ol.f at ol.d(1)
``` |

October 18, 2012 Re: Extending library functions | ||||
---|---|---|---|---|

| ||||

Posted in reply to simendsjo | ```
On Thursday, 18 October 2012 at 13:35:55 UTC, simendsjo wrote:
> On Thursday, 18 October 2012 at 12:10:17 UTC, tn wrote:
>> On Thursday, 18 October 2012 at 11:43:40 UTC, simendsjo wrote:
>>> On Thursday, 18 October 2012 at 11:31:47 UTC, tn wrote:
>>> (...)
>>> You need to manually add std.math.exp2 to the overload set so importing external methods doesn't hijack your methods:
>>> http://dlang.org/function.html#overload-sets
>>>
>>> alias std.math.exp2 exp2;
>>
>> Thanks, that clarifies quite a lot. Unfortunately my example was too simplified, as my type is a template.
>>
>> This still does not work:
>> --------------------
>> import std.math;
>>
>> struct Lognum(T) {
>> T lx;
>> }
>>
>> T log(T)(Lognum!T x) {
>> return x.lx;
>> }
>>
>> alias std.math.log log;
>>
>> void main() {
>> //assert(std.math.log(1.0) == 0.0);
>> assert(log(1.0) == 0.0);
>> Lognum!double x;
>> x.lx = 0.0;
>> assert(log(x) == 0.0);
>> }
>> --------------------
>
> I don't think you can overload template methods with non-template methods:
>
> void f(string i) {}
> void f(T)(T i) if (is(T == double)) {}
>
> void main(string[] args) {
> f(2.2);
> }
>
> Error: template ol.f(T) if (is(T == double)) conflicts with function ol.f at ol.d(1)
That's too bad. But why then does this work:
--------------------
module a;
void f(string i) {}
--------------------
module b;
void f(T)(T i) if (is(T == double)) {}
--------------------
import a;
import b;
void main(string[] args) {
f("asdf");
f(2.2);
}
--------------------
``` |

October 18, 2012 Re: Extending library functions | ||||
---|---|---|---|---|

| ||||

Posted in reply to simendsjo | ```
simendsjo:
> I don't think you can overload template methods with non-template methods:
But maybe this will change.
Bye,
bearophile
``` |

October 18, 2012 Re: Extending library functions | ||||
---|---|---|---|---|

| ||||

Posted in reply to simendsjo | On 2012-10-18 15:35, simendsjo wrote: > I don't think you can overload template methods with non-template methods You cannot. The usual workaround for this is to make the non-template method a dummy template: void foo () (int a) {} // Note the extra pair of empty parentheses But this won't work if you're not controlling the non-template method. -- /Jacob Carlborg |

October 18, 2012 Re: Extending library functions | ||||
---|---|---|---|---|

| ||||

Posted in reply to bearophile | ```
On Thursday, October 18, 2012 16:22:17 bearophile wrote:
> simendsjo:
> > I don't think you can overload template methods with
>
> > non-template methods:
> But maybe this will change.
It's bug (I forget the exact bug number). TDPL says that you can do it, and as I understand it, it's simply a question of when someone is going to fix it (though I have no idea how easy it will be to fix it) and not a question of whether it'll change or not.
- Jonathan M Davis
``` |