Re: DIP 1015--Deprecation of Implicit Conversion of Int. & Char. Literals to bool--Formal Assement
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.