469,366 Members | 2,242 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,366 developers. It's quick & easy.

Boxing and Unboxing ??

According to Troelsen in "C# and the .NET Platform"
"Boxing can be formally defined as the process of explicitly converting a value
type into a corresponding reference type."

I think that my biggest problem with this process is that the terms "value type"
and "reference type" mean something entirely different than what they mean on
every other platform in every other language. Normally a value type is the
actual data itself stored in memory, (such as an integer) and a reference type
is simply the address of this data.

It seems that .NET has made at least one of these two terms mean something
entirely different. can someone please give me a quick overview of what the
terms "value type" and "reference type" actually mean in terms of their
underlying architecture?
Jan 12 '07
161 6551
Peter Olcott <No****@SeeScreen.comwrote:
You wish to switch to a dotnet based solution to reduce the development time,
but you don't want to put the time in to learning the language(C#). Sounds to
me like you are doomed to failure anyway.

I can only put in a little time to learn the language now. I am focusing this
time on assessing the feasibility of using C# and .NET for my future needs. It
looks like C# does have the performance that I need. In order to get this
performance, I must use relatively obscure nuances of C# that are barely
mentioned in even the most comprehensive textbooks. Specifically because of this
newsgroup thread, I was able to learn these relatively obscure nuances. It
definitely looks like C# and .NET will be the future of essentially ALL MS
Windows development.
No, in order to get good performance you need to accept things like
"don't make huge value types". That's a much better solution than
creating a large value type and passing it by reference.

Please, just try to work *with* the platform instead of fighting
against it.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 15 '07 #101
Hi,

|
| I still don't see any reason why a completely type safe language can not
be
| constructed without the need for any runtime overhead. You could even
allow
| construct such as the above, and still be completely type safe, merely
disallow
| type casting.

You cannot, Type casting is in the core of OOP , IIRC all the languages
support it in some form.
| Global data is disallowed?

Depend of what you understand for that? You can have a data that is
accesible from anywhere in your program. Does this satisfy your globallity?

Jan 15 '07 #102
Hi,

"Peter Olcott" <No****@SeeScreen.comwrote in message
news:oh******************@newsfe15.phx...
| So with Generics Boxing and UnBoxing beomes obsolete?

Not at all.

Generics simply offer the mechanisn for you not to be forced to use a
"cover all instances type" type when you declare a class. Before generics
you used to declare collections as storing objects. as you knew for sure
that EVERYTHING could be converted to an object reference (this imply boxing
with value types). This allowed you to write ONE ArrayList class and use it
with any kind of types.
Of course you could always write one for each value type plus one for
references type this would prevent boxing/unboxing

Now with generic you are taking the second approach one level further. It's
the compiler now who create that class for you at compile time.
But boxing/unboxing will still be there, forever and ever :)
Jan 15 '07 #103

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Peter Olcott <No****@SeeScreen.comwrote:
You wish to switch to a dotnet based solution to reduce the development
time,
but you don't want to put the time in to learning the language(C#). Sounds
to
me like you are doomed to failure anyway.

I can only put in a little time to learn the language now. I am focusing this
time on assessing the feasibility of using C# and .NET for my future needs.
It
looks like C# does have the performance that I need. In order to get this
performance, I must use relatively obscure nuances of C# that are barely
mentioned in even the most comprehensive textbooks. Specifically because of
this
newsgroup thread, I was able to learn these relatively obscure nuances. It
definitely looks like C# and .NET will be the future of essentially ALL MS
Windows development.

No, in order to get good performance you need to accept things like
"don't make huge value types". That's a much better solution than
creating a large value type and passing it by reference.
There are some cases where this suggestion would be bad design. The case in mind
is similar to the cases where a "friend" function is used in C++.
Please, just try to work *with* the platform instead of fighting
against it.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too

Jan 15 '07 #104

"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.comwrote in
message news:O4**************@TK2MSFTNGP06.phx.gbl...
Hi,

|
| I still don't see any reason why a completely type safe language can not
be
| constructed without the need for any runtime overhead. You could even
allow
| construct such as the above, and still be completely type safe, merely
disallow
| type casting.
I was not referring to polymorphic type casting. I was referring to such things
such as casting an integer to a function pointer.
You cannot, Type casting is in the core of OOP , IIRC all the languages
support it in some form.
Does polymorphic type casting require an explicitly specified cast, or could
this possibly be implicitly performed behind the scenes?
>

| Global data is disallowed?

Depend of what you understand for that? You can have a data that is
accesible from anywhere in your program. Does this satisfy your globallity?

Jan 15 '07 #105

"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.comwrote in
message news:up**************@TK2MSFTNGP04.phx.gbl...
Hi,

"Peter Olcott" <No****@SeeScreen.comwrote in message
news:oh******************@newsfe15.phx...
| So with Generics Boxing and UnBoxing beomes obsolete?

Not at all.

Generics simply offer the mechanisn for you not to be forced to use a
"cover all instances type" type when you declare a class. Before generics
you used to declare collections as storing objects. as you knew for sure
that EVERYTHING could be converted to an object reference (this imply boxing
with value types). This allowed you to write ONE ArrayList class and use it
with any kind of types.
Of course you could always write one for each value type plus one for
references type this would prevent boxing/unboxing

Now with generic you are taking the second approach one level further. It's
the compiler now who create that class for you at compile time.
But boxing/unboxing will still be there, forever and ever :)
I don't think so.
>

Jan 15 '07 #106
Peter Olcott wrote:
"Larry Lard" <la*******@googlemail.comwrote in message
news:51*************@mid.individual.net...
>Peter Olcott wrote:
>>By working 90 hours a week, I am still 80 hours a week short of what I need
to get done.
You realise this means you are doomed to failure?

It means that I can't afford to waste any time, and must find shortcuts to
achieve the required end-results.
If you can not afford to waste time, then shortcuts are too risky.

Arne
Jan 15 '07 #107
Peter Olcott wrote:
It
definitely looks like C# and .NET will be the future of essentially ALL MS
Windows development.
C# and to some extent VB.NET will take over most of Windows
development that are not required to be highly portable to
other OS's or required to access hardware very directly.

But hopefully the people writing the code will have
time to read about and understand C# and .NET.

Arne

Jan 15 '07 #108
Peter Olcott wrote:
"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.comwrote in
>But boxing/unboxing will still be there, forever and ever :)
I don't think so.
In C# it will.

Arne
Jan 15 '07 #109
Peter Olcott wrote:
Add [in] remove [ref] the net difference is no more elements. However we are
adding one simple parameter qualifier and removing a complex qualifier.
You *never* remove features from a language.
There is no useful distinction between [ref] and [out].
There is a semantic difference in that code exist where one
of them will give a compiler error and the other will not.

There is a clear indication of different intentions by
using the two different keywords.

You may not find the distinction useful, but that does
not preclude that other people do.

Arne

Jan 15 '07 #110

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>"Larry Lard" <la*******@googlemail.comwrote in message
news:51*************@mid.individual.net...
>>Peter Olcott wrote:
By working 90 hours a week, I am still 80 hours a week short of what I need
to get done.
You realise this means you are doomed to failure?

It means that I can't afford to waste any time, and must find shortcuts to
achieve the required end-results.

If you can not afford to waste time, then shortcuts are too risky.

Arne
That depends on what the short cuts are. One of my shortcuts was to embed a
third party computer language in my product rather than write my own computer
language from scratch. Another short-cut is forming a partnership with an
existing marketing company, rather than handling the direct sales myself.
Jan 15 '07 #111
Peter Olcott wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
>If the programmer wants to inside his/her head to see the
native instructions for the code being written (as was the
case in the post I commented on), then I don't think
C# is the right choice.

If a C# programmer lacks the ability to see inside his head the underlying
machine code corresponding to the specified C# code, then this programmer lacks
a sufficient understanding of C# and .NET.
This is not the 1980's.

Leave that stuff to the compiler and runtime library writers.
For business apps that read and write text to databases, this won't make much of
a difference. To the author of the database management system itself, this makes
a significant difference. The difference is between excellent quality and
mediocrity.
No. The performance of a database is not determined by optimizing
code based on micro benchmarking. It is determined by high level
design of locking, caching, query plan etc..

Arne
Jan 15 '07 #112

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:45***********************@news.sunsite.dk...
Peter Olcott wrote:
>Add [in] remove [ref] the net difference is no more elements. However we are
adding one simple parameter qualifier and removing a complex qualifier.

You *never* remove features from a language.
Ever hear of deprecation?
>
>There is no useful distinction between [ref] and [out].

There is a semantic difference in that code exist where one
of them will give a compiler error and the other will not.

There is a clear indication of different intentions by
using the two different keywords.
I think that it is possible to take the .NET platform one large step further in
its abstraction of the underlying details. This large step would be to make the
issue of reference type and value type so transparent to the end user of the
respective languages that no one except .NET compiler writers even need bother
to learn the difference between them.

>
You may not find the distinction useful, but that does
not preclude that other people do.

Arne

Jan 15 '07 #113
Barry Kelly wrote:
Arne Vajhøj wrote:
>For interop you obvious need to know something about
the native stuff to use the functionality. That is not
"looking under the hood".

I think doing a lot of interop effectively requires a fair amount of
knowledge of what the CLR is doing. In particular, there are some almost
sneaky things the CLR can do, such as the GC collecting your class
before its methods finished executing, that can cause insidious bugs.
True.

But that is still interface/functional not really
"under the hood".
>Regarding getting maximum performance then it can
be necessary to look under the hood, but it can also
be dangerous. Often you end up optimizing for current
.NET version on your current PC. Performance characteristics
for the .NET versions and the hardware being used in the
codes life time may be significantly different.

Perhaps, but I doubt things like Windows, CPUs and caches / memory
hierarchies are going away anytime soon, and you need to have an idea of
the behaviour of those guys, even if it's simple rules of thumb, like
"row-then-column" rather than "column-then-row" when iterating through
large 2D arrays, or writing asynchronous code to avoid thread-switching
overhead, etc.
I can agree on that.

There are something that are good to do on almost any current
or future within a reasonable time horizon.

I say stop when we come to optimizing stuff for x86, x86-64, IA-64 etc..
>If the programmer wants to inside his/her head to see the
native instructions for the code being written (as was the
case in the post I commented on), then I don't think
C# is the right choice.

Sure, if one is tweaking one's code so it inlines "just so", or adds
comments like:

// not creating variable for this expression because it forces
// register spill to stack

... then I think one is going to far, I agree.
That is a good example of something that will be completely
different on x86, x86-64 and IA-64 due to different number
of registers.

Arne
Jan 15 '07 #114
Peter Olcott wrote:
"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11**********************@a75g2000cwd.googlegr oups.com...
Peter Olcott wrote:
That last subtle distinction is why discussing these things in a newsgroup is
much more effective than merely reading books. I have a very good 1,000 page
book that never bothers to mention this distinction. In any case it would
still
seem that adding an [in] parameter qualifier might be an improvement.
I don't see the advantage. If you leave the qualifiers off, the
parameter is already "in" by default. Optimizations like the one you're

Its pass by value, which is not the same thing as "in" by default. My suggestion
is to make [in] pass by address, and read-only exactly equivalent to:
ReturnType (const ValueType&, VariableName) // C++
proposing can just as well be handled by the CLR detecting that a large
value-type parameter is never modified, and deciding internally to pass
it by reference instead of copying. Adding an extra language keyword to

Is it read-only? If its not read-only, then its not the same.
Correct: it's not the same, it's better.

Making the parameter read-only is a pointless restriction on the
programmer. The need for it to be read-only is a side effect of the
fact that it's being passed by reference. But the CLR can already
detect whether the parameter is, in fact, modified within the method,
and simply pass value types by reference to the methods where they
aren't modified. Sometimes you need to modify a parameter, and
sometimes you don't; by leaving the optimization up to the CLR, you can
automatically get the benefits when possible without having to change
your code.

Jesse

Jan 16 '07 #115
Peter Olcott wrote:
"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.comwrote in
message news:up**************@TK2MSFTNGP04.phx.gbl...
Generics simply offer the mechanisn for you not to be forced to use a
"cover all instances type" type when you declare a class.
[...]
But boxing/unboxing will still be there, forever and ever :)
I don't think so.
Well, boxing certainly won't be removed from .NET, for the obvious
practical reason that a ton of code already depends on it, and so does
much of the OOP design philosophy of .NET. All types derive from
System.Object, and the only way to do that without boxing would be to
make all types into reference types, which would kill performance.

Generics don't eliminate the need for, or usefulness of, boxing. Boxing
is necessary when you need to fit arbitrary values into one type;
generics eliminate some of those cases by constraining the type
automatically, but there are still times when generics are impractical
or don't help at all.

For example, the Tag property of visual controls is an object property,
so it can store a string, an integer, an instance of your own class,
etc., depending on how you want to use that particular control. Doing
that with generics would mean specializing each control class for each
possible tag type - you'd have Button<intwhose Tag property is an
integer, Button<stringto hold strings, etc... and even then, you'd be
limiting the usefulness of the class, because today the very same
button instance can hold an int one minute and a string the next.

Another example: the reflection methods to invoke a method dynamically
from a MethodInfo. You pass in the parameters as object[], which means
any value type parameters have to be boxed. How would you do that with
generics? Every element of the array has to have the same type, but the
method probably doesn't use the same type for each parameter. You might
think about replacing the single invocation method with a tedious
series of generic methods:

Invoke<A>(MethodInfo mi, A arg1)
Invoke<A,B>(MethodInfo mi, A arg1, B arg2)
Invoke<A,B,C>(MethodInfo mi, A arg1, B arg2, C arg3)
and so on

.... but that introduces a number of problems: (1) you'd be limiting the
number of parameters you can pass to the method, because no matter how
many different versions of Invoke you write, each one still only has a
finite number of parameters; (2) you'd need to know the number of
parameters at compile time, whereas today the number of parameters is
determined at runtime by the length of the array you pass in; (3) you'd
complicate any code surrounding a call to Invoke, and probably
complicate Invoke itself, and certainly waste a lot of memory storing
all the different forms of the Invoke method and their specializations.

Jesse

Jan 16 '07 #116

"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11*********************@a75g2000cwd.googlegro ups.com...
Peter Olcott wrote:
>"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11**********************@a75g2000cwd.googleg roups.com...
Peter Olcott wrote:
That last subtle distinction is why discussing these things in a newsgroup
is
much more effective than merely reading books. I have a very good 1,000
page
book that never bothers to mention this distinction. In any case it would
still
seem that adding an [in] parameter qualifier might be an improvement.

I don't see the advantage. If you leave the qualifiers off, the
parameter is already "in" by default. Optimizations like the one you're

Its pass by value, which is not the same thing as "in" by default. My
suggestion
is to make [in] pass by address, and read-only exactly equivalent to:
ReturnType (const ValueType&, VariableName) // C++
proposing can just as well be handled by the CLR detecting that a large
value-type parameter is never modified, and deciding internally to pass
it by reference instead of copying. Adding an extra language keyword to

Is it read-only? If its not read-only, then its not the same.

Correct: it's not the same, it's better.

Making the parameter read-only is a pointless restriction on the
programmer.
If this statement was true, then C++ would have never added [const], since C++
did add [const] therefore this statement is not true.
The need for it to be read-only is a side effect of the
fact that it's being passed by reference. But the CLR can already
detect whether the parameter is, in fact, modified within the method,
and simply pass value types by reference to the methods where they
aren't modified. Sometimes you need to modify a parameter, and
sometimes you don't; by leaving the optimization up to the CLR, you can
automatically get the benefits when possible without having to change
your code.

Jesse

Jan 16 '07 #117

"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11**********************@l53g2000cwa.googlegr oups.com...
Peter Olcott wrote:
>"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.comwrote in
message news:up**************@TK2MSFTNGP04.phx.gbl...
Generics simply offer the mechanisn for you not to be forced to use a
"cover all instances type" type when you declare a class.
[...]
But boxing/unboxing will still be there, forever and ever :)
I don't think so.

Well, boxing certainly won't be removed from .NET, for the obvious
practical reason that a ton of code already depends on it, and so does
much of the OOP design philosophy of .NET. All types derive from
System.Object, and the only way to do that without boxing would be to
make all types into reference types, which would kill performance.

Generics don't eliminate the need for, or usefulness of, boxing. Boxing
is necessary when you need to fit arbitrary values into one type;
generics eliminate some of those cases by constraining the type
automatically, but there are still times when generics are impractical
or don't help at all.

For example, the Tag property of visual controls is an object property,
so it can store a string, an integer, an instance of your own class,
etc., depending on how you want to use that particular control. Doing
that with generics would mean specializing each control class for each
possible tag type - you'd have Button<intwhose Tag property is an
integer, Button<stringto hold strings, etc... and even then, you'd be
limiting the usefulness of the class, because today the very same
button instance can hold an int one minute and a string the next.

Another example: the reflection methods to invoke a method dynamically
from a MethodInfo. You pass in the parameters as object[], which means
any value type parameters have to be boxed. How would you do that with
generics? Every element of the array has to have the same type, but the
method probably doesn't use the same type for each parameter. You might
think about replacing the single invocation method with a tedious
series of generic methods:

Invoke<A>(MethodInfo mi, A arg1)
Invoke<A,B>(MethodInfo mi, A arg1, B arg2)
Invoke<A,B,C>(MethodInfo mi, A arg1, B arg2, C arg3)
and so on

... but that introduces a number of problems: (1) you'd be limiting the
number of parameters you can pass to the method, because no matter how
many different versions of Invoke you write, each one still only has a
finite number of parameters; (2) you'd need to know the number of
parameters at compile time, whereas today the number of parameters is
determined at runtime by the length of the array you pass in; (3) you'd
complicate any code surrounding a call to Invoke, and probably
complicate Invoke itself, and certainly waste a lot of memory storing
all the different forms of the Invoke method and their specializations.

Jesse
Ah so the boxing and unboxing overhead that does not cost very much adds a lot
of versatility to the underlying functionality while maintaining type safety. It
is comparable to the slight extra overhead that polymorphism requires yet
providing much more versatile code.
Jan 16 '07 #118
Peter Olcott wrote:
"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11*********************@a75g2000cwd.googlegro ups.com...
[...]
Making the parameter read-only is a pointless restriction on the
programmer.

If this statement was true, then C++ would have never added [const], since C++
did add [const] therefore this statement is not true.
C++ is not C#. C++ was not designed to run on a virtual machine capable
of reading class definitions and method bodies at runtime and
automatically deducing which optimizations can be performed safely. C#
was, and this is the kind of optimization the CLR can theoretically
perform (even if it doesn't already) without any input from the
programmer.

Why should the programmer have to change his code just to enable an
optimization? Why not just say "your methods will run faster if you
don't modify large value-type parameters"?

Jesse

Jan 16 '07 #119

"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11**********************@s34g2000cwa.googlegr oups.com...
Peter Olcott wrote:
>"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11*********************@a75g2000cwd.googlegr oups.com...
[...]
Making the parameter read-only is a pointless restriction on the
programmer.

If this statement was true, then C++ would have never added [const], since
C++
did add [const] therefore this statement is not true.

C++ is not C#. C++ was not designed to run on a virtual machine capable
of reading class definitions and method bodies at runtime and
automatically deducing which optimizations can be performed safely. C#
was, and this is the kind of optimization the CLR can theoretically
perform (even if it doesn't already) without any input from the
programmer.

Why should the programmer have to change his code just to enable an
optimization? Why not just say "your methods will run faster if you
don't modify large value-type parameters"?

Jesse
This aspect is not a matter of optimization, it is a matter of preventing
programming errors. By using the [const] parameter qualifier it is impossible to
inadvertently change a function parameter that was not intended to be changed.
Jan 16 '07 #120

Peter Olcott wrote:
"Bruce Wood" <br*******@canada.comwrote in message
It might be possible to design a language that has essentially all of the
functionally capabilities of the lower level languages, without the
requirement
of ever directly dealing with pointers.
True, but one question I know the C# team constantly asks is whether a
feature is worth the additional complexity it adds to the language. (I
know this because they frequently cite that as a reason for not
including certain features.) What does it really buy you being able to
take the address of an arbitrary variable (in safe code... I know that
you can do it in unsafe code)? As I said, I think that Java (and now
C#) have demonstrated that it doesn't buy you much. You mentioned
boxing overhead, but in .NET 2.0 you can pretty-much avoid boxing...
all you have to do is learn a new idiom: a new way to do what you've
always done, but now in a new language.

Are you referring to Generics? Does this address this issue of passing a struct
by (address) reference?
No. "ref" and "out" address the issue of passing a struct by reference
(to a method).

Generics address the problem of writing a type that contains another,
arbitrary type that could be a value type or a reference type, without
incurring boxing overhead and while maintaining compile-time type
safety. For example, in .NET 1.1 if I wanted a "vector" of Persons, I
would write:

ArrayList personList = new ArrayList();
personList.Add(new Person("Frank"));
Person frank = (Person)personList[0];

Here, Person is a reference type (as most user-defined types are) and
so the ArrayList now contains one entry, which is a reference to a
Person that has space allocated for it on the heap. However, I've lost
(compile-time) type checking: ArrayList is a collection of Object, and
so to get Frank back I had to use a cast, which involves a run-time
type check.

If I want a "vector" of ints, I say this:

ArrayList intList = new ArrayList();
intList.Add(15);
int i = (int)intList[0];

Here, 15 is an integer value type. Since ArrayList is a collection of
Object, the value type has to be boxed onto the heap and a reference to
it placed in the ArrayList. In order to get the value back, I have to
unbox the value, the unbox operation here represented by the cast.

Generics eliminate both problems. You'll recognize the template syntax
of C++:

List<PersonpersonList = new List<Person>();
personList.Add(new Person("Frank"));
Person frank = personList[0];

There's no need for a cast or for a run-time type check because the
compiler already knows that every reference in the list refers to a
Person.

Similarly,

List<intintList = new List<int>();
intList.Add(15);
int i = intList[0];

No boxing, no unboxing. The list holds native integers, not Objects.
That, in the end, is what it comes down to: C# works very well. It's
just that it does things differently than does C++, and you can't take
C++ idioms and concepts and start writing C# as though it were C++. In
a few domains, C++ is much better suited to the problems than is C#,
but in most domains C# gives you all the functionality you need while
helping keep you out of trouble.

I think that it is possible to take the concept of C# further along. To be able
to provide every required feature of a language such as C++, yet to do this in
an entirely type safe way, with essentially no additional execution time
overhead, and drastically reduce the number of details that must be handled by
the programmer. I think that C# has done an excellent job of achieving these
goals up to this point. I think that there are two opportunities for
improvement:

(1) Little tweaks here and there to eliminate more of the additional execution
time overhead.

(2) Abstract out the distinction between reference types and value types so that
the programmer will not even need to know the difference. The underlying
architecture can still have separate reference types and value types, yet, this
can be handled entirely transparently by the compiler and CLR.
How would you begin to achieve this?

I'm sorry, but I have to ask this... I don't mean to be combative or
snobby, but I'm a bit confused. It appears to me that you're trying to
get your head around C#'s version of value types, how they work, what
is boxing and unboxing and when does it happen, what are generics, and
some basic plumbing issues about how C# works. Correct me if I'm wrong,
but you seem knowledgeable about the inner workings of the machine, but
you're still trying to map what's going on in C# back to what happens
under the covers. If I can presume to sum up your questions, you're
experienced and intelligent, but some aspects of C# haven't quite
"clicked" for you yet.

And yet... you claim that C# is somehow lacking and needs improvement,
and I'm just dying to ask... based on what? I guess something just
isn't "clicking" for ME here.... I find myself very productive in C#.
There are some areas of the .NET Framework that I think could use
improvement, but the language itself works just fine for me. I find the
difference between value types and reference types very clear and
logical. I don't see where the "great rewards in increased programmer
productivity" will come from by trying to unify the two of them into...
what? A C++ type model? I'm sorry, but I found more people utterly
confounded by C++ than I have ever found confounded by Java or (now)
C#. C++ is a difficult language to master; C# by comparison is much
simpler, at least IMHO.

My problem is that I can't see where you're going with this idea. Could
you outline what's wrong with C#'s type system, how it should be
improved, and how those improvements would increase programmer
productivity?

Jan 16 '07 #121

Peter Olcott wrote:
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Peter Olcott <No****@SeeScreen.comwrote:
You wish to switch to a dotnet based solution to reduce the development
time,
but you don't want to put the time in to learning the language(C#). Sounds
to
me like you are doomed to failure anyway.

I can only put in a little time to learn the language now. I am focusing this
time on assessing the feasibility of using C# and .NET for my future needs.
It
looks like C# does have the performance that I need. In order to get this
performance, I must use relatively obscure nuances of C# that are barely
mentioned in even the most comprehensive textbooks. Specifically because of
this
newsgroup thread, I was able to learn these relatively obscure nuances. It
definitely looks like C# and .NET will be the future of essentially ALL MS
Windows development.
No, in order to get good performance you need to accept things like
"don't make huge value types". That's a much better solution than
creating a large value type and passing it by reference.
There are some cases where this suggestion would be bad design. The case in mind
is similar to the cases where a "friend" function is used in C++.
What on earth has "friend" to do with value versus reference types?

By the way, C# has no concept of "friend", and there's really no way to
fake it. Again, you have to think differently when you design in C#. If
you start your design assuming that there is some sort of "friend"
mechanism and then try to fudge it in, you'll end up with nothing but a
mess, just as if you start your design in C++ by creating a class
called "Object" and then try to derive everything from it (a la C#)
what you end up with is a mess.

Different language, different idioms.

Jan 16 '07 #122

Peter Olcott wrote:
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP************************@msnews.microsoft.c om...
Peter Olcott <No****@SeeScreen.comwrote:
You wish to switch to a dotnet based solution to reduce the development
time,
but you don't want to put the time in to learning the language(C#). Sounds
to
me like you are doomed to failure anyway.

I can only put in a little time to learn the language now. I am focusing this
time on assessing the feasibility of using C# and .NET for my future needs.
It
looks like C# does have the performance that I need. In order to get this
performance, I must use relatively obscure nuances of C# that are barely
mentioned in even the most comprehensive textbooks. Specifically because of
this
newsgroup thread, I was able to learn these relatively obscure nuances. It
definitely looks like C# and .NET will be the future of essentially ALL MS
Windows development.
No, in order to get good performance you need to accept things like
"don't make huge value types". That's a much better solution than
creating a large value type and passing it by reference.
There are some cases where this suggestion would be bad design. The case in mind
is similar to the cases where a "friend" function is used in C++.
What on earth has "friend" to do with value versus reference types?

By the way, C# has no concept of "friend", and there's really no way to
fake it. Again, you have to think differently when you design in C#. If
you start your design assuming that there is some sort of "friend"
mechanism and then try to fudge it in, you'll end up with nothing but a
mess, just as if you start your design in C++ by creating a class
called "Object" and then try to derive everything from it (a la C#)
what you end up with is a mess.

Different language, different idioms.

Jan 16 '07 #123
Peter Olcott wrote:
"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11**********************@s34g2000cwa.googlegr oups.com...
Why should the programmer have to change his code just to enable an
optimization? Why not just say "your methods will run faster if you
don't modify large value-type parameters"?

This aspect is not a matter of optimization, it is a matter of preventing
programming errors. By using the [const] parameter qualifier it is impossible to
inadvertently change a function parameter that was not intended to be changed.
It's already impossible! Those errors don't exist today: if you pass a
value type into a method, any changes the method makes will only affect
the local copy inside that method; the original value in the caller
won't be changed.

The potential errors are purely a side effect of the *optimization*
you've been proposing, which is to pass "in" value types by reference
even though you don't expect to get a changed value back from the
method (which is the purpose of "ref" and "out" parameters). If you
weren't passing them by reference, there'd be no need for those
parameters to be read-only, because any changes would be local to the
method being called.

Jesse

Jan 16 '07 #124

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@v45g2000cwv.googlegr oups.com...
>
Peter Olcott wrote:
>"Bruce Wood" <br*******@canada.comwrote in message
>It might be possible to design a language that has essentially all of the
functionally capabilities of the lower level languages, without the
requirement
of ever directly dealing with pointers.

True, but one question I know the C# team constantly asks is whether a
feature is worth the additional complexity it adds to the language. (I
know this because they frequently cite that as a reason for not
including certain features.) What does it really buy you being able to
take the address of an arbitrary variable (in safe code... I know that
you can do it in unsafe code)? As I said, I think that Java (and now
C#) have demonstrated that it doesn't buy you much. You mentioned
boxing overhead, but in .NET 2.0 you can pretty-much avoid boxing...
all you have to do is learn a new idiom: a new way to do what you've
always done, but now in a new language.

Are you referring to Generics? Does this address this issue of passing a
struct
by (address) reference?

No. "ref" and "out" address the issue of passing a struct by reference
(to a method).

Generics address the problem of writing a type that contains another,
arbitrary type that could be a value type or a reference type, without
incurring boxing overhead and while maintaining compile-time type
safety. For example, in .NET 1.1 if I wanted a "vector" of Persons, I
would write:

ArrayList personList = new ArrayList();
personList.Add(new Person("Frank"));
Person frank = (Person)personList[0];

Here, Person is a reference type (as most user-defined types are) and
so the ArrayList now contains one entry, which is a reference to a
Person that has space allocated for it on the heap. However, I've lost
(compile-time) type checking: ArrayList is a collection of Object, and
so to get Frank back I had to use a cast, which involves a run-time
type check.

If I want a "vector" of ints, I say this:

ArrayList intList = new ArrayList();
intList.Add(15);
int i = (int)intList[0];

Here, 15 is an integer value type. Since ArrayList is a collection of
Object, the value type has to be boxed onto the heap and a reference to
it placed in the ArrayList. In order to get the value back, I have to
unbox the value, the unbox operation here represented by the cast.

Generics eliminate both problems. You'll recognize the template syntax
of C++:

List<PersonpersonList = new List<Person>();
personList.Add(new Person("Frank"));
Person frank = personList[0];

There's no need for a cast or for a run-time type check because the
compiler already knows that every reference in the list refers to a
Person.

Similarly,

List<intintList = new List<int>();
intList.Add(15);
int i = intList[0];

No boxing, no unboxing. The list holds native integers, not Objects.
That, in the end, is what it comes down to: C# works very well. It's
just that it does things differently than does C++, and you can't take
C++ idioms and concepts and start writing C# as though it were C++. In
a few domains, C++ is much better suited to the problems than is C#,
but in most domains C# gives you all the functionality you need while
helping keep you out of trouble.

I think that it is possible to take the concept of C# further along. To be
able
to provide every required feature of a language such as C++, yet to do this
in
an entirely type safe way, with essentially no additional execution time
overhead, and drastically reduce the number of details that must be handled
by
the programmer. I think that C# has done an excellent job of achieving these
goals up to this point. I think that there are two opportunities for
improvement:

(1) Little tweaks here and there to eliminate more of the additional
execution
time overhead.

(2) Abstract out the distinction between reference types and value types so
that
the programmer will not even need to know the difference. The underlying
architecture can still have separate reference types and value types, yet,
this
can be handled entirely transparently by the compiler and CLR.

How would you begin to achieve this?

I'm sorry, but I have to ask this... I don't mean to be combative or
snobby, but I'm a bit confused. It appears to me that you're trying to
get your head around C#'s version of value types, how they work, what
is boxing and unboxing and when does it happen, what are generics, and
some basic plumbing issues about how C# works. Correct me if I'm wrong,
but you seem knowledgeable about the inner workings of the machine, but
you're still trying to map what's going on in C# back to what happens
under the covers. If I can presume to sum up your questions, you're
experienced and intelligent, but some aspects of C# haven't quite
"clicked" for you yet.

And yet... you claim that C# is somehow lacking and needs improvement,
and I'm just dying to ask... based on what? I guess something just
isn't "clicking" for ME here.... I find myself very productive in C#.
There will always be a need for improvement in computer programming languages
until computers reach the point where they can anticipate every possible need in
advance. What I am saying is that C# has made great strides in providing
essentially all of the capability of C++, but at a reduced cost of programmer
effort. C# is in many respects an improved C++.

All of the benefits of advances in programming languages are derived in terms of
reduced programming effort to achieve the desired result. C# can go one more
step further with this and eliminate the need for programmers to ever pay any
attention to the differences between value types and reference types.
There are some areas of the .NET Framework that I think could use
improvement, but the language itself works just fine for me. I find the
difference between value types and reference types very clear and
logical. I don't see where the "great rewards in increased programmer
productivity" will come from by trying to unify the two of them into...
what? A C++ type model? I'm sorry, but I found more people utterly
No, not into a C++ type model.
C# unified [Varname.FieldName and Varname->FieldName]
into the single [Varname.FieldName]
Take this same C# idea to its logical conclusion.
confounded by C++ than I have ever found confounded by Java or (now)
C#. C++ is a difficult language to master; C# by comparison is much
simpler, at least IMHO.

My problem is that I can't see where you're going with this idea. Could
you outline what's wrong with C#'s type system, how it should be
improved, and how those improvements would increase programmer
productivity?

Jan 16 '07 #125

Jesse McGrew wrote:
Peter Olcott wrote:
"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11**********************@s34g2000cwa.googlegr oups.com...
Why should the programmer have to change his code just to enable an
optimization? Why not just say "your methods will run faster if you
don't modify large value-type parameters"?
This aspect is not a matter of optimization, it is a matter of preventing
programming errors. By using the [const] parameter qualifier it is impossible to
inadvertently change a function parameter that was not intended to be changed.

It's already impossible! Those errors don't exist today: if you pass a
value type into a method, any changes the method makes will only affect
the local copy inside that method; the original value in the caller
won't be changed.

The potential errors are purely a side effect of the *optimization*
you've been proposing, which is to pass "in" value types by reference
even though you don't expect to get a changed value back from the
method (which is the purpose of "ref" and "out" parameters). If you
weren't passing them by reference, there'd be no need for those
parameters to be read-only, because any changes would be local to the
method being called.
Jesse, I think that you misunderstand. C++ has a concept of "const" by
which you can pass a reference type, but can indicate that none of its
fields can be changed.

To my knowledge, the C# team is considering such a construct, but they
still haven't figured out how to fit it cleanly into the language (and
possibly the CLR) taking into account security concerns, etc.

Jan 16 '07 #126
Bruce Wood <br*******@canada.comwrote:

<snip>
Jesse, I think that you misunderstand. C++ has a concept of "const" by
which you can pass a reference type, but can indicate that none of its
fields can be changed.

To my knowledge, the C# team is considering such a construct, but they
still haven't figured out how to fit it cleanly into the language (and
possibly the CLR) taking into account security concerns, etc.
For what it's worth, this has been debated around Java for *ages* (well
before .NET came on the scene) - C# is moving somewhat quicker in
general, but there are certainly lots of thorny issues :(

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 16 '07 #127

Peter Olcott wrote:
"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@v45g2000cwv.googlegr oups.com...

Peter Olcott wrote:
"Bruce Wood" <br*******@canada.comwrote in message
It might be possible to design a language that has essentially all of the
functionally capabilities of the lower level languages, without the
requirement
of ever directly dealing with pointers.

True, but one question I know the C# team constantly asks is whether a
feature is worth the additional complexity it adds to the language. (I
know this because they frequently cite that as a reason for not
including certain features.) What does it really buy you being able to
take the address of an arbitrary variable (in safe code... I know that
you can do it in unsafe code)? As I said, I think that Java (and now
C#) have demonstrated that it doesn't buy you much. You mentioned
boxing overhead, but in .NET 2.0 you can pretty-much avoid boxing...
all you have to do is learn a new idiom: a new way to do what you've
always done, but now in a new language.

Are you referring to Generics? Does this address this issue of passing a
struct
by (address) reference?
No. "ref" and "out" address the issue of passing a struct by reference
(to a method).

Generics address the problem of writing a type that contains another,
arbitrary type that could be a value type or a reference type, without
incurring boxing overhead and while maintaining compile-time type
safety. For example, in .NET 1.1 if I wanted a "vector" of Persons, I
would write:

ArrayList personList = new ArrayList();
personList.Add(new Person("Frank"));
Person frank = (Person)personList[0];

Here, Person is a reference type (as most user-defined types are) and
so the ArrayList now contains one entry, which is a reference to a
Person that has space allocated for it on the heap. However, I've lost
(compile-time) type checking: ArrayList is a collection of Object, and
so to get Frank back I had to use a cast, which involves a run-time
type check.

If I want a "vector" of ints, I say this:

ArrayList intList = new ArrayList();
intList.Add(15);
int i = (int)intList[0];

Here, 15 is an integer value type. Since ArrayList is a collection of
Object, the value type has to be boxed onto the heap and a reference to
it placed in the ArrayList. In order to get the value back, I have to
unbox the value, the unbox operation here represented by the cast.

Generics eliminate both problems. You'll recognize the template syntax
of C++:

List<PersonpersonList = new List<Person>();
personList.Add(new Person("Frank"));
Person frank = personList[0];

There's no need for a cast or for a run-time type check because the
compiler already knows that every reference in the list refers to a
Person.

Similarly,

List<intintList = new List<int>();
intList.Add(15);
int i = intList[0];

No boxing, no unboxing. The list holds native integers, not Objects.
That, in the end, is what it comes down to: C# works very well. It's
just that it does things differently than does C++, and you can't take
C++ idioms and concepts and start writing C# as though it were C++. In
a few domains, C++ is much better suited to the problems than is C#,
but in most domains C# gives you all the functionality you need while
helping keep you out of trouble.

I think that it is possible to take the concept of C# further along. To be
able
to provide every required feature of a language such as C++, yet to do this
in
an entirely type safe way, with essentially no additional execution time
overhead, and drastically reduce the number of details that must be handled
by
the programmer. I think that C# has done an excellent job of achieving these
goals up to this point. I think that there are two opportunities for
improvement:

(1) Little tweaks here and there to eliminate more of the additional
execution
time overhead.

(2) Abstract out the distinction between reference types and value types so
that
the programmer will not even need to know the difference. The underlying
architecture can still have separate reference types and value types, yet,
this
can be handled entirely transparently by the compiler and CLR.
How would you begin to achieve this?

I'm sorry, but I have to ask this... I don't mean to be combative or
snobby, but I'm a bit confused. It appears to me that you're trying to
get your head around C#'s version of value types, how they work, what
is boxing and unboxing and when does it happen, what are generics, and
some basic plumbing issues about how C# works. Correct me if I'm wrong,
but you seem knowledgeable about the inner workings of the machine, but
you're still trying to map what's going on in C# back to what happens
under the covers. If I can presume to sum up your questions, you're
experienced and intelligent, but some aspects of C# haven't quite
"clicked" for you yet.

And yet... you claim that C# is somehow lacking and needs improvement,
and I'm just dying to ask... based on what? I guess something just
isn't "clicking" for ME here.... I find myself very productive in C#.

There will always be a need for improvement in computer programming languages
until computers reach the point where they can anticipate every possible need in
advance. What I am saying is that C# has made great strides in providing
essentially all of the capability of C++, but at a reduced cost of programmer
effort. C# is in many respects an improved C++.

All of the benefits of advances in programming languages are derived in terms of
reduced programming effort to achieve the desired result. C# can go one more
step further with this and eliminate the need for programmers to ever pay any
attention to the differences between value types and reference types.
I disagree. The only way I can think of to interpret your suggestion is
by way of comparison, viz:

C# has two fundamental classes of types: value types and reference
types. The act very differently: value types being... well, values such
as integers, doubles, floats. Also included here are date/times and
some other types such as System.Drawing.Point and
System.Drawing.Rectangle. You can also make your own value types, but
you should have very little cause to do so. Reference types are used
for almost everything else. Java takes a similar approach to this.

One could unify the two classes of types by making everything a
reference type, or at least act like a reference type. Every integer,
double, float, or decimal would live (or appear to live) on the heap,
with a reference pointing to it. I believe that Smalltalk took an
approach similar to this, although I can't be sure because I've never
actually used Smalltalk.

One could also unify the two classes of types by making everything a
value type. This is essentially what C++ does. If you don't explicitly
take the address of something, it's a value. C# could do this, but then
you would have to have some syntax to indicate that you were passing a
reference to a method, for example, instead of passing the entire
object on the stack, which most of the time you don't want to do.
Because C++ has pointers, this is all very easy in C++. However, I
claim that this is one place where C# got it right: MOST OF THE TIME
you want to pass a reference to an object, and you want to pass what C#
considers value types by value. In C#, if you say nothing special, this
is what you get. If you say "ref", then you can pass a value type by
reference (or change the reference to a reference type--a pointer to a
pointer, in C++ terms). The C# team _could_ create a "copy" keyword
that would allow you to pass a reference type "by value" as it were, as
you can do in C++, rather than forcing you to say
"(Person)frank.Clone()" which is rather clunky.

So, again, I don't see how unifying the two kinds of types would
"improve programmer productivity". It would certainly make it easier
for people coming from the C++ world to understand what was going on,
but I think that it would confuse most newbies and if it were done
wrong would lead to newbies copying huge objects onto the stack by
mistake, which undermines claims to "improved productivity."
>
There are some areas of the .NET Framework that I think could use
improvement, but the language itself works just fine for me. I find the
difference between value types and reference types very clear and
logical. I don't see where the "great rewards in increased programmer
productivity" will come from by trying to unify the two of them into...
what? A C++ type model? I'm sorry, but I found more people utterly

No, not into a C++ type model.
C# unified [Varname.FieldName and Varname->FieldName]
into the single [Varname.FieldName]
Take this same C# idea to its logical conclusion.
Again, I'm confused. C# has no Varnam->FieldName syntax. That's C++.
The only ways I can see to "unify" the model is put everything on the
heap (or make it act as though it were on the heap), or make everything
a value type (which is essentially C++'s approach). Neither alternative
makes the language easier to understand or use, IMHO.

And it's not really very difficult to start with. There's only one rule
that's different from C++, which is this: "Reference types (which is to
say, most types) in C# act natively like pointer types in C++. That is,
if Person is a reference type, passing a Person to a method passes a
reference; every Person variable holds a reference; and every Person
instance lives on the heap." All other types (that is, value types) act
like C++ types. In the end, it's C# reference types, not value types,
that differ from C++.

And you know what? I like that better. No more "&", no more "*"... you
just use the types and they do what you probably wanted to do anyway
without having to pepper your code with additional syntax. Oh, and
you're not allowed to do patently silly things like pass an 80Kb
instance on the stack, even if 0.01% of the time that really is what
you would have wanted to do....

Jan 16 '07 #128

Jon wrote:
Bruce Wood <br*******@canada.comwrote:

<snip>
Jesse, I think that you misunderstand. C++ has a concept of "const" by
which you can pass a reference type, but can indicate that none of its
fields can be changed.

To my knowledge, the C# team is considering such a construct, but they
still haven't figured out how to fit it cleanly into the language (and
possibly the CLR) taking into account security concerns, etc.

For what it's worth, this has been debated around Java for *ages* (well
before .NET came on the scene) - C# is moving somewhat quicker in
general, but there are certainly lots of thorny issues :(
Indeed. C++ sidesteps the problems by providing an un-cost-cast by
which you can remove the "constness" of something. In other words, C++
provides "const", but the language doesn't guarantee that none of the
called methods will modify the object. As such, "const" in C++ is more
a suggestion to the programmer that carries weight only if the
programmer decides to abide by it.

I believe that the C# team's concern is that they want a tight
contract: they want a "const" that guarantees "const", not just a
guideline for programmers.

As well, there's the ugly C++ cascading-const problem. As a programmer,
even if you want to abide by a "const" contract imposed upon you, it's
not uncommon to find yourself in the situation in which "if a is
'const' then that means that parameter b to function F must be 'const',
but then if that's 'const' then parameter c to function G must also be
'const', but then...." If you haven't carefully used 'const' throughout
your libraries and code from the very start, it can get ugly pretty
quickly. Doubly so if you buy a library from someone and _they_ haven't
bothered using 'const' everywhere they could.

Anyway, I trust the C# team to introduce this (very useful) feature
only when they have it sorted out and not before. As Anders Heljsberg
said, "It's easy to add new features to a language later; it's very
difficult to change them if you include them and then later decide that
you didn't get it right" or words to that effect. Wise man.

Jan 16 '07 #129
Bruce Wood <br*******@canada.comwrote:

<snip>
As well, there's the ugly C++ cascading-const problem. As a programmer,
even if you want to abide by a "const" contract imposed upon you, it's
not uncommon to find yourself in the situation in which "if a is
'const' then that means that parameter b to function F must be 'const',
but then if that's 'const' then parameter c to function G must also be
'const', but then...." If you haven't carefully used 'const' throughout
your libraries and code from the very start, it can get ugly pretty
quickly. Doubly so if you buy a library from someone and _they_ haven't
bothered using 'const' everywhere they could.
That's one way of making it cascade in an ugly way - another is in
terms of generics. If people think Map<Foo,List<Bar>is bad, what
about Map<const Foo, const List<const Bar>>? Eek!
Anyway, I trust the C# team to introduce this (very useful) feature
only when they have it sorted out and not before. As Anders Heljsberg
said, "It's easy to add new features to a language later; it's very
difficult to change them if you include them and then later decide that
you didn't get it right" or words to that effect. Wise man.
Well, that's true from a *language* point of view - but much harder in
terms of a framework. Applying "const" retrospectively is an infeasibly
resource-intensive process, I suspect - and working out backwards
compatibility will be nightmarish.

One easier thing to do with reliability which I think the C# team is
interested in is the opposite of nullable value types: non-nullable
reference types. Basically a compile-time way of preventing non-null
references from being passed in. I suspect it has similar gotchas, but
might be somewhat simpler.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 16 '07 #130

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@m58g2000cwm.googlegr oups.com...
>
Peter Olcott wrote:
>"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@v45g2000cwv.googleg roups.com...
>All of the benefits of advances in programming languages are derived in terms
of
reduced programming effort to achieve the desired result. C# can go one more
step further with this and eliminate the need for programmers to ever pay any
attention to the differences between value types and reference types.

I disagree. The only way I can think of to interpret your suggestion is
by way of comparison, viz:

C# has two fundamental classes of types: value types and reference
types. The act very differently: value types being... well, values such
as integers, doubles, floats. Also included here are date/times and
some other types such as System.Drawing.Point and
System.Drawing.Rectangle. You can also make your own value types, but
you should have very little cause to do so. Reference types are used
for almost everything else. Java takes a similar approach to this.

One could unify the two classes of types by making everything a
reference type, or at least act like a reference type. Every integer,
double, float, or decimal would live (or appear to live) on the heap,
with a reference pointing to it. I believe that Smalltalk took an
approach similar to this, although I can't be sure because I've never
actually used Smalltalk.

One could also unify the two classes of types by making everything a
value type. This is essentially what C++ does. If you don't explicitly
take the address of something, it's a value. C# could do this, but then
you would have to have some syntax to indicate that you were passing a
reference to a method, for example, instead of passing the entire
object on the stack, which most of the time you don't want to do.
Because C++ has pointers, this is all very easy in C++. However, I
claim that this is one place where C# got it right: MOST OF THE TIME
you want to pass a reference to an object, and you want to pass what C#
considers value types by value. In C#, if you say nothing special, this
is what you get. If you say "ref", then you can pass a value type by
reference (or change the reference to a reference type--a pointer to a
pointer, in C++ terms). The C# team _could_ create a "copy" keyword
that would allow you to pass a reference type "by value" as it were, as
you can do in C++, rather than forcing you to say
"(Person)frank.Clone()" which is rather clunky.

So, again, I don't see how unifying the two kinds of types would
"improve programmer productivity". It would certainly make it easier
for people coming from the C++ world to understand what was going on,
but I think that it would confuse most newbies and if it were done
wrong would lead to newbies copying huge objects onto the stack by
mistake, which undermines claims to "improved productivity."
What I am saying is to raise the C# language to a whole other level of
abstraction where programmers writing programs in this language never have any
reason to know the first thing about separate value types and reference types,
there is only one type, and it simply works correctly and efficiently without
paying any attention at all to the underlying details.

There may still be separate value types and reference types under the covers,
but, the programmer using the language will care about these to the same degree
that they care about which operand is located in which machine register, not at
all.
>>
There are some areas of the .NET Framework that I think could use
improvement, but the language itself works just fine for me. I find the
difference between value types and reference types very clear and
logical. I don't see where the "great rewards in increased programmer
productivity" will come from by trying to unify the two of them into...
what? A C++ type model? I'm sorry, but I found more people utterly

No, not into a C++ type model.
C# unified [Varname.FieldName and Varname->FieldName]
into the single [Varname.FieldName]
Take this same C# idea to its logical conclusion.

Again, I'm confused. C# has no Varnam->FieldName syntax. That's C++.
C# has no VarName->FieldName syntax specifcally because it took the C++ syntax
for working with reference types and value types and combined this sytax into a
single syntax.
The only ways I can see to "unify" the model is put everything on the
heap (or make it act as though it were on the heap), or make everything
a value type (which is essentially C++'s approach). Neither alternative
makes the language easier to understand or use, IMHO.

And it's not really very difficult to start with. There's only one rule
that's different from C++, which is this: "Reference types (which is to
say, most types) in C# act natively like pointer types in C++. That is,
if Person is a reference type, passing a Person to a method passes a
reference; every Person variable holds a reference; and every Person
instance lives on the heap." All other types (that is, value types) act
like C++ types. In the end, it's C# reference types, not value types,
that differ from C++.

And you know what? I like that better. No more "&", no more "*"... you
just use the types and they do what you probably wanted to do anyway
without having to pepper your code with additional syntax. Oh, and
you're not allowed to do patently silly things like pass an 80Kb
instance on the stack, even if 0.01% of the time that really is what
you would have wanted to do....

Jan 16 '07 #131

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@v45g2000cwv.googlegr oups.com...
>
Jon wrote:
>Bruce Wood <br*******@canada.comwrote:

<snip>
Jesse, I think that you misunderstand. C++ has a concept of "const" by
which you can pass a reference type, but can indicate that none of its
fields can be changed.

To my knowledge, the C# team is considering such a construct, but they
still haven't figured out how to fit it cleanly into the language (and
possibly the CLR) taking into account security concerns, etc.

For what it's worth, this has been debated around Java for *ages* (well
before .NET came on the scene) - C# is moving somewhat quicker in
general, but there are certainly lots of thorny issues :(

Indeed. C++ sidesteps the problems by providing an un-cost-cast by
which you can remove the "constness" of something. In other words, C++
provides "const", but the language doesn't guarantee that none of the
called methods will modify the object. As such, "const" in C++ is more
a suggestion to the programmer that carries weight only if the
programmer decides to abide by it.

I believe that the C# team's concern is that they want a tight
contract: they want a "const" that guarantees "const", not just a
guideline for programmers.
The idea of [const] is to prevent accidental errors. Until C# has some form of
[const] it will be either somewhat more error prone than C++ or somewhat slower
than C++. If you really want to enforce [const] at run-time, then there is no
way to prevent its cascading effect.
As well, there's the ugly C++ cascading-const problem. As a programmer,
even if you want to abide by a "const" contract imposed upon you, it's
not uncommon to find yourself in the situation in which "if a is
'const' then that means that parameter b to function F must be 'const',
but then if that's 'const' then parameter c to function G must also be
'const', but then...." If you haven't carefully used 'const' throughout
your libraries and code from the very start, it can get ugly pretty
quickly. Doubly so if you buy a library from someone and _they_ haven't
bothered using 'const' everywhere they could.

Anyway, I trust the C# team to introduce this (very useful) feature
only when they have it sorted out and not before. As Anders Heljsberg
said, "It's easy to add new features to a language later; it's very
difficult to change them if you include them and then later decide that
you didn't get it right" or words to that effect. Wise man.

Jan 16 '07 #132
Bruce Wood wrote:
Jesse McGrew wrote:
Peter Olcott wrote:
"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11**********************@s34g2000cwa.googlegr oups.com...
Why should the programmer have to change his code just to enable an
optimization? Why not just say "your methods will run faster if you
don't modify large value-type parameters"?
>
This aspect is not a matter of optimization, it is a matter of preventing
programming errors. By using the [const] parameter qualifier it is impossible to
inadvertently change a function parameter that was not intended to be changed.
It's already impossible! Those errors don't exist today: if you pass a
value type into a method, any changes the method makes will only affect
the local copy inside that method; the original value in the caller
won't be changed.

The potential errors are purely a side effect of the *optimization*
you've been proposing, which is to pass "in" value types by reference
even though you don't expect to get a changed value back from the
method (which is the purpose of "ref" and "out" parameters). If you
weren't passing them by reference, there'd be no need for those
parameters to be read-only, because any changes would be local to the
method being called.

Jesse, I think that you misunderstand. C++ has a concept of "const" by
which you can pass a reference type, but can indicate that none of its
fields can be changed.
Maybe I am misunderstanding Peter's suggestion, then. I thought he was
talking about providing this for value types, such that 'void Foo(in
LargeStruct bar)' would pass bar by reference like the "ref" keyword,
but it would then be read-only from within Foo.

I can see the merits of applying a "const" attribute to reference types
- although read-only wrappers seem to be a decent solution too.

Jesse

Jan 17 '07 #133
Peter Olcott wrote:
"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@m58g2000cwm.googlegr oups.com...
[...]
So, again, I don't see how unifying the two kinds of types would
"improve programmer productivity". It would certainly make it easier
for people coming from the C++ world to understand what was going on,
but I think that it would confuse most newbies and if it were done
wrong would lead to newbies copying huge objects onto the stack by
mistake, which undermines claims to "improved productivity."

What I am saying is to raise the C# language to a whole other level of
abstraction where programmers writing programs in this language never have any
reason to know the first thing about separate value types and reference types,
there is only one type, and it simply works correctly and efficiently without
paying any attention at all to the underlying details.

There may still be separate value types and reference types under the covers,
but, the programmer using the language will care about these to the same degree
that they care about which operand is located in which machine register, not at
all.
Perhaps you could share your thoughts as to how this might be done.
Bruce has explained two ways to do it, but they both suffer from some
key problems. It seems to me that the distinction between value and
reference types is one that has evolved out of necessity over the
years, building on the experience of Smalltalk, C++, and Java, and that
if there were an obvious better way to handle these types, we'd already
be using it.

Jesse

Jan 17 '07 #134

"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11**********************@l53g2000cwa.googlegr oups.com...
Peter Olcott wrote:
>"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@m58g2000cwm.googleg roups.com...
[...]
So, again, I don't see how unifying the two kinds of types would
"improve programmer productivity". It would certainly make it easier
for people coming from the C++ world to understand what was going on,
but I think that it would confuse most newbies and if it were done
wrong would lead to newbies copying huge objects onto the stack by
mistake, which undermines claims to "improved productivity."

What I am saying is to raise the C# language to a whole other level of
abstraction where programmers writing programs in this language never have
any
reason to know the first thing about separate value types and reference
types,
there is only one type, and it simply works correctly and efficiently without
paying any attention at all to the underlying details.

There may still be separate value types and reference types under the covers,
but, the programmer using the language will care about these to the same
degree
that they care about which operand is located in which machine register, not
at
all.

Perhaps you could share your thoughts as to how this might be done.
Bruce has explained two ways to do it, but they both suffer from some
key problems. It seems to me that the distinction between value and
reference types is one that has evolved out of necessity over the
years, building on the experience of Smalltalk, C++, and Java, and that
if there were an obvious better way to handle these types, we'd already
be using it.

Jesse
I am not saying that this would be easy, but, then the advances from machine
language to object oriented programming weren't easy either. The end result that
I am proposing is far simpler than the prior example.

I was thinking along the lines of treating everything as a reference type and
mostly doing away with value types under the covers. There would be three
parameter qualifiers: {in, out, io}, [out] would be the same as it already is,
and [io] would take the place of the deprecated [ref], [in] would be for
read-only input parameters.
Jan 17 '07 #135

Peter Olcott wrote:
What I am saying is to raise the C# language to a whole other level of
abstraction where programmers writing programs in this language never have any
reason to know the first thing about separate value types and reference types,
there is only one type, and it simply works correctly and efficiently without
paying any attention at all to the underlying details.
OK, then we disagree. I prefer the way that it is now.

The issue is that abstracting away details can be good or bad. It can
be good when the details are getting in the way of understanding a
problem; abstract away the details, and the problem becomes clearer. It
can be bad when the details _matter_; abstract away the details and you
obscure the problem because the details were an important part of the
problem or its solution.

C++ has a unified type system that essentially lets the programmer do
anything they want. This includes both elegant and efficient solutions
to problems, as well as horribly inefficient misapplications of said
features. It gives you, as one author put it, "Enough rope to shoot
yourself in the foot with."

C# divides the type system into two groups, based on what you would
normally use the type for, and makes the types act (by default) in the
way you would usually want to use them. It reduces flexibility, but,
IMHO, makes the code easier to understand.

So is the unified abstraction that C++ offers a "bad abstraction,"
then? Not for those who have the high IQ necessary to understand how it
works, and understand which uses of types are good solutions and which
are misapplications. C# takes a lot of the guesswork out of it: how you
apply each kind of type (value vs reference) is baked into the
language. It makes it hard to do patently stupid things, but at the
cost of making the language a little less flexible.

I say that unifying C# value and reference types (a la C++) would make
the language harder to use well, not easier, and would reduce
programmer productivity.
There may still be separate value types and reference types under the covers,
but, the programmer using the language will care about these to the same degree
that they care about which operand is located in which machine register, not at
all.
A specious comparison. Changing the register in which an operand is
located doesn't change the semantics of my program. Passing something
on the stack and copying it on assignment, versus passing a reference
on the stack and copying a reference radically changes the semantics of
my program.

When I'm programming in C#, I don't "care" about the distinction in the
sense that it gets in my way. I know how the types work and I use them,
in the same way that when I drive my car I don't "care" about changing
gears. I've driven standard shift cars for so long that I no longer
even think about about the process... I just do it.

I _do_ think about value versus reference types in the sense that I
think about the semantics of my program. Do I want a particular type to
act like a value, or act like a (reference) object? That's an important
design decision that I would have to make even in C++, when I decide
whether to pass an object on the stack, or pass its address. In a way,
it's worse in C++ because I have to make that decision every time I
call a method or assign a variable. In C# I make a design decision when
I write the class and then I get the "usual" behaviour by default from
then on.

As I said, we disagree. :-)

Jan 17 '07 #136
Peter Olcott wrote:
The idea of [const] is to prevent accidental errors. Until C# has some form of
[const] it will be either somewhat more error prone than C++
That's only true if, absent a const modifier, C++ and C# are equal in
error liability. (And I strongly believe they aren't.)
or somewhat slower
than C++.
Ditto re speed, but "speed" arguments are meaningless without context.
There are architectural limitations in both .NET and C++ that constrain
compilers / runtimes differently.
If you really want to enforce [const] at run-time, then there is no
way to prevent its cascading effect.
And does this not result in a net increase in error liability?

-- Barry

--
http://barrkel.blogspot.com/
Jan 17 '07 #137

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@s34g2000cwa.googlegr oups.com...
>
Peter Olcott wrote:
>What I am saying is to raise the C# language to a whole other level of
abstraction where programmers writing programs in this language never have
any
reason to know the first thing about separate value types and reference
types,
there is only one type, and it simply works correctly and efficiently without
paying any attention at all to the underlying details.

OK, then we disagree. I prefer the way that it is now.

The issue is that abstracting away details can be good or bad. It can
be good when the details are getting in the way of understanding a
problem; abstract away the details, and the problem becomes clearer. It
can be bad when the details _matter_; abstract away the details and you
obscure the problem because the details were an important part of the
problem or its solution.
Abstracting away details is the primary means of every advance in programming
technology. The advance from machine language to assembly language abstracted
away the details of having to memorize opcodes. The advance from assembly
language to 3GLs abstracted away the details of dealing with unstructured
control flow.

The great advance from machine code to assembly language to "C" to C++ is that
there is very little loss of performance and much greater ease of use. C# has
seemed to have effectively accomplished this same thing, and taken it another
quarter step of ease of use through reduction in details. I think that C# could
progress along the same path that it is on and abstract out the {value type,
reference type} detail with no loss to performance.
>
C++ has a unified type system that essentially lets the programmer do
anything they want. This includes both elegant and efficient solutions
to problems, as well as horribly inefficient misapplications of said
features. It gives you, as one author put it, "Enough rope to shoot
yourself in the foot with."

C# divides the type system into two groups, based on what you would
normally use the type for, and makes the types act (by default) in the
way you would usually want to use them. It reduces flexibility, but,
IMHO, makes the code easier to understand.

So is the unified abstraction that C++ offers a "bad abstraction,"
then? Not for those who have the high IQ necessary to understand how it
works, and understand which uses of types are good solutions and which
are misapplications. C# takes a lot of the guesswork out of it: how you
apply each kind of type (value vs reference) is baked into the
language. It makes it hard to do patently stupid things, but at the
cost of making the language a little less flexible.

I say that unifying C# value and reference types (a la C++) would make
the language harder to use well, not easier, and would reduce
programmer productivity.
>There may still be separate value types and reference types under the covers,
but, the programmer using the language will care about these to the same
degree
that they care about which operand is located in which machine register, not
at
all.

A specious comparison. Changing the register in which an operand is
located doesn't change the semantics of my program. Passing something
on the stack and copying it on assignment, versus passing a reference
on the stack and copying a reference radically changes the semantics of
my program.

When I'm programming in C#, I don't "care" about the distinction in the
sense that it gets in my way. I know how the types work and I use them,
in the same way that when I drive my car I don't "care" about changing
gears. I've driven standard shift cars for so long that I no longer
even think about about the process... I just do it.

I _do_ think about value versus reference types in the sense that I
think about the semantics of my program. Do I want a particular type to
act like a value, or act like a (reference) object? That's an important
design decision that I would have to make even in C++, when I decide
whether to pass an object on the stack, or pass its address. In a way,
it's worse in C++ because I have to make that decision every time I
call a method or assign a variable. In C# I make a design decision when
I write the class and then I get the "usual" behaviour by default from
then on.

As I said, we disagree. :-)

Jan 17 '07 #138

Peter Olcott wrote:
Abstracting away details is the primary means of every advance in programming
technology. The advance from machine language to assembly language abstracted
away the details of having to memorize opcodes. The advance from assembly
language to 3GLs abstracted away the details of dealing with unstructured
control flow.
Motherhood and apple pie. Of course, of course, but you seem to have
missed the point....

OK, if all abstraction is progress, then let me recommend another
abstraction that will lead to tremendous progress: why not abstract
away the difference between byte, short, int, long, long long, float,
double, and decimal? Why not just have one "numeric" type that
encompasses all of them. This will clearly abstract away a lot of
trivial housekeeping and vastly improve programmer productivity.

Except that it won't, because those details, or at least the difference
between int, double, and decimal, are very important considerations
when writing code. Abstracting away the difference doesn't lead to
progress: it just leads to bloated programs and, in all likelihood,
buggy programs that don't deal with numerical values properly. Why?
Because we've abstracted away a critical detail.

You see how silly the argument is? Some abstraction is progress, but
some is not. Some abstraction makes things worse. Sorry, Peter, but
I've been programmer for far too long to be impressed by people
labeling their ideas "progressive" and trying to hang an argument on
that. I need you to demonstrate why C++'s type system (which is
essentially what you're promoting) makes programmers more productive
than C#'s type system, not play with words like "progress".
The great advance from machine code to assembly language to "C" to C++ is that
there is very little loss of performance and much greater ease of use. C# has
seemed to have effectively accomplished this same thing, and taken it another
quarter step of ease of use through reduction in details. I think that C# could
progress along the same path that it is on and abstract out the {value type,
reference type} detail with no loss to performance.
OK, let's try this again.... I STILL have to worry about value type vs
reference type in C++. Every time I decide to call Foo(x) instead of
Foo(&x), I've made a value-type-versus-reference-type decision. On
every call. Every time I write a copy constructor. Every time I declare
int x instead of int *x. I'm making those decisions all of the time in
C++.

In C#, I make that decision _once_: when I create the type. Then I
forget about it, because C# almost always does what I want to do after
that without any further verbage or decision-making.

Which language, then, makes it easier for me to write code? Which
abstraction, then, leads to greater programmer productivity? I claim
that it's C#'s way of doing things, which, as unfamiliar as it may be
to you, makes my life a whole lot easier and my code a whole lot
simpler. That, in fact is the bottom line: _the code is a lot simpler_.
At an abstract level it may not be as elegant, but in the trenches it's
simpler.

Heck, if you love abstraction for abstraction's sake, I can point you
to the most elegant language I ever used: LISP. A whole whack of people
in my uni failed the course, but for the few of us who "got it" it was
beautiful.

C# is designed to be usable by most programmers, all the way from
dabblers up to geniuses. You don't have to be terribly detail oriented
(which you must be in order to write C++) and you don't need to be a
great thinker (which you must be in order to write LISP). It's a
workmanlike language that gives up a little expressive power in order
to be accessible to the masses.

I claim that the abstraction you propose would sacrifice the latter.

Jan 17 '07 #139

"Bruce Wood" <br*******@canada.comwrote in message
news:11*********************@v45g2000cwv.googlegro ups.com...
>
Peter Olcott wrote:
>Abstracting away details is the primary means of every advance in programming
technology. The advance from machine language to assembly language abstracted
away the details of having to memorize opcodes. The advance from assembly
language to 3GLs abstracted away the details of dealing with unstructured
control flow.

Motherhood and apple pie. Of course, of course, but you seem to have
missed the point....

OK, if all abstraction is progress,
All progress is from abstraction does not entail that all abstraction results in
progress, simple non sequitur error.
then let me recommend another
abstraction that will lead to tremendous progress: why not abstract
away the difference between byte, short, int, long, long long, float,
double, and decimal? Why not just have one "numeric" type that
encompasses all of them. This will clearly abstract away a lot of
trivial housekeeping and vastly improve programmer productivity.

Except that it won't, because those details, or at least the difference
between int, double, and decimal, are very important considerations
when writing code. Abstracting away the difference doesn't lead to
progress: it just leads to bloated programs and, in all likelihood,
buggy programs that don't deal with numerical values properly. Why?
Because we've abstracted away a critical detail.

You see how silly the argument is? Some abstraction is progress, but
some is not. Some abstraction makes things worse. Sorry, Peter, but
I've been programmer for far too long to be impressed by people
labeling their ideas "progressive" and trying to hang an argument on
that. I need you to demonstrate why C++'s type system (which is
essentially what you're promoting) makes programmers more productive
than C#'s type system, not play with words like "progress".
>The great advance from machine code to assembly language to "C" to C++ is
that
there is very little loss of performance and much greater ease of use. C# has
seemed to have effectively accomplished this same thing, and taken it another
quarter step of ease of use through reduction in details. I think that C#
could
progress along the same path that it is on and abstract out the {value type,
reference type} detail with no loss to performance.

OK, let's try this again.... I STILL have to worry about value type vs
reference type in C++. Every time I decide to call Foo(x) instead of
Foo(&x), I've made a value-type-versus-reference-type decision. On
every call. Every time I write a copy constructor. Every time I declare
int x instead of int *x. I'm making those decisions all of the time in
C++.

In C#, I make that decision _once_: when I create the type. Then I
forget about it, because C# almost always does what I want to do after
that without any further verbage or decision-making.

Which language, then, makes it easier for me to write code? Which
abstraction, then, leads to greater programmer productivity? I claim
that it's C#'s way of doing things, which, as unfamiliar as it may be
to you, makes my life a whole lot easier and my code a whole lot
simpler. That, in fact is the bottom line: _the code is a lot simpler_.
At an abstract level it may not be as elegant, but in the trenches it's
simpler.

Heck, if you love abstraction for abstraction's sake, I can point you
to the most elegant language I ever used: LISP. A whole whack of people
in my uni failed the course, but for the few of us who "got it" it was
beautiful.

C# is designed to be usable by most programmers, all the way from
dabblers up to geniuses. You don't have to be terribly detail oriented
(which you must be in order to write C++) and you don't need to be a
great thinker (which you must be in order to write LISP). It's a
workmanlike language that gives up a little expressive power in order
to be accessible to the masses.

I claim that the abstraction you propose would sacrifice the latter.

Jan 17 '07 #140
Peter Olcott wrote:
[...]
I am not saying that this would be easy, but, then the advances from machine
language to object oriented programming weren't easy either. The end result that
I am proposing is far simpler than the prior example.

I was thinking along the lines of treating everything as a reference type and
mostly doing away with value types under the covers. There would be three
parameter qualifiers: {in, out, io}, [out] would be the same as it already is,
and [io] would take the place of the deprecated [ref], [in] would be for
read-only input parameters.
Treating everything as a reference type is, as I understand it, the
Smalltalk approach. And it carries a big performance penalty, because
every integer, boolean, and character has to be a full-fledged garbage
collected heap object.

Furthermore, "out" and "ref", when used with reference types, mean that
the *reference itself* may be changed by the method, not the object
that the reference points to. By making "in" parameters read-only, you
create a situation where if you want to call a method and let it change
the contents of an object, you also have to let it change your
reference to point to a whole new object.

Jesse

Jan 17 '07 #141

Peter Olcott wrote:
"Bruce Wood" <br*******@canada.comwrote in message
news:11*********************@v45g2000cwv.googlegro ups.com...

Peter Olcott wrote:
Abstracting away details is the primary means of every advance in programming
technology. The advance from machine language to assembly language abstracted
away the details of having to memorize opcodes. The advance from assembly
language to 3GLs abstracted away the details of dealing with unstructured
control flow.
Motherhood and apple pie. Of course, of course, but you seem to have
missed the point....

OK, if all abstraction is progress,

All progress is from abstraction does not entail that all abstraction results in
progress, simple non sequitur error.
True, but that was the only substance I could find in your post: the
implication that unifying the type model would introduce a new
abstraction, abstraction is progress, and therefore unifying the type
model is progressive. If there was something I missed, please tell me
so.

I then went on to explain why I find C#'s type model easier to work
with than the unified model of C++. Perhaps if you could explain why
I'm wrong, we could get the discussion back on track....

Jan 17 '07 #142
OK.. this discussion is descending into silly territory. Perhaps this
will help. I make the following claims.

1. The price for the unified type model and additional expressive power
of C++ (where everything is a value unless you "manually" take a
reference to it) is that you are forced to take careful note of lots of
picky details. In particular, you have to litter your code with & and
*, and _know when to do so_ and when not to.

2. Far from liberating the programmer from "having to worry about value
versus reference types", C++ throws it right in your face and forces
you to deal with it in almost every line of code. By contrast, C# does
something conceptually ugly but practically beautiful. By dividing
types into value types and reference types, C# forces you to make the
choice once, up front. From then on the language normally does what you
would expect with the type.

3. C# is simpler to code in for what appears to be a trivial reason,
but turns out to be pivotal: in order to get the behaviour you want,
you don't have to say anything. You don't have to say &, or *, or ref,
or out. You just declare a variable, work with it, pass it to methods,
and everything works the way you would like it to. As with all
heuristic rules, this one is not absolute. Sometimes the language
_doesn't_ do what you want by default, and you have to say "ref" or
"out". However, look around the Framework classes and see how often you
see those two keywords. They're very, very rarely needed.

4. Point #3 means that C# is easier to learn for newbies. One just
writes code, and by and large it does "the right thing" without any
extra tweaking. The same cannot be said for C++. I was amazed in a
previous job by how many people were guessing at when to use & and when
to pass a variable straight into a method, and when they had to
dereference with * and when they didn't. These were experienced
programmers. The only time this happens in C# is in that
one-in-a-hundred case in which you need ref, out, or a clone.

5. Far from "improving programmer productivity," unifying the type
model in C# in the style of C++ would reduce programmer productivity
and increase programmer confusion. I saw it happen in C and C++. I see
no reason why the same change in C# would not produce the same results.

6. There is a price for the greater ease of use of C#: there are some
occasionally useful C++ idioms that simply can't be done in C#. One
that comes to mind is deciding to pass an object instance on the stack.
Another is storing a reference to an arbitrary variable for later
update. C# is certainly less powerful than C++. However, I think that
the C# team has done an excellent job of eliminating power where it's
the kind of power that usually gets you into big trouble and is only
occasionally legitimately useful. Others may disagree.

Jan 17 '07 #143

| >
| Ah so the boxing and unboxing overhead that does not cost very much

It can cost a lot, if you use it in a loop it can count for a big chunk of
the process.
| adds a lot of versatility to the underlying functionality while
maintaining type safety.

Maintaining type safety how?
In reality you lose the type safety, when you box an int for example you
will get an object reference, you could try to cast it to any other type and
get an error, unfortunately this error will be detected at runtime and not
at compile time. so it does not help but quite the opposite.

|It
| is comparable to the slight extra overhead that polymorphism requires yet
| providing much more versatile code.

Not at all, they are two very different things.
--
Ignacio Machin
machin AT laceupsolutions com
Jan 17 '07 #144
Hi,

| >
| But boxing/unboxing will still be there, forever and ever :)
| >
| I don't think so.

Why?, can you explain why you think the un/boxing will go away?
--
Ignacio Machin
machin AT laceupsolutions com
Jan 17 '07 #145

"Jesse McGrew" <jm*****@gmail.comwrote in message
news:11*********************@q2g2000cwa.googlegrou ps.com...
Peter Olcott wrote:
[...]
>I am not saying that this would be easy, but, then the advances from machine
language to object oriented programming weren't easy either. The end result
that
I am proposing is far simpler than the prior example.

I was thinking along the lines of treating everything as a reference type and
mostly doing away with value types under the covers. There would be three
parameter qualifiers: {in, out, io}, [out] would be the same as it already
is,
and [io] would take the place of the deprecated [ref], [in] would be for
read-only input parameters.

Treating everything as a reference type is, as I understand it, the
Smalltalk approach. And it carries a big performance penalty, because
every integer, boolean, and character has to be a full-fledged garbage
collected heap object.
I said mostly doing away with value types, not completely doing away with them.
In other words almost never pass any parameters (unless integer or smaller) by
value.
>
Furthermore, "out" and "ref", when used with reference types, mean that
the *reference itself* may be changed by the method, not the object
that the reference points to. By making "in" parameters read-only, you
create a situation where if you want to call a method and let it change
the contents of an object, you also have to let it change your
reference to point to a whole new object.
No this is not true there are many ways around this. For example you could have
[local-input] meaning that this function can not change the variable, but,
subsequent functions that have this same parameter qualified differently (such
as [ref] or [io]) could change the variable.

This does not have to be enforced at run-time it could be enforced at compile
time. If it must be enforced at run-time, and must remain immutable, then there
is no possible way to avoid its cascading effect. However if it must be enforced
at run-time, but is not immutable, then the cascading effect can be eliminated.
Each function could change the parameter qualifier attribute of the data as the
data enters the function.
>
Jesse

Jan 17 '07 #146

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@a75g2000cwd.googlegr oups.com...
>
Peter Olcott wrote:
>"Bruce Wood" <br*******@canada.comwrote in message
news:11*********************@v45g2000cwv.googlegr oups.com...
>
Peter Olcott wrote:
Abstracting away details is the primary means of every advance in
programming
technology. The advance from machine language to assembly language
abstracted
away the details of having to memorize opcodes. The advance from assembly
language to 3GLs abstracted away the details of dealing with unstructured
control flow.

Motherhood and apple pie. Of course, of course, but you seem to have
missed the point....

OK, if all abstraction is progress,

All progress is from abstraction does not entail that all abstraction results
in
progress, simple non sequitur error.

True, but that was the only substance I could find in your post: the
implication that unifying the type model would introduce a new
abstraction, abstraction is progress, and therefore unifying the type
model is progressive. If there was something I missed, please tell me
so.

I then went on to explain why I find C#'s type model easier to work
with than the unified model of C++. Perhaps if you could explain why
I'm wrong, we could get the discussion back on track....
It might very well be that the C# model is superior to the C++ model in that it
can accomplish the same end-result with less programming effort. It is not true
that C# is the epitome of the best possible computer language that can ever be
created.

In order to improve computer language design one must look for ways to reduce
the number of details that the programmer must keep track of. The distinction
between value types and reference types as separate types is one detail that
might be able to be eliminated. It might be able to be eliminated with no
degradation of performance in terms of increases in either time or space. (CPU
cycles or RAM).
Jan 17 '07 #147

"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@51g2000cwl.googlegro ups.com...
OK.. this discussion is descending into silly territory. Perhaps this
will help. I make the following claims.

1. The price for the unified type model and additional expressive power
of C++ (where everything is a value unless you "manually" take a
reference to it) is that you are forced to take careful note of lots of
picky details. In particular, you have to litter your code with & and
*, and _know when to do so_ and when not to.
I am not recommending making C# more like C++, just the opposite. I am
recommending that C# reduce its complexity even more, and do this in a way that
neither reduces speed nor increases space very much. Polymorphism both reduces
speed and increases space, yet the benefits far outweigh the cost, because the
benefits are large and the cost is small.
>
2. Far from liberating the programmer from "having to worry about value
versus reference types", C++ throws it right in your face and forces
you to deal with it in almost every line of code. By contrast, C# does
something conceptually ugly but practically beautiful. By dividing
types into value types and reference types, C# forces you to make the
choice once, up front. From then on the language normally does what you
would expect with the type.

3. C# is simpler to code in for what appears to be a trivial reason,
but turns out to be pivotal: in order to get the behaviour you want,
you don't have to say anything. You don't have to say &, or *, or ref,
or out. You just declare a variable, work with it, pass it to methods,
and everything works the way you would like it to. As with all
heuristic rules, this one is not absolute. Sometimes the language
_doesn't_ do what you want by default, and you have to say "ref" or
"out". However, look around the Framework classes and see how often you
see those two keywords. They're very, very rarely needed.

4. Point #3 means that C# is easier to learn for newbies. One just
writes code, and by and large it does "the right thing" without any
extra tweaking. The same cannot be said for C++. I was amazed in a
previous job by how many people were guessing at when to use & and when
to pass a variable straight into a method, and when they had to
dereference with * and when they didn't. These were experienced
programmers. The only time this happens in C# is in that
one-in-a-hundred case in which you need ref, out, or a clone.

5. Far from "improving programmer productivity," unifying the type
model in C# in the style of C++ would reduce programmer productivity
and increase programmer confusion. I saw it happen in C and C++. I see
no reason why the same change in C# would not produce the same results.

6. There is a price for the greater ease of use of C#: there are some
occasionally useful C++ idioms that simply can't be done in C#. One
that comes to mind is deciding to pass an object instance on the stack.
Another is storing a reference to an arbitrary variable for later
update. C# is certainly less powerful than C++. However, I think that
the C# team has done an excellent job of eliminating power where it's
the kind of power that usually gets you into big trouble and is only
occasionally legitimately useful. Others may disagree.

Jan 17 '07 #148

"Ignacio Machin ( .NET/ C# MVP )" <machin TA laceupsolutions.comwrote in
message news:en*************@TK2MSFTNGP02.phx.gbl...
Hi,

| >
| But boxing/unboxing will still be there, forever and ever :)
| >
| I don't think so.

Why?, can you explain why you think the un/boxing will go away?
If you always keep everything in a box that needs to be in a box, and permit
access to internal data without taking it out of the box, then there is no need
to put it in a box, and take it out of a box, back and forth, just initialize it
in the box. For function parameters, the function can keep track of the type,
data does not need to keep track of itself. This could be done entirely at
compile-time, or run-time support could be added.
>

--
Ignacio Machin
machin AT laceupsolutions com


Jan 17 '07 #149

Peter Olcott wrote:
"Bruce Wood" <br*******@canada.comwrote in message
news:11**********************@a75g2000cwd.googlegr oups.com...

Peter Olcott wrote:
"Bruce Wood" <br*******@canada.comwrote in message
news:11*********************@v45g2000cwv.googlegro ups.com...

Peter Olcott wrote:
Abstracting away details is the primary means of every advance in
programming
technology. The advance from machine language to assembly language
abstracted
away the details of having to memorize opcodes. The advance from assembly
language to 3GLs abstracted away the details of dealing with unstructured
control flow.

Motherhood and apple pie. Of course, of course, but you seem to have
missed the point....

OK, if all abstraction is progress,

All progress is from abstraction does not entail that all abstraction results
in
progress, simple non sequitur error.
True, but that was the only substance I could find in your post: the
implication that unifying the type model would introduce a new
abstraction, abstraction is progress, and therefore unifying the type
model is progressive. If there was something I missed, please tell me
so.

I then went on to explain why I find C#'s type model easier to work
with than the unified model of C++. Perhaps if you could explain why
I'm wrong, we could get the discussion back on track....

It might very well be that the C# model is superior to the C++ model in that it
can accomplish the same end-result with less programming effort.
But if that is true, doesn't that hint that making the C# model more
like the C++ model would result in more programming effort?
It is not true that C# is the epitome of the best possible computer language that can ever be
created.
Oh, I would never claim that it is. I just happen to think that they
got this detail (dividing types into "value" and "reference") right.
There are other areas where I think C# is lacking; this just doesn't
happen to be one of them.
In order to improve computer language design one must look for ways to reduce
the number of details that the programmer must keep track of. The distinction
between value types and reference types as separate types is one detail that
might be able to be eliminated.
Perhaps, but the only ways I can think of to eliminate this detail
create even more ugly details, or result in horrid inefficiencies. I
can't for the life of me figure out how to unify the C# type system
(and thus eliminate the value / reference distinction and the need to
pay any attention to it at all) without introducing far more details
for the programmer to keep track of. I freely admit that this may be a
lack of imagination on my part. :-)
It might be able to be eliminated with no
degradation of performance in terms of increases in either time or space. (CPU
cycles or RAM).
AND while making things better (simpler) for the programmer, not worse.

Jan 17 '07 #150

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

43 posts views Thread by Mountain Bikn' Guy | last post: by
3 posts views Thread by Steve | last post: by
94 posts views Thread by Peter Olcott | last post: by
19 posts views Thread by ahjiang | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
1 post views Thread by Marylou17 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.