www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - why compiler try use my sqrt not std.math?

reply KnightMare <black80 bk.ru> writes:
// ============= test5.d ==============
import std.stdio, std.conv, std.bigint, std.math, std.algorithm;

ulong sqrt( ulong n ) { return cast( ulong )real( n ).sqrt; }
ulong sqrt1( ulong n ) { return cast( ulong )real( n ).sqrt.ceil; 
}

void main() { }
// ============= EOF test5.d ==============

and result is:
test5.d(5): Error: std.math.ceil called with argument types 
(ulong) matches both:
C:\programz\D\ldc2\bin\..\import\std\math.d(4869):     
std.math.ceil(real x)
and:
C:\programz\D\ldc2\bin\..\import\std\math.d(4982):     
std.math.ceil(float x)

prog compiles ok when I comment my ulong sqrt( ulong )

IMO about sqrt1 (I tried cast(real)n instead real(n) too with 
same result)
real(n).sqrt should to use real std.math.sqrt(real) that returns 
real. so ceil should be used real std.math.ceil(real). and after 
that only cast to ulong.

what happened here?
May 08 2019
next sibling parent reply KnightMare <black80 bk.ru> writes:
so compiler thinks and try convert my code upper to
ulong sqrt1( ulong n ) {
   return cast( ulong )ceil<float OR real?>(  ret(ulong)my_sqrt( 
cast( ulong )real( n )));
}
why that? I didnt ask that.

yes, I know that I can add inside sqrt1
import std.math : sqrt;
but.. WHY?
May 08 2019
parent reply Cym13 <cpicard purrfect.fr> writes:
On Wednesday, 8 May 2019 at 08:28:57 UTC, KnightMare wrote:
 so compiler thinks and try convert my code upper to
 ulong sqrt1( ulong n ) {
   return cast( ulong )ceil<float OR real?>(  ret(ulong)my_sqrt( 
 cast( ulong )real( n )));
 }
 why that? I didnt ask that.

 yes, I know that I can add inside sqrt1
 import std.math : sqrt;
 but.. WHY?
First of all, such questions are better suited for the Learn section if you want quality answers. When you define a function it's reasonnable to assume that you want to use it, that's probably why D (and any language I know really) resolves function names from the most local scope to the largest one. If it worked the other way arround you could define a function like byLine thinking that this name is safe and be equally confused when the program tries making web requests because you have no clue that it's actually already defined in std.net.curl. Here at least you're confused but you have the function before you so that confusion shouldn't last as long. It's also true inside that function's definition: recursive functions are common and they need that mechanics to work. Now, in my opinion, the right way to fix your code (short of choosing another name) is to specify the function you wish to use explicitely: import std.math; ulong sqrt(ulong n) { return cast(ulong) std.math.sqrt(real(n)); } And for reference, should you want to name the current module's implementation of sqrt, you would do as such: ulong sqrt(ulong n) { return cast(ulong) .sqrt(real(n)); } But of course here it would cause infinite recursion and stack overflow.
May 08 2019
parent reply Cym13 <cpicard purrfect.fr> writes:
On Wednesday, 8 May 2019 at 08:48:40 UTC, Cym13 wrote:
 On Wednesday, 8 May 2019 at 08:28:57 UTC, KnightMare wrote:
 [...]
First of all, such questions are better suited for the Learn section if you want quality answers. [...]
I hadn't noticed the type issue, my answer is off.
May 08 2019
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Wednesday, May 8, 2019 2:52:34 AM MDT Cym13 via Digitalmars-d wrote:
 On Wednesday, 8 May 2019 at 08:48:40 UTC, Cym13 wrote:
 On Wednesday, 8 May 2019 at 08:28:57 UTC, KnightMare wrote:
 [...]
First of all, such questions are better suited for the Learn section if you want quality answers. [...]
I hadn't noticed the type issue, my answer is off.
It doesn't matter, because the local scope always wins when there's a symbol conflict with an imported symbol. If you try to use the same name as a symbol you're importing, and you want to use the imported symbol, then you need to either use the full import path when using the symbol, rename it when importing it, or alias the symbol (using the full path name) to a different name. In the latter two cases, you then of course have to use the new name for the symbol and not the original name. IIRC, you have the same problem when you have a local import which imports symbols explicitly instead of the entire module, because that effectively aliases the symbol with that name in the local scope. You basically can't overload symbols from other modules in the local scope, because the language assumes that you want the local symbol. In general though, D doesn't go with the "best match" with overload sets. It will take the exact match, and it will do implicit conversions if there's only one possible choice, but once multiple overloads would all accept the same type but none of them accept the exact type of the argument, then it's an error. D is much pickier about overloads than C++ in order to avoid issues with function hijacking. It can get annoying sometimes, but by being pickier about it, it avoids a whole class of bugs that exist in C++. https://dlang.org/articles/hijack.html - Jonathan M Davis
May 08 2019
prev sibling next sibling parent KnightMare <black80 bk.ru> writes:
compiler should select right sqrt by arg types. it shouldnt 
prefer my sqrt( ulong ) over std.math.sqrt( real ) when I pass to 
sqrt real with explicit cast

it has from std.math
float sqrt( float )
double sqrt( double )
real sqrt( real )
I added
ulong sqrt( ulong )
and try invoke sqrt( real(SomeVal))
we have real arg, so call std.math.sqrt( real ). no doubt!
WHY compiler tries be too much smart and looks stupid and buggy?

in case no misunderstanding what ceil should be called I missed 
this BUG (compiler call MY sqrt(ulong)) before some tests or 
debugging session
May 08 2019
prev sibling next sibling parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Wednesday, 8 May 2019 at 08:16:27 UTC, KnightMare wrote:
 // ============= test5.d ==============
 import std.stdio, std.conv, std.bigint, std.math, std.algorithm;

 ulong sqrt( ulong n ) { return cast( ulong )real( n ).sqrt; }
 ulong sqrt1( ulong n ) { return cast( ulong )real( n 
 ).sqrt.ceil; }

 void main() { }
 // ============= EOF test5.d ==============

 and result is:
 test5.d(5): Error: std.math.ceil called with argument types 
 (ulong) matches both:
 C:\programz\D\ldc2\bin\..\import\std\math.d(4869):     
 std.math.ceil(real x)
 and:
 C:\programz\D\ldc2\bin\..\import\std\math.d(4982):     
 std.math.ceil(float x)

 prog compiles ok when I comment my ulong sqrt( ulong )

 IMO about sqrt1 (I tried cast(real)n instead real(n) too with 
 same result)
 real(n).sqrt should to use real std.math.sqrt(real) that 
 returns real. so ceil should be used real std.math.ceil(real). 
 and after that only cast to ulong.

 what happened here?
When a function overload is looked up, the most local symbol is used. In this case, that's your sqrt function. We can even prove this by testing sqrt: import std.math; ulong sqrt( ulong n ) { return cast( ulong )real( n ).sqrt; } void main() { assert(4UL.sqrt == 2); } The above program will hang, since sqrt calls itself recursively. When you comment out sqrt, the imported sqrt will be used instead. To combine the overload sets, you will need to explicitly mention std.math.sqrt somehow, either: import std.math : sqrt; or import std.math; alias sqrt = std.math.sqrt; Once that's done, your code will do the Right Thing™. -- Simen
May 08 2019
prev sibling parent reply KnightMare <black80 bk.ru> writes:
OFFTOPIC
Dlang is good language but sometimes happens big badaboom (shit 
in other words):

and happens something bad/unexpected in lines where you not see 
any criminal (no typos, no semantic issues). u just write working 
code in your mind-stream, u write such code many times in other 
languages and it worked as expected.
and... BOOOM!.. you are thrown out of the stream.. what happened 
here?

u asked questions on forum and u will get an answer in few hours 
but till u sit and reflection yourself and question of universe:
why author do this way? he had some reason for this.
why other langs do way as I expected? maybe appear some cases 
where this way better than in other langs? OR maybe such things 
works same in other langs and I just forgot it? FK! maybe I have 
alzheimer's disease? I am too young for this shit!..

after 2 such bigbadaboom people lefts Dlang. I can understand 
that.
it like Russian language - u have 1/4 of book rules and 3/4 
exceptions from this rules, u shouldnt understand it, u must 
remember it and that all, dont think, dont doubt!

well, lets write all unclear cases of Dlang in some page (better 
home page)
1) case with sqrt: I compiler prefer func in this file/module 
over func in included module and it ignores types of parameters?
2) why
(string s) { return cast( int )s.length; } typeof is int 
delegate( string )
but
(string s) => { return cast( int )s.length; } typeof is int 
delegate() delegate( string )
3) add more, dont be shy
May 08 2019
next sibling parent Cym13 <cpicard purrfect.fr> writes:
On Wednesday, 8 May 2019 at 09:20:35 UTC, KnightMare wrote:
 2) why
 (string s) { return cast( int )s.length; } typeof is int 
 delegate( string )
 but
 (string s) => { return cast( int )s.length; } typeof is int 
 delegate() delegate( string )
That I can answer: (string s) => { return cast( int )s.length; } is equivalent to (string s) => (){ return cast( int )s.length; } since empty parens can be ommited. So it's a delegate that returns a delegate. Don't put {} there. The equivalent with => will be: (string s) => cast( int )s.length
May 08 2019
prev sibling parent KnightMare <black80 bk.ru> writes:
tale in Russian
https://bormor.livejournal.com/354899.html

translation over google translator:
One rather big village had a rather large flock of sheep. And, as 
usual, the shepherd was put in charge of the flock - and the most 
vocal of the village boys was chosen for the role of the 
shepherd, so that it could be heard from afar. And so, he grazes 
the first day of these sheep, and suddenly a wolf! Well, the 
shepherd immediately screamed, the village ran up, scared the 
wolf, praised the shepherd, and went back. An hour passes - the 
wolf has come again! The shepherd screams, the village people 
come running, the wolf runs away, everyone’s leaving. Another 
hour passed — the shepherd screamed again, the village men run 
again — yes, surely, no deception, the wolf is in place, chasing 
him away and going about his business. Another hour - screams 
again; Well, the villagers could not stand it, they ran, the 
shepherd was mortified and removed from harm's way into the army 
- let him yell as much as he could. And they put a deaf-and-dumb 
fool to the sheep, and they even blindfolded him with a 
handkerchief so that he wouldn’t see it by chance.
And since then, in the village, peace and quiet. Sheep, of 
course, disappear, but on the other hand, there was much less 
cause for concern.

so "peace and quiet" should be preference by proging lang writers.
or.. am I "most vocal of the village boys"? :)
May 08 2019