February 21, 2008
Please please please, can we have this either not compile, or else do a reference compare:

class C {}

C x = null;
x != null;
x == null;

I just got bit by this again today!  I hate this stupid "feature".  The result is always a segmentation fault, with no information on where it happened.  I probably have more of these in my code that just haven't executed yet.

Before people respond saying "you need to use is or !is", um yeah I know.  I just can't get my brain to re-learn how to compare to null, when every other language on the planet does it with ==.  Even if the compiler complained, I wouldn't mind.

If ever there was a subtle bug that could easily be fixed by a compiler update, and absolutely wouldn't affect any existing valid code, this is it.

-Steve


February 21, 2008
On Thu, 21 Feb 2008 09:53:00 -0700, Darryl Bleau wrote:

> bearophile wrote:
>> Another solution is to think "in" as an operator, and "!in" as two operators, where ! negates the result of the precedent "in", where "in" returns a pointer. I don't see this as silly :-)
> 
> I should have read this first. Yes, that's exactly what I would like.

Fwiw:
"is" may be no boolean operator, but "!" is a boolean operator.
Hence, "!is" can be boolean operator the same way as "=" is not a boolean
operator, but "!=" is.
February 21, 2008
Gregor Richards wrote:
> /me boos !in again.
> 
> Walter's argument against !in makes perfect sense, and nobody ever acknowledges that. 'in' is not a boolean operation, and it wouldn't be good for 'in' to return a pointer and '!in' to return a bool. That's just silly.

Why not make it generic? I hereby propose that "a !op b" be always equivalent to "(a op b) !is cast(typeof(a op b))0". (Not just "!(a op b)" because I'm not sure whether that works in all cases, but I think this should.)

Imagine the increased clarity:

return *a !- *b ? *a!**b : foo!(int)!&a;

Compare this to the ludicrously verbose:

return *a - *b == 0 ? *a * *b == 0 : (foo!(int) & a) !is null;

We even sidestep the problem of "a & b == 0" being parsed as "a & (b == 0)"!

-- 
E-mail address: matti.niemenmaa+news, domain is iki (DOT) fi
February 21, 2008
On 21/02/2008, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> Please please please, can we have this either not compile, or else do a
>  reference compare:
>
>  class C {}
>
>  C x = null;
>  x != null;
>  x == null;

Yeah, but then how would you call opEquals?
February 21, 2008
"Janice Caron" wrote
> On 21/02/2008, Steven Schveighoffer wrote:
>> Please please please, can we have this either not compile, or else do a
>>  reference compare:
>>
>>  class C {}
>>
>>  C x = null;
>>  x != null;
>>  x == null;
>
> Yeah, but then how would you call opEquals?

Simple.  If you are not doing == null, then call opEquals.  And I don't mean make the check at runtime, I mean the compiler should check if you are doing == null with the keyword null, then either throw an error or do the bit compare.  Anything else, call opEquals.  It's one of those little hackish exceptions to the rule that would make life soo much easier, and would not impact anyone adversely.

-Steve


February 21, 2008
Jarrett Billingsley wrote:
> "Robert Fraser" <fraserofthenight@gmail.com> wrote in message news:fpjuh5$uai$1@digitalmars.com...
>> Darryl Bleau wrote:
>>> opIndexConcat
>>> opIndexConcatAssign
> 
> // Contrived, but shows the issue.
> struct IntArray
> {
>     int[] mData;
> 
>     int opIndex(size_t idx)
>     {
>         return mData[idx];
>     }
> }
> 
> int[] realArray = [1, 2, 3];
> realArray[0]++; // now contains [2, 2, 3]
> 
> IntArray a;
> a.mData = [1, 2, 3];
> a[0]++; // FAIL
> 
> In other words without these opIndexSomethingAssign overloads or ref returns it's impossible to make a user container type behave just like a built-in one.
> 
> (as an aside MiniD solves this by defining "a[0]++" to be "temp = a[0]; temp++; a[0] = temp;" but that's beside the point.) 

So it sounds like what you actually meant was opIndexAddAssign.
opIndexConcatAssign would be like a[0]~=10.

But anyway, generally going that route would require creating a whole slew of new operators, basically an opIndex version of every current op***Assign operator.  That *would* give a class designer fine grained control over what was allowed and not allowed, but it's probably overkill.

On the other hand, the "return a reference" solution also has drawbacks in that it exposes the implementation and gives up control over the element.  Consider for instance an array wrapper where you want to track every modification to every element.  Currently you can do that quite easily by making opIndexAssign the only means of modifying the data. But then you can't do things like a[10] += 5.   So I think there's a place for the solution you use in MiniD as well.  Even after reference returns become possible I'd be happy to see the compiler use that trick in cases where there is no reference-returning version of opIndex defined.

--bb
February 21, 2008
Leandro Lucarella wrote:
> Darryl Bleau, el 21 de febrero a las 09:48 me escribiste:
>> Jarrett Billingsley wrote:
>>> "Darryl Bleau" <user@example.net> wrote in message news:fphle3$20np$1@digitalmars.com...
>>>> opIndexConcat
>>>> opIndexConcatAssign
>>>>
>>>> in D1, of course.
>>>>
>>>> I would also potentially accept:
>>>>
>>>> Returning static arrays from functions.
>>>>
>>>> or, possibly:
>>>>
>>>> !in
>>> Sorry, no new language features in D1.
>>>
>> I know, and I knew when writing it that it was futile to ask. I suppose
>> I was more just venting my frustration that it seems that D1 was
>> released, and Walter said, 'go forth and create programs', which we did,
>> but now we turn around and say, hey, this D stuff is great, could we
>> just have a few minor changes? But, are denied. Seems Const and Enum are
>> much more important than helping with actual practical applications of
>> the current language.
> 
> I agree. D1.0 looks more "abandoned" than "stable". A language should keep
> moving even when it's stable, as long as the changes are backward
> compatibles. That mean that a new syntax that was previosly forbiden or
> new additions to the standard library could be done without affecting
> stability.
> 
> If Walter don't have the time, maybe, again, it's time to name a
> successor, someone who has the time to take over like Linus does with
> the stable kernels.
> 
> I know this is extremely difficult with DMD being closed, but maybe he can
> find a way.
> 
> For now, it's like there is no viable D Language, you have D1.0 wich is
> broken (there are a lot of things specified in the specs that are not
> implemented in D1.) and gets too little attention, or D2.0 that it's
> continously evolving and getting huge changes.
> 
> I think D1.0 is good enough and deserves a little love to finally polish
> all the rough corners and make it move forward in small and backward
> compatible steps to be a nice, maintained and usable language.
> 

My sentiments exactly.
Well put.

--bb
February 21, 2008
Steven Schveighoffer wrote:
> "Janice Caron" wrote
>> On 21/02/2008, Steven Schveighoffer wrote:
>>> Please please please, can we have this either not compile, or else do a
>>>  reference compare:
>>>
>>>  class C {}
>>>
>>>  C x = null;
>>>  x != null;
>>>  x == null;
>> Yeah, but then how would you call opEquals?
> 
> Simple.  If you are not doing == null, then call opEquals.  And I don't mean make the check at runtime, I mean the compiler should check if you are doing == null with the keyword null, then either throw an error or do the bit compare.  Anything else, call opEquals.  It's one of those little hackish exceptions to the rule that would make life soo much easier, and would not impact anyone adversely.

I'd vote enthusiastically for issuing a warning, but I don't like the idea of changing behavior just for that one special case.
For instance what would this do?

C Null = null;
if (x != Null) {...}

Seems pretty confusing to me if that does something different from x!=null.

--bb
February 21, 2008
On 21/02/2008, Bill Baxter <dnewsgroup@billbaxter.com> wrote:
> I'd vote enthusiastically for issuing a warning, but I don't like the
>  idea of changing behavior just for that one special case.

I'd be inclined to agree, but for the fact that D doesn't have warnings.

So, you could say, second best option, make it a compile error.

    if (c == null) // ERROR

Anyone see any problem with that? Sure, it'd be annoying, but I think it would a lot /less/ annoying than a crash at run time.
February 21, 2008
Janice Caron wrote:
> On 21/02/2008, Bill Baxter <dnewsgroup@billbaxter.com> wrote:
>> I'd vote enthusiastically for issuing a warning, but I don't like the
>>  idea of changing behavior just for that one special case.
> 
> I'd be inclined to agree, but for the fact that D doesn't have warnings.
> 
> So, you could say, second best option, make it a compile error.
> 
>     if (c == null) // ERROR
> 
> Anyone see any problem with that? Sure, it'd be annoying, but I think
> it would a lot /less/ annoying than a crash at run time.

What's that -w flag do?  Wouldn't it be appropriate there?

--bb