July 07, 2009

BCS wrote:
> Hello Daniel,
> 
>> [1] like me. My girlfriend disagrees with me on this,
> 
> You have a girlfriend that even bothers to have an opinion on a programming issue, lucky bastard.

No, when I said "like me", I meant:

"Unless there's some egregious problem aside from being a bit on the
ugly side (like me), ..."

My girlfriend is actually a nurse, but I could ask for her opinion on case ranges if you want.  :)

>> though. *I* think she's crazy, but I'm not exactly
>> inclined to try and change her mind. :)
> 
> That reminds me of a quote: "If you assume a woman's mind is supposed to work like a man's, the only conclusion you can come to is they are *all* crazy." OTOH you can switch the perspective on that around and I expect it's just as true. It should be pointed out that, almost by definition, you can't have 50% of the world be crazy.

My opinion is based more on that, with respect to the above issue, she seems to think differently to more or less everyone else I've ever met, including myself.
July 07, 2009
Robert Jacques wrote:
> On Tue, 07 Jul 2009 01:48:41 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> 
>> Robert Jacques wrote:
>>> On Mon, 06 Jul 2009 01:05:10 -0400, Walter Bright <newshound1@digitalmars.com> wrote:
>>>
>>>> Something for everyone here.
>>>>
>>>>
>>>> http://www.digitalmars.com/d/1.0/changelog.html
>>>> http://ftp.digitalmars.com/dmd.1.046.zip
>>>>
>>>>
>>>> http://www.digitalmars.com/d/2.0/changelog.html
>>>> http://ftp.digitalmars.com/dmd.2.031.zip
>>>  Thanks for another great release.
>>>  Also, I'm not sure if this is a bug or a feature with regard to the new integer rules:
>>>     byte x,y,z;
>>>    z = x+y;    // Error: cannot implicitly convert expression (cast(int)x + cast(int)y) of type int to byte
>>>  which makes sense, in that a byte can overflow, but also doesn't make sense, since integer behaviour is different.
>>
>> Walter has implemented an ingenious scheme for disallowing narrowing conversions while at the same time minimizing the number of casts required. He hasn't explained it, so I'll sketch an explanation here.
>>
>> The basic approach is "value range propagation": each expression is associated with a minimum possible value and a maximum possible value. As complex expressions are assembled out of simpler expressions, the ranges are computed and propagated.
>>
>> For example, this code compiles:
>>
>> int x = whatever();
>> bool y = x & 1;
>>
>> The compiler figures that the range of x is int.min to int.max, the range of 1 is 1 to 1, and (here's the interesting part), the range of x & 1 is 0 to 1. So it lets the code go through. However, it won't allow this:
>>
>> int x = whatever();
>> bool y = x & 2;
>>
>> because x & 2 has range between 0 and 2, which won't fit in a bool.
>>
>> The approach generalizes to arbitrary complex expressions. Now here's the trick though: the value range propagation is local, i.e. all ranges are forgotten beyond one expression. So as soon as you move on to the next statement, the ranges have been forgotten.
>>
>> Why? Simply put, increased implementation difficulties and increased compiler memory footprint for diminishing returns. Both Walter and I noticed that expression-level value range propagation gets rid of all dangerous cases and the vast majority of required casts. Indeed, his test suite, Phobos, and my own codebase required surprisingly few changes with the new scheme. Moreover, we both discovered bugs due to the new feature, so we're happy with the status quo.
>>
>> Now consider your code:
>>
>> byte x,y,z;
>> z = x+y;
>>
>> The first line initializes all values to zero. In an intra-procedural value range propagation, these zeros would be propagated to the next statement, which would range-check. However, in the current approach, the ranges of x, y, and z are forgotten at the first semicolon. Then, x+y has range -byte.min-byte.min up to byte.max+byte.max as far as the type checker knows. That would fit in a short (and by the way I just found a bug with that occasion) but not in a byte.
> 
> That's really cool. But I don't think that's actually happening (Or are these the bugs you're talking about?):
> 
>     byte x,y;
>     short z;
>     z = x+y;  // Error: cannot implicitly convert expression (cast(int)x + cast(int)y) of type int to short
> 
>     // Repeat for ubyte, bool, char, wchar and *, -, /

http://d.puremagic.com/issues/show_bug.cgi?id=3147 You may want to add to it.

> And by that logic shouldn't the following happen?
> 
>     int x,y;
>     int z;
>     z = x+y;  // Error: cannot implicitly convert expression (cast(long)x + cast(long)y) of type long to int

No. Int remains "special", i.e. arithmetic operations on it don't automatically grow to become long.

> i.e. why the massive inconsistency between byte/short and int/long? (This is particularly a pain for generic i.e. templated code)

I don't find it a pain. It's a practical decision.

> BTW: this means byte and short are not closed under arithmetic operations, which drastically limit their usefulness.

I think they shouldn't be closed because they overflow for relatively small values.


Andrei
July 07, 2009
BCS wrote:
> Hello Daniel,
> 
>> [1] like me. My girlfriend disagrees with me on this,
> 
> You have a girlfriend that even bothers to have an opinion on a programming issue, lucky bastard.

My understanding is that he's referring to a different issue.

>> though. *I* think she's crazy, but I'm not exactly
>> inclined to try and change her mind. :)
> 
> That reminds me of a quote: "If you assume a woman's mind is supposed to work like a man's, the only conclusion you can come to is they are *all* crazy."

To paraphrase: "If you assume a woman's mind is supposed to work like a man's, you won't get laid. Ever."


Andrei
July 07, 2009
Robert Jacques wrote:
> Another inconsistency:
> 
>     byte[] x,y,z;
>     z[] = x[]*y[]; // Compiles

Bugzilla is its name.

Andrei
July 07, 2009
>> That's really cool. But I don't think that's actually happening (Or are these the bugs you're talking about?):
>>
>>     byte x,y;
>>     short z;
>>     z = x+y;  // Error: cannot implicitly convert expression
>> (cast(int)x + cast(int)y) of type int to short
>>
>>     // Repeat for ubyte, bool, char, wchar and *, -, /
> 
> http://d.puremagic.com/issues/show_bug.cgi?id=3147 You may want to add to it.

Before going too far, consider:

byte x, y, z;
short a;
a = x + y + z;

How far should the logic go?
July 07, 2009
Brad Roberts wrote:
>>> That's really cool. But I don't think that's actually happening (Or
>>> are these the bugs you're talking about?):
>>>
>>>     byte x,y;
>>>     short z;
>>>     z = x+y;  // Error: cannot implicitly convert expression
>>> (cast(int)x + cast(int)y) of type int to short
>>>
>>>     // Repeat for ubyte, bool, char, wchar and *, -, /
>> http://d.puremagic.com/issues/show_bug.cgi?id=3147 You may want to add
>> to it.
> 
> Before going too far, consider:
> 
> byte x, y, z;
> short a;
> a = x + y + z;
> 
> How far should the logic go?

Arbitrarily far for any given expression, which is the beauty of it all. In the case above, the expression is evaluated as (x + y) + z, yielding a range of -byte.min-byte.min to byte.max+byte.max for the parenthesized part. Then that range is propagated to the second addition yielding a final range of -byte.min-byte.min-byte.min to byte.max+byte.max+byte.max for the entire expression. That still fits in a short, so the expression is valid.

Now, if you add more than 255 bytes, things won't compile anymore ;o).


Andrei
July 07, 2009
Derek Parnell wrote:
> Then we can use "-deps=dep.txt -nogen" to get the dependency data so build
> tools can then work out what needs to actually be compiled. And in that
> vein, a hash (eg CRC32, MD5, SHA256) of the file's used by DMD would be
> nice to see in the 'deps' file. Would help build tools detect which files
> have been modified.

I think this should be the job of the build tool, not the compiler. For example, xfBuild uses the compiler-generated dependency files to keep track of its own project database containing dependencies and file modification times. I guess I'll be adding hashes as well :) Why a separate file? When doing incremental builds, you'll only pass some of the project's modules to the compiler so the deps file would not contain everything. The proper approach is to parse it and update the project database with it.


> May I make a small syntax suggestion for the deps format. Instead of
> enclosing a path in parentheses, and using ':' as a field delimiter, have
> the first (and last) character of each line be the field delimiter to use
> in that line. The delimiter would be guaranteed to never be part of any of
> the fields' characters. That way, we don't need escape characters and
> parsing the text is greatly simplified.

I don't think the parsing is currently very complicated at all, but I guess YMMV. I'd argue that the current format is easier to generate and more human-readable than your proposed syntax. The latter might also be harder to process by UNIXy tools like grep or cut.


> Also, simplifying the paths by resolving the ".." and "." would be nice. 

Yea, that would be nice.


-- 
Tomasz Stachowiak
http://h3.team0xf.com/
h3/h3r3tic on #D freenode
July 07, 2009
Andrei Alexandrescu escribió:
> BCS wrote:
>> Hello Daniel,
>>
>>> [1] like me. My girlfriend disagrees with me on this,
>>
>> You have a girlfriend that even bothers to have an opinion on a programming issue, lucky bastard.
> 
> My understanding is that he's referring to a different issue.
> 
>>> though. *I* think she's crazy, but I'm not exactly
>>> inclined to try and change her mind. :)
>>
>> That reminds me of a quote: "If you assume a woman's mind is supposed to work like a man's, the only conclusion you can come to is they are *all* crazy."
> 
> To paraphrase: "If you assume a woman's mind is supposed to work like a man's, you won't get laid. Ever."

lol :)
July 07, 2009
On 2009-07-07 01:12:12 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> Nick Sabalausky wrote:
>> Those examples are all cases where the meaning and context are wildly different fbetween one use and the other. But with '..', both uses are very similar: "From xxx to (incl/excl) yyy". Big differences are ok, they stand out as obvious. Small differences can be more problematic.
> 
> You'd have an uphill battle using a counterfeit Swiss army knife against a battery of Gatling guns



> arguing that
> 
> case 'a': .. case 'z':
> 
> is very similar with
> 
> 0 .. 10
> 
> That's actually much more different than e.g.
> 
> a = b * c;
> 
> versus
> 
> b * c;

They aren't so much different if you consider "case 'a':" and "case 'z':" as two items joined by a "..", which I believe is the expected way to read it. In the first case "case 'a':" and "case 'z':" joined by a ".." means an inclusive range, in the second case "0" and "10" joined by a ".." means an exclusive one.

With "b * c", the meaning is completly different depending on whether b is a type or not. If "b" is a type, you can't reasonabily expect "b * c" to do a multiplication and you'll get an error about it if that's what you're trying to do. Wheras with "case 'a': .. case 'b':" you can reasonably expect an exclusive range if you aren't too familiar with the syntax (and that's a resonable expectation if you know about ranges), and you won't get an error of you mix things up; thus, clarity of the syntax becomes more important.

I still think that having that syntax is better than nothing, but I do believe it's an inconsistency and that it may looks ambiguous to someone unfamiliar with it.

But my worse grief about that new feature is the restriction about 256 values which is pretty limitating if you're writing a parser dealing with ranges of unicode characters. I guess I'll have to continue using ifs for that.


-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

July 07, 2009
Ary Borenszweig wrote:
> Jesse Phillips escribió:
>> On Mon, 06 Jul 2009 14:38:53 -0500, Andrei Alexandrescu wrote:
>>
>>> Denis Koroskin wrote:
>>>> Reuse goto?
>>> So any case-labeled code should end either with a control flow statement
>>> that transfers control elswhere? That sounds like a great idea.
>>> Fall-through is so rare and so rarely intended, it makes sense to
>>> require the programmer to state the intent explicitly via a goto case.
>>>
>>> Andrei
>>
>> The goto method already works, the only change needed would be to not have fallthru default.
>>
>> http://digitalmars.com/d/2.0/statement.html#GotoStatement
> 
> But that's kind of redundant:
> 
> case 1: goto case 11:
> case 11: goto case 111:
> case 111: goto case 1111:
> case 1111:
>     doIt();
> 
> don't you think?

Maybe http://msdn.microsoft.com/en-us/vcsharp/aa336815.aspx .

> 
> If you change the case expression, you must change it twice.
> 
> Why not:
> 
> case 1: continue case;
> case 11: continue case;
> 
> etc.?
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19