digitalmars.D - Cases where I miss C++ 'using'
- Bill Baxter (76/76) Nov 06 2006 In C++ 'using' can be like a D alias but with the target name implied.
- Daniel Keep (13/50) Nov 06 2006 Or, you could use this to keep it consistent with various other
- =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= (4/25) Nov 07 2006 I mostly use enums inside switch statements. Java makes a nice
- Daniel Keep (19/47) Nov 07 2006 True, since that negates one of the benefits of Enums: organisation.
- Bill Baxter (13/61) Nov 07 2006 I don't want them to be available everywhere either. Just in particular...
- Bill Baxter (7/17) Nov 07 2006 Another case would be comparing equality like
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
Nov 06 2006
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 --bbAllowing 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/
Nov 06 2006
Daniel Keep wrote: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.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 --bbAllowing 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.
Nov 07 2006
Jari-Matti Mäkelä wrote:Daniel Keep wrote: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: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.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 --bbAllowing 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.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/
Nov 07 2006
Daniel Keep wrote:Jari-Matti Mäkelä wrote: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.Daniel Keep wrote:True, since that negates one of the benefits of Enums: organisation.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.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 --bbAllowing 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.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: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.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 :)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
Nov 07 2006
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
Nov 07 2006