Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Walter Bright via Digitalmars-d-announce

On 11/13/2018 8:37 PM, Isaac S. wrote:
It probably depends on where someone is from (asinine isn't considered a big 
insult where I live [rural US]).


Regardless of that, I will admit I did overstep (especially in calling Walter 
ignorant) and so I do apologize to Walter (I'm sorry that sounds in-sincere, I 
don't know how to properly apologize in text-form).


Thank you. I gladly accept.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Walter Bright via Digitalmars-d-announce

On 11/13/2018 8:49 PM, Jonathan M Davis wrote:

Not AFAIK, but calling someone or something extremely stupid or foolish is
almost always a terrible idea in a professional discussion (or pretty much
any discussion that you want to be civil) - especially if it can be
interpreted as calling the person stupid or foolish. That's just throwing
insults around. If an idea or decision is bad, then it should be shown as to
why it's bad, and if it is indeed a terrible idea, then the arguments
themselves should make that obvious without needing to throw insults around.

It's not always easy to avoid calling ideas stupid when you get emotional
about something, but the stronger the language used, the more likely it is
that you're going to get a strong emotional response out of the other person
rather than a logical, reasoned discussion that can come to a useful
conclusion rather than a flame war, and asinine is a pretty strong word.
It's the sort of word that's going to tend to get people mad and insulted
rather than help with a logical argument in any way - which is why Walter
called in unprofessional.


Exactly right.

It's not that I'm angry about this (I'm not), I've been around too long to get 
annoyed at this sort of thing. I'm pointing out that using such tactics will 
produce the following reactions:


1. professionals (i.e. people that matter) will ignore you

2. the recipient will get angry with you, will go out of his way to refuse to 
acknowledge your position, and will entrench himself deeper in his position


3. discourage professionals (i.e. people that matter) from participating in the 
forums


4. you'll find yourself interacting solely with other egg-throwers, 
accomplishing nothing


None of these are a desirable result.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Nicholas Wilson via Digitalmars-d-announce

On Wednesday, 14 November 2018 at 06:56:12 UTC, aliak wrote:
On Tuesday, 13 November 2018 at 09:17:51 UTC, Walter Bright 
wrote:

[...]


Ok, thanks!

[...]


Bummer. At least if this enum : int case is fixed that doesn't 
seem like it's hard to work out in my head at least - but I 
guess I'm missing some edge case maybe, but I can't figure it 
out.


Pus, it seems to work as "expected" with alias this. So I kinda 
wonder what reasons there could be to not make it work as 
expected for other scenarios.


struct B {
enum A : int { a }
alias b = A.a;
alias b this;
}

void f(short) {}
void f(int) {}

f(B()); // does what anyone would expect


Hahaha! That is hilarious! for the curious 
https://run.dlang.io/is/fqlllS


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread aliak via Digitalmars-d-announce

On Tuesday, 13 November 2018 at 09:17:51 UTC, Walter Bright wrote:

On 11/13/2018 12:23 AM, aliak wrote:

Doesn't the above miss a step, and wouldn't it be:

1) A.a => 
2) A.a => 



So basically for the f(short) path you have 3 steps instead of 
2 for the f(int) path.


So does it matter how many implicit conversions need to happen 
before D stops trying? Or is it basically convert as long as 
you can? Does D actually do a "find the shortest path via 
implicit conversions to an overload" algorithm?


It is not a shortest path algorithm. It's simply the enum is 
converted to the base type and the base type is matched against 
the parameter type.


Ok, thanks!



One could have  be treated as 
"better than" , and 
it sounds like a good idea, but even C++, not known for 
simplicity, tried that and had to abandon it as nobody could 
figure it out once the code examples got beyond trivial 
examples.


Interesting. This seems simpler intuitively (shorter path, 
pick it), so I'm wondering if there're any links you can point 
to that describe what these problems were?


No, I simply remember the discussions about it in the early 
90's. Yes, it seems to intuitively make sense, but if you look 
at real C++ code and try to figure it out, it's a nightmare. 
There can also be multiple paths of conversions, and loops in 
those paths. There's a quadratic problem when there are 
multiple parameters.


Bummer. At least if this enum : int case is fixed that doesn't 
seem like it's hard to work out in my head at least - but I guess 
I'm missing some edge case maybe, but I can't figure it out.


Pus, it seems to work as "expected" with alias this. So I kinda 
wonder what reasons there could be to not make it work as 
expected for other scenarios.


struct B {
enum A : int { a }
alias b = A.a;
alias b this;
}

void f(short) {}
void f(int) {}

f(B()); // does what anyone would expect



Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Isaac S. via Digitalmars-d-announce

On Wednesday, 14 November 2018 at 04:37:38 UTC, Isaac S. wrote:
On Wednesday, 14 November 2018 at 04:27:29 UTC, Nicholas Wilson 
wrote:
asinine, adjective: extremely stupid or foolish. Is there some 
additional connotation I am missing on this living 
(comparatively) in the middle of nowhere? (Genuine question.)


It probably depends on where someone is from (asinine isn't 
considered a big insult where I live [rural US]).


And to clarify what I meant by asinine: issue 10560 being the 
correct behavior is that. I was not meaning to call Walter 
extremely foolish (although now I can see how it can be 
interpreted as that and if he took it that way: I'm sorry).


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Jonathan M Davis via Digitalmars-d-announce
On Tuesday, November 13, 2018 9:27:29 PM MST Nicholas Wilson via 
Digitalmars-d-announce wrote:
> On Wednesday, 14 November 2018 at 04:24:20 UTC, Jonathan M Davis
>
> wrote:
> > Given how strong the negative response is to this and how
> > incomprenhensible a number of us find the reasoning behind how
> > bool functions in some scenarios, Walter probably does need to
> > sit back and think about this, but using words like asinine is
> > pretty much always uncalled for in a professional discussion. I
> > can very much understand Isaac's frustration, but making
> > statements like that really is the sort of thing that comes
> > across as attacking the poster and is going to tend to result
> > in folks not listening to your arguments anymore, even if
> > they're well-reasoned and logical. It's already hard enough to
> > convince people when your arguments are solid without getting
> > anything into the mix that could come across as insulting.
> >
> > - Jonathan M Davis
>
> asinine, adjective: extremely stupid or foolish. Is there some
> additional connotation I am missing on this living
> (comparatively) in the middle of nowhere? (Genuine question.)

Not AFAIK, but calling someone or something extremely stupid or foolish is
almost always a terrible idea in a professional discussion (or pretty much
any discussion that you want to be civil) - especially if it can be
interpreted as calling the person stupid or foolish. That's just throwing
insults around. If an idea or decision is bad, then it should be shown as to
why it's bad, and if it is indeed a terrible idea, then the arguments
themselves should make that obvious without needing to throw insults around.

It's not always easy to avoid calling ideas stupid when you get emotional
about something, but the stronger the language used, the more likely it is
that you're going to get a strong emotional response out of the other person
rather than a logical, reasoned discussion that can come to a useful
conclusion rather than a flame war, and asinine is a pretty strong word.
It's the sort of word that's going to tend to get people mad and insulted
rather than help with a logical argument in any way - which is why Walter
called in unprofessional.

- Jonathan M Davis





Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Nicholas Wilson via Digitalmars-d-announce

On Wednesday, 14 November 2018 at 04:33:23 UTC, Isaac S. wrote:
On Wednesday, 14 November 2018 at 04:27:05 UTC, Walter Bright 
wrote:
There have been various attempts over the years to "fix" 
various things in the D matching system by adding "just one 
more" match level. I've rejected all of them, because things 
that look simple and obvious with trivial examples tend to 
sink in a swamp with the dirty reality of the rather vast 
number of types and conversions that D supports. This happens 
in C++, and what people tend to do is just throw up their 
hands and hackishly add in more overloads until they get the 
result they want.


The thing is, this isn't a new match level. Rather than the 
enum implicitly casting to its literal (I'm hoping I'm using 
the correct word here) I'm proposing it implicitly cast to its 
typed literal (Instead of A.a implicitly converting to 0, it 
converts to int(0)). This would mean it would match the int 
since its a direct match.


The water is already somewhat murky here, the magic enums 
`__c_long` & friends already do some of this, but array of them 
don't (which I'm going to fix in 
https://github.com/dlang/dmd/pull/8950 as its needed to make 
__c_wchar_t actually useful). Extending this to all enums would 
probably do the trick.



enum implicitly casting to its literal


memory type is what the compiler calls it.



Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Isaac S. via Digitalmars-d-announce
On Wednesday, 14 November 2018 at 04:27:29 UTC, Nicholas Wilson 
wrote:
asinine, adjective: extremely stupid or foolish. Is there some 
additional connotation I am missing on this living 
(comparatively) in the middle of nowhere? (Genuine question.)


It probably depends on where someone is from (asinine isn't 
considered a big insult where I live [rural US]).


Regardless of that, I will admit I did overstep (especially in 
calling Walter ignorant) and so I do apologize to Walter (I'm 
sorry that sounds in-sincere, I don't know how to properly 
apologize in text-form).


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Isaac S. via Digitalmars-d-announce
On Wednesday, 14 November 2018 at 04:27:05 UTC, Walter Bright 
wrote:
There have been various attempts over the years to "fix" 
various things in the D matching system by adding "just one 
more" match level. I've rejected all of them, because things 
that look simple and obvious with trivial examples tend to sink 
in a swamp with the dirty reality of the rather vast number of 
types and conversions that D supports. This happens in C++, and 
what people tend to do is just throw up their hands and 
hackishly add in more overloads until they get the result they 
want.


The thing is, this isn't a new match level. Rather than the enum 
implicitly casting to its literal (I'm hoping I'm using the 
correct word here) I'm proposing it implicitly cast to its typed 
literal (Instead of A.a implicitly converting to 0, it converts 
to int(0)). This would mean it would match the int since its a 
direct match.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Nicholas Wilson via Digitalmars-d-announce
On Wednesday, 14 November 2018 at 04:24:20 UTC, Jonathan M Davis 
wrote:
Given how strong the negative response is to this and how 
incomprenhensible a number of us find the reasoning behind how 
bool functions in some scenarios, Walter probably does need to 
sit back and think about this, but using words like asinine is 
pretty much always uncalled for in a professional discussion. I 
can very much understand Isaac's frustration, but making 
statements like that really is the sort of thing that comes 
across as attacking the poster and is going to tend to result 
in folks not listening to your arguments anymore, even if 
they're well-reasoned and logical. It's already hard enough to 
convince people when your arguments are solid without getting 
anything into the mix that could come across as insulting.


- Jonathan M Davis


asinine, adjective: extremely stupid or foolish. Is there some 
additional connotation I am missing on this living 
(comparatively) in the middle of nowhere? (Genuine question.)


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Walter Bright via Digitalmars-d-announce

On 11/13/2018 7:12 PM, Isaac S. wrote:
why should an enum 
not convert to its declared type, rather than blindly using its literal value. 
Just using the literal value discards the secondary-type information the 
programmer had given it.


D has the following match levels:

1. exact
2. conversion to const
3. implicit conversion
4. no match

C++, on the other hand, has a long list of match levels, which nobody remembers, 
and yet still causes problems (see Scott Meyers). The conversion of `A` to `int` 
already drops it to match level 3, from which it will not rise. I.e. the second 
level being an exact match with `int` does not help.


The further disambiguation between multiple matching functions is done using 
partial ordering. This has NOTHING to do with the arguments. It just looks at:


   f(int)
   f(short)

and picks f(short) because it is more specialized. This partial ordering is what 
C++ does with template functions. It is simpler and more robust than the older 
more primitive "match level" system C++ uses for non-template functions. I 
suspect that if C++ were to do a "do-over" with function overloading, it would 
use partial ordering instead of match levels.


Interestingly, the match level and partial ordering methods almost always 
produce the same results.


There have been various attempts over the years to "fix" various things in the D 
matching system by adding "just one more" match level. I've rejected all of 
them, because things that look simple and obvious with trivial examples tend to 
sink in a swamp with the dirty reality of the rather vast number of types and 
conversions that D supports. This happens in C++, and what people tend to do is 
just throw up their hands and hackishly add in more overloads until they get the 
result they want.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Jonathan M Davis via Digitalmars-d-announce
On Tuesday, November 13, 2018 8:47:01 PM MST Nicholas Wilson via 
Digitalmars-d-announce wrote:
> On Wednesday, 14 November 2018 at 03:02:48 UTC, Walter Bright
>
> wrote:
> > On 11/13/2018 3:50 PM, Isaac S. wrote:
> >> is asinine and ignorant.
> >
> > Some friendly advice - nobody is going to pay serious attention
> > to articles that sum up with such unprofessional statements.
> > Continuing the practice will just result in the moderators
> > removing them.
>
> I read the first adjective as a statement of opinion about your
> reasoning for rejection and the second about the way you have
> dismissed the opinions of others, neither of which are uncalled
> for and certainly not unprofessional.
>
> You would do well to think about that before you post further.

Given how strong the negative response is to this and how incomprenhensible
a number of us find the reasoning behind how bool functions in some
scenarios, Walter probably does need to sit back and think about this, but
using words like asinine is pretty much always uncalled for in a
professional discussion. I can very much understand Isaac's frustration, but
making statements like that really is the sort of thing that comes across as
attacking the poster and is going to tend to result in folks not listening
to your arguments anymore, even if they're well-reasoned and logical. It's
already hard enough to convince people when your arguments are solid without
getting anything into the mix that could come across as insulting.

- Jonathan M Davis





Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Nicholas Wilson via Digitalmars-d-announce
On Wednesday, 14 November 2018 at 03:02:48 UTC, Walter Bright 
wrote:

On 11/13/2018 3:50 PM, Isaac S. wrote:

is asinine and ignorant.


Some friendly advice - nobody is going to pay serious attention 
to articles that sum up with such unprofessional statements. 
Continuing the practice will just result in the moderators 
removing them.


I read the first adjective as a statement of opinion about your 
reasoning for rejection and the second about the way you have 
dismissed the opinions of others, neither of which are uncalled 
for and certainly not unprofessional.


You would do well to think about that before you post further.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Isaac S. via Digitalmars-d-announce
On Wednesday, 14 November 2018 at 03:02:48 UTC, Walter Bright 
wrote:

On 11/13/2018 3:50 PM, Isaac S. wrote:

is asinine and ignorant.


Some friendly advice - nobody is going to pay serious attention 
to articles that sum up with such unprofessional statements. 
Continuing the practice will just result in the moderators 
removing them.


I'm sorry that it is unkind but I came to D because I found it to 
be an extremely well-designed language. Seeing something like 
10560 be declared as "correct" is really disheartening because 
it's _obviously_ a design flaw (and should thus be fixed).


Regardless of my unprofessional attitude (I do apologize; I 
normally try to be professional but something like this is really 
irritating): why should an enum not convert to its declared type, 
rather than blindly using its literal value. Just using the 
literal value discards the secondary-type information the 
programmer had given it.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Walter Bright via Digitalmars-d-announce

On 11/13/2018 3:50 PM, Isaac S. wrote:

is asinine and ignorant.


Some friendly advice - nobody is going to pay serious attention to articles that 
sum up with such unprofessional statements. Continuing the practice will just 
result in the moderators removing them.




Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Isaac S. via Digitalmars-d-announce
On Wednesday, 14 November 2018 at 02:45:38 UTC, Walter Bright 
wrote:
In your articles, it is crucial to understand the difference 
between a manifest constant of type `int` and one of type `A`.


Still doesn't change the fact that a typed enum should convert to 
its own type first (rather than blindly using the literal).


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Walter Bright via Digitalmars-d-announce

On 11/13/2018 3:29 PM, Rubn wrote:

enum : int { a = 127 }


To reiterate, this does not create an anonymous enum type. 'a' is typed as 
'int'. Technically,


`a` is a manifest constant of type `int` with a value of `127`.

> enum A : int { a = 127 }

`a` is a manifest constant of type `A` with a value of `127`.

Remember that `A` is not an `int`. It is implicitly convertible to an integer 
type that its value will fit in (Value Range Propagation). Other languages do 
not have VRP, so expectations from how those languages behave do not apply to D. 
VRP is a nice feature, it is why:


enum s = 100; // typed as int
enum t = 300; // also typed as int
ubyte u = s + 50; // works, no cast required,
  // although the type is implicitly converted
ubyte v = t + 50; // fails

In your articles, it is crucial to understand the difference between a manifest 
constant of type `int` and one of type `A`.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Neia Neutuladh via Digitalmars-d-announce
On Wed, 14 Nov 2018 00:43:54 +, Rubn wrote:
> I wonder what these examples are? What did C++ do instead, cause
> something tells me it didn't do what D is doing. An enum in C++ doesn't
> call different function overloads based on the constant value.

Long long and unsigned long long give an ambiguous overload error. 
Unsigned int uses the unsigned int overload. Everything else uses the int 
overload.

Test code:

```
#include 
#include 
using namespace std;
void foo(bool c) { cout << "bool " << c << endl; }
void foo(unsigned char c) { cout << "unsigned char " << c << endl; }
void foo(char c) { cout << "char " << c << endl; }
void foo(int c) { cout << "int " << c << endl; }
void foo(unsigned int c) { cout << "unsigned int " << c << endl; }
void foo(long long c) { cout << "long long " << c << endl; }
void foo(unsigned long long c) { cout << "unsigned long long " << c << 
endl; }
enum Bool : bool { b = 1 };
enum Char : char { c = CHAR_MAX };
enum UChar : unsigned char { d = UCHAR_MAX };
enum Short : short { e = SHRT_MAX };
enum UShort : unsigned short { f = USHRT_MAX };
enum Int : int { g = INT_MAX };
enum UInt : unsigned int { h = UINT_MAX };
enum LongLong : long long { i = LLONG_MAX };
enum ULongLong : unsigned long long { j = ULLONG_MAX };
int main(int argc, char** argv)
{
foo(b);
foo(c);
foo(d);
foo(e);
foo(f);
foo(g);
foo(h);
//foo(i);
//foo(j);
}
```

Output:
int 1
int 127
int 255
int 32767
int 65535
int 2147483647
unsigned int 4294967295


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Rubn via Digitalmars-d-announce

On Monday, 12 November 2018 at 22:07:39 UTC, Walter Bright wrote:
One could have  be treated as 
"better than" , and 
it sounds like a good idea, but even C++, not known for 
simplicity, tried that and had to abandon it as nobody could 
figure it out once the code examples got beyond trivial 
examples.


I wonder what these examples are? What did C++ do instead, cause 
something tells me it didn't do what D is doing. An enum in C++ 
doesn't call different function overloads based on the constant 
value.


The trivial examples with D's current implementation aren't even 
understood by most people it seems like.





Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Isaac S. via Digitalmars-d-announce

On Monday, 12 November 2018 at 22:07:39 UTC, Walter Bright wrote:

int f(short s) { return 1; }
int f(int i) { return 2; }

enum : int { a = 0 }
enum A : int { a = 0 }

pragma (msg, f(a));   // calls f(int)
pragma (msg, f(A.a)); // calls f(short)

*snip*

So f(short) is selected, because the "Most Specialized" 
function is selected when there is an ambiguous match.


Note: the "most specialized" partial ordering rules are 
independent of the arguments being passed.


Walter, this still doesn't change the fact any _reasonable_ 
programmer would expect foo(A.a) to, in a way, convert to 
foo(int(0)) because that keeps the type information rather than 
ignoring the type information completely and just putting the 
literal value in like it was foo(0).


Honestly, while I (and most others in the community) wanted 
DIP1015, I'm not going to sweat it (even given the illogical 
reason for refusing it), but marking issue 10560 as "correct 
behavior" is asinine and ignorant.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread NoMoreBugs via Digitalmars-d-announce
On Monday, 12 November 2018 at 10:05:09 UTC, Jonathan M Davis 
wrote:


*sigh* Well, I guess that's the core issue right there. A lot 
of us would strongly disagree with the idea that bool is an 
integral type and consider code that treats it as such as 
inviting bugs. We _want_ bool to be considered as being 
completely distinct from integer types. The fact that you can 
ever pass 0 or 1 to a function that accepts bool without a cast 
is a problem in and of itself. But it doesn't really surprise 
me that Walter doesn't agree on that point, since he's never 
agreed on that point, though I was hoping that this DIP was 
convincing enough, and its failure is certainly disappointing.


- Jonathan M Davis


Well, I think the DIP was too narrow in its thinking - by 
restricting itself to bool.


There is a bigger picture, which is more important.

Fact 1 - Implicit conversions are nothing more than a weakening 
of type safety.


Fact 2 - A weakening of type safety can (and often does) 
contribute to bugs.


If anyone wants to dispute facts 1 and 2, please go ahead.

Ideally, a 'modern' programming language would have addressed 
these two facts already.


(i.e Rust).

Unfortunately, D is very much tied to its C/C++ heritage, so 
'modernizing' can be painful.


D still can still modernize though, without breaking backward 
compatibility, by providing 'an option' for the programmer to 
explicitly declare their desire for greater type safety - and not 
just with bools.


Fact 3 - Everyone will benefit from greater type safety
 (disputable - at least for those that prefer convenience 
over correctness).


There is just no reason that I can see, why any modern 
programming language should allow my bool to be implicitly 
converted to a char, int, short, byte, long, double, 
float.and god knows what else...and certainly not without 
some warning.


Additionally, it really troubles me to see a programming language 
wanting to strut itself on the worlds stage, that can (and worst, 
just will) do things like that - no warning, no option to prevent 
it.




Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Rubn via Digitalmars-d-announce

On Monday, 12 November 2018 at 22:07:39 UTC, Walter Bright wrote:

On 11/12/2018 12:34 PM, Neia Neutuladh wrote:

Tell me more about this "consistency".


int f(short s) { return 1; }
int f(int i) { return 2; }

enum : int { a = 0 }
enum A : int { a = 0 }

pragma (msg, f(a));   // calls f(int)
pragma (msg, f(A.a)); // calls f(short)

I.e. it's consistent.

Here's how it works:

f(a): `a` is a manifest constant of type `int`, and `int` is an 
exact match for f(int), and f(short) requires an implicit 
conversion. The exact match of f(int) is better.


f(A.a): `a` is an enum of type `A`. `A` gets implicitly 
converted to `int`. The `int` then gets exact match to f(int), 
and an implicit match to f(short). The sequence of conversions 
is folded into one according to:


=> conversion>
  => conversion>


Both f(int) and f(short) match, because implicit conversions 
rank the same. To disambiguate, f(short) is pitted against 
f(int) using partial ordering rules,

which are:

Can a short be used to call f(int)? Yes.
Can an int be used to call f(short)? No.

So f(short) is selected, because the "Most Specialized" 
function is selected when there is an ambiguous match.


Note: the "most specialized" partial ordering rules are 
independent of the arguments being passed.


---

One could have  be treated as 
"better than" , and 
it sounds like a good idea, but even C++, not known for 
simplicity, tried that and had to abandon it as nobody could 
figure it out once the code examples got beyond trivial 
examples.


This just seems like a bug to me. Any sane human being would 
expect all these functions to output the same thing. But it 
entirely depends on how you use it.


import std.stdio;

void foo(byte v) { writeln("byte ", v); }
void foo(int v) { writeln("int ", v); }

enum : int { a = 127 }
enum A : int { a = 127 }

void main()
{
A v = A.a;
foo(A.a); // byte 127 < These two are probably the best 
showcase of what's wrong
foo(v);   // int 127  < same values being passed with same 
type but different result


foo(a);   // int 127
foo(127); // int 127
}

https://run.dlang.io/is/aARCDo



Re: DMD backend now in D

2018-11-13 Thread Joakim via Digitalmars-d-announce

On Tuesday, 13 November 2018 at 20:42:00 UTC, Temtaime wrote:
On Monday, 12 November 2018 at 02:37:54 UTC, Walter Bright 
wrote:

On 11/11/2018 3:58 PM, Mike Franklin wrote:

This is a significant milestone.  Congratulations, Walter!


Many people helped out with this, too.

There are still a few .c files in 
https://github.com/dlang/dmd/tree/master/src/dmd/backend, so 
what's the significance of those?


tk.c
fp.c
os.c
strtold.c
tk/mem.c

These could be converted too, but are independent from 
everything else and hardly seem worth the bother. Sebastian 
has a PR for os.cd.



Will there ever be a day when we no longer need a C/C++ 
compiler to build DMD?


Sure.



No, as phobos is dependent on C libraries such as a zlib for 
example.


DMD doesn't use Phobos.


Also D is dependent on libc.


It's possible to reimplement the subset of libc functions that 
DMD depends on in D.


Re: DMD backend now in D

2018-11-13 Thread Temtaime via Digitalmars-d-announce

On Monday, 12 November 2018 at 02:37:54 UTC, Walter Bright wrote:

On 11/11/2018 3:58 PM, Mike Franklin wrote:

This is a significant milestone.  Congratulations, Walter!


Many people helped out with this, too.

There are still a few .c files in 
https://github.com/dlang/dmd/tree/master/src/dmd/backend, so 
what's the significance of those?


tk.c
fp.c
os.c
strtold.c
tk/mem.c

These could be converted too, but are independent from 
everything else and hardly seem worth the bother. Sebastian has 
a PR for os.cd.



Will there ever be a day when we no longer need a C/C++ 
compiler to build DMD?


Sure.



No, as phobos is dependent on C libraries such as a zlib for 
example.

Also D is dependent on libc.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Neia Neutuladh via Digitalmars-d-announce
On Tue, 13 Nov 2018 17:53:27 +, 12345swordy wrote:
> Ok, now that has got to be a bug. If you explicit cast the number to an
> integer then you expect the overload function with int to be called.
> 
> -Alex

...my mistake, I can't reproduce that anymore. Pretend I didn't say 
anything.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Neia Neutuladh via Digitalmars-d-announce
On Tue, 13 Nov 2018 09:46:17 -0500, Steven Schveighoffer wrote:
> Maybe the biggest gripe here is that enums don't prefer their base types
> over what their base types convert to. In the developer's mind, the
> conversion is:
> 
> A => int => (via VRP) short
> 
> which seems more complex than just
> 
> A => int

It affects explicit casts too:

void foo(short a) { writefln("short %s", a); }
void foo(int a) { writefln("int %s", a); }
foo(cast(int)0);  // prints: short 0

In order to force the compiler to choose a particular overload, you either 
need to assign to a variable or use a struct with alias this.

C++, Java, and C# all default to int, even for bare literals that fit into 
bytes or shorts, and let you use casts to select overloads.

C++ has some weird stuff where an enum that doesn't fit into an int is an 
equal match for all integer types:

void foo(unsigned long long);
void foo(short);
enum A : unsigned long long { a = 2 };
foo(a);  // ambiguous!

But if you just have an unsigned long long that's not in an enum, it only 
matches the unsigned long long overload.

In C#, if you define multiple implicit casts from a type that match 
multiple overloads, the compiler prefers the smallest matching type, and 
it prefers signed over unsigned types. However, for this situation to come 
up at all, you need to define implicit conversions for multiple numeric 
types, so it's not directly comparable.

Anyway, VRP overload selection hit me yesterday (accepts-invalid sort): I 
was calling a function `init_color(short, short, short, short)` with a 
bunch of things that I explicitly casted to int. Tried wrapping it in a 
function and I discovered the compiler had implicitly casted int to short. 
Not the end of the world, but I thought a cast would set the type of the 
expression (instead of just, in this case, truncating floating point 
numbers).


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread 12345swordy via Digitalmars-d-announce
On Tuesday, 13 November 2018 at 17:50:20 UTC, Neia Neutuladh 
wrote:

On Tue, 13 Nov 2018 09:46:17 -0500, Steven Schveighoffer wrote:
Maybe the biggest gripe here is that enums don't prefer their 
base types over what their base types convert to. In the 
developer's mind, the conversion is:


A => int => (via VRP) short

which seems more complex than just

A => int


It affects explicit casts too:

void foo(short a) { writefln("short %s", a); }
void foo(int a) { writefln("int %s", a); }
foo(cast(int)0);  // prints: short 0

Ok, now that has got to be a bug. If you explicit cast the number 
to an integer then you expect the overload function with int to 
be called.


-Alex



Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Steven Schveighoffer via Digitalmars-d-announce

On 11/13/18 11:26 AM, Chris M. wrote:

On Monday, 12 November 2018 at 09:45:14 UTC, Mike Parker wrote:
DIP 1015, "Deprecation and removal of implicit conversion from integer 
and character literals to bool, has been rejected, primarily on the 
grounds that it is factually incorrect in treating bool as a type 
distinct from other integral types.


The TL;DR is that the DIP is trying to change behavior that is working 
as intended.


From Example A in the DIP:

    bool b = 1;

This works because bool is a "small integral" with a range of 0..1. 
The current behavior is consistent with all other integrals.


From Example B in the DIP:

```
int f(bool b) { return 1; }
int f(int i) { return 2; }

enum E : int
{
    a = 0,
    b = 1,
    c = 2,
}
```

Here, f(a) and f(b) call the bool overload, while f(c) calls the int 
version. This works because D selects the overload with the tightest 
conversion. This behavior is consistent across all integral types. 
Replace bool with ubyte and f(a), f(b) would both call the ubyte 
version. The same holds for the DIP's Example C.


Walter and Andrei left the door open to change the overload behavior 
for *all* integral types, with the caveat that it's a huge hurdle for 
such a DIP to be accepted. It would need a compelling argument.


You can read a few more details in the summary I appended to the DIP:

https://github.com/dlang/DIPs/blob/master/DIPs/rejected/DIP1015.md#formal-assessment 



Thanks to Mike Franklin for sticking with the process to the end.


I was going to write something up about how you can't do arithmetic on 
bool types therefore they aren't integral, but I tested and realized D 
allows this (i.e. bool + bool, bool * bool). Still that seems 
nonsensical, so I guess my question what is the definition of an 
integral type and how does bool fit?


What it's doing is promoting false to an integer 0 and true to an 
integer 1. These work just like all the other integer promotion rules.


Interestingly enough, since bool can only be promoted to 0 or 1, bool * 
bool can be assigned back to a bool, but bool + bool can't be assigned 
back to a bool unless you cast. But don't expect the addition to behave 
as other integers do, as true + true == 2, which then casts to true.


-Steve


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Chris M. via Digitalmars-d-announce

On Monday, 12 November 2018 at 09:45:14 UTC, Mike Parker wrote:
DIP 1015, "Deprecation and removal of implicit conversion from 
integer and character literals to bool, has been rejected, 
primarily on the grounds that it is factually incorrect in 
treating bool as a type distinct from other integral types.


The TL;DR is that the DIP is trying to change behavior that is 
working as intended.


From Example A in the DIP:

bool b = 1;

This works because bool is a "small integral" with a range of 
0..1. The current behavior is consistent with all other 
integrals.


From Example B in the DIP:

```
int f(bool b) { return 1; }
int f(int i) { return 2; }

enum E : int
{
a = 0,
b = 1,
c = 2,
}
```

Here, f(a) and f(b) call the bool overload, while f(c) calls 
the int version. This works because D selects the overload with 
the tightest conversion. This behavior is consistent across all 
integral types. Replace bool with ubyte and f(a), f(b) would 
both call the ubyte version. The same holds for the DIP's 
Example C.


Walter and Andrei left the door open to change the overload 
behavior for *all* integral types, with the caveat that it's a 
huge hurdle for such a DIP to be accepted. It would need a 
compelling argument.


You can read a few more details in the summary I appended to 
the DIP:


https://github.com/dlang/DIPs/blob/master/DIPs/rejected/DIP1015.md#formal-assessment

Thanks to Mike Franklin for sticking with the process to the 
end.


I was going to write something up about how you can't do 
arithmetic on bool types therefore they aren't integral, but I 
tested and realized D allows this (i.e. bool + bool, bool * 
bool). Still that seems nonsensical, so I guess my question what 
is the definition of an integral type and how does bool fit?


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Chris M. via Digitalmars-d-announce

On Tuesday, 13 November 2018 at 16:26:55 UTC, Chris M. wrote:

On Monday, 12 November 2018 at 09:45:14 UTC, Mike Parker wrote:

[...]


I was going to write something up about how you can't do 
arithmetic on bool types therefore they aren't integral, but I 
tested and realized D allows this (i.e. bool + bool, bool * 
bool). Still that seems nonsensical, so I guess my question 
what is the definition of an integral type and how does bool 
fit?


Addendum: definition of an integral type in Walter/Andrei's mind


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Steven Schveighoffer via Digitalmars-d-announce

On 11/12/18 4:38 PM, Walter Bright wrote:

On 11/12/2018 8:28 AM, 12345swordy wrote:
The issue that I see is unintended implicit conversation when passing 
values to functions that have both int and bool overloads.


The exact same thing happens when there are both int and short overloads.

The underlying issue is is bool a one bit integer type, or something 
special? D defines it as a one bit integer type, fitting it into the 
other integer types using exactly the same rules.


D's definition is wanting. Most integer types act differently than bool:

1. Integer types can be incremented, bool cannot
2. Integer types truncate by removing the extraneous bits, bool 
truncates to `true` for all values except 0.

3. Integer types have signed and unsigned variants, bool does not.
4. Integer types allow negation, bool does not.
5. Integer types can be used in a foreach(x; v1 .. v2), bool cannot.

It is true that bools act similarly to a 1-bit integer type in many 
cases, but only via promotion. That is, they *convert* to 1-bit 
integers, but don't behave like integers in their own type.


Regarding enums with base types, I admit I would totally expect an enum 
based on int to match an int overload over a short overload.


You don't think this is confusing to an average developer?

import std.stdio;

void foo(int x)
{
writeln("integer");
}

void foo(short x)
{
writeln("short");
}

enum A : int
{
a = 1,
b = 2,
c = 3
}

void main()
{
auto a = A.a;
foo(A.a); // case 1
foo(a);   // case 2
}

case 1 prints short, but case 2 prints integer. Both are passed the same 
value. This comes into play when using compile-time generation -- you 
are expecting the same behavior when using the same values. This is 
super-confusing.


But on the other hand, an A can ONLY be 3 or less, so why doesn't case 2 
print short? If VRP is used here, it seems lacking.


Maybe the biggest gripe here is that enums don't prefer their base types 
over what their base types convert to. In the developer's mind, the 
conversion is:


A => int => (via VRP) short

which seems more complex than just

A => int

If it is to be a special type with special rules, what about the other 
integer types? D has a lot of basic types :-)


The added value of having bool implicitly cast to integer types is 
great. I wouldn't want to eliminate that. The other way around seems of 
almost no value, except maybe to avoid extra code in the compiler.


So, I would be fine to have bool be a non-integer type that implicitly 
casts to integer for use in math or other reasons. But having 1 or 0 
implicitly cast to true or false has little value, and especially using 
it as "just another 1-bit integer", which it really isn't, has almost no 
usage.


-Steve


Re: NES emulator written in D

2018-11-13 Thread blahness via Digitalmars-d-announce

On Tuesday, 13 November 2018 at 08:24:05 UTC, Manu wrote:
A great test is to emulate an Atari2600; you'll know your 6502 
is 100%
perfect if you can play pitfall or some other complex 2600 
games ;)
I can't see how your cycle counting logic works, it looks like 
it's
missing a lot of cycles. How do you clock your scanlines 
against your

CPU?
Can you run Battletoads or Super Mario Bros? They're pretty 
sensitive

to proper timing.


Every cycle is accounted for via a memory read or write. Notice 
both memoryRead & memoryWrite call nextCycle. In nextCycle you'll 
notice after every CPU cycle the PPU gets 3 cycles (equivalent to 
1 CPU cycle) & the APU gets 1 cycle. Super Mario Bros runs fine 
but Battletoads has some issues unrelated to the CPU. It is 
highly dependent on correct sprite 0 collision detection timing. 
It's a PPU timing issue.


I'm relying on these CPU tests: 
https://wiki.nesdev.com/w/index.php/Emulator_tests. Notice one of 
the authors of one of the most extensive tests is kevtris who's 
most famous for his FPGA recreations of the NES & Super Nintendo 
for Analogue (https://www.analogue.co/). I'm pretty confident 
about the CPU being cycle accurate at least as far as the NES is 
concerned.


Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread Walter Bright via Digitalmars-d-announce

On 11/13/2018 12:23 AM, aliak wrote:

Doesn't the above miss a step, and wouldn't it be:

1) A.a => 
2) A.a => 



So basically for the f(short) path you have 3 steps instead of 2 for the f(int) 
path.


So does it matter how many implicit conversions need to happen before D stops 
trying? Or is it basically convert as long as you can? Does D actually do a 
"find the shortest path via implicit conversions to an overload" algorithm?


It is not a shortest path algorithm. It's simply the enum is converted to the 
base type and the base type is matched against the parameter type.



One could have  be treated as "better than" 
, and it sounds like a good idea, 
but even C++, not known for simplicity, tried that and had to abandon it as 
nobody could figure it out once the code examples got beyond trivial examples.


Interesting. This seems simpler intuitively (shorter path, pick it), so I'm 
wondering if there're any links you can point to that describe what these 
problems were?


No, I simply remember the discussions about it in the early 90's. Yes, it seems 
to intuitively make sense, but if you look at real C++ code and try to figure it 
out, it's a nightmare. There can also be multiple paths of conversions, and 
loops in those paths. There's a quadratic problem when there are multiple 
parameters.




Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread NoMoreBugs via Digitalmars-d-announce

On Tuesday, 13 November 2018 at 07:13:01 UTC, NoMoreBugs wrote:


You nailed it on the head.

The only sensible course of action, therefore, is to give 
programmers the option to disable implicit conversions, 
completely (or if doable, more precisely).


And while you're thinking about how to do that, can you also 
please think about how to give the programmer the option to 
enforce privacy on variable/method within a module.


Programmers just want to be able to write code that is more 
likely to be correct, than not, and have the compiler catch it 
when it's not.


You want to attract such programmers, or not?


ok...not such a great idea (the compiler switch), after I thought 
more about that idea.


but some sort of annotation, and the programmers intent could 
become *much* clearer (allowing the programmer - and those 
reading it - to better reason about the correctness of the code):


bool(this) b; // compiler not allowed to do implicit conversions 
when assigning on b
double(this) d; // compiler not allowed to do implicit 
conversions when assigning to d


class C  //(or struct)
{
 private(this) password; // compiler will not allow other code 
outside of this type,
//  (but in the same module) to directly 
access password.

}


i.e (this) is just an annotation, for saying:

"I own this type, and the type needs to stay the way it's defined 
- no exceptions".


Too much? The language could not handle it? The programmer would 
never want it?





Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement

2018-11-13 Thread aliak via Digitalmars-d-announce

On Monday, 12 November 2018 at 22:07:39 UTC, Walter Bright wrote:

On 11/12/2018 12:34 PM, Neia Neutuladh wrote:

Tell me more about this "consistency".


int f(short s) { return 1; }
int f(int i) { return 2; }

enum : int { a = 0 }
enum A : int { a = 0 }

pragma (msg, f(a));   // calls f(int)
pragma (msg, f(A.a)); // calls f(short)

I.e. it's consistent.

Here's how it works:

f(a): `a` is a manifest constant of type `int`, and `int` is an 
exact match for f(int), and f(short) requires an implicit 
conversion. The exact match of f(int) is better.


f(A.a): `a` is an enum of type `A`. `A` gets implicitly 
converted to `int`. The `int` then gets exact match to f(int), 
and an implicit match to f(short). The sequence of conversions 
is folded into one according to:


=> conversion>
  => conversion>


Doesn't the above miss a step, and wouldn't it be:

1) A.a => 
2) A.a => 



So basically for the f(short) path you have 3 steps instead of 2 
for the f(int) path.


So does it matter how many implicit conversions need to happen 
before D stops trying? Or is it basically convert as long as you 
can? Does D actually do a "find the shortest path via implicit 
conversions to an overload" algorithm?





One could have  be treated as 
"better than" , and 
it sounds like a good idea, but even C++, not known for 
simplicity, tried that and had to abandon it as nobody could 
figure it out once the code examples got beyond trivial 
examples.


Interesting. This seems simpler intuitively (shorter path, pick 
it), so I'm wondering if there're any links you can point to that 
describe what these problems were?


Cheers,
- Ali




Re: NES emulator written in D

2018-11-13 Thread Manu via Digitalmars-d-announce
On Mon, Nov 12, 2018 at 10:30 PM blahness via Digitalmars-d-announce
 wrote:
>
> On Tuesday, 13 November 2018 at 05:59:52 UTC, Manu wrote:
> >
> > Nice work.
> >
> > Oh wow, this is pretty rough!
> > ```
> > void createTable() {
> >   this.table = [
> > , , , , ,
> > ,
> > , , , , ,
> > ,
> > , , , ,
> > ...
> > ```
> >
> > Here's one I prepared earlier:
> > https://github.com/TurkeyMan/superemu (probably doesn't work
> > with DMD from the last year or 2!) Extensible architecture,
> > supports a bunch of systems.
>
> That's an artifact from the original code which was written in
> Go. My main focus was adding missing instructions & fixing any
> timing issues. It now passes nearly every NES specific CPU
> instruction & timing test I can throw at it so I'm fairly happy
> with it. Any improvements are always welcome though.

A great test is to emulate an Atari2600; you'll know your 6502 is 100%
perfect if you can play pitfall or some other complex 2600 games ;)
I can't see how your cycle counting logic works, it looks like it's
missing a lot of cycles. How do you clock your scanlines against your
CPU?
Can you run Battletoads or Super Mario Bros? They're pretty sensitive
to proper timing.