hey pete...inline...
> > I have to say I think that lambda functions are incredible. Although a
> > little disconcerting at first I think they really unclutter code and are
[quoted text clipped - 12 lines]
> but at least there's a genuine balancing benefit. I don't see what the
> benefit for a static extension method would be.
> > 2. return by reference! - you can pass in by ref why not return by ref
>
> What point would there be in returning "by ref"? To what would the
> reference refer? So far the only thing I've seen you suggest as a benefit
> is performance, and I don't believe that you'd gain any appreciable
> performance by allowing returning value types by reference.
> > 3. automatic properties that create...
>
[quoted text clipped - 6 lines]
> and who knows? Maybe you'll get your wish eventually. But I don't see
> that as being something the language should be implementing itself.
> > 4. DateTime that stores in utc (DateTimeUTC)
> > - the problem with the DateTimeOffset class is it uses two fields
[quoted text clipped - 7 lines]
>
> Pete
>> Extension methods as they are happen to be potentially misleading as
>> well,
>> but at least there's a genuine balancing benefit. I don't see what the
>> benefit for a static extension method would be.
>
> the benefit would be exactly the same benefit of an instance extension.
That's a trivially false statement. Given that a primary benefit of
instance extensions is to be able to implicitly call a static method that
takes an instance of a particular type on an instance of an object of that
type, obviously a "static extension" would not be "exactly the same".
> extension methods alleviate the million helper classes that non-trivial
> apps
> tend to have.
Huh? You don't get rid of the helper classes. They're still there. You
just don't have to type the name of them explicitly when you use them.
And since a static extension would still require you to type the name of
_some_ class, why not just type the name of the class where the method is
really defined?
> i think saying you can't see a reason for them and therefore shouldn't
> have
> them is ridiculous.
Well, when you provide an actual example of how a static extension would
be useful, I might change my mind. But I think it's ridiculous for you to
insist that I agree with you before you've proven your point.
I don't mind having my mind changed by a strong argument, but you have to
present that argument first.
> why not let the individual developer decide if there is
> not a valid reason to omit them? why polute the namespace with a bunch
> of
> other types when they should be grouped accordingly.
The namespace is already "polluted", even with instance extensions. You
just don't have to type the class name. But it's still there. So that's
not a valid argument in favor of a static extension.
What's left? Making the static method look like it belongs to some other
class (the one you're extending). What's the point of making a static
method look like it belongs to some other class? Other than the name you
type, it will behave _exactly_ as it would if you just used it from your
own class.
With an instance extension, you can really create code that makes it look
like you've added a method to an instance of a given object, and that can
clean up the code a lot. But with a static extension, all you can do is
swap one name for another. How is that useful? Why does it matter to you
so much which exact letters you type when calling a method?
As far as "return by reference" goes...
>> What point would there be in returning "by ref"? To what would the
>> reference refer? So far the only thing I've seen you suggest as a
[quoted text clipped - 3 lines]
>
> to not make a copy of the object is the point of returning by ref.
But that's impossible to do with a value type. C# has no syntax for
referring to value types as if they were referenced. Where would that "no
copy of the object" come from? The run-time would essentially have to box
the object, and then provide some sort of new semantic that allows the use
of the object without unboxing it.
But C# already has a semantic for using an object without unboxing it.
It's called reference types. And if you need to use a type in that way,
then a reference type is what you should be using.
In any case, even if you somehow managed to get a "return by reference"
into the language, you'd have to make sweeping changes to the rest of the
language (and likely the run-time) in order to support that change. As
things stand now, if it's a value type, you can't use it without making a
copy of it. This would be true even if you somehow managed to return a
reference to a copy of it.
> it would
> refer to the object. there are really two benefits to being able to
> return
> by reference and that is exposing a value type by property.
What does that mean? What does "exposing a value type by property" mean?
I know what the individual words mean, but put together like that they
don't convey any useful information to me.
> that is enough
> in itself but a more important reason is performance. there's no
> appreciable
> gain by returning a 4/8 byte pointer rather than a 200 byte object???
If you have an object that's (for example) 200 bytes, it doesn't really
belong in a struct in the first place. You're trying to fix broken code
by breaking something else, rather than just fixing the broken code.
Then, we have your "lazily instantiated" properties...
> well theres a reason why automatic properties were introduced and that
> is to
> reduce boilerplate code.
Let's be clear: it reduces boilerplate code >> that is used on a
remarkably common basis << .
> however they really are only useful on primitive
> types and tightly controlled scenarios.
How so? They are useful in _any_ situation in which you have a property
that is simply a getter and/or setter for some field. That works with any
type, not just primitives, and it hardly requires that the scenario is
"tightly controlled".
> when you find yourself writing the
> same code a hundred zillion times (as im sure others have also) then its
> time
> for a built-in feature (or a way to create one yourself).
If you are writing this sort of "lazily instaniated" property "a hundred
zillion times", you are in a completely unique situation and not one that
justifies a whole new language feature just to support your own personal
problem.
Suffice to say, most programmers write entire applications without ever
having to lazily initialize a field behind a property, and even those that
do only have to do for a handful of properties at most. And even _then_,
in many of those situations a parameterless constructor isn't sufficient
(and may not even be available).
If this sort of thing applies in the vast majority of your code, you have
very unusual code. You might want to look into the "code snippet" feature
of Visual Studio, but otherwise your own needs do not in any way suggest a
need for a new language feature. In the broader scheme of things, code
that does what you're talking about is extremely rare.
> anyone miss macros?
Nope, not really.
> Yes I believe I said c#/cli features just for this case! The problem, as
> i'm sure others have run into many times, is that when you write an app
[quoted text clipped - 3 lines]
> value and transmit in utc then interpret for display in the current
> timezone.
So? Then do that. Store the data as UTC (which you can do) and then
convert to the local timezone for display (which you can also do). The
latest .NET even provides direct support for converting to timezones other
than the local one (which admittedly was a significant failing in previous
versions).
What feature are you looking for here that doesn't already exist?
Pete
Ben Voigt [C++ MVP] - 19 Mar 2008 16:55 GMT
> As far as "return by reference" goes...
>
[quoted text clipped - 8 lines]
> But that's impossible to do with a value type. C# has no syntax for
> referring to value types as if they were referenced. Where would
Yes it does. Pointers.
> that "no copy of the object" come from? The run-time would
> essentially have to box the object, and then provide some sort of new
> semantic that allows the use of the object without unboxing it.
Why would it have to box the object? It could simply use a pointer
internally, just like it does for reference parameters and reference types.
Creating references to stack variables could be forbidden to enhance type
safety (even though for example a reference to a ref parameter is guaranteed
to still be valid in your caller's context, that isn't transitively true).
Peter Duniho - 19 Mar 2008 19:09 GMT
>> But that's impossible to do with a value type. C# has no syntax for
>> referring to value types as if they were referenced. Where would
>
> Yes it does. Pointers.
Relevant only for unsafe code and that exists today. We are talking here
about a new feature in C#. It's true that you could implement something
like it using unsafe code in C# now, but if you're going to raise that as
somehow relevant, then the OP's complaint that what he wants to do is
unsupported is wrong from the outset.
Personally, I took it as granted that he's not looking for a solution that
involves unsafe code. Since you didn't offer the use of a pointer as a
return type as a solution to his original question, it seems to me that
you did too. So I am wondering what the point of your reply to my post
here is.
> Why would it have to box the object? It could simply use a pointer
> internally, just like it does for reference parameters and reference
> types.
It would have to box it because that's the semantics of a value type. C#
currently provides the guarantee that an instance of a value type cannot
be changed except through direct access or passing by reference as a
parameter.
To support the OP's request, either the value type needs to be boxed so
that it can be changed without affecting the original storage, or C# has
to treat the reference to the value type as read-only (which could negate
the whole point of returning a mutable struct by reference).
Pete
Ben Voigt [C++ MVP] - 19 Mar 2008 20:34 GMT
>>> But that's impossible to do with a value type. C# has no syntax for
>>> referring to value types as if they were referenced. Where would
[quoted text clipped - 12 lines]
> seems to me that you did too. So I am wondering what the point of
> your reply to my post here is.
A reference would not be unsafe, because it is a pointer with the unsafe
operations removed.
It cannot be created from a different pointer type or an integer.
It cannot be used in pointer arithmetic.
I'd actually prefer changing the rules for pointers so that only those two
operations need unsafe blocks, and creation/dereference of pointers to value
types on the heap can be used anywhere. But that's much more likely to be a
breaking change rather than a new feature.
>> Why would it have to box the object? It could simply use a pointer
>> internally, just like it does for reference parameters and reference
[quoted text clipped - 4 lines]
> cannot be changed except through direct access or passing by
> reference as a parameter.
And this would simply extend the case of reference parameters.
The fact that __makeref even exists suggests that it's doesn't conflict with
C# semantics in any way, it just isn't included in the standard.
Peter Duniho - 19 Mar 2008 23:42 GMT
> A reference would not be unsafe, because it is a pointer with the unsafe
> operations removed.
You wrote "pointers". I responded with comments about "pointers". Why
does "a reference would not be unsafe" have any relevance here? We were
talking about pointers, not references.
> [...]
> The fact that __makeref even exists suggests that it's doesn't conflict
> with
> C# semantics in any way, it just isn't included in the standard.
Huh? I would argue the exact opposite. The fact that __makeref exists
but isn't actually part of the language suggests that it _does_ conflict
with C# semantics and that's why it's not included in the standard.
Pete
Ben Voigt [C++ MVP] - 21 Mar 2008 15:06 GMT
>> A reference would not be unsafe, because it is a pointer with the
>> unsafe operations removed.
>
> You wrote "pointers". I responded with comments about "pointers". Why
> does "a reference would not be unsafe" have any relevance here? We were
> talking about pointers, not references.
We were talking about whether the existing feature "pointers" satisfy the
need for returning a reference to a value type instance on the heap. They
do not, because they are rejected outside of unsafe code blocks.
>> [...]
>> The fact that __makeref even exists suggests that it's doesn't
[quoted text clipped - 5 lines]
> _does_ conflict with C# semantics and that's why it's not included in
> the standard.
The fact that garbage collection does exist, but isn't actually part of the
Win32 API suggests that it does conflict with Win32 semantics!
That's a very nonsensical line of reasoning. Most current parts of C++, for
example, first started out as extensions and later were added to the
standard.
> Pete
Peter Duniho - 21 Mar 2008 17:51 GMT
>>> A reference would not be unsafe, because it is a pointer with the
>>> unsafe operations removed.
[quoted text clipped - 7 lines]
> They
> do not, because they are rejected outside of unsafe code blocks.
So now you are agreeing with me. Thank you.
>> Huh? I would argue the exact opposite. The fact that __makeref
>> exists but isn't actually part of the language suggests that it
[quoted text clipped - 4 lines]
> the
> Win32 API suggests that it does conflict with Win32 semantics!
Yes. I don't see anything wrong with that statement. The Win32 API is a
specific API and doesn't take into account garbage collection at all. In
fact, the main reason we have IDisposable and finalizers is that garbage
collection and the Win32 API do not otherwise "get along with each other".
> That's a very nonsensical line of reasoning. Most current parts of C++,
> for
> example, first started out as extensions and later were added to the
> standard.
I realize that for you, C++ may seem like the pinnacle of language
design. Suffice to say, I see C++ differently and just because C++ does
something, that doesn't imply to me that it results in an semantically
consistent language. You can call my line of reasoning "nonsensical" all
you want, it doesn't make you right.
Pete
Ben Voigt [C++ MVP] - 21 Mar 2008 19:00 GMT
>>>> A reference would not be unsafe, because it is a pointer with the
>>>> unsafe operations removed.
[quoted text clipped - 9 lines]
>
> So now you are agreeing with me. Thank you.
I thought you were saying that return by reference isn't needed.
I'm championing the opposite, that pointers aren't good enough so we need
return by reference. You say, make it a reference type. That's really the
problem, .NET forces you to choose between value and reference semantics in
the type declaration, which is a bad architecture. Maybe 99% of the time
value semantics are desired, placing the object inside its container is
desirable for locality of reference, and it doesn't need to be independently
garbage collected. Seems to me that demands a .NET value type. But now for
the 1% of uses which require return by reference, you're going to change the
behavior of every user of that type.
>>> Huh? I would argue the exact opposite. The fact that __makeref
>>> exists but isn't actually part of the language suggests that it
[quoted text clipped - 10 lines]
> that garbage collection and the Win32 API do not otherwise "get along
> with each other".
That's "different", not a conflict.
If there was a conflict, .NET couldn't exist.
And, __makeref IS part of the language. It's not part of the international
standard though.
>> That's a very nonsensical line of reasoning. Most current parts of
>> C++, for
[quoted text clipped - 5 lines]
> does something, that doesn't imply to me that it results in an
> semantically consistent language. You can call my line of reasoning
There a difference between "inconsistent" and "conflict". "Conflict"
suggests, to me at least, that there can be no coexistance, which certainly
is not the case here.
> "nonsensical" all you want, it doesn't make you right.
>
> Pete
Peter Duniho - 21 Mar 2008 19:58 GMT
> I thought you were saying that return by reference isn't needed.
No. Well, personally I don't see it as being a big deal. In that sense,
I don't really think it's needed.
But no, that's not what I was saying. I was just saying that as C# stands
today, it doesn't really provide that functionality.
> I'm championing the opposite, that pointers aren't good enough so we need
> return by reference.
I agree that pointers aren't good enough to address the question. I don't
really think it's strictly necessary to add return by reference.
IMHO it's a philosophical difference, and it's one that I think comes up
between you and me on a regular basis. One of the reasons I love C# so
much is its simplicity. It's true, there are lots of things you can do in
a more "powerful" language like C++ that aren't exactly duplicated in C#.
But IMHO you can always achieve basically the same results, and in a much
simpler context.
Some engineers like complicated design, some like simple design. I'm in
the latter camp, in that I find the simplicity leads to architectures that
are easier to design correctly and reliably. IMHO, introducing a "return
by reference" semantic would not be in keeping with the existing semantics
in C# and would unnecessarily complicate the language.
You obviously disagree, as does the OP. But you are both free to use a
different language, one that does support what you'd like to do. Why
invest effort in messing up C# for those of us that appreciate its
simplicity?
> You say, make it a reference type. That's really the
> problem, .NET forces you to choose between value and reference semantics
[quoted text clipped - 8 lines]
> the
> behavior of every user of that type.
Well, I disagree with that perspective. There's a fundamental difference
between value types and reference types in C#, and this difference is
preserved by the current restriction in the language wrt return types, and
would not be if methods could return value types "by reference". I
disagree that it's bad architecture for the type itself to determine
whether value or reference semantics are appropriate.
I'm not going to try to argue that it's _superior_ architecture, but I
will vehemently disagree that it's de facto a bad choice for the
language. It's simply a design choice, and a valid one at that. You may
not like it, but there's no shortage of other languages to choose from in
which you aren't so constrained.
> [...]
>> Yes. I don't see anything wrong with that statement. The Win32 API
[quoted text clipped - 6 lines]
>
> If there was a conflict, .NET couldn't exist.
I guess that depends on whether you feel the word "conflict" implies lack
of resolution. I don't. You seem to.
> And, __makeref IS part of the language. It's not part of the
> international
> standard though.
I have no idea what that means. If it's not part of the standard, how is
it part of "the language"? I can write a C++ compiler to include whatever
non-standard elements I want. Microsoft has in fact done so repeatedly.
That doesn't mean those elements are part of "the language". They are
just non-standard additions.
Pete