Re: Function hijack on selective import

2018-01-16 Thread rumbu via Digitalmars-d-learn

On Tuesday, 16 January 2018 at 20:30:43 UTC, H. S. Teoh wrote:

On Tue, Jan 16, 2018 at 07:14:00PM +, 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



Re: Function hijack on selective import

2018-01-16 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Jan 16, 2018 at 07:14:00PM +, 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


Re: Function hijack on selective import

2018-01-16 Thread rumbu via Digitalmars-d-learn

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



Re: Function hijack on selective import

2017-12-26 Thread rumbu via Digitalmars-d-learn

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.


Re: Function hijack on selective import

2017-12-26 Thread Adam D. Ruppe via Digitalmars-d-learn

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)


Re: Function hijack on selective import

2017-12-26 Thread rumbu via Digitalmars-d-learn

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 *))[F.SIGNPOS_BYTE] & 0x80) != 0;
}




Re: Function hijack on selective import

2017-12-26 Thread Adam D. Ruppe via Digitalmars-d-learn
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.



Function hijack on selective import

2017-12-26 Thread rumbu via Digitalmars-d-learn
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)