I've been trying to think of something that drastically change how I coded. Bugs and productivity really are the two major dragons to slay.
I'm just spitballing here but something I'd really like to see stuff like code contracts and unit testing, but more integrated with the language, less verbose and requiring less to setup. Being able to let the "meat" of a method be separated from all the error-checking, post, pre conditions etc would really make things cleaner.
Current implementation feels like it requires too much setup with separate classes, duplicate method signatures in several places etc etc. It would be really cool to have something like
public int SomeMethod(int a, int b)
pre
{
Requires (a > 5);
Requires (b >= 0, new Exception("something something"));
}
{
// DoStuffHere
}
post
{
Ensures (result > 0, new Exception("needs to be above 0"));
}
I'd even want to be able to separate it into separate files using partial classes (or something) so you could the condition stuff separate , with or without duplicating signature
depending if you wanted to target specific overloads
Full signature would simply be without the body:
public int SomeMethod(int a, int b)
pre
{
Requires (a > 5);
Requires (b >= 0 ,new Exception("something something"));
}
post
{
Ensures (result > 0);
}
Without signature is trickier, but would be cool since you could use same conditions for several overloads, and just target the variables that are included in each:
Conditions.SomeMethod
{
pre
{
Requires (a > 5);
Requires (b >= 0, new Exception("something something"));
}
post
{
Ensures (result > 0);
}
}
heck, why not even throw in "test blocks" and Visual studio could run light-weight kind of unit test as you programmed and mark the whole method as functioning or not. Imagine having a sort method and throw in something like:
public IEnumerable<int> Sort (IEnumerable<int> list, Order order)
test
{
(list = {3,5,6,2}, order = Order.Ascending) => result == {2,3,5,6};
(list = {3,5,6,2}, order = Order.Descending) => result == {6,5,3,2}
}
VS could highlight the failed test(s) directly in the editor as you coded
The specifics and syntaxes of these things requires some thought but I love the basic premise, am I rambling?
edit: I saw that something in this direction if not as extensive was actually discussed
We've had a robust way of doing code contracts since C# 2.0.
If you instruct the compiler to treat all warnings as errors (so that variables must be defintitely assigned), then the following code gives you what you want:
public PositiveInt SomeMethod(GreaterThanFive a, NonNegative b)
{
//do stuff;
}
public struct GreaterThanFive
{
readonly int n;
public GreaterThanFive (int n)
{
if(n < 5)
throw new ArgumentException("n must be greater than 5")
this.n = n;
}
public static implicit operator GreaterThanFive(int n)
{
return GreaterThanFive(n);
}
public static implicit operator int (GreaterThanFive n)
{
return n.n;
}
}
//Similar definitions for NonNegative and PositiveInt
We can even have nice diagnostic messages since the advent of C# 5's CallerInfo attributes (CallerMemberName, CallerLineNumber, and CallerFilePath).
Very clever. It may be robust, but is ridiculously verbose and feels sorta obfuscatory. Also pays a runtime penalty unless they've improved the CLR codegen.
It also might not be super amenable to static analysis.
But, structs pay a very small runtime penalty, if at all, right?
The verbosity will be mostly ameliorated with primary constructor. I propose going further by allowing programmers to annotate constructors so that they can be used as user-defined conversion operators.
Thus, the aforementioned code could become something like:
public struct GreaterThanFive implicit (int n)
{
readonly int n = n;
if(n <= 5)
throw new ArgumentException("n must be greater than 5");
}
Traditionally, structs paid a large codegen penalty, as a lot of optimizations and stuff were turned off. It also seemed like the codegen wasn't super smart about passing them around. Maybe that's all changed.
I meant the verbosity of having to create a custom type for each kind of restriction, versus some inline "int n [n > 5]" notation.
Multiple bracket blocks is not the most esthetic of solutions I think but it's the best I can think of. Attributes feels too clunky and just stacking contracts as lines after the class statement feels too disorganized
I'm just spitballing here but something I'd really like to see stuff like code contracts and unit testing, but more integrated with the language, less verbose and requiring less to setup. Being able to let the "meat" of a method be separated from all the error-checking, post, pre conditions etc would really make things cleaner.
Current implementation feels like it requires too much setup with separate classes, duplicate method signatures in several places etc etc. It would be really cool to have something like
I'd even want to be able to separate it into separate files using partial classes (or something) so you could the condition stuff separate , with or without duplicating signature depending if you wanted to target specific overloadsFull signature would simply be without the body:
Without signature is trickier, but would be cool since you could use same conditions for several overloads, and just target the variables that are included in each: heck, why not even throw in "test blocks" and Visual studio could run light-weight kind of unit test as you programmed and mark the whole method as functioning or not. Imagine having a sort method and throw in something like: VS could highlight the failed test(s) directly in the editor as you codedThe specifics and syntaxes of these things requires some thought but I love the basic premise, am I rambling?
edit: I saw that something in this direction if not as extensive was actually discussed