"with" still sucks + removing features + adding features

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon May 18 10:46:03 PDT 2009


Johan Granberg wrote:
> BCS wrote:
> 
>> Hello Andrei,
>>
>>> I think "with" is a very dangerous feature due to the way it hides
>>> symbols. It essentially makes the feeblest attempt at modular
>>> reasoning utterly impossible:
>>>
>>> int x, y;
>>> with (whatever)
>>> {
>>> y += x;
>>> ++x;
>>> }
>>>
>>> Maintenance of any type that is being used with "with" becomes a very
>>> dangerous proposition because it can silently change meaning of code.
>> I'd be willing to go the half way solution of making accessing a shadowing
>> symbol an error, resulting in (loudly) not being able to access either.
> 
> I think this solution is a good idea but that removing or restricting
> anything more regarding with is a bad idea as others have pointed out.
> 
> I'm using with quit a lot and it was one of thous things that attracted me
> to D (I get the feeling that D has a quite pragmatic way of looking at
> language features, if it's usefull lets have it unless it's harmfull to
> other parts of D, sort of.).

I personally still think it's a bad feature because it introduces 
long-distance coupling between symbols defined in two different places, 
both distinct from the place where the statement is used! Consider:

import wyda;  // defines symbol write
import geeba; // defines struct S { ... }

void main()
{
    S s;
    with (s) {
       write(5);
    }
}

Machiavelly would jump in joy at such code. What did I achieve? I saved 
a few "s.". What did I lose? The ability so say anything, but absolutely 
anything on what the code does. If S changes, the code may compile and 
run, yet doing something completely different. The dependency is not 
between the code as seen and wyda or geeba. It's between wyda and geeba, 
intermediated by "with"! I mean, if one _planned_ to design a maximally 
damaging language feature one couldn't come up with something better. 
And for what? Because you find it convenient to not type "s." a few 
times or just go in the blessed object and define a member? Is _this_ 
what makes or breaks your productivity? And are you willing to pay the 
ability to do the feeblest reasoning about your code for that doubtful 
benefit?

This is so against every single good notion of language design, I kid 
you not I feel my blood pressure rising only as I think of it. No amount 
of "but I find it useful" can protect this awful non-feature. It should 
be taken in the back and shot in the head, no trial. Shoot the lawyer 
too if it has one.

> On a similar note, Andrei, what is this spree of removing features? Ok some
> are obviously bad, imaginary types for example, but why remove other stuff
> such as commplex and with?

TDPL is coming out. This is quite literally the last chance to shed some 
old skin. Complex as a built-in does nothing of interest to anyone 
except a cute syntax for literals that nobody uses (how many remarkable 
complex literals could you imagine?) About "with"... see above before I 
die of a heart attack.

The baroque "!<>=" operators became much more attractive since Walter 
said he's considering making them overloadable.

On the other hand new features are coming, which I believe are "good 
skin". Narrowing integral conversions will go. Walter is working on a 
very cool scheme for inferring the range of expressions that makes casts 
unnecessary in many cases. Casts are a plague not only for safe code, 
but also for generic code that wants to be scalable and change-robust. 
The ease with which C and C++ allow losing state and the drowning 
necessity of integral casts in Java or C# are both extremes that I'm 
happy to see D avoid.

Final switch works with enums and forces you to handle each and every 
value of the enum. Regular switch gets ranged cases by the syntax case 
a: .. case b: (I've always thought switch would be greatly helped by that).

Static foreach might be making it too.


Andrei



More information about the Digitalmars-d mailing list