<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>
<channel>
	<title>Comments on: Runtime vs. Test time</title>
	<atom:link href="http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/</link>
	<description></description>
	<pubDate>Tue, 06 Jan 2009 10:26:45 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-14985</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Tue, 12 Feb 2008 21:22:48 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-14985</guid>
		<description>Michael Foord: I agree, TDD is a useful design methodology.  But I'm describing a difference between unit and system and runtime tests, not test-first and test-last.  Maybe it would be helpful to clarify that my post is much more applicable to the maintenance and debugging of existing software, software that has already been designed.

Mike Bayer: I don't think it's usually very bad in practice.  Especially for the places where runtime checks are most applicable, which is inside larger integration projects, as opposed to small reusable libraries.  Though reusable libraries also should have good checks, as it makes the library much more pleasant to use.  So... maybe it applies to both.  Either way, I don't think the efficiency is a big problem, and that it's a good tradeoff.  A simple assertion is generally quite fast.

Also, these checks are often best to put in in response to real errors, found during debugging (even during debugging of code written with TDD, as TDD also implies lots of failing tests).  The total number of errors you *could* check for is huge, but the number of errors that a programmer is likely to make is much smaller.  So maybe coming back to Michael's post, this actually does make sense along with TDD, as you still have lots of bugs in a TDD process, those are just the bugs you pre-identified using TDD, and fixing the test and writing the code becomes the same thing.</description>
		<content:encoded><![CDATA[<p>Michael Foord: I agree, TDD is a useful design methodology.  But I&#8217;m describing a difference between unit and system and runtime tests, not test-first and test-last.  Maybe it would be helpful to clarify that my post is much more applicable to the maintenance and debugging of existing software, software that has already been designed.</p>

<p>Mike Bayer: I don&#8217;t think it&#8217;s usually very bad in practice.  Especially for the places where runtime checks are most applicable, which is inside larger integration projects, as opposed to small reusable libraries.  Though reusable libraries also should have good checks, as it makes the library much more pleasant to use.  So&#8230; maybe it applies to both.  Either way, I don&#8217;t think the efficiency is a big problem, and that it&#8217;s a good tradeoff.  A simple assertion is generally quite fast.</p>

<p>Also, these checks are often best to put in in response to real errors, found during debugging (even during debugging of code written with TDD, as TDD also implies lots of failing tests).  The total number of errors you <em>could</em> check for is huge, but the number of errors that a programmer is likely to make is much smaller.  So maybe coming back to Michael&#8217;s post, this actually does make sense along with TDD, as you still have lots of bugs in a TDD process, those are just the bugs you pre-identified using TDD, and fixing the test and writing the code becomes the same thing.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Wouter Lievens</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-14218</link>
		<dc:creator>Wouter Lievens</dc:creator>
		<pubDate>Fri, 08 Feb 2008 10:22:33 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-14218</guid>
		<description>Static typing is, imo, a subset of design by contract: an error will be raised when an inappropriate type is passed to a function.

The mere fact that static typing produces these errors at compile time is a detail, it just means that some contracts could (or should?) be checked at run time.</description>
		<content:encoded><![CDATA[<p>Static typing is, imo, a subset of design by contract: an error will be raised when an inappropriate type is passed to a function.</p>

<p>The mere fact that static typing produces these errors at compile time is a detail, it just means that some contracts could (or should?) be checked at run time.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mmj</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-14212</link>
		<dc:creator>mmj</dc:creator>
		<pubDate>Fri, 08 Feb 2008 09:27:34 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-14212</guid>
		<description>Oh, the important part - you have to use a language with expressive type system. I was strongly influenced by haskell and ml, but the project is in c++ for practical reasons. Java for example would be too weak to express all the types that we use. We'd probably have to make Java "precompiler" and insert our own checks in the process.</description>
		<content:encoded><![CDATA[<p>Oh, the important part - you have to use a language with expressive type system. I was strongly influenced by haskell and ml, but the project is in c++ for practical reasons. Java for example would be too weak to express all the types that we use. We&#8217;d probably have to make Java &#8220;precompiler&#8221; and insert our own checks in the process.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mmj</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-14211</link>
		<dc:creator>mmj</dc:creator>
		<pubDate>Fri, 08 Feb 2008 09:17:01 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-14211</guid>
		<description>(term "type" in this post means anything type-checkable - class, method, generic types, etc.)

Tests (and similarly runtime contract checks) are not that suitable, if you want to enforce certain rules across the whole code base. I learned to program by designing types, so certain (design?) errors that I encountered during development are impossible (or very hard) to express using the new types. For example, when I find a bug, I always think: "could the bug fix be expressed as a type?". If it is, you introduce the new type and delete the old one and the compiler will simply flag all possible bugs (= usage of old type) for you**.

Of course, it takes quite some practice to design classes/functions in a way, that bugs will actually be prevented AND your team members will understand you code. I do use both unit and functional tests in addition because it is more suitable for more localized type of bugs, though.

So, the last 6 years on the project were largely just a constant iteration (sound familiar?:) of type modifications hugely aided by static compiler checks.

** Note, this isn't just refactoring, which is done in dynamic languages. For example, we introduced new multi-threading primitives, because old ones were found to be problematic in certain cases. You might know, that multi-threading is simply not testable dynamically (not with current tools at least), you just have to enforce it statically.</description>
		<content:encoded><![CDATA[<p>(term &#8220;type&#8221; in this post means anything type-checkable - class, method, generic types, etc.)</p>

<p>Tests (and similarly runtime contract checks) are not that suitable, if you want to enforce certain rules across the whole code base. I learned to program by designing types, so certain (design?) errors that I encountered during development are impossible (or very hard) to express using the new types. For example, when I find a bug, I always think: &#8220;could the bug fix be expressed as a type?&#8221;. If it is, you introduce the new type and delete the old one and the compiler will simply flag all possible bugs (= usage of old type) for you**.</p>

<p>Of course, it takes quite some practice to design classes/functions in a way, that bugs will actually be prevented AND your team members will understand you code. I do use both unit and functional tests in addition because it is more suitable for more localized type of bugs, though.</p>

<p>So, the last 6 years on the project were largely just a constant iteration (sound familiar?:) of type modifications hugely aided by static compiler checks.</p>

<p>** Note, this isn&#8217;t just refactoring, which is done in dynamic languages. For example, we introduced new multi-threading primitives, because old ones were found to be problematic in certain cases. You might know, that multi-threading is simply not testable dynamically (not with current tools at least), you just have to enforce it statically.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: mike bayer</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-13989</link>
		<dc:creator>mike bayer</dc:creator>
		<pubDate>Thu, 07 Feb 2008 16:06:05 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-13989</guid>
		<description>ian -

how do you deal with the performance latency as well as source code bloat introduced by injecting argument checkers throughout all methods and functions ?  what I like about unit tests is that you can get similarly good results without weighing down the application's core functionality, with the "argument checkers" focused mainly on the public-facing API functions.  its still "design by contract" but the contract lives externally, with no restrictions on how deeply and completely it can validate functionality.</description>
		<content:encoded><![CDATA[<p>ian -</p>

<p>how do you deal with the performance latency as well as source code bloat introduced by injecting argument checkers throughout all methods and functions ?  what I like about unit tests is that you can get similarly good results without weighing down the application&#8217;s core functionality, with the &#8220;argument checkers&#8221; focused mainly on the public-facing API functions.  its still &#8220;design by contract&#8221; but the contract lives externally, with no restrictions on how deeply and completely it can validate functionality.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michael Foord</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-13919</link>
		<dc:creator>Michael Foord</dc:creator>
		<pubDate>Thu, 07 Feb 2008 12:35:53 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-13919</guid>
		<description>Although you don't mention it, I wonder if you miss the point about TDD. TDD doesn't produce better code because it produces more tested code, it produces better code because it is a better *design* process. This is overwhelmingly my experience (based on a massive two years worth of experience!) and has irrevocably changed the way I program.

Having a full test suite is a great side effect that is very useful for refactoring, but it is only a side effect.


(Your 'Website' field in the comment form doesn't allow enough characters by the way!)</description>
		<content:encoded><![CDATA[<p>Although you don&#8217;t mention it, I wonder if you miss the point about TDD. TDD doesn&#8217;t produce better code because it produces more tested code, it produces better code because it is a better <em>design</em> process. This is overwhelmingly my experience (based on a massive two years worth of experience!) and has irrevocably changed the way I program.</p>

<p>Having a full test suite is a great side effect that is very useful for refactoring, but it is only a side effect.</p>

<p>(Your &#8216;Website&#8217; field in the comment form doesn&#8217;t allow enough characters by the way!)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tony Morris</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-13825</link>
		<dc:creator>Tony Morris</dc:creator>
		<pubDate>Thu, 07 Feb 2008 08:28:40 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-13825</guid>
		<description>Please read http://cdsmith.twu.net/types.html and stop spreading the Agile memetic fallacy.</description>
		<content:encoded><![CDATA[<p>Please read <a href="http://cdsmith.twu.net/types.html" rel="nofollow">http://cdsmith.twu.net/types.html</a> and stop spreading the Agile memetic fallacy.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jake McArthur</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-13808</link>
		<dc:creator>Jake McArthur</dc:creator>
		<pubDate>Thu, 07 Feb 2008 06:49:08 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-13808</guid>
		<description>That is true. You generally have to be willing to sacrifice Turing completeness in order to be able to statically check all properties. Then again, the kinds of contracts that would impose this restriction could just be checked at runtime anyway. There are not many cases I can think of that this would be strictly necessary though. Turing completeness is overrated most of the time.

Anyway, it's still an open area of research. We will have practical results from it eventually though!</description>
		<content:encoded><![CDATA[<p>That is true. You generally have to be willing to sacrifice Turing completeness in order to be able to statically check all properties. Then again, the kinds of contracts that would impose this restriction could just be checked at runtime anyway. There are not many cases I can think of that this would be strictly necessary though. Turing completeness is overrated most of the time.</p>

<p>Anyway, it&#8217;s still an open area of research. We will have practical results from it eventually though!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-13807</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Thu, 07 Feb 2008 06:25:35 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-13807</guid>
		<description>*Sometimes* a contract can be statically checked.  But as we all have learned from statically typed languages, this kind of language analysis can lead to blowback for the programs, restricting the kinds of programs you can write in order to facilitate the static analysis.  There's simply *no* static analysis that is smart enough to accept all correct programs.  This goes double for contracts.

Of course a contract can also get kind of expensive at runtime.  E.g., `for item in seq: assert item is None or isinstance(item, int)`.  You have to consider just how far you are willing to go to check values up-front.  But then an assert in the middle of a function (e.g., inside a `for` loop) can be just as good, and often much cheaper.</description>
		<content:encoded><![CDATA[<p><em>Sometimes</em> a contract can be statically checked.  But as we all have learned from statically typed languages, this kind of language analysis can lead to blowback for the programs, restricting the kinds of programs you can write in order to facilitate the static analysis.  There&#8217;s simply <em>no</em> static analysis that is smart enough to accept all correct programs.  This goes double for contracts.</p>

<p>Of course a contract can also get kind of expensive at runtime.  E.g., <code>for item in seq: assert item is None or isinstance(item, int)</code>.  You have to consider just how far you are willing to go to check values up-front.  But then an assert in the middle of a function (e.g., inside a <code>for</code> loop) can be just as good, and often much cheaper.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jake McArthur</title>
		<link>http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/comment-page-1/#comment-13804</link>
		<dc:creator>Jake McArthur</dc:creator>
		<pubDate>Thu, 07 Feb 2008 06:19:19 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/02/06/runtime-vs-test-time/#comment-13804</guid>
		<description>You have the right idea, but there is another step you can take this. Your contracts can be *statically* checked! Unfortunately, we don't have many (any?) general purpose programming languages that can do this yet, but the theory is sound, and theorem provers (Coq, for example) already use the technique.

The idea is that, in a dependently typed language (one in which your types can depend on the values... which sounds weird but these *can* be statically checked), you pass around proofs. That is, arguments in your functions call for propositions (preconditions to assert), and calling these functions will only compile if you supply appropriate proofs of these propositions. Likewise, the function can return proofs (postconditions) to be used elsewhere as well. That's a very rough metaphor of what you actually do, anyway.

So design by contract isn't really a substitute for static typing after all, since it can be statically checked!</description>
		<content:encoded><![CDATA[<p>You have the right idea, but there is another step you can take this. Your contracts can be <em>statically</em> checked! Unfortunately, we don&#8217;t have many (any?) general purpose programming languages that can do this yet, but the theory is sound, and theorem provers (Coq, for example) already use the technique.</p>

<p>The idea is that, in a dependently typed language (one in which your types can depend on the values&#8230; which sounds weird but these <em>can</em> be statically checked), you pass around proofs. That is, arguments in your functions call for propositions (preconditions to assert), and calling these functions will only compile if you supply appropriate proofs of these propositions. Likewise, the function can return proofs (postconditions) to be used elsewhere as well. That&#8217;s a very rough metaphor of what you actually do, anyway.</p>

<p>So design by contract isn&#8217;t really a substitute for static typing after all, since it can be statically checked!</p>
]]></content:encoded>
	</item>
</channel>
</rss>
