www.digitalmars.com         C & C++   DMDScript  

D - Cannot import both std.string and std.ctype

reply Dave Sieber <dsieber spamnot.sbcglobal.net> writes:
c:\dmd\bin\..\src\phobos\std\string.d(502): function toupper conflicts with 
ctype.toupper at c:\dmd\bin\..\src\phobos\std\ctype.d(36)

Anyone else getting this?

-- 
dave
Mar 26 2004
next sibling parent reply J C Calvarese <jcc7 cox.net> writes:
Dave Sieber wrote:
 c:\dmd\bin\..\src\phobos\std\string.d(502): function toupper conflicts with 
 ctype.toupper at c:\dmd\bin\..\src\phobos\std\ctype.d(36)

I assume you're talking about code like this... import std.ctype; import std.string; void main() { char[] s = "some string"; s = toupper(s); printf("%.*s\n", s); }
 
 Anyone else getting this?

If you're just using toupper once, the best thing to do is probably refer to the name of the module you want to disambiguate: s = std.string.toupper(s); or s = std.ctype.toupper(s); Also (especially if you use this function a lot of times), you could use an alias near the top of your program like this: import std.ctype; import std.string; alias std.string.toupper toupper; /* selects the std.string function */ void main() { char[] s = "some string"; s = std.string.toupper(s); printf("%.*s\n", s); } -- Justin http://jcc_7.tripod.com/d/
Mar 26 2004
parent reply Dave Sieber <dsieber spamnot.sbcglobal.net> writes:
J C Calvarese <jcc7 cox.net> wrote:

 I assume you're talking about code like this...
 
 import std.ctype;
 import std.string;
 
 void main()
 {
      char[] s = "some string";
      s = toupper(s);
      printf("%.*s\n", s);
 }

Yes, that's basically it, but I was needing toupper() on a character.
 If you're just using toupper once, the best thing to do is probably 
 refer to the name of the module you want to disambiguate:
 
 s = std.string.toupper(s);
 or
 s = std.ctype.toupper(s);

Cool, this works. But I'm not sure I understand why -- aren't the two functions unambiguous? char[] toupper(char[] s) dchar toupper(dchar c) When I import both std.string and std.ctype, even this doesn't work: dchar dc; dc = toupper(dc); and there is nothing ambiguous about the argument. -- dave (still struggling... :-)
Mar 26 2004
next sibling parent reply J C Calvarese <jcc7 cox.net> writes:
Dave Sieber wrote:
 J C Calvarese <jcc7 cox.net> wrote:
 
 
I assume you're talking about code like this...

import std.ctype;
import std.string;

void main()
{
     char[] s = "some string";
     s = toupper(s);
     printf("%.*s\n", s);
}

Yes, that's basically it, but I was needing toupper() on a character.

 
If you're just using toupper once, the best thing to do is probably 
refer to the name of the module you want to disambiguate:

s = std.string.toupper(s);
or
s = std.ctype.toupper(s);

Cool, this works. But I'm not sure I understand why -- aren't the two functions unambiguous? char[] toupper(char[] s) dchar toupper(dchar c)

If they're in the same module, yes. But I think D checks if the symbol is in different modules BEFORE it looks at parameter types. Maybe we can persuade Walter to change this. Also, I think it'd be an improvement if the toupper is std.ctype was moved to std.string, but I suppose the idea is to have char/dchar functions in std.ctype and char[] functions in std.string.
 
 When I import both std.string and std.ctype, even this doesn't work:
 
 dchar dc;
 dc = toupper(dc);
 
 and there is nothing ambiguous about the argument.
 

import std.ctype; import std.string; alias std.ctype.toupper toupper; void main() { dchar s; s = toupper(cast(dchar) 's'); /* I don't think printf supports Unicode, but this seems to be an exception. */ printf("%c\n", s); } -- Justin http://jcc_7.tripod.com/d/
Mar 26 2004
parent reply Dave Sieber <dsieber spamnot.sbcglobal.net> writes:
J C Calvarese <jcc7 cox.net> wrote:

 Well, I don't read minds. :) At least, not at 100% accuracy.

What???? I am _deeply_ disappointed... <G>
 If they're in the same module, yes. But I think D checks if the symbol 
 is in different modules BEFORE it looks at parameter types. Maybe we can 
 persuade Walter to change this.

Perhaps we can, but it should approached with careful study. As Walter has said in the D docs, the C++ lookup rules got pretty crazy, and we'd want to avoid that. Anyway, this is only my second day programming with D, so my questions are probably representation of what a long-time C++ programmer would expect (rightly or wrongly) when moving to D.
 Also, I think it'd be an improvement if the toupper is std.ctype was 
 moved to std.string, but I suppose the idea is to have char/dchar 
 functions in std.ctype and char[] functions in std.string.

I suspect it was traditional, because in C toupper/tolower were found in ctype.h.
 Try this:
 
 import std.ctype;
 import std.string;
 
 alias std.ctype.toupper toupper;
 
 void main()
 {
      dchar s;
      s = toupper(cast(dchar) 's');
      
      /* I don't think printf supports Unicode,
         but this seems to be an exception. */
      printf("%c\n", s);
 }

Well, that doesn't seem to work either, but perhaps I am still doing something wrong. Am I still thinking too much like a C++ programmer? :-) IAC, I've solved my immediate problem with my learning code, and realize I need more study. -- dave
Mar 26 2004
parent J C Calvarese <jcc7 cox.net> writes:
Dave Sieber wrote:
 J C Calvarese <jcc7 cox.net> wrote: 
 
Well, I don't read minds. :) At least, not at 100% accuracy.

What???? I am _deeply_ disappointed... <G>
If they're in the same module, yes. But I think D checks if the symbol 
is in different modules BEFORE it looks at parameter types. Maybe we can 
persuade Walter to change this.

Perhaps we can, but it should approached with careful study. As Walter has said in the D docs, the C++ lookup rules got pretty crazy, and we'd want to avoid that. Anyway, this is only my second day programming with D, so my questions are probably representation of what a long-time C++ programmer would expect (rightly or wrongly) when moving to D.

If Walter has already considered this issue, it's probably already set in stone. But if he hasn't considered this before it's possible that he'd change it. But I suspect that having the compiler consider the parameter types when it's looking for ambiguous symbols would be so much effort that the status quo is the way it stays.
Also, I think it'd be an improvement if the toupper is std.ctype was 
moved to std.string, but I suppose the idea is to have char/dchar 
functions in std.ctype and char[] functions in std.string.

I suspect it was traditional, because in C toupper/tolower were found in ctype.h.

I didn't realize that. It doesn't mean that it can't change, though.
Try this:

import std.ctype;
import std.string;

alias std.ctype.toupper toupper;

void main()
{
     dchar s;
     s = toupper(cast(dchar) 's');
     
     /* I don't think printf supports Unicode,
        but this seems to be an exception. */
     printf("%c\n", s);
}

Well, that doesn't seem to work either, but perhaps I am still doing something wrong. Am I still thinking too much like a C++ programmer? :-)

I'm sure I don't have that problem since I don't know C++. Unfortunately, I'm probably going to have to learn it someday since there's so much cool code out there written in C++ (such as the DMD front end).
 IAC, I've solved my immediate problem with my learning code, and realize I 
 need more study. 

-- Justin http://jcc_7.tripod.com/d/
Mar 26 2004
prev sibling parent reply Ilya Minkov <minkov cs.tum.edu> writes:
Dave Sieber schrieb:
 Cool, this works. But I'm not sure I understand why -- aren't the two 
 functions unambiguous?

No, they are unambigous. But they are not overloads of the same symbol. To make them overload the same symbol you can do something like alias std.string.toupper toupper; alias std.ctype.toupper toupper; These make both functions overload toupper in your module's scope and you can call both directly. Additionally, if you also define your own toupper in the same module, it will also overload correctly. I think if we need Walter to change the system, namely that not the symbols are searched within foreign scopes, but dropped temporarily into current scope, then we have to collect strong arguments. It is not impossible, but Walter is not someone who can change his mind without being really convinced. -eye
Mar 26 2004
parent reply J C Calvarese <jcc7 cox.net> writes:
Ilya Minkov wrote:
 Dave Sieber schrieb:
 
 Cool, this works. But I'm not sure I understand why -- aren't the two 
 functions unambiguous?

No, they are unambigous. But they are not overloads of the same symbol. To make them overload the same symbol you can do something like alias std.string.toupper toupper; alias std.ctype.toupper toupper;

I didn't realize that was possible. Awesome! Now that I know that, I don't think we should change the foreign scope system at all when we can work like this within the current system.
 These make both functions overload toupper in your module's scope and 
 you can call both directly. Additionally, if you also define your own 
 toupper in the same module, it will also overload correctly.
 
 I think if we need Walter to change the system, namely that not the 
 symbols are searched within foreign scopes, but dropped temporarily into 
 current scope, then we have to collect strong arguments. It is not 
 impossible, but Walter is not someone who can change his mind without 
 being really convinced.

Right.
 -eye

-- Justin http://jcc_7.tripod.com/d/
Mar 26 2004
parent Dave Sieber <dsieber spamnot.sbcglobal.net> writes:
J C Calvarese <jcc7 cox.net> wrote:

 Ilya Minkov wrote:

 alias std.string.toupper toupper;
 alias std.ctype.toupper toupper;

I didn't realize that was possible. Awesome! Now that I know that, I don't think we should change the foreign scope system at all when we can work like this within the current system.

I agree, that is a good solution, and now understanding what is going on, I see why. But -- I also think that the standard library (Phobos) should work correctly "out of the box" without having to resort to any aliasing or explicit module resolutions in your code. If I were importing some foreign module from somewhere and it had a name that was identical to something else, fine. I would thank Walter for designing the language to allow this to work. But I think that whenever you see some kind of "standard" workaround that everyone has to use (such as the aliases above, or in C/C++ a macro to return the number of elements in a static array, #ifdef kludges in .h files to get around the multiple inclusion problem, etc.) it reveals a design weakness in the language, library, whatever. IMHO. In this case, I might suggest the char[] version of toupper be named differently, especially since these libraries appear to want to mirror what a C programmer knows and uses (even down to the module names themselves). If it were named strupr, for instance, it would be the name every C/C++ programmer knows and might expect, and would present no problems or surprises to anyone. It would "just work". My two cents... :-) -- dave
Mar 26 2004
prev sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
Dave Sieber wrote:

 c:\dmd\bin\..\src\phobos\std\string.d(502): function toupper conflicts with 
 ctype.toupper at c:\dmd\bin\..\src\phobos\std\ctype.d(36)
 
 Anyone else getting this?

You have to specify which one you want to use. So long!
Mar 26 2004