Jump to page: 1 2
Thread overview
[Issue 9999] New: Integer literal 0 and 1 should prefer integer type in overload resolution
Apr 27, 2013
Kenji Hara
Apr 27, 2013
Kenji Hara
Apr 27, 2013
Kenji Hara
Apr 27, 2013
Walter Bright
Apr 27, 2013
Kenji Hara
Apr 27, 2013
Martin Nowak
Apr 28, 2013
Jonathan M Davis
Apr 28, 2013
Martin Nowak
Apr 28, 2013
Jonathan M Davis
Apr 29, 2013
Don
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999

           Summary: Integer literal 0 and 1 should prefer integer type in
                    overload resolution
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: k.hara.pg@gmail.com


--- Comment #0 from Kenji Hara <k.hara.pg@gmail.com> 2013-04-27 11:04:05 PDT ---
I think this is unexpected for most of D users, but AFAIK, current compiler implementation (and Walter) intents this behavior. So I honestly mark this as 'enhancement'.

Forum discussion: http://forum.dlang.org/thread/klc5r7$3c4$1@digitalmars.com

This program:

import std.stdio;
void foo(bool b) { writeln("bool"); }
void foo(long l) { writeln("long"); }
void main()
{
    foo(0);
    foo(1);
    foo(2);
}

Prints:

bool
bool
long

Integer literal 0 and 1 prefer 'bool' version than 'long' version.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999



--- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> 2013-04-27 11:24:52 PDT ---
In here, following mechanism would work for overload resolution.

0. Integer literal 0 and 1 have `int` type, and it does not exactly match to
bool and long.
1. bool is regarded as an integer type which has the value 0 or 1.
2. Integer literal 0 and 1 matches to bool with Value Range Propagation (VRP).
3. In general, long values don't match to bool type, but bool values match to
long type. So, foo(bool) is more specialized than foo(long)

Finally:
- foo(0) and foo(1) satisfy all of above conditions, so match to foo(bool).
- foo(2) does not satisfy #2, then matches to foo(long).

This is a *designed* behavior, but most D users would expect that integer literal value prefers integer overload version. From the user's view, this behavior is *unnatural*.

In D, if function arguments match to two or more functions, the ambiguity would
be resolved with "partial ordering rule". In above, #3 is corresponding to
that.
To make the overload resolution mechanism more natural, I think we need to add
a special rule there. That is:

  In partial ordering resolution, bool parameter is treated as less specialized
  than other integer types (byte, ubyte, short, ushort, int, uint, long, ulong,
  char, wchar, dchar).

The bool literals 'true' and 'false' always don't match to other integer types, so the 'special case' does not affect to other existing overload resolution result IMO.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999


Kenji Hara <k.hara.pg@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull


--- Comment #2 from Kenji Hara <k.hara.pg@gmail.com> 2013-04-27 11:41:25 PDT ---
https://github.com/D-Programming-Language/dmd/pull/1942

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999


Walter Bright <bugzilla@digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bugzilla@digitalmars.com


--- Comment #3 from Walter Bright <bugzilla@digitalmars.com> 2013-04-27 12:29:50 PDT ---
I do not agree with this enhancement. First off, making special cases for partial ordering takes a simple, straightforward idea and turns it into a potential morass of conflicting cases that we'll be stuck with forever. Secondly, the only issue here is whether '1' should be implicitly convertible to 'bool'.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999



--- Comment #4 from Kenji Hara <k.hara.pg@gmail.com> 2013-04-27 13:23:21 PDT ---
Walter, I can understand your concern. But I think it would not be so big. Because the possibility of extending basic type set is not so much in the future.

Keeping language spec simple is necessary, but also reduce special rule for humans is also important. This is a much rare case that is the mismatch between simple rule and natural behavior for human. Fixing this issue would be valuable for many D users.

Logically 'true' and  'false' are not related to any integer values. Although it is widely known and used, considering boolean type as a kind of specialized integer type is not general - it is implementation detail. At least it comes from C language. In old ages, boolean type had not been supported properly in many programming languages, but today, languages which not supporting it would not regarded as useful. D is a modern programming language, so more proper behavior for boolean type is necessary.

As one of its goal, D should aim the successor of C. Therefore, we cannot drop
the implicit conversion between bool and other integer types which inherited
from C.
But this problem behavior is definitely unnatural for many programmers, and
would enforce to study bad know-how for them. Loosing future users for the
compiler simplicity is not good decision. Of course, balance is necessary
there, but I think this is necessary complexity.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 27, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999


Martin Nowak <code@dawg.eu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |code@dawg.eu


--- Comment #5 from Martin Nowak <code@dawg.eu> 2013-04-27 15:29:18 PDT ---
I can't come up with a use-case for '1' to bool conversion.
We already deviate from C++ as there is no implicit integral to bool
conversion.

bool b = 0;                 // implicit, questionable
bool b = 1;                 // implicit, questionable
bool b = 3;                 // error
bool b = int_val;           // error

bool b = cast(bool)int_val; // explicit

int i = false;              // implicit
int i = true;               // implicit
int i = bool_val;           // implicit

int i = cast(int)bool_val;  // explicit

The if-condition is handled as explicit cast(bool)expr right?

if (0) {}                   // explicit
if (int_val) {}             // explicit

Now one thing that worries me is that we already had a similar discussion with short/long overloads.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 28, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999


Jonathan M Davis <jmdavisProg@gmx.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jmdavisProg@gmx.com


--- Comment #6 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-04-27 20:43:01 PDT ---
If you simply made it so that integer literals didn't implicitly convert to bool, that would solve this particular problem. There's really no need to have them implicitly convert to bool as that's what true and false are for. But it _would_ mean that integer literals behaved differently from actual integers (though I am firmly in the camp who thinks that integers shouldn't implicitly convert to bool in the first place).

Another alternative would be to simply remove bool from Value Range Propagation, as it really doesn't help with bool at all. It _would_ be another special case, but it would be a fairly simple one, and neither of these suggestions require special casing overloads, just implicit conversions of integer literals.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 28, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999



--- Comment #7 from Martin Nowak <code@dawg.eu> 2013-04-28 04:05:07 PDT ---
(In reply to comment #6)
> If you simply made it so that integer literals didn't implicitly convert to bool, that would solve this particular problem. There's really no need to have them implicitly convert to bool as that's what true and false are for.

That would solve the problem and I don't see any drawback.

> But it _would_ mean that integer literals behaved differently from actual integers (though I am firmly in the camp who thinks that integers shouldn't implicitly convert to bool in the first place).
>

Integers do NOT implicitly convert to bool (see comment 5), but they can be used as http://dlang.org/statement.html#IfCondition which is kind of an explicit cast.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 28, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999



--- Comment #8 from Jonathan M Davis <jmdavisProg@gmx.com> 2013-04-28 06:48:32 PDT ---
> Integers do NOT implicitly convert to bool (see comment 5)

You're right. In the general case, they don't, but VPR makes it so that it can happen (and not necessarily just with literals), whereas if bool were strongly typed, it would _never_ happen. if and loop conditions are a different beast entirely, because they invisibly insert explicit casts, which I don't see as a problem. But I don't think that integral values should ever implicitly convert to bool or vice versa.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
April 29, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9999



--- Comment #9 from Don <clugdbug@yahoo.com.au> 2013-04-29 01:19:47 PDT ---
I don't have strong feelings about this, but I don't know how to defend the current behaviour.

Implicit conversion from int to bool is indeed rather odd. Do we really need it? Initially, literal 0 and 1 sound like acceptable ways of writing 'false' and 'true', but constant folding makes it much harder to justify.

foo( 8 - 7 );   // matches bool rather than long!

Long ago, D had a 'bit' type which was a 1-bit integer. It was replaced by
'bool'.  I think this is an odd case where D still has 'bit' semantics.
IE, bool _used to be_ an integer. It isn't any more. Perhaps we didn't go quite
far enough in replacing 'bit'.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2