<?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-2162461901212281926</id><updated>2012-02-07T14:08:16.193-08:00</updated><category term='correctness'/><category term='haskell galois professional-development course'/><category term='commute'/><category term='math'/><category term='advice'/><category term='hackingsprint'/><category term='latex'/><category term='tutorial'/><category term='continuations'/><category term='cabal'/><category term='syntax'/><category term='pdx'/><category term='freedom'/><category term='gui'/><category term='libraries'/><category term='proof'/><category term='chrome'/><category term='types'/><category term='ghc'/><category term='c'/><category term='evidence'/><category term='ui'/><category term='takusen'/><category term='darcs'/><category term='opengl'/><category term='git'/><category term='opinion'/><category term='metrics'/><category term='haskell'/><category term='gcc'/><category term='performance'/><category term='testing'/><category term='imported'/><category term='database'/><title type='text'>dagit.o</title><subtitle type='html'>compilations of a developer</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.codersbase.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/-/darcs'/><link rel='alternate' type='text/html' href='http://blog.codersbase.com/search/label/darcs'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>dagitj</name><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>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2162461901212281926.post-276452137364072993</id><published>2010-08-29T15:40:00.000-07:00</published><updated>2011-03-17T21:20:53.776-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='metrics'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='darcs'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>Fun, but pointless, code metrics</title><content type='html'>I'm not really sure what motivated this, but I just used &lt;a href="http://cloc.sourceforge.net/"&gt;cloc&lt;/a&gt;&amp;nbsp;to count the lines of code in both the darcs source and the git source. &amp;nbsp;Here are the numbers.  The git source tree: &lt;pre&gt;1951 text files.&lt;br /&gt;    1836 unique files.                                          &lt;br /&gt;     848 files ignored.&lt;br /&gt;&lt;br /&gt;http://cloc.sourceforge.net v 1.51  T=15.0 s (72.3 files/s, 20377.3 lines/s)&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;Language                      files          blank        comment           code&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;C                               267          15517          13469         100133&lt;br /&gt;Bourne Shell                    589          15127           5508          84826&lt;br /&gt;Perl                             40           3798           3441          23825&lt;br /&gt;Tcl/Tk                           39           1453            375           9762&lt;br /&gt;C/C++ Header                     99           1977           3557           8301&lt;br /&gt;make                             12            413            434           2673&lt;br /&gt;Bourne Again Shell                1            144            110           2165&lt;br /&gt;Lisp                              2            231            170           1779&lt;br /&gt;Python                           13            465            442           1384&lt;br /&gt;ASP.Net                           8            141              0            931&lt;br /&gt;m4                                2             87             21            858&lt;br /&gt;CSS                               2            154             24            710&lt;br /&gt;Javascript                        2            113            319            477&lt;br /&gt;Assembly                          1             26            100             98&lt;br /&gt;XSLT                              7             15             29             77&lt;br /&gt;DOS Batch                         1              0              0              1&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;SUM:                           1085          39661          27999         238000&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;The darcs source tree: &lt;pre &gt;561 text files.&lt;br /&gt;     549 unique files.                                          &lt;br /&gt;      57 files ignored.&lt;br /&gt;&lt;br /&gt;http://cloc.sourceforge.net v 1.51  T=189.0 s (2.7 files/s, 298.0 lines/s)&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;Language                      files          blank        comment           code&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;Haskell                         169           4361           7374          27760&lt;br /&gt;Bourne Shell                    300           2071           2869           8333&lt;br /&gt;C                                 7            325            153           1494&lt;br /&gt;HTML                              5             41              4            316&lt;br /&gt;C/C++ Header                     12             92             83            308&lt;br /&gt;Bourne Again Shell                3             51             95            180&lt;br /&gt;Perl                              2             43             36            130&lt;br /&gt;CSS                               1             21              3             79&lt;br /&gt;make                              1             12              6             53&lt;br /&gt;Lisp                              1              5              6             23&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;SUM:                            501           7022          10629          38676&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;Take those categories with a grain of salt.  For example, the darcs source does not have any lisp files.  It is interesting that git has 200k more lines than darcs.  I'm not sure what that says.  C is far more verbose than Haskell?  Although, that's not really fair because they also have an order of magnitude more shell code.  If you're just comparing C to Haskell it's a factor of about 4.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2162461901212281926-276452137364072993?l=blog.codersbase.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.codersbase.com/feeds/276452137364072993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.codersbase.com/2010/08/fun-but-pointless-code-metrics.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/276452137364072993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/276452137364072993'/><link rel='alternate' type='text/html' href='http://blog.codersbase.com/2010/08/fun-but-pointless-code-metrics.html' title='Fun, but pointless, code metrics'/><author><name>dagitj</name><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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2162461901212281926.post-886636038132476412</id><published>2010-06-10T13:44:00.000-07:00</published><updated>2010-06-10T13:44:01.357-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='darcs'/><category scheme='http://www.blogger.com/atom/ns#' term='continuations'/><title type='text'>Delimited Continuations and version control: an update</title><content type='html'>Last time I presented the idea that version control and delimited continuations are related. &amp;nbsp;I left off with a question how how to make Darcs fit this model. &amp;nbsp;I think I understand now what I was missing.&lt;br /&gt;&lt;br /&gt;I forgot to think about Darcs operations in terms of the intermediate operations that get performed. &amp;nbsp;In Darcs, everything is based on commuting patches, even merging. &amp;nbsp;Therefore, to see how Darcs fits into this model it's important to think about commuting patches in terms of delimited continuations.&lt;br /&gt;&lt;br /&gt;Specifically, I now believe that commuting two patches introduces marks that can be &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;ed to later.&lt;br /&gt;&lt;br /&gt;I have several ideas for the next steps of this. &amp;nbsp;One is to start modeling toy versions of svn and darcs in Haskell via delimited continuations. &amp;nbsp;After that, I would like to figure out the correspondence between the delimited continuations that I've identified and their data structure reification as zippers. &amp;nbsp;I hope to have more about that later.&lt;br /&gt;&lt;br /&gt;Judging by a paper written by Oleg, there should be a natural way to convert the delimited continuation representation into a zipper. &amp;nbsp;Investigating this model might shed light on the Darcs patch model, or even lead to a more concise formalism.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2162461901212281926-886636038132476412?l=blog.codersbase.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.codersbase.com/feeds/886636038132476412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.codersbase.com/2010/06/delimited-continuations-and-version_10.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/886636038132476412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/886636038132476412'/><link rel='alternate' type='text/html' href='http://blog.codersbase.com/2010/06/delimited-continuations-and-version_10.html' title='Delimited Continuations and version control: an update'/><author><name>dagitj</name><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-2162461901212281926.post-4736936267421045057</id><published>2010-06-06T02:30:00.000-07:00</published><updated>2010-06-06T02:41:55.134-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='darcs'/><category scheme='http://www.blogger.com/atom/ns#' term='continuations'/><title type='text'>Delimited Continuations and Version Control</title><content type='html'>Delimited continuations give us a way to create markers that we can jump back to.  We can construct the future of the computation, work with the computation so far, or abort the current continuation and go down a new path (create a new future).&lt;br /&gt;&lt;br /&gt;These primitives have a natural correspondence with version control systems that snapshot the world like&lt;br /&gt;SVN. &amp;nbsp;Focusing on SVN for a moment:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The current continuation is the transformation of repository state that you're working on. &amp;nbsp;It's the diff you're creating.&lt;/li&gt;&lt;li&gt;For commits, each revision created by commit is a marker, so we model this with &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Checking out an older revision, or reverting changes, corresponds to &lt;span class="Apple-style-span" style="font-family: inherit;"&gt;a &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;. &amp;nbsp;We discard the current continuation and move back to a marker created by a specific &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Updating consists of having the client copy learn the current state of the continuation on the server and applying it to the local copy.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Starting a branch corresponds to a &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Merging two branches is a bit trickier I suspect. &amp;nbsp;I haven't worked out all the details sufficiently to convince myself I have it right, but here is how I think this case works. &amp;nbsp;The merge first &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;s to each of the markers and then combines those two continuations into one future. &amp;nbsp;The part that seems weird to me about this, is that I haven't really seen examples of delimited continuations were the continuation of two different markers (prompts) were combined.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Now, if you accept the above it gives us some intuition to build on. &amp;nbsp;Although my correspondence is terribly informal at the moment, if we took some time to make it formal by working out enough details to model it in, say, Haskell, then we'd have a nice formal backing for how SVN works. &amp;nbsp;I think the above model applies equally well to git, but I'm not confident with git's model.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One insight the above gives, is that the way merging works is not described by the continuations in general. &amp;nbsp;It's up to the exact combining function to determine the merge. &amp;nbsp;We know that an automatic merge can fail in practice due to things like conflicts between the changes in the branches. &amp;nbsp;So, in the SVN implementation considerable work has gone into implementing logic for creating the proper continuation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now, in general when a merge, or update, is performed human intervention may be required. &amp;nbsp;This typically happens when the changes are in conflict. &amp;nbsp;What this means for our model is that in general the creation of the continuation requires knowledge outside of our model. &amp;nbsp;What does that correspond to? &amp;nbsp;Well, it's essentially saying that calculating the correct continuation to resolve the merge is &lt;b&gt;non-deterministic&lt;/b&gt;!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In other words, this continuation view of version control gives us a rigorous way to talk about our intuition. &amp;nbsp;Of course we can easily tell that merging is going to require human intervention without needing to study delimited continuations, but this framework of reasoning now gives us a more mathematical way to say it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The next question is: &amp;nbsp; How does the delimited continuation model of vcs apply to Darcs?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So far I'm not sure. &amp;nbsp;I suspect, without working through the details, that in Darcs, every time you record a patch multiple &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;s happen, instead of just one. &amp;nbsp;The model really breaks down for Darcs because you can seemingly visit points in "history" that did not exist when the patches were created, but they are valid repository states.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;For example, imagine a repository that only exists locally. &amp;nbsp;You create a sequence of patches. &amp;nbsp;Now, take a patch in the middle that can be commuted to the end of the patch sequence. &amp;nbsp;Doing so has not created a new repository state; so far this is fine with the above model as no new markers need to be created. &amp;nbsp;Suppose we remove the patch from the end of the patch sequence. &amp;nbsp;This is exactly how darcs unpull works. &amp;nbsp;The funny thing is, we've now created a state that never existed previously. &amp;nbsp;So in the delimited continuation model, what marker did we just &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;to?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;I don't know the answer yet, but I think it's an interesting question. &amp;nbsp;I suspect there are multiple "correct" answers, but that only some answers will yield elegant and robust models here.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2162461901212281926-4736936267421045057?l=blog.codersbase.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.codersbase.com/feeds/4736936267421045057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.codersbase.com/2010/06/delimited-continuations-and-version.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/4736936267421045057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/4736936267421045057'/><link rel='alternate' type='text/html' href='http://blog.codersbase.com/2010/06/delimited-continuations-and-version.html' title='Delimited Continuations and Version Control'/><author><name>dagitj</name><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>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2162461901212281926.post-7268393640516106517</id><published>2009-03-25T01:12:00.000-07:00</published><updated>2010-06-06T01:14:44.495-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='darcs'/><category scheme='http://www.blogger.com/atom/ns#' term='imported'/><title type='text'>Type-Correct Changes — A Safe Approach to Version Control Implementation</title><content type='html'>&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;On March 20th, 2009, I successfully defended my Master’s thesis in Computer Science.&lt;br /&gt;&lt;br /&gt;Abstract:&lt;br /&gt;Ensuring correctness of real-world software applications is a challenging task. Testing can be used to find many bugs, but is typically not sufficient for proving correctness or even eliminating entire classes of bugs. However, formal proof and verification techniques tend to be very heavy weight and are simply not available for day to day use in many common programming environments.&lt;br /&gt;&lt;br /&gt;We demonstrate a form of light-weight proof assistant by using the type checking features of the programming language Haskell with existing extensions. We apply this work to the Open Source version control system Darcs. The properties checked by our approach are derived directly from the data model used by Darcs. This allows us to eliminate entire classes of bugs at compile time. We also examine how these techniques improve the quality of the Darcs codebase and the challenges that arise when applying these techniques in practice.&lt;br /&gt;&lt;br /&gt;You can read the&amp;nbsp;&lt;a href="http://files.codersbase.com/thesis.pdf" style="color: #2244bb;" target="_blank"&gt;full thesis here&lt;/a&gt;. The slides from my&amp;nbsp;&lt;a href="http://files.codersbase.com/thesistalk.pdf" style="color: #2244bb;" target="_blank"&gt;presentation are located here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The bottom line is that we used Generalized Algebraic Data Types (GADTs) to enforce proper patch manipulations. In the Darcs implementation, patches are stored in sequences and rearranging those sequences can only be done is very specific ways. Our use of GADTs allowed us to express those constraints using existentially quantified types, phantom types, and witness types. If you’ve ever wondered how to use GADTs in real-world software, this serves as a very illustrative example.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2162461901212281926-7268393640516106517?l=blog.codersbase.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.codersbase.com/feeds/7268393640516106517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.codersbase.com/2009/03/type-correct-changes-safe-approach-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/7268393640516106517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/7268393640516106517'/><link rel='alternate' type='text/html' href='http://blog.codersbase.com/2009/03/type-correct-changes-safe-approach-to.html' title='Type-Correct Changes — A Safe Approach to Version Control Implementation'/><author><name>dagitj</name><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-2162461901212281926.post-1119345114761663919</id><published>2008-10-28T01:09:00.000-07:00</published><updated>2010-06-06T01:14:44.503-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hackingsprint'/><category scheme='http://www.blogger.com/atom/ns#' term='pdx'/><category scheme='http://www.blogger.com/atom/ns#' term='haskell'/><category scheme='http://www.blogger.com/atom/ns#' term='darcs'/><category scheme='http://www.blogger.com/atom/ns#' term='imported'/><title type='text'>Darcs Hacking Sprint — Summary from Portland Team</title><content type='html'>&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;The weekend of 24-25 October 2008 was an&amp;nbsp;&lt;strong&gt;International&lt;/strong&gt;&amp;nbsp;darcs hacking sprint! The sprint was a lot of fun and we’ll be having more. The sprint provides a very productive atmosphere for hacking.&lt;br /&gt;&lt;br /&gt;We had a team in Brighton with posts from&amp;nbsp;&lt;a href="http://koweycode.blogspot.com/2008/10/darcs-hacking-sprints-some-pictures.html" style="color: #2244bb;" target="_blank"&gt;Day 1&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="http://koweycode.blogspot.com/2008/10/darcs-hacking-sprint-team-brighton-day.html" style="color: #2244bb;" target="_blank"&gt;Day 2&lt;/a&gt;. We also had team in Paris but I don’t have a link for them.&lt;br /&gt;&lt;br /&gt;Here are just some of the highlights from the Portland Team:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Adding language pragmas in all files:&lt;ul&gt;&lt;li&gt;makes the code cleaner when it’s time to drop ghc6.6 support&lt;/li&gt;&lt;li&gt;all required language extensions are now known&lt;/li&gt;&lt;li&gt;makes it easier to check for Haskell’ compatibility&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Removed OldFastPackedStrings&lt;/li&gt;&lt;li&gt;Replaced FastPackedStrings api in favor of Data.ByteString api&lt;ul&gt;&lt;li&gt;lots of small optimizations, less pack/unpack, more standard&lt;br /&gt;ByteString code&lt;/li&gt;&lt;li&gt;removed a fair bit of C code, new code compiles to same or&lt;br /&gt;faster assembly (Don checked)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;cabalization:&lt;ul&gt;&lt;li&gt;no autoconf or make needed&lt;/li&gt;&lt;li&gt;cabal install tested and working on linux / osx, windows testing&lt;br /&gt;soon to follow&lt;/li&gt;&lt;li&gt;builds out of the box w/ 6.8 and 6.10&lt;/li&gt;&lt;li&gt;configure is much faster&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://galois.com/~dons/images/darcs.svg" style="color: #2244bb;" target="_blank"&gt;module graph&lt;/a&gt;&amp;nbsp;(depends on cabalization)&lt;/li&gt;&lt;li&gt;Duncan improved zlib&lt;ul&gt;&lt;li&gt;soon to be available on hackage&lt;/li&gt;&lt;li&gt;allows us to replace our own implementation of zlib bindings&lt;br /&gt;with the main stream one&lt;/li&gt;&lt;li&gt;will make building on windows easier&lt;/li&gt;&lt;li&gt;can use lazy bytestrings&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;Here are some random pictures from the Portland Sprint.&lt;br /&gt;Packages we should consider:&lt;br /&gt;&lt;img alt="Packages we should consider" src="http://galois.com/~dons/images/darcs-oct-08/Image003.jpg" /&gt;&lt;br /&gt;The TODO list we made on the first day:&lt;br /&gt;&lt;img alt="The TODO list we made on the first day" src="http://galois.com/~dons/images/darcs-oct-08/Image004.jpg" /&gt;&lt;br /&gt;Checking on Team Brighton:&lt;br /&gt;&lt;img alt="Checking on Team Brighton" src="http://galois.com/~dons/images/darcs-oct-08/Image006.jpg" /&gt;&lt;br /&gt;Duncan and Jason looking at the projector:&lt;br /&gt;&lt;img alt="Duncan and Jason looking at the projector" src="http://galois.com/~dons/images/darcs-oct-08/Image007.jpg" /&gt;&lt;br /&gt;Ah, beautiful Portland in fall:&lt;br /&gt;&lt;img alt="Ah, beautiful Portland in fall" src="http://galois.com/~dons/images/darcs-oct-08/Image002.jpg" /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2162461901212281926-1119345114761663919?l=blog.codersbase.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.codersbase.com/feeds/1119345114761663919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.codersbase.com/2008/10/darcs-hacking-sprint-summary-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/1119345114761663919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/1119345114761663919'/><link rel='alternate' type='text/html' href='http://blog.codersbase.com/2008/10/darcs-hacking-sprint-summary-from.html' title='Darcs Hacking Sprint — Summary from Portland Team'/><author><name>dagitj</name><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-2162461901212281926.post-4382491760195973846</id><published>2008-10-24T00:52:00.000-07:00</published><updated>2010-06-06T01:14:44.511-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='commute'/><category scheme='http://www.blogger.com/atom/ns#' term='darcs'/><category scheme='http://www.blogger.com/atom/ns#' term='imported'/><title type='text'>Understanding Darcs Commute</title><content type='html'>&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;People often want to understand how commute on patches works. Usually we start by saying:&lt;br /&gt;&lt;blockquote&gt;Given two patches, A and B, if A and B commute then: AB &amp;lt;--&amp;gt; B’ A’, for some B’ and A’.&lt;/blockquote&gt;Naturally people ask, “But what is the relationship between A and A’ or B and B’?”&amp;nbsp;This is a very important question and I’ll provide you with some insight.&lt;br /&gt;&lt;br /&gt;Suppose we have a repository with 2 files, a and b. We could then make the following operations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;mv b c&lt;/li&gt;&lt;li&gt;mv a b&lt;/li&gt;&lt;li&gt;mv c a&lt;/li&gt;&lt;/ul&gt;You can think of each operation as a transformation on the ’state’ of your repository.&lt;br /&gt;Suppose also, that we make an edit to a, and an edit to b.&lt;br /&gt;&lt;br /&gt;Let’s name the above, using T for transformation:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;T_bc = mv b c&lt;/li&gt;&lt;li&gt;T_ab = mv a b&lt;/li&gt;&lt;li&gt;T_ca = mv c a&lt;/li&gt;&lt;li&gt;T_a = edit a&lt;/li&gt;&lt;li&gt;T_b = edit b&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;You can imagine that if I gave the diff for T_a and the diff for T_b that you could apply those diffs in either order to your repository and get the same final ’state’. Meaning, a and b are the same whether you update a first or b first.&lt;br /&gt;&lt;br /&gt;But, suppose instead that I performed T_bc, T_ab, and then T_ca. This has the effect of swapping a and b by name. Now suppose you applied the diffs T_a and T_b. What would you want the outcome to be?&lt;br /&gt;It turns out, that it matters which operations were created first. If you created the diffs T_a and T_b *before* you did the operations of the swap, then you should expect that after the swap the diff for T_a actually modifies b, whereas T_b should modify a. On the other hand, if you created the diffs T_a and T_b *after* the swap, then you expect T_a to modify a and T_b to modify b.&lt;br /&gt;&lt;br /&gt;We have an intuitive idea of ‘context’ now. As in, what is the context that T_a and T_b were created in? Knowing this will tell us how they transform the repository state.&lt;br /&gt;&lt;br /&gt;Intuitively, it seems as though we need to remember the ‘context’ in which T_a and T_b were created. So let’s say that the operations performed up to the point where T_a is created is the context of T_a. In other words, the context for T_a is sequence of transformations that existed when T_a was created.&amp;nbsp;Similarly, since T_a is a transformation, creating it results in a new context, which is the old context plus T_a. We could say that T_b has this context. Going a bit further, it seems like we should talk about how T_a has a pre-context and it also has a post-context.&lt;br /&gt;&lt;br /&gt;For example, if we created T_a before doing the swap, then the pre-context might include two transformations, one that creates a and another one that creates b. The post-context would then include those two transformations and T_a itself. If we created T_a after doing the swap, the pre-context and post-contexts of T_a would include T_bc, T_ab and T_ca also.&lt;br /&gt;&lt;br /&gt;Now a side note about commutative functions. Consider the function created by composing T_a and T_b, let’s write T_a . T_b. Recall, that with function composition parameters start on the right and pass through the sequence to the left. As discussed in the intro, T_a . T_b is equal to T_b . T_a. This is because T_a and T_b are independent of each other. Thus, we would say that the functions T_a and T_b are commutative functions. This means, that changing their order of application does not change the result.&lt;br /&gt;&lt;br /&gt;We are saying that:&lt;br /&gt;&lt;blockquote&gt;T_a . T_b = T_b . T_a&lt;/blockquote&gt;Because T_a and T_b are commutative it doesn’t matter which order we compose them. If we restrict our view to just the repository above with only the files a, b and no c, then on this restricted set of repository state how do these two compare?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;T_b . T_a&lt;/li&gt;&lt;li&gt;T_a . T_b . (T_ca . T_ab . T_bc)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;In plain English, the first one edits a and then b, the second one swaps a and b, edits b and finally edits a.&lt;br /&gt;As far as the mathematics of it is concerned, the first one will edit a and b, while the second one will have T_a editing a different a than the first one and T_b editing a different b than the second one.&lt;br /&gt;Going a bit further, let’s say that T_a and T_b were created without any of T_bc, T_ab or T_ca in their context. So we could have two scenarios.&lt;br /&gt;&lt;br /&gt;We could, for example, start with T_b and T_a, swap their order and then do the swap of a and b afterwards. That would give us:&lt;br /&gt;&lt;blockquote&gt;T_b . T_a&lt;/blockquote&gt;and&lt;br /&gt;&lt;blockquote&gt;(T_ca . T_ab . T_bc) . T_a . T_b&lt;/blockquote&gt;Intuitively, it seems like T_a and T_bc are commutative functions, eg., T_bc . T_a = T_a . T_bc. So we could rewrite the second one as this:&lt;br /&gt;&lt;blockquote&gt;T_ca . T_ab . T_a . T_bc . T_b&lt;/blockquote&gt;Now, suppose when we commute the function T_a with T_ab, that we replace T_a with T_a’. T_a’ is like T_a except that T_a’ makes the edits of T_a to b instead of a. After all, this results in T_a’ editing the correct file after the rename. Similarly, when we commute T_b with T_bc, T_b is replaced with T_b’ that edits c instead of b. When we commute T_b’ with T_ca we replace T_b’ with T_b” that edits a instead of c.&lt;br /&gt;&lt;br /&gt;So, the above goes through these steps:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;T_ca . T_a’ . T_ab . T_bc . T_b (commute T_a to the left)&lt;/li&gt;&lt;li&gt;T_a’ . T_ca . T_ab . T_bc . T_b (commute T_a’ to the left)&lt;/li&gt;&lt;li&gt;T_a’ . T_ca . T_ab . T_b’ . T_bc (commute T_b to the left)&lt;/li&gt;&lt;li&gt;T_a’ . T_ca . T_b’ . T_ab . T_bc (commute T_b’ to the left)&lt;/li&gt;&lt;li&gt;T_a’ . T_b” . T_ca . T_ab . T_bc&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;The last one will then have T_a’ and T_b” making edits the same file contents as T_a and T_b respectively, even though the names of the files were changed by the swap.&lt;br /&gt;&lt;br /&gt;So, if you’ve followed me to this point, then you now have the intuition for what we mean when two patches A and B, commute to B’ and A’, as AB &amp;lt;--&amp;gt; B’ A’. You can think of a patch as being one of the above transformations along with the context of the transformation. You might also notice that commute of patches must be doing something to the context of the patches.&lt;br /&gt;&lt;br /&gt;Patch commute has the potential to update the context and transformation the patches it swaps OR it could update the context and leave the state transformations equal to what they were in the input. Patch commute can also fail, but we’re ignoring that case for the moment.&lt;br /&gt;&lt;br /&gt;Thinking back to how we arrived at the need for context, you might notice that for each context, that is each sequence of operations, we get one unique repository state. This is a very important property of context. Without it, context wouldn’t really be useful. Also, notice that the opposite is not true, repository state does not determine the context. Which makes sense, because there are lots of operations you can do that get the repository to a particular state, so given a state how do you know what was done?&lt;br /&gt;&lt;br /&gt;The next important property we want for commuting patches is that once two patches have been commuted, you can commute them again to undo the commutation. In fact, it turns out the examples above are saying we want contexts to determine the same state if you commute the patches inside the context (again, context is a sequence of patches!).&lt;br /&gt;&lt;br /&gt;For R to be an equivalence relation, we need three things:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;x R x, is true for all x&lt;/li&gt;&lt;li&gt;if x R y then y R x&lt;/li&gt;&lt;li&gt;if x R y and y R z then x R z&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Here, we replace x R y with “the sequencing, or order, of x can be obtained by commuting adjacent elements of y”. Roughly how to prove each:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;either claim that 0 commutes satisfies definition of R or check that commute is self-inverting&lt;/li&gt;&lt;li&gt;relies on self-inverting nature, I think&lt;/li&gt;&lt;li&gt;messier but should still be provable&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I’m pretty sure both (2) and (3) could be done with a brute force proof that considered all the pairings of patch types in their general cases. Start with all sequences of length 2, then 3 and I think at that point you could make an inductive argument to hit sequences of length n. This would be a lot of work, and I’m not convinced it could be fully automated.&lt;br /&gt;&lt;br /&gt;Why would we want to show the above? Showing that R is a relation would tell us that sequences of patches are equivalent under commute. Now, combine this with the idea that context determines the state uniquely and now we know sets of patches uniquely determine your repository.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2162461901212281926-4382491760195973846?l=blog.codersbase.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.codersbase.com/feeds/4382491760195973846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.codersbase.com/2008/10/understanding-darcs-commute.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/4382491760195973846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/4382491760195973846'/><link rel='alternate' type='text/html' href='http://blog.codersbase.com/2008/10/understanding-darcs-commute.html' title='Understanding Darcs Commute'/><author><name>dagitj</name><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-2162461901212281926.post-2854675905894245184</id><published>2008-08-21T00:49:00.000-07:00</published><updated>2010-06-06T01:53:20.590-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='darcs'/><category scheme='http://www.blogger.com/atom/ns#' term='imported'/><title type='text'>Darcs 2 Real-World Push Performance Evaluation</title><content type='html'>&lt;span class="Apple-style-span" style="border-collapse: collapse; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;Thanks to&amp;nbsp;&lt;a href="http://koweycode.blogspot.com/" style="color: #2244bb;" target="_blank"&gt;Eric Kow&lt;/a&gt;, Duncan Coutts and Ian Lynagh we have some great timing data for using darcs2 and darcs1 to push patches over ssh.&lt;br /&gt;&lt;br /&gt;Eric wrote a script to test three different scenarios of using darcs to push patches:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Scenario l1r1:&lt;/li&gt;This is a local darcs1 client talking to a remote darcs1 executable.&lt;li&gt;Scenario l1r2:&lt;/li&gt;This is a local darcs1 client talking to a remote darcs2 executable.&lt;li&gt;Scenario l2r2:&lt;/li&gt;This is a local darcs2 client talking to a remote darcs2 executable.&lt;/ol&gt;Next, Duncan and Ian provided us with access to 131 real-world repositories hosted at&amp;nbsp;&lt;a href="http://code.haskell.org/" style="color: #2244bb;" target="_blank"&gt;http://code.haskell.org&lt;/a&gt;. We ran the script to push patches to each repository, this gave us a ton of times. Then in Excel we crunched these numbers to see that not only is scenario l2r2 no worse than the other two, it’s actually faster on the time consuming cases!&lt;br /&gt;&lt;br /&gt;The one caveat we found is that the minimum start-up time for the first two scenarios is 1 second and in the last scenario it’s 2 seconds. I’m confident we can shave off this 1 second difference in the future.&lt;br /&gt;&lt;img height="219" src="http://spreadsheets.google.com/pub?key=pCrZlx9LBLA2GSXzICOaULw&amp;amp;oid=2&amp;amp;output=image" style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px;" width="640" /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="-webkit-text-decorations-in-effect: none; color: black;"&gt;This is a histogram that shows you how the push times distribute, click on it for a large image. Along the bottom we have how many seconds the push took, and along the vertical axis we have the number of data points in that range. At a glance you can see that most repositories take just a few seconds to push. We can also see that darcs2 is slower on small pushes by about one second. Darcs2 in this chart corresponds to l2r2 and darcs1 corresponds to l1r1.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;On a side note, we also tested converting all the repositories to darcs2 repository format and that worked great as well. Converting all the repositories at once takes less than 20 minutes on my laptop without a single error. There were a few warnings, but that’s to be expected as potentially exponential merges are fixed in the new darcs2 format, but darcs emits a warning when fixing them.&lt;br /&gt;&lt;br /&gt;For anyone that wants to see the raw numbers click&amp;nbsp;&lt;a href="http://files.codersbase.com/darcs-times.htm" style="color: #2244bb;" target="_blank"&gt;here&lt;/a&gt;. The link does work, but not all web browsers are showing the numbers. Opera and FF3 work on some platforms and not others.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2162461901212281926-2854675905894245184?l=blog.codersbase.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.codersbase.com/feeds/2854675905894245184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://blog.codersbase.com/2008/08/darcs-2-real-world-push-performance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/2854675905894245184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2162461901212281926/posts/default/2854675905894245184'/><link rel='alternate' type='text/html' href='http://blog.codersbase.com/2008/08/darcs-2-real-world-push-performance.html' title='Darcs 2 Real-World Push Performance Evaluation'/><author><name>dagitj</name><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></feed>
