By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
426,179 Members | 2,175 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 426,179 IT Pros & Developers. It's quick & easy.

Anders Hejlsberg comment on immutable objects

P: n/a
Hi

Just read this article http://www.artima.com/intv/choices.html.

Towards the end of the dicussions, when asked "Did you consider
including support for the concept of immutable directly in C# and the
CLR?" Anders' reply included this comment: "The concept of an
immutable object is very useful, but it's just up to the author to say
that it's immutable."

I'm just wondering if "up to the author to say" means that the author
needs to clearly state this in documentation or is there something
stronger than can be done?

Any comments appreciated!

Andrew Quine
an**********@fastmail.fm
Nov 15 '05 #1
Share this Question
Share on Google+
48 Replies


P: n/a
On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (Andrew Quine)
wrote:
I'm just wondering if "up to the author to say" means that the author
needs to clearly state this in documentation or is there something
stronger than can be done?


From the context of the article I think he refers to comments. As I
understand it he doesn't want a language keyword that's effectively
just a comment because the compiler can't properly enforce it.
--
http://www.kynosarges.de
Nov 15 '05 #2

P: n/a
Well, it would be really nice if we could apply the readonly keyword to a
class or a struct, to state that it is immutable. This would be equivalent
to marking all the fields as immutable.

IMO, this would be a rather straightforward enhancement to the C# language,
that does not raise any backward compatibility issue (because the readonly
keyword is already there). I already suggested this a while ago, but did not
see much follow-up.

Bruno.

"Andrew Quine" <an**********@fastmail.fm> a écrit dans le message de
news:d7**************************@posting.google.c om...
Hi

Just read this article http://www.artima.com/intv/choices.html.

Towards the end of the dicussions, when asked "Did you consider
including support for the concept of immutable directly in C# and the
CLR?" Anders' reply included this comment: "The concept of an
immutable object is very useful, but it's just up to the author to say
that it's immutable."

I'm just wondering if "up to the author to say" means that the author
needs to clearly state this in documentation or is there something
stronger than can be done?

Any comments appreciated!

Andrew Quine
an**********@fastmail.fm

Nov 15 '05 #3

P: n/a
On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (Andrew Quine)
wrote:
Hi

Just read this article http://www.artima.com/intv/choices.html.

Towards the end of the dicussions, when asked "Did you consider
including support for the concept of immutable directly in C# and the
CLR?" Anders' reply included this comment: "The concept of an
immutable object is very useful, but it's just up to the author to say
that it's immutable."

<Anders Hejlsberg>
With respect to immutability, it's tricky because what you're saying
when you say something is immutable, is that from an external
perspective, I cannot observe any mutation. That doesn't necessarily
mean that it doesn't have a cache inside that makes it go more
efficiently. It's just on the outside it looks immutable. That's hard
for a compiler to figure out.
</Anders Hejlsberg>

C++ solves this problem quite handily with the mutable keyword. Only
fields declared mutable may be modified by a const member.

I'm just wondering if "up to the author to say" means that the author
needs to clearly state this in documentation or is there something
stronger than can be done?


As is, I can't think of anything better than making state holding
fields readonly where possible.

If C# had const correctness then making all members const would
certainly be stronger. Possibly one might add an immutable keyword
which would make all member of a class declared immutable implicitly
const.
I find Anders' comments on const very surprising:

<Anders Hejlsberg>
With respect to const, it's interesting, because we hear that
complaint all the time too: "Why don't you have const?" Implicit in
the question is, "Why don't you have const that is enforced by the
runtime?" That's really what people are asking, although they don't
come out and say it that way.
</Anders Hejlsberg>

C++ style const, which is what was mentioned, is not implemented at
runtime. Const correctness is enforced at compile time.

<Anders Hejlsberg>
The reason that const works in C++ is because you can cast it away. If
you couldn't cast it away, then your world would suck.
</Anders Hejlsberg>

Const can be cast away legally only if you know that the actual
instance in question is not declared const. Otherwise it invokes
undefined behavior. More importantly, casting away const is always a
breach of contract. Competent programmers do so only as a last resort
in exceptional circumstances.

<Anders Hejlsberg>
If you declare a method that takes a const Bla, you could pass it a
non-const Bla. But if it's the other way around you can't.
</Anders Hejlsberg>

That is exactly the point to having const. That is a boon. If your
code fails to compile because of this, you were just saved from
introducing a bug by modifying an instance you had no right to modify.

<Anders Hejlsberg>
f you declare a method that takes a non-const Bla, you can't pass it a
const Bla. So now you're stuck.
</Anders Hejlsberg>

If you declared the method to take a non const Bla you did so because
the method modifies it's parameter. If you pass such a method an
instance that may not be altered you are introducing a bug and the
compiler is correct in not allowing you to do so.

<Anders Hejlsberg>
So you gradually need a const version of everything that isn't const,
and you end up with a shadow world.
</Anders Hejlsberg>

There is only one version with different constraints enforced upon it.
There is no duplication of code, no shadows.

class Foo
{
private:
int value;

public:
Foo():value(0){}

int getValue() const//This is all you need to do. Write const once.
{
return value;
}

void setValue(int newValue)
{
value = newValue;
}
};
void Bar()
{
Foo foo;//setValue can be invoked on this instance.
const Foo constFoo;//setValue cannot be invoked on this instance.
foo.setValue(5);//OK
constFoo.setValue(6);//Compiler error
}
If you want to see shadows, try the way that read only collections are
implemented in the BCL.
1. Entire duplicate classes are written for each class.
2. These classes violate Liskov's Substitutability Principle.
3. Errors occur at run time instead of compile time.

<Anders Hejlsberg>
In C++ you get away with it, because as with anything in C++ it is
purely optional whether you want this check or not. You can just whack
the constness away if you don't like it.
</Anders Hejlsberg>
No. See comments above about casting away const.
/Magnus Lidbom

Nov 15 '05 #4

P: n/a

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:lm********************************@4ax.com...
On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (Andrew Quine)
wrote:
Hi

Just read this article http://www.artima.com/intv/choices.html.

Towards the end of the dicussions, when asked "Did you consider
including support for the concept of immutable directly in C# and the
CLR?" Anders' reply included this comment: "The concept of an
immutable object is very useful, but it's just up to the author to say
that it's immutable."

<Anders Hejlsberg>
With respect to immutability, it's tricky because what you're saying
when you say something is immutable, is that from an external
perspective, I cannot observe any mutation. That doesn't necessarily
mean that it doesn't have a cache inside that makes it go more
efficiently. It's just on the outside it looks immutable. That's hard
for a compiler to figure out.
</Anders Hejlsberg>

C++ solves this problem quite handily with the mutable keyword. Only
fields declared mutable may be modified by a const member.


It is a clean solution, however it promotes keyword and language bloat. Is
it worth yet another modifier? However that doesn't directly approach the
subject. An immutable object is not *const*, it is immutable. There is no
need to declare the reference const and no way to cast away from it, just as
its not possible to remove immutability from string. Crossing the two leads
to confusion as to your actual meaning, IMHO.

I'm just wondering if "up to the author to say" means that the author
needs to clearly state this in documentation or is there something
stronger than can be done?
As is, I can't think of anything better than making state holding
fields readonly where possible.

If C# had const correctness then making all members const would
certainly be stronger. Possibly one might add an immutable keyword
which would make all member of a class declared immutable implicitly
const.
I find Anders' comments on const very surprising:

<Anders Hejlsberg>
With respect to const, it's interesting, because we hear that
complaint all the time too: "Why don't you have const?" Implicit in
the question is, "Why don't you have const that is enforced by the
runtime?" That's really what people are asking, although they don't
come out and say it that way.
</Anders Hejlsberg>

C++ style const, which is what was mentioned, is not implemented at
runtime. Const correctness is enforced at compile time.


It can't be in .NET. Although it works ok in C++, this is no longer a pure
C++ world. Const has to exist(as I've argued before) in the runtime,
verified by the runtime, otherwise its a joke at best, a lie at worst.
Without runtime verification, your code *is* going to get screwed because
something that claims const really isn't. A contract like clause that isn't
a contract thats called a contract is something better left out than hacked
in, IMHO.

<Anders Hejlsberg>
The reason that const works in C++ is because you can cast it away. If
you couldn't cast it away, then your world would suck.
</Anders Hejlsberg>

Const can be cast away legally only if you know that the actual
instance in question is not declared const. Otherwise it invokes
undefined behavior. More importantly, casting away const is always a
breach of contract. Competent programmers do so only as a last resort
in exceptional circumstances.
Const in C++ isn't really much of a contract, its just a "you really
shouldn't do this, but go ahead if you want to" kind of thing. You can't
consider competent programmers as the end all. A truely competent programmer
wouldn't call a method that modifies an object with or without the const
modifier if he doesn't want to modify the object. In that case isn't const
enforcment just a catchall existing only for the non-competent, and the
const keyword nothing but documentation for the lazy? If competence is all
you care about there is little need for any access modifiers, exceptions, or
quite a few other things
I don't consider the C++ const implemetnation to be sufficent, the more I
think about it the more I consider it broken for .NET\C#.

<Anders Hejlsberg>
If you declare a method that takes a const Bla, you could pass it a
non-const Bla. But if it's the other way around you can't.
</Anders Hejlsberg>

That is exactly the point to having const. That is a boon. If your
code fails to compile because of this, you were just saved from
introducing a bug by modifying an instance you had no right to modify.
But it is annoying when the code actually doesn't make a modification, but
simply was written without regard to const(which, at this point, will be
most code). Its a considerable limitation when your const methods have to
start rolling their own methods to do everything because they can't
realistically pass a const reference into a non-const method.
I would expect something like
public const MyType MyMethod(const MyType t) const
{
MyOtherMethod((MyType)t);
return t;
}

to fail the compile time verification. t may have changed in the call to
MyOtherMethod and is no longer verifiably const. For this reason I don't
want to see const as somethign that can be cast away. I simply don't believe
in the competent programmer.

<Anders Hejlsberg>
f you declare a method that takes a non-const Bla, you can't pass it a
const Bla. So now you're stuck.
</Anders Hejlsberg>

If you declared the method to take a non const Bla you did so because
the method modifies it's parameter. If you pass such a method an
instance that may not be altered you are introducing a bug and the
compiler is correct in not allowing you to do so.

<Anders Hejlsberg>
So you gradually need a const version of everything that isn't const,
and you end up with a shadow world.
</Anders Hejlsberg>

There is only one version with different constraints enforced upon it.
There is no duplication of code, no shadows.

class Foo
{
private:
int value;

public:
Foo():value(0){}

int getValue() const//This is all you need to do. Write const once.
{
return value;
}

void setValue(int newValue)
{
value = newValue;
}
};
void Bar()
{
Foo foo;//setValue can be invoked on this instance.
const Foo constFoo;//setValue cannot be invoked on this instance.
foo.setValue(5);//OK
constFoo.setValue(6);//Compiler error
}
If you want to see shadows, try the way that read only collections are
implemented in the BCL.
1. Entire duplicate classes are written for each class.
2. These classes violate Liskov's Substitutability Principle.
3. Errors occur at run time instead of compile time.
This I'll agree on, but I think const fixes these problems while resulting
in a similar list of different problems.

<Anders Hejlsberg>
In C++ you get away with it, because as with anything in C++ it is
purely optional whether you want this check or not. You can just whack
the constness away if you don't like it.
</Anders Hejlsberg>
No. See comments above about casting away const. Again, .NET isn't C++, the C++ rules just don't work.

/Magnus Lidbom

Nov 15 '05 #5

P: n/a
On Sun, 8 Feb 2004 12:30:17 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:lm********************************@4ax.com.. .
On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (Andrew Quine)
wrote:
<snip>

<Anders Hejlsberg>
With respect to immutability, it's tricky because what you're saying
when you say something is immutable, is that from an external
perspective, I cannot observe any mutation. That doesn't necessarily
mean that it doesn't have a cache inside that makes it go more
efficiently. It's just on the outside it looks immutable. That's hard
for a compiler to figure out.
</Anders Hejlsberg>

C++ solves this problem quite handily with the mutable keyword. Only
fields declared mutable may be modified by a const member.
It is a clean solution, however it promotes keyword and language bloat. Is
it worth yet another modifier?


If C++ style const is introduced, mutable is a necessity. The need for
lazy evaluation and similar techniques is far to common to leave
mutable out.
However that doesn't directly approach the
subject. An immutable object is not *const*, it is immutable.
It is const. That's what immutable means. That any and all instances
of the class are const.

<snip>

<Anders Hejlsberg>
With respect to const, it's interesting, because we hear that
complaint all the time too: "Why don't you have const?" Implicit in
the question is, "Why don't you have const that is enforced by the
runtime?" That's really what people are asking, although they don't
come out and say it that way.
</Anders Hejlsberg>

C++ style const, which is what was mentioned, is not implemented at
runtime. Const correctness is enforced at compile time.


It can't be in .NET. Although it works ok in C++, this is no longer a pure
C++ world. Const has to exist(as I've argued before) in the runtime,


I don't see why C# could not give the same guarantees through a
compile time validation that C++ can. Could you elaborate on this?

<snip>
Const in C++ isn't really much of a contract, its just a "you really
shouldn't do this, but go ahead if you want to" kind of thing.
Only if you consider bugs and undefined behavior to be OK.
Const can't stop programmers from making a mess when they break the
rules on purpose. That doesn't detract anything from the protection
and clarification that it can provide.

You can't
consider competent programmers as the end all. A truely competent programmer
wouldn't call a method that modifies an object with or without the const
modifier if he doesn't want to modify the object. In that case isn't const
enforcment just a catchall existing only for the non-competent, and the
const keyword nothing but documentation for the lazy? If competence is all
you care about there is little need for any access modifiers, exceptions, or
quite a few other things
There is great need for all of those. They all make it easier for the
programmer to write safe code. In the case of access modifiers and
const they make contracts explicit and make it possible for the
compiler to verify that those contracts are not breached, at least not
without making the breach explicit through the use of a cast. This is
very valuable regardless of the competence of the programmer.

Would you say that a competent police officer doesn't need a west when
storming a building?
I don't consider the C++ const implemetnation to be sufficent, the more I
think about it the more I consider it broken for .NET\C#.
Please elaborate.

<Anders Hejlsberg>
If you declare a method that takes a const Bla, you could pass it a
non-const Bla. But if it's the other way around you can't.
</Anders Hejlsberg>

That is exactly the point to having const. That is a boon. If your
code fails to compile because of this, you were just saved from
introducing a bug by modifying an instance you had no right to modify.


But it is annoying when the code actually doesn't make a modification, but
simply was written without regard to const(which, at this point, will be
most code).


The fix is extremely simple, add const to the parameter declaration.
Its a considerable limitation when your const methods have to
start rolling their own methods to do everything because they can't
realistically pass a const reference into a non-const method.
I would expect something like
public const MyType MyMethod(const MyType t) const
{
MyOtherMethod((MyType)t);
return t;
}

to fail the compile time verification. t may have changed in the call to
MyOtherMethod
Only if MyOtherMethod takes a non const MyType.
and is no longer verifiably const. For this reason I don't
want to see const as somethign that can be cast away. I simply don't believe
in the competent programmer.


Making it impossible to cast away const would, as you say, require
modifications to the runtime. Unless I'm mistaken, it would in fact
require changing the runtime representation of a reference, doubling
its size from 32 bits to 64, and introducing another level of
indirection for each invocation of a member on a reference. I don't
think the consequences of such a change would be palatable. For
starters it would almost double the memory usage of most .Net
applications, and I'd expect a performance degradation across the
board.

<snip>

/Magnus Lidbom

Nov 15 '05 #6

P: n/a

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:5e********************************@4ax.com...
On Sun, 8 Feb 2004 12:30:17 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:lm********************************@4ax.com.. .
On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (Andrew Quine)
wrote:
<snip>

<Anders Hejlsberg>
With respect to immutability, it's tricky because what you're saying
when you say something is immutable, is that from an external
perspective, I cannot observe any mutation. That doesn't necessarily
mean that it doesn't have a cache inside that makes it go more
efficiently. It's just on the outside it looks immutable. That's hard
for a compiler to figure out.
</Anders Hejlsberg>

C++ solves this problem quite handily with the mutable keyword. Only
fields declared mutable may be modified by a const member.
It is a clean solution, however it promotes keyword and language bloat. Is
it worth yet another modifier?


If C++ style const is introduced, mutable is a necessity. The need for
lazy evaluation and similar techniques is far to common to leave
mutable out.
However that doesn't directly approach the
subject. An immutable object is not *const*, it is immutable.


It is const. That's what immutable means. That any and all instances
of the class are const.

What I mean is that an immutable object is different from
public const MyObject o; An immutable object cannot be changed from the
outside, ever, where as in the way const works(as I understand it, again I'm
no C++ master) it is strictly a reference\variable\signature based system. I
consider these significantly different and deserving of different terms(and
keywords if both are to be added). Overall while const is more valuable as
its much harder to design for without extra support, immutability isn't
something to be ignored.
<snip>

<Anders Hejlsberg>
With respect to const, it's interesting, because we hear that
complaint all the time too: "Why don't you have const?" Implicit in
the question is, "Why don't you have const that is enforced by the
runtime?" That's really what people are asking, although they don't
come out and say it that way.
</Anders Hejlsberg>

C++ style const, which is what was mentioned, is not implemented at
runtime. Const correctness is enforced at compile time.
It can't be in .NET. Although it works ok in C++, this is no longer a pure
C++ world. Const has to exist(as I've argued before) in the runtime,


I don't see why C# could not give the same guarantees through a
compile time validation that C++ can. Could you elaborate on this?


To be entirely clear, the C# compiler would be expected to provide compile
time verification, thats a given in my mind. However, I don't feel that it
is enough. The runtime should provide the last-word guarentee, while the
language\compiler provides compiletime verification of its own source
against the contract provided by classes, but no deeper. The point of this
would be that *no* code could break const. Isn't that part of the point of
managed code, ?

<snip>
Const in C++ isn't really much of a contract, its just a "you really
shouldn't do this, but go ahead if you want to" kind of thing.
Only if you consider bugs and undefined behavior to be OK.
Const can't stop programmers from making a mess when they break the
rules on purpose. That doesn't detract anything from the protection
and clarification that it can provide.

I agree, however, I simply don't feel such a thing as a competent programmer
exists(we all screw up and make bad choices once in a while), if we are
going to go ahead with const we may as well do it right. const *isn't* a
contract when applied to a reference, in the C++ style, it is more a
shelter. It protects the coder from making a mistake, but doesn't stop them.
I would like to see a form of const in C#\.NET that *is* a contract. A const
instance should always be constant.
For that matter, what I consider to be ok and what is a real contract are
very different things. For what I consider, documentation is strong enough,
I will read it and believe it(unless the code starts to show otherwise). A
real contract should be enforced by both the compiler and the runtime, not
something that can be circumvented so easily as C++ const can.
You can't
consider competent programmers as the end all. A truely competent programmerwouldn't call a method that modifies an object with or without the const
modifier if he doesn't want to modify the object. In that case isn't constenforcment just a catchall existing only for the non-competent, and the
const keyword nothing but documentation for the lazy? If competence is allyou care about there is little need for any access modifiers, exceptions, orquite a few other things
There is great need for all of those. They all make it easier for the
programmer to write safe code. In the case of access modifiers and
const they make contracts explicit and make it possible for the
compiler to verify that those contracts are not breached, at least not
without making the breach explicit through the use of a cast. This is
very valuable regardless of the competence of the programmer.

Would you say that a competent police officer doesn't need a west when
storming a building?
I don't consider the C++ const implemetnation to be sufficent, the more I
think about it the more I consider it broken for .NET\C#.


Please elaborate.

Much as I was saying above. It is a weak contract, if a contract at all, and
not something that should be in a system like .NET. This is one of the
fundamental differences between managed code and old C++. C++ doesn't offer
a good many of the other niceties of managed code and I simply think its
silly to decide to use a weak version of one concept simply out of laziness
or unwillingness to think of something new. Although it should have been in
the orignal version, const is something that should be done properly.
<Anders Hejlsberg>
If you declare a method that takes a const Bla, you could pass it a
non-const Bla. But if it's the other way around you can't.
</Anders Hejlsberg>

That is exactly the point to having const. That is a boon. If your
code fails to compile because of this, you were just saved from
introducing a bug by modifying an instance you had no right to modify.
But it is annoying when the code actually doesn't make a modification, butsimply was written without regard to const(which, at this point, will be
most code).


The fix is extremely simple, add const to the parameter declaration.


And do what exactly when you don't control that code?
Its a considerable limitation when your const methods have to
start rolling their own methods to do everything because they can't
realistically pass a const reference into a non-const method.
I would expect something like
public const MyType MyMethod(const MyType t) const
{
MyOtherMethod((MyType)t);
return t;
}

to fail the compile time verification. t may have changed in the call to
MyOtherMethod
Only if MyOtherMethod takes a non const MyType.


I should have specified that, but I meant to imply that MyOtherMethod
doesn't take const MyType as its parameter.
and is no longer verifiably const. For this reason I don't
want to see const as somethign that can be cast away. I simply don't believein the competent programmer.
Making it impossible to cast away const would, as you say, require
modifications to the runtime. Unless I'm mistaken, it would in fact
require changing the runtime representation of a reference, doubling
its size from 32 bits to 64, and introducing another level of
indirection for each invocation of a member on a reference. I don't
think the consequences of such a change would be palatable. For
starters it would almost double the memory usage of most .Net
applications, and I'd expect a performance degradation across the
board.


I don't think there would be a nessecery increase in the size of a
reference. 32 bits will handle 4 billion references, which is impossible to
do with 32 bit hardware(16gigs of references alone), on 64 bit hardware you
have far more. It wouldn't be impossibleto carve off 2 or 3 bits from a
reference for flags, even if a reference is only 30 bits you end up with
about 1billion possible references, which is more than enough for *ANY*
application running on the framework, even 500 million is probably
sufficent(at this numbers, the size of reference * the number of references
alone supercedes .NET allocable memory, leaving no room for the actual
objects). While such a thing isn't nessecerily feasible, it would work
without any of the problems. It also assumes the top 2 bits aren't already
used for something.
On 64 bit systems, the maximum number of references at 60 bits would be well
beyond memory capacity(I don't think many 64 bit chips actually use 64 bit
addressing).
Ideally, it would be possible to cast *to* const, but not from. The
orignator of an object should have the choice as to where it wants to pass
const and non-const references. With the system above such a cast would be a
bitmask, just by setting the first bit.

<snip>

/Magnus Lidbom

Nov 15 '05 #7

P: n/a
On Sun, 8 Feb 2004 15:03:21 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:5e********************************@4ax.com.. .
On Sun, 8 Feb 2004 12:30:17 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
>
>"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>news:lm********************************@4ax.com.. .
>> On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (Andrew Quine)
>> wrote:
<snip>
>>
>> <Anders Hejlsberg>
>> With respect to immutability, it's tricky because what you're saying
>> when you say something is immutable, is that from an external
>> perspective, I cannot observe any mutation. That doesn't necessarily
>> mean that it doesn't have a cache inside that makes it go more
>> efficiently. It's just on the outside it looks immutable. That's hard
>> for a compiler to figure out.
>> </Anders Hejlsberg>
>>
>> C++ solves this problem quite handily with the mutable keyword. Only
>> fields declared mutable may be modified by a const member.
>
>It is a clean solution, however it promotes keyword and language bloat.Is >it worth yet another modifier?


If C++ style const is introduced, mutable is a necessity. The need for
lazy evaluation and similar techniques is far to common to leave
mutable out.
>However that doesn't directly approach the
>subject. An immutable object is not *const*, it is immutable.


It is const. That's what immutable means. That any and all instances
of the class are const.

What I mean is that an immutable object is different from
public const MyObject o;


In concept yes. In implementation, not necessarily. A class for which
all references are implicitly const is in fact immutable.

<snip>
I don't see why C# could not give the same guarantees through a
compile time validation that C++ can. Could you elaborate on this?


To be entirely clear, the C# compiler would be expected to provide compile
time verification, thats a given in my mind. However, I don't feel that it
is enough. The runtime should provide the last-word guarentee, while the
language\compiler provides compiletime verification of its own source
against the contract provided by classes, but no deeper. The point of this
would be that *no* code could break const. Isn't that part of the point of
managed code, ?


Providing better guarantees and helping the programmer as much as
possible, certainly is a large part of the point. But you can only
take it so far. Sometimes one must be pragmatic and take what one can
get with a reasonable amount of effort and at a reasonable cost in
runtime complexity and performance.


<snip>
>Const in C++ isn't really much of a contract, its just a "you really
>shouldn't do this, but go ahead if you want to" kind of thing.
Only if you consider bugs and undefined behavior to be OK.
Const can't stop programmers from making a mess when they break the
rules on purpose. That doesn't detract anything from the protection
and clarification that it can provide.

I agree, however, I simply don't feel such a thing as a competent programmer
exists(we all screw up and make bad choices once in a while), if we are
going to go ahead with const we may as well do it right. const *isn't* a
contract when applied to a reference, in the C++ style, it is more a
shelter.


Const in C++ lets you state things like:
You may not invoke this member on a const reference.
Invoking this member will not modify observable state.

To me, that is a contract.

It protects the coder from making a mistake, but doesn't stop them.
I would like to see a form of const in C#\.NET that *is* a contract. A const
instance should always be constant.
For that matter, what I consider to be ok and what is a real contract are
very different things. For what I consider, documentation is strong enough,
I will read it and believe it(unless the code starts to show otherwise). A
real contract should be enforced by both the compiler and the runtime, not
something that can be circumvented so easily as C++ const can.
Once again, easily only if you consider undefined behavior and bugs
ok.
>I don't consider the C++ const implemetnation to be sufficent, the more I
>think about it the more I consider it broken for .NET\C#.


Please elaborate.

Much as I was saying above. It is a weak contract, if a contract at all, and
not something that should be in a system like .NET.


I think our differences in opinion here stem from different cultural
values as to the use of casts. Casts are a last resort sledgehammer.
It's telling the compiler that you know better than it does and that
it should look the other way while you cheat. The lack of generics in
C# has fostered an attitude towards casts that I consider unhealthy.
Cast are used all over the place, often unnecessarily, and no one bats
an eyelid. Hopefully that will start to change with the arrival of
generics. The C# community will need to learn that casts are "evil"
and should only ever be used in exceptional circumstances. I would
like to se a compiler warning for every cast at the highest warning
level. That should help to raise awareness that casts are dangerous
and should be avoided unless absolutely necessary. After the arrival
of generics the average application should not need a single cast.
<Anders Hejlsberg>
If you declare a method that takes a const Bla, you could pass it a
non-const Bla. But if it's the other way around you can't.
</Anders Hejlsberg>

That is exactly the point to having const. That is a boon. If your
code fails to compile because of this, you were just saved from
introducing a bug by modifying an instance you had no right to modify.

But it is annoying when the code actually doesn't make a modification,
but
>simply was written without regard to const(which, at this point, will be
>most code).


The fix is extremely simple, add const to the parameter declaration.

And do what exactly when you don't control that code?


You complain to the provider, demanding they supply a reasonably well
designed interface. In the meantime you copy the instance. If that's
undoable you bring out the sledgehammer, cast const away, and hope you
know what you are doing.
> Its a considerable limitation when your const methods have to
>start rolling their own methods to do everything because they can't
>realistically pass a const reference into a non-const method.
>I would expect something like
>public const MyType MyMethod(const MyType t) const
>{
> MyOtherMethod((MyType)t);
> return t;
>}
>
>to fail the compile time verification. t may have changed in the call to
>MyOtherMethod


Only if MyOtherMethod takes a non const MyType.


I should have specified that, but I meant to imply that MyOtherMethod
doesn't take const MyType as its parameter.

Ok. Then you're certainly right, that code would, and should, fail to
compile.
<snip>
Making it impossible to cast away const would, as you say, require
modifications to the runtime. Unless I'm mistaken, it would in fact
require changing the runtime representation of a reference, doubling
its size from 32 bits to 64, and introducing another level of
indirection for each invocation of a member on a reference. I don't
think the consequences of such a change would be palatable. For
starters it would almost double the memory usage of most .Net
applications,


I overestimated badly here. The implementation I imagined would move
the vtable pointer from the instance to the reference. The increase
would occurred only for instances having multiple references to them.
Also, no increase would occur for structs. The increase would likely
be noticeable. but probably be nowhere near a doubling for the average
application.
and I'd expect a performance degradation across the
board.
I don't think there would be a nessecery increase in the size of a
reference. 32 bits will handle 4 billion references, which is impossible to
do with 32 bit hardware(16gigs of references alone), on 64 bit hardware you
have far more. It wouldn't be impossibleto carve off 2 or 3 bits from a
reference for flags, even if a reference is only 30 bits you end up with
about 1billion possible references, which is more than enough for *ANY*
application running on the framework, even 500 million is probably
sufficent(at this numbers, the size of reference * the number of references
alone supercedes .NET allocable memory, leaving no room for the actual
objects). While such a thing isn't nessecerily feasible, it would work
without any of the problems. It also assumes the top 2 bits aren't already
used for something.


This would still require a translation for every single derefencing of
a pointer/reference. You may save some memory, but you will certainly
still suffer a performance degradation across the board.
Ideally, it would be possible to cast *to* const

That should be an implicit conversion. Zero runtime cost with a
classic implementation.

<snip>

Regards /Magnus Lidbom
Nov 15 '05 #8

P: n/a
Dan... I agree. Immutable objects simplify concurrent programming and
addresses a different problem domain than the const keyword in C++.

Regards,
Jeff
What I mean is that an immutable object is different from

public const MyObject o;<

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Nov 15 '05 #9

P: n/a
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:lm********************************@4ax.com...
<Anders Hejlsberg>
With respect to immutability, it's tricky because what you're saying
when you say something is immutable, is that from an external
perspective, I cannot observe any mutation. That doesn't necessarily
mean that it doesn't have a cache inside that makes it go more
efficiently. It's just on the outside it looks immutable. That's hard
for a compiler to figure out.
</Anders Hejlsberg>

C++ solves this problem quite handily with the mutable keyword. Only
fields declared mutable may be modified by a const member.
[snipped]


Below is my interpretation of Anders' comments, in a C++ program.
Notice how 'inst' is a const reference, so the assumption is that it behaves
immutably. Anything I do to 'inst' should not affect its behavior in any
way - I should have no ability to change its state. However, with the
mutable keyword, I can easily violate that "contract".
When Anders says "that's hard for a compiler to figure out", I think this is
the situation he refers to.

class myclass
{
protected:
mutable int _myint;

public:
myclass() : _myint(0)
{
}

int getmyint() const
{
return _myint++;
}
};
int main()
{
const myclass inst;
std::cout << inst.getmyint();
std::cout << inst.getmyint();
return 0;
}
Nov 15 '05 #10

P: n/a
On Mon, 09 Feb 2004 02:09:56 GMT, "Michael Sparks"
<mi************@remove.this.sbcglobal.net> wrote:
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:lm********************************@4ax.com.. .
<Anders Hejlsberg>
With respect to immutability, it's tricky because what you're saying
when you say something is immutable, is that from an external
perspective, I cannot observe any mutation. That doesn't necessarily
mean that it doesn't have a cache inside that makes it go more
efficiently. It's just on the outside it looks immutable. That's hard
for a compiler to figure out.
</Anders Hejlsberg>

C++ solves this problem quite handily with the mutable keyword. Only
fields declared mutable may be modified by a const member.
[snipped]
Below is my interpretation of Anders' comments, in a C++ program.
Notice how 'inst' is a const reference


Since I'm a compulsive nitpicker, inst is not a reference.
, so the assumption is that it behaves
immutably. Anything I do to 'inst' should not affect its behavior in any
way - I should have no ability to change its state. However, with the
mutable keyword, I can easily violate that "contract".
When Anders says "that's hard for a compiler to figure out", I think this is
the situation he refers to.


Perhaps, but I doubt that a compiler with a reasonably accurate
ability to detect logical errors on the part of a programmer will
appear anytime soon, and I doubt that Anders would expect contemporary
compilers to do so. To me, rather surprisingly, his comment reads more
as if he was unaware of the mutable keyword or neglected to take it
into account. His other comments on const were equally surprising.
Perhaps he was not given time to carefully consider his comments. Or
perhaps he does in fact need to upgrade his C++ knowledge.

<snip>

/Magnus Lidbom
Nov 15 '05 #11

P: n/a
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:bb********************************@4ax.com...
On Mon, 09 Feb 2004 02:09:56 GMT, "Michael Sparks"
<mi************@remove.this.sbcglobal.net> wrote:
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:lm********************************@4ax.com.. .
<Anders Hejlsberg>
With respect to immutability, it's tricky because what you're saying
when you say something is immutable, is that from an external
perspective, I cannot observe any mutation. That doesn't necessarily
mean that it doesn't have a cache inside that makes it go more
efficiently. It's just on the outside it looks immutable. That's hard
for a compiler to figure out.
</Anders Hejlsberg>

C++ solves this problem quite handily with the mutable keyword. Only
fields declared mutable may be modified by a const member.
[snipped]
Below is my interpretation of Anders' comments, in a C++ program.
Notice how 'inst' is a const reference


Since I'm a compulsive nitpicker, inst is not a reference.


Ah, good catch. I'll claim that I meant it in a literary sense. :-)
, so the assumption is that it behaves
immutably. Anything I do to 'inst' should not affect its behavior in any
way - I should have no ability to change its state. However, with the
mutable keyword, I can easily violate that "contract".
When Anders says "that's hard for a compiler to figure out", I think this isthe situation he refers to.


Perhaps, but I doubt that a compiler with a reasonably accurate
ability to detect logical errors on the part of a programmer will
appear anytime soon, and I doubt that Anders would expect contemporary
compilers to do so.


Yes, I agree that he wouldn't expect contemporary compilers to detect
logical errors, hence his comment, "that's hard for a compiler to figure
out."
I am pretty new to all this myself, so I please forgive if I get some of the
terminology wrong - I hope the idea comes through correctly.

We all acknowledge that in the presence of 'mutable', the compiler can not
reasonably be expected to enfore the concept of 'const'.
We also aknowledge that 'const' without 'mutable' is a lot less useful - it
means we can't have caching, delay loading, etc.

I count three options:
1. Have 'const' without having 'mutable'. This is not desirable because it
rules out caching, delay loading, etc.
2. Have 'const' and 'mutable'. Since the compiler and runtime can't
enforce this, it is only marginally more trustworthy than comments and
documentation.
3. Have neither. The status quo. Lose out on extra safety features and
expressiveness that we could have with 'const'.

None of the options look very good. I'm a C++ programmer at heart, so I
tend to lean toward option 2. Although it isn't perfect, C++ does just fine
with it and we don't know a better way to do it.

I can certainly understand Microsoft's reluctance though. They want the CLR
to have as pristine a type system as possible, and option 2 takes away from
that.
To me, rather surprisingly, his comment reads more
as if he was unaware of the mutable keyword or neglected to take it
into account. His other comments on const were equally surprising.
Perhaps he was not given time to carefully consider his comments. Or
perhaps he does in fact need to upgrade his C++ knowledge.


I suppose it's all speculation as to what he actually meant. I'm content in
believing he knows about mutable. :-) But you may be onto something about
being rushed in a taped interview.

Mike
Nov 15 '05 #12

P: n/a
On Mon, 09 Feb 2004 04:27:16 GMT, "Michael Sparks"
<mi************@remove.this.sbcglobal.net> wrote:
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:bb********************************@4ax.com.. .
On Mon, 09 Feb 2004 02:09:56 GMT, "Michael Sparks"
<mi************@remove.this.sbcglobal.net> wrote:
>"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>news:lm********************************@4ax.com.. .
>> <Anders Hejlsberg>

<snip>
We all acknowledge that in the presence of 'mutable', the compiler can not
reasonably be expected to enfore the concept of 'const'.
Actually, I don't. I expect it to enforce the concept of const, but
not to guarantee that a programmer provides a correct implementation.
In other words, I don't expect it to be able to see that the way that
a programmer modifies a mutable variable constitutes a breach of
contract, but I do expect it to catch the overwhelming majority of
accidental modifications.

We also aknowledge that 'const' without 'mutable' is a lot less useful - it
means we can't have caching, delay loading, etc.

I count three options:
1. Have 'const' without having 'mutable'. This is not desirable because it
rules out caching, delay loading, etc.
2. Have 'const' and 'mutable'. Since the compiler and runtime can't
enforce this, it is only marginally more trustworthy than comments and
documentation.
I strongly disagree with this estimation as to the trustworthiness of
const. See above.

<snip>
I suppose it's all speculation as to what he actually meant. I'm content in
believing he knows about mutable. :-) But you may be onto something
about being rushed in a taped interview.


I'm of the opinion that, considering the staggering amount of
information involved in creating a new programming language, it's all
but a certainty that there will be areas where anyone involved in such
en enterprise will have a less then optimal understanding. Mutable may
be quite familiar to you, but there are plenty of long time C++
programmers that don't know of it. The human mind is also far from
infallible and it's all too easy for often heard prejudices to stick
in ones mind and be mistaken for factual information. Nobody is immune
to this. The best one can do is watch for it and take the opportunity
to learn when it presents itself.
Regards /Magnus Lidbom
Nov 15 '05 #13

P: n/a
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:t7********************************@4ax.com...
We all acknowledge that in the presence of 'mutable', the compiler can notreasonably be expected to enfore the concept of 'const'.


Actually, I don't. I expect it to enforce the concept of const, but
not to guarantee that a programmer provides a correct implementation.
In other words, I don't expect it to be able to see that the way that
a programmer modifies a mutable variable constitutes a breach of
contract, but I do expect it to catch the overwhelming majority of
accidental modifications.


I think the only remaining disagreement is over the definition of the word
"contract" and how it applies to immutable. There appear to be two usages.
One usage means something that is verifiable by the compiler and/or runtime,
like the method signatures of an interface implementation - the contract can
be specified in code. The other, more general usage, is about semantics.
Most interfaces have a sort of semantic contract that the compiler can't
enforce in any way.

Slightly condensed, my argument, again, is that the C++ meaning of immutable
(const,mutable keywords) represents only a semantic contract - the kind that
the compiler can't enforce 100%. You seem to agree with this by your
statement above, and argue that it is acceptable. I also tend to think it
is acceptable, since it is what I've been using in C++ for years and it does
the job quite well.

A problem could arise, however, when unenlightened users of the language
fail to see the subtle difference in the meanings of "contract". The
absence of this sort of complexity is, IMO, what Microsoft has strived for
with C#, but there are always tradeoffs.
2. Have 'const' and 'mutable'. Since the compiler and runtime can't
enforce this, it is only marginally more trustworthy than comments and
documentation.


I strongly disagree with this estimation as to the trustworthiness of
const. See above.


Yes, I was probably being too clinical about it. :-) I actually think it
is very useful for practical everyday problems.

From a completely theoretical perspective, I'd still have to argue that if
it's unenforceable even 1% of the time, then it is untrustworthy. I admit
that assigning arbitrary values of trustworthiness (such as 'marginal')
doesn't accomplish much in the theoretical perspective, as (again, in the
theory) trustworthiness seems to be a completely binary quality.

Mike
Nov 15 '05 #14

P: n/a
On Mon, 09 Feb 2004 06:25:58 GMT, "Michael Sparks"
<mi************@remove.this.sbcglobal.net> wrote:
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:t7********************************@4ax.com.. .
>We all acknowledge that in the presence of 'mutable', the compiler cannot >reasonably be expected to enfore the concept of 'const'.


Actually, I don't. I expect it to enforce the concept of const, but
not to guarantee that a programmer provides a correct implementation.
In other words, I don't expect it to be able to see that the way that
a programmer modifies a mutable variable constitutes a breach of
contract, but I do expect it to catch the overwhelming majority of
accidental modifications.


I think the only remaining disagreement is over the definition of the word
"contract" and how it applies to immutable. There appear to be two usages.
One usage means something that is verifiable by the compiler and/or runtime,
like the method signatures of an interface implementation - the contract can
be specified in code. The other, more general usage, is about semantics.
Most interfaces have a sort of semantic contract that the compiler can't
enforce in any way.

Slightly condensed, my argument, again, is that the C++ meaning of immutable
(const,mutable keywords) represents only a semantic contract - the kind that
the compiler can't enforce 100%. You seem to agree with this by your
statement above, and argue that it is acceptable. I also tend to think it
is acceptable, since it is what I've been using in C++ for years and it does
the job quite well.

A problem could arise, however, when unenlightened users of the language
fail to see the subtle difference in the meanings of "contract". The
absence of this sort of complexity is, IMO, what Microsoft has strived for
with C#, but there are always tradeoffs.
>2. Have 'const' and 'mutable'. Since the compiler and runtime can't
>enforce this, it is only marginally more trustworthy than comments and
>documentation.


I strongly disagree with this estimation as to the trustworthiness of
const. See above.


Yes, I was probably being too clinical about it. :-) I actually think it
is very useful for practical everyday problems.

From a completely theoretical perspective, I'd still have to argue that if
it's unenforceable even 1% of the time, then it is untrustworthy. I admit
that assigning arbitrary values of trustworthiness (such as 'marginal')
doesn't accomplish much in the theoretical perspective, as (again, in the
theory) trustworthiness seems to be a completely binary quality.


There's an implied assumption here. Namely that the compiler can
enforce other contracts, such as private members. But reflection
allows you to violate those contracts quite easily as well, so
claiming that they are enforceable, while const is not, and that they
are therefore "cleaner" seems a flawed argument to me. More than
that, the enforcement we are talking about here is about catching
programmer error, such as incorrect usage of mutable. The compiler
can't catch such errors for any of the other contracts either. It is
not able to tell that the field declared public should have been
protected or perhaps private.

Regards /Magnus Lidbom
Nov 15 '05 #15

P: n/a
Magnus Lidbom <ma***********@hotmail.com> wrote:
From a completely theoretical perspective, I'd still have to argue that if
it's unenforceable even 1% of the time, then it is untrustworthy. I admit
that assigning arbitrary values of trustworthiness (such as 'marginal')
doesn't accomplish much in the theoretical perspective, as (again, in the
theory) trustworthiness seems to be a completely binary quality.


There's an implied assumption here. Namely that the compiler can
enforce other contracts, such as private members. But reflection
allows you to violate those contracts quite easily as well, so
claiming that they are enforceable, while const is not, and that they
are therefore "cleaner" seems a flawed argument to me. More than
that, the enforcement we are talking about here is about catching
programmer error, such as incorrect usage of mutable. The compiler
can't catch such errors for any of the other contracts either. It is
not able to tell that the field declared public should have been
protected or perhaps private.


Reflection only allows you to violate contracts when you tell the
runtime that it's okay to do so by running it in full trust. If you
don't like the runtime allowing that, change the security permissions
for the CLR.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #16

P: n/a

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:2m********************************@4ax.com...
On Sun, 8 Feb 2004 15:03:21 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:5e********************************@4ax.com.. .
On Sun, 8 Feb 2004 12:30:17 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

>
>"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>news:lm********************************@4ax.com.. .
>> On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (Andrew Quine) >> wrote:

<snip>

>>
>> <Anders Hejlsberg>
>> With respect to immutability, it's tricky because what you're saying
>> when you say something is immutable, is that from an external
>> perspective, I cannot observe any mutation. That doesn't necessarily
>> mean that it doesn't have a cache inside that makes it go more
>> efficiently. It's just on the outside it looks immutable. That's hard >> for a compiler to figure out.
>> </Anders Hejlsberg>
>>
>> C++ solves this problem quite handily with the mutable keyword. Only
>> fields declared mutable may be modified by a const member.
>
>It is a clean solution, however it promotes keyword and language bloat.
Is
>it worth yet another modifier?

If C++ style const is introduced, mutable is a necessity. The need for
lazy evaluation and similar techniques is far to common to leave
mutable out.

>However that doesn't directly approach the
>subject. An immutable object is not *const*, it is immutable.

It is const. That's what immutable means. That any and all instances
of the class are const.
What I mean is that an immutable object is different from
public const MyObject o;


In concept yes. In implementation, not necessarily. A class for which
all references are implicitly const is in fact immutable.


Is not concept enough? I don't consider implementation enough at times.
<snip>
I don't see why C# could not give the same guarantees through a
compile time validation that C++ can. Could you elaborate on this?
To be entirely clear, the C# compiler would be expected to provide compile
time verification, thats a given in my mind. However, I don't feel that itis enough. The runtime should provide the last-word guarentee, while the
language\compiler provides compiletime verification of its own source
against the contract provided by classes, but no deeper. The point of thiswould be that *no* code could break const. Isn't that part of the point ofmanaged code, ?


Providing better guarantees and helping the programmer as much as
possible, certainly is a large part of the point. But you can only
take it so far. Sometimes one must be pragmatic and take what one can
get with a reasonable amount of effort and at a reasonable cost in
runtime complexity and performance.

The question is whats reasonable. I feel that a runtime verified system *is*
reasonable. I don't think raw performance really matters anymore, not in
apps I write in .NET. Considering the performance drops from code access
security, reflection, and the dozen other things we use in our apps every
day, would it really matter?

<snip>

>Const in C++ isn't really much of a contract, its just a "you really
>shouldn't do this, but go ahead if you want to" kind of thing.

Only if you consider bugs and undefined behavior to be OK.
Const can't stop programmers from making a mess when they break the
rules on purpose. That doesn't detract anything from the protection
and clarification that it can provide.I agree, however, I simply don't feel such a thing as a competent programmerexists(we all screw up and make bad choices once in a while), if we are
going to go ahead with const we may as well do it right. const *isn't* a
contract when applied to a reference, in the C++ style, it is more a
shelter.


Const in C++ lets you state things like:
You may not invoke this member on a const reference.
Invoking this member will not modify observable state.

To me, that is a contract.


const on a method is a contract, const on a variable isn't. That is what I
meant.

It protects the coder from making a mistake, but doesn't stop them.
I would like to see a form of const in C#\.NET that *is* a contract. A constinstance should always be constant.
For that matter, what I consider to be ok and what is a real contract are
very different things. For what I consider, documentation is strong enough,I will read it and believe it(unless the code starts to show otherwise). Areal contract should be enforced by both the compiler and the runtime, notsomething that can be circumvented so easily as C++ const can.
Once again, easily only if you consider undefined behavior and bugs
ok.


You are making a very big mistake assuming that undefined behaviour and bugs
matters as to how easy it is to dispose of. It is *really* easy to simply
cast it away, and as I've said many times, everyone, me and you included,
are going to make stupid mistakes. C++ simply *DOESN'T* protect from that,
at times it may well promote it.
>I don't consider the C++ const implemetnation to be sufficent, the more I >think about it the more I consider it broken for .NET\C#.

Please elaborate.

Much as I was saying above. It is a weak contract, if a contract at all, andnot something that should be in a system like .NET.


I think our differences in opinion here stem from different cultural
values as to the use of casts. Casts are a last resort sledgehammer.
It's telling the compiler that you know better than it does and that
it should look the other way while you cheat. The lack of generics in
C# has fostered an attitude towards casts that I consider unhealthy.
Cast are used all over the place, often unnecessarily, and no one bats
an eyelid. Hopefully that will start to change with the arrival of
generics. The C# community will need to learn that casts are "evil"
and should only ever be used in exceptional circumstances. I would
like to se a compiler warning for every cast at the highest warning
level. That should help to raise awareness that casts are dangerous
and should be avoided unless absolutely necessary. After the arrival
of generics the average application should not need a single cast.


It depends, I cast pretty much only to explicitly convert to an interface.
Casts are frustrating things, but they are nessecery at times. I consider
casts to be a smaller issue in .NET than it is in C++. Simply put, casts are
*never* undefined, it is either an exception(a cast to a type that the
object isn't), an implicit or explicit conversion, or a cast to a actual
class. Its not possible to cast to a random object and circumvent things as
it is in C\C++.
A warning on every cast would annoy me greatly, I don't like casting things
that can be implicitly cast without an explicit cast.
> <Anders Hejlsberg>
> If you declare a method that takes a const Bla, you could pass it a
> non-const Bla. But if it's the other way around you can't.
> </Anders Hejlsberg>
>
> That is exactly the point to having const. That is a boon. If your
> code fails to compile because of this, you were just saved from
> introducing a bug by modifying an instance you had no right to modify.
But it is annoying when the code actually doesn't make a modification,
but
>simply was written without regard to const(which, at this point, will be >most code).

The fix is extremely simple, add const to the parameter declaration.

And do what exactly when you don't control that code?


You complain to the provider, demanding they supply a reasonably well
designed interface. In the meantime you copy the instance. If that's
undoable you bring out the sledgehammer, cast const away, and hope you
know what you are doing.


Now, when the *entire* framework doesn't have const, thats an awful lot of
sledgehammering, isn't it?

> Its a considerable limitation when your const methods have to
>start rolling their own methods to do everything because they can't
>realistically pass a const reference into a non-const method.
>I would expect something like
>public const MyType MyMethod(const MyType t) const
>{
> MyOtherMethod((MyType)t);
> return t;
>}
>
>to fail the compile time verification. t may have changed in the call to >MyOtherMethod

Only if MyOtherMethod takes a non const MyType.


I should have specified that, but I meant to imply that MyOtherMethod
doesn't take const MyType as its parameter.

Ok. Then you're certainly right, that code would, and should, fail to
compile.
<snip>
Making it impossible to cast away const would, as you say, require
modifications to the runtime. Unless I'm mistaken, it would in fact
require changing the runtime representation of a reference, doubling
its size from 32 bits to 64, and introducing another level of
indirection for each invocation of a member on a reference. I don't
think the consequences of such a change would be palatable. For
starters it would almost double the memory usage of most .Net
applications,
I overestimated badly here. The implementation I imagined would move
the vtable pointer from the instance to the reference. The increase
would occurred only for instances having multiple references to them.
Also, no increase would occur for structs. The increase would likely
be noticeable. but probably be nowhere near a doubling for the average
application.


structs should be immutable by default, IMHO. Considering they are by value,
const should be irrelevent in this case.
and I'd expect a performance degradation across the
board.
I don't think there would be a nessecery increase in the size of a
reference. 32 bits will handle 4 billion references, which is impossible

todo with 32 bit hardware(16gigs of references alone), on 64 bit hardware youhave far more. It wouldn't be impossibleto carve off 2 or 3 bits from a
reference for flags, even if a reference is only 30 bits you end up with
about 1billion possible references, which is more than enough for *ANY*
application running on the framework, even 500 million is probably
sufficent(at this numbers, the size of reference * the number of referencesalone supercedes .NET allocable memory, leaving no room for the actual
objects). While such a thing isn't nessecerily feasible, it would work
without any of the problems. It also assumes the top 2 bits aren't alreadyused for something.


This would still require a translation for every single derefencing of
a pointer/reference. You may save some memory, but you will certainly
still suffer a performance degradation across the board.


It shouldn't be that much, considering the work done for a reference anyway,
it shouldn't be a big deal.
Ideally, it would be possible to cast *to* const

That should be an implicit conversion. Zero runtime cost with a
classic implementation.


I dislike implicit conversions, would have been happy if the implicit
conversion operator didn't exist in C#.

<snip>

Regards /Magnus Lidbom

Nov 15 '05 #17

P: n/a
So we have these statements about the use of const as an argument qualifier:

1. It cannot be enforced anyway, the language should not suggest it does
something it cannot guarantee.
2. Any help the compiler can give in preventing unintentional errors is
welcome.

I would add that, as an OO-programmer, I never found using const with a
method argument very useful. This is why.

If I, as a client, pass in an argument by value I don't care whether the
method changes the argument or not. Const would have little meaning, it
would serve merely as an annotation on the server side saying "this argument
will not be changed by the implementation". Since it only has meaning to the
implementation the annotation does not belong in the nterface declaration.

If I pass in a simple type by reference I typically want it to be changed.
Had this not been my intent, I would have passed it by value. C# has ref and
out for those purposes and they serve us well.

If I pass in some large structure by reference for performance reasons or if
I pass in an object that is to be used by the server method for
informational purposes only, const as a concept would be appropriate.
However, this is old style programming! Today you would pass in an interface
that offers read methods and the server method could do no harm. If using
the object "for informational purposes only" is a valid application of the
object, this should be expressed in an interface and the argument's type
would be that of the interface, not the object.

So I would say that today (or at least in C#) we can well do without const
as an argument qualifier and there is no valid reason for dragging this
relic into 21st century programming.

Martin.
Nov 15 '05 #18

P: n/a
Martin Maat [EBL] <du***@somewhere.nl> wrote:
If I, as a client, pass in an argument by value I don't care whether the
method changes the argument or not. Const would have little meaning, it
would serve merely as an annotation on the server side saying "this argument
will not be changed by the implementation". Since it only has meaning to the
implementation the annotation does not belong in the nterface declaration.

If I pass in a simple type by reference I typically want it to be changed.
Had this not been my intent, I would have passed it by value. C# has ref and
out for those purposes and they serve us well.


No they don't, because just passing in a reference by value doesn't
mean that the object it refers to won't be changed. Don't forget that
you never actually pass objects as parameters in C#.

For instance, take Array.Sort(Array). That doesn't change the
*parameter*, but it *does* change the array itself. Making the
parameter a "by reference" parameter would be ludicrous, as the method
doesn't want to change the parameter itself.

Also, your argument doesn't extend to properties and return values - if
something returns a byte array, am I free to alter that or not?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #19

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Martin Maat [EBL] <du***@somewhere.nl> wrote:
If I pass in a simple type by reference I typically want it to be changed. Had this not been my intent, I would have passed it by value. C# has ref and out for those purposes and they serve us well.

No they don't, because just passing in a reference by value doesn't
mean that the object it refers to won't be changed. Don't forget that
you never actually pass objects as parameters in C#.
I was discriminating between simple types and objects, simple types being
integer, DateTime and such. I got to the objects in the next paragraph.
For instance, take Array.Sort(Array). That doesn't change the
*parameter*, but it *does* change the array itself.
If you are worried about this you don't make the argument a type that
supports methods that can be used to change the object. This is a good
example of a situation where a read interface does help out. If the
interface offers only an indexed get property, the server method will be
able to read the byte array, not change it. Only if you can't be bothered
and trust the server method, you simply pass the full blown object.
Also, your argument doesn't extend to properties and return values - if
something returns a byte array, am I free to alter that or not?


I wasn't considering return values but the same applies. If you intend to
return an object with the sole purpose of providing information to the
client, you should return a limited interface, not the object itself. It
will be clear at least, the client will not have to wonder if it may change
the object or not. I am not saying there will be no way to hack around it.

As you pointed out with your examples it is hard to define what should be
considered change, what is a violation of a const contract. With any complex
type that is quite impossible, not only technically but even more so
semantically. To what does the contract extend if you have contained and
agrigated objects? I believe this is the shadow world Anders was refering
to.

Martin.
Nov 15 '05 #20

P: n/a
On Mon, 9 Feb 2004 08:08:54 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:2m********************************@4ax.com.. .
On Sun, 8 Feb 2004 15:03:21 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
>
>"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>news:5e********************************@4ax.com.. .
>> On Sun, 8 Feb 2004 12:30:17 -0600, "Daniel O'Connell [C# MVP]"
>> <onyxkirx@--NOSPAM--comcast.net> wrote:
>>
>> >
>> >"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>> >news:lm********************************@4ax.com.. .
>> >> On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (AndrewQuine) >> >> wrote:
<snip>
>What I mean is that an immutable object is different from
>public const MyObject o;
In concept yes. In implementation, not necessarily. A class for which
all references are implicitly const is in fact immutable.


Is not concept enough? I don't consider implementation enough at times.


I don't understand what you mean. Enough what?

>> I don't see why C# could not give the same guarantees through a
>> compile time validation that C++ can. Could you elaborate on this?
>
>To be entirely clear, the C# compiler would be expected to providecompile >time verification, thats a given in my mind. However, I don't feel thatit >is enough. The runtime should provide the last-word guarentee, while the
>language\compiler provides compiletime verification of its own source
>against the contract provided by classes, but no deeper. The point ofthis >would be that *no* code could break const. Isn't that part of the pointof >managed code, ?


Providing better guarantees and helping the programmer as much as
possible, certainly is a large part of the point. But you can only
take it so far. Sometimes one must be pragmatic and take what one can
get with a reasonable amount of effort and at a reasonable cost in
runtime complexity and performance.

The question is whats reasonable. I feel that a runtime verified system *is*
reasonable. I don't think raw performance really matters anymore,
not in
apps I write in .NET. Considering the performance drops from code access
security, reflection, and the dozen other things we use in our apps every
day, would it really matter?


Performance is an important characteristic of any application. There's
always a level that's not good enough. For a much used tool, a central
library, and any number of other applications, good performance is
critical. If one wishes for ones application to do well in this area,
one needs to keep it in mind, and performance will to some degree
affect every architectural decision made. Every day I work, my
productivity is to some degree dictated by the performance of the
applications that are my tools in trade. The same goes for anyone
using a computer, everyone using the applications I make. The rising
power of hardware has not been able to do much more than offset the
rising level of complexity that the average application demands.
Hardware just a few years old is now completely unsuitable for complex
modern applications, and there's no end in sight for that trend.

>>
>> >Const in C++ isn't really much of a contract, its just a "you really
>> >shouldn't do this, but go ahead if you want to" kind of thing.
>>
>> Only if you consider bugs and undefined behavior to be OK.
>> Const can't stop programmers from making a mess when they break the
>> rules on purpose. That doesn't detract anything from the protection
>> and clarification that it can provide.
>I agree, however, I simply don't feel such a thing as a competentprogrammer >exists(we all screw up and make bad choices once in a while), if we are
>going to go ahead with const we may as well do it right. const *isn't* a
>contract when applied to a reference, in the C++ style, it is more a
>shelter.


Const in C++ lets you state things like:
You may not invoke this member on a const reference.
Invoking this member will not modify observable state.

To me, that is a contract.


const on a method is a contract, const on a variable isn't. That is what I
meant.


To my mind, when you declare a variable const you are signing a
contract saying that you will not modify that variable.
> It protects the coder from making a mistake, but doesn't stop them.
>I would like to see a form of const in C#\.NET that *is* a contract. Aconst >instance should always be constant.
>For that matter, what I consider to be ok and what is a real contract are
>very different things. For what I consider, documentation is strongenough, >I will read it and believe it(unless the code starts to show otherwise).A >real contract should be enforced by both the compiler and the runtime,not >something that can be circumvented so easily as C++ const can.


Once again, easily only if you consider undefined behavior and bugs
ok.


You are making a very big mistake assuming that undefined behaviour and bugs
matters as to how easy it is to dispose of. It is *really* easy to simply
cast it away, and as I've said many times, everyone, me and you included,
are going to make stupid mistakes. C++ simply *DOESN'T* protect from that,
at times it may well promote it.


Certainly. It is easy to make mistakes. I make them every day. That's
largely why I need all the abstractions that helps me create better,
safer code faster than I could without them. I very much appreciate
the compilers efforts on my behalf. But at the end of the day the
compiler is a tool that I need to do what I tell it. If I tell it to
look the other way while I cheat, by applying a cast, I expect it to
obey, because there are situations where I must have that ability. You
brought one such situation up in your last post.
I think our differences in opinion here stem from different cultural
values as to the use of casts. Casts are a last resort sledgehammer.
It's telling the compiler that you know better than it does and that
it should look the other way while you cheat. The lack of generics in
C# has fostered an attitude towards casts that I consider unhealthy.
Cast are used all over the place, often unnecessarily, and no one bats
an eyelid. Hopefully that will start to change with the arrival of
generics. The C# community will need to learn that casts are "evil"
and should only ever be used in exceptional circumstances. I would
like to se a compiler warning for every cast at the highest warning
level. That should help to raise awareness that casts are dangerous
and should be avoided unless absolutely necessary. After the arrival
of generics the average application should not need a single cast.


It depends, I cast pretty much only to explicitly convert to an interface.


Good catch. I failed to consider that quirk of the language. Since the
compiler already knows that the class implements the interface, and
that the cast will therefore always succeed, no warning should be
issued in this case. Semantically, this is not a cast. It is merely a
mechanism to allow you to unambiguously specify which method you
intended to call in the presence of naming conflicts when implementing
multiple interfaces.

Casts are frustrating things, but they are nessecery at times. I consider
casts to be a smaller issue in .NET than it is in C++. Simply put, casts are
*never* undefined, it is either an exception(a cast to a type that the
object isn't), an implicit or explicit conversion, or a cast to a actual
class. Its not possible to cast to a random object and circumvent things as
it is in C\C++.
A warning on every cast would annoy me greatly, I don't like casting things
that can be implicitly cast without an explicit cast.
Implicit conversions are quite different. Nowhere near as dangerous as
casts. Barring improper user defined conversions and violations of
Liskov's Substitutability Principle, implicit conversions should
always be safe. I certainly wouldn't want warnings for those.

>>>> <Anders Hejlsberg>
>>>> If you declare a method that takes a const Bla, you could pass it a
>>>> non-const Bla. But if it's the other way around you can't.
>>>> </Anders Hejlsberg>
>>>>
>>>> That is exactly the point to having const. That is a boon. If your
>>>> code fails to compile because of this, you were just saved from
>>>> introducing a bug by modifying an instance you had no right tomodify. >>>
>>>But it is annoying when the code actually doesn't make a modification,
>>>but
>> >simply was written without regard to const(which, at this point, willbe >> >most code).
>>
>> The fix is extremely simple, add const to the parameter declaration.
>And do what exactly when you don't control that code?


You complain to the provider, demanding they supply a reasonably well
designed interface. In the meantime you copy the instance. If that's
undoable you bring out the sledgehammer, cast const away, and hope you
know what you are doing.


Now, when the *entire* framework doesn't have const, thats an awful lot of
sledgehammering, isn't it?


If no part of the framework uses const then const will simply be
irrelevant in the context of the framework classes. There will be no
need for casts. Problems arise only upon inconsistent use of const.
>> Making it impossible to cast away const would, as you say, require
>> modifications to the runtime. Unless I'm mistaken, it would in fact
>> require changing the runtime representation of a reference, doubling
>> its size from 32 bits to 64, and introducing another level of
>> indirection for each invocation of a member on a reference. I don't
>> think the consequences of such a change would be palatable. For
>> starters it would almost double the memory usage of most .Net
>> applications,


I overestimated badly here. The implementation I imagined would move
the vtable pointer from the instance to the reference. The increase
would occurred only for instances having multiple references to them.
Also, no increase would occur for structs. The increase would likely
be noticeable. but probably be nowhere near a doubling for the average
application.


structs should be immutable by default, IMHO.


Immutability is a relatively rare trait, making it the default would ,
in my opinion, be inappropriate. It certainly would break an immense
amount of code.
Considering they are by value,
const should be irrelevent in this case.
What about ref and out parameters?

>I don't think there would be a nessecery increase in the size of a
>reference. 32 bits will handle 4 billion references, which is impossibleto >do with 32 bit hardware(16gigs of references alone), on 64 bit hardwareyou >have far more. It wouldn't be impossibleto carve off 2 or 3 bits from a
>reference for flags, even if a reference is only 30 bits you end up with
>about 1billion possible references, which is more than enough for *ANY*
>application running on the framework, even 500 million is probably
>sufficent(at this numbers, the size of reference * the number ofreferences >alone supercedes .NET allocable memory, leaving no room for the actual
>objects). While such a thing isn't nessecerily feasible, it would work
>without any of the problems. It also assumes the top 2 bits aren'talready >used for something.


This would still require a translation for every single derefencing of
a pointer/reference. You may save some memory, but you will certainly
still suffer a performance degradation across the board.


It shouldn't be that much, considering the work done for a reference anyway,
it shouldn't be a big deal.
>Ideally, it would be possible to cast *to* const

That should be an implicit conversion. Zero runtime cost with a
classic implementation.


I dislike implicit conversions,


Even those, like the one above, that are 100% guaranteed to be safe?
would have been happy if the implicit
conversion operator didn't exist in C#.


You rarely need to define your own conversion operator, but when you
do the difference in usability of the type tends to be very large. I
certainly would't care for the need to cast from Int32 to Int64 or the
equivalent in complex numbers.

You don't believe in the competent programmer. I don't believe in the
safe programming language. I do believe in the balanced programming
language. The one that takes a pragmatic approach and tries to shelter
the programmers as much as possible without hamstringing them or
creating catch 22 scenarios. I think C# has done very well so far.
/Magnus Lidbom

Nov 15 '05 #21

P: n/a
On Mon, 9 Feb 2004 18:45:01 +0100, "Martin Maat [EBL]"
<du***@somewhere.nl> wrote:
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft. com...
Martin Maat [EBL] <du***@somewhere.nl> wrote:
> If I pass in a simple type by reference I typically want it to bechanged. > Had this not been my intent, I would have passed it by value. C# has refand > out for those purposes and they serve us well.
No they don't, because just passing in a reference by value doesn't
mean that the object it refers to won't be changed. Don't forget that
you never actually pass objects as parameters in C#.


I was discriminating between simple types and objects, simple types being
integer, DateTime and such. I got to the objects in the next paragraph.
For instance, take Array.Sort(Array). That doesn't change the
*parameter*, but it *does* change the array itself.


If you are worried about this you don't make the argument a type that
supports methods that can be used to change the object. This is a good
example of a situation where a read interface does help out. If the
interface offers only an indexed get property, the server method will be
able to read the byte array, not change it. Only if you can't be bothered
and trust the server method, you simply pass the full blown object.


I wrote a post, with a short comparison of const and read only
interfaces, not long ago that you may find enlightening:

http://groups.google.com/groups?q=g:...lin.de&rnum=38
Also, your argument doesn't extend to properties and return values - if
something returns a byte array, am I free to alter that or not?


I wasn't considering return values but the same applies. If you intend to
return an object with the sole purpose of providing information to the
client, you should return a limited interface, not the object itself. It
will be clear at least, the client will not have to wonder if it may change
the object or not. I am not saying there will be no way to hack around it.

As you pointed out with your examples it is hard to define what should be
considered change, what is a violation of a const contract.


Not really. He just pointed out the fact that you must distinguish the
parameter from the object referenced by the parameter in the case of
reference type parameters, and that the ref and out keywords doesn't
help in managíng access to that object.
With any complex
type that is quite impossible,
not only technically but even more so
semantically. To what does the contract extend if you have contained and
agrigated objects? I believe this is the shadow world Anders was refering
to.


I've never seen or heard of any such impossibilities. How const
applies to aggregated objects has always seemed perfectly logical and
infinitely extensible to me. Could you provide a concrete example?

/Magnus Lidbom
Nov 15 '05 #22

P: n/a

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:98********************************@4ax.com...
On Mon, 9 Feb 2004 08:08:54 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:2m********************************@4ax.com.. .
On Sun, 8 Feb 2004 15:03:21 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

>
>"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>news:5e********************************@4ax.com.. .
>> On Sun, 8 Feb 2004 12:30:17 -0600, "Daniel O'Connell [C# MVP]"
>> <onyxkirx@--NOSPAM--comcast.net> wrote:
>>
>> >
>> >"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>> >news:lm********************************@4ax.com.. .
>> >> On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (AndrewQuine)
>> >> wrote:
<snip>
What I mean is that an immutable object is different from
>public const MyObject o;

In concept yes. In implementation, not necessarily. A class for which
all references are implicitly const is in fact immutable.


Is not concept enough? I don't consider implementation enough at times.


I don't understand what you mean. Enough what?

Implicitly const classes are immutable by implementation. That makes the
object immutable as either a sideeffect or a matter of const implementation.
This is slightly different than an object being immutable at its core. It is
subtle, I suppose.

>> I don't see why C# could not give the same guarantees through a
>> compile time validation that C++ can. Could you elaborate on this?
>
>To be entirely clear, the C# compiler would be expected to providecompile
>time verification, thats a given in my mind. However, I don't feel that
it
>is enough. The runtime should provide the last-word guarentee, while
the >language\compiler provides compiletime verification of its own source
>against the contract provided by classes, but no deeper. The point of

this
>would be that *no* code could break const. Isn't that part of the point
of
>managed code, ?

Providing better guarantees and helping the programmer as much as
possible, certainly is a large part of the point. But you can only
take it so far. Sometimes one must be pragmatic and take what one can
get with a reasonable amount of effort and at a reasonable cost in
runtime complexity and performance.

The question is whats reasonable. I feel that a runtime verified system *is*reasonable. I don't think raw performance really matters anymore,
not in
apps I write in .NET. Considering the performance drops from code access
security, reflection, and the dozen other things we use in our apps every
day, would it really matter?


Performance is an important characteristic of any application. There's
always a level that's not good enough. For a much used tool, a central
library, and any number of other applications, good performance is
critical. If one wishes for ones application to do well in this area,
one needs to keep it in mind, and performance will to some degree
affect every architectural decision made. Every day I work, my
productivity is to some degree dictated by the performance of the
applications that are my tools in trade. The same goes for anyone
using a computer, everyone using the applications I make. The rising
power of hardware has not been able to do much more than offset the
rising level of complexity that the average application demands.
Hardware just a few years old is now completely unsuitable for complex
modern applications, and there's no end in sight for that trend.

On this I agree, however for most apps I still think overarching performance
is a tertiary issue, feature set\specs are first, good enough performance
second Where to draw the line isn't really my place, most apps I write
aren't highly performance critical, speed of development and safety of
development is. It would be mainly a tradeoff between the speed of the app
and the ease and safety of the code...sounds alot like the major tradoff
between unmanaged and managed code?>
>> >Const in C++ isn't really much of a contract, its just a "you
really >> >shouldn't do this, but go ahead if you want to" kind of thing.
>>
>> Only if you consider bugs and undefined behavior to be OK.
>> Const can't stop programmers from making a mess when they break the
>> rules on purpose. That doesn't detract anything from the protection
>> and clarification that it can provide.
>I agree, however, I simply don't feel such a thing as a competentprogrammer
>exists(we all screw up and make bad choices once in a while), if we are >going to go ahead with const we may as well do it right. const *isn't* a >contract when applied to a reference, in the C++ style, it is more a
>shelter.

Const in C++ lets you state things like:
You may not invoke this member on a const reference.
Invoking this member will not modify observable state.

To me, that is a contract.


const on a method is a contract, const on a variable isn't. That is what Imeant.


To my mind, when you declare a variable const you are signing a
contract saying that you will not modify that variable.


To mine, you are saying "I'll try not to modfiy this, but if I have to I
will anyway". Thats not a contract. At the very least its a very weakly
binding contract. It protects the coder from making a mistake, but doesn't stop them.
>I would like to see a form of const in C#\.NET that *is* a contract. Aconst
>instance should always be constant.
>For that matter, what I consider to be ok and what is a real contract are >very different things. For what I consider, documentation is strong

enough,
>I will read it and believe it(unless the code starts to show otherwise).
A
>real contract should be enforced by both the compiler and the runtime,

not
>something that can be circumvented so easily as C++ const can.

Once again, easily only if you consider undefined behavior and bugs
ok.


You are making a very big mistake assuming that undefined behaviour and bugs
matters as to how easy it is to dispose of. It is *really* easy to simply
cast it away, and as I've said many times, everyone, me and you included,
are going to make stupid mistakes. C++ simply *DOESN'T* protect from that,at times it may well promote it.


Certainly. It is easy to make mistakes. I make them every day. That's
largely why I need all the abstractions that helps me create better,
safer code faster than I could without them. I very much appreciate
the compilers efforts on my behalf. But at the end of the day the
compiler is a tool that I need to do what I tell it. If I tell it to
look the other way while I cheat, by applying a cast, I expect it to
obey, because there are situations where I must have that ability. You
brought one such situation up in your last post.

WHich is part of what bothers me. Cheating via reflection or something else
that can be controlled by security is one thing, cheating using the language
is quite antoher. I think our differences in opinion here stem from different cultural
values as to the use of casts. Casts are a last resort sledgehammer.
It's telling the compiler that you know better than it does and that
it should look the other way while you cheat. The lack of generics in
C# has fostered an attitude towards casts that I consider unhealthy.
Cast are used all over the place, often unnecessarily, and no one bats
an eyelid. Hopefully that will start to change with the arrival of
generics. The C# community will need to learn that casts are "evil"
and should only ever be used in exceptional circumstances. I would
like to se a compiler warning for every cast at the highest warning
level. That should help to raise awareness that casts are dangerous
and should be avoided unless absolutely necessary. After the arrival
of generics the average application should not need a single cast.

It depends, I cast pretty much only to explicitly convert to an interface.
Good catch. I failed to consider that quirk of the language. Since the
compiler already knows that the class implements the interface, and
that the cast will therefore always succeed, no warning should be
issued in this case. Semantically, this is not a cast. It is merely a
mechanism to allow you to unambiguously specify which method you
intended to call in the presence of naming conflicts when implementing
multiple interfaces.
Unfortunatly, the compiler can't actually know if the class implements the
interface, atleast usually. A typed variable has no constraints on if the
class provides an interface unless the type does. Derived classes are free
to (re)implement interfaces. It may not be the cleanest thing but it is
often reliable(preferably using as rather than (cast) operation, but still).
Casts are frustrating things, but they are nessecery at times. I consider
casts to be a smaller issue in .NET than it is in C++. Simply put, casts are*never* undefined, it is either an exception(a cast to a type that the
object isn't), an implicit or explicit conversion, or a cast to a actual
class. Its not possible to cast to a random object and circumvent things asit is in C\C++.
A warning on every cast would annoy me greatly, I don't like casting thingsthat can be implicitly cast without an explicit cast.
Implicit conversions are quite different. Nowhere near as dangerous as
casts. Barring improper user defined conversions and violations of
Liskov's Substitutability Principle, implicit conversions should
always be safe. I certainly wouldn't want warnings for those.

Safe is one thing, confusing and unapparent is another. Implicit conversions
in most cases are an issue more of apparentability than anything else. Casts
are apparent and a coder can deal with them, an implicit conversion is a
risky thing that can cause code and behaviour to come into being that isn't
expected.
>>> <Anders Hejlsberg>
>>>> If you declare a method that takes a const Bla, you could pass it
a >>>> non-const Bla. But if it's the other way around you can't.
>>>> </Anders Hejlsberg>
>>>>
>>>> That is exactly the point to having const. That is a boon. If your
>>>> code fails to compile because of this, you were just saved from
>>>> introducing a bug by modifying an instance you had no right tomodify.
>>>
>>>But it is annoying when the code actually doesn't make a modification, >>>but
>> >simply was written without regard to const(which, at this point, will
be
>> >most code).
>>
>> The fix is extremely simple, add const to the parameter declaration.
>And do what exactly when you don't control that code?

You complain to the provider, demanding they supply a reasonably well
designed interface. In the meantime you copy the instance. If that's
undoable you bring out the sledgehammer, cast const away, and hope you
know what you are doing.


Now, when the *entire* framework doesn't have const, thats an awful lot ofsledgehammering, isn't it?


If no part of the framework uses const then const will simply be
irrelevant in the context of the framework classes. There will be no
need for casts. Problems arise only upon inconsistent use of const.

If const is limited to only some areas, is it right? Is it valuable? In my
opinoin it isn't. If const isn't used everywehre its utility is
significantly reduced, fragemented really. If theframework isn't const able,
const is a useless feature.
>> Making it impossible to cast away const would, as you say, require
>> modifications to the runtime. Unless I'm mistaken, it would in fact
>> require changing the runtime representation of a reference, doubling
>> its size from 32 bits to 64, and introducing another level of
>> indirection for each invocation of a member on a reference. I don't
>> think the consequences of such a change would be palatable. For
>> starters it would almost double the memory usage of most .Net
>> applications,

I overestimated badly here. The implementation I imagined would move
the vtable pointer from the instance to the reference. The increase
would occurred only for instances having multiple references to them.
Also, no increase would occur for structs. The increase would likely
be noticeable. but probably be nowhere near a doubling for the average
application.
structs should be immutable by default, IMHO.


Immutability is a relatively rare trait, making it the default would ,
in my opinion, be inappropriate. It certainly would break an immense
amount of code.

Possibly, I should say immutability should be a design goal for value types.
Due to their copy by value nature, you can't rely on a value type for much,
immutability is often logical.
Considering they are by value,
const should be irrelevent in this case.
What about ref and out parameters?

Thats irrellevent, ref paramenters are implicitly going to change, thats the
purpose of the ref(to allow the parameter to change the reference or
structure directly). const wouldn't work in this case, run this, waht do you
get?:
using System;

public class Class1
{
public static void Main(string[] args)
{
int x = 10;
int y = x;
TestMethod(ref y);
Console.WriteLine("X: " + x);
Console.WriteLine("Y: " + y);
}
static void TestMethod(ref int value)
{
value = 44;
}
}

x is never changed, nor should it be, the value is copied to y. const would
only make sense in the case of boxing.

>I don't think there would be a nessecery increase in the size of a
>reference. 32 bits will handle 4 billion references, which is
impossibleto
>do with 32 bit hardware(16gigs of references alone), on 64 bit
hardwareyou
>have far more. It wouldn't be impossibleto carve off 2 or 3 bits from
a >reference for flags, even if a reference is only 30 bits you end up with >about 1billion possible references, which is more than enough for *ANY* >application running on the framework, even 500 million is probably
>sufficent(at this numbers, the size of reference * the number ofreferences
>alone supercedes .NET allocable memory, leaving no room for the actual
>objects). While such a thing isn't nessecerily feasible, it would work
>without any of the problems. It also assumes the top 2 bits aren't

already
>used for something.

This would still require a translation for every single derefencing of
a pointer/reference. You may save some memory, but you will certainly
still suffer a performance degradation across the board.


It shouldn't be that much, considering the work done for a reference

anyway,it shouldn't be a big deal.
>Ideally, it would be possible to cast *to* const
That should be an implicit conversion. Zero runtime cost with a
classic implementation.


I dislike implicit conversions,


Even those, like the one above, that are 100% guaranteed to be safe?


Except in limited situations, I'd rather see the explicit cast in code,
mainly for maintaince sake.
would have been happy if the implicit
conversion operator didn't exist in C#.
You rarely need to define your own conversion operator, but when you
do the difference in usability of the type tends to be very large. I
certainly would't care for the need to cast from Int32 to Int64 or the
equivalent in complex numbers.

You have a point here, There are some *limited* uses for implicit casts.
You don't believe in the competent programmer. I don't believe in the
safe programming language. I do believe in the balanced programming
language. The one that takes a pragmatic approach and tries to shelter
the programmers as much as possible without hamstringing them or
creating catch 22 scenarios. I think C# has done very well so far. As do I, I just think there are a few other bits that could be done, ;).

/Magnus Lidbom

Nov 15 '05 #23

P: n/a
Martin Maat [EBL] <du***@somewhere.nl> wrote:
No they don't, because just passing in a reference by value doesn't
mean that the object it refers to won't be changed. Don't forget that
you never actually pass objects as parameters in C#.
I was discriminating between simple types and objects, simple types being
integer, DateTime and such. I got to the objects in the next paragraph.


Apologies, yes.
For instance, take Array.Sort(Array). That doesn't change the
*parameter*, but it *does* change the array itself.


If you are worried about this you don't make the argument a type that
supports methods that can be used to change the object. This is a good
example of a situation where a read interface does help out. If the
interface offers only an indexed get property, the server method will be
able to read the byte array, not change it. Only if you can't be bothered
and trust the server method, you simply pass the full blown object.


But you can't add your own interfaces on top of, say, arrays,
ArrayList, etc, and the existing interfaces just aren't enough. I
suppose they could be added, but then you'd have pretty much one
interface per mutable class - is that really better than a single extra
keyword?
Also, your argument doesn't extend to properties and return values - if
something returns a byte array, am I free to alter that or not?


I wasn't considering return values but the same applies. If you intend to
return an object with the sole purpose of providing information to the
client, you should return a limited interface, not the object itself. It
will be clear at least, the client will not have to wonder if it may change
the object or not. I am not saying there will be no way to hack around it.


Indeed - just casting would do it.
As you pointed out with your examples it is hard to define what should be
considered change, what is a violation of a const contract. With any complex
type that is quite impossible, not only technically but even more so
semantically. To what does the contract extend if you have contained and
agrigated objects? I believe this is the shadow world Anders was refering
to.


I don't think my example showed it being hard at all - Sort certainly
wouldn't take a "const array", although it could take an "array of
const elements" because it doesn't change the elements themselves. One
of the biggest problems there is the syntax, really.

Admittedly, there *is* another problem which is quite nasty. For
instance:

object[] o = new object[...];
o[0]=o;
....

Should you be able to sort o or not? Changing the array changes the
element within it because it contains itself. Personally, I'd be happy
with something which didn't try to particularly get things right in
that kind of situation, just because it's *so* hard to get right.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #24

P: n/a
There are two different issues here:

1) Marking a whole struct or class as being immutable (like String,
DateTime, etc.)

2) Qualifying method parameters (or target) with const.

Regarding 1), I really don't understand why C# does not let you apply the
readonly keyword to a class, to mean that all the fields are readonly. This
does not require the introduction of a new keyword (like immutable),
readonly is good enough.

Of course, this does not address the case where the class is mutable
internally but immutable from an external observer's viewpoint (the case
Anders worries about). But I don't care so much about this case, because 95%
of the time, my "immutable" entities are small classes or structs that are
also immutable internally. So, to me "readonly" at class level would be
enough. Later on, we can see if it is worth introducing "mutable" to qualify
fields that make it mutable internally but not externally.

Regarding 2), I don't think it is worth the trouble. As Martin Matt points
out, it is not useful when the argument is a struct because then, the
presence of the ref/out keyword defines how const it will be from the
caller's point of view (nobody cares about how the callee will treat it
(*)). And, in the case of objects, defining readonly interfaces and passing
the object as one of its readonly interfaces is probably the best way to go.

(*) Unfortunately C# followed the C, C++ and Java tradition and allows you
to use parameters as variables inside the method. Things would be much
cleaner if you were only allowed to reassign a value to the parameter when
it is qualified with ref or out (the way Pascal does it).

Bruno.


Nov 15 '05 #25

P: n/a
On Mon, 9 Feb 2004 13:26:08 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:98********************************@4ax.com.. .
On Mon, 9 Feb 2004 08:08:54 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
>
>"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>news:2m********************************@4ax.com.. .
>> On Sun, 8 Feb 2004 15:03:21 -0600, "Daniel O'Connell [C# MVP]"
>> <onyxkirx@--NOSPAM--comcast.net> wrote:
>>
>> >
>> >"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>> >news:5e********************************@4ax.com.. .
>> >> On Sun, 8 Feb 2004 12:30:17 -0600, "Daniel O'Connell [C# MVP]"
>> >> <onyxkirx@--NOSPAM--comcast.net> wrote:
>> >>
>> >> >
>> >> >"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>> >> >news:lm********************************@4ax.com.. .
>> >> >> On 8 Feb 2004 04:38:29 -0800, an**********@fastmail.fm (Andrew
>Quine)
>> >> >> wrote:
<snip>
>> >What I mean is that an immutable object is different from
>> >public const MyObject o;
>>
>> In concept yes. In implementation, not necessarily. A class for which
>> all references are implicitly const is in fact immutable.
>>
>
>Is not concept enough? I don't consider implementation enough at times.


I don't understand what you mean. Enough what?

Implicitly const classes are immutable by implementation. That makes the
object immutable as either a sideeffect or a matter of const implementation.
This is slightly different than an object being immutable at its core. It is
subtle, I suppose.


I'm sorry, I still don't understand what point you are trying to
make. What do you mean by "at its core"? I don't understand why you'd
consider it a sideaffect. The immutability could be accomplished
,behind the scenes, by implicitly making all members and alll
instances of a class declared immutable const. That doesn't mean the
immutability of the class would be any less an conscious, intentional,
and explicit atribute of the class.

Performance is an important characteristic of any application. There's
always a level that's not good enough. For a much used tool, a central
library, and any number of other applications, good performance is
critical. If one wishes for ones application to do well in this area,
one needs to keep it in mind, and performance will to some degree
affect every architectural decision made. Every day I work, my
productivity is to some degree dictated by the performance of the
applications that are my tools in trade. The same goes for anyone
using a computer, everyone using the applications I make. The rising
power of hardware has not been able to do much more than offset the
rising level of complexity that the average application demands.
Hardware just a few years old is now completely unsuitable for complex
modern applications, and there's no end in sight for that trend.

On this I agree, however for most apps I still think overarching performance
is a tertiary issue,


Only if performance is already acceptable. Would you use a news reader
that took 90 seconds to start and 15 seconds to display a post? No
matter how many nifty features it had, or how maintainable it was, I
wouldn't.
feature set\specs are first, good enough performance
second Where to draw the line isn't really my place, most apps I write
aren't highly performance critical, speed of development and safety of
development is. It would be mainly a tradeoff between the speed of the app
and the ease and safety of the code
I find that clean well structured designs generally perform very well.
Caching and lazy evaluation barred, I rarely find myself complicating
a design in order to improve performance.
Certainly. It is easy to make mistakes. I make them every day. That's
largely why I need all the abstractions that helps me create better,
safer code faster than I could without them. I very much appreciate
the compilers efforts on my behalf. But at the end of the day the
compiler is a tool that I need to do what I tell it. If I tell it to
look the other way while I cheat, by applying a cast, I expect it to
obey, because there are situations where I must have that ability. You
brought one such situation up in your last post.

WHich is part of what bothers me. Cheating via reflection or something else
that can be controlled by security is one thing, cheating using the language
is quite antoher.


It bothers me too, but I've yet to hear of an alternative I consider
better.

>It depends, I cast pretty much only to explicitly convert to aninterface.

Good catch. I failed to consider that quirk of the language. Since the
compiler already knows that the class implements the interface, and
that the cast will therefore always succeed, no warning should be
issued in this case. Semantically, this is not a cast. It is merely a
mechanism to allow you to unambiguously specify which method you
intended to call in the presence of naming conflicts when implementing
multiple interfaces.

Unfortunatly, the compiler can't actually know if the class implements the
interface, atleast usually. A typed variable has no constraints on if the
class provides an interface unless the type does. Derived classes are free
to (re)implement interfaces. It may not be the cleanest thing but it is
often reliable(preferably using as rather than (cast) operation, but still).


I assumed you were talking about casting an instance of a specific
class to an interface that the instance's class implements explicitly.
If that's not what you mean, then either there is no need for a cast,
or we are talking about the sledgehammer that I would want to se a
warning for, at the highest warning level.

>Casts are frustrating things, but they are nessecery at times. I consider
>casts to be a smaller issue in .NET than it is in C++. Simply put, castsare >*never* undefined, it is either an exception(a cast to a type that the
>object isn't), an implicit or explicit conversion, or a cast to a actual
>class. Its not possible to cast to a random object and circumvent thingsas >it is in C\C++.
To a great degree that's true. But how hard is it to cast
IConstMyClass to MyClass? Any harder than casting away const? Any
more safe? How about IList to ArrayList when the debugger has shown
you that it is an ArrayList?
Safe is one thing, confusing and unapparent is another. Implicit conversions
in most cases are an issue more of apparentability than anything else. Casts
are apparent and a coder can deal with them, an implicit conversion is a
risky thing that can cause code and behaviour to come into being that isn't
expected.


It should be neither confusing, unapparent nor risky. Implicit
conversions should occur only where the source type is an instance of
the target type as far as OO is concerned. As far as I know this is
the case for all built in implicit convertions.
>Now, when the *entire* framework doesn't have const, thats an awful lotof >sledgehammering, isn't it?


If no part of the framework uses const then const will simply be
irrelevant in the context of the framework classes. There will be no
need for casts. Problems arise only upon inconsistent use of const.

If const is limited to only some areas, is it right? Is it valuable? In my
opinoin it isn't. If const isn't used everywehre its utility is
significantly reduced, fragemented really. If theframework isn't const able,
const is a useless feature.


Can you present an example, in code, where the framework not using
const would significantly detract from my ability to benefit from
using const? Except for needing to swap out the included collections,
I don't see much of a problem at all. And I'd certainly expect const
correct collections to be provided if const was implemented.
>structs should be immutable by default, IMHO.


Immutability is a relatively rare trait, making it the default would ,
in my opinion, be inappropriate. It certainly would break an immense
amount of code.

Possibly, I should say immutability should be a design goal for value types.
Due to their copy by value nature, you can't rely on a value type for much,
immutability is often logical.


This is not at all my experience. Actually, I don't know of a single
immutable struct type. Could you provide examples and a motivation for
this guideline?
>Considering they are by value,
>const should be irrelevent in this case.


What about ref and out parameters?

Thats irrellevent, ref paramenters are implicitly going to change, thats the
purpose of the ref


Exactly. That doesn't mix at all with immutable structs, which was the
point I was trying to make.

<snip>

>> >Ideally, it would be possible to cast *to* const
>> That should be an implicit conversion. Zero runtime cost with a
>> classic implementation.
>
>I dislike implicit conversions,


Even those, like the one above, that are 100% guaranteed to be safe?


Except in limited situations, I'd rather see the explicit cast in code,
mainly for maintaince sake.


I don't understand this at all. How would placing a cast at the site
of every implicit convertion help maintainability? I'd expect the
opposite. A whole lot of code would still compile after changing the
type of a variable, because you explicitly cast it when passing it as
a base type or interface. You've written a whole lot of unnessessary
casts and moved refactoring problems from compile time to runtime, as
well as significantly increased the pure typing effort involved in
both the original coding and any refactoring. I see no gain in any of
this. Quite the opposite.
<snip>
You don't believe in the competent programmer. I don't believe in the
safe programming language. I do believe in the balanced programming
language. The one that takes a pragmatic approach and tries to shelter
the programmers as much as possible without hamstringing them or
creating catch 22 scenarios. I think C# has done very well so far.

As do I, I just think there are a few other bits that could be done, ;).


As do I. Most of the things I want done are in fact scheduled for
Whidbey :)
Regards /Magnus Lidbom

Nov 15 '05 #26

P: n/a
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:tg********************************@4ax.com...
I wrote a post, with a short comparison of const and read only
interfaces, not long ago that you may find enlightening: http://groups.google.com/groups?q=g:...lin.de&rnum=38

Okay, you compare using interfaces to the const keyword and conclude that
const is more concise and thus more powerful. It would be if it were the
same as using interfaces. The problem with const as I understand it is that
it will never be quite clear what exactly is to be considered const. The
implementor (or definor of the language if you will) has to choose a level
of protection ranging from just the object reference pointer (pretty
useless) to any dependencies one might access through the object. The latter
would be stronger but could turn out to be equally useless because it
ultimately would mean that the code querying the object should be denied
write access to anything, meaning it would not work.

I think the const concept just doesn't fit the object concept. Const is okay
for simple types but has no meaning to objects. In other words: it makes
sense for data but not for behavior.

It seems to me that if one says "it would be nice if we could apply const to
object arguments" one doesn't grasp the concequences.

I am not too confident myself here and the previous statement is not to say
you don't know what you are talking about (it sounds a bit like an insult),
my point is that I think once we apply const to objects, the possible
complexity is infinite and it would be impossible to implement (if you take
the protection serious anyway).
Not really. He just pointed out the fact that you must distinguish the
parameter from the object referenced by the parameter in the case of
reference type parameters, and that the ref and out keywords doesn't
help in managíng access to that object.


That is the issue, managing access to the object. I don't see how it could
be done because the compiler doesn't know what changes the object and what
doesn't. Like with the Sort method or retrieval of contained object
properties that may themselves expose write methods. The compiler could
never track that and sometimes it may not even make sense to do so. It would
be like asking the compiler to understand the semantics of your class and
then make judgements about what should be considered change and what should
not.

Some ten years ago the buz was fuzzy logic. It never took on. This reminds
me of fuzzy logic, I don't think I want it in C#.

Martin.
Nov 15 '05 #27

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
But you can't add your own interfaces on top of, say, arrays,
ArrayList, etc, and the existing interfaces just aren't enough.
No, it doesn't work for sealed classes. You would have to descend from them
and implement the interface in the descendant. A lot of work, true.
I suppose they could be added, but then you'd have pretty much one
interface per mutable class - is that really better than a single extra
keyword?


I would know what it does and what it does not and as the writer of the
interface I would have full control over what to lock down. Const would
supposedly lock down "the object". Defining that seems impossible to me. I
eleborate on that in my message to Magnus.

Perhaps I am just not easily satisfied with a "practicle" implementation of
const for object arguments. I tend to go with those that say "if you can't
do it right/clean, don't do it at all". Not so much for purity's sake
(catching half of the bugs is better than none, I agree) as for fuzzy
semantics. If I don't understand what it does I don't want it. I guess it
would be possible to define some generic behavior for const on object
arguments that would be practicle but it would be too complicated for me to
understand.

Martin.
Nov 15 '05 #28

P: n/a
On Tue, 10 Feb 2004 00:26:27 +0100, "Martin Maat [EBL]"
<du***@somewhere.nl> wrote:
"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:tg********************************@4ax.com.. .
I wrote a post, with a short comparison of const and read only
interfaces, not long ago that you may find enlightening:

http://groups.google.com/groups?q=g:...lin.de&rnum=38

Okay, you compare using interfaces to the const keyword and conclude that
const is more concise and thus more powerful.
It would be if it were the
same as using interfaces. The problem with const as I understand it is that
it will never be quite clear what exactly is to be considered const.


If the compiler could not always unambiguously deduce what was const
it would be fundamentally broken. The C++ compilers are not broken in
this fashion.
The
implementor (or definor of the language if you will) has to choose a level
of protection ranging from just the object reference pointer (pretty
useless) to any dependencies one might access through the object. The latter
would be stronger but could turn out to be equally useless because it
ultimately would mean that the code querying the object should be denied
write access to anything, meaning it would not work.
I think the const concept just doesn't fit the object concept. Const is okay
for simple types but has no meaning to objects. In other words: it makes
sense for data but not for behavior.
It seems to me that if one says "it would be nice if we could apply const to
object arguments" one doesn't grasp the concequences.
If that was correct, then the entire C++ community must have failed to
grasp the consequences.
I am not too confident myself here and the previous statement is not to say
you don't know what you are talking about (it sounds a bit like an insult),
my point is that I think once we apply const to objects, the possible
complexity is infinite and it would be impossible to implement (if you take
the protection serious anyway).
Not really. He just pointed out the fact that you must distinguish the
parameter from the object referenced by the parameter in the case of
reference type parameters, and that the ref and out keywords doesn't
help in managíng access to that object.


That is the issue, managing access to the object. I don't see how it could
be done because the compiler doesn't know what changes the object and what
doesn't.


If you wish to gain an understanding of how const works, I suggest you
get a book about C++ and do some studying.

/Magnus Lidbom

Nov 15 '05 #29

P: n/a
"Martin Maat [EBL]" <du***@somewhere.nl> wrote in message
news:10*************@corp.supernews.com...
As you pointed out with your examples it is hard to define what should be
considered change, what is a violation of a const contract. With any complex type that is quite impossible, not only technically but even more so
semantically. To what does the contract extend if you have contained and
agrigated objects? I believe this is the shadow world Anders was refering
to.


For a good example of the shadow world, consider the C++ STL's collection
classes. (my apologies to those who are already familiar with this example)
Suppose I have a collection declared as follows:

std::list<int> mylist;

'mylist' is not const, so I can modify it and its members. If I want to
iterate its members and set them all to 5, here is one way to do it:

std::list<int>::iterator it;
for(it=mylist.begin();mylist.end()!=it;it++)
*it=5;

Now, lets suppose that I have another reference to mylist that is const:

const std::list<int>& myconstlist=mylist;

'myconstlist' is const, so that means I can't change its contents. I can't
add or remove from the list, and the const also propagates to the elements
of the list that I access through 'mylist'.

There is a problem with iterators, however. I can call a function on
'mylist', begin(), to obtain an interator, which is a separate class. In
order for the iterator to be useful to me, I must be able to modify it -
otherwise I can't tell it to advance to the next entry in the list. The
iterator itself must not be const, but I will be using it to access the
members of the list, which should be const. Since my reference to
myconstlist is const, we want the iterator that I get to enforce that
constness on the elements that I access through it. The STL addresses this
by creating another kind of iterator, called const_iterator. Here is an
example:

std::list<int>::const_iterator constit;
for(constid=myconstlist.begin();myconstlist.end()! =constit;constit++)
cout << *constit;

I am clearly modifying the iterator in this example (with the ++), but when
I dereference the iterator (with the *constit), I obtain a const reference
to the element.

I would not have been able to iterate myconstlist with a regular
list<T>::iterator, because dereferencing that iterator yeilds a non-const
reference to the element, which is semantially invalid since myconstlist is
const.

This is accomplished in list<T>'s implementation by having begin(), etc.,
being overloaded like this:

iterator begin();
const_iterator begin() const;

This way, if I access the list<T> via a const reference, I can not call the
non-const begin(), so the compiler forces me to take a const_iterator.

If it isn't obvious already, the shadow world is happening because I have to
iterator classes, namely list<T>::iterator and list<T>::const_iterator.
Incidentally, neither of the iterator classes are ever used via const
references, since that would render them useless.

Mike
Nov 15 '05 #30

P: n/a
> >> >
>Is not concept enough? I don't consider implementation enough at times.
I don't understand what you mean. Enough what?Implicitly const classes are immutable by implementation. That makes the
object immutable as either a sideeffect or a matter of const implementation.
This is slightly different than an object being immutable at its core. It issubtle, I suppose.


I'm sorry, I still don't understand what point you are trying to
make. What do you mean by "at its core"? I don't understand why you'd
consider it a sideaffect. The immutability could be accomplished
,behind the scenes, by implicitly making all members and alll
instances of a class declared immutable const. That doesn't mean the
immutability of the class would be any less an conscious, intentional,
and explicit atribute of the class.


Lemme reword this. Immutability is a design goal that is achieved by use of
const, not an effect or result of const itself. It can be achieved *without*
it, and has been. Immutability is a concept, a constant method is a
different concept, even if one is used to achieve the other.

Performance is an important characteristic of any application. There's
always a level that's not good enough. For a much used tool, a central
library, and any number of other applications, good performance is
critical. If one wishes for ones application to do well in this area,
one needs to keep it in mind, and performance will to some degree
affect every architectural decision made. Every day I work, my
productivity is to some degree dictated by the performance of the
applications that are my tools in trade. The same goes for anyone
using a computer, everyone using the applications I make. The rising
power of hardware has not been able to do much more than offset the
rising level of complexity that the average application demands.
Hardware just a few years old is now completely unsuitable for complex
modern applications, and there's no end in sight for that trend.
On this I agree, however for most apps I still think overarching performance
is a tertiary issue,


Only if performance is already acceptable. Would you use a news reader
that took 90 seconds to start and 15 seconds to display a post? No
matter how many nifty features it had, or how maintainable it was, I
wouldn't.


Nor would I, but that doesn't mean my app needs to run in .0015 seconds
either. Even with some runtime additions I doubt performance would drop
significantly. My algorithms are more likely the issue.
feature set\specs are first, good enough performance
second Where to draw the line isn't really my place, most apps I write
aren't highly performance critical, speed of development and safety of
development is. It would be mainly a tradeoff between the speed of the appand the ease and safety of the code


I find that clean well structured designs generally perform very well.
Caching and lazy evaluation barred, I rarely find myself complicating
a design in order to improve performance.


As do I, which really isn't on point. I believe originally it was a concern
about runtime const verification being a performance liability?
Certainly. It is easy to make mistakes. I make them every day. That's
largely why I need all the abstractions that helps me create better,
safer code faster than I could without them. I very much appreciate
the compilers efforts on my behalf. But at the end of the day the
compiler is a tool that I need to do what I tell it. If I tell it to
look the other way while I cheat, by applying a cast, I expect it to
obey, because there are situations where I must have that ability. You
brought one such situation up in your last post.WHich is part of what bothers me. Cheating via reflection or something else
that can be controlled by security is one thing, cheating using the languageis quite antoher.


It bothers me too, but I've yet to hear of an alternative I consider
better.

It depends, I cast pretty much only to explicitly convert to an

interface.

Good catch. I failed to consider that quirk of the language. Since the
compiler already knows that the class implements the interface, and
that the cast will therefore always succeed, no warning should be
issued in this case. Semantically, this is not a cast. It is merely a
mechanism to allow you to unambiguously specify which method you
intended to call in the presence of naming conflicts when implementing
multiple interfaces.

Unfortunatly, the compiler can't actually know if the class implements the
interface, atleast usually. A typed variable has no constraints on if the
class provides an interface unless the type does. Derived classes are freeto (re)implement interfaces. It may not be the cleanest thing but it is
often reliable(preferably using as rather than (cast) operation, but still).
I assumed you were talking about casting an instance of a specific
class to an interface that the instance's class implements explicitly.
If that's not what you mean, then either there is no need for a cast,
or we are talking about the sledgehammer that I would want to se a
warning for, at the highest warning level.
Usually because of explicit implementation(or to decouple things, usually
due to reflection.) However it can be difficult sometimes to know if an
explicit implementation exists or not, just because a base class implements
it implicitly, a derived class could reimplement it explicitly, so I'll
often cast to get the interface instead of simply hoping that the entire
interface is implicitly implemented. I generally don't trust that MyObject o
= <whatever> is nessecerily MyObject, not MyObjectDerivedFromMyObject.
Casts are frustrating things, but they are nessecery at times. I consider >casts to be a smaller issue in .NET than it is in C++. Simply put, castsare
>*never* undefined, it is either an exception(a cast to a type that the
>object isn't), an implicit or explicit conversion, or a cast to a
actual >class. Its not possible to cast to a random object and circumvent
thingsas
>it is in C\C++.
To a great degree that's true. But how hard is it to cast
IConstMyClass to MyClass? Any harder than casting away const? Any
more safe? How about IList to ArrayList when the debugger has shown
you that it is an ArrayList? Which is, in part, a problem. However there is simply no way to avoid it. I
feel with const that there may well be a way to avoid it without leaving
this hole.
Safe is one thing, confusing and unapparent is another. Implicit
conversionsin most cases are an issue more of apparentability than anything else. Castsare apparent and a coder can deal with them, an implicit conversion is a
risky thing that can cause code and behaviour to come into being that isn'texpected.


It should be neither confusing, unapparent nor risky. Implicit
conversions should occur only where the source type is an instance of
the target type as far as OO is concerned. As far as I know this is
the case for all built in implicit convertions.

If you are working strictly with built in types you are lucky. I don't hav
ethe time to analyze every piece of code\library I get nor can I
realistically reject something simply because it provides an implicit
conversion I don't like. I don't like to rely on implicit conversions
otuside of some very limited situationsNow, when the *entire* framework doesn't have const, thats an awful
lot
of
>sledgehammering, isn't it?

If no part of the framework uses const then const will simply be
irrelevant in the context of the framework classes. There will be no
need for casts. Problems arise only upon inconsistent use of const.If const is limited to only some areas, is it right? Is it valuable? In myopinoin it isn't. If const isn't used everywehre its utility is
significantly reduced, fragemented really. If theframework isn't const able,const is a useless feature.


Can you present an example, in code, where the framework not using
const would significantly detract from my ability to benefit from
using const? Except for needing to swap out the included collections,
I don't see much of a problem at all. And I'd certainly expect const
correct collections to be provided if const was implemented.

Mainly because you would loose the ability to pass objects into the
framework. If an object can't be used with the framework then why have a
framework? As I illustrated before(different convo), you also technically
loose access to ToString(), Equals(), GetHashCode(), the comparison operator
and more or less any other method that the framework uses constantly.
Without const in System.Object, const is broken.structs should be immutable by default, IMHO.

Immutability is a relatively rare trait, making it the default would ,
in my opinion, be inappropriate. It certainly would break an immense
amount of code.Possibly, I should say immutability should be a design goal for value types.
Due to their copy by value nature, you can't rely on a value type for much,immutability is often logical.


This is not at all my experience. Actually, I don't know of a single
immutable struct type. Could you provide examples and a motivation for
this guideline?

The primative .NET types are immutable. You create a new value type instead
of modifying the existing one. Other simple value types will be immutable,
when only one data type exists, why allow them to chagne the existing value?
Beyond that, it rarely matters, changing a struct usually only affects the
code that changed the structConsidering they are by value,
>const should be irrelevent in this case.

What about ref and out parameters?Thats irrellevent, ref paramenters are implicitly going to change, thats the
purpose of the ref


Exactly. That doesn't mix at all with immutable structs, which was the
point I was trying to make.

It isn't related at all. I'm not entirely sure what your point is here. ref
implies that the *variable* can change, not the struct. There is a different
IMHO

<snip>

> >Ideally, it would be possible to cast *to* const
>> That should be an implicit conversion. Zero runtime cost with a
>> classic implementation.
>
>I dislike implicit conversions,

Even those, like the one above, that are 100% guaranteed to be safe?
Except in limited situations, I'd rather see the explicit cast in code,
mainly for maintaince sake.


I don't understand this at all. How would placing a cast at the site
of every implicit convertion help maintainability? I'd expect the
opposite. A whole lot of code would still compile after changing the
type of a variable, because you explicitly cast it when passing it as
a base type or interface. You've written a whole lot of unnessessary
casts and moved refactoring problems from compile time to runtime, as
well as significantly increased the pure typing effort involved in
both the original coding and any refactoring. I see no gain in any of
this. Quite the opposite.


Simply because the next guy can easily tell whats going on. With the
exception of numeric conversions(mostly because thats how peoples minds
work), I don't like implicit conversions. A cast to a base class isn't an
implicit conversion, thats an implicit cast. Which is quite a different
thing.


<snip>
You don't believe in the competent programmer. I don't believe in the
safe programming language. I do believe in the balanced programming
language. The one that takes a pragmatic approach and tries to shelter
the programmers as much as possible without hamstringing them or
creating catch 22 scenarios. I think C# has done very well so far.As do I, I just think there are a few other bits that could be done, ;).


As do I. Most of the things I want done are in fact scheduled for
Whidbey :)

Hehe, although I think generics are a litttle overhyped, whidbey also adds a
few features that may make things worse...I just don't know yet.
Regards /Magnus Lidbom

Nov 15 '05 #31

P: n/a
"Martin Maat [EBL]" <du***@somewhere.nl> wrote:
"Some ten years ago the buz was fuzzy logic. It never took on."
Fuzzy logic is currently in use for a variety of applications.
Following are several publications which detail the application of
fuzzy logic to real problems. These are all available online, and
were published in 2000 - 2003:

http://80.110.251.60/corp/archiv/pap...03_Abbasov.pdf
http://jds.fass.org/cgi/reprint/84/2/400.pdf
http://www3.sympatico.ca/alawnicz/PAGE0212.PDF
http://www.ensc.sfu.ca/~ljilja/ENSC8...esentation.pdf
http://eprint.uq.edu.au/archive/00000625/02/paper13.pdf
http://udel.edu/~ebenson/Journal_Art..._Detection.pdf
http://www.medialab.ntua.gr/medialab...3/2003-8/8.pdf
-Will Dwinnell
http://will.dwinnell.com
Nov 15 '05 #32

P: n/a
"Will Dwinnell" <pr******@bellatlantic.net> wrote in message
news:2b*************************@posting.google.co m...
"Martin Maat [EBL]" <du***@somewhere.nl> wrote:
"Some ten years ago the buz was fuzzy logic. It never took on."
I knew I was offending somebody when I wrote it :-).
Fuzzy logic is currently in use for a variety of applications.
Following are several publications which detail the application of
fuzzy logic to real problems. These are all available online, and
were published in 2000 - 2003:

http://80.110.251.60/corp/archiv/pap...03_Abbasov.pdf
http://jds.fass.org/cgi/reprint/84/2/400.pdf
http://www3.sympatico.ca/alawnicz/PAGE0212.PDF
http://www.ensc.sfu.ca/~ljilja/ENSC8...esentation.pdf
http://eprint.uq.edu.au/archive/00000625/02/paper13.pdf
http://udel.edu/~ebenson/Journal_Art..._Detection.pdf http://www.medialab.ntua.gr/medialab...3/2003-8/8.pdf


If I ever have to write software for harvesting crop, for identifying fake
smiles or for determining if the cows are horny I'll know where to look. And
if never, it will be good reading for a sunny day in the garden.

(the middle one is no longer available by the way)
Nov 15 '05 #33

P: n/a
After reading the entire discussion, I completely agree that there are
issues to resolve. But I would like to switch to a concrete example
for a minute. Please consider the following:
class Box
{
public double Weight;
}
class Shipment
{
private Box myBox;

public Box Box { get myBox; }
}
Shipment myShipment;
Box theBox = myShipment.Box; // OK
double weight = myShipment.Box.Weight; // OK
myShipment.Box = new Box; // GOOT a COMPILE FAILURE;

// Now the bug. I need to prevent.....

myShipment.Box.Weight = 123.45;
Trivial solution for this tirivial smaple. Is to not expose the Box
directly but rahter export a property BoxWeight which does the
referencing internally. While this works for simple examples.
Consider what happens is "Box" has 100 members, and is used in 100
different aggregations. That is 10,000 wrapper functions and 101
changes everytime a property is added/removed from Box.

One little word ("const") would solve the whole problem!!!.

Regarding the "competitent programmer" issue. We have a coding
standard that absolutely prohibits "C" style casts in our C++ code,
and required justification (seperate document requiring approval) for
any C++ style cast (static_cast,const_cast, etc). While this might
seem to be an overly conservitive (paranoid?) approach. We have found
that there really is almost never a need for casts in any of the code
we have developed. For interfacing with code written by others, casts
do sometimes have to be used (especially for people who do not use
the const modifier on C++ members which do not modify an object. Our
solution is to not do business with these prople/companies wherever
possible, or write wrapper functions that compensate for their
shortcomings. This is much prefferable to "corrupting" our code with
workarounds.
[
Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
Nov 15 '05 #34

P: n/a

"TheCPUWizard" <dv******@optonline-dot-net.no-spam.invalid> wrote in message
news:40**********@Usenet.com...
After reading the entire discussion, I completely agree that there are
issues to resolve. But I would like to switch to a concrete example
for a minute. Please consider the following:
class Box
{
public double Weight;
}
class Shipment
{
private Box myBox;

public Box Box { get myBox; }
}
Shipment myShipment;
Box theBox = myShipment.Box; // OK
double weight = myShipment.Box.Weight; // OK
myShipment.Box = new Box; // GOOT a COMPILE FAILURE;

// Now the bug. I need to prevent.....

myShipment.Box.Weight = 123.45;
Trivial solution for this tirivial smaple. Is to not expose the Box
directly but rahter export a property BoxWeight which does the
referencing internally. While this works for simple examples.
Consider what happens is "Box" has 100 members, and is used in 100
different aggregations. That is 10,000 wrapper functions and 101
changes everytime a property is added/removed from Box.

One little word ("const") would solve the whole problem!!!.

Regarding the "competitent programmer" issue. We have a coding
standard that absolutely prohibits "C" style casts in our C++ code,
and required justification (seperate document requiring approval) for
any C++ style cast (static_cast,const_cast, etc). While this might
seem to be an overly conservitive (paranoid?) approach. We have found
that there really is almost never a need for casts in any of the code
we have developed. For interfacing with code written by others, casts
do sometimes have to be used (especially for people who do not use
the const modifier on C++ members which do not modify an object. Our
solution is to not do business with these prople/companies wherever
possible, or write wrapper functions that compensate for their
shortcomings. This is much prefferable to "corrupting" our code with
workarounds.

I'd rather corrupt my code than corrupt the language itself. I don't feel
C++'s const implementation is good enough. Most of the arguments I've seen
are basically "we did this in C++", again, just cause C++ does it that way
doesn't mean its right, just that it's the C++ way. const is needed, but C++
const should be left in the past.

[
Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com

Nov 15 '05 #35

P: n/a
On Wed, 11 Feb 2004 13:27:29 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"TheCPUWizard" <dv******@optonline-dot-net.no-spam.invalid> wrote in message
news:40**********@Usenet.com...
After reading the entire discussion, I completely agree that there are
issues to resolve. But I would like to switch to a concrete example
for a minute. Please consider the following:
class Box
{
public double Weight;
}
class Shipment
{
private Box myBox;

public Box Box { get myBox; }
}
Shipment myShipment;
Box theBox = myShipment.Box; // OK
double weight = myShipment.Box.Weight; // OK
myShipment.Box = new Box; // GOOT a COMPILE FAILURE;

// Now the bug. I need to prevent.....

myShipment.Box.Weight = 123.45;
Trivial solution for this tirivial smaple. Is to not expose the Box
directly but rahter export a property BoxWeight which does the
referencing internally. While this works for simple examples.
Consider what happens is "Box" has 100 members, and is used in 100
different aggregations. That is 10,000 wrapper functions and 101
changes everytime a property is added/removed from Box.

One little word ("const") would solve the whole problem!!!.

Regarding the "competitent programmer" issue. We have a coding
standard that absolutely prohibits "C" style casts in our C++ code,
and required justification (seperate document requiring approval) for
any C++ style cast (static_cast,const_cast, etc). While this might
seem to be an overly conservitive (paranoid?) approach. We have found
that there really is almost never a need for casts in any of the code
we have developed. For interfacing with code written by others, casts
do sometimes have to be used (especially for people who do not use
the const modifier on C++ members which do not modify an object. Our
solution is to not do business with these prople/companies wherever
possible, or write wrapper functions that compensate for their
shortcomings. This is much prefferable to "corrupting" our code with
workarounds.


I'd rather corrupt my code than corrupt the language itself. I don't feel
C++'s const implementation is good enough. Most of the arguments I've seen
are basically "we did this in C++", again, just cause C++ does it that way
doesn't mean its right, just that it's the C++ way. const is needed, but C++
const should be left in the past.


Unless I've missed something you've said, the only change in semantics
from C++ const that you would like to see is a complete removal of the
ability to cast const away. Is this correct? If not, what other
changes would you like to see?

If you do remove the ability to cast const away, how would you propose
to solve the problem of interfacing with badly designed components?

Regards /Magnus Lidbom
Nov 15 '05 #36

P: n/a

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:jm********************************@4ax.com...
On Wed, 11 Feb 2004 13:27:29 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"TheCPUWizard" <dv******@optonline-dot-net.no-spam.invalid> wrote in messagenews:40**********@Usenet.com...
After reading the entire discussion, I completely agree that there are
issues to resolve. But I would like to switch to a concrete example
for a minute. Please consider the following:
class Box
{
public double Weight;
}
class Shipment
{
private Box myBox;

public Box Box { get myBox; }
}
Shipment myShipment;
Box theBox = myShipment.Box; // OK
double weight = myShipment.Box.Weight; // OK
myShipment.Box = new Box; // GOOT a COMPILE FAILURE;

// Now the bug. I need to prevent.....

myShipment.Box.Weight = 123.45;
Trivial solution for this tirivial smaple. Is to not expose the Box
directly but rahter export a property BoxWeight which does the
referencing internally. While this works for simple examples.
Consider what happens is "Box" has 100 members, and is used in 100
different aggregations. That is 10,000 wrapper functions and 101
changes everytime a property is added/removed from Box.

One little word ("const") would solve the whole problem!!!.

Regarding the "competitent programmer" issue. We have a coding
standard that absolutely prohibits "C" style casts in our C++ code,
and required justification (seperate document requiring approval) for
any C++ style cast (static_cast,const_cast, etc). While this might
seem to be an overly conservitive (paranoid?) approach. We have found
that there really is almost never a need for casts in any of the code
we have developed. For interfacing with code written by others, casts
do sometimes have to be used (especially for people who do not use
the const modifier on C++ members which do not modify an object. Our
solution is to not do business with these prople/companies wherever
possible, or write wrapper functions that compensate for their
shortcomings. This is much prefferable to "corrupting" our code with
workarounds.

I'd rather corrupt my code than corrupt the language itself. I don't feel
C++'s const implementation is good enough. Most of the arguments I've seenare basically "we did this in C++", again, just cause C++ does it that waydoesn't mean its right, just that it's the C++ way. const is needed, but C++const should be left in the past.


Unless I've missed something you've said, the only change in semantics
from C++ const that you would like to see is a complete removal of the
ability to cast const away. Is this correct? If not, what other
changes would you like to see?

No, the main thing I dislike about C++ const is its a compile time only
construct, without (deep) runtime support I feel it is a very bad thing, I
also think the syntax needs a bit of work(as I've illustrated before).
However the ability to cast it away irks me too, or atteast the ability to
cast it away without some form of control.
If you do remove the ability to cast const away, how would you propose
to solve the problem of interfacing with badly designed components? Personally, like most things, if casting away from const support is needed,
I feel it would have to be done in a way similar to unsafe code. It should
not only be something that the developer needs to decide to do
explicitly(perhaps with more than a cast), but something an administrator(or
a developer) can explicitly rule out or control with security rules and
permissions. It has to be something that travels with the object, even when
its cast to object or a base class. My gripe isn't with the concept of
const, but with bits of the C++ implementation and the blind "we need const
now, just do everything the C++ way" idea people seem to have. Permissions,
code controls, etc need to be considered instead of just allowing things to
work exactly as they did. I am also not entirely sure that const needs to be
part of the type instead of being a property, an attribute you could say, of
the instance. Its the post-compile stuff I'm not satisfied with yet. I want
to be able to pass a const reference into third party code and *know* that
code can't break const and cause trouble. I want to be able to disallow
breaking const explicitly in code where such a thing just isn't permitted.
And I want these things to be done by the compiler and the runtime, not
my(or others) eyes looking for mistakes. Generics will help, but I don't
think they can do the whole thing.

Actually, somethings have brought me to wonder. What is more common, a const
or a non const parameter(as in parameters that are not changed, not
nessecerily marked as const)?
Regards /Magnus Lidbom

Nov 15 '05 #37

P: n/a
Daniel O'Connell, thanks for the response. But it leaves open the
question of how to deliver a solution that prevents the user from
performing operations that should not be allowed?

If the user can set the value (especially using a "clean" statement),
then he will invariably try. Since setting the value would not have
the intended effects, it can cause much trouble.

IMHO this will be sufficient reason for my firm to NOT produce C#
versions of our libraries. While C++ will allow "bad" things, you
really do have to work at them if the code is designed properly.
Opening up this can of worms would increase our support call volume
(and therefore costs) to the point that it could easily bankrupt us!

David V. Corbin
President
Dynamic Concepts Development Corp.
Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
Nov 15 '05 #38

P: n/a

"TheCPUWizard" <dv******@optonline-dot-net.no-spam.invalid> wrote in message
news:40**********@Usenet.com...
Daniel O'Connell, thanks for the response. But it leaves open the
question of how to deliver a solution that prevents the user from
performing operations that should not be allowed?

If the user can set the value (especially using a "clean" statement),
then he will invariably try. Since setting the value would not have
the intended effects, it can cause much trouble. I must ask why, if setting the value is so dangerous, that you allow it to
be set at all? Exposing a field in a class is generally a bad thing to do,
ideally it would be a read only property(is there *ever* a case where a box
weight may change? Or will it always be the same from the beginning?).
Assuming you get different access modifiers on properties in the coming
versions of the framework, is const really needed in this case? That is one
issue with const that worries me, that people will use const as a crutch in
situations like this and expose fields with weak protection when they should
be exposing get only properties. Data that is catastrophic to change
shouldn't be allowed to change without authorization, either by not
providing a set accessor, by making a demand based on strong name, by only
allowing the changes via an internal call, or whatever other means
nessecery.
IMHO this will be sufficient reason for my firm to NOT produce C#
versions of our libraries. While C++ will allow "bad" things, you
really do have to work at them if the code is designed properly.
Opening up this can of worms would increase our support call volume
(and therefore costs) to the point that it could easily bankrupt us!
I don't particularly consider a cast alot of work. Your previous C# code
wasn't particularly well designed at that(public or protected field is a
cardinal no-no, IMHO). With a proper design you should have some work
involved in screwing with a C# app as well(things like reflection, etc,
which I suspect you wouldn't support in any situation). David V. Corbin
President
Dynamic Concepts Development Corp.
Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com

Nov 15 '05 #39

P: n/a
dv******@optonline-dot-net.no-spam.invalid (TheCPUWizard) wrote:
Consider what happens is "Box" has 100 members, and is used in 100
different aggregations. That is 10,000 wrapper functions and 101


Don't you think that the 100 member "Box" is the at core of problems?
It's astonishing that an organization thats so strict about the
usage of casts would allow the creation of such a class.

Even if the class cannot be refactored to multiple smaller
classes, the members of that class should be categorized
and "captured" in multiple interfaces. Then the classes that
contain instances of that "Box" class only have to expose
those interfaces to their clients that they would (or should)
be interested in (thereby reducing the number of
"wrapper functions").

Juval Löwy's guidelines are that the optimal number of members
per interface are six to nine members - once you reach 12 you should
consider splitting the interface. He also mentions that a coding
standard should adopt a maximum "never to be exceeded", like 20.
Nov 15 '05 #40

P: n/a
On Mon, 9 Feb 2004 20:45:50 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
>> >
>> >Is not concept enough? I don't consider implementation enough attimes. >>
>> I don't understand what you mean. Enough what?
>Implicitly const classes are immutable by implementation. That makes the
>object immutable as either a sideeffect or a matter of constimplementation. >This is slightly different than an object being immutable at its core. Itis >subtle, I suppose.
I'm sorry, I still don't understand what point you are trying to
make. What do you mean by "at its core"? I don't understand why you'd
consider it a sideaffect. The immutability could be accomplished
,behind the scenes, by implicitly making all members and alll
instances of a class declared immutable const. That doesn't mean the
immutability of the class would be any less an conscious, intentional,
and explicit atribute of the class.


Lemme reword this. Immutability is a design goal that is achieved by use of
const, not an effect or result of const itself. It can be achieved *without*
it, and has been. Immutability is a concept, a constant method is a
different concept, even if one is used to achieve the other.


Agreed. Immutable means that all instances are const. That no visible
value or behavior in any instance can be changed. For reference types,
const ensures that no visible value or behavior of an instance can be
modified through a const reference an instance. For value types, const
ensures that no part of a value type instance can change.

<snip>
>> >It depends, I cast pretty much only to explicitly convert to an
>interface.
>>
>> Good catch. I failed to consider that quirk of the language. Since the
>> compiler already knows that the class implements the interface, and
>> that the cast will therefore always succeed, no warning should be
>> issued in this case. Semantically, this is not a cast. It is merely a
>> mechanism to allow you to unambiguously specify which method you
>> intended to call in the presence of naming conflicts when implementing
>> multiple interfaces.
>>
>Unfortunatly, the compiler can't actually know if the class implementsthe >interface, atleast usually. A typed variable has no constraints on if the
>class provides an interface unless the type does. Derived classes arefree >to (re)implement interfaces. It may not be the cleanest thing but it is
>often reliable(preferably using as rather than (cast) operation, butstill).

I assumed you were talking about casting an instance of a specific
class to an interface that the instance's class implements explicitly.
If that's not what you mean, then either there is no need for a cast,
or we are talking about the sledgehammer that I would want to se a
warning for, at the highest warning level.


Usually because of explicit implementation(or to decouple things, usually
due to reflection.) However it can be difficult sometimes to know if an
explicit implementation exists or not, just because a base class implements
it implicitly, a derived class could reimplement it explicitly


Could you give an example where it would make sense for a subclass to
explicitly implement an interface that a base class implements
implicitly?

What if subclass of such a class overrides a method implicitly
implemented? Polymorphism is broken for such a class hierarchy.

Given that Foo exists in two versions, both implementations of
IBar.Foo, could you give an example where you would not consider the
class broken if instance.Foo != ((IBar)instance).Foo? Or if the result
of calling instance.Foo() was not the same as that of calling
((IBar)instance).Foo()?

If you can, how do you determine that the explicit' implementation is
the correct one to call? It may not be the most derived.

For my part, I consider such a class hierarchy fundamentally broken,
and as such, a problem I will deal with if I ever encounter it.

<snip>

>Safe is one thing, confusing and unapparent is another. Implicitconversions >in most cases are an issue more of apparentability than anything else.Casts >are apparent and a coder can deal with them, an implicit conversion is a
>risky thing that can cause code and behaviour to come into being thatisn't >expected.


It should be neither confusing, unapparent nor risky. Implicit
conversions should occur only where the source type is an instance of
the target type as far as OO is concerned. As far as I know this is
the case for all built in implicit convertions.

If you are working strictly with built in types you are lucky. I don't hav
ethe time to analyze every piece of code\library I get nor can I
realistically reject something simply because it provides an implicit
conversion I don't like. I don't like to rely on implicit conversions
otuside of some very limited situations


If you mean that you use cast to mark _improper_ implicit conversions,
then I'm all for it. Improper implicit conversions constitute a nasty
form of obfuscation. I define improper as any conversion not fitting
my comment above.
If an object can't be used with the framework then why have a
framework? As I illustrated before(different convo), you also technically
loose access to ToString(), Equals(), GetHashCode(), the comparison operator
and more or less any other method that the framework uses constantly.
Without const in System.Object, const is broken.


It would certainly be very annoying, and inconvenient if the framework
was not reworked to be const aware. But it would be possible to work
around. Unless the ability to cast away const was removed as you've
suggested.

In the interest of clarity let me make it clear that I most definitely
want const in the framework. I just disagree with the opinion that
const would be useless if it wasn't. The discussion is almost
certainly purely academic however. I find it extremely hard to believe
that const would be implemented without proper modifications to the
appropriate parts of the framework.

>> >structs should be immutable by default, IMHO.
>>
>> Immutability is a relatively rare trait, making it the default would ,
>> in my opinion, be inappropriate. It certainly would break an immense
>> amount of code.
>Possibly, I should say immutability should be a design goal for valuetypes. >Due to their copy by value nature, you can't rely on a value type formuch, >immutability is often logical.


This is not at all my experience. Actually, I don't know of a single
immutable struct type. Could you provide examples and a motivation for
this guideline?

The primative .NET types are immutable.


int i = 0;
++i;

void ModyfyDate(ref DateTime date)
{
date = DateTime.Now;
}

The reason that the primitives have no modifiers, besides operators,
it that, since they hold only one value, replacing the entire struct
is equivalent to changing that single value.

I do see how you could consider them immutable. They supply no
modifiers as such, besides operators. But the value of the variable is
the value type instance, and that value can be changed.

With value types, the variable's value is the object, not a reference
to the object, and immutable means that no part of an object can be
changed in any externally detectable way. No instance of a value type
in .Net can be immutable if not declared const.
<snipped area addressed by the above comment>

>> >> >Ideally, it would be possible to cast *to* const
>> >> That should be an implicit conversion. Zero runtime cost with a
>> >> classic implementation.
>> >
>> >I dislike implicit conversions,
>>
>> Even those, like the one above, that are 100% guaranteed to be safe?
>
>Except in limited situations, I'd rather see the explicit cast in code,
>mainly for maintaince sake.


I don't understand this at all. How would placing a cast at the site
of every implicit convertion help maintainability? I'd expect the
opposite. A whole lot of code would still compile after changing the
type of a variable, because you explicitly cast it when passing it as
a base type or interface. You've written a whole lot of unnessessary
casts and moved refactoring problems from compile time to runtime, as
well as significantly increased the pure typing effort involved in
both the original coding and any refactoring. I see no gain in any of
this. Quite the opposite.


Simply because the next guy can easily tell whats going on. With the
exception of numeric conversions(mostly because thats how peoples minds
work), I don't like implicit conversions. A cast to a base class isn't an
implicit conversion, thats an implicit cast. Which is quite a different
thing.


The type system, quite correctly, consider an ArrayList to be an
Object. No cast, implicit or otherwise, is employed to pass an
ArrayList as an Object or to invoke Object members on an ArrayList
instance. I'd consider casting to a base class obfuscation since a
cast is a clear indication that a dangerous conversion is performed
and this is simply not the case for such a convection.

Do you really write code like this?

int i = 1;
Console.WriteLine((object)i);
Type intType = ((Object)i).GetType();

Do you really consider code like that to improve maintainability and
legibility?

<snip>

Regards /Magnus Lidbom

Nov 15 '05 #41

P: n/a

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:ra********************************@4ax.com...
On Mon, 9 Feb 2004 20:45:50 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
>> >
>> >Is not concept enough? I don't consider implementation enough attimes.
>>
>> I don't understand what you mean. Enough what?
>Implicitly const classes are immutable by implementation. That makes the >object immutable as either a sideeffect or a matter of const

implementation.
>This is slightly different than an object being immutable at its core. It
is
>subtle, I suppose.

I'm sorry, I still don't understand what point you are trying to
make. What do you mean by "at its core"? I don't understand why you'd
consider it a sideaffect. The immutability could be accomplished
,behind the scenes, by implicitly making all members and alll
instances of a class declared immutable const. That doesn't mean the
immutability of the class would be any less an conscious, intentional,
and explicit atribute of the class.


Lemme reword this. Immutability is a design goal that is achieved by use of
const, not an effect or result of const itself. It can be achieved *without*it, and has been. Immutability is a concept, a constant method is a
different concept, even if one is used to achieve the other.


Agreed. Immutable means that all instances are const. That no visible
value or behavior in any instance can be changed. For reference types,
const ensures that no visible value or behavior of an instance can be
modified through a const reference an instance. For value types, const
ensures that no part of a value type instance can change.

<snip>
> >It depends, I cast pretty much only to explicitly convert to an
>interface.
>>
>> Good catch. I failed to consider that quirk of the language. Since
the >> compiler already knows that the class implements the interface, and
>> that the cast will therefore always succeed, no warning should be
>> issued in this case. Semantically, this is not a cast. It is merely a >> mechanism to allow you to unambiguously specify which method you
>> intended to call in the presence of naming conflicts when implementing >> multiple interfaces.
>>
>Unfortunatly, the compiler can't actually know if the class implements

the
>interface, atleast usually. A typed variable has no constraints on if the >class provides an interface unless the type does. Derived classes are

free
>to (re)implement interfaces. It may not be the cleanest thing but it is >often reliable(preferably using as rather than (cast) operation, but

still).

I assumed you were talking about casting an instance of a specific
class to an interface that the instance's class implements explicitly.
If that's not what you mean, then either there is no need for a cast,
or we are talking about the sledgehammer that I would want to se a
warning for, at the highest warning level.


Usually because of explicit implementation(or to decouple things, usually
due to reflection.) However it can be difficult sometimes to know if an
explicit implementation exists or not, just because a base class implementsit implicitly, a derived class could reimplement it explicitly


Could you give an example where it would make sense for a subclass to
explicitly implement an interface that a base class implements
implicitly?

What if subclass of such a class overrides a method implicitly
implemented? Polymorphism is broken for such a class hierarchy.

Given that Foo exists in two versions, both implementations of
IBar.Foo, could you give an example where you would not consider the
class broken if instance.Foo != ((IBar)instance).Foo? Or if the result
of calling instance.Foo() was not the same as that of calling
((IBar)instance).Foo()?

If you can, how do you determine that the explicit' implementation is
the correct one to call? It may not be the most derived.

For my part, I consider such a class hierarchy fundamentally broken,
and as such, a problem I will deal with if I ever encounter it.


Perhaps it isn't right, but it is legal. For one, part of the reason that
explicit interface implementation exists is so an interface name can class
with another interface. You can't rely on instance.Foo to be the actual
interface member, usually due to two interfaces with colliding member names
or with base type member collision with the interfaces.
<snip>

Safe is one thing, confusing and unapparent is another. Implicitconversions
>in most cases are an issue more of apparentability than anything else.

Casts
>are apparent and a coder can deal with them, an implicit conversion is a >risky thing that can cause code and behaviour to come into being that

isn't
>expected.

It should be neither confusing, unapparent nor risky. Implicit
conversions should occur only where the source type is an instance of
the target type as far as OO is concerned. As far as I know this is
the case for all built in implicit convertions.

If you are working strictly with built in types you are lucky. I don't hav
ethe time to analyze every piece of code\library I get nor can I
realistically reject something simply because it provides an implicit
conversion I don't like. I don't like to rely on implicit conversions
otuside of some very limited situations


If you mean that you use cast to mark _improper_ implicit conversions,
then I'm all for it. Improper implicit conversions constitute a nasty
form of obfuscation. I define improper as any conversion not fitting
my comment above.


Improper conversion sounds like a good description, that is indeed what I
mean.
If an object can't be used with the framework then why have a
framework? As I illustrated before(different convo), you also technically
loose access to ToString(), Equals(), GetHashCode(), the comparison operatorand more or less any other method that the framework uses constantly.
Without const in System.Object, const is broken.
It would certainly be very annoying, and inconvenient if the framework
was not reworked to be const aware. But it would be possible to work
around. Unless the ability to cast away const was removed as you've
suggested.

In the interest of clarity let me make it clear that I most definitely
want const in the framework. I just disagree with the opinion that
const would be useless if it wasn't. The discussion is almost
certainly purely academic however. I find it extremely hard to believe
that const would be implemented without proper modifications to the
appropriate parts of the framework.

As do I.
> >structs should be immutable by default, IMHO.
>>
>> Immutability is a relatively rare trait, making it the default would , >> in my opinion, be inappropriate. It certainly would break an immense
>> amount of code.
>Possibly, I should say immutability should be a design goal for valuetypes.
>Due to their copy by value nature, you can't rely on a value type for

much,
>immutability is often logical.

This is not at all my experience. Actually, I don't know of a single
immutable struct type. Could you provide examples and a motivation for
this guideline?

The primative .NET types are immutable.


int i = 0;
++i;

void ModyfyDate(ref DateTime date)
{
date = DateTime.Now;
}

The reason that the primitives have no modifiers, besides operators,
it that, since they hold only one value, replacing the entire struct
is equivalent to changing that single value.

I do see how you could consider them immutable. They supply no
modifiers as such, besides operators. But the value of the variable is
the value type instance, and that value can be changed.

With value types, the variable's value is the object, not a reference
to the object, and immutable means that no part of an object can be
changed in any externally detectable way. No instance of a value type
in .Net can be immutable if not declared const.


I disagree here, in both cases *new* objects\data are created and placed in
the same place. That is a different thing(granted, a stack value isn't an
object until its boxed, I don't think its possible to operate on it without
performing a cast, retaining immutability). It is inherently a property of
the .NET type system but that is simply how it is. A const reference, to my
knowledge anyway, would mean the object refered to is const, not the
reference variable itself.

<snipped area addressed by the above comment>

>> >> >Ideally, it would be possible to cast *to* const
>> >> That should be an implicit conversion. Zero runtime cost with a
>> >> classic implementation.
>> >
>> >I dislike implicit conversions,
>>
>> Even those, like the one above, that are 100% guaranteed to be safe?
>
>Except in limited situations, I'd rather see the explicit cast in code, >mainly for maintaince sake.

I don't understand this at all. How would placing a cast at the site
of every implicit convertion help maintainability? I'd expect the
opposite. A whole lot of code would still compile after changing the
type of a variable, because you explicitly cast it when passing it as
a base type or interface. You've written a whole lot of unnessessary
casts and moved refactoring problems from compile time to runtime, as
well as significantly increased the pure typing effort involved in
both the original coding and any refactoring. I see no gain in any of
this. Quite the opposite.
Simply because the next guy can easily tell whats going on. With the
exception of numeric conversions(mostly because thats how peoples minds
work), I don't like implicit conversions. A cast to a base class isn't an
implicit conversion, thats an implicit cast. Which is quite a different
thing.


The type system, quite correctly, consider an ArrayList to be an
Object. No cast, implicit or otherwise, is employed to pass an
ArrayList as an Object or to invoke Object members on an ArrayList
instance. I'd consider casting to a base class obfuscation since a
cast is a clear indication that a dangerous conversion is performed
and this is simply not the case for such a convection.

Do you really write code like this?

int i = 1;
Console.WriteLine((object)i);
Type intType = ((Object)i).GetType();

Do you really consider code like that to improve maintainability and
legibility?

That isn't what I meant. What you are illustrating there is a cast, not a
conversion. My problem is with conversions, such as if ArrayList defined an
implicit conversion to an array. To be clear, a conversion creates a new
object(usually) of a different type, a cast wouldn't. A cast casts to
something the object is, just a different view of it, a conversion should
allow cast like syntax to convert to an object of a different type. I'm not
a big fan of explict conversions either, I'd rather see a method call, but
still. <snip>

Regards /Magnus Lidbom

Nov 15 '05 #42

P: n/a
On Wed, 11 Feb 2004 20:45:29 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:ra********************************@4ax.com.. .
On Mon, 9 Feb 2004 20:45:50 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
<snip>
>> >> >It depends, I cast pretty much only to explicitly convert to an
>> >interface.
>> >>
>> >> Good catch. I failed to consider that quirk of the language. Sincethe >> >> compiler already knows that the class implements the interface, and
>> >> that the cast will therefore always succeed, no warning should be
>> >> issued in this case. Semantically, this is not a cast. It is merelya >> >> mechanism to allow you to unambiguously specify which method you
>> >> intended to call in the presence of naming conflicts whenimplementing >> >> multiple interfaces.
>> >>
>> >Unfortunatly, the compiler can't actually know if the class implements
>the
>> >interface, atleast usually. A typed variable has no constraints on ifthe >> >class provides an interface unless the type does. Derived classes are
>free
>> >to (re)implement interfaces. It may not be the cleanest thing but itis >> >often reliable(preferably using as rather than (cast) operation, but
>still).
>>
>> I assumed you were talking about casting an instance of a specific
>> class to an interface that the instance's class implements explicitly.
>> If that's not what you mean, then either there is no need for a cast,
>> or we are talking about the sledgehammer that I would want to se a
>> warning for, at the highest warning level.
>
>Usually because of explicit implementation(or to decouple things, usually
>due to reflection.) However it can be difficult sometimes to know if an
>explicit implementation exists or not, just because a base classimplements >it implicitly, a derived class could reimplement it explicitly
Could you give an example where it would make sense for a subclass to
explicitly implement an interface that a base class implements
implicitly?

What if subclass of such a class overrides a method implicitly
implemented? Polymorphism is broken for such a class hierarchy.

Given that Foo exists in two versions, both implementations of
IBar.Foo, could you give an example where you would not consider the
class broken if instance.Foo != ((IBar)instance).Foo? Or if the result
of calling instance.Foo() was not the same as that of calling
((IBar)instance).Foo()?

If you can, how do you determine that the explicit' implementation is
the correct one to call? It may not be the most derived.

For my part, I consider such a class hierarchy fundamentally broken,
and as such, a problem I will deal with if I ever encounter it.


Perhaps it isn't right, but it is legal. For one, part of the reason that
explicit interface implementation exists is so an interface name can class
with another interface. You can't rely on instance.Foo to be the actual
interface member, usually due to two interfaces with colliding member names
or with base type member collision with the interfaces.


Yes, I know what the purpose of the feature is :) It is also useful
for the ability to implement an internal interface. But neither of
these uses would replace an implicit implementation with an explicit
one. My point was that such a replacement is a fundamentally flawed
design that makes it impossible, even in theory, to know in a generic
fashion how to call the method in order to access the correct method.
There simply is no correct method. Given this, I wouldn't cast to an
interface unless it was emplicitly implemented for the class in
question. Of course, I'd have no choice in that situaton :)

>> >Safe is one thing, confusing and unapparent is another. Implicit
>conversions
>> >in most cases are an issue more of apparentability than anything else.
>Casts
>> >are apparent and a coder can deal with them, an implicit conversion isa >> >risky thing that can cause code and behaviour to come into being that
>isn't
>> >expected.
>>
>> It should be neither confusing, unapparent nor risky. Implicit
>> conversions should occur only where the source type is an instance of
>> the target type as far as OO is concerned. As far as I know this is
>> the case for all built in implicit convertions.
>If you are working strictly with built in types you are lucky. I don'thav >ethe time to analyze every piece of code\library I get nor can I
>realistically reject something simply because it provides an implicit
>conversion I don't like. I don't like to rely on implicit conversions
>otuside of some very limited situations


If you mean that you use cast to mark _improper_ implicit conversions,
then I'm all for it. Improper implicit conversions constitute a nasty
form of obfuscation. I define improper as any conversion not fitting
my comment above.


Improper conversion sounds like a good description, that is indeed what I
mean.


Glad we got that worked out :)
>> >> >structs should be immutable by default, IMHO.
>> >>
>> >> Immutability is a relatively rare trait, making it the default would, >> >> in my opinion, be inappropriate. It certainly would break an immense
>> >> amount of code.
>> >Possibly, I should say immutability should be a design goal for value
>types.
>> >Due to their copy by value nature, you can't rely on a value type for
>much,
>> >immutability is often logical.
>>
>> This is not at all my experience. Actually, I don't know of a single
>> immutable struct type. Could you provide examples and a motivation for
>> this guideline?
>The primative .NET types are immutable.


int i = 0;
++i;

void ModyfyDate(ref DateTime date)
{
date = DateTime.Now;
}

The reason that the primitives have no modifiers, besides operators,
it that, since they hold only one value, replacing the entire struct
is equivalent to changing that single value.

I do see how you could consider them immutable. They supply no
modifiers as such, besides operators. But the value of the variable is
the value type instance, and that value can be changed.

With value types, the variable's value is the object, not a reference
to the object, and immutable means that no part of an object can be
changed in any externally detectable way. No instance of a value type
in .Net can be immutable if not declared const.


I disagree here, in both cases *new* objects\data are created and placed in
the same place. That is a different thing(granted, a stack value isn't an
object until its boxed, I don't think its possible to operate on it without
performing a cast, retaining immutability). It is inherently a property of
the .NET type system but that is simply how it is.


I think I understand how you're thinking here. Basicly you view the
variable as a sort of implicit reference, and feel that unless the
value of the variable can be changed piecemeal, only replaced, then
the type should be considered immutable. Is this what you mean?

Consider the affects of our different views on a const
implementation. Should the variable's "whole" value be considered
different from the value stored in it, then you'd have to be able to
separately assign constness to the two, Something like:

const MyStruct const myInstance = new MyStruct();

But this is meaningless. You cannot change the variable without
changing the object, and vice versa. Separating the concepts is not
meaningful, because when you get right down to it, they are the same
bucket of memory. There is no separate bucket for the myInstance
variable. It simply is the MyStruct instance. The simpler declaration
below is good enough to do the job.

const MyStruct myInstance = new MyStruct();

A const reference, to my
knowledge anyway, would mean the object refered to is const, not the
reference variable itself.


In C++ yes, but that's because C++ references are immutable. You can
only initialize a C++ reference, not assign it. A .Net const
implemention might be considered incomplete if you could not have
const references as well as references to const. I've been using the
expression "const reference" so far since in C++ the meaning would
have been unambigous and I failed to realise that in C# it's not. I
should have been saying "reference to const". In the case where both
are const it would be "const reference to const".

I say might above because I'm not sure const for references would be
much use. You could use it locally to avoid mistakes, and in parameter
declarations to ensure no use of the param as an assignable variable
in a method, but I'm not sure either reason is compelling enough to
justify the added complexity. The reason it's not more useful is that
unlike with pointers, you can't have references to references, so the
need to protect a reference refererenced by a reference does not
exist.

>> >> >> >Ideally, it would be possible to cast *to* const
>> >> >> That should be an implicit conversion. Zero runtime cost with a
>> >> >> classic implementation.
>> >> >
>> >> >I dislike implicit conversions,
>> >>
>> >> Even those, like the one above, that are 100% guaranteed to be safe?
>> >
>> >Except in limited situations, I'd rather see the explicit cast incode, >> >mainly for maintaince sake.
>>
>> I don't understand this at all. How would placing a cast at the site
>> of every implicit convertion help maintainability? I'd expect the
>> opposite. A whole lot of code would still compile after changing the
>> type of a variable, because you explicitly cast it when passing it as
>> a base type or interface. You've written a whole lot of unnessessary
>> casts and moved refactoring problems from compile time to runtime, as
>> well as significantly increased the pure typing effort involved in
>> both the original coding and any refactoring. I see no gain in any of
>> this. Quite the opposite.
>
>Simply because the next guy can easily tell whats going on. With the
>exception of numeric conversions(mostly because thats how peoples minds
>work), I don't like implicit conversions. A cast to a base class isn't an
>implicit conversion, thats an implicit cast. Which is quite a different
>thing.


The type system, quite correctly, consider an ArrayList to be an
Object. No cast, implicit or otherwise, is employed to pass an
ArrayList as an Object or to invoke Object members on an ArrayList
instance. I'd consider casting to a base class obfuscation since a
cast is a clear indication that a dangerous conversion is performed
and this is simply not the case for such a convection.

Do you really write code like this?

int i = 1;
Console.WriteLine((object)i);
Type intType = ((Object)i).GetType();

Do you really consider code like that to improve maintainability and
legibility?

That isn't what I meant. What you are illustrating there is a cast, not a
conversion. My problem is with conversions, such as if ArrayList defined an
implicit conversion to an array. To be clear, a conversion creates a new
object(usually) of a different type


Not neccessarily. This is probably where our disagreement comes from.
The C# language spec should clear things up:

http://www.jaggersoft.com/csharp_standard/13.1.4.htm

As per the spec, what I'm doing is applying a cast that is completely
unneccessary since subclass to baseclass is an implicit reference
conversion. The same would be true had I cast to IComparable instead.
There is no new object created. See the bottom note at the page above.
In fact the casts above should generate no IL what so ever.
<snip>

Regards /Magnus Lidbom

Nov 15 '05 #43

P: n/a
if you allow me to drop in, i think there is something to clarify, which
will help you both to get on the same track...
....in the interest of continuing the interesting dicussion.

<inline>

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:sc********************************@4ax.com...
On Wed, 11 Feb 2004 20:45:29 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:ra********************************@4ax.com.. .
On Mon, 9 Feb 2004 20:45:50 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
<snip>
> >> >It depends, I cast pretty much only to explicitly convert to an
>> >interface.
>> >>
>> >> Good catch. I failed to consider that quirk of the language. Since
the
>> >> compiler already knows that the class implements the interface,
and >> >> that the cast will therefore always succeed, no warning should be
>> >> issued in this case. Semantically, this is not a cast. It is merely
a
>> >> mechanism to allow you to unambiguously specify which method you
>> >> intended to call in the presence of naming conflicts whenimplementing
>> >> multiple interfaces.
>> >>
>> >Unfortunatly, the compiler can't actually know if the class
implements >the
>> >interface, atleast usually. A typed variable has no constraints on ifthe
>> >class provides an interface unless the type does. Derived classes
are >free
>> >to (re)implement interfaces. It may not be the cleanest thing but itis
>> >often reliable(preferably using as rather than (cast) operation,
but >still).
>>
>> I assumed you were talking about casting an instance of a specific
>> class to an interface that the instance's class implements explicitly. >> If that's not what you mean, then either there is no need for a cast, >> or we are talking about the sledgehammer that I would want to se a
>> warning for, at the highest warning level.
>
>Usually because of explicit implementation(or to decouple things, usually >due to reflection.) However it can be difficult sometimes to know if an >explicit implementation exists or not, just because a base class

implements
>it implicitly, a derived class could reimplement it explicitly

Could you give an example where it would make sense for a subclass to
explicitly implement an interface that a base class implements
implicitly?

What if subclass of such a class overrides a method implicitly
implemented? Polymorphism is broken for such a class hierarchy.

Given that Foo exists in two versions, both implementations of
IBar.Foo, could you give an example where you would not consider the
class broken if instance.Foo != ((IBar)instance).Foo? Or if the result
of calling instance.Foo() was not the same as that of calling
((IBar)instance).Foo()?

If you can, how do you determine that the explicit' implementation is
the correct one to call? It may not be the most derived.

For my part, I consider such a class hierarchy fundamentally broken,
and as such, a problem I will deal with if I ever encounter it.


Perhaps it isn't right, but it is legal. For one, part of the reason that
explicit interface implementation exists is so an interface name can

classwith another interface. You can't rely on instance.Foo to be the actual
interface member, usually due to two interfaces with colliding member namesor with base type member collision with the interfaces.


Yes, I know what the purpose of the feature is :) It is also useful
for the ability to implement an internal interface. But neither of
these uses would replace an implicit implementation with an explicit
one. My point was that such a replacement is a fundamentally flawed
design that makes it impossible, even in theory, to know in a generic
fashion how to call the method in order to access the correct method.
There simply is no correct method. Given this, I wouldn't cast to an
interface unless it was emplicitly implemented for the class in
question. Of course, I'd have no choice in that situaton :)

> >Safe is one thing, confusing and unapparent is another. Implicit
>conversions
>> >in most cases are an issue more of apparentability than anything else. >Casts
>> >are apparent and a coder can deal with them, an implicit conversion is
a
>> >risky thing that can cause code and behaviour to come into being
that >isn't
>> >expected.
>>
>> It should be neither confusing, unapparent nor risky. Implicit
>> conversions should occur only where the source type is an instance of >> the target type as far as OO is concerned. As far as I know this is
>> the case for all built in implicit convertions.
>If you are working strictly with built in types you are lucky. I don't

hav
>ethe time to analyze every piece of code\library I get nor can I
>realistically reject something simply because it provides an implicit
>conversion I don't like. I don't like to rely on implicit conversions
>otuside of some very limited situations

If you mean that you use cast to mark _improper_ implicit conversions,
then I'm all for it. Improper implicit conversions constitute a nasty
form of obfuscation. I define improper as any conversion not fitting
my comment above.


Improper conversion sounds like a good description, that is indeed what I
mean.


Glad we got that worked out :)
> >> >structs should be immutable by default, IMHO.
>> >>
>> >> Immutability is a relatively rare trait, making it the default would
,
>> >> in my opinion, be inappropriate. It certainly would break an
immense >> >> amount of code.
>> >Possibly, I should say immutability should be a design goal for value >types.
>> >Due to their copy by value nature, you can't rely on a value type for >much,
>> >immutability is often logical.
>>
>> This is not at all my experience. Actually, I don't know of a single
>> immutable struct type. Could you provide examples and a motivation for >> this guideline?
>The primative .NET types are immutable.

int i = 0;
++i;

void ModyfyDate(ref DateTime date)
{
date = DateTime.Now;
}

The reason that the primitives have no modifiers, besides operators,
it that, since they hold only one value, replacing the entire struct
is equivalent to changing that single value.

I do see how you could consider them immutable. They supply no
modifiers as such, besides operators. But the value of the variable is
the value type instance, and that value can be changed.

With value types, the variable's value is the object, not a reference
to the object, and immutable means that no part of an object can be
changed in any externally detectable way. No instance of a value type
in .Net can be immutable if not declared const.


I disagree here, in both cases *new* objects\data are created and placed inthe same place. That is a different thing(granted, a stack value isn't an
object until its boxed, I don't think its possible to operate on it withoutperforming a cast, retaining immutability). It is inherently a property ofthe .NET type system but that is simply how it is.


I think I understand how you're thinking here. Basicly you view the
variable as a sort of implicit reference, and feel that unless the
value of the variable can be changed piecemeal, only replaced, then
the type should be considered immutable. Is this what you mean?

Consider the affects of our different views on a const
implementation. Should the variable's "whole" value be considered
different from the value stored in it, then you'd have to be able to
separately assign constness to the two, Something like:

const MyStruct const myInstance = new MyStruct();

But this is meaningless. You cannot change the variable without
changing the object, and vice versa. Separating the concepts is not
meaningful, because when you get right down to it, they are the same
bucket of memory. There is no separate bucket for the myInstance
variable. It simply is the MyStruct instance. The simpler declaration
below is good enough to do the job.

const MyStruct myInstance = new MyStruct();

A const reference, to my
knowledge anyway, would mean the object refered to is const, not the
reference variable itself.


In C++ yes, but that's because C++ references are immutable. You can
only initialize a C++ reference, not assign it. A .Net const
implemention might be considered incomplete if you could not have
const references as well as references to const. I've been using the
expression "const reference" so far since in C++ the meaning would
have been unambigous and I failed to realise that in C# it's not. I
should have been saying "reference to const". In the case where both
are const it would be "const reference to const".

I say might above because I'm not sure const for references would be
much use. You could use it locally to avoid mistakes, and in parameter
declarations to ensure no use of the param as an assignable variable
in a method, but I'm not sure either reason is compelling enough to
justify the added complexity. The reason it's not more useful is that
unlike with pointers, you can't have references to references, so the
need to protect a reference refererenced by a reference does not
exist.

> >> >> >Ideally, it would be possible to cast *to* const
>> >> >> That should be an implicit conversion. Zero runtime cost with a >> >> >> classic implementation.
>> >> >
>> >> >I dislike implicit conversions,
>> >>
>> >> Even those, like the one above, that are 100% guaranteed to be safe? >> >
>> >Except in limited situations, I'd rather see the explicit cast in

code,
>> >mainly for maintaince sake.
>>
>> I don't understand this at all. How would placing a cast at the site
>> of every implicit convertion help maintainability? I'd expect the
>> opposite. A whole lot of code would still compile after changing the
>> type of a variable, because you explicitly cast it when passing it as >> a base type or interface. You've written a whole lot of unnessessary
>> casts and moved refactoring problems from compile time to runtime, as >> well as significantly increased the pure typing effort involved in
>> both the original coding and any refactoring. I see no gain in any of >> this. Quite the opposite.
>
>Simply because the next guy can easily tell whats going on. With the
>exception of numeric conversions(mostly because thats how peoples minds >work), I don't like implicit conversions. A cast to a base class isn't an >implicit conversion, thats an implicit cast. Which is quite a different >thing.

The type system, quite correctly, consider an ArrayList to be an
Object. No cast, implicit or otherwise, is employed to pass an
ArrayList as an Object or to invoke Object members on an ArrayList
instance. I'd consider casting to a base class obfuscation since a
cast is a clear indication that a dangerous conversion is performed
and this is simply not the case for such a convection.

Do you really write code like this?

int i = 1;
Console.WriteLine((object)i);
Type intType = ((Object)i).GetType();

Do you really consider code like that to improve maintainability and
legibility?

That isn't what I meant. What you are illustrating there is a cast, not a
conversion. My problem is with conversions, such as if ArrayList defined animplicit conversion to an array. To be clear, a conversion creates a new
object(usually) of a different type


Not neccessarily. This is probably where our disagreement comes from.
The C# language spec should clear things up:

http://www.jaggersoft.com/csharp_standard/13.1.4.htm

As per the spec, what I'm doing is applying a cast that is completely
unneccessary since subclass to baseclass is an implicit reference
conversion. The same would be true had I cast to IComparable instead.
There is no new object created. See the bottom note at the page above.
In fact the casts above should generate no IL what so ever.


The spec here is using the word conversion (in conjunction with reference,
as in "reference conversion") literaly.
Magnus, the "conversions" you are talking about are simply "casts" in
Daniel's mind.
As he says, casts do not change the value of the object casted.
The conversions Daniel refers to are those, defined with a conversion
operator in C#:

public static implicit operator T1 (T2 v)
{
...somehow convert the object v from type T2 to T1, pottentially
creating a new object...
}

Excuse me if that was clear to both of you, it might very well have been. In
that case, please ignore this message.
Just trying to help...

On a sideline, I have to disagree with Daniel on the usefullness of
conversions.
Conversions (and especially implicit ones) are invaluable asset in C#, one
of the things that makes it far more expressive than Java.
I agree there is dark side to them in the sense that for someone might not
be obvious what is going on, but still, I think the benefits are well worth
it.


<snip>

Regards /Magnus Lidbom

Nov 15 '05 #44

P: n/a

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:sc********************************@4ax.com...
On Wed, 11 Feb 2004 20:45:29 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:ra********************************@4ax.com.. .
On Mon, 9 Feb 2004 20:45:50 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
<snip>
> >> >It depends, I cast pretty much only to explicitly convert to an
>> >interface.
>> >>
>> >> Good catch. I failed to consider that quirk of the language. Since
the
>> >> compiler already knows that the class implements the interface,
and >> >> that the cast will therefore always succeed, no warning should be
>> >> issued in this case. Semantically, this is not a cast. It is merely
a
>> >> mechanism to allow you to unambiguously specify which method you
>> >> intended to call in the presence of naming conflicts whenimplementing
>> >> multiple interfaces.
>> >>
>> >Unfortunatly, the compiler can't actually know if the class
implements >the
>> >interface, atleast usually. A typed variable has no constraints on ifthe
>> >class provides an interface unless the type does. Derived classes
are >free
>> >to (re)implement interfaces. It may not be the cleanest thing but itis
>> >often reliable(preferably using as rather than (cast) operation,
but >still).
>>
>> I assumed you were talking about casting an instance of a specific
>> class to an interface that the instance's class implements explicitly. >> If that's not what you mean, then either there is no need for a cast, >> or we are talking about the sledgehammer that I would want to se a
>> warning for, at the highest warning level.
>
>Usually because of explicit implementation(or to decouple things, usually >due to reflection.) However it can be difficult sometimes to know if an >explicit implementation exists or not, just because a base class

implements
>it implicitly, a derived class could reimplement it explicitly

Could you give an example where it would make sense for a subclass to
explicitly implement an interface that a base class implements
implicitly?

What if subclass of such a class overrides a method implicitly
implemented? Polymorphism is broken for such a class hierarchy.

Given that Foo exists in two versions, both implementations of
IBar.Foo, could you give an example where you would not consider the
class broken if instance.Foo != ((IBar)instance).Foo? Or if the result
of calling instance.Foo() was not the same as that of calling
((IBar)instance).Foo()?

If you can, how do you determine that the explicit' implementation is
the correct one to call? It may not be the most derived.

For my part, I consider such a class hierarchy fundamentally broken,
and as such, a problem I will deal with if I ever encounter it.


Perhaps it isn't right, but it is legal. For one, part of the reason that
explicit interface implementation exists is so an interface name can

classwith another interface. You can't rely on instance.Foo to be the actual
interface member, usually due to two interfaces with colliding member namesor with base type member collision with the interfaces.


Yes, I know what the purpose of the feature is :) It is also useful
for the ability to implement an internal interface. But neither of
these uses would replace an implicit implementation with an explicit
one. My point was that such a replacement is a fundamentally flawed
design that makes it impossible, even in theory, to know in a generic
fashion how to call the method in order to access the correct method.
There simply is no correct method. Given this, I wouldn't cast to an
interface unless it was emplicitly implemented for the class in
question. Of course, I'd have no choice in that situaton :)

Unfortunatly, there are alot of situations where an explicit implementation
may have been chosen. I try to work with interfaces as interfaces(actually
try to never see anything but the interface, but factories can't always
solve the problem). Most of the time I work with interfaces explicitly,
trying to avoid concrete types(I do alot of plugin\loosely coupled systems).
So my casts to interfaces are done at a rather low level, usually casting
from object using as. It works fairly well, IMHO.> >Safe is one thing, confusing and unapparent is another. Implicit
>conversions
>> >in most cases are an issue more of apparentability than anything else. >Casts
>> >are apparent and a coder can deal with them, an implicit conversion is
a
>> >risky thing that can cause code and behaviour to come into being
that >isn't
>> >expected.
>>
>> It should be neither confusing, unapparent nor risky. Implicit
>> conversions should occur only where the source type is an instance of >> the target type as far as OO is concerned. As far as I know this is
>> the case for all built in implicit convertions.
>If you are working strictly with built in types you are lucky. I don'thav
>ethe time to analyze every piece of code\library I get nor can I
>realistically reject something simply because it provides an implicit
>conversion I don't like. I don't like to rely on implicit conversions
>otuside of some very limited situations

If you mean that you use cast to mark _improper_ implicit conversions,
then I'm all for it. Improper implicit conversions constitute a nasty
form of obfuscation. I define improper as any conversion not fitting
my comment above.


Improper conversion sounds like a good description, that is indeed what I
mean.


Glad we got that worked out :)
> >> >structs should be immutable by default, IMHO.
>> >>
>> >> Immutability is a relatively rare trait, making it the default would
,
>> >> in my opinion, be inappropriate. It certainly would break an
immense >> >> amount of code.
>> >Possibly, I should say immutability should be a design goal for value >types.
>> >Due to their copy by value nature, you can't rely on a value type for >much,
>> >immutability is often logical.
>>
>> This is not at all my experience. Actually, I don't know of a single
>> immutable struct type. Could you provide examples and a motivation for >> this guideline?
>The primative .NET types are immutable.

int i = 0;
++i;

void ModyfyDate(ref DateTime date)
{
date = DateTime.Now;
}

The reason that the primitives have no modifiers, besides operators,
it that, since they hold only one value, replacing the entire struct
is equivalent to changing that single value.

I do see how you could consider them immutable. They supply no
modifiers as such, besides operators. But the value of the variable is
the value type instance, and that value can be changed.

With value types, the variable's value is the object, not a reference
to the object, and immutable means that no part of an object can be
changed in any externally detectable way. No instance of a value type
in .Net can be immutable if not declared const.


I disagree here, in both cases *new* objects\data are created and placed inthe same place. That is a different thing(granted, a stack value isn't an
object until its boxed, I don't think its possible to operate on it withoutperforming a cast, retaining immutability). It is inherently a property ofthe .NET type system but that is simply how it is.


I think I understand how you're thinking here. Basicly you view the
variable as a sort of implicit reference, and feel that unless the
value of the variable can be changed piecemeal, only replaced, then
the type should be considered immutable. Is this what you mean?

Consider the affects of our different views on a const
implementation. Should the variable's "whole" value be considered
different from the value stored in it, then you'd have to be able to
separately assign constness to the two, Something like:

const MyStruct const myInstance = new MyStruct();

But this is meaningless. You cannot change the variable without
changing the object, and vice versa. Separating the concepts is not
meaningful, because when you get right down to it, they are the same
bucket of memory. There is no separate bucket for the myInstance
variable. It simply is the MyStruct instance. The simpler declaration
below is good enough to do the job.

const MyStruct myInstance = new MyStruct();


I think readonly would fit here better. readonly const MyStruct myInstance.
readonly already restricts access to a reference to only a constructor for
fields, in a method it could be limited to declaration or perhaps a readonly
block:

readonly
{
readonly const MyStruct myInstance;
myInstance = new MyStruct();
}

This isn't nessecerily the same thing, more complicated structures like
point have fields that can be set, properties and methods that can be
called. Some of these properties and method are const, some are not. In
these cases changing the entire structure is a different matter than
changing certain fields. Granted I'd rather see readonly disallow
modification to fields, readonly extension to reference types would make
sense as well.
A const reference, to my
knowledge anyway, would mean the object refered to is const, not the
reference variable itself.
In C++ yes, but that's because C++ references are immutable. You can
only initialize a C++ reference, not assign it. A .Net const
implemention might be considered incomplete if you could not have
const references as well as references to const. I've been using the
expression "const reference" so far since in C++ the meaning would
have been unambigous and I failed to realise that in C# it's not. I
should have been saying "reference to const". In the case where both
are const it would be "const reference to const".

I say might above because I'm not sure const for references would be
much use. You could use it locally to avoid mistakes, and in parameter
declarations to ensure no use of the param as an assignable variable
in a method, but I'm not sure either reason is compelling enough to
justify the added complexity. The reason it's not more useful is that
unlike with pointers, you can't have references to references, so the
need to protect a reference refererenced by a reference does not
exist.

I'm not entirely sure either, but with structs, I don't think const can be
realistically enforced without it either.
>> >> >> >Ideally, it would be possible to cast *to* const
>> >> >> That should be an implicit conversion. Zero runtime cost with a >> >> >> classic implementation.
>> >> >
>> >> >I dislike implicit conversions,
>> >>
>> >> Even those, like the one above, that are 100% guaranteed to be safe? >> >
>> >Except in limited situations, I'd rather see the explicit cast in

code,
>> >mainly for maintaince sake.
>>
>> I don't understand this at all. How would placing a cast at the site
>> of every implicit convertion help maintainability? I'd expect the
>> opposite. A whole lot of code would still compile after changing the
>> type of a variable, because you explicitly cast it when passing it as >> a base type or interface. You've written a whole lot of unnessessary
>> casts and moved refactoring problems from compile time to runtime, as >> well as significantly increased the pure typing effort involved in
>> both the original coding and any refactoring. I see no gain in any of >> this. Quite the opposite.
>
>Simply because the next guy can easily tell whats going on. With the
>exception of numeric conversions(mostly because thats how peoples minds >work), I don't like implicit conversions. A cast to a base class isn't an >implicit conversion, thats an implicit cast. Which is quite a different >thing.

The type system, quite correctly, consider an ArrayList to be an
Object. No cast, implicit or otherwise, is employed to pass an
ArrayList as an Object or to invoke Object members on an ArrayList
instance. I'd consider casting to a base class obfuscation since a
cast is a clear indication that a dangerous conversion is performed
and this is simply not the case for such a convection.

Do you really write code like this?

int i = 1;
Console.WriteLine((object)i);
Type intType = ((Object)i).GetType();

Do you really consider code like that to improve maintainability and
legibility?

That isn't what I meant. What you are illustrating there is a cast, not a
conversion. My problem is with conversions, such as if ArrayList defined animplicit conversion to an array. To be clear, a conversion creates a new
object(usually) of a different type


Not neccessarily. This is probably where our disagreement comes from.
The C# language spec should clear things up:

http://www.jaggersoft.com/csharp_standard/13.1.4.htm

As per the spec, what I'm doing is applying a cast that is completely
unneccessary since subclass to baseclass is an implicit reference
conversion. The same would be true had I cast to IComparable instead.
There is no new object created. See the bottom note at the page above.
In fact the casts above should generate no IL what so ever.

This is addressed(well) in Kamen's post, I'll respond there. <snip>

Regards /Magnus Lidbom

Nov 15 '05 #45

P: n/a
<snip>
> The type system, quite correctly, consider an ArrayList to be an
> Object. No cast, implicit or otherwise, is employed to pass an
> ArrayList as an Object or to invoke Object members on an ArrayList
> instance. I'd consider casting to a base class obfuscation since a
> cast is a clear indication that a dangerous conversion is performed
> and this is simply not the case for such a convection.
>
> Do you really write code like this?
>
> int i = 1;
> Console.WriteLine((object)i);
> Type intType = ((Object)i).GetType();
>
> Do you really consider code like that to improve maintainability and
> legibility?
>
That isn't what I meant. What you are illustrating there is a cast, not aconversion. My problem is with conversions, such as if ArrayList defined
an
implicit conversion to an array. To be clear, a conversion creates a
newobject(usually) of a different type


Not neccessarily. This is probably where our disagreement comes from.
The C# language spec should clear things up:

http://www.jaggersoft.com/csharp_standard/13.1.4.htm

As per the spec, what I'm doing is applying a cast that is completely
unneccessary since subclass to baseclass is an implicit reference
conversion. The same would be true had I cast to IComparable instead.
There is no new object created. See the bottom note at the page above.
In fact the casts above should generate no IL what so ever.


The spec here is using the word conversion (in conjunction with reference,
as in "reference conversion") literaly.
Magnus, the "conversions" you are talking about are simply "casts" in
Daniel's mind.
As he says, casts do not change the value of the object casted.
The conversions Daniel refers to are those, defined with a conversion
operator in C#:

public static implicit operator T1 (T2 v)
{
...somehow convert the object v from type T2 to T1, pottentially
creating a new object...
}

Excuse me if that was clear to both of you, it might very well have been.

In that case, please ignore this message.
Just trying to help...
This is pretty much waht I mean, conversion operators. On a sideline, I have to disagree with Daniel on the usefullness of
conversions.
Conversions (and especially implicit ones) are invaluable asset in C#, one
of the things that makes it far more expressive than Java.
I agree there is dark side to them in the sense that for someone might not
be obvious what is going on, but still, I think the benefits are well worth it. I dislike implicit conversion operators, mainly because they are unapparent.
I would have no problem with explicit conversion operators if they didn't
use the cast operator, instead opting for different syntax. The cast and
implicit conversions make it to hard to determine exactly what is going on.
I also have issues with the way operators work, being static they are
unreliable, I simply don't care for them.


<snip>

Regards /Magnus Lidbom


Nov 15 '05 #46

P: n/a
On Thu, 12 Feb 2004 11:01:05 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
news:sc********************************@4ax.com.. .
On Wed, 11 Feb 2004 20:45:29 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
>
>"Magnus Lidbom" <ma***********@hotmail.com> wrote in message
>news:ra********************************@4ax.com.. .
>> On Mon, 9 Feb 2004 20:45:50 -0600, "Daniel O'Connell [C# MVP]"
>> <onyxkirx@--NOSPAM--comcast.net> wrote:
>>
<snip>
Yes, I know what the purpose of the feature is :) It is also useful
for the ability to implement an internal interface. But neither of
these uses would replace an implicit implementation with an explicit
one. My point was that such a replacement is a fundamentally flawed
design that makes it impossible, even in theory, to know in a generic
fashion how to call the method in order to access the correct method.
There simply is no correct method. Given this, I wouldn't cast to an
interface unless it was emplicitly implemented for the class in
question. Of course, I'd have no choice in that situaton :)

Unfortunatly, there are alot of situations where an explicit implementation
may have been chosen. I try to work with interfaces as interfaces(actually
try to never see anything but the interface, but factories can't always
solve the problem). Most of the time I work with interfaces explicitly,
trying to avoid concrete types(I do alot of plugin\loosely coupled systems).
So my casts to interfaces are done at a rather low level, usually casting
from object using as. It works fairly well, IMHO.


I've been arguing against using unnecessary casts. For a plugin
architecture, there is no choice, that I know of, somewhere you will
have to cast to the interface that the plugins implement. As long as
this is done only in the appropriate part of the subsystem that sets
up the plugins, I see nothing wrong with it.

>> >> >> >structs should be immutable by default, IMHO.
>> >> >>
>> >> >> Immutability is a relatively rare trait, making it the defaultwould >,
>> >> >> in my opinion, be inappropriate. It certainly would break animmense >> >> >> amount of code.
>> >> >Possibly, I should say immutability should be a design goal forvalue >> >types.
>> >> >Due to their copy by value nature, you can't rely on a value typefor >> >much,
>> >> >immutability is often logical.
>> >>
>> >> This is not at all my experience. Actually, I don't know of a single
>> >> immutable struct type. Could you provide examples and a motivationfor >> >> this guideline?
>> >The primative .NET types are immutable.
>>
>> int i = 0;
>> ++i;
>>
>> void ModyfyDate(ref DateTime date)
>> {
>> date = DateTime.Now;
>> }
>>
>> The reason that the primitives have no modifiers, besides operators,
>> it that, since they hold only one value, replacing the entire struct
>> is equivalent to changing that single value.
>>
>> I do see how you could consider them immutable. They supply no
>> modifiers as such, besides operators. But the value of the variable is
>> the value type instance, and that value can be changed.
>>
>> With value types, the variable's value is the object, not a reference
>> to the object, and immutable means that no part of an object can be
>> changed in any externally detectable way. No instance of a value type
>> in .Net can be immutable if not declared const.
>>
>
>I disagree here, in both cases *new* objects\data are created and placedin >the same place. That is a different thing(granted, a stack value isn't an
>object until its boxed, I don't think its possible to operate on itwithout >performing a cast, retaining immutability). It is inherently a propertyof >the .NET type system but that is simply how it is.


I think I understand how you're thinking here. Basicly you view the
variable as a sort of implicit reference, and feel that unless the
value of the variable can be changed piecemeal, only replaced, then
the type should be considered immutable. Is this what you mean?

Consider the affects of our different views on a const
implementation. Should the variable's "whole" value be considered
different from the value stored in it, then you'd have to be able to
separately assign constness to the two, Something like:

const MyStruct const myInstance = new MyStruct();

But this is meaningless. You cannot change the variable without
changing the object, and vice versa. Separating the concepts is not
meaningful, because when you get right down to it, they are the same
bucket of memory. There is no separate bucket for the myInstance
variable. It simply is the MyStruct instance. The simpler declaration
below is good enough to do the job.

const MyStruct myInstance = new MyStruct();


I think readonly would fit here better. readonly const MyStruct myInstance.
readonly already restricts access to a reference to only a constructor for
fields, in a method it could be limited to declaration or perhaps a readonly
block:

readonly
{
readonly const MyStruct myInstance;
myInstance = new MyStruct();
}

This isn't nessecerily the same thing, more complicated structures like
point have fields that can be set, properties and methods that can be
called. Some of these properties and method are const, some are not. In
these cases changing the entire structure is a different matter than
changing certain fields.


But that's my point, there is no meaningful difference. The variable
is the instance There are no references, except when using ref or out,
to value types. If const above means no field may be modified, then it
also means that the entire instance may not be replaced, because that
would replace all the fields. The variable, the instance, and the
instance's fields, are all one and the same, they occupy the same
memory. Accordingly, you only need one. Readonly or const.
<snip>

/Magnus Lidbom
Nov 15 '05 #47

P: n/a
<snip>

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
message news:%2****************@tk2msftngp13.phx.gbl...
<snip>
>> The type system, quite correctly, consider an ArrayList to be an
>> Object. No cast, implicit or otherwise, is employed to pass an
>> ArrayList as an Object or to invoke Object members on an ArrayList
>> instance. I'd consider casting to a base class obfuscation since a
>> cast is a clear indication that a dangerous conversion is performed
>> and this is simply not the case for such a convection.
>>
>> Do you really write code like this?
>>
>> int i = 1;
>> Console.WriteLine((object)i);
>> Type intType = ((Object)i).GetType();
>>
>> Do you really consider code like that to improve maintainability and >> legibility?
>>
>That isn't what I meant. What you are illustrating there is a cast,
not
a >conversion. My problem is with conversions, such as if ArrayList defined
an
>implicit conversion to an array. To be clear, a conversion creates a new >object(usually) of a different type

Not neccessarily. This is probably where our disagreement comes from.
The C# language spec should clear things up:

http://www.jaggersoft.com/csharp_standard/13.1.4.htm

As per the spec, what I'm doing is applying a cast that is completely
unneccessary since subclass to baseclass is an implicit reference
conversion. The same would be true had I cast to IComparable instead.
There is no new object created. See the bottom note at the page above.
In fact the casts above should generate no IL what so ever.
The spec here is using the word conversion (in conjunction with

reference, as in "reference conversion") literaly.
Magnus, the "conversions" you are talking about are simply "casts" in
Daniel's mind.
As he says, casts do not change the value of the object casted.
The conversions Daniel refers to are those, defined with a conversion
operator in C#:

public static implicit operator T1 (T2 v)
{
...somehow convert the object v from type T2 to T1, pottentially
creating a new object...
}

Excuse me if that was clear to both of you, it might very well have been. In
that case, please ignore this message.
Just trying to help...
This is pretty much waht I mean, conversion operators.
On a sideline, I have to disagree with Daniel on the usefullness of
conversions.
Conversions (and especially implicit ones) are invaluable asset in C#,

one of the things that makes it far more expressive than Java.
I agree there is dark side to them in the sense that for someone might not be obvious what is going on, but still, I think the benefits are well

worth
it.

I dislike implicit conversion operators, mainly because they are

unapparent. I would have no problem with explicit conversion operators if they didn't
use the cast operator, instead opting for different syntax. The cast and
implicit conversions make it to hard to determine exactly what is going on. I also have issues with the way operators work, being static they are
unreliable, I simply don't care for them.


Well, I am glad you are not on the C# design team :)
Again, it is almost always apparent what you want to do in Java, but to
maintain this apperentability, the expressions are more complex than they
should be (well, at least more complex than I am willing to tolerate).
Now that Java 1.5 has boxing and generics, can you please tell me what is it
that will make *YOU* prefer whidbey instead of java 1.5?


<snip>

Regards /Magnus Lidbom



Nov 15 '05 #48

P: n/a

"Kamen Yotov" <ka***@yotov.org> wrote in message
news:%2***************@TK2MSFTNGP12.phx.gbl...
<snip>

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> wrote in
message news:%2****************@tk2msftngp13.phx.gbl... <snip>

This is pretty much waht I mean, conversion operators.
On a sideline, I have to disagree with Daniel on the usefullness of
conversions.
Conversions (and especially implicit ones) are invaluable asset in C#, one of the things that makes it far more expressive than Java.
I agree there is dark side to them in the sense that for someone might not be obvious what is going on, but still, I think the benefits are well

worth
it.

I dislike implicit conversion operators, mainly because they are

unapparent.
I would have no problem with explicit conversion operators if they didn't use the cast operator, instead opting for different syntax. The cast and
implicit conversions make it to hard to determine exactly what is going

on.
I also have issues with the way operators work, being static they are
unreliable, I simply don't care for them.


Well, I am glad you are not on the C# design team :)
Again, it is almost always apparent what you want to do in Java, but to
maintain this apperentability, the expressions are more complex than they
should be (well, at least more complex than I am willing to tolerate).
Now that Java 1.5 has boxing and generics, can you please tell me what is

it that will make *YOU* prefer whidbey instead of java 1.5?
Well, as a whole mainly that I am not particularlarly fond of java. I've
used it several times and while the language itself is fine, the IDE's and
many of the libraries\design decisions leave alot to be desired. I dislike
the java implementation of generics(as I understand them), dislike the java
event system(is that changing in 1.5?), dislike not having valuetypes,
dislike not having unsafe code(use it rarely but I like having the option),
dislike the hoops required to interop with non-java code(I use vb.net to
work with office now and then). I consider java naming conventions to be
aimed at obfustication. If I wanted to try, I imagine I could come up with
more, however I think you've got my point.

My argument against implicit conversions is that they are abusable and in
*almost* every case they are used they are abused. I do see their value, in
mathematics and other small domains, however as a whole I'd rather see
explicit conversions(using a different operator, convert<int>(x) for
example, even if it is a touch more complex, however in math it would be
annoying(I would rather cast a long to int rather than use a conversion
operator, in almost every other case I'd rather see the conversion. Such
rules make things too complex in and of themselves though.). Operator
overloading is tricky IMHO. I am not entirely sure what I'd like to see, if
I'd prefer polymorphic, instance based operators(with ==(object,object)
defined as a reference comparison on the base) and using more complex rules
to determine which operator to call vs using the static ones as they are.
They both have their upsides, both their downsides, and sometimes it makes
it a bit too complex. As with implicit conversions, they are ok if used
carefully, when viable. Not as a shortcut for the lazy(one operator I doubt
I'll ever approve of is the assignment operator, I don't think that should
be overloadable).

Nov 15 '05 #49

This discussion thread is closed

Replies have been disabled for this discussion.