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

C# Language Proposal for 'out' Parameters

P: n/a
Note
----

Please use a fixed-width font to view this, such as Courier New.

Problem
-------

When passing a parameter with the modifier 'out', it is necessary to
write two statements:

- one for the declaration of the variable due to receive the value; and
- one for the method call, where the variable is passed as a parameter.

Example:

static void Main()
{
int i;
if (TryGetValue(out i)) {
Console.WriteLine("Value is: {0}.", i);
}
}

This is inconsistent with the traditional way of returning values from a
method.

Example:

static void Main()
{
int i = GetValue();
Console.WriteLine("Value is: {0}.", i);
}

Solution
--------

The solution to this problem would be to allow the declaration of the
variable to appear within the statment where it's being passed as an
'out' parameter.

Example:

static void Main()
{
if (TryGetValue(out int i)) {
Console.WriteLine("Value is: {0}.", i);
}
}

Benefits
--------

(a) Method bodies can benefit from one less statement for each time this
technique is used, promoting readability.

(b) C# becomes more consistent since returning values using both the
traditional way, and using 'out' parameters, is uniform. Again,
this promotes readability.

Example:

// traditional way
static void Main()
{
int i = GetANumber();
DoSomethingWith(i);
}

// using an 'out' parameter, with the aforementioned syntax
static void Main()
{
if (TryGetANumber(out int i)) {
DoSomethingWith(i);
}
}

End
---

Comments?

Regards,
C. S. Learner
Nov 16 '05 #1
Share this Question
Share on Google+
33 Replies


P: n/a
I have a better proposal for ref and out:

instead of using "pass by reference" semantics, why not use
"copyin/copyout" semantics for "ref" and "copyout"semantics for "out".

This way, you would not need to declare a variable every time. In lots of
cases, you would be able to receive the value directly into an object
property. For example:

if (TryGetValue(myObj.MyProp))
{
// doSomething
}

This would be equivalent (almost) to the following that you have to write
today:

int i;
if (TryGetValue(out i))
{
myObj.MyProp = i;
}

For a "ref" (in/out) parameter, the gain is even more obvious. It would save
both the assignment from the property to a temp variable before the call,
and the reverse assignment after the call.

Also, I understand why "ref" and "out" are needed in the method declaration,
but it seems superfluous to have to specify them at every call.

The last refinement would be to have normal parameters (no keyword, "in"
semantics) be "readonly" inside the method body (you can do this in Java by
marking them with "final"). Of course this is probably too far fetched as it
goes against the C/C++/Java tradition, but IMO, this is so much cleaner and
would make the language easier to understand to beginners (for once,
mimicking Pascal or ADA rather than C++ would help).

Just some ideas...

Bruno.

"C# Learner" <cs****@learner.here> a écrit dans le message de
news:ew**************@TK2MSFTNGP10.phx.gbl...
Note
----

Please use a fixed-width font to view this, such as Courier New.

Problem
-------

When passing a parameter with the modifier 'out', it is necessary to
write two statements:

- one for the declaration of the variable due to receive the value; and
- one for the method call, where the variable is passed as a parameter.

Example:

static void Main()
{
int i;
if (TryGetValue(out i)) {
Console.WriteLine("Value is: {0}.", i);
}
}

This is inconsistent with the traditional way of returning values from a
method.

Example:

static void Main()
{
int i = GetValue();
Console.WriteLine("Value is: {0}.", i);
}

Solution
--------

The solution to this problem would be to allow the declaration of the
variable to appear within the statment where it's being passed as an
'out' parameter.

Example:

static void Main()
{
if (TryGetValue(out int i)) {
Console.WriteLine("Value is: {0}.", i);
}
}

Benefits
--------

(a) Method bodies can benefit from one less statement for each time this
technique is used, promoting readability.

(b) C# becomes more consistent since returning values using both the
traditional way, and using 'out' parameters, is uniform. Again,
this promotes readability.

Example:

// traditional way
static void Main()
{
int i = GetANumber();
DoSomethingWith(i);
}

// using an 'out' parameter, with the aforementioned syntax
static void Main()
{
if (TryGetANumber(out int i)) {
DoSomethingWith(i);
}
}

End
---

Comments?

Regards,
C. S. Learner

Nov 16 '05 #2

P: n/a
"C# Learner" <cs****@learner.here> wrote:
[proposed new syntax]
if (TryGetValue(out int i))


I'd appreciate that. It seems no more problematic than being able to declare
a loop counter variable within a for statement.

P.
Nov 16 '05 #3

P: n/a
>Also, I understand why "ref" and "out" are needed in the method
declaration,
but it seems superfluous to have to specify them at every call. i think it makes the code more understandable, for example while debugging
you wont have to goto to see the method declaration to find out if the
parameter was a ref or out, instead you'll know right there and then from
the call what the methods accepts.

"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote in message
news:Oc**************@TK2MSFTNGP09.phx.gbl... I have a better proposal for ref and out:

instead of using "pass by reference" semantics, why not use
"copyin/copyout" semantics for "ref" and "copyout"semantics for "out".

This way, you would not need to declare a variable every time. In lots of
cases, you would be able to receive the value directly into an object
property. For example:

if (TryGetValue(myObj.MyProp))
{
// doSomething
}

This would be equivalent (almost) to the following that you have to write
today:

int i;
if (TryGetValue(out i))
{
myObj.MyProp = i;
}

For a "ref" (in/out) parameter, the gain is even more obvious. It would save both the assignment from the property to a temp variable before the call,
and the reverse assignment after the call.

Also, I understand why "ref" and "out" are needed in the method declaration, but it seems superfluous to have to specify them at every call.

The last refinement would be to have normal parameters (no keyword, "in"
semantics) be "readonly" inside the method body (you can do this in Java by marking them with "final"). Of course this is probably too far fetched as it goes against the C/C++/Java tradition, but IMO, this is so much cleaner and would make the language easier to understand to beginners (for once,
mimicking Pascal or ADA rather than C++ would help).

Just some ideas...

Bruno.

"C# Learner" <cs****@learner.here> a écrit dans le message de
news:ew**************@TK2MSFTNGP10.phx.gbl...
Note
----

Please use a fixed-width font to view this, such as Courier New.

Problem
-------

When passing a parameter with the modifier 'out', it is necessary to
write two statements:

- one for the declaration of the variable due to receive the value; and
- one for the method call, where the variable is passed as a parameter.

Example:

static void Main()
{
int i;
if (TryGetValue(out i)) {
Console.WriteLine("Value is: {0}.", i);
}
}

This is inconsistent with the traditional way of returning values from a
method.

Example:

static void Main()
{
int i = GetValue();
Console.WriteLine("Value is: {0}.", i);
}

Solution
--------

The solution to this problem would be to allow the declaration of the
variable to appear within the statment where it's being passed as an
'out' parameter.

Example:

static void Main()
{
if (TryGetValue(out int i)) {
Console.WriteLine("Value is: {0}.", i);
}
}

Benefits
--------

(a) Method bodies can benefit from one less statement for each time this
technique is used, promoting readability.

(b) C# becomes more consistent since returning values using both the
traditional way, and using 'out' parameters, is uniform. Again,
this promotes readability.

Example:

// traditional way
static void Main()
{
int i = GetANumber();
DoSomethingWith(i);
}

// using an 'out' parameter, with the aforementioned syntax
static void Main()
{
if (TryGetANumber(out int i)) {
DoSomethingWith(i);
}
}

End
---

Comments?

Regards,
C. S. Learner


Nov 16 '05 #4

P: n/a
"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote:
[...]
I understand why "ref" and "out" are needed in the
method declaration, but it seems superfluous to have
to specify them at every call.


I think it's good to be able to see which parameters might be changed
without having to examine the function being called.

P.
Nov 16 '05 #5

P: n/a
Bruno Jouhier [MVP] <bj******@club-internet.fr> wrote:
Also, I understand why "ref" and "out" are needed in the method declaration,
but it seems superfluous to have to specify them at every call.


Aargh no! It's absolutely *vital* to my mind that you should specify
them at every call - otherwise it's far from obvious, unless you look
at the declaration of what you're calling, that the parameter is being
passed by reference. I for one don't want to have to check the
declaration of every method which is called just in order to know
what's going on.

Ref/out are (or should be, IMO) rarely enough used that it's not like
it's going to take that many more keystrokes anyway, and the difference
in readability is huge.

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

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> skrev i meddelandet
news:MP************************@msnews.microsoft.c om...
Bruno Jouhier [MVP] <bj******@club-internet.fr> wrote:
Also, I understand why "ref" and "out" are needed in the method declaration, but it seems superfluous to have to specify them at every call.
Aargh no! It's absolutely *vital* to my mind that you should specify
them at every call - otherwise it's far from obvious, unless you look
at the declaration of what you're calling, that the parameter is being
passed by reference. I for one don't want to have to check the
declaration of every method which is called just in order to know
what's going on.

Ref/out are (or should be, IMO) rarely enough used that it's not like
it's going to take that many more keystrokes anyway, and the difference
in readability is huge.


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

Nov 16 '05 #7

P: n/a
>
(a) Method bodies can benefit from one less statement for each time this
technique is used, promoting readability.

(b) C# becomes more consistent since returning values using both the
traditional way, and using 'out' parameters, is uniform. Again,
this promotes readability.

Example:

// traditional way
static void Main()
{
int i = GetANumber();
DoSomethingWith(i);
}

// using an 'out' parameter, with the aforementioned syntax
static void Main()
{
if (TryGetANumber(out int i)) {
DoSomethingWith(i);
}
}

End
---

Comments?
The primary problem I have with this is in all othercases I can think of, a
variable declared within a () is scoped to the underlying block(method
parameters, for (int x) { //x is only valid here }, using (IDisposable x)
{ //x is only valid here }. By allowing declarations within a method call,
you remove that partciular consistence of the language. Regards,
C. S. Learner

Nov 16 '05 #8

P: n/a
Daniel O'Connell [C# MVP] wrote:
Comments?


The primary problem I have with this is in all othercases I can think of, a
variable declared within a () is scoped to the underlying block(method
parameters, for (int x) { //x is only valid here }, using (IDisposable x)
{ //x is only valid here }. By allowing declarations within a method call,
you remove that partciular consistence of the language.


Hmm, good point. Back to the drawing board then.
Nov 16 '05 #9

P: n/a

"C# Learner" <cs****@learner.here> wrote in message
news:ut**************@TK2MSFTNGP11.phx.gbl...
Daniel O'Connell [C# MVP] wrote:
Comments?


The primary problem I have with this is in all othercases I can think of,
a variable declared within a () is scoped to the underlying block(method
parameters, for (int x) { //x is only valid here }, using (IDisposable x)
{ //x is only valid here }. By allowing declarations within a method
call, you remove that partciular consistence of the language.


Hmm, good point. Back to the drawing board then.


You'll find yourself doing that *alot* when trying to get syntax down. The
first forty ideas or so rarely seem to work, ;)
Nov 16 '05 #10

P: n/a
Ok. Maybe the few additional keystrokes are worth it. At least many people
seem to react strongly here.

If I remember well, languages like Pascal and ADA support in/out parameters
and you only need to specify this in the function/procedure declaration, you
don't repeat it every time you call. Also, seems to me that the method name
or the parameter name should give a good hint about the in/out nature of the
parameter. This is why I suggested that they are not that useful on the
caller side.

Also, I still do most of my developments in Java (or rather J#). So, I still
have to fight with the lack of goodies like in/out parameters :-(. So you
guys probably know better.

But I think that the debate around "by reference" semantics vs.
"copyin/copyout" semantics is interesting, and I don't really understand why
the C# (or rather .NET) designers did not choose copyin/copyout. In general
they made very good language design choices, but here, I think that they
made a rather poor choice.

Bruno.

"Jon Skeet [C# MVP]" <sk***@pobox.com> a écrit dans le message de
news:MP************************@msnews.microsoft.c om...
Bruno Jouhier [MVP] <bj******@club-internet.fr> wrote:
Also, I understand why "ref" and "out" are needed in the method declaration, but it seems superfluous to have to specify them at every call.


Aargh no! It's absolutely *vital* to my mind that you should specify
them at every call - otherwise it's far from obvious, unless you look
at the declaration of what you're calling, that the parameter is being
passed by reference. I for one don't want to have to check the
declaration of every method which is called just in order to know
what's going on.

Ref/out are (or should be, IMO) rarely enough used that it's not like
it's going to take that many more keystrokes anyway, and the difference
in readability is huge.

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

Nov 16 '05 #11

P: n/a
Bruno Jouhier [MVP] <bj******@club-internet.fr> wrote:
Ok. Maybe the few additional keystrokes are worth it. At least many people
seem to react strongly here.

If I remember well, languages like Pascal and ADA support in/out parameters
and you only need to specify this in the function/procedure declaration, you
don't repeat it every time you call.
And C# has learned from the mistakes of the past :)
Also, seems to me that the method name
or the parameter name should give a good hint about the in/out nature of the
parameter. This is why I suggested that they are not that useful on the
caller side.
I don't believe it's always obvious, to be honest.
Also, I still do most of my developments in Java (or rather J#). So, I still
have to fight with the lack of goodies like in/out parameters :-(. So you
guys probably know better.
Personally I don't really regard ref and out parameters as "goodies".
They're necessary evils for interop, but I try to keep them out of my
code wherever possible. Then again, I have a Java background as well.
But I think that the debate around "by reference" semantics vs.
"copyin/copyout" semantics is interesting, and I don't really understand why
the C# (or rather .NET) designers did not choose copyin/copyout. In general
they made very good language design choices, but here, I think that they
made a rather poor choice.


I'm not sure I particularly mind that much - what are the benefits of
copyin/copyout, here?

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

P: n/a
> > But I think that the debate around "by reference" semantics vs.
"copyin/copyout" semantics is interesting, and I don't really understand why the C# (or rather .NET) designers did not choose copyin/copyout. In general they made very good language design choices, but here, I think that they
made a rather poor choice.


I'm not sure I particularly mind that much - what are the benefits of
copyin/copyout, here?


The main benefit of copyin/copyout is that you can pass any valid
assignement LHS as in/out argument. In particular, you can pass an object
property and indexed expression, etc. For example, instead of having to
write:

int val = obj.Prop;
if (GetNewValue(ref val)) {
obj.Prop = val;
// more stuff
}

You just need to write:

if (GetNewValue(inout obj.Prop)) {
// more stuff
}

This is more concise, easier to read, and just as efficient.

Bruno.
Nov 16 '05 #13

P: n/a

"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote in message
news:%2***************@TK2MSFTNGP12.phx.gbl...
> But I think that the debate around "by reference" semantics vs.
> "copyin/copyout" semantics is interesting, and I don't really
> understand why > the C# (or rather .NET) designers did not choose copyin/copyout. In general > they made very good language design choices, but here, I think that
> they
> made a rather poor choice.


I'm not sure I particularly mind that much - what are the benefits of
copyin/copyout, here?


The main benefit of copyin/copyout is that you can pass any valid
assignement LHS as in/out argument. In particular, you can pass an object
property and indexed expression, etc. For example, instead of having to
write:

int val = obj.Prop;
if (GetNewValue(ref val)) {
obj.Prop = val;
// more stuff
}

You just need to write:

if (GetNewValue(inout obj.Prop)) {
// more stuff
}

This is more concise, easier to read, and just as efficient.


Though, one may argue it basically provides the ability to do something that
you would probably never be able to justify doing. Passing a property(or a
field, even though its allowed) to a ref parameter is a very bad idea, IMHO.
If a non-essential method with a ref fails, the value of that ref is
undefined as far as I'm concerned. Allowing that to be extended to
properties is horrible. The syntactical changes that would be needed to
allow you to escape a method without performing the copy out is unpleasent.
Not providing any syntax in effect allows a failed method call to corrupt
the object's state and would make the exception\error handling code and the
code with the ref\out parameter have the nasty stuff instead of the standard
path. You can't just forget about the value of a property like you can with
a local, you have to take the time and back up the value if its at all
possible the method could fail.
You potentially end up with:
int val = obj.Prop
if (GetNewVal(inout obj.Prop))
{
//more stuff
}
else
{
obj.Prop = val;
}

or
int val = obj.Prop
try
{
GetNewVal(inout obj.Prop);
//more stuff
}
catch (WhateverException)
{
obj.Prop = val;
}
catch (WhateverOtherException)
{
obj.Prop = val;
}
catch (AnotherExceptionException)
{
//Again!
//makes me wish C# had fault handlers, I'd not have to write this so
much
obj.Prop = val;
}
finally
{
//do whatever
}

why is that better?
Nov 16 '05 #14

P: n/a
You got it wrong. There is no issue about corrupted state or anything like
that. Maybe you are confusing "copyin/copyout" with "passing by name".

The semantics of copyin/copyout are the following:

With a method declaration like:
MyMethod(inout MyType param)

A call like
MyMethod(inout expression);

is equivalent to:
MyType tmpVar = expression;
MyMethod(ref tmpVar);
expression = tmpVar;

This is actually cleaner than passing by reference because the inout
parameters behave exactly like return values (a ref parameter does not!). If
an exception is thrown by the method, the "copyout" assignment is **not**
performed and the expression is not assigned at all. So, I don't see where
there is a risk of corrupting the object state here. On the other hand, all
this seems very safe.

Passing "by name" is another story, and I would not advocate for it at all,
at least as a general passing mechanism. It has horrible side effects.

Bruno.

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> a écrit dans le
message de news:Oc*************@TK2MSFTNGP12.phx.gbl...

"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote in message
news:%2***************@TK2MSFTNGP12.phx.gbl...
> But I think that the debate around "by reference" semantics vs.
> "copyin/copyout" semantics is interesting, and I don't really
> understand why
> the C# (or rather .NET) designers did not choose copyin/copyout. In

general
> they made very good language design choices, but here, I think that
> they
> made a rather poor choice.

I'm not sure I particularly mind that much - what are the benefits of
copyin/copyout, here?


The main benefit of copyin/copyout is that you can pass any valid
assignement LHS as in/out argument. In particular, you can pass an object property and indexed expression, etc. For example, instead of having to
write:

int val = obj.Prop;
if (GetNewValue(ref val)) {
obj.Prop = val;
// more stuff
}

You just need to write:

if (GetNewValue(inout obj.Prop)) {
// more stuff
}

This is more concise, easier to read, and just as efficient.


Though, one may argue it basically provides the ability to do something

that you would probably never be able to justify doing. Passing a property(or a
field, even though its allowed) to a ref parameter is a very bad idea, IMHO. If a non-essential method with a ref fails, the value of that ref is
undefined as far as I'm concerned. Allowing that to be extended to
properties is horrible. The syntactical changes that would be needed to
allow you to escape a method without performing the copy out is unpleasent. Not providing any syntax in effect allows a failed method call to corrupt
the object's state and would make the exception\error handling code and the code with the ref\out parameter have the nasty stuff instead of the standard path. You can't just forget about the value of a property like you can with a local, you have to take the time and back up the value if its at all
possible the method could fail.
You potentially end up with:
int val = obj.Prop
if (GetNewVal(inout obj.Prop))
{
//more stuff
}
else
{
obj.Prop = val;
}

or
int val = obj.Prop
try
{
GetNewVal(inout obj.Prop);
//more stuff
}
catch (WhateverException)
{
obj.Prop = val;
}
catch (WhateverOtherException)
{
obj.Prop = val;
}
catch (AnotherExceptionException)
{
//Again!
//makes me wish C# had fault handlers, I'd not have to write this so
much
obj.Prop = val;
}
finally
{
//do whatever
}

why is that better?

Nov 16 '05 #15

P: n/a
Bruno Jouhier [MVP] <bj******@club-internet.fr> wrote:
The main benefit of copyin/copyout is that you can pass any valid
assignement LHS as in/out argument. In particular, you can pass an object
property and indexed expression, etc. For example, instead of having to
write:

int val = obj.Prop;
if (GetNewValue(ref val)) {
obj.Prop = val;
// more stuff
}

You just need to write:

if (GetNewValue(inout obj.Prop)) {
// more stuff
}

This is more concise, easier to read, and just as efficient.


Right. That makes sense - and presumably you could also have just
output parameters where the property isn't read to start with, it's
only written out at the end?

Interestingly enough, VB.NET allows you to specify properties as ByRef
parameters, which does exactly the above. Now, I hate the fact that it
does it silently, but if a parameter could actually be *declared* that
way, it would make an awful lot of sense.

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

P: n/a
> Right. That makes sense - and presumably you could also have just
output parameters where the property isn't read to start with, it's
only written out at the end?
Yes, of course, it also works for "out", this is simply "copyout" argument
passing.

BTW, copyout is what comes closest to multiple returns (the assignment is
done after the method returns), and, as my response to Daniel explains,
there is no special problem if the method throws an exception, the copyout
assignment is not performed, the same way the "normal" return value is not
assigned.

Bruno.

Interestingly enough, VB.NET allows you to specify properties as ByRef
parameters, which does exactly the above. Now, I hate the fact that it
does it silently, but if a parameter could actually be *declared* that
way, it would make an awful lot of sense.

Nov 16 '05 #17

P: n/a

"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote in message
news:O$**************@TK2MSFTNGP11.phx.gbl...
You got it wrong. There is no issue about corrupted state or anything like
that. Maybe you are confusing "copyin/copyout" with "passing by name".

The semantics of copyin/copyout are the following:

With a method declaration like:
MyMethod(inout MyType param)

A call like
MyMethod(inout expression);

is equivalent to:
MyType tmpVar = expression;
MyMethod(ref tmpVar);
expression = tmpVar;

This is actually cleaner than passing by reference because the inout
parameters behave exactly like return values (a ref parameter does not!).
If
an exception is thrown by the method, the "copyout" assignment is **not**
performed and the expression is not assigned at all. So, I don't see where
there is a risk of corrupting the object state here. On the other hand,
all
this seems very safe.

I hadn't considered that the code may be generated *around* the method, but
in, which helps mitigate much of the problem(not entirely sure why I was
thinking that way...3am responses aren't always well thought out, ;). The
problem still stands that you would have to throw an exception to stop that
copyout from happening. Your example itself uses an if block to determine
success, how do you escape without throwing an exception?
Passing "by name" is another story, and I would not advocate for it at
all,
at least as a general passing mechanism. It has horrible side effects.

Bruno.

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> a écrit dans
le
message de news:Oc*************@TK2MSFTNGP12.phx.gbl...

"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote in message
news:%2***************@TK2MSFTNGP12.phx.gbl...
>> > But I think that the debate around "by reference" semantics vs.
>> > "copyin/copyout" semantics is interesting, and I don't really
>> > understand
> why
>> > the C# (or rather .NET) designers did not choose copyin/copyout. In
> general
>> > they made very good language design choices, but here, I think that
>> > they
>> > made a rather poor choice.
>>
>> I'm not sure I particularly mind that much - what are the benefits of
>> copyin/copyout, here?
>
> The main benefit of copyin/copyout is that you can pass any valid
> assignement LHS as in/out argument. In particular, you can pass an object > property and indexed expression, etc. For example, instead of having to
> write:
>
> int val = obj.Prop;
> if (GetNewValue(ref val)) {
> obj.Prop = val;
> // more stuff
> }
>
> You just need to write:
>
> if (GetNewValue(inout obj.Prop)) {
> // more stuff
> }
>
> This is more concise, easier to read, and just as efficient.
>


Though, one may argue it basically provides the ability to do something

that
you would probably never be able to justify doing. Passing a property(or
a
field, even though its allowed) to a ref parameter is a very bad idea,

IMHO.
If a non-essential method with a ref fails, the value of that ref is
undefined as far as I'm concerned. Allowing that to be extended to
properties is horrible. The syntactical changes that would be needed to
allow you to escape a method without performing the copy out is

unpleasent.
Not providing any syntax in effect allows a failed method call to corrupt
the object's state and would make the exception\error handling code and

the
code with the ref\out parameter have the nasty stuff instead of the

standard
path. You can't just forget about the value of a property like you can

with
a local, you have to take the time and back up the value if its at all
possible the method could fail.
You potentially end up with:
int val = obj.Prop
if (GetNewVal(inout obj.Prop))
{
//more stuff
}
else
{
obj.Prop = val;
}

or
int val = obj.Prop
try
{
GetNewVal(inout obj.Prop);
//more stuff
}
catch (WhateverException)
{
obj.Prop = val;
}
catch (WhateverOtherException)
{
obj.Prop = val;
}
catch (AnotherExceptionException)
{
//Again!
//makes me wish C# had fault handlers, I'd not have to write this so
much
obj.Prop = val;
}
finally
{
//do whatever
}

why is that better?


Nov 16 '05 #18

P: n/a
See inline..
Bruno Jouhier [MVP] wrote:
Ok. Maybe the few additional keystrokes are worth it. At least many people
seem to react strongly here.

If I remember well, languages like Pascal and ADA support in/out parameters
and you only need to specify this in the function/procedure declaration, you
don't repeat it every time you call. Also, seems to me that the method name
or the parameter name should give a good hint about the in/out nature of the
parameter. This is why I suggested that they are not that useful on the
caller side.
I would disagree here. IMHO, the ref and out in the calling
function, helps catch wrong usage of functions at compile time. In large
code bases it would potentially save someone a huge amount of debugging
time

Also, I still do most of my developments in Java (or rather J#). So, I still
have to fight with the lack of goodies like in/out parameters :-(. So you
guys probably know better.

But I think that the debate around "by reference" semantics vs.
"copyin/copyout" semantics is interesting, and I don't really understand why
the C# (or rather .NET) designers did not choose copyin/copyout. In general
they made very good language design choices, but here, I think that they
made a rather poor choice.

Bruno.

"Jon Skeet [C# MVP]" <sk***@pobox.com> a écrit dans le message de
news:MP************************@msnews.microsoft.c om...
Bruno Jouhier [MVP] <bj******@club-internet.fr> wrote:
Also, I understand why "ref" and "out" are needed in the method
declaration,
but it seems superfluous to have to specify them at every call.


Aargh no! It's absolutely *vital* to my mind that you should specify
them at every call - otherwise it's far from obvious, unless you look
at the declaration of what you're calling, that the parameter is being
passed by reference. I for one don't want to have to check the
declaration of every method which is called just in order to know
what's going on.

Ref/out are (or should be, IMO) rarely enough used that it's not like
it's going to take that many more keystrokes anyway, and the difference
in readability is huge.

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



--
Regards,
Dilip Krishnan
MCAD, MCSD.net
dilipdotnet at apdiya dot com
Nov 16 '05 #19

P: n/a
> I hadn't considered that the code may be generated *around* the method,
but
in, which helps mitigate much of the problem(not entirely sure why I was
thinking that way...3am responses aren't always well thought out, ;). The
problem still stands that you would have to throw an exception to stop that copyout from happening. Your example itself uses an if block to determine
success, how do you escape without throwing an exception?


If the code is generated "in", as if the parameter was replaced by the
expression every time it appears in the body, this is called passing "by
name", and I would be very strongly against it.

I still don't understand your issue and why a special exception would be
required. I see two cases:

"inout" parameter: the method body may or may not reassign the inout
parameter. If the method completes "normally" (without throwing the
exception), the copyout will assign the last value of the parameter. If the
parameter has not been reassigned inside the method body, nothing really
terrible happens (the unmodified value is reassigned -- a variant would be
to prevent the copy out operation in this case to avoid potential side
effects but this makes code generation a bit more complex for the method
body -- even in the second case, I don't see why an exception is needed,
this can be done with a simple flag, and even by a static analysis at
compile time in most cases).

"out" parameter: here the compiler must check that all execution paths
assign a value to the "out" parameter inside the method body (unless they
throw an exception of course), the same way it checks that all execution
paths return a value if the method has a non void return type. Here, if the
method returns "normally", it must assign a value to "out" parameter.

Bruno.

Nov 16 '05 #20

P: n/a

"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
I hadn't considered that the code may be generated *around* the method, but
in, which helps mitigate much of the problem(not entirely sure why I was
thinking that way...3am responses aren't always well thought out, ;). The
problem still stands that you would have to throw an exception to stop

that
copyout from happening. Your example itself uses an if block to determine
success, how do you escape without throwing an exception?


If the code is generated "in", as if the parameter was replaced by the
expression every time it appears in the body, this is called passing "by
name", and I would be very strongly against it.

I still don't understand your issue and why a special exception would be
required. I see two cases:

"inout" parameter: the method body may or may not reassign the inout
parameter. If the method completes "normally" (without throwing the
exception), the copyout will assign the last value of the parameter. If
the
parameter has not been reassigned inside the method body, nothing really
terrible happens (the unmodified value is reassigned -- a variant would be
to prevent the copy out operation in this case to avoid potential side
effects but this makes code generation a bit more complex for the method
body -- even in the second case, I don't see why an exception is needed,
this can be done with a simple flag, and even by a static analysis at
compile time in most cases).

"out" parameter: here the compiler must check that all execution paths
assign a value to the "out" parameter inside the method body (unless they
throw an exception of course), the same way it checks that all execution
paths return a value if the method has a non void return type. Here, if
the
method returns "normally", it must assign a value to "out" parameter.


Consider:

public bool GetNamedThing(string name, inout Thing thing)
{
if (ThingTable.Contains(name))
{
thing = ThingTable.GetThing(name);
return true;
}
else
{
return false;
}
}

//at th ecall point

if (GetNamedThing("thingy", inout this.MyThing))
{
//do stuff
}

now, if you don't want MyThing to be changed on the return of the value of
false, there is no simple way to express that. You would *have* to throw an
exception or the value is copied anyway. Basically the same way ref works
now but with the same resultant effect as pass by name would have in this
case.
Introducing rules that try to measure the return value would be very bad as
well, IMHO. You'd have to have a special form of return if you wanted to
return boolean failures.
Bruno.

Nov 16 '05 #21

P: n/a
> Consider:

public bool GetNamedThing(string name, inout Thing thing)
{
if (ThingTable.Contains(name))
{
thing = ThingTable.GetThing(name);
return true;
}
else
{
return false;
}
}

//at th ecall point

if (GetNamedThing("thingy", inout this.MyThing))
{
//do stuff
}

now, if you don't want MyThing to be changed on the return of the value of
false, there is no simple way to express that. You would *have* to throw an exception or the value is copied anyway. Basically the same way ref works
now but with the same resultant effect as pass by name would have in this
case.
If the return is false, this.MyThing will be reassigned the value that it
had on entry. This is no big deal as long as there is no side effect
involved and no strong perf penalty involved.

As I explained in my post, it is possible for the compiler to generate a
slightly "smarter" IL that will avoid the copy-out assignment if the method
did not reassign the thing argument. What we see here is only the surface,
and behind the scenes, the compiler may very well generate its IL as if the
method had the following signature:
bool GetNamedThingBody(string name, ref Thing thing, ref bool
thingAssigned)
And generate code that sets thingAssigned to true in the path that leads to
"return true", and generate code that tests thingAssigned before performing
the copyout assignment.

I am not sure that this additional subtlety is not really worth the trouble
and the basic version (copyout reassigns the original value) may be
sufficient. Then, if you really want to avoid the potential side effect of
reassigning the same value, you can still pass a variable and assign it to
the property after the call (reproducing what you are doing today with ref).

In any case, all this can be achieved without introducing an exception. I
don't understand why you absolutely want this to be handled via an EH
mechanism.
Introducing rules that try to measure the return value would be very bad as well, IMHO. You'd have to have a special form of return if you wanted to
return boolean failures.


The rule that I am proposing to avoid the reassignment of the same value
does not measure the return value, it measures the presence of an assignment
of the inout parameter in the execution path. This is very different.
I don't understand why we would need a "special form or return" for boolean
failures. Can you explain?

Also, copyin/copyout is not an invention of my own, it is used by some well
known languages, ADA for example. I 'm not saying that ADA should be our
guideline, but sometimes, looking at other languages can give interesting
ideas.

Bruno.

Nov 16 '05 #22

P: n/a
>> Introducing rules that try to measure the return value would be very bad
as
well, IMHO. You'd have to have a special form of return if you wanted to
return boolean failures.
The rule that I am proposing to avoid the reassignment of the same value
does not measure the return value, it measures the presence of an
assignment
of the inout parameter in the execution path. This is very different.
I don't understand why we would need a "special form or return" for
boolean
failures. Can you explain?


The problem is that only an exception allows you to escape the method
without copyout. Basically it requires modifying the way you write the
method with the inout parameter so that the value isn't assigned until every
error condition is satisfied. It creates a fun little difference in returns
and exceptions. Its more of an issue with the patterns involved with passing
a property(or a field) to a value vs passing a local. Code patterns have to
change somewhere. This proposal moves that into the, probably better,
location of the method itself, but it leaves you without an escape outside
of exceptions.

Also, copyin/copyout is not an invention of my own, it is used by some
well
known languages, ADA for example. I 'm not saying that ADA should be our
guideline, but sometimes, looking at other languages can give interesting
ideas.
I agree, I made a similar suggestion that ref\out could have been extended
to get\set properties using such a mechanism not long ago(my basic idea then
had indeed been having the compiler generate a temp local which it passes as
ref and copies back to the property). However I made that suggestion to
support *not* using fields in ref parameters.

As I always suggest, implemting and playing with the feature would help
illustrate the issues more than simple conjecture, from MVP's or otherwise,
;).
Bruno.

Nov 16 '05 #23

P: n/a
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:
The problem is that only an exception allows you to escape the method
without copyout. Basically it requires modifying the way you write the
method with the inout parameter so that the value isn't assigned until every
error condition is satisfied. It creates a fun little difference in returns
and exceptions. Its more of an issue with the patterns involved with passing
a property(or a field) to a value vs passing a local. Code patterns have to
change somewhere. This proposal moves that into the, probably better,
location of the method itself, but it leaves you without an escape outside
of exceptions.


I'm not sure I see the problem - what's the difference here between out
and copyout? The only one I can see is that on successful return, the
output parameter's value is assigned to the actual property/variable
parameter. If an exception is thrown, any temporary value of the output
parameter is ignored, and if the actual parameter is a variable, it's
not deemed as assigned (just as is the case with out parameters now).

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

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:
The problem is that only an exception allows you to escape the method
without copyout. Basically it requires modifying the way you write the
method with the inout parameter so that the value isn't assigned until
every
error condition is satisfied. It creates a fun little difference in
returns
and exceptions. Its more of an issue with the patterns involved with
passing
a property(or a field) to a value vs passing a local. Code patterns have
to
change somewhere. This proposal moves that into the, probably better,
location of the method itself, but it leaves you without an escape
outside
of exceptions.
I'm not sure I see the problem - what's the difference here between out
and copyout? The only one I can see is that on successful return, the
output parameter's value is assigned to the actual property/variable
parameter. If an exception is thrown, any temporary value of the output
parameter is ignored, and if the actual parameter is a variable, it's
not deemed as assigned (just as is the case with out parameters now).

Only that copyout would let you write to properties. I'd have no argument
against inout without access to properties, but when you allow it to modify
state, I do have issue with the exact semantics and the inability to leave a
method without an exception AND without copyout is a problem, IMHO.
Basically there is successful return or exceptions, nothign else. Just not
assigning the variable could be a problem. If the user expects an assignment
to a property and it never comes that would introduce potential bugs and
make code more confusing. I am simply not convinced that throwing exceptions
is enough flexibility. --
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 16 '05 #25

P: n/a
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:
I'm not sure I see the problem - what's the difference here between out
and copyout? The only one I can see is that on successful return, the
output parameter's value is assigned to the actual property/variable
parameter. If an exception is thrown, any temporary value of the output
parameter is ignored, and if the actual parameter is a variable, it's
not deemed as assigned (just as is the case with out parameters now).
Only that copyout would let you write to properties. I'd have no argument
against inout without access to properties, but when you allow it to modify
state, I do have issue with the exact semantics and the inability to leave a
method without an exception AND without copyout is a problem, IMHO.
Why? I still don't see the problem. If it's the calling method which
ends up writing the property, only on successful termination of the
method, then I don't see what goes wrong - unless there are multiple
properties to be set, and it's the setting of one which throws the
exception.
Basically there is successful return or exceptions, nothign else. Just not
assigning the variable could be a problem. If the user expects an assignment
to a property and it never comes that would introduce potential bugs and
make code more confusing. I am simply not convinced that throwing exceptions
is enough flexibility.


If the assignment isn't made because an exception has been thrown, I
think that's fine - that's what copyout means (as I understand it) -
not that every time the assignment is made, the property is written.

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

P: n/a
> If the assignment isn't made because an exception has been thrown, I
think that's fine - that's what copyout means (as I understand it) -
not that every time the assignment is made, the property is written.


I agree, and I don't fully understand Daniel's point.

a call like
Foo(inout expression) // copyin/copyout semantics
behaves "exactly" like:
expression = Foo(expression)

and a call like
Bar(out expression) // copyout semantics
behaves "exactly" like:
expression = Bar()

We write this all the time, and we don't have any real issue with these
constructs. So, I don't see why copyin/copyout argument passing would create
a new problem (Daniel, I don't understand if your issue is on the caller or
callee's side but I don't see any real issue on the callee's side either).

On the other hand, I think that copyin/copyout would be slightly simpler to
explain than "ref" semantics and we would not get all these posts from
people who get confused between "passing by reference" and "passing the
reference" (fortunately Jon has a very good page on this one).

Bruno.
Nov 16 '05 #27

P: n/a

"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
If the assignment isn't made because an exception has been thrown, I
think that's fine - that's what copyout means (as I understand it) -
not that every time the assignment is made, the property is written.


I agree, and I don't fully understand Daniel's point.

a call like
Foo(inout expression) // copyin/copyout semantics
behaves "exactly" like:
expression = Foo(expression)

and a call like
Bar(out expression) // copyout semantics
behaves "exactly" like:
expression = Bar()

We write this all the time, and we don't have any real issue with these
constructs. So, I don't see why copyin/copyout argument passing would
create
a new problem (Daniel, I don't understand if your issue is on the caller
or
callee's side but I don't see any real issue on the callee's side either).

On the other hand, I think that copyin/copyout would be slightly simpler
to
explain than "ref" semantics and we would not get all these posts from
people who get confused between "passing by reference" and "passing the
reference" (fortunately Jon has a very good page on this one).


Sometimes I hate trying to explain these issues. I can see neither of you
understand what I am trying to say since your responses have been addressed
at issues slightly to the left of what I'm trying to explain. I will try
again, hopefully with more success.

The earliest syntax example I saw was something akin to

int value = obj.Prop;
if (GetNewValue(ref value))
{
obj.Prop = value;
//do some stuff
}

the suggested approach of
if (GetNewValue(inout obj.Prop))
{
//do some stuff
}

results in obj.Prop is assigned no matter what happens with the exception of
an exception(pun not intended). The the inout code is actually closer to

int value = obj.Prop
bool returnValue = GetNewValue(ref value)
obj.Prop = value;
if (returnValue)
{
//do some stuff.
}

That is, frankly, less than desirable often and IMHO reduces the utility of
inout semantics, not to mention reducing overall clarity of the code. It of
course also results in subtly different semantics, the two examples above
are different. You could not use code checks to ensure that a non-changing
variable doesn't get reassigned to the property because properties are code
backed, a value not changing doesn't mean an assignment won't change things.
Not assigning the property would be terribly unpredictable.

However, I think the above code pattern is *far* less common than the
original example, it is in my experiance anyway. The mere fact that an out
or ref parameter is being used suggests that more data has to come out of
the method than the return type can handle. In most cases this is going to
be either a success\failure code or another piece of data that may be used
to decide how to proceed. I can't think of any reasonable examples where
this isn't the case. The fundamental problem is that GetNewValue would
*have* to throw an exception if it doesn't want to cause a property
reassignment. Now to answer the question of where the problem is, IMHO it is
in three places: 1) GetNewValue itself, 2) the code calling GetNewValue, and
3) the property get\set accessors. You have to consider the ramifications of
using inout in all three of these pieces of code. You can admittedly get
around 3 by writing the code that calls GetNewValue without using inout when
possible, but that forces you to consider the effects of the property setter
in ways that you wouldn't using the original pattern of setting the property
within the if block. If you can't write the value of a get method into a set
and still get the same value from get then you can't pass the property to an
inout parameter(
theres a mouthful, to be clear, I mean

int value = obj.Prop;
obj.Prop = value;
if (obj.Prop == value || obj.underlyingField1 == old obj.underlyingField1 ||
.... obj.underlyingFieldN == old obj.underlyingFieldN)
//all is well
else
//we have big problems
)
However, unless you wrote the property or have very clear documentation on
the property, you probably shouldn't assume that the assignment has no side
effects. In the normal flow of a program, an explicit assignment clearly
states that the value will be set in most circumstances, again with the
exception of an exception being thrown. In that situation you are clearly
recognizing that tehre are sideeffects and that the assignment definatly
needs to happen. With an inout parameter there is the question of if
assignment should happen or not. Because of this the original example is
moot, the proposal doesn't actually solve the problem. TO me that makes it
less useful than it seems. If forces exceptions on you to achieve code that
uses a simple if in the current method, in code that should be the more
common pattern in any case.
My original point refuting "successful returns" comes from that *any* return
must perform the copy. You cannot design a feature that relys on a return
value to determine its behaviour, it is just *way* too complicated and
unpredictable. Nor could you rely on an underlying block to contain the
copyout code. There is no such thing as a successful return, just a return
or an exception. a return means copy, an exception behaves as an exception.
The semantics are identical to out currently, with the exception that inout
would permit the use of properties and would therefore add quite abit of
unpredictable behaviour to the mix. If you remove access to properties, and
allow just fields and locals as is the behaviour of out, and I have no
problem. And I actually think that inout would have been a better choice
than ref with the exception of overly large structs(which you shouldn't
really have anyway, eh?).
Nov 16 '05 #28

P: n/a

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> a écrit dans le
message de news:eb**************@TK2MSFTNGP11.phx.gbl...

"Bruno Jouhier [MVP]" <bj******@club-internet.fr> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
If the assignment isn't made because an exception has been thrown, I
think that's fine - that's what copyout means (as I understand it) -
not that every time the assignment is made, the property is written.
I agree, and I don't fully understand Daniel's point.

a call like
Foo(inout expression) // copyin/copyout semantics
behaves "exactly" like:
expression = Foo(expression)

and a call like
Bar(out expression) // copyout semantics
behaves "exactly" like:
expression = Bar()

We write this all the time, and we don't have any real issue with these
constructs. So, I don't see why copyin/copyout argument passing would
create
a new problem (Daniel, I don't understand if your issue is on the caller
or
callee's side but I don't see any real issue on the callee's side either).
On the other hand, I think that copyin/copyout would be slightly simpler
to
explain than "ref" semantics and we would not get all these posts from
people who get confused between "passing by reference" and "passing the
reference" (fortunately Jon has a very good page on this one).


Sometimes I hate trying to explain these issues. I can see neither of you
understand what I am trying to say since your responses have been

addressed at issues slightly to the left of what I'm trying to explain. I will try
again, hopefully with more success.

The earliest syntax example I saw was something akin to

int value = obj.Prop;
if (GetNewValue(ref value))
{
obj.Prop = value;
//do some stuff
}

the suggested approach of
if (GetNewValue(inout obj.Prop))
{
//do some stuff
}

results in obj.Prop is assigned no matter what happens with the exception of an exception(pun not intended). The the inout code is actually closer to

int value = obj.Prop
bool returnValue = GetNewValue(ref value)
obj.Prop = value;
if (returnValue)
{
//do some stuff.
}

That is, frankly, less than desirable often and IMHO reduces the utility of inout semantics, not to mention reducing overall clarity of the code. It of course also results in subtly different semantics, the two examples above
are different. You could not use code checks to ensure that a non-changing
variable doesn't get reassigned to the property because properties are code backed, a value not changing doesn't mean an assignment won't change things. Not assigning the property would be terribly unpredictable.

However, I think the above code pattern is *far* less common than the
original example, it is in my experiance anyway. The mere fact that an out
or ref parameter is being used suggests that more data has to come out of
the method than the return type can handle. In most cases this is going to
be either a success\failure code or another piece of data that may be used
to decide how to proceed. I can't think of any reasonable examples where
this isn't the case. The fundamental problem is that GetNewValue would
*have* to throw an exception if it doesn't want to cause a property
reassignment. Now to answer the question of where the problem is, IMHO it is in three places: 1) GetNewValue itself, 2) the code calling GetNewValue, and 3) the property get\set accessors. You have to consider the ramifications of using inout in all three of these pieces of code. You can admittedly get
around 3 by writing the code that calls GetNewValue without using inout when possible, but that forces you to consider the effects of the property setter in ways that you wouldn't using the original pattern of setting the property within the if block. If you can't write the value of a get method into a set and still get the same value from get then you can't pass the property to an inout parameter(
theres a mouthful, to be clear, I mean

int value = obj.Prop;
obj.Prop = value;
if (obj.Prop == value || obj.underlyingField1 == old obj.underlyingField1 || ... obj.underlyingFieldN == old obj.underlyingFieldN)
//all is well
else
//we have big problems
)
However, unless you wrote the property or have very clear documentation on
the property, you probably shouldn't assume that the assignment has no side effects. In the normal flow of a program, an explicit assignment clearly
states that the value will be set in most circumstances, again with the
exception of an exception being thrown. In that situation you are clearly
recognizing that tehre are sideeffects and that the assignment definatly
needs to happen. With an inout parameter there is the question of if
assignment should happen or not. Because of this the original example is
moot, the proposal doesn't actually solve the problem. TO me that makes it
less useful than it seems. If forces exceptions on you to achieve code that uses a simple if in the current method, in code that should be the more
common pattern in any case.
My original point refuting "successful returns" comes from that *any* return must perform the copy. You cannot design a feature that relys on a return
value to determine its behaviour, it is just *way* too complicated and
unpredictable. Nor could you rely on an underlying block to contain the
copyout code. There is no such thing as a successful return, just a return
or an exception. a return means copy, an exception behaves as an exception. The semantics are identical to out currently, with the exception that inout would permit the use of properties and would therefore add quite abit of
unpredictable behaviour to the mix. If you remove access to properties, and allow just fields and locals as is the behaviour of out, and I have no
problem. And I actually think that inout would have been a better choice
than ref with the exception of overly large structs(which you shouldn't
really have anyway, eh?).


Ok. Now I understand your issue completely. But consider the following:

1) You can always introduce a local variable and pass it instead of passing
the obj.Prop expression directly, if you want more control over the copy of
the result into your object property (and go back to what you write with ref
today). This is exactly like replacing:
obj.Prop = Foo(obj.Prop);
by
int tmpVal = Foo(obj.Prop);
// some test on tmpVal
obj.Prop = tmpVal.
Sometimes, you need to do this, but most of the time you don't.

2) When GetValue(inout val) returns false, val should not be reassigned by
the body of GetValue (at least this is the way I would code it). Then, the
copyout operation will just reassign the value that val had on entry, which
should not do much harm. Sometimes, this may involve introducing a local
variable inside the body of GetValue, so that you don't reassign val as you
go, but you compute the new value with a temp variable and you reassign it
to val only when you are sure that you will return true.

Also, I don't agree with you when you say that "you should not assume that
the assignment of the property
has no side effect". First, of course, assigning a property has side
effects (it changes the value of the property), but normally, reassigning
the same value several times should not have dramatic side effects (which is
what should happen when GetValue(inout val) returns false and val is not
reassigned by the body of GetValue). It may have a performance impact but it
should not change the future behavior of your object. If it does,
something's wrong with your design and you have used a set accessor to
trigger side effects that it should not trigger, you should have introduced
a method for that.

And, finally, I think that somewhere the problem comes from a "perversion"
that C introduced a long time ago: C (and all its successors) lets you treat
a "parameter" like a "local variable". So, you often write code like:

void Foo(int arg)
{
// do some stuff
arg = some_expression;
// more stuff
}

So, the programmer gets used to playing with parameters as if they were
local variables, and mentally, he dissociates the formal parameter
completely from its actual parameter. Then, if we introduce inout parameter,
the programmer has to do a mental effort and consider that reassigning the
parameter is not a harmless thing because now, the final value of the
parameter will be copied out.

If C did not introduce this perversion, and if normal parameter (in
parameters) were treated as they should be, i.e. as input values that cannot
be reassigned inside the method body (they are not local variables), then
the programmer would not make such a strong dissociation between formal and
actual parameters. In this ideal world, the programmer would understand the
impact of reassigning a parameter. He would only be able to do it with inout
or out parameters, and then he would understand that by doing this, he is
setting the value that will be copied out. The problem is that today, he is
free to reassign "in" parameters, and so, he has to be careful and
understand that there is a big difference between reassigning an "in"
parameter and an "inout" parameter. IMO, the C# designers could have fixed
that (and the Java designers before them) but they were too stuck in the
C/C++ mindset.

This last point may seem a bit odd. We (C, C++, Java, C# programmers) are so
used to playing with parameters as if they were local variables that we
don't see the problem any more. But I did a bit of Pascal programming before
learning C and I remember that in my first days of C programming, I found
this to be very disturbing. From a "naive" standpoint, it does not make
sense that the method can reassign the parameter without affecting the
actual in the caller, and it takes a little while to accept the way C does
it.

Bruno.
Nov 16 '05 #29

P: n/a
>
Ok. Now I understand your issue completely. But consider the following:

1) You can always introduce a local variable and pass it instead of
passing
the obj.Prop expression directly, if you want more control over the copy
of
the result into your object property (and go back to what you write with
ref
today). This is exactly like replacing:
obj.Prop = Foo(obj.Prop);
by
int tmpVal = Foo(obj.Prop);
// some test on tmpVal
obj.Prop = tmpVal.
Sometimes, you need to do this, but most of the time you don't.
In my opinion, the case where the test matters is the more common.

2) When GetValue(inout val) returns false, val should not be reassigned by
the body of GetValue (at least this is the way I would code it). Then, the
copyout operation will just reassign the value that val had on entry,
which
should not do much harm. Sometimes, this may involve introducing a local
variable inside the body of GetValue, so that you don't reassign val as
you
go, but you compute the new value with a temp variable and you reassign it
to val only when you are sure that you will return true.

Also, I don't agree with you when you say that "you should not assume that
the assignment of the property
has no side effect". First, of course, assigning a property has side
effects (it changes the value of the property), but normally, reassigning
the same value several times should not have dramatic side effects (which
is
what should happen when GetValue(inout val) returns false and val is not
reassigned by the body of GetValue). It may have a performance impact but
it
should not change the future behavior of your object. If it does,
something's wrong with your design and you have used a set accessor to
trigger side effects that it should not trigger, you should have
introduced
a method for that.
IMHO, arbitarily choosing not to reassign a property based on variable value
is not a good idea. What if the value is reassigned, but happens to be the
same variable? How do you make that determination? Should you use
Object.ReferenceEquals or Object.Equals? By attempting to ignore a
reassignment you risk behaviour that is *not* equivilent to value =
<action>;.

As for side effects, sometimes properties raise events or other actions upon
change. This is highly inappropriate as a method, don't you think? The issue
isn't directly reassigning the same value so much as that trying to avoid
reassignment would be a a problem. Since you cannot exit the inout method
normally(without an exception) without causing the copy to happen, chances
are that atleast some patterns are going to fail. And chances are if you are
using an inout method, then the return value has some particular bearing. I
don't see a great many void methods using ref or out, do you? Most of the
time I see bools or associated data structures which usually always
matter(if they don't, then you should probably be using two methods).
And, finally, I think that somewhere the problem comes from a "perversion"
that C introduced a long time ago: C (and all its successors) lets you
treat
a "parameter" like a "local variable". So, you often write code like:

void Foo(int arg)
{
// do some stuff
arg = some_expression;
// more stuff
}

So, the programmer gets used to playing with parameters as if they were
local variables, and mentally, he dissociates the formal parameter
completely from its actual parameter. Then, if we introduce inout
parameter,
the programmer has to do a mental effort and consider that reassigning the
parameter is not a harmless thing because now, the final value of the
parameter will be copied out.

If C did not introduce this perversion, and if normal parameter (in
parameters) were treated as they should be, i.e. as input values that
cannot
be reassigned inside the method body (they are not local variables), then
the programmer would not make such a strong dissociation between formal
and
actual parameters. In this ideal world, the programmer would understand
the
impact of reassigning a parameter. He would only be able to do it with
inout
or out parameters, and then he would understand that by doing this, he is
setting the value that will be copied out. The problem is that today, he
is
free to reassign "in" parameters, and so, he has to be careful and
understand that there is a big difference between reassigning an "in"
parameter and an "inout" parameter. IMO, the C# designers could have fixed
that (and the Java designers before them) but they were too stuck in the
C/C++ mindset.

This last point may seem a bit odd. We (C, C++, Java, C# programmers) are
so
used to playing with parameters as if they were local variables that we
don't see the problem any more. But I did a bit of Pascal programming
before
learning C and I remember that in my first days of C programming, I found
this to be very disturbing. From a "naive" standpoint, it does not make
sense that the method can reassign the parameter without affecting the
actual in the caller, and it takes a little while to accept the way C does
it.

I agree with this, however I think that it is entirely irrelevent to
introducing a way for code to assign a property without knowing its
assigning a property and the fundamental semantic issues involved in that.
The matter of writeability of a parameter is another issue entirely,
although I do think that it would produce clearer code if it wasn't possible
to write to those parameters.
Bruno.

Nov 16 '05 #30

P: n/a

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> a écrit dans le
message de news:u9**************@TK2MSFTNGP11.phx.gbl...

Ok. Now I understand your issue completely. But consider the following:

1) You can always introduce a local variable and pass it instead of
passing
the obj.Prop expression directly, if you want more control over the copy
of
the result into your object property (and go back to what you write with
ref
today). This is exactly like replacing:
obj.Prop = Foo(obj.Prop);
by
int tmpVal = Foo(obj.Prop);
// some test on tmpVal
obj.Prop = tmpVal.
Sometimes, you need to do this, but most of the time you don't.
In my opinion, the case where the test matters is the more common.


Ok, if you think so.

2) When GetValue(inout val) returns false, val should not be reassigned by the body of GetValue (at least this is the way I would code it). Then, the copyout operation will just reassign the value that val had on entry,
which
should not do much harm. Sometimes, this may involve introducing a local
variable inside the body of GetValue, so that you don't reassign val as
you
go, but you compute the new value with a temp variable and you reassign it to val only when you are sure that you will return true.

Also, I don't agree with you when you say that "you should not assume that the assignment of the property
has no side effect". First, of course, assigning a property has side
effects (it changes the value of the property), but normally, reassigning the same value several times should not have dramatic side effects (which is
what should happen when GetValue(inout val) returns false and val is not
reassigned by the body of GetValue). It may have a performance impact but it
should not change the future behavior of your object. If it does,
something's wrong with your design and you have used a set accessor to
trigger side effects that it should not trigger, you should have
introduced
a method for that.
IMHO, arbitarily choosing not to reassign a property based on variable

value is not a good idea. What if the value is reassigned, but happens to be the
same variable? How do you make that determination? Should you use
Object.ReferenceEquals or Object.Equals? By attempting to ignore a
reassignment you risk behaviour that is *not* equivilent to value =
<action>;.
This is where I get lost. I am not suggesting anything like this, and I
don't understand what you are talking about.
Here is an example that demonstrates what I am talking about, maybe it will
help clarify the debate:

bool GetNewValue(inout String val)
{
Resource res = GetResource(); // or whatever
if (res != null) {
val = res.Value;
return true;
}
else {
return false;
}
}

Inside GetNewValue, the code path that ends on "return true" reassigns val.
The code path that ends on "return false" does not reassign val.

If GetNewValue is called as follows:

if (GetNewValue(obj.Prop)) { ... }

the following will happen:

a) if GetNewValue returns true, the copyout operation will assign the new
value to obj.Prop. No problem on this side.

b) if GetNewValue returns false, val will **not** have been reassigned by
the body of GetNewValue. So, the copyout will reassign the value that
obj.Prop had on entry to obj.Prop (a bit like obj.Prop = obj.Prop).
Normally, no harm should be done here. Of course, if the set accessor
triggers all sorts of weird stuff and does not check if the value has really
changed, there may be negative side effects, but IMO the issue is more on
the set accessor side than on the copyout itself (it means that you also
expose yourself to negative side effects when you write something as
innocuous as obj.Prop = Foo(obj.Prop) even if Foo returns its argument
unchanged.

The variant that I was proposing was a variant in which the copyout
operation was skipped in case b). But this decision was based on the fact
that no assignment was performed by the method before reaching the return,
it was not based on any comparison done on the value itself (this is very
different and it seems that you did not get this point). So, there is no
issue about whether Equals or ReferenceEquals should be used, the issue is
about whether or not an assignment to var was performed or not. And the
compiler can easily generate a bit of extra IL to track that, like
introducing an extra "varAssigned" variable that is false initially, and
setting it to true after every statement that assigns var (with special care
if var is passed one level further in inout mode).
And, IMO, this variant is not really necessary because of what I wrote about
set accessors in the paragraph b) above.

As for side effects, sometimes properties raise events or other actions upon change. This is highly inappropriate as a method, don't you think? The issue isn't directly reassigning the same value so much as that trying to avoid
reassignment would be a a problem. Since you cannot exit the inout method
normally(without an exception) without causing the copy to happen, chances
are that atleast some patterns are going to fail. And chances are if you are using an inout method, then the return value has some particular bearing. I don't see a great many void methods using ref or out, do you? Most of the
time I see bools or associated data structures which usually always
matter(if they don't, then you should probably be using two methods).
I don't agree. There are many other cases where it is interesting to be able
to return several pieces of info.

A typical case is a parsing method (like ParseInt), where you would like to
return the value that has been parsed but also the index where the parsing
stopped (in Java, I have to allocate a ParsePosition to get this info).

Also, quite often, I would like to split a method body into several smaller
methods but I don't do it because the first submethod would need to
communicate more than one results to the second submethod. So, I don't do it
and I get suboptimal bulky code simply because I do not have inout or out
parameters (I'm still coding most of my stuff in J#).

So, there are good reasons to use inout and out parameters. And, IMO,
copyin/copyout argument passing is both cleaner and more powerful than ref.
And, finally, I think that somewhere the problem comes from a "perversion" that C introduced a long time ago: C (and all its successors) lets you
treat
a "parameter" like a "local variable". So, you often write code like:

void Foo(int arg)
{
// do some stuff
arg = some_expression;
// more stuff
}

So, the programmer gets used to playing with parameters as if they were
local variables, and mentally, he dissociates the formal parameter
completely from its actual parameter. Then, if we introduce inout
parameter,
the programmer has to do a mental effort and consider that reassigning the parameter is not a harmless thing because now, the final value of the
parameter will be copied out.

If C did not introduce this perversion, and if normal parameter (in
parameters) were treated as they should be, i.e. as input values that
cannot
be reassigned inside the method body (they are not local variables), then the programmer would not make such a strong dissociation between formal
and
actual parameters. In this ideal world, the programmer would understand
the
impact of reassigning a parameter. He would only be able to do it with
inout
or out parameters, and then he would understand that by doing this, he is setting the value that will be copied out. The problem is that today, he
is
free to reassign "in" parameters, and so, he has to be careful and
understand that there is a big difference between reassigning an "in"
parameter and an "inout" parameter. IMO, the C# designers could have fixed that (and the Java designers before them) but they were too stuck in the
C/C++ mindset.

This last point may seem a bit odd. We (C, C++, Java, C# programmers) are so
used to playing with parameters as if they were local variables that we
don't see the problem any more. But I did a bit of Pascal programming
before
learning C and I remember that in my first days of C programming, I found this to be very disturbing. From a "naive" standpoint, it does not make
sense that the method can reassign the parameter without affecting the
actual in the caller, and it takes a little while to accept the way C does it.

I agree with this, however I think that it is entirely irrelevent to
introducing a way for code to assign a property without knowing its
assigning a property and the fundamental semantic issues involved in that.
The matter of writeability of a parameter is another issue entirely,
although I do think that it would produce clearer code if it wasn't

possible to write to those parameters.
Bruno.


Nov 16 '05 #31

P: n/a

This is where I get lost. I am not suggesting anything like this, and I
don't understand what you are talking about.
Here is an example that demonstrates what I am talking about, maybe it
will
help clarify the debate: It is a response to the possibility of not reassigning based on the
assignment in the method body. As you said it was a proposed variant. What I
don't understand about that how it would work. The problem is I was arguing
both possiblities with the same argument at the same time(you can't just
avoid assigning because youcan't have the property not get assigned AND you
shouldn't call the property's set accessor for no reason what-so-ever).
bool GetNewValue(inout String val)
{
Resource res = GetResource(); // or whatever
if (res != null) {
val = res.Value;
return true;
}
else {
return false;
}
}

Inside GetNewValue, the code path that ends on "return true" reassigns
val.
The code path that ends on "return false" does not reassign val.

If GetNewValue is called as follows:

if (GetNewValue(obj.Prop)) { ... }

the following will happen:

a) if GetNewValue returns true, the copyout operation will assign the new
value to obj.Prop. No problem on this side.

b) if GetNewValue returns false, val will **not** have been reassigned by
the body of GetNewValue. So, the copyout will reassign the value that
obj.Prop had on entry to obj.Prop (a bit like obj.Prop = obj.Prop).
Normally, no harm should be done here. Of course, if the set accessor
triggers all sorts of weird stuff and does not check if the value has
really
changed, there may be negative side effects, but IMO the issue is more on
the set accessor side than on the copyout itself (it means that you also
expose yourself to negative side effects when you write something as
innocuous as obj.Prop = Foo(obj.Prop) even if Foo returns its argument
unchanged.

The variant that I was proposing was a variant in which the copyout
operation was skipped in case b). But this decision was based on the fact
that no assignment was performed by the method before reaching the return,
it was not based on any comparison done on the value itself (this is very
different and it seems that you did not get this point). So, there is no
issue about whether Equals or ReferenceEquals should be used, the issue is
about whether or not an assignment to var was performed or not. And the
compiler can easily generate a bit of extra IL to track that, like
introducing an extra "varAssigned" variable that is false initially, and
setting it to true after every statement that assigns var (with special
care
if var is passed one level further in inout mode).
And, IMO, this variant is not really necessary because of what I wrote
about
set accessors in the paragraph b) above.

As for side effects, sometimes properties raise events or other actions upon
change. This is highly inappropriate as a method, don't you think? The

issue
isn't directly reassigning the same value so much as that trying to avoid
reassignment would be a a problem. Since you cannot exit the inout method
normally(without an exception) without causing the copy to happen,
chances
are that atleast some patterns are going to fail. And chances are if you

are
using an inout method, then the return value has some particular bearing.

I
don't see a great many void methods using ref or out, do you? Most of the
time I see bools or associated data structures which usually always
matter(if they don't, then you should probably be using two methods).


I don't agree. There are many other cases where it is interesting to be
able
to return several pieces of info.

A typical case is a parsing method (like ParseInt), where you would like
to
return the value that has been parsed but also the index where the
parsing
stopped (in Java, I have to allocate a ParsePosition to get this info).


Which, one would think, is data you care about because you bothered to call
that overload. If there is other data, then is direct, automatic assignment
really proper? As it is I rarely assign a return value directly to a
property except in initalization. Initalization code that uses output
parameters is pretty rare, IMHO(of course, code that uses output parameters
is pretty rare itself).
Also, quite often, I would like to split a method body into several
smaller
methods but I don't do it because the first submethod would need to
communicate more than one results to the second submethod. So, I don't do
it
and I get suboptimal bulky code simply because I do not have inout or out
parameters (I'm still coding most of my stuff in J#).

So, there are good reasons to use inout and out parameters. And, IMO,
copyin/copyout argument passing is both cleaner and more powerful than
ref.


I agree, except I don't think it should be capable of setting a property
directly. It is certainly cleaner, although it retains the same power in
this case. I certainly like that on an exception, the value won't be changed
even if it has been assigned in the method.

However, in interest of the language and feature itself, I think one of us
should take the mono compiler and actually implement it, using code
generation that works around ref. I'll try to do it on my next run into the
source(should be within the week), unless someone else wants to. I would
like to be able to actually use the feature. I am interested in the overall
semantics, and I am only uncomfortable using it with properties
Nov 16 '05 #32

P: n/a

"Daniel O'Connell [C# MVP]" <onyxkirx@--NOSPAM--comcast.net> a écrit dans le
message de news:eB**************@tk2msftngp13.phx.gbl...

This is where I get lost. I am not suggesting anything like this, and I
don't understand what you are talking about.
Here is an example that demonstrates what I am talking about, maybe it
will
help clarify the debate: It is a response to the possibility of not reassigning based on the
assignment in the method body. As you said it was a proposed variant. What

I don't understand about that how it would work. The problem is I was arguing both possiblities with the same argument at the same time(you can't just
avoid assigning because youcan't have the property not get assigned AND you shouldn't call the property's set accessor for no reason what-so-ever).

bool GetNewValue(inout String val)
{
Resource res = GetResource(); // or whatever
if (res != null) {
val = res.Value;
return true;
}
else {
return false;
}
}

Inside GetNewValue, the code path that ends on "return true" reassigns
val.
The code path that ends on "return false" does not reassign val.

If GetNewValue is called as follows:

if (GetNewValue(obj.Prop)) { ... }

the following will happen:

a) if GetNewValue returns true, the copyout operation will assign the new value to obj.Prop. No problem on this side.

b) if GetNewValue returns false, val will **not** have been reassigned by the body of GetNewValue. So, the copyout will reassign the value that
obj.Prop had on entry to obj.Prop (a bit like obj.Prop = obj.Prop).
Normally, no harm should be done here. Of course, if the set accessor
triggers all sorts of weird stuff and does not check if the value has
really
changed, there may be negative side effects, but IMO the issue is more on the set accessor side than on the copyout itself (it means that you also
expose yourself to negative side effects when you write something as
innocuous as obj.Prop = Foo(obj.Prop) even if Foo returns its argument
unchanged.

The variant that I was proposing was a variant in which the copyout
operation was skipped in case b). But this decision was based on the fact that no assignment was performed by the method before reaching the return, it was not based on any comparison done on the value itself (this is very different and it seems that you did not get this point). So, there is no
issue about whether Equals or ReferenceEquals should be used, the issue is about whether or not an assignment to var was performed or not. And the
compiler can easily generate a bit of extra IL to track that, like
introducing an extra "varAssigned" variable that is false initially, and
setting it to true after every statement that assigns var (with special
care
if var is passed one level further in inout mode).
And, IMO, this variant is not really necessary because of what I wrote
about
set accessors in the paragraph b) above.

As for side effects, sometimes properties raise events or other actions upon
change. This is highly inappropriate as a method, don't you think? The

issue
isn't directly reassigning the same value so much as that trying to avoid reassignment would be a a problem. Since you cannot exit the inout method normally(without an exception) without causing the copy to happen,
chances
are that atleast some patterns are going to fail. And chances are if you
are
using an inout method, then the return value has some particular
bearing. I
don't see a great many void methods using ref or out, do you? Most of
the time I see bools or associated data structures which usually always
matter(if they don't, then you should probably be using two methods).


I don't agree. There are many other cases where it is interesting to be
able
to return several pieces of info.

A typical case is a parsing method (like ParseInt), where you would like
to
return the value that has been parsed but also the index where the
parsing
stopped (in Java, I have to allocate a ParsePosition to get this info).


Which, one would think, is data you care about because you bothered to

call that overload. If there is other data, then is direct, automatic assignment really proper? As it is I rarely assign a return value directly to a
property except in initalization. Initalization code that uses output
parameters is pretty rare, IMHO(of course, code that uses output parameters is pretty rare itself).
Also, quite often, I would like to split a method body into several
smaller
methods but I don't do it because the first submethod would need to
communicate more than one results to the second submethod. So, I don't
do it
and I get suboptimal bulky code simply because I do not have inout or out parameters (I'm still coding most of my stuff in J#).

So, there are good reasons to use inout and out parameters. And, IMO,
copyin/copyout argument passing is both cleaner and more powerful than
ref.


I agree, except I don't think it should be capable of setting a property
directly. It is certainly cleaner, although it retains the same power in
this case. I certainly like that on an exception, the value won't be

changed even if it has been assigned in the method.
I agree that most of the time, you will probably be passing a variable
rather than a property.

But copyin/copyout does not limit you to properties, you can pass any valid
assignment LHS. So, for example, with a method like the GetNewValue above,
you can call it in a loop to get an array of values and pass an expression
like newValues[i] as inout argument, you do not need to get the value into a
temp variable and then assign it to your array.

However, in interest of the language and feature itself, I think one of us
should take the mono compiler and actually implement it, using code
generation that works around ref. I'll try to do it on my next run into the source(should be within the week), unless someone else wants to. I would
like to be able to actually use the feature. I am interested in the overall semantics, and I am only uncomfortable using it with properties

I fooled around with the GCC compiler a long while ago, but I don't have
much time for this kind of exercise any more. So, I'll let you do it.

Note: the copyout code must be generated in the IL that calls the method,
not in the method itself. So, you will need to extend the meta information
to flag the parameter as inout so that you can generate the right IL at the
calling point.

Good luck, and let me know how it goes if you get time to do it.

Bruno

Nov 16 '05 #33

P: n/a

I agree, except I don't think it should be capable of setting a property
directly. It is certainly cleaner, although it retains the same power in
this case. I certainly like that on an exception, the value won't be changed
even if it has been assigned in the method.


I agree that most of the time, you will probably be passing a variable
rather than a property.

But copyin/copyout does not limit you to properties, you can pass any
valid
assignment LHS. So, for example, with a method like the GetNewValue above,
you can call it in a loop to get an array of values and pass an expression
like newValues[i] as inout argument, you do not need to get the value into
a
temp variable and then assign it to your array.


Yes, that is the major upside. My problem is with properties specifically
and more as to if the compiler should permit using them or not. I'll try
both ways. One other problem I'm not entirely sure how to handle is based on
something Jon Skeet suggested. Consider GetNewValue(inout a, inout b); If
two properties are passed to a and b, and the set accessor for b causes an
exception...is state valid, one assignment happened, one didn't? It'd
probably be prudent to recommend agaisnt passing properties to multiple
inout parameters. That is however probably even less likely to happen than
any of the other scenarios I've been worried about.

However, in interest of the language and feature itself, I think one of
us
should take the mono compiler and actually implement it, using code
generation that works around ref. I'll try to do it on my next run into the
source(should be within the week), unless someone else wants to. I would
like to be able to actually use the feature. I am interested in the

overall
semantics, and I am only uncomfortable using it with properties


I fooled around with the GCC compiler a long while ago, but I don't have
much time for this kind of exercise any more. So, I'll let you do it.

Note: the copyout code must be generated in the IL that calls the method,
not in the method itself. So, you will need to extend the meta information
to flag the parameter as inout so that you can generate the right IL at
the
calling point.

Good luck, and let me know how it goes if you get time to do it.


Actually, I muck with the compiler quite often. Almost all of my free time
that isn't spent here or in whatever novel I'm working on is spent toying
with mono's C# compiler. Enough so that I've got about a half dozen
experimental features implemetned and am in the process of adding new
preprocesser directives that can be used to control the behaviour of a
feature so that I can add multiple behaviours and experiment with them
without having to maintain multiple versions of the compiler or even
multiple files. Its pretty much my hobby right now, turns out I enjoy
compilers and programming languages more than booze, video games, and
movies. Stereotypical geek I suppose ;). Anyway, I will certainly have the
time in the near future and I'll keep you up to date.

My intentions right now will be to make it a ref parameter and add an
InOutAttribute or somesuch to the parameter. This will allow my compiler to
treat it as an inout parameter as well as allowing other compilers to access
it, and it means I don't have to modify a runtime(I think you suggested this
approach as well, somewhere back in this thread). I think it will work quite
well, I am just concerned about the mono parse tree and determining that a
parameter is marked with the given attribute at code gen. I'll probably
follow the format of out and ref by requiring inout to be specified at the
call site. That way it is not only obvious to the user, but it makes it
clear to the compiler what is going on. It still doesn't ensure I can
determine if its usage is valid or not.

I think I may also toy with an additional usage of the in or readonly
keywords to specify a parameter is in only. This particular syntax wouldn't
require callsite modifications and wouldn't operate implicitly over all
parameters, but I am interested in the semantics of that particular idea as
well.
Bruno


Nov 16 '05 #34

This discussion thread is closed

Replies have been disabled for this discussion.