www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [Suggestion] The 'As' Operator

reply AJG <AJG_member pathlink.com> writes:
What do you guys think of the C# 'as' operator?

It's essentially a more aesthetic way to make a cast, but if incorporated into
D, it could be made different. For example:

# void func(Foo foo) {
#     // You can do:
#     Bar bar = foo as Bar;
#     bar.someBarFunc();
#     
#     // Or even the highly effective:
#     (foo as Bar).someBarFunc();
# }

You've got to admit it's a much cleaner syntax.

Note: I believe in C# this is an Exception-safe operation, and it will return
null on failure. Whereas a direct cast would throw InvalidCast. I think this is
a useful distinction, because it's therefore a condensed version of something
like:

(Foo is Bar ? (cast (Bar) Foo) : (cast (Bar) null));

Cheers,
--AJG.
Jul 05 2005
next sibling parent reply Chris Sauls <ibisbasenji gmail.com> writes:
AJG wrote:
 What do you guys think of the C# 'as' operator?

 #     (foo as Bar).someBarFunc();
 
 You've got to admit it's a much cleaner syntax.

 Note: I believe in C# this is an Exception-safe operation, and it will return
 null on failure. Whereas a direct cast would throw InvalidCast. I think this is
 a useful distinction, because it's therefore a condensed version of something
 like:
 
 (Foo is Bar ? (cast (Bar) Foo) : (cast (Bar) null));

behaves just like your 'as' expression. Maybe in D the 'as' expression (if it existed) would be the one to throw an exception on failure... so that doing: # Foo foo = new Foo; # Bar bar = foo as Bar; Would be semantically equivelant to: # Foo foo = new Foo; # Bar bar = cast(Bar) foo; # if (bar is null) # throw new InvalidCastException(Foo.classinfo.name, Bar.classinfo.name); Or something like that. -- Chris Sauls
Jul 05 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Chris Sauls" <ibisbasenji gmail.com> wrote in message 
news:dafsqi$1k9a$1 digitaldaemon.com...
 In D the cast() operation currently returns null if it fails with objects. 
 So it already behaves just like your 'as' expression.  Maybe in D the 'as' 
 expression (if it existed) would be the one to throw an exception on 
 failure... so that doing:

Man, would _that_ confuse prospective D users coming from C# ;) cast() and as switched! I _do_ like the "as" syntax.
Jul 06 2005
parent Stefan Zobel <Stefan_member pathlink.com> writes:
In article <dagv0m$2fd9$1 digitaldaemon.com>, Jarrett Billingsley says...
"Chris Sauls" <ibisbasenji gmail.com> wrote in message 
news:dafsqi$1k9a$1 digitaldaemon.com...
 In D the cast() operation currently returns null if it fails with objects. 
 So it already behaves just like your 'as' expression.  Maybe in D the 'as' 
 expression (if it existed) would be the one to throw an exception on 
 failure... so that doing:

Man, would _that_ confuse prospective D users coming from C# ;) cast() and as switched! I _do_ like the "as" syntax.

Well, I'm coming from C# (amongst others) and I don't feel confused :) It wasn't hard to switch to cast(). While I also like the "as" syntax, my proposition is to leave it as it is. There are simply more important things to be done (e.g. that whole const/immutable thing) ... Just my 2 c, Stefan
Jul 06 2005
prev sibling next sibling parent "Lionello Lunesu" <lio lunesu.removethis.com> writes:
Needless to say, it has been suggested before, and it's still a good idea.


L. 
Jul 05 2005
prev sibling next sibling parent reply clayasaurus <clayasaurus gmail.com> writes:
AJG wrote:
 What do you guys think of the C# 'as' operator?
 
 It's essentially a more aesthetic way to make a cast, but if incorporated into
 D, it could be made different. For example:
 
 # void func(Foo foo) {
 #     // You can do:
 #     Bar bar = foo as Bar;
 #     bar.someBarFunc();
 #     
 #     // Or even the highly effective:
 #     (foo as Bar).someBarFunc();
 # }
 
 You've got to admit it's a much cleaner syntax.
 
 Note: I believe in C# this is an Exception-safe operation, and it will return
 null on failure. Whereas a direct cast would throw InvalidCast. I think this is
 a useful distinction, because it's therefore a condensed version of something
 like:
 
 (Foo is Bar ? (cast (Bar) Foo) : (cast (Bar) null));
 
 Cheers,
 --AJG.
 
 

It may look better, but it doesn't stick out as much as 'cast' does. Also, when you do a search for 'as' you will get more than just instances of the keyword 'as'
Jul 06 2005
parent reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
AJG wrote:
 What do you guys think of the C# 'as' operator?

Definitely sweeter looking than 'cast', but not exactly an essential addition, since it can easily be duplicated with normal casting. I wouldn't mind it and probably would even use it, but I won't miss it if it isn't implemented. clayasaurus wrote:
 Also, when you do a search for 'as' you will get more than just
 instances of the keyword 'as'

Which is why you should search for 'as' surrounded by whitespace. The Perl-compatible regexp /\s+as\s+/ should do the trick. Plaintext searching can get a bit trickier (say, if somebody's decided to break the line right before the 'as', and then uses tabs for indentation), but in most cases ' as ' works. It's how I always search for keywords :-)
Jul 06 2005
parent reply clayasaurus <clayasaurus gmail.com> writes:
Deewiant wrote:
 AJG wrote:
 
What do you guys think of the C# 'as' operator?

Definitely sweeter looking than 'cast', but not exactly an essential addition, since it can easily be duplicated with normal casting. I wouldn't mind it and probably would even use it, but I won't miss it if it isn't implemented. clayasaurus wrote:
Also, when you do a search for 'as' you will get more than just
instances of the keyword 'as'

Which is why you should search for 'as' surrounded by whitespace. The Perl-compatible regexp /\s+as\s+/ should do the trick. Plaintext searching can get a bit trickier (say, if somebody's decided to break the line right before the 'as', and then uses tabs for indentation), but in most cases ' as ' works. It's how I always search for keywords :-)

But it will still pick up... void set(int) // set class bob as an int :-P whereas with cast you can search for 'cast('
Jul 06 2005
parent reply Deewiant <deewiant.doesnotlike.spam gmail.com> writes:
clayasaurus wrote:
 Deewiant wrote:
 clayasaurus wrote:

 Also, when you do a search for 'as' you will get more than just
 instances of the keyword 'as'

Which is why you should search for 'as' surrounded by whitespace. The Perl-compatible regexp /\s+as\s+/ should do the trick. Plaintext searching can get a bit trickier (say, if somebody's decided to break the line right before the 'as', and then uses tabs for indentation), but in most cases ' as ' works. It's how I always search for keywords :-)

But it will still pick up... void set(int) // set class bob as an int :-P whereas with cast you can search for 'cast('

Which will still pick up... foo = bar; // here I don't need to use cast(baz)bar because... ;-)
Jul 06 2005
parent reply clayasaurus <clayasaurus gmail.com> writes:
Deewiant wrote:
 clayasaurus wrote:
 
Deewiant wrote:

clayasaurus wrote:


Also, when you do a search for 'as' you will get more than just
instances of the keyword 'as'

Which is why you should search for 'as' surrounded by whitespace. The Perl-compatible regexp /\s+as\s+/ should do the trick. Plaintext searching can get a bit trickier (say, if somebody's decided to break the line right before the 'as', and then uses tabs for indentation), but in most cases ' as ' works. It's how I always search for keywords :-)

But it will still pick up... void set(int) // set class bob as an int :-P whereas with cast you can search for 'cast('

Which will still pick up... foo = bar; // here I don't need to use cast(baz)bar because... ;-)

If you know what type you are looking for. It will take a while to search int = float, bar = foo, char = ubyte, etc. With cast, you just search for 'cast(' and collect them all. IMO, cast() sticks out like a sore thumb, as it should. It's the reason why C style casting was depreciated... int bob = (int)floatnum; It is harder to find this type of cast in the code, I assume 'as' would be a little easier to find than (int), but cast() is uglier and easier to find. Should cast's in D blend nicely with the code and be easy to program? I don't think we want to encourage casting, do we?
Jul 06 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"clayasaurus" <clayasaurus gmail.com> wrote in message
news:dahij9$2v2b$1 digitaldaemon.com...
 If you know what type you are looking for. It will take a while to
 search int = float, bar = foo, char = ubyte, etc. With cast, you just
 search for 'cast(' and collect them all.

 IMO, cast() sticks out like a sore thumb, as it should. It's the reason
 why C style casting was depreciated...

 int bob = (int)floatnum;

 It is harder to find this type of cast in the code, I assume 'as' would
 be a little easier to find than (int), but cast() is uglier and easier
 to find.

 Should cast's in D blend nicely with the code and be easy to program? I
 don't think we want to encourage casting, do we?

You're right. D's cast syntax was deliberately chosen to make it stand out. There's a school of thought that says that a cast is indicative either of poor program design or poor language design. But since D is meant to be a practical language, sometimes it's more practical to cast than redesign the whole program! Nevertheless, since casts are a blunt instrument, they should be used with caution and merit attention in a serious code review. Hence the standout syntax.
Jul 07 2005
parent reply AJG <AJG_member pathlink.com> writes:
Hi,

"clayasaurus" <clayasaurus gmail.com> wrote in message
news:dahij9$2v2b$1 digitaldaemon.com...
 If you know what type you are looking for. It will take a while to
 search int = float, bar = foo, char = ubyte, etc. With cast, you just
 search for 'cast(' and collect them all.

 IMO, cast() sticks out like a sore thumb, as it should. It's the reason
 why C style casting was depreciated...

 int bob = (int)floatnum;

 It is harder to find this type of cast in the code, I assume 'as' would
 be a little easier to find than (int), but cast() is uglier and easier
 to find.

 Should cast's in D blend nicely with the code and be easy to program? I
 don't think we want to encourage casting, do we?

You're right. D's cast syntax was deliberately chosen to make it stand out. There's a school of thought that says that a cast is indicative either of poor program design or poor language design. But since D is meant to be a practical language, sometimes it's more practical to cast than redesign the whole program! Nevertheless, since casts are a blunt instrument, they should be used with caution and merit attention in a serious code review. Hence the standout syntax.

This is a very good point, and I suppose it's a good thing that it does that. However, what about using 'as' for the cases where the cast is less "blunt," like a cast-down? Those aren't always bad design. Maybe for unsigned/signed casts? // Some examples: class Foo {} class Bar : Foo {} class Bob {} Bar bar = new Foo as Bar; // OK. Bar bar = new Bob as Bar; // Wrong. // or: long l = 1; string s = "1"; int i = l as int; // OK. int i = s as int; // Wrong. Cheers, --AJG.
Jul 07 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"AJG" <AJG_member pathlink.com> wrote in message
news:dal5ps$2fcm$1 digitaldaemon.com...
 This is a very good point, and I suppose it's a good thing that it does

 However, what about using 'as' for the cases where the cast is less

 like a cast-down? Those aren't always bad design. Maybe for

 casts?

 // Some examples:
 class Foo {}
 class Bar : Foo {}
 class Bob {}
 Bar bar = new Foo as Bar; // OK.
 Bar bar = new Bob as Bar; // Wrong.

 // or:
 long l = 1;
 string s = "1";
 int i = l as int; // OK.
 int i = s as int; // Wrong.

I just don't see that it adds much over the current cast syntax. Furthermore, there are potential parsing problems as in: s as int**p; Does that parse as (s as int*)*p or (s as int)*(*p) ?
Jul 09 2005
parent Eugene Pelekhay <pelekhay gmail.com> writes:
Walter wrote:
 "AJG" <AJG_member pathlink.com> wrote in message
 news:dal5ps$2fcm$1 digitaldaemon.com...
 
This is a very good point, and I suppose it's a good thing that it does

that.
However, what about using 'as' for the cases where the cast is less

"blunt,"
like a cast-down? Those aren't always bad design. Maybe for

unsigned/signed
casts?

// Some examples:
class Foo {}
class Bar : Foo {}
class Bob {}
Bar bar = new Foo as Bar; // OK.
Bar bar = new Bob as Bar; // Wrong.

// or:
long l = 1;
string s = "1";
int i = l as int; // OK.
int i = s as int; // Wrong.

I just don't see that it adds much over the current cast syntax.

(cast(Interface3)(cast(Interface2)(cast(Interface1)obj).getObjWithInterface2()).getObjWithInterface3()).func(); and (((obj as Interface1).getObjWithInterface2() as Interface2).getObjWithInterface3() as Interface3).func(); or obj.as(Interface1).getObjWithInterface2().as(Interface2).getObjWithInterface3().as(Interface3).func(); IMHO last form is little bit easier to read for human eyes
 Furthermore, there are potential parsing problems as in:
 
     s as int**p;
 
 Does that parse as (s as int*)*p or (s as int)*(*p) ?
 
 

Jul 11 2005
prev sibling parent "Craig Black" <cblack ara.com> writes:
I like "as" also.  Probably will not get into D though.

-Craig 
Jul 07 2005