www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.algorithm.cmp is conflicting with itself.

reply realhet <real_het hotmail.com> writes:
Hello,

I try to make an overload group of cmp() functions in my utility 
module but everything works well except when I import some 3rd 
party module that imports std.algorithm. Then I get an error:
C:\D\testCmpOverload.d(11,8): Error:
function `std.algorithm.comparison.cmp!(string, string).cmp` at
c:\D\ldc2\bin\..\import\std\algorithm\comparison.d(625,6)
conflicts with
function `std.algorithm.comparison.cmp!(string, string).cmp` at 
c:\D\ldc2\bin\..\import\std\algorithm\comparison.d(625,6)

It is conflicting with itself.
My question is that how to solve this without choosing a 
different identifier, other than 'cmp'?

Here's the utility module:
```d
module testcmpmodule;

//publicly output these modules, like I did in my always used 
'utils' module.
public import std.algorithm, std.math, std.stdio;

import std.range, std.traits;

//create function overload group
public import std.algorithm : cmp;
public import std.math      : cmp;

auto cmp(A, B)(in A a, in B b)
if(!(isInputRange!A && isInputRange!B)          //exclude 
std.algorithm.cmp
&& !(isFloatingPoint!A && isFloatingPoint!B))   //exclude 
std.math.cmp
{
   return a==b ? 0 : a<b ? -1 : 1; //last resort
}

```

The other module that publishes the utility module:
```d
module testcmpmodule2;

public import std.algorithm, testcmpmodule, std.stdio;

void w(A...)(in A a){ writeln(a); }
```

The main module:
```d
import testcmpmodule2;

void main(){
   w(cmp(.1, .2));   //std.math.cmp
   w(cmp("a", "b")); //std.algorithm.cmp   <- here's the error
   w(cmp(1, 2));     //my cmp
}
```

I have a project with 40K lines. And I don't even have to use 
public import in the 'second' module, like in this example, the 
error is happenning because something pulls it in.

My not so good solution was this:
```d
alias cmp_ = cmp; //so wherever there is a conflict, I only have 
to put a _ symbol after the cmp, but that's still ugly.


To be more precise:
I have a het.math module where I implement math routines that are 
close to opengl.
That module does a log of patching of various std functions, 
mainly enable them to work on vector/matrix.
I also have a het.utils module which publicly imports het.math, 
and also many std modules.
And finally when I make an application using the complete 
framework, I lost the game finding what imports std.algorithm and 
thus ruining my fragile function overload groups.

Also I wonder why there is no cmp() function for integers in the 
std library?  It's easy to code (a-b   or   a==b?0:a<b?-1:1)  but 
still, I can do mistakes. (And I did: many of my comparisons had 
bugs :D So I wan't to centralize cmp())


Thank You in advance!
Aug 11 2022
parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 11 August 2022 at 17:46:00 UTC, realhet wrote:
 Here's the utility module:
 ```d
 module testcmpmodule;

 //publicly output these modules, like I did in my always used 
 'utils' module.
 public import std.algorithm, std.math, std.stdio;

 import std.range, std.traits;

 //create function overload group
 public import std.algorithm : cmp;
 public import std.math      : cmp;

 auto cmp(A, B)(in A a, in B b)
 if(!(isInputRange!A && isInputRange!B)          //exclude 
 std.algorithm.cmp
 && !(isFloatingPoint!A && isFloatingPoint!B))   //exclude 
 std.math.cmp
 {
   return a==b ? 0 : a<b ? -1 : 1; //last resort
 }

 ```

 The other module that publishes the utility module:
 ```d
 module testcmpmodule2;

 public import std.algorithm, testcmpmodule, std.stdio;

 void w(A...)(in A a){ writeln(a); }
 ```
What's happening here is that the overload set created by the utility module is conflicting with the overload set created by the `public import` in `testcmpmodule2`. If you remove `std.algorithm` from `testcmpmodule2`'s `public import` line, the code compiles successfully.
Aug 11 2022
parent reply realhet <real_het hotmail.com> writes:
On Thursday, 11 August 2022 at 18:10:31 UTC, Paul Backus wrote:
 ... If you remove `std.algorithm` from `testcmpmodule2`'s 
 `public import` line, the code compiles successfully.
Yes, but in the 40 module project I'm unable to make it work. I doublechecked that the only public import of std.algorithm is in that utility module which is making the overload set. If a third party module uses std.algorithm, it's not public, and I also restrict the import for specific names that it uses. And still I'm not able to cmp("a", "b"), because of the conflict. What I'm thinking of maybe it is some module in the std library that can make a second conflicting overload set? (I public import some std modules, and if there is a public import inside that module to std.algorithm it can happen. I guess it's a possibility.)
Aug 11 2022
parent reply bachmeier <no spam.net> writes:
On Thursday, 11 August 2022 at 18:32:54 UTC, realhet wrote:
 On Thursday, 11 August 2022 at 18:10:31 UTC, Paul Backus wrote:
 ... If you remove `std.algorithm` from `testcmpmodule2`'s 
 `public import` line, the code compiles successfully.
Yes, but in the 40 module project I'm unable to make it work. I doublechecked that the only public import of std.algorithm is in that utility module which is making the overload set. If a third party module uses std.algorithm, it's not public, and I also restrict the import for specific names that it uses. And still I'm not able to cmp("a", "b"), because of the conflict. What I'm thinking of maybe it is some module in the std library that can make a second conflicting overload set? (I public import some std modules, and if there is a public import inside that module to std.algorithm it can happen. I guess it's a possibility.)
std.string does a public import of std.algorithm.cmp.
Aug 11 2022
parent reply realhet <real_het hotmail.com> writes:
On Thursday, 11 August 2022 at 19:33:31 UTC, bachmeier wrote:
 std.string does a public import of std.algorithm.cmp.
That was it! Thanks! Conclusion: This is how to overload cmp() ```d //this is the only place from where all other modules can see these std modules public import std.string, std.uni, std.algorithm, std.math; import std.range, std.traits; //create function overload group public import std.algorithm : cmp; public import std.math : cmp; auto cmp(A, B)(in A a, in B b) //the custom cmp() function if(!(isInputRange!A && isInputRange!B) //exclude std.algorithm.cmp && !(isFloatingPoint!A && isFloatingPoint!B)) //exclude std.math.cmp { return a==b ? 0 : a<b ? -1 : 1; } ```
Aug 11 2022
parent reply bachmeier <no spam.net> writes:
On Thursday, 11 August 2022 at 22:34:11 UTC, realhet wrote:
 On Thursday, 11 August 2022 at 19:33:31 UTC, bachmeier wrote:
 std.string does a public import of std.algorithm.cmp.
That was it! Thanks! Conclusion: This is how to overload cmp()
A search of the forum suggests [this is how I learned about it](https://forum.dlang.org/post/mailman.1843.1415813238.9932.digitalma s-d puremagic.com). I most likely had the same problem early in my D career. I don't know if anything further was ever done to fix the problem (if anything could be done), but if this is a design mistake that can't be fixed, there should at least be an informative error message so we know where to look. The error message you posted already identifies it as std.algorithm.comparison.cmp.
Aug 11 2022
parent realhet <real_het hotmail.com> writes:
On Friday, 12 August 2022 at 02:13:48 UTC, bachmeier wrote:
 Informative error message
I'm making something like an IDE. The text search function in it is able to search across all user modules. I thought about filtering the search results by context. The following contexts are planned already: - inside code - inside comment - inside string literal Now I can add: - inside import declarations - search inside std That would help a lot with this type of error message. I think extending some general std routines is really helpful. This way I can write code in DLang, copy/paste it into GLSL and with minimal changes it can work there as well, and vice verse. The only downside is that when I want to use 3rd party packages: I have to check and modify them to not harm my overload sets with their imports.
Aug 12 2022