Another C# critique

  • Thread starter christopher diggins
  • Start date
F

Frans Bouma

Magnus Lidbom said:
In this case the mapping information has a one to one relationship to
the type of the object that is mapped. Duplicating the mapping
information for each entity would mean huge memory consumption and very
bad performance. Is there such a thing as an object relational mapping
framework that duplicates mapping information for each entity?

With my tool, LLBLGen Pro, I supply templates which generate code
in 2 different paradigms: selfservicing and adapter. Selfservicing
contains persistence info per entity. adapter uses a central repository
for that. Selfservicing requires this info in the entity because it has to
be able to execute code like this:

CustomerEntity customer = new CustomerEntity("CHOPS");

that creates an entity object instance of type Customer and fetches the
entity data with PK "CHOPS" from the database into this new entity
instance. This code has to be able to function completely decoupled from a
central repository, so the data is carried with the entity. THe other
model doesn't use this paradigm, as it uses a central 'adapter' class
which handles all actions with the persistent storage and which retrieves
persistence info for an entity at runtime from a central repository
(singleton object store)

However I don't see why it would result in huge memory problems.
The thing is: you don't carry around an entity for a long time that often,
it's not that wise to load 1000s of entity objects into memory anyway, if
you want to load a list of data for example. You then can better use
readonly lists build ontop of entity definitions which fetch data into a
datatable fast.
This framework does not support such functionality at the moment. It
might eventually if a compelling need is demonstrated. However, I see no
need to duplicate the mapping information for each entity in order to
implement such functionality. A single new mapping per scenario should
suffice.

The problem is that you should be able to do that on a per-call
basis. Of course, if you as a developer can inject at runtime, mapping
information on a per call basis, it's perfect. I agree that duplicating
information in objects is not that great if it's not necessary. However if
no central object is used, like a central context, broker or other object,
to retrieve/create entity objects, you have to do it this way. Of course
you can create a static class which creates at application start the
repository in core and which is consulted by the entity objects, still,
this can lead to some slowdowns in performance. As I said, duplicated
mapping info at runtime is not that much of a problem, as mapping info is
fairly small and entities are not carried around long, at least they
shouldn't be, due to the fact that an entity that's rather old can get out
of sync sooner or later.

FB
 
F

Frans Bouma

Daniel O'Connell said:
While it would be a noble feature, as has been expressed several times
by various MS employees(I can probably still find references if you want
'em) because .NET & C# didn't have const in the beginning, the vast
amount of existing code(the framework most notably) that has no concept
of const may make it as much of a silly issue as it is in C++(cast it
away easily, etc). Realistically, adding const to C# really would mean
adding it to the BCL or its usage would be *heavily* marginalized. Just
as adding optional exception specs would effectivly do no good because a
very large portion of functionality doesn't have them, its an issue that
will have to be addressed.

I find this a non-issue. The thing is: *if* const is added, the
developer using const on his own code passing it to a BCL method will run
into trouble and this is correct. For THAT purpose he has to write a non-
const property. IF the BCL is set up correctly it works with base
classes/known interfaces ONLY anyway which do not specify const at all.

If const is added to the spec, developers can finally protect
object states of deep object trees or other objects easily and on a per-
property/method basis. This is essential for code working with THAT code.
It has nothing to do with the BCL, because passing a const object to a BCL
method which modifies it is incorrect by definition, so why should it be a
problem, the developer knows it is a const :)

The reason const isn't part of the language is, if I understood
Gunnerson correctly, that interop with other languages is then a problem,
because these other languages don't have a concept of 'const'.

That's all fine and clear but these other languages also don't have
the concept of generics in some cases. Furthermore, the future will
probably ask for features to be added some languages don't support. Should
the syntax of COBOL be the limiter on C#'s syntaxis? I really don't see
why. Sooner or later, MS has to let go of the 'common concept', because
it's nog going to work. Is it a tough call you can't use a C#'s object in
..NET Cobol? perhaps for the .NET cobol users, however if that means that
2000 .NET cobol users can limit C#'s syntax, used by millions, I don't
know but then something is seriously wrong with the vision for .NET.

FB
 
F

Frans Bouma

Magnus Lidbom said:
Yes, there are cases where the need for const was so pressing that
the long way around of writing entire extra classes to do the job was
chosen since const isn't around. And this still, after all that work,
results in runtime errors instead of compile time errors, since the type
system cannot tell the purpose of the wrapper. And there is no standard
way of doing this, or of obtaining the readonly wrapper. The result:
more work, more reading docs, more confusing code, more time necessary
for maintenance, more bugs.

How does this mitigate the need for const?

Excellent, excellent wordings, Magnus :)

FB
 
S

Sami Vaaraniemi

codymanix said:
Normal objects will be programmed in a way that they will always have a
consistant, well-defined state.
They protect theirselven either through their interface or through thrown
exceptions if a modification is tried
that would result in inconsistent or undefined state.

Const is not about ensuring an object has a consistent and well-defined
state. It is about ensuring that the state does not change from one
consistent well-defined state to another. If an object's state changes when
the programmer assumes it won't, it may be disastrous even if the new state
is consistent and well-defined.

Sami
 
M

Magnus Lidbom

Frans Bouma said:
With my tool, LLBLGen Pro, I supply templates which generate code
Your tool appears to be a code generator. Aren't we comparing apples and
oranges here? Wouldn't a "mapping" in a code generating solution consist of
code? Meaning it uses no memory what so ever per instance?
in 2 different paradigms: selfservicing and adapter. Selfservicing
contains persistence info per entity. adapter uses a central repository
for that. Selfservicing requires this info in the entity because it has to
be able to execute code like this:

CustomerEntity customer = new CustomerEntity("CHOPS");
It requires that the information be available to the class. Not that it be
duplicated for each instance.
that creates an entity object instance of type Customer and fetches the
entity data with PK "CHOPS" from the database into this new entity
instance. This code has to be able to function completely decoupled from a
central repository,
What do you mean by repository in this context? An object cache?
so the data is carried with the entity.
What data are we talking about here? When I say mapping, I mean things like:
Field A in class X maps to column B in table Y.
Y is an identity column.
Y may not be null.
A is of type.
.............

THe other
model doesn't use this paradigm, as it uses a central 'adapter' class
which handles all actions with the persistent storage and which retrieves
persistence info for an entity at runtime from a central repository
(singleton object store)

However I don't see why it would result in huge memory problems.
Huge is subjective. When a class uses an order of magnitude more memory per
instance I call that huge.

class UserPermission
{
private User m_user;
private SecurityObject m_object;
private SecurityLevel m_level;
//methods and properties
}

I'd expect a UserPermission instance itself to occupy not much more than 12
bytes of memory since all fields are references to objects shared by many
UserPermission instances. I'd expect the mapping information to occupy
hundreds of bytes.

The thing is: you don't carry around an entity for a long time that often,
it's not that wise to load 1000s of entity objects into memory anyway, if
you want to load a list of data for example. You then can better use
readonly lists build ontop of entity definitions which fetch data into a
datatable fast.
In the framework I mentioned it's perfectly appropriate to fetch large lists
of objects. It also performs quite well. For instance, I should be able to
carry around many million instances of the above sketched class without any
problem what so ever in the sessions of a web application on a rather old
server. It should have no meaningful affect on performance.

The problem is that you should be able to do that on a per-call
basis. Of course, if you as a developer can inject at runtime, mapping
information on a per call basis, it's perfect.
If you mean that the information is gathered on demand and then used
repeatedly, then that is what I currently do.

Should I eventually implement this type of dynamic remapping it would
probably look something like this:

UserVector importedUsers;
//Remap the User class to an import table
using(DataMapper.SetMapping(typeof(User), mappingName) )
{
//Read all users from import table
//I can't wait for generics so I can get rid of these ugly casts.
importedUsers = new UserVector((User[])DataAdapter.List(typeof(User)));
}//Dispose method restores mapping.

//Save users in the default table
DataAdapter.Save(importedUsers);

I agree that duplicating
information in objects is not that great if it's not necessary.
However if
no central object is used, like a central context, broker or other object,
to retrieve/create entity objects, you have to do it this way.
I find it hard to believe that you could persuade me that mapping
information should be per instance. I see no need. But I'm not sure we are
talking about the same information.
Of course
you can create a static class which creates at application start the
repository in core and which is consulted by the entity objects, still,
this can lead to some slowdowns in performance.
I don't see how fetching a reference to the mapping when necessary could be
slower than duplicating it.
As I said, duplicated
mapping info at runtime is not that much of a problem, as mapping info is
fairly small
How do you define small? In relation to the objects mapped or on an absolute
scale?
and entities are not carried around long, at least they
shouldn't be, due to the fact that an entity that's rather old can get out
of sync sooner or later.
This, in my opinion, must be considered on a per case basis. Appropriate
caching is a vital part of most reasonably complex applications in my
experience. Se above example.


I'm guessing we're mostly just misunderstanding each other due to the very
different natures of the implementations. Code generation vs. Runtime
mapping.

/Magnus Lidbom
 
C

christopher diggins

Daniel O'Connell said:
While it would be a noble feature, as has been expressed several times by
various MS employees(I can probably still find references if you want 'em)
because .NET & C# didn't have const in the beginning, the vast amount of
existing code(the framework most notably) that has no concept of const may
make it as much of a silly issue as it is in C++(cast it away easily, etc).
Realistically, adding const to C# really would mean adding it to the BCL or
its usage would be *heavily* marginalized. Just as adding optional exception
specs would effectivly do no good because a very large portion of
functionality doesn't have them, its an issue that will have to be
addressed.

I originally tried to leave const out of the language design for Heron, but
without const a couple of problems arrive 1) allowing only primitives to
have constness elevates primitives to a special status, 2) when a design
calls for immutable and mutable instances of the same class we have to
create two separate classes. The alternative, programmer enforced
mutability, adds unneeded complexity and increases the potential for bugs
significantly. I agree though casting away const is generally a very bad
idea. But C++ is all about letting programmers do very strange things.
 
D

Daniel O'Connell [C# MVP]


As a note, this is in response to all three, just don't feel like writing
essentially the same response three times:
I find this a non-issue. The thing is: *if* const is added, the
developer using const on his own code passing it to a BCL method will run
into trouble and this is correct. For THAT purpose he has to write a non-
const property. IF the BCL is set up correctly it works with base
classes/known interfaces ONLY anyway which do not specify const at all.

The point I meant to make is that due to the BCL(and other existing code)
not supporting a notion of const, the usage of const will be limited to the
point where it may be *impossible* to use a const reference without casting
it away. At that point I consider const to be a silly limitation. You either
end up with const that doesn't count(const is just a decorator, irrelevent
to reality), or constant casting back and forth. Neither one is attractive.
I would be much more pro-const semantics if it had been done in the first
place instead of trying to wedge it in 3 or 4 versions down the line. It
works right down to object. Object.ToString() is not const, object.Equals is
not const, IEnumerable.GetEnumerator() isn't const(actually, pre-iterators
it often can't be, assuming declarations in iterator doesn't cause a const
violation, iterators should fix that), the list just continues, we all know
these methods are generally const, but the runtime wouldn't. And I'd shudder
at a suggestion to simply hard code types to ignore.
I don't know how const works in inheritance(can you change the const-ness of
an overridden method? I would hope not that seems to be a contract
violation, a method is either const or not, its not a pick and choose
thing), but without additions of the const concept to Object and all
inheritors, you start having to cast away from const to do things you
shouldn't have to worry about. If the notion of const is going to force me
to produce alot of extra casts per object, then its value is diminished
greatly.
Then, if you throw in generics, const can be a real problem. If you can
modify the const-ness of ToString, you'd have to have a generic constraint
something like where T.ToString() is const, or you'd run into odd
issues(calling ToString() on a const reference where ToString() isn't
const).
Const has to be considered and added to the BCL and the runtime, not
nessecerily everywhere but to atleast a few specific places, Object
specifically. A C# only extension will not suffice.

On another note, the syntax probably needs work, I don't particularly like
the C++ style of trailing declarators for most things(when, where, or throws
is fine, it reads ok, const, etc isn't), so figuring out a method to define
a method as both returning a const reference and being a const method.

If const is added to the spec, developers can finally protect
object states of deep object trees or other objects easily and on a per-
property/method basis. This is essential for code working with THAT code.
It has nothing to do with the BCL, because passing a const object to a BCL
method which modifies it is incorrect by definition, so why should it be a
problem, the developer knows it is a const :)

The reason const isn't part of the language is, if I understood
Gunnerson correctly, that interop with other languages is then a problem,
because these other languages don't have a concept of 'const'.

That's all fine and clear but these other languages also don't have
the concept of generics in some cases. Furthermore, the future will
probably ask for features to be added some languages don't support. Should
the syntax of COBOL be the limiter on C#'s syntaxis? I really don't see
why. Sooner or later, MS has to let go of the 'common concept', because
it's nog going to work. Is it a tough call you can't use a C#'s object in
.NET Cobol? perhaps for the .NET cobol users, however if that means that
2000 .NET cobol users can limit C#'s syntax, used by millions, I don't
know but then something is seriously wrong with the vision for .NET.

On this I sincerly agree. Outside of perhaps VB, there is *NO* language that
should have that much hold on C#. A developer would have to accept, just as
with generics(although its kind of annoying), that const isn't CLS compliant
and you will simply have to design that way. It is a limitation but one I do
feel the developer should decide on, not Microsoft. To this end I do feel
that perhaps an additional layer of compliance needs to exist,
CLS+(generics, const, unsigned types, few other bits) perchance. Allowing
you to target a good subset of clients with some assurance(I hate writing
non CLS-Compliant code, but I have to most of the time).
 
F

Frans Bouma

Magnus Lidbom said:
Your tool appears to be a code generator. Aren't we comparing apples and
oranges here? Wouldn't a "mapping" in a code generating solution consist
of code? Meaning it uses no memory what so ever per instance?

Following one paradigm, the instance contains the mapping material,
so it doesn't have to consult any other object to get its stuff persisted.
Although the mapping info is generated into the code, it is inserted via
constructors in the instance. I admit that this is a bit redundant, that's
also why the other paradigm is offered using a central repository for
mapping info, which means that the entity instances do not contain any
mapping info. In normal usage, this is not a problem though. I do not
consider an object graph of 4 million objects 'normal'.
It requires that the information be available to the class. Not that it
be duplicated for each instance.

if you want to store it physically into a variable, it has to. As I
said, it is a bit verbose perhaps, it can be more compact, I'm perfectly
aware of that, however it has advantages for people who want to alter
mapping info at runtime. That's not my prefered choice, but some people
want it ;)
What do you mean by repository in this context? An object cache?

A store with the mapping data for entity type ABC and its fields.
What data are we talking about here? When I say mapping, I mean things
like: Field A in class X maps to column B in table Y.
Y is an identity column.
Y may not be null.
A is of type.
............

that kind of data indeed. I formulated it wrong, 'data' is not the
entity data itself, it's the mapping info :)
Huge is subjective. When a class uses an order of magnitude more memory
per instance I call that huge.

class UserPermission
{
private User m_user;
private SecurityObject m_object;
private SecurityLevel m_level;
//methods and properties
}

I'd expect a UserPermission instance itself to occupy not much more
than 12 bytes of memory since all fields are references to objects
shared by many UserPermission instances. I'd expect the mapping
information to occupy hundreds of bytes.

Ok, that's also the case here, I was talking about the mapping info
for the entity fields, like Customer's fields: CustomerID, ContactName
etc.
If you mean that the information is gathered on demand and then used
repeatedly, then that is what I currently do.

Should I eventually implement this type of dynamic remapping it would
probably look something like this:

UserVector importedUsers;
//Remap the User class to an import table
using(DataMapper.SetMapping(typeof(User), mappingName) )
{
//Read all users from import table
//I can't wait for generics so I can get rid of these ugly casts.

heheh same here ;)
importedUsers = new
UserVector((User[])DataAdapter.List(typeof(User)));
}//Dispose method restores mapping.

//Save users in the default table
DataAdapter.Save(importedUsers);

yes something like that.
I find it hard to believe that you could persuade me that mapping
information should be per instance. I see no need. But I'm not sure we
are talking about the same information.

Well, if memory limitations are not an issue (the average asp.net
webapplication is not bogged down by millions of entity objects and their
mapping info for example) you can create a fetch query from the info
directly available in the entity's field objects. If you don't have that,
you have to look up the mapping information for each field. It then
depends on how you've stored your mapping information to make this read is
fast. With mapping info inside the entity, you don't have that.

It's of course also depending on how the entity classes should look
like: abstract base classes with entity field objects or a totally
different approach: clean, developer supplied classes which can only be
filled through reflection for example.
I don't see how fetching a reference to the mapping when necessary could
be slower than duplicating it.

multiple queries generated from a single entity instance: they will
be slower if you have to determine the mapping info each time you are
generating the query.

However, it depends also on how you designed your total framework.
Speed won can be lost in other areas like the CLR has to copy bigger
chunks of memory around, etc.
How do you define small? In relation to the objects mapped or on an
absolute scale?

In relation to the data the entity contains in general. Mapping
info is nothing more than a couple of strings and some ints.
I'm guessing we're mostly just misunderstanding each other due to the
very different natures of the implementations. Code generation vs.
Runtime mapping.

I think so. I was more giving an example :) which of course can be
done in another framework in a total different way.

FB
 
M

Magnus Lidbom


The point I meant to make is that due to the BCL(and other existing code)
not supporting a notion of const, the usage of const will be limited to the
point where it may be *impossible* to use a const reference without casting
it away.
At that point I consider const to be a silly limitation. You either
end up with const that doesn't count(const is just a decorator, irrelevent
to reality), or constant casting back and forth. Neither one is attractive.
I would be much more pro-const semantics if it had been done in the first
place instead of trying to wedge it in 3 or 4 versions down the line. It
works right down to object. Object.ToString() is not const, object.Equals is
not const, IEnumerable.GetEnumerator() isn't const(actually, pre-iterators
it often can't be, assuming declarations in iterator doesn't cause a const
violation, iterators should fix that), the list just continues, we all know
these methods are generally const, but the runtime wouldn't. And I'd shudder
at a suggestion to simply hard code types to ignore.
I don't know how const works in inheritance(can you change the const-ness of
an overridden method?
No. Const is part of the member signature.
I would hope not that seems to be a contract
violation, a method is either const or not, its not a pick and choose
thing), but without additions of the const concept to Object and all
inheritors, you start having to cast away from const to do things you
shouldn't have to worry about. If the notion of const is going to force me
to produce alot of extra casts per object, then its value is diminished
greatly. Agreed.

Then, if you throw in generics, const can be a real problem. If you can
modify the const-ness of ToString, you'd have to have a generic constraint
something like where T.ToString() is const, or you'd run into odd
issues(calling ToString() on a const reference where ToString() isn't
const).
This is a non issue since const would be part of the member signature.
Const has to be considered and added to the BCL and the runtime, not
nessecerily everywhere but to atleast a few specific places, Object
specifically. A C# only extension will not suffice.
That would certainly be preferrable. I'm not convinced it's a must. I don't
believe there will be quite as much need for casting as you seem to.
On another note, the syntax probably needs work, I don't particularly like
the C++ style of trailing declarators for most things(when, where, or throws
is fine, it reads ok, const, etc isn't), so figuring out a method to define
a method as both returning a const reference and being a const method.
In my opinion the existing and well known syntax should be used. C# has gone
that route so far. I see no reason to change that.


I don't see that this needs to be a problem. Const is a a compile time
thing. Couldn't it be implemented using assembly metadata? So that it
simply isn't visible at all to languages that doesn't support it? Or it
might even be possible to have const enforced at runtime when assemblies
using const are used from languages that don't support const and vice versa.
On this I sincerly agree. Outside of perhaps VB, there is *NO* language that
should have that much hold on C#. A developer would have to accept, just as
with generics(although its kind of annoying), that const isn't CLS compliant
and you will simply have to design that way. It is a limitation but one I do
feel the developer should decide on, not Microsoft. To this end I do feel
that perhaps an additional layer of compliance needs to exist,
CLS+(generics, const, unsigned types, few other bits) perchance. Allowing
you to target a good subset of clients with some assurance(I hate writing
non CLS-Compliant code, but I have to most of the time).

Here I too sincerely agree. In one way or another there really needs to be a
way to write interoperable code that uses such features as generics, const,
and operator overloading. If not it means that the powerful mainstream
languages are crippled in order to keep from marginalizing smaller
languages. That does seems silly to me.

Regards /Magnus Lidbom
 
F

Frans Bouma

Daniel O'Connell said:
The point I meant to make is that due to the BCL(and other existing
code) not supporting a notion of const, the usage of const will be
limited to the point where it may be *impossible* to use a const
reference without casting it away. At that point I consider const to be
a silly limitation. You either end up with const that doesn't
count(const is just a decorator, irrelevent to reality), or constant
casting back and forth. Neither one is attractive.

That's not the point. If you write a tool which accepts plugins,
and you want to offer these plugins access to internal contained data but
some data is readonly and other data is not, you can only achieve that by
copying to be readonly data into dummy objects so altering the data has no
effect. With const, this would have been easier.

That's not to say the plugin can't alter the data if it wants to,
however teh tool developer has provided a solid interface which in theory
is correct. The fact that custom objects then are passed to CLR methods
which want to alter them (which is not that common though) and which then
would cause trouble with respect to the const aspect of these objects, is
not important as the developer passing the const objects is in violation.
You can see that as 'limitation' but it's a limitation initiated by the
developer who created the code which produced the object that is const.

I just want to protect the objects exposed to other code from being
altered in given situations and I can now only do that by creating an
immense big pile of copy code and that's no picknick.
I would be much more
pro-const semantics if it had been done in the first place instead of
trying to wedge it in 3 or 4 versions down the line.

Agreed, but that's not reality, so this will not alter anything of
the current situation :) I also simply don't understand why generics
aren't introduced in the first CLR, after all, generics are around for
decades.
Then, if you throw in generics, const can be a real problem. If you can
modify the const-ness of ToString, you'd have to have a generic
constraint something like where T.ToString() is const, or you'd run into
odd issues(calling ToString() on a const reference where ToString()
isn't const).
Const has to be considered and added to the BCL and the runtime, not
nessecerily everywhere but to atleast a few specific places, Object
specifically. A C# only extension will not suffice.

I don't see why not. It's compiler sugar. C++'s const can be
compiled into C code, a language which doesn't contain const. I don't see
why ToString() has any importance in this though. :) It doesn't alter
anything, it just transfers a value to a string format which is returned,
the actual value isn't altered.

FB
 
D

Daniel O'Connell [C# MVP]

Magnus Lidbom said:
object.Equals const-ness
No. Const is part of the member signature.

This is a non issue since const would be part of the member signature.

That would certainly be preferrable. I'm not convinced it's a must. I don't
believe there will be quite as much need for casting as you seem to.
The big issue I have is really Equals and ToString. Those are methods that
are used fairly often. Another issue is the == operator. You would have to
control the constness of an == operation(there is no real limitation,
although its expected to not modify objects, operator==(const a, const b)
const would be ideal, but having to implement it everywhere wouldn't be), or
you would have to peform a cast for equality checks. This is one of the risk
points, a language that doesn't support const could provide an == operator
that accepts const by convention(all == operator args are implicitly const),
but ignores it because the language allows it to, that could circumvent
constness. Becuase of this, you could get some *really* weird and unexpected
bugs. If teh runtime performed checking itself it would *really* help.
Anyway, point is, if the simplist tenents of the language are going to
require casting, the design is probably flawed and needs to be redone.

I also feel it would be a great disservice to not include the BCL, while
little languages are probably marginal, its really unrealistic to believe
that VB, MC++, and perhaps a few others(Delphi, etc) are not important for
interoperability and compatibility. If only C# supports full const-ness, the
domain where const is vaild diminishes, and as much as some people want to
believe it, its not a homogeneous C# world.
Beyond that, having to cast simply to use a method on object is BS, IMHO.
Those methods should be available on *EVERY* type, const or not const(they
are all const methods, effectivly). I do not wish to have to cast then, it
starts to make using C# a burden and would probably reduce the usage of
const dramatically.
In my opinion the existing and well known syntax should be used. C# has gone
that route so far. I see no reason to change that.

I don't really like it, but it is probably something that can't be changed.
My main reason is it isn't a pleasent syntax and sometimes you have to let
convention go, thats the point of new languages isn't it? I find prefixes
harder to read and easier to mistake, as well as disrupting to my flow of
reading. I consider const an adjective, a descriptor, something that should
go *before* the method(just as virtual, public, etc go), unlike where or
throws, which are constraints and should go after. In my view its a hack to
allow both returning and marking a method as const, not a particularly
eloquent syntax.
however, something like
public const string const Method(); isn't particularly attractive either.
a cleaner syntax may be
[Constant]
public const string Method();

however, to people not familiar with C++, that will suggest that Method is
const, not string. That is an issue I have as well, public const string
certainly looks like its making the Method const, not the return type. Its
just a quirk I don't like, even though I know what it does. Also, two word
type names are not very common in C#. Instead of unsigned int or whatever,
it is uint, ulong. I really don't think it fits into the C# model that well.
While
public const string x;
and
public void Method(const string x);

work with the model
publc const string method() doesn't so well, in that case it seems much more
like a type or Method modifier than a return value modifier.

Again, I doubt many will agree with me. I just don't think that because C++
does it means its nessecerily right.
I don't see that this needs to be a problem. Const is a a compile time
thing. Couldn't it be implemented using assembly metadata? So that it
simply isn't visible at all to languages that doesn't support it? Or it
might even be possible to have const enforced at runtime when assemblies
using const are used from languages that don't support const and vice versa.

If it can be enforced at runtime a developer has to be aware of const, the
language has to support it in some fashion. If it isn't enforced, you could
get a class that claims const but, because it was developed in a const-less
language really isn't. In that case I imagine you wouldn't be pleased when
your object state started changing in const methods. However, due to the
point that the BCL really needs const-ness to make it truly effective,
instead of a burden, it would mean that you couldn't trust const without
examing the source, which in a sense defeats the point. All CLS languages
would atleast have to respect constness, if not provide a way to create
const references of your own.
 
D

Daniel O'Connell [C# MVP]

Frans Bouma said:
That's not the point. If you write a tool which accepts plugins,
and you want to offer these plugins access to internal contained data but
some data is readonly and other data is not, you can only achieve that by
copying to be readonly data into dummy objects so altering the data has no
effect. With const, this would have been easier.

That's not to say the plugin can't alter the data if it wants to,
however teh tool developer has provided a solid interface which in theory
is correct. The fact that custom objects then are passed to CLR methods
which want to alter them (which is not that common though) and which then
would cause trouble with respect to the const aspect of these objects, is
not important as the developer passing the const objects is in violation.
You can see that as 'limitation' but it's a limitation initiated by the
developer who created the code which produced the object that is const.

I just want to protect the objects exposed to other code from being
altered in given situations and I can now only do that by creating an
immense big pile of copy code and that's no picknick.


Agreed, but that's not reality, so this will not alter anything of
the current situation :) I also simply don't understand why generics
aren't introduced in the first CLR, after all, generics are around for
decades.


I don't see why not. It's compiler sugar. C++'s const can be
compiled into C code, a language which doesn't contain const. I don't see
why ToString() has any importance in this though. :) It doesn't alter
anything, it just transfers a value to a string format which is returned,
the actual value isn't altered.

Thats the point, ToString() is *NOT* const, its a non-const method. Meaning
you would haveto cast const-ness away to use it. Thats the annoyance I'm
trying to get at.
While I agree is compiler sugar, I just think its next to useless if it is
only applicable in one language out of many that *could* source the code.
Exposing it as a bit of metadata markup is one thing, you actually could
write static tools to verify this if you were enterprising enough, but
really integrating it into the language and the runtime is something else. I
don't feel that its proper to just start cramming things in as "compiler
sugar" at this point. I would rather see a clean, well thought out
implementation in V5 instead of a hacked, half-assed one in V3. Remeber,
once it goes in, it can never come back out.
A mechanism to attach attributes to instances(a way to track a const that
has been cast out of constness for a period as const) as well as CLS and BCL
support for const-ness would really be a nicer solution than just having a
C# developer *hope* that the const attribute applied to X is valid, and not
just some silly J# twit applying an attribute to non-const code.
Even as a plugin point, do you really want to limit your plugins to C#?
 
M

Magnus Lidbom

Frans Bouma said:
Following one paradigm, the instance contains the mapping material,
so it doesn't have to consult any other object to get its stuff persisted.
Although the mapping info is generated into the code, it is inserted via
constructors in the instance. I admit that this is a bit redundant, that's
also why the other paradigm is offered using a central repository for
mapping info, which means that the entity instances do not contain any
mapping info. In normal usage, this is not a problem though. I do not
consider an object graph of 4 million objects 'normal'.
Not the typical case. But certainly one I'd expect to have no problem at all
with for objects such as those I assume you're referring to.
if you want to store it physically into a variable, it has to.
Why not use a static field for this and an instance field only for when the
default mapping is overridden?

Ok, that's also the case here, I was talking about the mapping info
for the entity fields, like Customer's fields: CustomerID, ContactName
etc.
I'm not sure I understand you. The fields in the above class are entity
fields. At least by my, context dependent, definitions of entity. Namely a
mapped class.

Well, if memory limitations are not an issue (the average asp.net
webapplication is not bogged down by millions of entity objects and their
mapping info for example)
Bogged down by some 12-100MB of memory usage? I really don't see why. And
that's assuming a _very_ high number of concurrent users and a _very_ high
number of different objects for which access levels need to be defined.
Unless the server actually runs out of memory, memory consumption should
have very little impact on performance. Assuming such a load as discussed,
what would you say would happen to performance if the information was read
from the database for each request instead of cached?
you can create a fetch query from the info
directly available in the entity's field objects. If you don't have that,
you have to look up the mapping information for each field. It then
depends on how you've stored your mapping information to make this read is
fast. With mapping info inside the entity, you don't have that.
At worst the cost is a single lookup in a hashtable the size of which is the
number of mapped classes in the project. This is done once for an instance,
not for each field, and only when fetching or persisting single instances.
In other cases it's better optimized.
It's of course also depending on how the entity classes should look
like: abstract base classes with entity field objects or a totally
different approach: clean, developer supplied classes which can only be
filled through reflection for example.
At the moment it's the clean approach with an unfortunate need for minimal
custom code when you want lazy loading:

class User
{
private User m_manager;
public User Manager
{
get
{
MappingUtil.EnsureMember(typeof(User), "m_manager");
return m_manager;
}
}
}


This need will be eliminated soon, unfortunately at the cost of requiring
the properties to be virtual(The current way will remain for those situation
where complete control is necessary or just preferred.). I'll also be
adding support for the abstract class approach soon. Mixing the two
approaches will be supported, right down to abstract and concrete properties
in the same class. Unless of course I'm missing something that will shoot
that idea down :)

multiple queries generated from a single entity instance: they will
be slower if you have to determine the mapping info each time you are
generating the query.
I don't see why you would need to. Surely static fields could hold the
information for the vast majority of cases? For the runtime remapping case
you could fetch the information once and reuse it for the lifetime of the
instance or remapping. This would require an added instance size of 4 bytes
only.

However, it depends also on how you designed your total framework.
Speed won can be lost in other areas like the CLR has to copy bigger
chunks of memory around, etc.


In relation to the data the entity contains in general. Mapping
info is nothing more than a couple of strings and some ints.
And in my case a number of instances of reflection emit generated classes
allowing access to the instances fields. These classes were some 200 times
faster than using FieldInfo for protected fields and 20 times for public
when I last measured(.net 1.0), so I'd say they're essential. They are very
small, but they do add to the total.

<snip>

/Magnus Lidbom
 
M

Magnus Lidbom

Daniel O'Connell said:
If it can be enforced at runtime a developer has to be aware of const, the
language has to support it in some fashion. If it isn't enforced, you could
get a class that claims const but, because it was developed in a const-less
language really isn't. In that case I imagine you wouldn't be pleased when
your object state started changing in const methods. However, due to the
point that the BCL really needs const-ness to make it truly effective,
instead of a burden, it would mean that you couldn't trust const without
examing the source, which in a sense defeats the point. All CLS languages
would atleast have to respect constness, if not provide a way to create
const references of your own.

<snip>

Hmm, I should have run further with the assembly metadata idea. There should
be no need for runtime support. Const correctness could be enforced by a
post compile check at the IL level for non-supporting languages. No extra
work would be necccessary for the compilers for these languages beyond
invoking the check upon completion and mapping errors back to reasonably
sensible messages. Should these compilers fail to do so the problem would
be caught by the jit compiler.

Anyone know a reason why this wouldn't work?

/Magnus Lidbom
 
D

Daniel O'Connell [C# MVP]

Magnus Lidbom said:
<snip>

Hmm, I should have run further with the assembly metadata idea. There should
be no need for runtime support. Const correctness could be enforced by a
post compile check at the IL level for non-supporting languages. No extra
work would be necccessary for the compilers for these languages beyond
invoking the check upon completion and mapping errors back to reasonably
sensible messages. Should these compilers fail to do so the problem would
be caught by the jit compiler.

The main issue is that you can't apply an attribute to a variable, only to
fields, etc. Which means only class members can have const specified, not
specific fields. To achieve const you need to be able to attach the data to
a particular variable, which requires compiletime supoprt
 
M

Magnus Lidbom

Daniel O'Connell said:
Magnus Lidbom said:
Daniel O'Connell said:
message
"Daniel O'Connell [C# MVP]" <[email protected]>
wrote
in

Hmm, I should have run further with the assembly metadata idea. There should
be no need for runtime support. Const correctness could be enforced by a
post compile check at the IL level for non-supporting languages. No extra
work would be necccessary for the compilers for these languages beyond
invoking the check upon completion and mapping errors back to reasonably
sensible messages. Should these compilers fail to do so the problem would
be caught by the jit compiler.

The main issue is that you can't apply an attribute to a variable, only to
fields, etc. Which means only class members can have const specified, not
specific fields. To achieve const you need to be able to attach the data
to
a particular variable, which requires compiletime supoprt
Yes, but that would only need to be done when compiling the languages that
do support const since the others can't create their own const references.
Validating use for other languages could be done in a post compile step or
by some sort of plugin for the existing compiler. Don't most languages
compilers use reflection emit to create IL? If that's universal, plugging in
const checking there should do the trick shouldn't it?


Regards /Magnus Lidbom
 
D

Daniel O'Connell [C# MVP]

Magnus Lidbom said:
Yes, but that would only need to be done when compiling the languages that
do support const since the others can't create their own const references.
Validating use for other languages could be done in a post compile step or
by some sort of plugin for the existing compiler. Don't most languages
compilers use reflection emit to create IL? If that's universal, plugging in
const checking there should do the trick shouldn't it?
Well, I don't know about most compilers, the Mono C# compiler does for sure.
Plugging const into the runtime(both reflection emit and whatever else it
takes, perhaps the ref table) would be nessecery. I'm not sure of *how* to
plug it in, perhaps the experimental Rotor mod that adds const would have
more information on that.
It may be possible, just perhaps a good bit of work(tracking references
could be tricky).
 
M

Magnus Lidbom

Daniel O'Connell said:
Magnus Lidbom said:
Daniel O'Connell said:
message

"Daniel O'Connell [C# MVP]" <[email protected]>
wrote
in
message
in

Hmm, I should have run further with the assembly metadata idea. There
should
be no need for runtime support. Const correctness could be enforced
by
only
to
Yes, but that would only need to be done when compiling the languages that
do support const since the others can't create their own const references.
Validating use for other languages could be done in a post compile step or
by some sort of plugin for the existing compiler. Don't most languages
compilers use reflection emit to create IL? If that's universal,
plugging
in
const checking there should do the trick shouldn't it?
Well, I don't know about most compilers, the Mono C# compiler does for sure.
Plugging const into the runtime(both reflection emit and whatever else it
takes, perhaps the ref table) would be nessecery. I'm not sure of *how* to
plug it in, perhaps the experimental Rotor mod that adds const would have
more information on that.
It may be possible, just perhaps a good bit of work(tracking references
could be tricky).
It would hardly be the first task for the those components that took time or
was tricky though :)

The reason I'm pursuing this is that I seem to remember language
interoperability being quoted as the scale tipping reason for leaving const
out of the language. In my opinion, that argument fails if const correctness
checking can be supplied for any language by modifying reflection emit, or
by supplying a common IL validator. Wait a sec now, thats ilasm.exe for
crying out loud :)

Regards /Magnus Lidbom
 
D

Daniel O'Connell [C# MVP]

Magnus Lidbom said:
Daniel O'Connell said:
Magnus Lidbom said:
message

message

in
message
"Daniel O'Connell [C# MVP]"
wrote
in


<snip>

Hmm, I should have run further with the assembly metadata idea. There
should
be no need for runtime support. Const correctness could be
enforced
by only specified,
not
step
or plugging
Well, I don't know about most compilers, the Mono C# compiler does for sure.
Plugging const into the runtime(both reflection emit and whatever else it
takes, perhaps the ref table) would be nessecery. I'm not sure of *how* to
plug it in, perhaps the experimental Rotor mod that adds const would have
more information on that.
It may be possible, just perhaps a good bit of work(tracking references
could be tricky).
It would hardly be the first task for the those components that took time or
was tricky though :)

The reason I'm pursuing this is that I seem to remember language
interoperability being quoted as the scale tipping reason for leaving const
out of the language. In my opinion, that argument fails if const correctness
checking can be supplied for any language by modifying reflection emit, or
by supplying a common IL validator. Wait a sec now, thats ilasm.exe for
crying out loud :)
Hehe, sorry, I misread your post. I thought you were propsing a tool to
determine const behavior *now*.
The language issue does exist, though a common, standardized verification
interface for compilers would go a long way. Instead of forcing a compiler
to behave just allow all compilers to accept the same rules\plugins....
 
M

Magnus Lidbom

Daniel O'Connell said:
Magnus Lidbom said:
Daniel O'Connell said:
message

"Daniel O'Connell [C# MVP]" <[email protected]>
wrote
in
message

in
message
"Daniel O'Connell [C# MVP]"
The reason I'm pursuing this is that I seem to remember language
interoperability being quoted as the scale tipping reason for leaving const
out of the language. In my opinion, that argument fails if const correctness
checking can be supplied for any language by modifying reflection emit, or
by supplying a common IL validator. Wait a sec now, thats ilasm.exe for
crying out loud :)
Hehe, sorry, I misread your post. I thought you were propsing a tool to
determine const behavior *now*.

Oh. I don't think I'd care to attempt that :)
The language issue does exist, though a common, standardized verification
interface for compilers would go a long way. Instead of forcing a compiler
to behave just allow all compilers to accept the same rules\plugins....

Exactly. Unless there are stumbling blocks I'm not seeing the
interoperability issue should be a relatively minor one. Such an
implementation might also greatly simplify the migration of the BCL and
other existing code to a const correct state. A compiler flag could be used
to disable the compilers own support for checking const correctness and
delegating it to the generic validator. Since this validator would examine
actual usage of references, not declarations of references , it would allow
for the gradual introduction of const correctness in existing code without
any intermediate code breaking what so ever! Coder error barred of course.
Such a switch seems to me to counter every problem with introducing const
that you've brought up so far.

Am I missing anything?
Anyone have a reason why this wouldn't work?

Regards /Magnus Lidbom
 

Ask a Question

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

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

Ask a Question

Similar Threads

CSharp Coding Standards 18

Top