About syntactic sugar

  • Thread starter Thread starter Sam Kong
  • Start date Start date
S

Sam Kong

Hi,

While discussing C#'s using statement, a guy and I had an argument.
In C# spec (15.13), there's an explanation like the following.

using (R r1 = new R()) {
r1.F();
}

is precisely equivalent to

R r1 = new R();
try {
r1.F();
}
finally {
if (r1 != null) ((IDisposable)r1).Dispose();
}

I think that using statement is just a syntactic sugar.
But the guy doesn't think so.
He has a very narrow definition of syntactic sugar.
He says that doing the same thing doesn't mean it's a syntactic sugar.
He shows examples like the following.

a++ is a syntactic sugar for a = a + 1.
a is a syntactic sugar for *(a + i) in C language.

I want to know what people think.
Would you call "using" statement a syntactic sugar?
If so, why?
If not, why not?

Thanks.

Sam
 
Sure it's syntactic sugar. Generally if you can do the exact same thing two
different ways, one of them (usualy the shorter) is syntactic sugar.

But then who cares? I like syntactic sugar. Anything that my code easier
to read and therefore cheaper to maintain for the next programmer who looks
at it is a good thing.

BTW, a is not the same thing as *(a+i) in C, therefore it is not
syntactic sugar (even though they accomplish the same thing).
 
Everything is sugar over something else. The framework is sugar over win32.
Win32 is sugar over something else. I would use "using" over the manual
method.

--
William Stacey [MVP]

| Hi,
|
| While discussing C#'s using statement, a guy and I had an argument.
| In C# spec (15.13), there's an explanation like the following.
|
| using (R r1 = new R()) {
| r1.F();
| }
|
| is precisely equivalent to
|
| R r1 = new R();
| try {
| r1.F();
| }
| finally {
| if (r1 != null) ((IDisposable)r1).Dispose();
| }
|
| I think that using statement is just a syntactic sugar.
| But the guy doesn't think so.
| He has a very narrow definition of syntactic sugar.
| He says that doing the same thing doesn't mean it's a syntactic sugar.
| He shows examples like the following.
|
| a++ is a syntactic sugar for a = a + 1.
| a is a syntactic sugar for *(a + i) in C language.
|
| I want to know what people think.
| Would you call "using" statement a syntactic sugar?
| If so, why?
| If not, why not?
|
| Thanks.
|
| Sam
|
 
Sam,

That's about as sweet as they come. You can tell it's sugar by looking
at the IL generated.

Brian
 
Maybe its just me but there seems to also be a significant scope
difference between the 2 as well.
 
Sam,

I don't agree, with you, your part is in my idea syntatic sugar because
there is a much easier to write method the other guy did did and therefore
it is better to maintain.

The sugar in your method is that it looks more precise, while that is not
true.

Just my thought,

Cor
 
I want to know what people think.
Would you call "using" statement a syntactic sugar?
If so, why?
If not, why not?

Yes, I'd say it's just syntactic sugar, for precisely the reasons
you've given. I don't regard "syntactic sugar" as a bad thing though :)
 
Steven,

It's not just you. I always thought it strange as well especially
since the specification uses the word "precisely". But, then again, I
don't think scope was the focus of the explanation in that section.

Brian
 
Sure. But I guess what I want to point out is that its not JUST sugar
in this particular argument. There are some scope issues that seriously
differentiate the 2 examples.

I'm not very clued up on the specification though. Perhaps I should
read it some time soon.
 
Yes, there is a scope difference.

Another difference (IIRC) is that the using statement stores away a
reference to the object, so that it can be disposed even if you destroy
the declared reference to it.

If you do this:

using (R r1 = new R()) {
r1.F();
r1 = null;
}

the object will still be disposed properly.
 
IIRC, the "}" in the using just explicitly calls dispose() so there really
is not much magic going on or object storage (the object already exists in
the method scope). using is a nice little pattern that is very helpful.

--
William Stacey [MVP]

| Yes, there is a scope difference.
|
| Another difference (IIRC) is that the using statement stores away a
| reference to the object, so that it can be disposed even if you destroy
| the declared reference to it.
|
| If you do this:
|
| using (R r1 = new R()) {
| r1.F();
| r1 = null;
| }
|
| the object will still be disposed properly.
|
| Steven Nagy wrote:
| > Maybe its just me but there seems to also be a significant scope
| > difference between the 2 as well.
| >
 
Steven said:
Sure. But I guess what I want to point out is that its not JUST sugar
in this particular argument. There are some scope issues that seriously
differentiate the 2 examples.

I guess what I'm saying is that the specification either used wording
that was too strong or didn't accurately represent the expansion.
Obviously, the specification's description and the compiler's behavior
aren't in complete agreement. Now if it said that it was precisely
like the following then I'd be more comfortable with it.

{ // Begin inner scope.
R r1 = new R();
try {
r1.F();
}
finally {
if (r1 != null) ((IDisposable)r1).Dispose();
}
}

So despite what the specification says I think it is nothing more than
a syntactical convenience. A good one I might add :)
I'm not very clued up on the specification though. Perhaps I should
read it some time soon.

I can't say I'm that familiar with it either. I recommend reading the
ECMA version as opposed to the MSDN version. It's a little more
verbose.
 
Sam said:
Hi,

While discussing C#'s using statement, a guy and I had an argument.
In C# spec (15.13), there's an explanation like the following.

By the by, the O'Reilly C# Language Pocket Reference (ISBN: 059600429X)
has a very similar assertion on page 30-31. They don't discuss scope
either.

My opinion is that the try...finally is more immediately understandable,
but that's probably due to my experience with Java and C++.

Undoubtedly, the using() {} is very nice and concise when you have some
experience in C#. To me it well represents the paradigm of managed
code. It is like the other gentleman's example of arrays in C. I could
easily see someone doing *(a+i) in C, but it would really seem out of
place to me in C++ instead of a. I'm tempted to do a benchmark/asm
comparison session with that tho ;)

~Jason

--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top