<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-825172855488132129</id><updated>2012-02-16T13:10:32.594-08:00</updated><category term='type checking'/><category term='lazy function'/><category term='Oz'/><category term='Mozart'/><category term='runtime'/><category term='functional'/><category term='debugger'/><title type='text'>Minnepinne</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://wolfgangmeyer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/825172855488132129/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://wolfgangmeyer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Wolfgang Meyer</name><uri>http://www.blogger.com/profile/08636669076392383554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-825172855488132129.post-8592255325388719778</id><published>2008-04-05T11:14:00.000-07:00</published><updated>2008-04-06T11:37:48.904-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Oz'/><category scheme='http://www.blogger.com/atom/ns#' term='lazy function'/><category scheme='http://www.blogger.com/atom/ns#' term='runtime'/><category scheme='http://www.blogger.com/atom/ns#' term='type checking'/><category scheme='http://www.blogger.com/atom/ns#' term='Mozart'/><title type='text'>Runtime type-checking of recursive data types with lazy recursive functions</title><content type='html'>In &lt;i&gt;&lt;a href="http://www.info.ucl.ac.be/~pvr/book.html"&gt;Concepts, Techniques, and Models of Computer Programming&lt;/a&gt;&lt;/i&gt; van Roy and Haridi introduce a notation to describe recursive data types. For example, this is a possible description of binary trees (simplified from Section 4.3.1: Type Notation):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;BTree T&amp;gt; ::= tree(value: T&lt;br /&gt;                   left: &amp;lt;BTree T&amp;gt;&lt;br /&gt;                   right: &amp;lt;BTree T&amp;gt;)&lt;br /&gt;              | leaf(value: T)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This notation is close to the record syntax of &lt;a href="http://www.mozart-oz.org"&gt;Oz&lt;/a&gt;, which is no coincidence, given that the book uses Oz as its principle vehicle. Records in Oz are a very powerful and flexible data type. Even lists are just nested records in Oz, albeit supported by a special syntax. So records are a natural fit as an implementation technique for recursive data types.&lt;br /&gt;&lt;br /&gt;Can we exploit this notation to check the well-formedness of trees and other recursive data types at runtime?&lt;sup&gt;&lt;a href="#1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;Yes, we can! The trick is to use &lt;i&gt;lazy functions&lt;/i&gt; to describe such data types.&lt;sup&gt;&lt;a href="#2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;br /&gt;&lt;br /&gt;So we define types as functions with type variables as their arguments. In order to produce valid Oz code, the notation must be adjusted slightly. Instead of &lt;code&gt;A|B&lt;/code&gt;, we write &lt;code&gt;one_of(A B)&lt;/code&gt;. Also, the angle brackets disappear. Where we refer back to the defined type itself, we need to use function call syntax, of course:&lt;br /&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 10pt; COLOR: #f5deb3; BACKGROUND-COLOR: #2f4f4f"&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; lazy &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;BTree&lt;/b&gt;&lt;/font&gt; T }&lt;br /&gt;   one_of(tree(value: T&lt;br /&gt;               left: {BTree T}&lt;br /&gt;               right: {BTree T}&lt;br /&gt;              )&lt;br /&gt;          leaf(value: T)&lt;br /&gt;         )&lt;br /&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;The result of &lt;code&gt;{BTree int}&lt;/code&gt;, for example, is an "infinite" record that describes the set of binary trees with integer elements. &lt;code&gt;{BTree {BTree atom}}&lt;/code&gt; describes binary trees of binary trees of atoms.&lt;br /&gt;At this point, it becomes clear why &lt;code&gt;BTree&lt;/code&gt; must be annotated as lazy: Otherwise the function would never return.&lt;br /&gt;&lt;br /&gt;It is now pretty easy to implement a function that actually checks the type of concrete instances:&lt;br /&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 10pt; COLOR: #f5deb3; BACKGROUND-COLOR: #2f4f4f"&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;Check&lt;/b&gt;&lt;/font&gt; Val Type}&lt;br /&gt;   &lt;font color="#fa8072"&gt;case&lt;/font&gt; Type&lt;br /&gt;   &lt;font color="#fa8072"&gt;of&lt;/font&gt; one_of(&lt;font color="#fa8072"&gt;...&lt;/font&gt;) &lt;font color="#fa8072"&gt;then&lt;/font&gt;&lt;br /&gt;      {Record&lt;font color="#fa8072"&gt;.&lt;/font&gt;some Type &lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt; T} {Check Val T} &lt;font color="#fa8072"&gt;end&lt;/font&gt;}&lt;br /&gt;   &lt;font color="#fa8072"&gt;else&lt;/font&gt;&lt;br /&gt;      &lt;font color="#fa8072"&gt;if&lt;/font&gt; {Atom&lt;font color="#fa8072"&gt;.&lt;/font&gt;is Type} &lt;font color="#fa8072"&gt;then&lt;/font&gt;&lt;br /&gt;         {Value&lt;font color="#fa8072"&gt;.&lt;/font&gt;type Val} &lt;font color="#fa8072"&gt;==&lt;/font&gt; Type&lt;br /&gt;      &lt;font color="#fa8072"&gt;elseif&lt;/font&gt; {Record&lt;font color="#fa8072"&gt;.&lt;/font&gt;is Type} &lt;font color="#fa8072"&gt;then&lt;/font&gt;&lt;br /&gt;         {CheckRecordType Val Type}&lt;br /&gt;      &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;   &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;CheckRecordType&lt;/b&gt;&lt;/font&gt; Val Type}&lt;br /&gt;   {Record&lt;font color="#fa8072"&gt;.&lt;/font&gt;is Val} &lt;font color="#fa8072"&gt;andthen&lt;/font&gt;&lt;br /&gt;   {Record&lt;font color="#fa8072"&gt;.&lt;/font&gt;label Val} &lt;font color="#fa8072"&gt;==&lt;/font&gt; {Record&lt;font color="#fa8072"&gt;.&lt;/font&gt;label Type} &lt;font color="#fa8072"&gt;andthen&lt;/font&gt;&lt;br /&gt;   {Record&lt;font color="#fa8072"&gt;.&lt;/font&gt;allInd Type&lt;br /&gt;    &lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt; Feat Field}&lt;br /&gt;       {HasFeature Val Feat} &lt;font color="#fa8072"&gt;andthen&lt;/font&gt; {Check Val&lt;font color="#fa8072"&gt;.&lt;/font&gt;Feat Field}&lt;br /&gt;    &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;   }&lt;br /&gt;   &lt;font color="#fa8072"&gt;andthen&lt;/font&gt; &lt;font color="#add8e6"&gt;% &lt;/font&gt;&lt;font color="#add8e6"&gt;no additional fields in Val:&lt;br /&gt;&lt;/font&gt;   {All {Record&lt;font color="#fa8072"&gt;.&lt;/font&gt;arity Val}&lt;br /&gt;    &lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;$&lt;/b&gt;&lt;/font&gt; Feat}&lt;br /&gt;       {HasFeature Type Feat}&lt;br /&gt;    &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;   } &lt;br /&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;The details of these two mutually recursive functions are not really interesting. They just walk through &lt;code&gt;Val&lt;/code&gt; and &lt;code&gt;Type&lt;/code&gt; in parallel and recursively check that every field in &lt;code&gt;Val&lt;/code&gt; has the type that is specified in the corresponding field of &lt;code&gt;Type&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;This type of runtime type checking is quite costly. For a tree with N nodes, &lt;code&gt;Check&lt;/code&gt; has a complexity of O(N). This might be okay in unit tests, but is probably too expensive for production code. Another drawback is that it does not work with cyclic data structures.&lt;br /&gt;&lt;br /&gt;With a little helper procedure, we can assert the type of a value concisely:&lt;br /&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 10pt; COLOR: #f5deb3; BACKGROUND-COLOR: #2f4f4f"&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="#fa8072"&gt;proc&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;AssertType&lt;/b&gt;&lt;/font&gt; Val Type}&lt;br /&gt;   &lt;font color="#fa8072"&gt;thread&lt;/font&gt;&lt;br /&gt;      &lt;font color="#fa8072"&gt;if&lt;/font&gt; {Check Val Type} &lt;font color="#fa8072"&gt;==&lt;/font&gt; &lt;font color="#fa8072"&gt;false&lt;/font&gt; &lt;font color="#fa8072"&gt;then&lt;/font&gt;&lt;br /&gt;         &lt;font color="#fa8072"&gt;raise&lt;/font&gt; typeError(Val Type) &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;      &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;   &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;In this way, it is even possible to assert the type of unbound variables.&lt;br /&gt;&lt;code&gt;Check&lt;/code&gt; is called concurrently, so it will not block the execution in this case. The type check of &lt;code&gt;Val&lt;/code&gt; will be finished as soon as &lt;code&gt;Val&lt;/code&gt; has been computed completely, thanks to dataflow programming and cheap threads in Oz.&lt;br /&gt;&lt;br /&gt;Ideally, we'd like to print an informative error message which refers back to the source file and line number when a type check failed. This is currently only possible by using the &lt;a href="http://www.mozart-oz.org/documentation/macro/index.html"&gt;deprecated macro facility&lt;/a&gt; of Oz.&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;sup&gt;&lt;a name="1"&gt;1&lt;/a&gt;&lt;/sup&gt; Oz is a dynamically typed programming language. You cannot define recursive data types at compile time and neither the compiler nor the runtime will check the well-formedness of trees or other custom data types automatically.&lt;br /&gt;&lt;sup&gt;&lt;a name="2"&gt;2&lt;/a&gt;&lt;/sup&gt; For Haskellers, this will hardly come as a surprise. Constructors in Haskell are just a &lt;a href="http://www.haskell.org/tutorial/functions.html#sect3.4"&gt;special kind of function&lt;/a&gt; that can be used in pattern matching.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/825172855488132129-8592255325388719778?l=wolfgangmeyer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wolfgangmeyer.blogspot.com/feeds/8592255325388719778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=825172855488132129&amp;postID=8592255325388719778' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/825172855488132129/posts/default/8592255325388719778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/825172855488132129/posts/default/8592255325388719778'/><link rel='alternate' type='text/html' href='http://wolfgangmeyer.blogspot.com/2008/04/runtime-type-checking-of-recursive-data.html' title='Runtime type-checking of recursive data types with lazy recursive functions'/><author><name>Wolfgang Meyer</name><uri>http://www.blogger.com/profile/08636669076392383554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-825172855488132129.post-1543175880764851770</id><published>2008-04-02T03:41:00.000-07:00</published><updated>2008-04-04T07:37:38.697-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debugger'/><category scheme='http://www.blogger.com/atom/ns#' term='Oz'/><category scheme='http://www.blogger.com/atom/ns#' term='functional'/><category scheme='http://www.blogger.com/atom/ns#' term='Mozart'/><title type='text'>Debuggers are Needlessly Tedious to Use</title><content type='html'>Are debuggers useful? Giles Bowkett certainly &lt;a href="http://gilesbowkett.blogspot.com/2007/10/debugger-support-considered-harmful.html"&gt;doesn't think so&lt;/a&gt;. According to him, "debuggers encourage a backwards workflow". They seduce you into working in a trial-and-error way instead of producing clear, well-tested code. They make you step through your code again and again to check whether you finally got it right.&lt;br /&gt;&lt;br /&gt;However, in my opinion, there &lt;em&gt;are &lt;/em&gt;circumstances under which debuggers are useful:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;when working your way through legacy code,&lt;/li&gt;&lt;li&gt;when encountering a strange bug that is completely beyond your understanding,&lt;/li&gt;&lt;li&gt;when experimenting with a new technology.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;Nevertheless, many experienced developers find debuggers pretty useless. One reason for that is that debuggers are typically tedious to use. Stepping manually through code takes a lot of time. Especially if you are hunting for a bug and don't know where exactly the bug actually happens.&lt;br /&gt;&lt;br /&gt;At every function call you face a choice: to step into the function or not to step into the function. If you optimistically don't step into it and find that its result is not what you expected, you have to do it all over again: setting a new breakpoint, restarting the program (or test suite)...&lt;strong&gt;Tedious!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;A Proposal&lt;/H3&gt;Why do debuggers work this way? Wouldn't it be much more useful if debuggers could just show what goes on inside a function, without requiring you to step through the code again and again?&lt;br /&gt;&lt;br /&gt;To explore the idea, I implemented a prototypical "source code annotating debugger"&lt;sup&gt;&lt;A href="#download"&gt;1&lt;/a&gt;&lt;/sup&gt; for a subset of the programming language &lt;A href="http://www.mozart-oz.org"&gt;Oz&lt;/A&gt;. I'm using Oz as a functional programming language here, but it does in fact support multiple styles of programming in a harmonious way.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;Example&lt;/H3&gt;Let's look at a (somewhat contrived) example which contains a well-hidden bug:&lt;br /&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 10pt; COLOR: #f5deb3; BACKGROUND-COLOR: #2f4f4f"&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="#fa8072"&gt;declare&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;RemoveEvenNumbers&lt;/b&gt;&lt;/font&gt; Xs}&lt;br /&gt;   &lt;font color="#fa8072"&gt;case&lt;/font&gt; Xs &lt;font color="#fa8072"&gt;of&lt;/font&gt; X&lt;font color="#fa8072"&gt;|&lt;/font&gt;Xr &lt;font color="#fa8072"&gt;then&lt;/font&gt;&lt;br /&gt;      &lt;font color="#fa8072"&gt;if&lt;/font&gt; {IsOdd X} &lt;font color="#fa8072"&gt;then&lt;/font&gt;&lt;br /&gt;         X&lt;font color="#fa8072"&gt;|&lt;/font&gt;{RemoveEvenNumbers Xr}&lt;br /&gt;      &lt;font color="#fa8072"&gt;else&lt;/font&gt;&lt;br /&gt;         {RemoveEvenNumbers Xr}&lt;br /&gt;      &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;   &lt;font color="#fa8072"&gt;[]&lt;/font&gt; nil &lt;font color="#fa8072"&gt;then&lt;/font&gt; nil&lt;br /&gt;   &lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;Sum&lt;/b&gt;&lt;/font&gt; Xs}&lt;br /&gt;   {FoldL Xs Number&lt;font color="#fa8072"&gt;.&lt;/font&gt;&lt;font color="#ffa07a"&gt;'+'&lt;/font&gt; 0}&lt;br /&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;SumOfOddNumbers&lt;/b&gt;&lt;/font&gt; Xs}&lt;br /&gt;   {Sum&lt;br /&gt;    {RemoveEvenNumbers Xs}&lt;br /&gt;   }&lt;br /&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;proc&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;Main&lt;/b&gt;&lt;/font&gt;}&lt;br /&gt;   {System&lt;font color="#fa8072"&gt;.&lt;/font&gt;show {SumOfOddNumbers [&lt;font color="#fa8072"&gt;~&lt;/font&gt;3 &lt;font color="#fa8072"&gt;~&lt;/font&gt;2 &lt;font color="#fa8072"&gt;~&lt;/font&gt;1 0 1]}}&lt;br /&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="#fa8072"&gt;in&lt;/font&gt;&lt;br /&gt;{Main}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;(The example has to be executed in the "OPI", i.e. from within Emacs in "Oz mode". Don't forget to save the buffer first because the debugger needs a buffer filename to work correctly.&lt;br /&gt;The Oz syntax may look unfamiliar first, but it is in fact not much different from other functional languages.&lt;br /&gt;&lt;code&gt;fun {Name FormalArg1 FormalArg2) ... end&lt;/code&gt; defines a function "Name" with two arguments.&lt;br /&gt;&lt;code&gt;{Name ActualArg1 ActualArg2}&lt;/code&gt; calls the defined function.&lt;br /&gt;The &lt;code&gt;case&lt;/code&gt; statement is a pattern matching construct and &lt;code&gt;X|Xr&lt;/code&gt; constructs a list with the head &lt;code&gt;X&lt;/code&gt; and the tail &lt;code&gt;Xr&lt;/code&gt;.)&lt;/blockquote&gt;&lt;br /&gt;The example program is intended to calculate and display the sum of a list of numbers, only taking into account the odd numbers. When running the code (with Mozart version 1.3.2), the result is: &lt;code&gt;1&lt;/code&gt;. Huh? It should of course be &lt;code&gt;-3 + -1 + 1 = -3&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;With the cursor on the call to &lt;code&gt;SumOfOddNumbers&lt;/code&gt;, the debugger is started with a keyboard shortcut (M-Shift-t). Its output is the following annotated code, shown in a new Emacs buffer:&lt;br /&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 10pt; COLOR: #f5deb3; BACKGROUND-COLOR: #2f4f4f"&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;SumOfOddNumbers&lt;/b&gt;&lt;/font&gt; Xs}&lt;br /&gt;   {Sum&lt;br /&gt;    {RemoveEvenNumbers Xs} &lt;font color="#add8e6"&gt;%%&lt;/font&gt;&lt;font color="#add8e6"&gt;&amp;gt; Xs:[~3 ~2 ~1 0 1] {RemoveEvenNumber..}:[1] &lt;br /&gt;&lt;/font&gt;   }                       &lt;font color="#add8e6"&gt;%%&lt;/font&gt;&lt;font color="#add8e6"&gt;&amp;gt; {Sum    {Remov..}:1 &lt;br /&gt;&lt;/font&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;The problem seems to be the function &lt;code&gt;RemoveEvenNumbers&lt;/code&gt;. Its result is the single-element list &lt;code&gt;[1]&lt;/code&gt;, which is certainly not expected.&lt;br /&gt;We move the cursor to the call to &lt;code&gt;RemoveEvenNumbers&lt;/code&gt; and press M-Shift-t again. The debugger will annotate the source code of &lt;code&gt;RemoveEvenNumbers&lt;/code&gt; as if it was executed with the current parameters bindings:&lt;br /&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 10pt; COLOR: #f5deb3; BACKGROUND-COLOR: #2f4f4f"&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;RemoveEvenNumbers&lt;/b&gt;&lt;/font&gt; Xs}&lt;br /&gt;   &lt;font color="#fa8072"&gt;case&lt;/font&gt; Xs &lt;font color="#fa8072"&gt;of&lt;/font&gt; X&lt;font color="#fa8072"&gt;|&lt;/font&gt;Xr &lt;font color="#fa8072"&gt;then&lt;/font&gt;        &lt;font color="#add8e6"&gt;%%&lt;/font&gt;&lt;font color="#add8e6"&gt;&amp;gt; Xs:[~3 ~2 ~1 0 1] &amp;lt;&amp;lt;X|Xr&amp;gt;&amp;gt;:success &lt;br /&gt;&lt;/font&gt;      &lt;font color="#fa8072"&gt;if&lt;/font&gt; {IsOdd X} &lt;font color="#fa8072"&gt;then&lt;/font&gt;        &lt;font color="#add8e6"&gt;%%&lt;/font&gt;&lt;font color="#add8e6"&gt;&amp;gt; X:~3 {IsOdd X}:false &lt;br /&gt;&lt;/font&gt;         X&lt;font color="#fa8072"&gt;|&lt;/font&gt;{RemoveEvenNumbers Xr}&lt;br /&gt;      &lt;font color="#fa8072"&gt;else&lt;/font&gt;&lt;br /&gt;         {RemoveEvenNumbers Xr}&lt;font color="#add8e6"&gt;%%&lt;/font&gt;&lt;font color="#add8e6"&gt;&amp;gt; Xr:[~2 ~1 0 1] {RemoveEvenNumber..}:[1] &lt;br /&gt;&lt;/font&gt;      &lt;font color="#fa8072"&gt;end&lt;/font&gt;                      &lt;font color="#add8e6"&gt;%%&lt;/font&gt;&lt;font color="#add8e6"&gt;&amp;gt; &amp;lt;&amp;lt;if {IsOdd X} t..&amp;gt;&amp;gt;:[1] &lt;br /&gt;&lt;/font&gt;   &lt;font color="#fa8072"&gt;[]&lt;/font&gt; nil &lt;font color="#fa8072"&gt;then&lt;/font&gt; nil&lt;br /&gt;   &lt;font color="#fa8072"&gt;end&lt;/font&gt;                         &lt;font color="#add8e6"&gt;%%&lt;/font&gt;&lt;font color="#add8e6"&gt;&amp;gt; &amp;lt;&amp;lt;case Xs of X|X..&amp;gt;&amp;gt;:[1] &lt;br /&gt;&lt;/font&gt;&lt;font color="#fa8072"&gt;end&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Curiously, the system function &lt;code&gt;IsOdd&lt;/code&gt; returns &lt;code&gt;false&lt;/code&gt; for the input value &lt;code&gt;~3&lt;/code&gt; (Oz notation for "-3"). This is unexpected! It looks like we found an error in the system libraries.&lt;br /&gt;&lt;br /&gt;Let's check the source code of &lt;code&gt;IsOdd&lt;/code&gt; (again with M-Shift-t):&lt;br /&gt;&lt;br /&gt;&lt;div style="FONT-SIZE: 10pt; COLOR: #f5deb3; BACKGROUND-COLOR: #2f4f4f"&gt;&lt;br /&gt;&lt;pre&gt;&lt;font color="#fa8072"&gt;fun&lt;/font&gt;&lt;font color="#7fffd4"&gt;&lt;b&gt; &lt;/b&gt;&lt;/font&gt;{&lt;font color="#7fffd4"&gt;&lt;b&gt;IsOdd&lt;/b&gt;&lt;/font&gt; X} X &lt;font color="#fa8072"&gt;mod&lt;/font&gt; 2 &lt;font color="#fa8072"&gt;==&lt;/font&gt; 1 &lt;font color="#fa8072"&gt;end&lt;/font&gt; &lt;font color="#add8e6"&gt;%%&lt;/font&gt;&lt;font color="#add8e6"&gt;&amp;gt; X:~3 &amp;lt;&amp;lt; X mod 2&amp;gt;&amp;gt;:~1 &amp;lt;&amp;lt;X mod 2..&amp;gt;&amp;gt;:false&lt;/font&gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Finally, we found the real bug. &lt;code&gt;IsOdd&lt;/code&gt; only works correctly for non-negative numbers because &lt;code&gt;X mod 2&lt;/code&gt; is negative for odd negative values of X. The underlying problem is that in Oz the modulo operation returns a negative result for negative dividends (as in many other languages), while in math, the result is always positive.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;(In reality, I did &lt;em&gt;not &lt;/em&gt; find this bug, but another Oz user did and the bug is already fixed in the subversion repository.)&lt;/blockquote&gt;&lt;br /&gt;&lt;H3&gt;Conclusion&lt;/H3&gt;With the standard Oz debugger &lt;A href="http://www.mozart-oz.org/home/doc/ozcar/index.html"&gt;Ozcar&lt;/A&gt; (which is very usable), it takes about 12 key strokes and some mouse work to find out the reason for the bug in this small example. Using the alternative approach, it takes two key strokes plus some navigating in Emacs.&lt;br /&gt;I believe this is a significant improvement. The biggest advantage is that you can easily inspect the values of all variables and the result of function calls at every place within the debugged function - just by looking at the annotated source code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;H3&gt;Limitations&lt;/H3&gt;The current implementation has some serious limitations. Some of these can be overcome by more sophisticated implementations, with some I'm not so sure:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The display space for annotations is limited. Large data cannot be shown completely. This can be resolved by an implementation which allows to explore the annotations interactively.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The debugger shows inconsistent results if the 'world' changes between executions, e.g. if global state is involved or external files are read and written. To solve this, one needs a debugger which remembers the state of all variables, along the complete callgraph, such that multiple executions are not necessary. For large programs, this might be impractical.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;One of the features of Oz which are not supported, are &lt;code&gt;for&lt;/code&gt; loops. They are in fact difficult to support because it would be necessary to annotate the code with the data of every single run of the loop.&lt;br /&gt;Recursive function like &lt;code&gt;FoldL&lt;/code&gt; are less problematic. You can simply press M-Shift-t again and again if you want to explore the nested calls to such a function.&lt;br /&gt;&lt;em&gt;The proposed approach to debugging therefore seems to be more useful for (mostly) functional programming language like Haskell or Oz than for imperative languages like C++, which very much depend on the use of loops.&lt;/em&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;sup&gt;&lt;A name="download"&gt;1&lt;/A&gt;&lt;/sup&gt;The prototypical implementation of the source-code annotating debugger for Oz can be downloaded &lt;A href="http://code.google.com/p/oz-code/"&gt;here&lt;/A&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/825172855488132129-1543175880764851770?l=wolfgangmeyer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://wolfgangmeyer.blogspot.com/feeds/1543175880764851770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=825172855488132129&amp;postID=1543175880764851770' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/825172855488132129/posts/default/1543175880764851770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/825172855488132129/posts/default/1543175880764851770'/><link rel='alternate' type='text/html' href='http://wolfgangmeyer.blogspot.com/2008/04/debuggers-are-needlessly-tedious-to-use.html' title='Debuggers are Needlessly Tedious to Use'/><author><name>Wolfgang Meyer</name><uri>http://www.blogger.com/profile/08636669076392383554</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry></feed>
