<?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-3246670076294002668</id><updated>2011-07-08T01:08:16.701-04:00</updated><category term='distributed'/><category term='nongeeky'/><category term='diversity'/><category term='tailor'/><category term='gabi'/><category term='dvcs'/><category term='trainwreak'/><category term='legacy'/><category term='house'/><category term='processing icfp geometry'/><category term='atlhack'/><category term='refactoring dvcs versioncontrol merging tools'/><category term='kittens'/><category term='vcs'/><title type='text'>shiftpop</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-793106839323023955</id><published>2008-12-30T10:36:00.002-05:00</published><updated>2008-12-30T11:10:07.758-05:00</updated><title type='text'>PHP's strtotime</title><content type='html'>I generally think of PHP as the buck-toothed high-school drop-out sibling of Perl (itself the unbathed cousin of Python and Ruby). But today I discovered the library function &lt;a href=""&gt;strtotime&lt;/a&gt;, which is a very flexible parser for text expressing a date/time. One cool example is &lt;a href="http://brian.moonspot.net/2008/09/20/strtotime-the-php-date-swiss-army-knife/"&gt;a snippet that calculates the current year's Thanksgiving day&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The closest Python equivalent to &lt;i&gt;strtotime&lt;/i&gt; seems to be &lt;a href="http://labix.org/python-dateutil#head-c0e81a473b647dfa787dc11e8c69557ec2c3ecd2"&gt;dateutil.parser.parse&lt;/a&gt;, though it's much less flexible from a cursory glance. Of course, if a person is only trying to compute "&lt;i&gt;common moveable Christian feasts that can be deduced from the date of Easter Sunday&lt;/i&gt;" they need look no further than the &lt;a href="http://books.google.com/books?id=bqteixWa98wC&amp;pg=PA259&amp;lpg=PA259&amp;dq=mx+date+feasts&amp;source=web&amp;ots=O5Xedzu-e7&amp;sig=GIi7n_oj9PQFLOgqcdKxSIwI6QY&amp;hl=en&amp;sa=X&amp;oi=book_result&amp;resnum=4&amp;ct=result"&gt;mx.DateTime.Feasts&lt;/a&gt; library (which includes translations into German and French). Weird. And awesome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-793106839323023955?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/793106839323023955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=793106839323023955' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/793106839323023955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/793106839323023955'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/12/phps-strtotime.html' title='PHP&apos;s strtotime'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-768256817691629439</id><published>2008-12-05T10:35:00.002-05:00</published><updated>2008-12-05T11:00:14.515-05:00</updated><title type='text'>Not Lazy Enough</title><content type='html'>It occurred to me that many performance problems when dealing with large datasets are due to programs not being "lazy enough". My example problem was "ALTER TABLE" statements in a database, which in most implementations will read, modify, and write every row in the table. Because with large tables this is a significant performance hit, we rarely see people doing "dynamic language things" i.e. altering their schemas in application logic.&lt;br /&gt;&lt;br /&gt;One reason for being non-lazy (some say: strict) is to ensure consistency across your dataset. If exact consistency is not a requirement, object/document stores like CouchDB or AppEngine's datastore can provide inexpensive "ALTER TABLE" behavior. With these systems, outdated/unaltered rows only need to be upgraded/altered when they're fetched from the datastore. Here's a case where deferring the "ALTER TABLE" code allows us to write more flexible/dynamic programs because our data management is lazier.&lt;br /&gt;&lt;br /&gt;Code can be too lazy though, resulting in bad caching behavior and sometimes huge memory space growth.&lt;br /&gt;&lt;br /&gt;Any other examples of cases where laziness/demand-driven-evaluation would be a performance win?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-768256817691629439?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/768256817691629439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=768256817691629439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/768256817691629439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/768256817691629439'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/12/not-lazy-enough.html' title='Not Lazy Enough'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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-3246670076294002668.post-5241715771890901704</id><published>2008-10-10T00:20:00.005-04:00</published><updated>2008-10-10T01:30:28.976-04:00</updated><title type='text'>Ten Years of Progress</title><content type='html'>"I'm afraid this is very bad. The stones tell me the boar god came from far to the west."&lt;br /&gt;&lt;img src="http://www.geocities.com/ericliao12/wise-woman.jpg"/&gt;&lt;br /&gt;&lt;br /&gt;Hello from October 10th 2008. The Dow Jones Industrial Average closed yesterday at &lt;a href="http://finance.yahoo.com/q/hp?s=%5EDJI&amp;a=09&amp;b=8&amp;c=2008&amp;d=09&amp;e=11&amp;f=2008&amp;g=d"&gt;8,579&lt;/a&gt; which is a little bit under its close of &lt;a href="http://finance.yahoo.com/q/hp?s=%5EDJI&amp;a=02&amp;b=8&amp;c=1998&amp;d=02&amp;e=11&amp;f=1998&amp;g=d"&gt;8,643&lt;/a&gt; on March 10th 1998.&lt;br /&gt;&lt;br /&gt;Does this mean that the global economy could have been &lt;i&gt;put on hold&lt;/i&gt; ten years ago and life would be just the same today?&lt;br /&gt;&lt;i&gt;Probably not.&lt;/i&gt; People have to eat.&lt;br /&gt;&lt;br /&gt;Does it mean that ten years worth of free market profit motive could have been thrown out the window, that executives could have been told to just &lt;i&gt;keep 'er runnin'&lt;/i&gt; and life would be just the same as today?&lt;br /&gt;&lt;i&gt;Probably not.&lt;/i&gt; There have been winners and losers, and markets have adjusted for changing consumer preferences over the decade.&lt;br /&gt;&lt;br /&gt;I don't know what it means.&lt;br /&gt;But it does seem like an appropriate time to ask:&lt;br /&gt;&lt;b&gt;"Have we been making &lt;a href="http://en.wikipedia.org/wiki/Progress"&gt;progress&lt;/a&gt;?"&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I think that the answer is: Yes!&lt;br /&gt;&lt;br /&gt;Though we may have to scale down our retirement plans, and start buying the less expensive brand of veggie burgers, our Wikipedia Content Index (WCI) just keeps growing:&lt;br /&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/6/6f/EnglishWikipediaArticleCountGraphs.png "&gt;&lt;img src="http://upload.wikimedia.org/wikipedia/commons/6/6f/EnglishWikipediaArticleCountGraphs.png" width="400"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And lest we ignore the importance of emerging global cute funds, think of how far we've come since &lt;a href="http://www.google.com/search2001/search?hl=en&amp;q=lolcats&amp;btnG=Google+Search"&gt;1998: a world without lolcats&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-5241715771890901704?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/5241715771890901704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=5241715771890901704' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/5241715771890901704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/5241715771890901704'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/10/ten-years-of-progress.html' title='Ten Years of Progress'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-6805233619782051208</id><published>2008-09-25T14:14:00.004-04:00</published><updated>2008-09-25T15:48:27.248-04:00</updated><title type='text'>Compiling x264 with MP4 support on OS X</title><content type='html'>I've been wanting to futz around with the internals of a modern video codec, and since H.264 seems like a pretty happening codec, and the x264 project seems pretty awesome,  I downloaded their source and tried compiling it on my Mac. I hit a few roadbumps, so here are instructions for anyone else who wants to compile x264 on OS X:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wget http://downloads.sourceforge.net/gpac/gpac-0.4.4.tar.gz&lt;br /&gt;open gpac # lazy-man's untar&lt;br /&gt;git clone git://git.videolan.org/x264.git x264&lt;br /&gt;cd gpac&lt;br /&gt;find . -name os_net.c | xargs perl -pi -e 's/u_long/unsigned long/g'&lt;br /&gt;./configure&lt;br /&gt;make lib&lt;br /&gt;make install-lib&lt;br /&gt;&lt;br /&gt;cd ../x264&lt;br /&gt;./configure --enable-mp4-output&lt;br /&gt;make&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then, to test that everything worked, run this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;wget notlime.com/2008/h264/foreman_part_qcif.yuv&lt;br /&gt;./x264 -v -q 20 -o foreman.mp4 foreman_part_qcif.yuv 176x144&lt;br /&gt;open foreman.mp4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If you don't have &lt;i&gt;git&lt;/i&gt; installed, you can find a nightly tarball of the x264 source code at &lt;a href="ftp://ftp.videolan.org/pub/videolan/x264/snapshots/"&gt;ftp://ftp.videolan.org/pub/videolan/x264/snapshots/&lt;/a&gt;. Hope this helps someone!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-6805233619782051208?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/6805233619782051208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=6805233619782051208' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/6805233619782051208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/6805233619782051208'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/09/compiling-x264-with-mp4-support-on-os-x.html' title='Compiling x264 with MP4 support on OS X'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-1108205118524570126</id><published>2008-09-02T21:38:00.002-04:00</published><updated>2008-09-02T21:44:43.354-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='processing icfp geometry'/><title type='text'>Growing Triangle Vines</title><content type='html'>When I was in school I was addicted to making &lt;a href="http://www.processing.org"&gt;Processing&lt;/a&gt; sketches. I haven't been as active recently, but made these in the past month and a half.&lt;br /&gt;&lt;br /&gt;The first is a visualization of a geometric computation that we used in the ICFP contest: &lt;a href="http://notlime.com/2008/processing/arcsin_of_r_over_d/"&gt;Arcsin of R / D&lt;/a&gt;&lt;br/&gt;&lt;br /&gt;And the second comes from a pen-and-paper sketch made on a legal pad during my WTC tenure: &lt;a href="http://notlime.com/2008/processing/iconic_growing_triangles/"&gt;Iconic Growing Triangles&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-1108205118524570126?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/1108205118524570126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=1108205118524570126' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/1108205118524570126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/1108205118524570126'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/09/growing-triangle-vines.html' title='Growing Triangle Vines'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-4121803640505345037</id><published>2008-08-26T22:52:00.004-04:00</published><updated>2008-08-26T23:52:05.065-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='refactoring dvcs versioncontrol merging tools'/><title type='text'>Persistent Refactorings</title><content type='html'>Refactorings are usually &lt;a href="http://www.science.uva.nl/~robbert/zappa/albums/Waka_Jawaka/03.html"&gt;one-shot deals&lt;/a&gt;,  triggered through an IDE, saved, committed, forgotten.&lt;br /&gt;&lt;br /&gt;Imagine for a moment though, that your revision control system was aware of refactorings, and recorded the refactoring command itself, not just the source text changes. You (or your IDE) might run this command:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;svn refactor pullup myFunction&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Which would record the refactoring and which could &lt;i&gt;be used to inform merges&lt;/i&gt; with other branches. Everyone loves easier merges of course, but if your automatic merge of two significantly-differently-structured-branches was nearly flawlessness, it would be possible to support two functionally equivalent, but architecturally different branches over a long timespan. In practice you could commit to either branch, and then pull from the other branch, relying on your version control system to refactor your changes so that the merge succeeded.&lt;br /&gt;&lt;br /&gt;Why do this?&lt;br /&gt;&lt;br /&gt;Perhaps you have a refactoring that reduces code-duplication but makes your codebase less readable, scannable, coherent. In this case you can branch and refactor, ending up with one easy-to-read branch, and one safe-to-modify-without-fear-of-missing-a-copy-pasted-version-of-the-same-function-in-another-module branch. Because the refactorings that we're considering here don't change the code functionally, these aren't really even branches, but simply two views on the same trunk.&lt;br /&gt;&lt;br /&gt;What other cases can you see this being handy for?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-4121803640505345037?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/4121803640505345037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=4121803640505345037' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/4121803640505345037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/4121803640505345037'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/08/persistent-refactorings.html' title='Persistent Refactorings'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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-3246670076294002668.post-2584394689532531053</id><published>2008-07-30T14:00:00.002-04:00</published><updated>2008-07-30T15:46:54.570-04:00</updated><title type='text'>Prolog Instantiation Modes (and Python exit contexts)</title><content type='html'>I wrote &lt;a href="http://code.google.com/p/python-macros/source/browse/trunk/return_context.py"&gt;a piece of Python code&lt;/a&gt; that does a funny little transform on the syntax tree of a function, and creates a new function that returns all the local variables defined at the exit point of the original function. When I explain this to someone, they ask "Why?" and I don't have a good answer, but usually I say that it's related to predicates in Prolog that have multiple calling modes. Which I'm going to try explaining here:&lt;br /&gt;&lt;br /&gt;So, Prolog doesn't have functions, but it has something called "predicates" which are just as good. Predicates don't return a value, but any argument to a predicate can be an "output" variable, like a &lt;a href="http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/PARAMS.html#ref"&gt;C reference parameter&lt;/a&gt;. Unlike C though, Prolog predicates often treat all of their parameters as outputs. For example, the function &lt;tt&gt;append&lt;/tt&gt; can be used in (no less than) three different ways.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/* Appending, mode = input,input,output */&lt;br /&gt;?- append([1,2,3],[4,5], X).&lt;br /&gt;X = [1,2,3,4,5]&lt;br /&gt;&lt;br /&gt;/* Trimming off a shared starting sequence, mode = input,output,input */&lt;br /&gt;?- append([1,2,3],X,[1,2,3,4,5]).&lt;br /&gt;X = [4,5]&lt;br /&gt;&lt;br /&gt;/* Trimming off a shared ending sequence, mode = output,input,input */&lt;br /&gt;?- append(X,[4,5],[1,2,3,4,5]).&lt;br /&gt;X = [1,2,3]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Through these three operations seem very different from the perspective of an imperative language, in Prolog &lt;tt&gt;append&lt;/tt&gt; can be &lt;a title="append([X|Y],Z,[X|W]) :- append(Y,Z,W). append([],X,X)." href="http://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_7.html"&gt;defined in two simple lines&lt;/a&gt;.  The intuition about Prolog is that the runtime doesn't think of variables so much as inputs and outputs, but as "things I already know" and "thinks I don't know yet".&lt;br /&gt;&lt;br /&gt;We can translate Prolog's &lt;a href="http://code.google.com/p/python-macros/source/browse/trunk/prology_append.py"&gt;append into Python&lt;/a&gt; (at some loss of conciseness and functionality), and then use the Python macro mentioned above to check that the variable bindings at the end of the function maintain the invariant that we expect:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;context = append_exit_context(None,[4,5],[1,2,3,4,5])&lt;br /&gt;assert context['head'] + context['tail'] == context['result']&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So, this is pretty cool, we can pretend that we're writing a predicate instead of a function, assigning computed values to variables when we're able to discover them, and then examine those bindings after running the predicate.&lt;br /&gt;&lt;br /&gt;Of course, Prolog's &lt;tt&gt;append&lt;/tt&gt; can also be called with the first two arguments uninstantiated, but that sort of magic is much harder to fit into Python.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-2584394689532531053?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/2584394689532531053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=2584394689532531053' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/2584394689532531053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/2584394689532531053'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/07/prolog-instantiation-modes-and-python.html' title='Prolog Instantiation Modes (and Python exit contexts)'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-4576407411912222411</id><published>2008-07-19T22:29:00.001-04:00</published><updated>2010-07-29T23:37:24.598-04:00</updated><title type='text'>Slow Sphinx Indexing</title><content type='html'>Tejus and I are building a Ruby on Rails site that needs both structured and unstructured search.  Hamed suggested that we use &lt;a href="http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html"&gt;Ultrasphinx&lt;/a&gt;, a Rails plugin that provides an interface to the &lt;a href="http://www.sphinxsearch.com/"&gt;Sphinx&lt;/a&gt; search backend.&lt;br /&gt;&lt;br /&gt;I got everything downloaded and compiled, and had figured out how to debug the &lt;tt&gt;nil:NilClass&lt;/tt&gt; errors that Ultrasphinx's configuration mini-language was generating, and then when I went to build the index for our database of seven documents... it seemed to hang. I was patient though, and let it run in the background for &lt;b&gt;10 minutes&lt;/b&gt;. This might be acceptable on a huge database, but... it was clear that something was wrong.&lt;br /&gt;&lt;br /&gt;Several hours of debugging led me to the root cause: sphinx was assuming that the primary keys of the indexed table were sequential, and was creating a query for every 5000 rows between the min and max id of that table. With an auto_increment primary key, this is a valid assumption, but our data was being loaded by an &lt;a href="http://wiki.rubyonrails.org/rails/pages/ActiveRecordYamlFixtures"&gt;ActiveRecord fixture&lt;/a&gt; which was generating random primary keys, so the range between min and max was nearly a billion, thus the number of queries was in the hundreds of thousands, all but seven of them returning nothing.&lt;br /&gt;&lt;br /&gt;The solution of course, is to put explicit id's on your fixtures.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-4576407411912222411?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/4576407411912222411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=4576407411912222411' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/4576407411912222411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/4576407411912222411'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/07/slow-sphinx-indexing.html' title='Slow Sphinx Indexing'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-4980161503580593172</id><published>2008-07-17T18:37:00.000-04:00</published><updated>2008-07-17T19:05:17.662-04:00</updated><title type='text'>ICFP 2008</title><content type='html'>Last weekend, I went over to the Monroe Drive House and wrote code for the &lt;a href="http://www.icfpcontest.org/"&gt;International Conference on Functional Programming Contest&lt;/a&gt;. Thankfully, the ICFP Contest doesn't require that your implementation language be purely functional (or even mostly functional), so we (Mark, Martin, and &lt;a href="http://www.subwindow.com"&gt;Erik&lt;/a&gt;) wrote our entry in python, using &lt;a href="http://twistedmatrix.com/trac/"&gt;twisted&lt;/a&gt; to handle network events. As we hacked on procedural code downstairs, &lt;a href="http://oniugnip.livejournal.com/"&gt;Alex&lt;/a&gt; and &lt;a href="http://lindseykuper.livejournal.com/"&gt;Lindsey&lt;/a&gt; wrote very pure Scheme code upstairs.&lt;br /&gt;&lt;br /&gt;We didn't do anything particularly fancy, just used a &lt;a href="http://en.wikipedia.org/wiki/PID_controller"&gt;PID controller&lt;/a&gt; to adjust the driver's angle towards the goal, and wrote some geometry routines to detect when we were on a collision course with an obstacle, and then plotted a course in whichever direction around the obstacle &lt;i&gt;looked&lt;/i&gt; shorter. We also moved away from Martians if they were too close to us (and facing us). We talked about several more complex tactics, but didn't wind up with the extra time (or brainpower) to implement them.&lt;br /&gt;&lt;br /&gt;We had an awful version control experience with &lt;a href="http://www.selenic.com/mercurial/wiki/"&gt;mercurial&lt;/a&gt;: constant permissions errors in the remote repository, the need to manually "hg up" on the remote server, and flukey merges. I've had good luck in the past with mercurial on (a PyWeek entry) &lt;a href="http://www.pyweek.org/e/etf/"&gt;stochasm&lt;/a&gt;, and some of the trouble this time was because we were using an SSH repository, rather than the svnserve style that Drew setup on stochasm.&lt;br /&gt;&lt;br /&gt;Finally, &lt;a href="http://notlime.com/2008/icfp2008.tgz"&gt;our entry, the code&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-4980161503580593172?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/4980161503580593172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=4980161503580593172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/4980161503580593172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/4980161503580593172'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/07/icfp-2008.html' title='ICFP 2008'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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-3246670076294002668.post-767761686358361743</id><published>2008-05-23T18:03:00.001-04:00</published><updated>2008-05-23T18:36:18.801-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='house'/><category scheme='http://www.blogger.com/atom/ns#' term='gabi'/><category scheme='http://www.blogger.com/atom/ns#' term='kittens'/><category scheme='http://www.blogger.com/atom/ns#' term='nongeeky'/><title type='text'>Kitten Naming</title><content type='html'>Gabi and I have acquired a set of four kittens and a momma-cat. They're a bit wild, and prone to hissing, but we feed them, and they rumpus in our backyard.&lt;br /&gt;&lt;br /&gt;We named momma-cat "Olestra" because it has a classical ring to it, and gave the four kittens the names: Sprint, Cingular, (T-) Mobile, and Verizon. We dropped the "T dash" from Mobile's name because it was confusing - what does the "T" mean anyways? Both Sprint and Mobile are grey-tan tabbies, we're not sure which is which yet. Cingular is the fuzzy brown-black one, and Verizon is skinny and all-black.&lt;br /&gt;&lt;br /&gt;Naming critter-litters is a bit like &lt;a href="http://blog.gtuhl.com/2007/05/25/server-naming-conventions/"&gt;naming servers&lt;/a&gt;: you want to pick your names from a category that is roughly the same size as your things-to-be-named.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-767761686358361743?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/767761686358361743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=767761686358361743' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/767761686358361743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/767761686358361743'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/05/kitten-naming.html' title='Kitten Naming'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-4553972001135817750</id><published>2008-03-11T19:08:00.000-04:00</published><updated>2008-03-11T19:27:07.090-04:00</updated><title type='text'>Avoiding ThreadDeath with env.js</title><content type='html'>&lt;p&gt;At &lt;a href="http://www.appcelerator.org"&gt;Appcelerator&lt;/a&gt; we use &lt;a href="http://ejohn.org/"&gt;John Resig&lt;/a&gt;'s "&lt;a href="http://ejohn.org/blog/bringing-the-browser-to-the-server/"&gt;simulated browser environment for Rhino&lt;/a&gt;" as part of our IDE. I'd had intermittent problems with a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ThreadDeath.html"&gt;ThreadDeath&lt;/a&gt; error being thrown, which would then cause any other thread running Rhino to hang.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I wasn't sure if the problem was in my Java code, my JavaScript, Rhino's Java code, or Aptana's Java code (we built our IDE atop their HTML/CSS/JS editor). Turns out it wasn't any of those! It was in that &lt;a href="http://jqueryjs.googlecode.com/svn/trunk/jquery/build/runtest/env.js"&gt;"simulated browser environment" code&lt;/a&gt;, in &lt;tt&gt;window.clearInterval&lt;/tt&gt; where the thread spawned with &lt;tt&gt;setInterval&lt;/tt&gt; is killed. I puzzled for a moment over why Mr.Resig was using multiple threads rather than a single one for setIntervals (expediency I assume), and then changed two lines so that it doesn't kill the thread, but allows it to die of natural causes.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; window.setInterval = function(fn, time){&lt;br /&gt;  var num = timers.length;&lt;br /&gt;  &lt;br /&gt;  timers[num] = new java.lang.Thread(new java.lang.Runnable({&lt;br /&gt;   run: function(){&lt;br /&gt;    &lt;span style="background: #ffcccc"&gt;while (true) {&lt;/span&gt;&lt;br /&gt;    &lt;span style="background: #ccffcc"&gt;while (timers[num]) {&lt;/span&gt;&lt;br /&gt;     java.lang.Thread.currentThread().sleep(time);&lt;br /&gt;     fn();&lt;br /&gt;    }&lt;br /&gt;   }&lt;br /&gt;  }));&lt;br /&gt;  &lt;br /&gt;  timers[num].start();&lt;br /&gt; &lt;br /&gt;  return num;&lt;br /&gt; };&lt;br /&gt; &lt;br /&gt; window.clearInterval = function(num){&lt;br /&gt;  if ( timers[num] ) {&lt;br /&gt;   &lt;span style="background: #ffcccc"&gt;timers[num].stop();&lt;/span&gt;&lt;br /&gt;   delete timers[num];&lt;br /&gt;  }&lt;br /&gt; };&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Another example of a day of debugging yielding a two line fix. Ugh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-4553972001135817750?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/4553972001135817750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=4553972001135817750' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/4553972001135817750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/4553972001135817750'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/03/avoiding-threaddeath-with-envjs.html' title='Avoiding ThreadDeath with env.js'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-7624657918967988151</id><published>2008-02-29T19:44:00.000-05:00</published><updated>2008-03-06T17:56:18.812-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tailor'/><category scheme='http://www.blogger.com/atom/ns#' term='dvcs'/><category scheme='http://www.blogger.com/atom/ns#' term='distributed'/><category scheme='http://www.blogger.com/atom/ns#' term='trainwreak'/><category scheme='http://www.blogger.com/atom/ns#' term='legacy'/><category scheme='http://www.blogger.com/atom/ns#' term='vcs'/><title type='text'>Dodging the DVCS Trainwreak</title><content type='html'>&lt;p&gt;So what happens when the darcs or mercurial project goes &lt;a href="http://www.redhat.com/magazine/010aug05/features/subversion/"&gt;the way of CVS&lt;/a&gt; (that is: to bit-heaven)? How do you rescue your distributed repository from legacy-software-land?&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Well, the &lt;a href="http://progetti.arstecnica.it/tailor"&gt;Tailor&lt;/a&gt; project provides convertors between different repository formats, even some of the more obscure distributed VCSes. It seems to work in an all-at-once mode, rather than mirroring one live repository in other formats, but it does full history support, so...&lt;br /&gt;&lt;br /&gt;There's no harm in picking a bizarre distributed version control system today, if the project stalls, you can always upgrade your repository to whichever system becomes mainstream!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-7624657918967988151?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/7624657918967988151/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=7624657918967988151' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/7624657918967988151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/7624657918967988151'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/02/dodging-dvcs-trainwreak.html' title='Dodging the DVCS Trainwreak'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3246670076294002668.post-93256123781955549</id><published>2008-02-27T19:01:00.000-05:00</published><updated>2008-03-13T19:30:33.712-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dvcs'/><category scheme='http://www.blogger.com/atom/ns#' term='atlhack'/><category scheme='http://www.blogger.com/atom/ns#' term='diversity'/><category scheme='http://www.blogger.com/atom/ns#' term='distributed'/><category scheme='http://www.blogger.com/atom/ns#' term='trainwreak'/><category scheme='http://www.blogger.com/atom/ns#' term='vcs'/><title type='text'>Atlhack distributed version control roundup</title><content type='html'>&lt;div&gt;&lt;br /&gt;Alex writes &lt;a href="http://penguinparens.blogspot.com/2008/02/todays-viewing-linus-on-git.html"&gt;about the advantages of git&lt;/a&gt;, Erik shows us how to configure &lt;a href="http://www.subwindow.com/articles/6"&gt;git to serve over http&lt;/a&gt;, &lt;a href="http://rockstarling.livejournal.com/"&gt;Lindsey&lt;/a&gt; is using darcs, &lt;a href="http://djfroofy.livejournal.com/"&gt;Drew&lt;/a&gt; has been using mercurial for his personal projects (Miru, Yue), and I've been using darcs.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Are there any DVCSes we haven't tried? It seems that &lt;a href="http://blog.ianbicking.org/dvcs-mini-roundup.html"&gt;Mr Bicking&lt;/a&gt; has the full list.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3246670076294002668-93256123781955549?l=shiftpop.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://shiftpop.blogspot.com/feeds/93256123781955549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3246670076294002668&amp;postID=93256123781955549' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/93256123781955549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3246670076294002668/posts/default/93256123781955549'/><link rel='alternate' type='text/html' href='http://shiftpop.blogspot.com/2008/02/atlhack-distributed-version-control.html' title='Atlhack distributed version control roundup'/><author><name>Mark Luffel</name><uri>http://www.blogger.com/profile/00904617076470560132</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></feed>
