Hacker News new | past | comments | ask | show | jobs | submit login

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.


In addition to the benefit of brevity, something like your proposal also has the virtue of being compatible with the `checked/unchecked` keywords.


You kind of used D's syntax for contracts,

http://dlang.org/contracts.html


cool, thanks!

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


Would be easy to add something like that in CLOS using :before and :after methods and maybe some macros to give suitable syntax.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: