methods without sideeffects (proposal)

  • Thread starter Thread starter cody
  • Start date Start date
C

cody

There should be a way to mark methods without sideeffects with a special
Attribute so that the compiler can recognize them and is able to issue a
warning:

public class string
{
[NoSideEffect()] // alternatively we could name it
[RequireUseReturnValue()]
public string Trim()
{
//...
}
}

this would be especially useful for immutable classes like string. A common
mistake is that you do:

myString.TrimEnd(',', ' ');

and as an effect, nothing happens since we forgot to assign the newly
created string.
 
Yeah I can understand that. I think the problems lies in the naming of the
methods. The method name 'Trim', just like 'Replace', implies it's actually
modifying the object itself rather than returning the modified object.
Perhaps if they prefixed the methods with 'Get' it wouldn't be so confusing.

While I like the concept of describing the behavior of the method with an
attribute, I don't think 'NoSideEffect' or 'RequiresUseReturnValue' really
explain it well enough.


This Attribute is for the compiler which will issue a warning if the method
is called without using its return value.
It is the same like myPoint.X; will issue a warning since properties have
(are should not have) sideeffects.
 
Yeah I can understand that. I think the problems lies in the naming of the
methods. The method name 'Trim', just like 'Replace', implies it's actually
modifying the object itself rather than returning the modified object.
Perhaps if they prefixed the methods with 'Get' it wouldn't be so confusing.

While I like the concept of describing the behavior of the method with an
attribute, I don't think 'NoSideEffect' or 'RequiresUseReturnValue' really
explain it well enough.
 
Yeah I understand what you're saying... just wasn't sure that 'NoSideEffect'
was the best way to describe it :)

It would actually also be good if the compiler could enforce that, ie.
issues another warning if the code implementing the property or function
containing this attribute were to actually modify other properties or fields
in the class, or to call a method that isn't marked with this attribute.

Yeah I'm all for it.
 
But how do you gaurantee that a method has no side effects? The Trim()
method has no side effects on the string class instance but it does have
side effects on the environment as a whole. It produces an extra allocation
which could in turn cause a garbage collection to occur.

I think you might also run into versioning problems with this idea. Say
that V1 of your product has a class A with method called DoSomething(). In
V2 you add the NoSideEffect() attribute. Now code that was working and
compiled against your V1 product will no longer compile against the V2
product.

--
Jared Parson [MSFT]
(e-mail address removed)

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
 
Say that V1 of your product has a class A with method called
DoSomething(). In V2 you add the NoSideEffect() attribute. Now code that
was working and compiled against your V1 product will no longer compile
against the V2 product. <<

Right and so it shouldn't though. The usage pattern for the function has
changed, so the code that called it shouldn't compile any longer because it
wouldn't be valid if it wasn't using the return value.

It's the same as changing the return type of a function, that shoudln't be
backwards compatible either.

Personally I think he has a good point here. It's certainly something where
the benefits outweigh the drawbacks. At the moment some aspects of the API
(especially the string class) just aren't clear enough without referring to
documentation. With the addition of this warning and attribute, it would
significantly reduce the likelihood that you would unintentionally misuse
the API.

John

Jared Parsons said:
But how do you gaurantee that a method has no side effects? The Trim()
method has no side effects on the string class instance but it does have
side effects on the environment as a whole. It produces an extra allocation
which could in turn cause a garbage collection to occur.

I think you might also run into versioning problems with this idea. Say
that V1 of your product has a class A with method called DoSomething(). In
V2 you add the NoSideEffect() attribute. Now code that was working and
compiled against your V1 product will no longer compile against the V2
product.

--
Jared Parson [MSFT]
(e-mail address removed)

This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm

cody said:
There should be a way to mark methods without sideeffects with a special
Attribute so that the compiler can recognize them and is able to issue a
warning:

public class string
{
[NoSideEffect()] // alternatively we could name it
[RequireUseReturnValue()]
public string Trim()
{
//...
}
}

this would be especially useful for immutable classes like string. A common
mistake is that you do:

myString.TrimEnd(',', ' ');

and as an effect, nothing happens since we forgot to assign the newly
created string.

--
cody

Freeware Tools, Games and Humour
http://www.deutronium.de.vu || http://www.deutronium.tk
 
Yeah I understand what you're saying... just wasn't sure that
'NoSideEffect'
was the best way to describe it :)

It would actually also be good if the compiler could enforce that, ie.
issues another warning if the code implementing the property or function
containing this attribute were to actually modify other properties or fields
in the class, or to call a method that isn't marked with this attribute.


What you're saying is like const methods in c++ which are not allowed to
call non-const methods or to modify fields (unless fields which are marked
as mutable).
If you go so far that you want to enforce that NoSideEffect methods must not
modify fields of that object you have to intruduce the mutable modifier too
because you sometimes want to set internal status variables from a
NoSideEffect method which does not 'officially' belong to the state of the
object .
 
But how do you gaurantee that a method has no side effects? The Trim()
method has no side effects on the string class instance but it does have
side effects on the environment as a whole. It produces an extra allocation
which could in turn cause a garbage collection to occur.

I think you might also run into versioning problems with this idea. Say
that V1 of your product has a class A with method called DoSomething(). In
V2 you add the NoSideEffect() attribute. Now code that was working and
compiled against your V1 product will no longer compile against the V2
product.


Nobody guarantees that the method has no sideeffects. But at least the
attribute say that the method does 'officially' have no sideeffects.
There aren't versioning problems because this attribute gives no error, it
is just a warning or a hint for the programmer.
Compiled Assemblies don't care about the attribute it only bothers you if
you try to recompile the code.
And if you change a method this way that it now doesn't modify the state of
the object and before it did or vice versa your code is likely to be broken
anyway.
 
Yeah, I guess the goal here isn't to make C# as complicated as C++. The
other day I was pining some of those C++ features and started thinking about
how much more complicated C# would be if it included them.

The likelihood of the NoSideEffects method changing internal status flags is
probably quite rare, and in that case they could somehow pragma the warning
away.

cody said:
Yeah I understand what you're saying... just wasn't sure that 'NoSideEffect'
was the best way to describe it :)

It would actually also be good if the compiler could enforce that, ie.
issues another warning if the code implementing the property or function
containing this attribute were to actually modify other properties or fields
in the class, or to call a method that isn't marked with this attribute.


What you're saying is like const methods in c++ which are not allowed to
call non-const methods or to modify fields (unless fields which are marked
as mutable).
If you go so far that you want to enforce that NoSideEffect methods must not
modify fields of that object you have to intruduce the mutable modifier too
because you sometimes want to set internal status variables from a
NoSideEffect method which does not 'officially' belong to the state of the
object .

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
 
Jared Parsons said:
But how do you gaurantee that a method has no side effects? The Trim()
method has no side effects on the string class instance but it does have
side effects on the environment as a whole. It produces an extra allocation
which could in turn cause a garbage collection to occur.

Yes, and the system time changes while the function is running, and so on,
but that's not the point: the idea is that the optimizer could eliminate
multiple calls to 'Trim' like it can elimininate common arithmetic
subexpressions, if it only knew that calling 'Trim' twice has no side
effect. In a managed environment, this can be enforced: the compiler could
simply say that an 'side-effect-free' function may only write to local
variables, and call only other side-effect-free functions.
Although it's not simple, some languages like Eiffel, Ada or Haskell do
provide language features like this.
I think you might also run into versioning problems with this idea. Say
that V1 of your product has a class A with method called DoSomething(). In
V2 you add the NoSideEffect() attribute. Now code that was working and
compiled against your V1 product will no longer compile against the V2
product.

Why that? I can see that the other way round would be a problem, but why
should anything prohibit an ordinary function from calling a
'side-effect-free' one?
And: changing a function's semantic like that (e.g. Trim suddenly changes a
global variable in V2) may cause trouble (e.g. threading issues),
side-effect-keyword or not.

Niki
 
Back
Top