<html><head></head><body><div style="font-family: Verdana;font-size: 12.0px;"><div>On Tue, 27 May 2014 06:42:41 -1000<br/>
Andrei Alexandrescu via Digitalmars-d-announce<br/>
<digitalmars-d-announce@puremagic.com> wrote:<br/>
<br/>
> <a href="http://www.reddit.com/r/programming/comments/26m8hy/scott_meyers_dconf_2014_keynote_the_last_thing_d/" target="_blank">http://www.reddit.com/r/programming/comments/26m8hy/scott_meyers_dconf_2014_keynote_the_last_thing_d/</a><br/>
><br/>
> <a href="https://news.ycombinator.com/newest" target="_blank">https://news.ycombinator.com/newest</a> (search that page, if not found<br/>
> click "More" and search again)<br/>
><br/>
> <a href="https://www.facebook.com/dlang.org/posts/855022447844771" target="_blank">https://www.facebook.com/dlang.org/posts/855022447844771</a><br/>
><br/>
> <a href="https://twitter.com/D_Programming/status/471330026168651777" target="_blank">https://twitter.com/D_Programming/status/471330026168651777</a><br/>
<br/>
Fortunately, for the most part, I think that we've avoided the types of<br/>
inconsistencies that Scott describes for C++, but we do definitely have some<br/>
of our own. The ones that come to mind at the moment are:<br/>
<br/>
1. The order of the dimensions of multi-dimensional static arrays is backwards<br/>
in comparison to what most everyone expects.<br/>
<br/>
    int[4][5][6] foo;<br/>
<br/>
is the same as<br/>
<br/>
    int foo[6][5][4];<br/>
<br/>
and has the same dimensions as<br/>
<br/>
    auto bar = new int[][][](6, 5, 4);<br/>
<br/>
The reasons for it stem from the fact that the compiler reads types outward<br/>
from the variable name (which is very important to understand in C because of<br/>
its function pointer syntax but not so important in D). However, once we did<br/>
<br/>
    const(int)* foo;<br/>
<br/>
and didn't allow<br/>
<br/>
    (int)const* foo;<br/>
<br/>
I think that we threw that particular bit of consistency with C/C++ out the<br/>
window, and we really should have just made static array dimensions be read<br/>
from left-to-right.<br/>
<br/>
Unfortunately, I don't think that we can fix that at this point, because doing<br/>
so would cause silent breakage (or at minimum, would be silent until<br/>
RangeErrors were thrown at runtime).<br/>
<br/>
<br/>
2. We're inconsistent with dynamic array dimensions.<br/>
<br/>
    auto foo = new int[5];<br/>
<br/>
is the same as<br/>
<br/>
    auto foo = new int[](5);<br/>
<br/>
but once you get into multi-dimensional arrays, it's just confusing, because<br/>
<br/>
    auto foo = new int[4][5][6];<br/>
<br/>
does _not_ declare a multi-dimensional dynimac array but rather a dynamic<br/>
array of length 6 which contains a multi-dimensonal static array of dimensions<br/>
4 and 5. Instead, what you need to do is<br/>
<br/>
    auto foo = new int[][][](4, 5, 6);<br/>
<br/>
IMHO, we should have made it illegal to have dynamic array dimensions inside<br/>
of the brackets rather than the parens, but I don't know if we can change<br/>
that. It wouldn't be silent breakage, but it _would_ make it so that a lot of<br/>
existing code would be broken - especially because so many people put the<br/>
array dimensions between the brackets for single-dimension dynamic arrays.<br/>
<br/>
<br/>
3. const, immutable, and inout on the left-hand side of a function declaration<br/>
are unfortunately legal. This inevitably trips people up, because they think<br/>
that the attribute applies to the return type, when it applies to the function<br/>
itself. This is to make the function attributes consistent, because all of<br/>
the others can go on either side, but the result is that it's essentially bad<br/>
practice to ever put any attribute on the left-hand side which could apply to<br/>
the return type, because it looks like a bug. If we just made it illegal for<br/>
those attributes to go on the left, the problem would be solved, and the<br/>
result would be far less confusing and bug-prone. I think that we can make<br/>
that change with minimal breakage (since it's already bad practice to put them<br/>
no the left-hand side), but AFAIK, Walter is against the idea.<br/>
<br/>
<br/>
4. There are some cases (such as with static constructors and unittest blocks)<br/>
that the attributes have to go on the left for some reason. I don't remember<br/>
the reasons for it, but it's an inconsistency which definitely trips up even<br/>
seasoned D programmers from time to time.<br/>
<br/>
<br/>
5. The fact that pure is called pure is very problematic at this point as far<br/>
as explaining things to folks goes. We should probably consider renaming it to<br/>
something like @noglobal, but I'm not sure that that would go over very well<br/>
given the amount of breakage involved. It _does_ require a lot of explaining<br/>
though.<br/>
<br/>
<br/>
6. The situation with ranges and string is kind of ugly, with them being<br/>
treated as ranges of code points. I don't know what the correct solution to<br/>
this is, since treating them as ranges of code units promotes efficiency but<br/>
makes code more error-prone, whereas treating them as ranges of graphemes<br/>
would just cost too much. Ranges of code points is _mostly_ correct but still<br/>
incorrect and _more_ efficient than graphemes but still quite a bit less<br/>
efficient than code units. So, it's kind of like it's got the best and worst<br/>
of both worlds. The current situation causes inconsistencies with everything<br/>
else (forcing us to use isNarrowString all over the place) and definitely<br/>
requires frequent explaining, but it does prevent some classes of problems.<br/>
So, I don't know. I used to be in favor of the current situation, but at this<br/>
point, if we could change it, I think that I'd argue in faver of just treating<br/>
them as ranges of code units and then have wrappers for ranges of code points<br/>
or graphemes. It seems like the current situation promotes either using<br/>
ubyte[] (if you care about efficiency) or the new grapheme facilities in<br/>
std.uni if you care about correctness, whereas just using strings as ranges of<br/>
dchar is probably a bad idea unless you just don't want to deal with any of<br/>
the Unicode stuff, don't care all that much about efficiency, and are willing<br/>
have bugs in the areas where operating at the code point level is incorrect.<br/>
<br/>
<br/>
7. There are several minor inconsistencies with local imports and nested<br/>
functions in comparison to module-level imports or free functions, and I think<br/>
that some of those should be fixed, but I'm not sure that all of them can be.<br/>
<br/>
<br/>
That's what I can think of at the moment (though I'm sure that there are<br/>
others, and this post is already probbaly too long). So, we definitely have<br/>
our own consistency issues, but I do think that we're still far better off<br/>
than C++ in that regard. Fortunately, while Phobos still has some naming<br/>
issues, a lot of the naming inconsistencies were sorted out a couple of years<br/>
ago, and we have solved a number of other inconsistencies in the language and<br/>
library over time, so if anything, we've probably been _reducing_ the number<br/>
of inconsistencies that we have rather than increasing them. But we should<br/>
look at reducing them further if we can and should _definitely_ keep an eye<br/>
out for areas where more inconsistencies could creep in.<br/>
<br/>
- Jonathan M Davis</div></div></body></html>