Naming structs with a variable

C

Chris Nahr

I repeat: this description has confused people in the past. Many
people, in fact. Why continue using a description which has proved to
be confusing?

Because it's technically accurate, in terms of both purpose and
implementation, and being confused by it merely reflects a lack of
knowledge about the CLR. Lack of knowledge should be remedied by
learning, not by redefining existing appropriate terms.

Incidentally, that's exactly what a C++ programmer would say to anyone
who is confused by the very great number of complexities and outright
absurdities of the C++ language and its runtime libraries. :)
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Chris said:
Funny, I could have sworn you could create instances of structs, and
put fields in them, and define methods on them...

You can define properties and methods in an interface to, but that
doesn't make it a "lightweight class".

Classes and structs have similarities, but that doesn't make them the
same. A class can have properties and methods, but that doesn't mean
that anything that can have properties and methods is a class.

Horses have four legs and a tail, but everything that has four legs and
a tails aren't horses...
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Chris said:
Because it's technically accurate, in terms of both purpose and
implementation,

No, it's not. It's a simplified description that gives the illusion of
conveying more insight in the matter than it does.

Saying that a struct is a "lightweight class" needs to be followed by an
explanation what that means. If it isn't, it's not very much short of a lie.
and being confused by it merely reflects a lack of
knowledge about the CLR.

But calling a struct a "leightweight class" makes people believe that
they don't need any deeper knowledge about the CLR, as it makes them
think that they know what a struct really is.
Lack of knowledge should be remedied by
learning, not by redefining existing appropriate terms.

A term is not apropriate if it over-simplifies things so much that it
gives people a false sense of knowledge. Few people will try to learn
more than they believe that they need.
Incidentally, that's exactly what a C++ programmer would say to anyone
who is confused by the very great number of complexities and outright
absurdities of the C++ language and its runtime libraries. :)

Yes, he might. But he wouldn't feed you simplified explanations that
would make you feel that it was a lot simpler than it is.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Bruce said:
No... I have a struct (value type) that contains a reference to an
object (reference type). It's called a Measure, and it is a quantity
(value) coupled with a unit of measure (object instance). The trick is
that the object instance is immutable. This struct allows me to
represent, and perform mathematics and conversions on quantities that
have attached units of measure. So, for example, I can add "5 meters"
to "3 feet" and get a sensible answer.

It's freaky when a value type contains a reference to a changeable
object. That would be a bit weird, because then you would have values
that _could_ change simultaneously when you changed some aspect of one:
sort of hybrid reference and value semantics.

However, holding a reference to an immutable object instance doesn't
present any problems at all.

Yes, immutable objects would be the exception.
 
J

Jon Skeet [C# MVP]

Chris Nahr said:
Because it's technically accurate, in terms of both purpose and
implementation

I wouldn't even say that though. If you have two types which each have
20 instance fields (all ints for the sake of argument). The only
difference between them is that one is a class and one is a struct. You
need to use these types as parameters and return values frequently. Now
which feels like a heavyweight type and which feels lighter?
and being confused by it merely reflects a lack of
knowledge about the CLR. Lack of knowledge should be remedied by
learning, not by redefining existing appropriate terms.

Where exactly is "lightweight class" defined in the first place? It's
not in the C# spec as far as I'm aware - the C# spec gives details
instead of relying on inappropriately brief descriptions.

I don't think it's particularly helpful to use terminology which you
*know* causes confusion on the grounds that people should learn more
about the subject so as to avoid being confused. We get the situation
where there are two types of reader: those who don't already know what
a struct is (who will be confused by your description) and those who do
(who won't gain anything by your description). Where exactly is the
benefit?
Incidentally, that's exactly what a C++ programmer would say to anyone
who is confused by the very great number of complexities and outright
absurdities of the C++ language and its runtime libraries. :)

I don't see why that makes it a good answer.
 
C

Chris Nahr

You can define properties and methods in an interface to, but that
doesn't make it a "lightweight class".

Correct, instead it makes the interface a purely abstract class since
you can't create an instance of it. Purely abstract classes is how
you emulate interfaces in C++ which doesn't have this construct.
Classes and structs have similarities, but that doesn't make them the
same. A class can have properties and methods, but that doesn't mean
that anything that can have properties and methods is a class.

You might want to read an introduction to OOP, and also look up the
base class of System.ValueType in the MSDN documentation.
 
C

Chris Nahr

I wouldn't even say that though. If you have two types which each have
20 instance fields (all ints for the sake of argument). The only
difference between them is that one is a class and one is a struct. You
need to use these types as parameters and return values frequently. Now
which feels like a heavyweight type and which feels lighter?

Practical experience with a given struct has no bearing on what I
said. Structs exist for the purpose of being more lightweight than
classes, and that purpose is reflected in their implementation.
Where exactly is "lightweight class" defined in the first place? It's
not in the C# spec as far as I'm aware - the C# spec gives details
instead of relying on inappropriately brief descriptions.

First, a literal reference from an authoritative source:

MSDN Library, "C# Programming Guide":
"A struct can be considered a lightweight class, ideal for creating
data types that store small amounts of data, and does not represent a
type that might later be extended via inheritance."
http://msdn2.microsoft.com/en-us/library/ms173109.aspx

Interestingly, C++/CLI uses the keywords "value class" as opposed to
"ref class" = reference type. Here's a paper on the subject by Rex
Jaeschke, standards editor for C++/CLI, CLI, and C#:

Rex Jaeschke, "A lightweight class mechanism", Dr. Dobb's Journal:
"The value class is a lightweight C++/CLI class mechanism that is
particularly useful for reasonably small data structures that have
value semantics."
http://www.ddj.com/dept/cpp/184401955

And here are a number of references that call structs "lightweight"
although they avoid the term "class" since it's already used as a
synonym for "reference type" in the context of the explanation:

MSDN Library, "C# Programmer's Reference":
"The struct type is suitable for representing lightweight objects such
as Point, Rectangle, and Color. Although it is possible to represent a
point as a class, a struct is more efficient in some scenarios."
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csref/html/vcrefStructTypes.asp

Jeff Richter, "CLR via C#", Microsoft Press, page 124:
"To improve performance for siple, frequently used types, the CLR
offers light-weight types called value types."

Steven Holzner, "Object-Oriented Programming in C#", Sams:
"Structs in C# are like lightweight versions of classes. [...] They
take up fewer resources in memory, so when you've got a small,
frequently used class, give some thought to using a struct instead."
http://www.samspublishing.com/articles/article.asp?p=101373&seqNum=9&rl=1

Fahad Gilani, MSDN Magazine, "C# in Depth" series:
"For scientific applications, value types can be fast, efficient, and
an excellent choice over reference types whenever possible. In the
next section, I'll take a look at one of the many uses of user-defined
lightweight data types in scientific programming."
http://msdn.microsoft.com/msdnmag/issues/04/03/ScientificC/

Other sources do not use the literal term "lightweight" but still
highlight the cheapness and efficiency of value types as compared to
reference types when introducing the concept:

Eric Gunnerson & Nick Wienholt, "A Programmer's Introduction to C#",
Apress, page 79:
"Sometimes, however, it may be desirable to crate an object that
behaves like one of the built-in types -- one that's cheap and fast to
allocate and doesn't have the overhead of references."

Don Box with Chris Sells, "Essential .NET vol. 1", Addison-Wesley,
p.133:
"In particular, instances of value types do not carry the storage
overhead of full-blown objects. This makes value types useful in
scenarios where the costs of an object would otherwise be
prohibitive."

So I hope we can agree that structs are, in fact, commonly introduced
as lightweight types in the literature. The motivation is in fact to
have a type that is less expensive than a reference type.
I don't think it's particularly helpful to use terminology which you
*know* causes confusion on the grounds that people should learn more
about the subject so as to avoid being confused. We get the situation
where there are two types of reader: those who don't already know what
a struct is (who will be confused by your description) and those who do
(who won't gain anything by your description). Where exactly is the
benefit?

Like the cited authors, I don't share your opinion that readers who
don't already know about structs will invariably be confused about the
"lightweight" moniker. Again, I think it's accurate and helpful.

When I was learning C# I found this characterisation appropriate and
useful in forming a mental concept of the purpose and implementation
of structs. The copy-on-pass semantics are always highlighted in the
vicinity of such an introduction, so I never had a problem with that.

Frankly, I don't see why we should give any regard to people who run
off and implement something (badly) after seeing a single adjective-
noun pair, as if that would explain everything! Of course it doesn't,
but what kind of programmer would assume that it does?
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Chris said:
Correct, instead it makes the interface a purely abstract class since
you can't create an instance of it.

No, it doesn't. You can inherit mutliple interfaces, but not multiple
classes, no matter how abstract they are.
Purely abstract classes is how
you emulate interfaces in C++ which doesn't have this construct.


You might want to read an introduction to OOP, and also look up the
base class of System.ValueType in the MSDN documentation.

An introduction to OOP? Well, I might have read one when I started using
OOP in the late eighties, has it changed much?

Why would I look up the base class of System.ValueType? Don't you think
that I know what the base class of System.ValueType is?
 
R

Rick Lones

Chris said:
But they should! That's a correct description! Microsoft introduced
structs in the first place because they are more efficient than
classes for small data containers such as numerical types, and they
are more efficient because their implement is in fact comparatively
lightweight -- no heap allocation (for locals), no object wrapper.

This is just silly, Chris. Structures in programming languages have been around
for longer than C, longer than object orientation, longer than C++, and WAY
longer than Microsoft. M/S did not "introduce" structs - and if anything the C#
usage perverts the concept.
What you guys are talking about are really just faulty assumptions on
the part of programmers who believe in silver bullets and don't stop
to think "gee, if structs are all-around better than classes then why
do classes exist at all?".

Because once you do stop to ask yourself that question it's pretty
blatantly obvious that a lightweight class is going to have _some_
disadvantage that prevents it from being used universally...

There's a lot to learn when you switch from C++ to C#. The meaning of
"struct" is just one part of it, and not a particularly difficult one
IMO. Maybe it can serve as a useful reminder that the C++ language
has not in fact monopolized the naming and semantics of all
programming constructs, the belief of its fans to the contrary. :)

Not everybody comes to C# from C++. Some may come from C. When I code "struct
Foo {...};" in a function body I am most likely declaring a local value type.
But when I code "typedef struct {...} *pFoo;" in a header I am describing the
layout of storage that I expect to access via a reference (aka a pointer).

It's likewise with older constructs such as PL/1 "based" storage and even IBM
360 DSECTs. These were abstract descriptions of storage, templates if you will.
(Yikes! - another loaded word.) Once the structure was "instantiated" by
allocating memory and returning a pointer that pointer got used much like a C#
reference.

Anyhow, although it's surely *historically* inaccurate to call a structure a
"lightweight class" this is not the real difficulty. If I describe classes as
"structures extended with methods", have I conveyed anything useful about what a
class is or how objects are used? Or have I just propagated a misleading
analogy which obscures the underlying real difference. Calling a structure a
lightweight class gives a misleading impression of how it behaves in certain key
ways.

C# structs look confusingly too much like classes as it is IMO, what with having
constructors and being instantiated with the "new" keyword. They are neither
true classes, nor do they really behave like the constructs formerly known as
structs either. I think I agree with those who wish C# style structs had just
been called something else entirely.

Regards,
-rick-
 
J

Jon Skeet [C# MVP]

Chris Nahr said:
Practical experience with a given struct has no bearing on what I
said. Structs exist for the purpose of being more lightweight than
classes, and that purpose is reflected in their implementation.

Except when you use them as parameters, return values, or use
assignment.

I would agree if you'd just said that structs are lighter weight
allocation and release, and can use less memory when a single value is
only used in one place. However, just calling them "lightweight
classes" implies (to me at least) that they're lighter *in general*
which clearly isn't true in reality. There are plenty of ways in which
using them is "heavier" than using classes, so the generalisation isn't
accurate IMO.
First, a literal reference from an authoritative source:

MSDN Library, "C# Programming Guide":
"A struct can be considered a lightweight class, ideal for creating
data types that store small amounts of data, and does not represent a
type that might later be extended via inheritance."
http://msdn2.microsoft.com/en-us/library/ms173109.aspx

Are, MSDN - that authoritative source which claimed for a long time
that System.Decimal was a fixed-point number type.

It's even wrong about saying its "ideal for creating data types that
store small amounts of data" - again, that ignores the whole value
semantics vs reference semantics which is surely at the heart of the
differences between structs and classes. If you want reference
semantics, you should use classes even if there's only a small amount
of data.
Interestingly, C++/CLI uses the keywords "value class" as opposed to
"ref class" = reference type.

The CLI spec uses different terminology for various things. This
shouldn't come as much of a surprise, although it occasionally causes a
lot of confusion.

And here are a number of references that call structs "lightweight"
although they avoid the term "class" since it's already used as a
synonym for "reference type" in the context of the explanation:

<snip>

I could give plenty of examples of early Java textbooks which claimed
that Java passed objects by reference - that wouldn't make them any
less confusing or any more accurate.
So I hope we can agree that structs are, in fact, commonly introduced
as lightweight types in the literature. The motivation is in fact to
have a type that is less expensive than a reference type.

I agree that they're commonly introduced as lightweight types. Now, do
you want me to find you a similar number of posts from people who have
been confused by that terminology? Just because lots of people use a
certain description doesn't make it accurate or useful. Heck, lots of
people talk about ASCII as if it had 256 characters in it. Are they
right too, just because there are lots of them?
Like the cited authors, I don't share your opinion that readers who
don't already know about structs will invariably be confused about the
"lightweight" moniker. Again, I think it's accurate and helpful.

It's accurate when the "lightweight" bit is qualified to allocation.
It's possibly helpful when it's in the context of a wider description.
On newsgroups, however, it's often left as the *whole* of the
description of structs, which is what I really object to.
When I was learning C# I found this characterisation appropriate and
useful in forming a mental concept of the purpose and implementation
of structs. The copy-on-pass semantics are always highlighted in the
vicinity of such an introduction, so I never had a problem with that.

No, those semantics *aren't* always highlighted - that's the problem.
Often structs are *just* described as "lightweight classes", and that's
where people get confused.
Frankly, I don't see why we should give any regard to people who run
off and implement something (badly) after seeing a single adjective-
noun pair, as if that would explain everything! Of course it doesn't,
but what kind of programmer would assume that it does?

So you're happy to confuse people by using an overly simplistic
description, knowing that some people *will* take that as sufficient
evidence to base decisions on? I prefer to do my utmost to make sure I
won't leave people with the wrong impression.
 
C

Chris Nahr

This is just silly, Chris. Structures in programming languages have been around
for longer than C, longer than object orientation, longer than C++, and WAY
longer than Microsoft. M/S did not "introduce" structs - and if anything the C#
usage perverts the concept.

When I say "Microsoft introduced structs" I obviously mean "Microsoft
introduced value types to .NET, aka C# structs" because that's the
context of this discussion. I can't believe I have to explain this.

There is nothing holy about the name "struct". They are obviously not
identical with "structures" in older languages, and the historical
meaning of "structure" is so vague anyway that there is hardly a
pre-existing "concept" to "pervert" here.
Not everybody comes to C# from C++. Some may come from C.

Yes, thank you, I had been programming in C before I moved on to C++,
too. I also know Pascal and Fortran and x86 assembler. But I never
expect one concept in one programming language to work identically to
another concept in another programming language just because of a
similar name.

We're talking exclusively in the concept of C# and .NET here. Your
knowledge of PL/1 and whatnot is completely irrelevant, and I suspect
you must get confused a lot if you always try to understand one
language in terms defined by a different language. It's this habit
that's the source of your confusion, not Microsoft's naming decisions.
Anyhow, although it's surely *historically* inaccurate to call a structure a
"lightweight class" this is not the real difficulty.

Good thing nobody calls "a structure a lightweight class", then.
Instead, we call the specific C# construct known as "struct", aka
value type, a lightweight class.
If I describe classes as
"structures extended with methods", have I conveyed anything useful about what a
class is or how objects are used?

Yes, you have. If you pick up any OOP book you'll see that "data plus
operations" is in fact the standard introductory description for
classes. Shall I list a bunch of citations for that, too?
C# structs look confusingly too much like classes as it is IMO

Gee, maybe that's because they are in fact a variant of classes, eh?
Please read an OOP book instead of relying on your knowledge of PL/1
for the rest of your professional carreer!
 
C

Chris Nahr

There is an OOP concept known as "class". This OOP concept comprises
the C# constructs "class" and "interface" and "struct", all of which
are different implementations of the OOP concept known as "class".

Furthermore, since the C# "class" is the most commonly used
implementation of the OOP concept "class" (which is why it got the
same name!), it is also appropriate to introduce the C# "interface"
and "struct" as variants of the C# "class". Which they actually are
if you look at the IL or the base class of System.ValueType.

Of course there are differences, otherwise there wouldn't be different
concepts in the first place, now would there? That's no reason to act
as if those concepts were somehow incomparable.
 
C

Chris Nahr

Except when you use them as parameters, return values, or use
assignment.

As long as your struct is no larger than an IntPtr it's no more
expensive than a class. Smaller structs may be less expensive, even.
I would agree if you'd just said that structs are lighter weight
allocation and release, and can use less memory when a single value is
only used in one place. However, just calling them "lightweight
classes" implies (to me at least) that they're lighter *in general*
which clearly isn't true in reality. There are plenty of ways in which
using them is "heavier" than using classes, so the generalisation isn't
accurate IMO.

To me, the term "lightweight" already implies that this construct is
to be used for small amounts of data which negates the potential cost
of copying on calls & assignments.

As for the references, I'm not going to discuss them. You asked
incredulously where this term came from, and I showed you. Your
arguing that all those sources are incorrect is just a rehash of the
rest of the discussion -- needless to say, I disagree.
I agree that they're commonly introduced as lightweight types. Now, do
you want me to find you a similar number of posts from people who have
been confused by that terminology? Just because lots of people use a
certain description doesn't make it accurate or useful. Heck, lots of
people talk about ASCII as if it had 256 characters in it. Are they
right too, just because there are lots of them?

Don't be ridiculous. This discussion is about a conceptual term, not
about a technical statement that can be true or false. And the
sources I gave were MSDN, Microsoft employees, and published authors,
not random Usenet posters.
It's accurate when the "lightweight" bit is qualified to allocation.
It's possibly helpful when it's in the context of a wider description.
On newsgroups, however, it's often left as the *whole* of the
description of structs, which is what I really object to.

And you may well object but that's a specific problem with those
newsgroup posts that fail to highlight the quirks and costs of
structs. It doesn't affect the usefulness of "lightweight" per se.

When a standard OOP book says that classes are data plus operations
that's not an exhaustive description of classes either, but it's still
a great introduction to the concept. That's how I feel about the term
"lightweight classes", too.
So you're happy to confuse people by using an overly simplistic
description, knowing that some people *will* take that as sufficient
evidence to base decisions on? I prefer to do my utmost to make sure I
won't leave people with the wrong impression.

Some people are always confused. Rather than spending my time on
elaborate explanations I'd rather they crash and burn with their hasty
decisions. Perhaps that will eventually teach them to improve their
decision-making process. Basing an implementation on a soundbite is a
ridiculous and unacceptable attitude towards programming.
 
W

Willy Denoyette [MVP]

| On Sat, 13 May 2006 16:50:04 -0400, Rick Lones
|

| Good thing nobody calls "a structure a lightweight class", then.
| Instead, we call the specific C# construct known as "struct", aka
| value type, a lightweight class.
|

Chris, I could live with it when it was consistently refered to as "a
lightweight type", 'class' is way too specific in C#, as it (wrongly)
implies reference type semantics.

Willy.
 
B

Bill Butler

To me, the term "lightweight" already implies that this construct is
to be used for small amounts of data which negates the potential cost
of copying on calls & assignments.

Perhaps that is the reason for the disagreement. Traditionally
speaking, the term "lightweight class" has NOTHING to do with the actual
data in the "lightweight class". The phrase tends to refer to the bells
and whistles that comes along with your object (Heap allocation,
inheritance, etc). The fact that small objects are a better fit for
structs is a by-product of the way they are implemented in C#.
A very common use for structs in C++ is when your object is little
more than a data holder. Few, if any methods. No need for inheritance.
So they create a struct with no virtual methods and the create it on the
stack and not the heap. The net result is a more efficient
implementation for their needs. The fact that the actual data may have
some girth, rarely enters the picture. Why? because they don't intend to
copy it all over the place. If they have to, they can pass it as a
pointer.

Some people are always confused. Rather than spending my time on
elaborate explanations I'd rather they crash and burn with their hasty
decisions. Perhaps that will eventually teach them to improve their
decision-making process. Basing an implementation on a soundbite is a
ridiculous and unacceptable attitude towards programming.

Wow, that's a pretty crappy attitude you have there.
I, personally, attempt to help other people if I can.
 
B

Bruce Wood

When I say "Microsoft introduced structs" I obviously mean "Microsoft
introduced value types to .NET, aka C# structs" because that's the
context of this discussion. I can't believe I have to explain this.

Hey, I had to explain that when I said that I had never found a
situation so compelling that I decided to
use a "struct" for efficiency reasons, that I wasn't talking about
native types. Live by the sword, die by the sword. :)
 
J

Jon Skeet [C# MVP]

<snip>

I think we've reached the end of any productive discussion. Probably
best to just leave it there. I can't see us agreeing about this any
time in the near future.
 
A

Alvin Bruney

<snip>
Some people are always confused. Rather than spending my time on
elaborate explanations I'd rather they crash and burn with their hasty
decisions. Perhaps that will eventually teach them to improve their
decision-making process. Basing an implementation on a soundbite is a
ridiculous and unacceptable attitude towards programming.
</snip>

I agree. This is a good summation of the issue. Jon expects to eliminate
this entirely for each and every confused programmer case. It's not
possible. If you make a decision to use a structure in an application based
on a soundbyte, you deserve what you get for being irresponsible - assuming
code reviewers don't catch the problem and inform you of it before it hits
production.

--

________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
-------------------------------------------------------
 
A

Alvin Bruney

I think we've reached the end of any productive discussion. Probably
best to just leave it there. I can't see us agreeing about this any
time in the near future.

ah but the discussion has been very spirited.

I think we can agree that
1. The existing literature establishes the ground rules.
2. It's too late to change the established ground rules even without regard
to the fact that they may or may not be correct.
3. Concepts defined within the C# language should not be viewed within the
context of other languages.
4. Programmers must understand language facets in detail before using these
constructs in production code especially where these constructs may have
have performance consequences or may be used in time-sensitive applications.
5. Happy mother's day to the ladies on the list with child. (we all can
surely agree on that one in particular)

--

________________________
Warm regards,
Alvin Bruney [MVP ASP.NET]

[Shameless Author plug]
Professional VSTO.NET - Wrox/Wiley
The O.W.C. Black Book with .NET
www.lulu.com/owc, Amazon
Blog: http://www.msmvps.com/blogs/alvin
 
L

Lucian Wischik

Alvin Bruney said:
5. Happy mother's day to the ladies on the list with child. (we all can
surely agree on that one in particular)

UK - "Mothering Sunday" not Mother's Day - March 26th
Norway - second sunday in February
Spain - first sunday in May
Argentina - second sunday in october
Panama - December 8th

!!!

from wikipedia.org
 

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

Top