Thread overview
On "if (x)" and initialization... - summary of the proposed solution
Apr 06, 2003
Luna Kid
Apr 07, 2003
Matthew Wilson
Apr 07, 2003
Luna Kid
April 06, 2003
--------------------------------------------------------------
(Dammit, I need a sleep... Here comes the corrected version. Also, I put it here, to top level, for "accessibility reasons".)
--------------------------------------------------------------

//////////////////////////////////////////////////// <some_final_comments note="Walter, please skip this...">

> > "Luna Kid" <lunakid@neuropolis.org> wrote in message news:b6aerf$158r$1@digitaldaemon.com...
> > > Mmm... Actuall, I start liking Sean's "with" idea more and more:
> > >
> > >     > with(o)  // skips the whole block if o is null
> > >     > {
> > >     > }
>
[...snip...]
>
> "Matthew Wilson" <dmd@synesis.com.au> wrote in message news:b6aqbd$1ds9$1@digitaldaemon.com...
> > I agree it seems kinda nice, but how to do complex conditional,
involving
> > perhaps a couple of objects, and maybe other conditions?
>
[...snip...]
>
"Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:b6beok$1qun$1@digitaldaemon.com...
> This would only cover half of the issue.  Assuming one wants distinct
> semantic actions to replace if (o != null) {} and if (o1 == o2), this
would
> only address the former.

Yes, as the core of the idea was separating general-purpose conditionals ("real if") from checking object availability.

</some_final_comments> ////////////////////////////////////////////////////

Actually (despite what I said in private to him earlier...),
Sean's with(x) would be _the_ solution:

- As to the syntax, both of the controversial, but frequently
  used and practical C/C++ idioms

    if (x)

  and

    if (x = new object)

  would be replaced this way with something nice and clean.

- As to the semantics: the meaning of the construct would be:
  "if x is initialized, do the following with it". What does
  "initialized" mean?

  For a start, "x != null" would be fine. (The current semantics
  of references allows null values already, which does indicate
  some sort of "uninitializedness" anyway.)

  But if not (e.g. in classes where RAII is not strictly
  followed, like

        x = new File; x.open("realfile"); with (x)...

  where x != null but invalid in any useful context), this
  semantics can be easily extended later.

  E.g., in the future, "with (x)" could implicitly call
  some x.initialized() method, if the class of x defined it.
  (Notice that this is actually the very common role of
  operator bool() in C++, which facilitates -- and makes so
  practical! -- the ugly if(x) conditionals there...)

  (Just as a side-note: besides the != null choice, it might
  be tempting to say, e.g. performance-wise, that having

        class_invariant == true

  would also be good, but since "with (x)" is a typical run-
  time success/failure scenario, disabling contracts would
  break the logic of the programs.)

- One "drawback" is the run-time overhead for != null checking.

  But no program is meaningful, which operates on uninitialized
  references anyway, so the code *must* contain the check, either
  way... Then, the preferable choice would be if the compiler
  kindly took this routine burden -- and throw some "object
  uninitialized" exception, as appropriate.

- Note, that this same exception could be also thrown when
  applying operations on x, when it is null (like x == ...
  - see in the "null == o" thread, for example).

  However, that would be probably be too much, contradicting
  with D's nice performance commitments. But luckily, as a bonus,
  this slightly extended with statement also offers a compromise
  to this:

  One (Walter) could agree that with(x) naturally ("explicitly")
  implies object validity checking, but all others (like ==)
  perform no check (but class invariant checking in debug mode),
  as currently, so those operations should be e.g. enclosed into
  a with(x) { ... } block.

And everyone could be quite happy then, I think...

Thanks,
Sab


April 07, 2003
>   One (Walter) could agree that with(x) naturally ("explicitly")
>   implies object validity checking, but all others (like ==)
>   perform no check (but class invariant checking in debug mode),
>   as currently, so those operations should be e.g. enclosed into
>   a with(x) { ... } block.
>
> And everyone could be quite happy then, I think...


Sorry, Luna, but I'm not going to be happy if writing

    X    x1    =    ...
    X    x2    =    ...

    ...

    if(x1 == x2)

can crash. I can't think of another language that does not make this statement work in a robust (at least non-crashing) and meaningful way. Why should D be the odd man out?

Indeed, either my recall has worn out on the raspy nub of this issue, of I've not actually heard a justification for not making == null-safe. Can anyone (re-)enlighten me?


However, I think your with() notion has merit. :)

Matthew


April 07, 2003
> Sorry, Luna, but I'm not going to be happy if writing
>
>     X    x1    =    ...
>     X    x2    =    ...
>
>     ...
>
>     if(x1 == x2)
>
> can crash. I can't think of another language that does not make this

Yeah, that's why I tried selling it as a compromise... ;)

> Indeed, either my recall has worn out on the raspy nub of this issue, of I've not actually heard a justification for not making == null-safe. Can anyone (re-)enlighten me?

You are still in the clear [do I use this properly?], I simply assumed that

    - Walter will not change the reference semantics.
    - Walter will possibly not sacrifice performance for ==.

> However, I think your with() notion has merit. :)

It's Sean's. I only gave it some fuel.

-------------------------------------
Regarding your other question:

> What about conditional
>
>  if (x == y)
>
> where one or both may be null? I assume your with() idea - on which I'm
> still cogitating - does not address this issue, which is, in my opinion, a
> lot more important than if(x) vs if(x != null)

True, it's more important, but is a diffrenent business.
Here, now, this humble with(x) thingie is just an lvalue
expression with some extended semantics in order to get
rid of the legacy if(x) and if(x = new X) crap.

It only affects the x == y issue in that

 - if we had this proposed simple and practical extension
   in the language, then if-conditional gets freed from the
   ugly idiomatic semantics inherited from C -- but remains
   loaded with the D'a problem with the null references...

 - it can also be presented as a compromise ("OK, we can at
   least enclose unsafe operations into safe with() blocks),
   should you happen to fail convincing Walter about the null
   ref problem... :)

As Sean also said, with(x) solves only part of the if problem.
But at least that part is now cleanly separated from the other
part (the null comparison), so much that now we can see they
are hardly related at all. :)
-------------------------------------

Cheers,
Lunasome Szabi