Thread overview
Function hijack on selective import
Dec 26
rumbu
Dec 26
rumbu
Dec 27
rumbu
2 days ago
rumbu
1 day ago
H. S. Teoh
1 day ago
rumbu
December 26
Is there anyway to extend an existing function to accept custom data types?



****************
Option 1 - global import of std.math


import std.math;

struct Custom {}

int signbit(T)(T x) if (is(T == Custom))
{
    return 0;
}

Custom c;
assert(signbit(c) == 0);
assert(signbit(-1.0) == 1);

Error: template main.signbit cannot deduce function from argument types !()(double), candidates are:
main.signbit(T)(T x) if (is(T == Custom))


*******************
Option 2 - selective import of std.math

import std.math : signbit;

struct Custom {}

int signbit(T)(T x) if (is(T == Custom))
{
    return 0;
}

Custom c;
assert(signbit(c) == 0);
assert(signbit(-1.0) == 1);


main.signbit called with argument types (Custom) matches both:
\..\src\phobos\std\math.d(5721):     std.math.signbit!(Custom).signbit(Custom x)
and:
main.signbit!(Custom).signbit(Custom x)
December 26
The mistake you're making is using a constraint when you should try a specialization:


int signbit(T:Custom)(T x)
{
    return 0;
}


That means to use this specialized function when T is Custom. Now, you just need to merge the overload sets:

import std.math;
alias signbit = std.math.signbit; // this merges local signbit with std.math.signbit


and boom it should compile and call your version.

December 26
On Tuesday, 26 December 2017 at 16:15:55 UTC, Adam D. Ruppe wrote:
> The mistake you're making is using a constraint when you should try a specialization:
>
>
> int signbit(T:Custom)(T x)
> {
>     return 0;
> }
>
>
> That means to use this specialized function when T is Custom. Now, you just need to merge the overload sets:
>
> import std.math;
> alias signbit = std.math.signbit; // this merges local signbit with std.math.signbit
>
>
> and boom it should compile and call your version.

"Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.

My opinion is that the mistake is in std.math, because std.math.signbit accepts any type instead to be constrained to float types. Actually, calling std.math.signbit with any other type than float will result in compiler error because signbit expects some float traits for the provided type:

int signbit(X)(X x) @nogc @trusted pure nothrow
{
    alias F = floatTraits!(X);
    return ((cast(ubyte *)&x)[F.SIGNPOS_BYTE] & 0x80) != 0;
}


December 26
On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote:
> "Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.

You can specialize on templated structs generically.

int foo(T : Bar!(X, Y), X, Y)

that kind of thing covers any case of Bar!(X,y)
December 27
On Tuesday, 26 December 2017 at 20:21:11 UTC, Adam D. Ruppe wrote:
> On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote:
>> "Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.
>
> You can specialize on templated structs generically.
>
> int foo(T : Bar!(X, Y), X, Y)
>
> that kind of thing covers any case of Bar!(X,y)

Thank you, Adam.
2 days ago
On Tuesday, 26 December 2017 at 20:21:11 UTC, Adam D. Ruppe wrote:
> On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote:
>> "Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.
>
> You can specialize on templated structs generically.
>
> int foo(T : Bar!(X, Y), X, Y)
>
> that kind of thing covers any case of Bar!(X,y)

Even specialized, now I have another problem:

std.math:

int signbit(X)(X x) { ... }

mylibrary:

int signbit(D: Decimal!bits, int bits) { ... }

=============

end user:

import std.math;
import mylibrary;

Decimal!32 d;
float f;

auto y = signbit(f); //ok, call to std.math.signbit
auto x = signbit(d); //error, also calls std.math.signbit

1 day ago
On Tue, Jan 16, 2018 at 07:14:00PM +0000, rumbu via Digitalmars-d-learn wrote:
> On Tuesday, 26 December 2017 at 20:21:11 UTC, Adam D. Ruppe wrote:
> > On Tuesday, 26 December 2017 at 19:41:47 UTC, rumbu wrote:
> > > "Custom" is a templated struct. I cannot imagine all the instantiations of Custom to write template specialisations for each of them.
> > 
> > You can specialize on templated structs generically.
> > 
> > int foo(T : Bar!(X, Y), X, Y)
> > 
> > that kind of thing covers any case of Bar!(X,y)
> 
> Even specialized, now I have another problem:
> 
> std.math:
> 
> int signbit(X)(X x) { ... }
> 
> mylibrary:
> 
> int signbit(D: Decimal!bits, int bits) { ... }
> 
> =============
> 
> end user:
> 
> import std.math;
> import mylibrary;
> 
> Decimal!32 d;
> float f;
> 
> auto y = signbit(f); //ok, call to std.math.signbit
> auto x = signbit(d); //error, also calls std.math.signbit

Arguably, this is a defect in Phobos.  Looking at the definition of std.math.signbit, it's obvious that it's only meant to handle built-in floating-point types, yet there are no sig constraints to that effect.

Fix: https://github.com/dlang/phobos/pull/6040


T

-- 
The computer is only a tool. Unfortunately, so is the user. -- Armaphine, K5
1 day ago
On Tuesday, 16 January 2018 at 20:30:43 UTC, H. S. Teoh wrote:
> On Tue, Jan 16, 2018 at 07:14:00PM +0000, rumbu via
>> 
>> Even specialized, now I have another problem:
>> 
>> std.math:
>> 
>> int signbit(X)(X x) { ... }
>> 
>> mylibrary:
>> 
>> int signbit(D: Decimal!bits, int bits) { ... }
>> 
>> =============
>> 
>> end user:
>> 
>> import std.math;
>> import mylibrary;
>> 
>> Decimal!32 d;
>> float f;
>> 
>> auto y = signbit(f); //ok, call to std.math.signbit
>> auto x = signbit(d); //error, also calls std.math.signbit
>
> Arguably, this is a defect in Phobos.  Looking at the definition of std.math.signbit, it's obvious that it's only meant to handle built-in floating-point types, yet there are no sig constraints to that effect.
>
> Fix: https://github.com/dlang/phobos/pull/6040
>
>
> T

Thank you for the pull request, but the list is longer :)
 https://issues.dlang.org/show_bug.cgi?id=18244