View mode: basic / threaded / horizontal-split · Log in · Help
November 06, 2006
Cases where I miss C++ 'using'
In C++ 'using' can be like a D alias but with the target name implied.

E.g.
   using Namespace::Class;

is like
   alias Module.Class Class;

I find I'm using the latter construct pretty often, and it just looks 
redundant compared to the equivalent in C++.  If not a new 'using' 
keyword, perhaps we could allow this?:

   alias some.package.module;

or this

   alias some.package.module .;  // unix 'ln -s' syntax!

as a synonym for

    alias some.package.module module;

If the thing being aliased has no dots,
    alias string;
then it would be an error (just like "alias x x" is an error).

--
Another use of 'using' in C++ is, within the current block scope, to 
bring every symbol in a namespace into the name table.  E.g.

   using namespace std;

makes std::string, std::vector, etc, all accessible without the std:: 
prefix.

This is quite similar to what with(std){...} would do, except 'using' 
does it in the _current_ block scope rather than requiring you create a 
new block scope.  I find 'with' to be quite handy, but sometimes the 
scope and extra nesting level are annoying, and it gets ugly if you want 
to 'with' two or more things simultaneously.  For example, say you want 
to use std.math and std.string in one function (but don't want them 
polluting your namespace elsewhere):

  static import std.math;
  static import std.string;
  ...
  void do_something()
  {
      with(std.math) {
          with(std.string) {
             str = format("%f <= %f", fmin(a,b), fmax(a,b));
             ...
             ...

          }
      }
  }

As an alternative to that, an alias-like "with declaration" would be handy:

  void do_something()
  {
      with std.math, std.string;
      str = format("%f <= %f", fmin(a,b), fmax(a,b));
      ...
      ...
  }

It's basically the same as 'import' (in fact "with m=std.math" would 
make sense too), except unlike import, it can be used anywhere, and not 
just at the top-level scope, and it doesn't actually import anything 
new, just gives new names to existing imported symbols.  For that reason 
it is probably a bad idea to use the 'import' keyword for this 
functionality.

Like in C++ the compiler can complain if there are some symbols that 
overlap.  Though I'd prefer it just use a 'last one wins' rule, which 
would be more equivalent to the nested 'with statements' case.  Anyway, 
I use that sort of pattern a lot in C++ (putting 'using' statements 
within functions or classes or individual scopes).  It's just good 
programming practice to minimize namepspace pollution as much as possible.

--
Finally I wish there were some way to bring all the values in an *enum* 
into the current name resolution scope.  For example:

enum Buttons {
   Left,
   Right,
   Middle
}
with(Buttons) {  // doesn't work!
   x = Left|Middle
}
alias Buttons B;
y = B.Left | B.Middle;  // ok, but not as nice looking


--bb
November 07, 2006
Re: Cases where I miss C++ 'using'
Bill Baxter wrote:
> ...
> 
> As an alternative to that, an alias-like "with declaration" would be handy:
> 
>   void do_something()
>   {
>       with std.math, std.string;
>       str = format("%f <= %f", fmin(a,b), fmax(a,b));
>       ...
>       ...
>   }
> 

Or, you could use this to keep it consistent with various other
block-modifying keywords:

> void do_something()
> {
>     with(std.math):
>     with(std.string): // or even with(std.math,std.string):
>     str = format("%f <= %f", fmin(a,b), fmax(a,b));
>     ...
>     ...
> }

> -- 
> Finally I wish there were some way to bring all the values in an *enum*
> into the current name resolution scope.  For example:
> 
> enum Buttons {
>    Left,
>    Right,
>    Middle
> }
> with(Buttons) {  // doesn't work!
>    x = Left|Middle
> }
> alias Buttons B;
> y = B.Left | B.Middle;  // ok, but not as nice looking
> 
> 
> --bb

Allowing you to use an Enum's name without the prefix is one of the
things I actually miss about Visual Basic.  Sure, requiring the prefix
is nice for the sake of organisation, but it gets *really* aggravating
after a while.

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even
make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D
i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
November 07, 2006
Re: Cases where I miss C++ 'using'
Daniel Keep wrote:
>> Finally I wish there were some way to bring all the values in an *enum*
>> into the current name resolution scope.  For example:
>>
>> enum Buttons {
>>    Left,
>>    Right,
>>    Middle
>> }
>> with(Buttons) {  // doesn't work!
>>    x = Left|Middle
>> }
>> alias Buttons B;
>> y = B.Left | B.Middle;  // ok, but not as nice looking
>>
>>
>> --bb
> 
> Allowing you to use an Enum's name without the prefix is one of the
> things I actually miss about Visual Basic.  Sure, requiring the prefix
> is nice for the sake of organisation, but it gets *really* aggravating
> after a while.

I mostly use enums inside switch statements. Java makes a nice
compromise here by only requiring the prefix outside switches. I don't
like making them accessible everywhere without prefixing.
November 08, 2006
Re: Cases where I miss C++ 'using'
Jari-Matti Mäkelä wrote:
> Daniel Keep wrote:
>>> Finally I wish there were some way to bring all the values in an *enum*
>>> into the current name resolution scope.  For example:
>>>
>>> enum Buttons {
>>>    Left,
>>>    Right,
>>>    Middle
>>> }
>>> with(Buttons) {  // doesn't work!
>>>    x = Left|Middle
>>> }
>>> alias Buttons B;
>>> y = B.Left | B.Middle;  // ok, but not as nice looking
>>>
>>>
>>> --bb
>> Allowing you to use an Enum's name without the prefix is one of the
>> things I actually miss about Visual Basic.  Sure, requiring the prefix
>> is nice for the sake of organisation, but it gets *really* aggravating
>> after a while.
> 
> I mostly use enums inside switch statements. Java makes a nice
> compromise here by only requiring the prefix outside switches. I don't
> like making them accessible everywhere without prefixing.

True, since that negates one of the benefits of Enums: organisation.
One thing I thought was very cool (I can't remember if this was VB6 or
VB.Net) was that if you were calling a function that took an enum, you
could omit the prefix.  ie:

> Sub Foo(SomeEnum e)

Could be called:

> Foo(SomeEnum.Bar)

Or:

> Foo(Bar)

Maybe if we allowed the prefix to be omitted when

a. we're switching on an enum,
b. we're passing an enum argument to a function and
c. when we're assigning to an enum typed variable

that would be enough.  Then again, maybe that's just because I'm a lazy
bugger :)

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even
make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D
i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
November 08, 2006
Re: Cases where I miss C++ 'using'
Daniel Keep wrote:
> 
> Jari-Matti Mäkelä wrote:
>> Daniel Keep wrote:
>>>> Finally I wish there were some way to bring all the values in an *enum*
>>>> into the current name resolution scope.  For example:
>>>>
>>>> enum Buttons {
>>>>    Left,
>>>>    Right,
>>>>    Middle
>>>> }
>>>> with(Buttons) {  // doesn't work!
>>>>    x = Left|Middle
>>>> }
>>>> alias Buttons B;
>>>> y = B.Left | B.Middle;  // ok, but not as nice looking
>>>>
>>>>
>>>> --bb
>>> Allowing you to use an Enum's name without the prefix is one of the
>>> things I actually miss about Visual Basic.  Sure, requiring the prefix
>>> is nice for the sake of organisation, but it gets *really* aggravating
>>> after a while.
>> I mostly use enums inside switch statements. Java makes a nice
>> compromise here by only requiring the prefix outside switches. I don't
>> like making them accessible everywhere without prefixing.
> 
> True, since that negates one of the benefits of Enums: organisation.

I don't want them to be available everywhere either.  Just in particular 
functions or scopes where I'm going to be using them heavily.  I don't 
see why that ability should be limited to the insides of switch 
statements.

> One thing I thought was very cool (I can't remember if this was VB6 or
> VB.Net) was that if you were calling a function that took an enum, you
> could omit the prefix.  ie:
> 
>> Sub Foo(SomeEnum e)
> 
> Could be called:
> 
>> Foo(SomeEnum.Bar)
> 
> Or:
> 
>> Foo(Bar)

I would like that.  That's one of my biggest annoyances with C++ that 
still remains in D right there.

But there are ambiguities with operator overloading.  But that's no 
biggie, the compiler just needs to complain if leaving off the enum type 
creates an ambiguous overload situation.

> Maybe if we allowed the prefix to be omitted when
> a. we're switching on an enum,
> b. we're passing an enum argument to a function and
> c. when we're assigning to an enum typed variable
> 
> that would be enough.  Then again, maybe that's just because I'm a lazy
> bugger :)

Me too.  But its not just laziness.  Having lots of repetitive cruft in 
the code makes it harder to see what's really going on.

--bb
November 08, 2006
Re: Cases where I miss C++ 'using'
Daniel Keep wrote:
> 
> 
> Maybe if we allowed the prefix to be omitted when
> 
> a. we're switching on an enum,
> b. we're passing an enum argument to a function and
> c. when we're assigning to an enum typed variable
> 
> that would be enough.  Then again, maybe that's just because I'm a lazy
> bugger :)

Another case would be comparing equality like

  SomeEnum val;
  ...
  if (val == SomeEnum.Bar) { ... }

Or any of the other operators defined for Enums probably - !=, |, &, etc.

--bb
Top | Discussion index | About this forum | D home