<?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-393915387617254561</id><updated>2011-10-18T20:52:25.307-07:00</updated><category term='man'/><category term='circuits'/><category term='PL'/><category term='synergy'/><category term='gnu screen'/><category term='tex'/><category term='English'/><category term='web'/><category term='apple'/><category term='compcert'/><category term='webcam'/><category term='haha'/><category term='music'/><category term='ssh'/><category term='art'/><category term='freedom'/><category term='time'/><category term='quine'/><category term='mutt'/><category term='make'/><category term='travel'/><category term='terminal'/><category term='python'/><category term='shell'/><category term='coq'/><category term='ipod'/><category term='internet'/><category term='puzzles'/><category term='windows'/><category term='vim'/><category term='ML'/><category term='game of life'/><category term='zaurus'/><category term='papers'/><category term='science'/><category term='svn'/><title type='text'>Zachary Tatlock</title><subtitle type='html'>&lt;a href="http://cseweb.ucsd.edu/~ztatlock"&gt;http://cseweb.ucsd.edu/~ztatlock&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default?start-index=101&amp;max-results=100'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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>118</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-393915387617254561.post-4198897001940594786</id><published>2010-02-06T23:39:00.001-08:00</published><updated>2010-02-06T23:42:07.447-08:00</updated><title type='text'>Peter Lee and DARPA</title><content type='html'>&lt;a href="http://norfolk.cs.washington.edu/htbin-post/unrestricted/colloq/details.cgi?id=903"&gt;Interesting talk&lt;/a&gt; by &lt;a href="http://www.cs.cmu.edu/~petel/"&gt;Peter Lee&lt;/a&gt; @ University of Washington about the new DARPA and his role in its leadership.

&lt;br /&gt;&lt;br /&gt;

Peter Lee is the only speaker I've seen use the phrase &lt;i&gt;"cosmic beauty"&lt;/i&gt; in a talk (last year @ UCSD).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4198897001940594786?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4198897001940594786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4198897001940594786' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4198897001940594786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4198897001940594786'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2010/02/peter-lee-and-darpa.html' title='Peter Lee and DARPA'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6755538072297660699</id><published>2010-02-02T11:44:00.000-08:00</published><updated>2010-02-17T18:21:26.990-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haha'/><title type='text'>Putting Reviews Into Perspective</title><content type='html'>This entertaining article shows how even legendary papers could get &lt;a href="http://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=01556500"&gt;horrible reviews&lt;/a&gt; (&lt;a href="http://www.fang.ece.ufl.edu/reject.html"&gt;html&lt;/a&gt;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6755538072297660699?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6755538072297660699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6755538072297660699' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6755538072297660699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6755538072297660699'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2010/02/putting-reviews-into-perspective.html' title='Putting Reviews Into Perspective'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-1929409684012026911</id><published>2010-01-25T16:30:00.000-08:00</published><updated>2010-01-25T18:36:48.564-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='freedom'/><title type='text'>H.264 and HTML5</title><content type='html'>Christopher Blizzard (one of the Mozilla guys) has a great post about the &lt;a href="http://www.0xdeadbeef.com/weblog/2010/01/html5-video-and-h-264-what-history-tells-us-and-why-were-standing-with-the-web/"&gt;consequences of H.264 becoming the de facto video codec for the web&lt;/a&gt;. Specifically, he's referring to Google's beta of &lt;a href="http://www.youtube.com/html5"&gt;YouTube in HTML5&lt;/a&gt;, which is very exciting. You should opt in today! (But push for open codecs tomorrow!)

&lt;br /&gt;&lt;br /&gt;

The relevant analogies are (1) the &lt;a href="http://www.cloanto.com/users/mcb/19950127giflzw.html"&gt;GIF fiasco&lt;/a&gt; and (2) &lt;a href="http://en.wikipedia.org/wiki/MP3"&gt;MP3 patent issues&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-1929409684012026911?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/1929409684012026911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=1929409684012026911' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1929409684012026911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1929409684012026911'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2010/01/h264-and-html5.html' title='H.264 and HTML5'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4946904843749786246</id><published>2010-01-20T21:39:00.000-08:00</published><updated>2010-01-20T21:43:06.489-08:00</updated><title type='text'>Jack Conte Anti-VideoSong</title><content type='html'>&lt;a href="http://www.youtube.com/user/jackcontemusic#p/c/7AB19A9722C8BE31"&gt;Jack Conte&lt;/a&gt; never ceases to cleverly entertain:

&lt;br /&gt;&lt;br /&gt;

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/M0n9R50xTpY&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/M0n9R50xTpY&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;br /&gt;&lt;br /&gt;

He's 1/2 of the excellent &lt;a href="http://www.youtube.com/user/PomplamooseMusic"&gt;Pomplamoose&lt;/a&gt; duo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4946904843749786246?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4946904843749786246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4946904843749786246' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4946904843749786246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4946904843749786246'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2010/01/jack-conte-anti-videosong.html' title='Jack Conte Anti-VideoSong'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2148186395875537694</id><published>2010-01-15T13:41:00.001-08:00</published><updated>2010-01-15T13:46:16.929-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tex'/><title type='text'>TeX month name</title><content type='html'>While making my &lt;a href="http://cseweb.ucsd.edu/~ztatlock/ztatlock-cv.pdf"&gt;CV&lt;/a&gt;, I needed the name of the current month. I found the trick &lt;a href="http://theoval.cmp.uea.ac.uk/~nlct/latex/l2h/l2h.pdf"&gt;here&lt;/a&gt;. Basically, you just have to create a switch:

&lt;pre style="border:1px solid black;"&gt;

    \newcommand{\monthname}{%
    \ifcase\number\month
    \or January%
    \or February%
    \or March%
    \or April%
    \or May%
    \or June%
    \or July%
    \or August%
    \or September%
    \or October%
    \or November%
    \or December%
    \fi}

&lt;/pre&gt;

After you've added this to the top of your TeX source, you can get the month name with &lt;span style="font-family: fixed;"&gt;\monthname&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2148186395875537694?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2148186395875537694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2148186395875537694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2148186395875537694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2148186395875537694'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2010/01/tex-month-name.html' title='TeX month name'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-350484221760294796</id><published>2010-01-12T16:13:00.000-08:00</published><updated>2010-01-12T16:21:58.542-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Start svnserve at boot in Ubuntu</title><content type='html'>&lt;a href="http://benrobb.com/2007/01/15/howto-start-subversion-at-boot-on-ubuntu/"&gt;This post&lt;/a&gt; provides a very simple init script to get svnserve going at boot. In Slackware, I only had to make a script executable for it to run at boot; here you must use some update-rc.d magic:

&lt;ol style="font-family:fixed;"&gt;
  &lt;li&gt;$ echo "svnserve -d --foreground -r /home/svn" \&lt;br /&gt;
        &amp;nbsp; &amp;nbsp; | sudo tee  /etc/init.d/svnserve&lt;/li&gt;
  &lt;li&gt;$ sudo chmod +x /etc/svnserve&lt;/li&gt;
  &lt;li&gt;$ sudo update-rc.d svnserve defaults&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-350484221760294796?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/350484221760294796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=350484221760294796' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/350484221760294796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/350484221760294796'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2010/01/start-svnserve-at-boot-in-ubuntu.html' title='Start svnserve at boot in Ubuntu'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-1923624711108958028</id><published>2009-12-29T06:40:00.000-08:00</published><updated>2009-12-29T07:10:11.832-08:00</updated><title type='text'>Fun in MN #3</title><content type='html'>We recently saw the &lt;a href="http://www.securio.net/btaa/btaa/index.cfm/fa/award.intro/year/2009"&gt;2009 British Television Advertising Awards&lt;/a&gt;, a 1.5 hour movie comprised of short advertisements. Two particularly interesting types of ad:

&lt;ol&gt;
  &lt;li&gt;Change blindness: &lt;br /&gt;
  The winning Transport for London ads advocate awareness of cyclists:
  &lt;br /&gt;&lt;br /&gt;

  Do the Test:
  &lt;br /&gt;

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Ahg6qcgoay4&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Ahg6qcgoay4&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

  &lt;br /&gt;&lt;br /&gt;

  Whodunnit?
  &lt;br /&gt;

&lt;object width="560" height="340"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ubNF9QNEQLA&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/ubNF9QNEQLA&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"&gt;&lt;/embed&gt;&lt;/object&gt;

  &lt;br /&gt;&lt;br /&gt;

  Both of these ads exploit "change blindness", a phenomenon where most people tend to miss drastic visual changes:
  &lt;br /&gt;

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/38XO7ac9eSs&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/38XO7ac9eSs&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

  &lt;br /&gt;&lt;br /&gt;

  Today, &lt;a href="http://www.schneier.com/blog/archives/2009/12/change_blindnes.html"&gt;Schneier&lt;/a&gt; noted how this could have drastic security implications. Neat stuff.
&lt;br /&gt;&lt;br /&gt;
&lt;/li&gt;

  &lt;li&gt;Anne and I both noticed that many of the ads were &lt;i&gt;not selling anything&lt;/i&gt; per se. Instead they were advocating a change in behavior. For example, one ad went into gruesome detail about knife wounds and then encouraged young people to stop carrying knives. Another examined the damage caused by gun violence. Others considered substance abuse and excessive drinking. All of them used the form of an ad to do something else: promote social change. In the US, the &lt;a href="http://www.adcouncil.org/"&gt;Ad Council&lt;/a&gt; works similarly.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;

Finally the show was presented in the &lt;a href="http://www.walkerart.org/index.wac"&gt;The Walker Art Museum&lt;/a&gt;, which is a fun, gorgeous place to stroll through, lots of interesting stuff. If you're in MN, don't miss it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-1923624711108958028?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/1923624711108958028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=1923624711108958028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1923624711108958028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1923624711108958028'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/fun-in-mn-3.html' title='Fun in MN #3'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4271393594825417554</id><published>2009-12-24T19:21:00.000-08:00</published><updated>2009-12-24T19:50:26.002-08:00</updated><title type='text'>Fun in MN #2</title><content type='html'>CA is great, but you don't get 18 inches of perfect snow in San Diego:

&lt;br /&gt;&lt;br /&gt;

&lt;img src="http://godel.ucsd.edu/share/sled-chain-09.jpg" /&gt;

&lt;br /&gt;&lt;br /&gt;

Here's the rest of the &lt;a href="http://godel.ucsd.edu/share/sledding-09"&gt;sledding fun&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4271393594825417554?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4271393594825417554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4271393594825417554' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4271393594825417554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4271393594825417554'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/fun-in-mn-2.html' title='Fun in MN #2'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4442705768965159922</id><published>2009-12-24T19:13:00.000-08:00</published><updated>2009-12-24T19:18:48.096-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='time'/><title type='text'>Time Management</title><content type='html'>A couple of great ideas about how to manage time (your most valuable resource!):

&lt;br /&gt;&lt;br /&gt;

&lt;a href="http://www.iwillteachyoutoberich.com/blog/time-management-how-an-mit-postdoc-writes-3-books-a-phd-defense-and-6-peer-reviewed-papers-and-finishes-by-530pm/"&gt;Time Management&lt;/a&gt; post from a financial advice blog.

&lt;br /&gt;&lt;br /&gt;

&lt;a href="http://video.google.com/videoplay?docid=-5784740380335567758#"&gt;Time Management&lt;/a&gt; and the &lt;a href="http://www.youtube.com/watch?v=ji5_MqicxSo"&gt;Last Lecture&lt;/a&gt; by &lt;a href="http://en.wikipedia.org/wiki/Randy_Pausch"&gt;Randy Pausch&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4442705768965159922?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4442705768965159922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4442705768965159922' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4442705768965159922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4442705768965159922'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/time-management.html' title='Time Management'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3500948333273920666</id><published>2009-12-21T19:24:00.000-08:00</published><updated>2009-12-21T19:38:13.445-08:00</updated><title type='text'>Fun in MN #1</title><content type='html'>The &lt;a href="http://garden.walkerart.org/index.wac"&gt;Minneapolis Sculpture Garden&lt;/a&gt; is a fun place, even 15 degrees below freezing:

&lt;br /&gt;&lt;br /&gt;
&lt;img src="http://godel.ucsd.edu/share/spoonbridge-and-cherry-200912.jpg" /&gt;
&lt;br /&gt;&lt;br /&gt;

Although it looks nicer in the summer:

&lt;br /&gt;&lt;br /&gt;
&lt;img src="http://mytwincities.net/images/20090115215855_032868.jpg" width="500px" /&gt;
&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3500948333273920666?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3500948333273920666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3500948333273920666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3500948333273920666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3500948333273920666'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/fun-in-mn-1.html' title='Fun in MN #1'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-1933281750366061757</id><published>2009-12-21T07:09:00.000-08:00</published><updated>2009-12-21T19:41:34.419-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Interesting Caml Flames</title><content type='html'>The caml list has an interesting thread about &lt;a href="http://caml.inria.fr/pub/ml-archives/caml-list/2009/12/d61e0b130d68422e82c2987e7bdd6227.en.html"&gt;multicore&lt;/a&gt; (&lt;a href="http://caml.inria.fr/pub/ml-archives/caml-list/2009/12/84fc751df1795ac9cea0e7254edf53d1.en.html"&gt;continued&lt;/a&gt;).

&lt;br /&gt;&lt;br /&gt;

Someone posted lack of good multicore support as a bug. Their argument is that because all machines now come with multiple cores, this is truly a bug that must be fixed. The followups:

&lt;ol&gt;
  &lt;li style="padding:10px;"&gt;Discuss whether this is really a bug.&lt;/li&gt;
  &lt;li style="padding:10px;"&gt;Consider how one could implement better support in a mature and broadly deployed system like caml.&lt;/li&gt;
  &lt;li style="padding:10px;"&gt;Give a cursory overview of the state of parallelization for functional langs (F# seems to be the favored ML for exploiting concurrency).&lt;/li&gt;
&lt;/ol&gt;

Jon Harrop and Yaron Minsky (both knowledgeable caml guys) weigh in at multiple points.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-1933281750366061757?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/1933281750366061757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=1933281750366061757' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1933281750366061757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1933281750366061757'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/interesting-caml-flames.html' title='Interesting Caml Flames'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2712863076407992758</id><published>2009-12-17T10:32:00.000-08:00</published><updated>2009-12-17T10:42:54.438-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haha'/><title type='text'>Holiday Decorating</title><content type='html'>Anne loves the holidays. Unfortunately, in Southern California we don't get the same great holiday spirit that the Midwest fosters with its biting cold and massive snow drifts. To make matters worse, our tiny apartment can't really fit a Christmas tree. So, we started hacking and:

&lt;br /&gt;&lt;br /&gt;
&lt;center&gt;
  &lt;img src="http://godel.ucsd.edu/share/anne-paper-xmas-tree.jpg" /&gt;
&lt;/center&gt;
&lt;br /&gt;&lt;br /&gt;

Of course, we spend a lot of time in the lab too, so we wanted a little holiday spirit at school as well. What's more festive than an 8 foot tall lambda in lights?

&lt;br /&gt;&lt;br /&gt;
&lt;center&gt;
  &lt;img src="http://godel.ucsd.edu/share/lambda-lights-2009.jpg" /&gt;
&lt;/center&gt;
&lt;br /&gt;&lt;br /&gt;

Happy Holidays!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2712863076407992758?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2712863076407992758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2712863076407992758' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2712863076407992758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2712863076407992758'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/holiday-decorating.html' title='Holiday Decorating'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-704885135083290779</id><published>2009-12-09T08:20:00.000-08:00</published><updated>2009-12-09T08:23:48.370-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzles'/><title type='text'>Regifting Robin: Cute Number Puzzle</title><content type='html'>Check out &lt;a href="http://www.regiftable.com/regiftingrobinpopup.html"&gt;Regifting Robin&lt;/a&gt;, a neat puzzle shared by &lt;a href="http://cseweb.ucsd.edu/~gupta/"&gt;Rajesh Gupta&lt;/a&gt; on the &lt;b&gt;misc&lt;/b&gt; list. &lt;i&gt;Hint&lt;/i&gt;: if you count the number of possible answers, you'll figure out the trick.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-704885135083290779?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/704885135083290779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=704885135083290779' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/704885135083290779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/704885135083290779'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/regifting-robn-cute-number-puzzle.html' title='Regifting Robin: Cute Number Puzzle'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3936554999775083362</id><published>2009-12-08T15:43:00.000-08:00</published><updated>2009-12-21T07:20:55.193-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Using bash variables in cases</title><content type='html'>Pattern matching in bash via the &lt;a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_03.html"&gt;case&lt;/a&gt; construct is quite useful. However, sometimes it's nice to compute the pattern you want to match against and store it as a variable. For example, the first thing one may try:

&lt;pre&gt;
    # BAD
    PAT='"hello"|"hi"'
    
    case $FOO in
      $PAT)
        echo "matched a greeting"
        ;;
    
      *)
        echo "nothing matched"
        ;;
    esac    
&lt;/pre&gt;

Unfortunately this is &lt;b&gt;not&lt;/b&gt; the same as:

&lt;pre&gt;
    case $FOO in
      "hello"|"hi")
        echo "matched a greeting"
        ;;
    
      *)
        echo "nothing matched"
        ;;
    esac    
&lt;/pre&gt;

The first example will only match a literal &lt;i&gt;"hello"|"hi"&lt;/i&gt;, while the second would match &lt;i&gt;hello&lt;/i&gt; or &lt;i&gt;hi&lt;/i&gt; as we expect.

&lt;br /&gt;&lt;br /&gt;

To fix this, we can wrap an &lt;u&gt;eval&lt;/u&gt; around the entire case, which will expand all the variables before the pattern matching is carried out, thus providing the desired behavior:

&lt;pre&gt;
    # GOOD
    PAT='"hello"|"hi"'
    
    eval "
    case $FOO in
      $PAT)
        echo "matched a greeting"
        ;;
    
      *)
        echo "nothing matched"
        ;;
    esac
    "  
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3936554999775083362?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3936554999775083362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3936554999775083362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3936554999775083362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3936554999775083362'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/using-bash-variables-in-cases.html' title='Using bash variables in cases'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-9055307609106078276</id><published>2009-12-08T15:37:00.001-08:00</published><updated>2009-12-08T15:56:30.385-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>New Webpage</title><content type='html'>I redid &lt;a href="http://cs.ucsd.edu/~ztatlock"&gt;http://cs.ucsd.edu/~ztatlock&lt;/a&gt;. Feedback is appreciated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-9055307609106078276?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/9055307609106078276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=9055307609106078276' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/9055307609106078276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/9055307609106078276'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/12/new-webpage.html' title='New Webpage'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-1113270735551910144</id><published>2009-11-24T21:44:00.001-08:00</published><updated>2009-11-24T22:13:37.106-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>Pomplamoose</title><content type='html'>I've been watching &lt;a href="http://www.youtube.com/user/PomplamooseMusic#p/u/0/s_b0I4KVpFk"&gt;Pomplamoose&lt;/a&gt; for a bit now (thanks Anne!). I really enjoy their sound and DIY ethic. They're sort of a calmer, more complex &lt;a href="http://www.mattandkimmusic.com/"&gt;Matt &amp;amp; Kim&lt;/a&gt; (another one of my favorite bands -- thanks Chris!).

&lt;br /&gt;&lt;br /&gt;
Examples include Hail Mary:
&lt;br /&gt;

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/fYy2p_0DVMU&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/fYy2p_0DVMU&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;br /&gt;&lt;br /&gt;
and Pas Encore (the only song I know with the phrase "internet forums"):
&lt;br /&gt;

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/FCCoggBkcdM&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/FCCoggBkcdM&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-1113270735551910144?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/1113270735551910144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=1113270735551910144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1113270735551910144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1113270735551910144'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/11/pomplamoose.html' title='Pomplamoose'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4130147959332115586</id><published>2009-11-24T19:14:00.000-08:00</published><updated>2009-11-24T21:00:44.055-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>most</title><content type='html'>The &lt;a href="http://www.jedsoft.org/most/"&gt;most&lt;/a&gt; pager does the right thing for colors without any futzing in .Xdefaults or setting multiple environment variables in .bashrc. Aside from being a drop-in replacement for more/less, the documentation mentions some other nice features, e.g. simple key remapping and "fold" like features for viewing code.

&lt;pre&gt;

  $ sudo apt-get install most
  $ echo "export PAGER=most" &gt;&gt; ~/.bashrc
&lt;/pre&gt;

&lt;br /&gt;&lt;br /&gt;

&lt;b&gt;update:&lt;/b&gt;

&lt;br /&gt;&lt;br /&gt;

&lt;b&gt;most&lt;/b&gt; lacks -F, which could be a deal breaker. From less's man page:

&lt;pre&gt;
  -F 
    Causes less to automatically exit if the entire
    file can be displayed on the first screen.
&lt;/pre&gt;

Fortunately, it looks like I can add -F support in a few lines. Unfortunately, the most source &lt;i&gt;mixes tabs and spaces&lt;/i&gt;. UGH! Worse, &lt;a href="http://www.gnu.org/software/indent/manual/indent.html"&gt;indent&lt;/a&gt; doesn't seem to fix things automagically.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4130147959332115586?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4130147959332115586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4130147959332115586' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4130147959332115586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4130147959332115586'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/11/most.html' title='most'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4143448888573583327</id><published>2009-11-22T10:34:00.000-08:00</published><updated>2009-11-22T10:56:02.516-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coq'/><title type='text'>coqwc</title><content type='html'>Friday we needed to measure our &lt;a href="http://coq.inria.fr/"&gt;Coq&lt;/a&gt; development for the &lt;a href="http://cs.stanford.edu/pldi10/"&gt;PLDI&lt;/a&gt; submission. Normally, I just use &lt;a href="http://en.wikipedia.org/wiki/Wc_(Unix)"&gt;wc&lt;/a&gt; to roughly estimate program size, and
&lt;pre&gt;
  $ grep ";\|}" FOO | wc
&lt;/pre&gt;
for a more accurate account (of C/Java code FOO). However, in Coq code one is usually interested in knowing both the amount of code you've written AND the size of the proofs about your code. Obviously, &lt;b&gt;wc&lt;/b&gt; can't tell the difference, and so I was reduced to hacking out some grep/sed/awk monstrosity that roughly estimates the number of lines in each category.

&lt;br /&gt;&lt;br /&gt;

Then today (too late) I find &lt;b&gt;coqwc&lt;/b&gt; which does &lt;i&gt;exactly&lt;/i&gt; what I want:
&lt;pre&gt;
$ coqwc PRTL.v EE.v SideCond_DNM.v 
     spec    proof comments
      279        0       19 PRTL.v
      266      163       84 EE.v
       81       42       18 SideCond_DNM.v
      626      205      121 total
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4143448888573583327?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4143448888573583327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4143448888573583327' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4143448888573583327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4143448888573583327'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/11/coqwc.html' title='coqwc'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3379816970504809790</id><published>2009-10-06T17:51:00.000-07:00</published><updated>2009-10-06T18:01:21.755-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='science'/><title type='text'>Brain Plasticity</title><content type='html'>&lt;a href="https://cseweb.ucsd.edu/~gary/"&gt;Gary Cottrell&lt;/a&gt; gave a neat talk yesterday about his lab's computational models for vision. One comment that really stuck: the brain contains many similar structures. These structure apply similar algorithms and pass their output to each other. 

&lt;br /&gt;&lt;br /&gt;

It seems like redundancy and self similarity are big wins for us. This also supports the idea of &lt;a href="http://en.wikipedia.org/wiki/Neuroplasticity"&gt;Neuroplasticity&lt;/a&gt; which &lt;i&gt;roughly&lt;/i&gt; says that the brain can reorganize itself to handle new environments. For example, some guys at MIT wired ferret retinal outputs into the auditory cortex. The ferrets learned how to see just fine. Also, people can see with their tongues. Those examples and more in &lt;a href="http://discovermagazine.com/2003/jun/feattongue/article_view?b_start:int=0&amp;-C="&gt;this great Discover article&lt;/a&gt;. Thanks &lt;a href="http://cseweb.ucsd.edu/~mstepp/"&gt;Mike&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3379816970504809790?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3379816970504809790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3379816970504809790' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3379816970504809790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3379816970504809790'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/10/brain-plasticity.html' title='Brain Plasticity'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2303163148013595122</id><published>2009-09-29T11:24:00.000-07:00</published><updated>2009-09-29T11:25:47.801-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>Carl Sagan + Auto Tune</title><content type='html'>I cannot stop watching: &lt;br /&gt; &amp;nbsp; &amp;nbsp;
&lt;a href="http://www.youtube.com/watch?v=zSgiXGELjbc"&gt;http://www.youtube.com/watch?v=zSgiXGELjbc&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2303163148013595122?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2303163148013595122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2303163148013595122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2303163148013595122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2303163148013595122'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/09/carl-sagan-auto-tune.html' title='Carl Sagan + Auto Tune'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5031039704123772957</id><published>2009-09-25T10:00:00.001-07:00</published><updated>2009-09-25T10:12:43.299-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Install Chromium in Ubuntu 9.04</title><content type='html'>&lt;a href="http://code.google.com/chromium/"&gt;Chromium&lt;/a&gt; is great. To use it in Ubuntu 9.04, run as root:

&lt;pre&gt;

  # F="http://ppa.launchpad.net/chromium-daily/ppa/ubuntu"
  # echo "deb $F jaunty main" &gt;&gt; /etc/apt/sources.list
  # echo "deb-src $F jaunty main" &gt;&gt; /etc/apt/sources.list
  # KS="--keyserver keyserver.ubuntu.com"
  # K="0xfbef0d696de1c72ba5a835fe5a9bf3bb4e5e17b5"
  # apt-key adv --recv-keys $KS $K 
  # apt-get update
  # apt-get install chromium-browser

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5031039704123772957?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5031039704123772957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5031039704123772957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5031039704123772957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5031039704123772957'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/09/install-chromium-ubuntu-904.html' title='Install Chromium in Ubuntu 9.04'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6803741416415185376</id><published>2009-09-03T11:31:00.001-07:00</published><updated>2009-09-03T11:40:14.682-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Keeping a Connection at Peet's</title><content type='html'>Peet's wireless for non-http traffic is extremely bursty, to the degree that ssh and other non-http connections get starved to death. However, as long as there's enough http traffic, it seems like all connections get along OK. So, to keep ssh alive, just keep requesting junk pages in the background:

&lt;pre&gt;

    #!/usr/bin/env bash
    
    function mksearch {
      echo -n "http://www.google.com/search?"
      echo "sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=$1"
    }
    
    while true; do 
      for s in taco zip foo bar baz burrito cat; do
        wget --user-agent="Firefox" -O /dev/null "$(mksearch $s)"
        sleep 15
      done
    done
    
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6803741416415185376?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6803741416415185376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6803741416415185376' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6803741416415185376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6803741416415185376'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/09/keeping-connection-at-peets.html' title='Keeping a Connection at Peet&apos;s'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6580888787661973194</id><published>2009-08-31T21:19:00.000-07:00</published><updated>2009-09-01T06:43:16.985-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='ipod'/><title type='text'>iPod: disable hfs+ journaling for Linux</title><content type='html'>Turns out that the Linux kernel can't handle journaling in hfs+ filesystems. You can recognize the problem from this &lt;a href="http://www.linfo.org/dmesg.html"&gt;dmesg&lt;/a&gt; error:

&lt;pre&gt;

    hfs: write access to a journaled filesystem is not supported,
         use the force option at your own risk, mounting read-only.

&lt;/pre&gt;

This matters if you want to write to an iPod. The best fix I've found is to disable journaling: simply mount the iPod in OSX and run:

&lt;pre&gt;

    $ diskutil disableJournal /Volumes/iPod

&lt;/pre&gt;

where "iPod" is the name of your iPod. Once the journal is disabled, using an iPod in Linux is a cinch, particularly with tools like &lt;a href="http://www.gtkpod.org/about.html"&gt;gtkpod&lt;/a&gt; or &lt;a href="http://projects.gnome.org/rhythmbox/"&gt;rhythmbox&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6580888787661973194?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6580888787661973194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6580888787661973194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6580888787661973194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6580888787661973194'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/08/ipod-disable-journaling-for-linux.html' title='iPod: disable hfs+ journaling for Linux'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3905527139898410021</id><published>2009-08-27T10:13:00.000-07:00</published><updated>2009-08-27T15:07:45.336-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freedom'/><title type='text'>Garry Kasparov: Best Politician Ever?</title><content type='html'>Kasparov is &lt;i&gt;sharp&lt;/i&gt; in an interview:
&lt;a href="http://crooksandliars.com/2007/10/20/real-time-with-bill-maher-kasparov-on-democracy"&gt;Kasparov vs. Maher&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3905527139898410021?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3905527139898410021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3905527139898410021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3905527139898410021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3905527139898410021'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/08/garry-kasparov-best-politician-ever.html' title='Garry Kasparov: Best Politician Ever?'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8388457893276552071</id><published>2009-08-25T21:43:00.000-07:00</published><updated>2009-08-25T21:52:17.870-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Convert ogg to mp3</title><content type='html'>Converting from one lossy format to another is a bad idea. Unfortunately, most portable music players do not support ogg. So, if you &lt;b&gt;really have&lt;/b&gt; turn your oggs in to mp3s, you can use this:

&lt;pre&gt;

  $ ffmpeg -i in.ogg out.mp3

&lt;/pre&gt;


[found in an &lt;a href="https://lists.ubuntu.com/archives/ubuntu-users/2008-December/168463.html"&gt;ubuntu list archive&lt;/a&gt;]

&lt;br /&gt;

A while ago I wrote the following "anything to mp3" script for similar tasks:

&lt;pre&gt;
    #!/usr/bin/env bash
    
    function ext {
      # if there is a file extension, print it
      # otherwise do nothing
      echo $1 | awk 'BEGIN {FS="."} {if(NF &amp;gt; 1) {print $NF}}'
    }
    
    function convert {
      # convert $1 to mp3
      src="$1"
      dst="$(dirname "$src")/$(basename "$src" .$(ext "$src")).mp3"
      wav="$$.wav"
    
      # decode to wav with mplayer
      mplayer \
        -vo null -vc dummy \
        -af resample=44100 \
        -ao pcm:waveheader:file="$wav" \
        "$src"
    
      # encode to mp3 with lame
      lame -m s "$wav" -o "$dst"
    
      # get rid of temporary file
      rm "$wav"
    }
    
    # handle spaces in file names
    IFS=$(echo -en "\n\b")
    
    for src in $* ; do
      echo -n "$src ... "
      convert "$src" &amp;amp;&amp;gt; /dev/null
      echo "done"
    done
    
&lt;/pre&gt;

I don't know if the ffmpeg approach is better or worse.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8388457893276552071?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8388457893276552071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8388457893276552071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8388457893276552071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8388457893276552071'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/08/convert-ogg-to-mp3.html' title='Convert ogg to mp3'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6695030127828416973</id><published>2009-08-04T09:57:00.000-07:00</published><updated>2009-08-04T09:58:24.421-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><title type='text'>No More Jetlag</title><content type='html'>Fast 12 - 16 hours before crossing time zones, &lt;a href="http://www.wisebread.com/how-to-naturally-reset-your-sleep-cycle-overnight"&gt;says science&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6695030127828416973?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6695030127828416973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6695030127828416973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6695030127828416973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6695030127828416973'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/08/no-more-jetlag.html' title='No More Jetlag'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3034069788108828885</id><published>2009-08-02T17:05:00.000-07:00</published><updated>2009-08-02T17:07:34.224-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haha'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>The iPhone's New Clothes</title><content type='html'>&lt;a href="http://www.theonion.com/content/news/apple_claims_new_iphone_only"&gt;New iPhone&lt;/a&gt; specially designed for Apple enthusiasts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3034069788108828885?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3034069788108828885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3034069788108828885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3034069788108828885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3034069788108828885'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/08/iphones-new-clothes.html' title='The iPhone&apos;s New Clothes'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8885695197702121598</id><published>2009-04-21T07:42:00.000-07:00</published><updated>2009-04-21T07:47:56.278-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Logic in Java</title><content type='html'>From &lt;a href="http://wadler.blogspot.com/2009/04/famelab-what-does-logic-have-to-do-with.html"&gt;Wadler's Blog&lt;/a&gt;, &lt;i&gt;What does logic have to do with Java?&lt;/i&gt; (wait for the gimmick at the &lt;b&gt;very end&lt;/b&gt;): &lt;br /&gt;&lt;br /&gt;

&lt;object width="560" height="340"&gt;
  &lt;param name="movie" value="http://www.youtube.com/v/KYeys_in_Ng&amp;hl=en&amp;fs=1&amp;rel=0"&gt;
  &lt;/param&gt;
  &lt;param name="allowFullScreen" value="true"&gt;
  &lt;/param&gt;
  &lt;param name="allowscriptaccess" value="always"&gt;
  &lt;/param&gt;
  &lt;embed src="http://www.youtube.com/v/KYeys_in_Ng&amp;hl=en&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="450" height="340"&gt;
  &lt;/embed&gt;
&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8885695197702121598?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8885695197702121598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8885695197702121598' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8885695197702121598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8885695197702121598'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/logic-in-java.html' title='Logic in Java'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3655741208750916069</id><published>2009-04-16T23:21:00.000-07:00</published><updated>2009-04-16T23:28:18.228-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><title type='text'>Remove Unwanted Icons (Windows)</title><content type='html'>In Windows, there are icons that cannot be deleted by right clicking, dragging to the recycle bin, or hitting the delete key. To get rid of these pesky, unwanted icons:

&lt;ol&gt;
  &lt;li&gt;Right click on the Desktop and select &lt;b&gt;Properties&lt;/b&gt;.&lt;/li&gt;
  &lt;li&gt;Select the &lt;b&gt;Desktop&lt;/b&gt; tab.&lt;/li&gt;
  &lt;li&gt;Click the &lt;b&gt;Customize Desktop&lt;/b&gt; button.&lt;/li&gt;
  &lt;li&gt;Click the &lt;b&gt;Clean Desktop Now&lt;/b&gt; button.&lt;/li&gt;
  &lt;li&gt;Check the checkboxes for any icons you do not want.&lt;/li&gt;
  &lt;li&gt;Click the &lt;b&gt;Apply&lt;/b&gt; button.&lt;/li&gt;
  &lt;li&gt;Now the icons you despise are in a folder on the Desktop. Delete that folder.&lt;/li&gt;
&lt;/ol&gt;

I found these instructions &lt;a href="http://www.annoyances.org/exec/forum/winxp/1192046804"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3655741208750916069?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3655741208750916069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3655741208750916069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3655741208750916069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3655741208750916069'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/remove-unwanted-icons-windows.html' title='Remove Unwanted Icons (Windows)'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-455574030253539185</id><published>2009-04-14T17:23:00.000-07:00</published><updated>2009-04-16T21:16:26.187-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>xdotool</title><content type='html'>&lt;a href="http://www.semicomplete.com/projects/xdotool/"&gt;xdotool&lt;/a&gt; is an awesome command that enables programmatic control of X events, e.g. pressing keys, moving or clicking the mouse, resizing windows, etc. It is a great response to this xkcd:

&lt;br /&gt;&lt;br /&gt;

&lt;a href="http://xkcd.com/196/"&gt;
&lt;img width="100%" src="http://imgs.xkcd.com/comics/command_line_fu.png" /&gt;
&lt;/a&gt;

&lt;br /&gt;&lt;br /&gt;

You can even make the mouse infinitely loop:

&lt;pre&gt;
    #!/usr/bin/env bash
    
    OFF=300
    RAD=300
    
    C=$(expr $OFF + $RAD)
    
    function x {
      echo "$RAD * c($1)" \
        | bc -l \
        | awk '{print int($1 + 0.5)}' \
        | xargs expr $C +
    }
    
    function y {
      echo "$RAD * s($1)" \
        | bc -l \
        | awk '{print int($1 + 0.5)}' \
        | xargs expr $C +
    }
    
    t=0
    d=0.02
    while true; do
      xdotool mousemove $(x $t) $(y $t)
      d=$(echo "$d * 1.001" | bc -l)
      t=$(echo "$t + $d" | bc -l)
    done
    
&lt;/pre&gt;

Watch this for a few minutes; it eventually starts doing some crazy things.
The script also contains several tricks for rounding, etc. that could be more generally useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-455574030253539185?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/455574030253539185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=455574030253539185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/455574030253539185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/455574030253539185'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/xdotool.html' title='xdotool'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8134268526589846718</id><published>2009-04-12T09:57:00.000-07:00</published><updated>2009-04-12T10:11:17.150-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Twitter on Scala</title><content type='html'>Here is &lt;a href="http://www.artima.com/scalazine/articles/twitter_on_scala.html"&gt;a nice interview&lt;/a&gt; with &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; developers about replacing an enterprise &lt;a href="http://www.ruby-lang.org/en/"&gt;Ruby&lt;/a&gt; backend with &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. Interesting topics include: flexibility, correctness, concurrency, and fun programming.

&lt;br /&gt;&lt;br /&gt;

Best excerpt:

&lt;blockquote&gt;
I think it may just be a property of large systems in dynamic languages, that eventually you end up rewriting your own type system, and you sort of do it badly.
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8134268526589846718?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8134268526589846718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8134268526589846718' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8134268526589846718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8134268526589846718'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/twitter-uses-scala.html' title='Twitter on Scala'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-465226601232251934</id><published>2009-04-05T21:38:00.000-07:00</published><updated>2009-04-05T21:50:49.596-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freedom'/><title type='text'>Media Subversion</title><content type='html'>&lt;a href="http://pppl.org/"&gt;Peace, Propaganda, and the Promised Land&lt;/a&gt; is a fairly well-made documentary available for free download. A first approximation of its theme could be:

&lt;pre&gt;
    Coverage of the Israeli occupation of Palestine from a
    perspective absent in US news sources.
&lt;/pre&gt;

but the &lt;b&gt;real&lt;/b&gt; point of the film is that:

&lt;pre&gt;
    US news organizations have been subverted.
&lt;/pre&gt;

Evidence of journalistic infidelity is provided by comparing US and British reports on identical events. The differences are disturbing. Of course, this comparison alone only shows &lt;i&gt;someone&lt;/i&gt; got it wrong, not necessarily the US. The documentary also covers history, motivation, and influence for the players involved in both the conflict and its media coverage. These factors suggest that the BBC's version of events is more reliable.

&lt;br /&gt;&lt;br /&gt;

The film provides very interesting examples of how the media's language has been controlled; the effects are dramatic. The whole situation seems quite &lt;a href="http://en.wikipedia.org/wiki/Orwellian"&gt;Orwellian&lt;/a&gt;.

&lt;br /&gt;&lt;br /&gt;

Take-home point: Supplement your news intake with sources from outside your home country.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-465226601232251934?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/465226601232251934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=465226601232251934' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/465226601232251934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/465226601232251934'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/media-subversion.html' title='Media Subversion'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4429027109781478658</id><published>2009-04-04T15:18:00.000-07:00</published><updated>2009-04-04T15:30:41.386-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='ML'/><title type='text'>OCaml Documentation in Vim</title><content type='html'>To have vim open a firefox tab to the documentation for a standard OCaml module:

&lt;ol&gt;
  &lt;li&gt;Place this script :
&lt;pre&gt;
    #!/bin/bash
    
    firefox http://caml.inria.fr/pub/docs/manual-ocaml/libref/${1}.html
&lt;/pre&gt;
in &lt;b&gt;~/bin/ocaml_lkup_module&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
  &lt;li&gt; $ chmod +x ~/bin/ocaml_lkup_module&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
  &lt;li&gt;Add this line :
&lt;pre&gt;
    " lookup modules in OCaml online documentation
    au BufRead,BufNewFile *.ml set keywordprg=~/bin/ocaml_lkup_module
&lt;/pre&gt;
to your &lt;b&gt;~/.vimrc&lt;/b&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;br /&gt;&lt;br /&gt;

To use, simply:
&lt;ol&gt;
  &lt;li&gt;Open up an OCaml source in vim.&lt;/li&gt;
  &lt;li&gt;In command mode, move the cursor onto a standard library module name.&lt;/li&gt;
  &lt;li&gt;Press 'K'.&lt;/li&gt;
  &lt;li&gt;Tah dah! The documentation for that module is open in a new firefox tab.&lt;/li&gt;
&lt;/ol&gt;

&lt;br /&gt;&lt;br /&gt;

Similar coverage of vim's &lt;b&gt;keywordprog&lt;/b&gt; in a past &lt;a href="http://ztatlock.blogspot.com/2008/11/thesaurus-in-vim.html"&gt;thesaurus in vim post&lt;/a&gt; and from a post over at &lt;a href="http://dailyvim.blogspot.com/2008/08/making-k-useful.html"&gt;Daily Vim : Making K Useful&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4429027109781478658?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4429027109781478658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4429027109781478658' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4429027109781478658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4429027109781478658'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/ocaml-documentation-in-vim.html' title='OCaml Documentation in Vim'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-1465692548359211395</id><published>2009-04-02T20:06:00.000-07:00</published><updated>2009-04-02T20:21:14.165-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Dynamically Resive Font in URxvt</title><content type='html'>This script allows you to dynamically change the &lt;a href="http://software.schmorp.de/pkg/rxvt-unicode.html"&gt;URxvt&lt;/a&gt; font size:

&lt;pre&gt;
    #!/usr/bin/env bash
    
    printf '\33]50;%s%d\007' "xft:Monospace:pixelsize=" $1    
&lt;/pre&gt;

So to change to a 16 pixel font:

&lt;pre&gt;
    $ fontsize 16
&lt;/pre&gt;

&lt;br /&gt;&lt;br /&gt;

I have no idea what the control characters mean or what they will do to other terminal emulators. I found this script on a very helpful &lt;a href="http://bbs.archlinux.org/viewtopic.php?id=44121"&gt;Arch Linux forum&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-1465692548359211395?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/1465692548359211395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=1465692548359211395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1465692548359211395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1465692548359211395'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/dynamically-resive-font-in-urxvt.html' title='Dynamically Resive Font in URxvt'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-7231132850628096363</id><published>2009-04-02T19:53:00.000-07:00</published><updated>2009-04-02T20:05:34.308-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Convert Anything to MP3</title><content type='html'>Occasionally I need &lt;a href="http://www.vorbis.com/"&gt;ogg&lt;/a&gt; files to be mp3 files. A couple days later I need wma files to be mp3s. etc. etc. This script converts about anything to mp3:

&lt;pre&gt;
    #!/usr/bin/env bash
    
    # yield the file extension or nothing if there is no extension
    function ext {
      echo $1 | awk 'BEGIN { FS="." } { if(NF &amp;gt; 1) {print $NF} }'
    }
    
    # convert $1 to mp3
    function convert {
      src="$1"
      dst="$(dirname "$src")/$(basename "$src" .$(ext "$src")).mp3"
    
      # decode to wav with mplayer
      mplayer -vo null -vc dummy -af resample=44100 -ao pcm:waveheader "$src"
    
      # encode to mp3 with lame
      lame -m s audiodump.wav -o "$dst"
    
      # get rid of temporary file
      rm audiodump.wav
    }
    
    # handle spaces in file names
    IFS=$(echo -en "\n\b")
    
    for src in $* ; do
      echo -n "$src ... "
      convert "$src" &amp;amp;&amp;gt; /dev/null
      echo "done"
    done
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-7231132850628096363?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/7231132850628096363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=7231132850628096363' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7231132850628096363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7231132850628096363'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/convert-anything-to-mp3.html' title='Convert Anything to MP3'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6216540454853468492</id><published>2009-04-01T08:54:00.000-07:00</published><updated>2009-04-01T08:58:29.392-07:00</updated><title type='text'>Rip CD to wav</title><content type='html'>&lt;a href="http://burtonini.com/blog/computers/sound-juicer"&gt;Sound Juicer&lt;/a&gt; does a nice job ripping and encoding audio CDs. However, being graphical, it is not clear how to use it in a script. &lt;a href="http://www.xiph.org/paranoia/"&gt;CDDA Paranoia&lt;/a&gt; fills this need; to rip all the tracks of a CD to wav files simply:

&lt;pre&gt;
    $ cdparanoia -B
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6216540454853468492?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6216540454853468492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6216540454853468492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6216540454853468492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6216540454853468492'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/04/rip-cd-to-wav.html' title='Rip CD to wav'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2691869711415639493</id><published>2009-03-31T08:18:00.000-07:00</published><updated>2009-04-11T19:55:33.669-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><title type='text'>SSH Keys</title><content type='html'>This &lt;a href="http://mah.everybody.org/docs/ssh"&gt;guide on SSH key setup&lt;/a&gt; has a lot of good detail (&lt;a href="http://pkeck.myweb.uga.edu/ssh/"&gt;another&lt;/a&gt;). Here is just the essence:

&lt;br /&gt;&lt;br /&gt;

Generate and install public key:
&lt;ol&gt;
  &lt;li&gt;$ ssh-keygen -f ~/.ssh/id_dsa -t dsa&lt;/li&gt;
  &lt;li&gt;Enter a passphrase and hit [Enter]. Repeat.&lt;/li&gt;
  &lt;li&gt;Install your fresh key:
&lt;pre&gt;
    $ cat ~/.ssh/id_dsa.pub \
        | ssh MACHINE "cat - &amp;gt;&amp;gt; ~/.ssh/authorized_keys"
&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt; 

&lt;br /&gt;&lt;br /&gt;

Now you can ssh to MACHINE without entering your password, &lt;i&gt;but&lt;/i&gt; you have to enter your passphrase every time you want to access your private key. &lt;a href="http://en.wikipedia.org/wiki/Ssh-agent"&gt;ssh-agent&lt;/a&gt; fixes this. Simply edit your .xsession so that ssh-agent starts when you login:

&lt;pre&gt;
    change the line:
        xmonad
    to:
        ssh-agent xmonad 
&lt;/pre&gt;

But replace &lt;b&gt;xmonad&lt;/b&gt; with whatever window manager you use. Now the first time during a session you want to use your private key, you should:

&lt;pre&gt;
    $ ssh-add ~/.ssh/id_dsa
&lt;/pre&gt;

and from then on you will be able to ssh to MACHINE without entering your password.

&lt;br /&gt;&lt;br /&gt;

To get the same setup with another machine M, simply:

&lt;pre&gt;
    $ cat ~/.ssh/id_dsa.pub \
        | ssh M "cat - &amp;gt;&amp;gt; ~/.ssh/authorized_keys"
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2691869711415639493?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2691869711415639493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2691869711415639493' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2691869711415639493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2691869711415639493'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/03/ssh-keys.html' title='SSH Keys'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-1966653367186115754</id><published>2009-03-30T23:25:00.000-07:00</published><updated>2009-03-30T23:29:48.509-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='art'/><title type='text'>Mechanical Marble Adder</title><content type='html'>Here's a really neat mechanical adder from a &lt;a href="http://woodgears.ca/"&gt;brilliant woodworker&lt;/a&gt;:

&lt;br /&gt;&lt;br /&gt;

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/GcDshWmhF4A&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/GcDshWmhF4A&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;br /&gt;&lt;br /&gt;

I wonder if this could be used for some interesting lessons in K-12.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-1966653367186115754?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/1966653367186115754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=1966653367186115754' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1966653367186115754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1966653367186115754'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/03/mechanical-marble-adder.html' title='Mechanical Marble Adder'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2698915525534489103</id><published>2009-03-22T18:57:00.000-07:00</published><updated>2009-03-22T19:06:55.848-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='art'/><title type='text'>Kinetic Art by Arthur Ganson</title><content type='html'>The art of &lt;a href="http://www.arthurganson.com/"&gt;Arthur Ganson&lt;/a&gt; is extremely appealing. Here are just two examples:

&lt;br /&gt;&lt;br /&gt;
&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/6VBXQxoP814&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/6VBXQxoP814&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;br /&gt;&lt;br /&gt;
&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/sGIGXLVQoJw&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/sGIGXLVQoJw&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;br /&gt;&lt;br /&gt;

I found this on &lt;a href="http://www.cs.washington.edu/homes/mkehrt/"&gt;Matt Kehrt&lt;/a&gt;'s journal, one of the interesting people met at &lt;a href="http://www.cs.york.ac.uk/etaps09/"&gt;ETAPS 2009&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2698915525534489103?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2698915525534489103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2698915525534489103' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2698915525534489103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2698915525534489103'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/03/kinetic-art-by-arthur-ganson.html' title='Kinetic Art by Arthur Ganson'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5190478052193170654</id><published>2009-03-22T18:33:00.000-07:00</published><updated>2009-03-22T18:51:58.758-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ssh'/><category scheme='http://www.blogger.com/atom/ns#' term='internet'/><title type='text'>The Internet is Different in the UK</title><content type='html'>Turns out your geographic location changes the internet (e.g. Netflix, Hulu, YouTube, etc.). To fix simply:

&lt;pre&gt;
    $ ssh -D 8080 -f -C -q -N LOGIN@HOST
&lt;/pre&gt;

Where LOGIN is you and HOST is running sshd in the country you want the internet to think you are from. Basically, this just makes all traffic from your machine on port 8080 go through HOST.

&lt;br /&gt;&lt;br /&gt;

Now to get firefox sorted:

&lt;ol&gt;
  &lt;li&gt;If you use &lt;a href="http://vimperator.org/trac/wiki/Vimperator"&gt;Vimperator&lt;/a&gt;, get the menu back up for a bit by running:
&lt;pre&gt;
    :set guioptions+=mT
&lt;/pre&gt;&lt;/li&gt;
  &lt;li&gt;Navigate &lt;b&gt;Edit &gt; Preferences &gt; Network &gt; Settings&lt;/b&gt;&lt;/li&gt;
  &lt;li&gt;Select &lt;b&gt;Manual proxy configuration&lt;/b&gt;&lt;/li&gt;
  &lt;li&gt;For &lt;b&gt;SOCKS Host:&lt;/b&gt; enter &lt;i&gt;localhost&lt;/i&gt;&lt;/li&gt;
  &lt;li&gt;For &lt;b&gt;Port:&lt;/b&gt; enter &lt;i&gt;8080&lt;/i&gt;&lt;/li&gt;
  &lt;li&gt;Make sure your settings look like this: &lt;br /&gt;
  &lt;img width="400px" src="http://cs.ucsd.edu/~ztatlock/share/ssh-port-forwarding-firefox-proxy.png" /&gt;
&lt;br /&gt;&lt;/li&gt;
  &lt;li&gt;Click OK.&lt;/li&gt;
  &lt;li&gt;If you use Vimperator, get rid of those pesky menus with:
&lt;pre&gt;
    :set guioptions-=mT
&lt;/pre&gt;
&lt;/ol&gt;

You are now set to go! I found this at &lt;a href="http://paulstamatiou.com/2008/05/16/how-to-surf-securely-with-ssh-tunnel"&gt;Paul Stamatiou&lt;/a&gt;'s site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5190478052193170654?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5190478052193170654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5190478052193170654' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5190478052193170654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5190478052193170654'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/03/internet-is-different-in-uk.html' title='The Internet is Different in the UK'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2919629525100272287</id><published>2009-03-19T22:15:00.000-07:00</published><updated>2009-03-19T22:28:11.781-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Steve Bourne on Bourne Shell</title><content type='html'>Computerworld has a piece with &lt;a href="http://www.computerworld.com.au/article/279011/-z_programming_languages_bourne_shell_sh?fp=4194304&amp;fpid=1"&gt;Steve Bourne on Bourne shell&lt;/a&gt;. The most interesting bit was how he summed up the important design constraint of unquoted strings:

&lt;blockquote&gt;
As the Unix command line interpreter, for example, you wouldn’t want to be typing commands and have all the strings quoted like you would in C, because most things you type are simply uninterpreted strings. You don’t want to type ls directory and have the directory name in string quotes because that would be such a royal pain. Also, spaces are used to separate arguments to commands. The basic design is driven from there and that determines how you represent strings in the language, which is as un-interpreted text.
&lt;/blockquote&gt;

&lt;br /&gt;

Another interesting consideration is the importance of the shell as both an interactive environment and a scripting language. I've heard of people using toplevels in Python or even OCaml as command shells. I'm skeptical as it seems like such schemes would make common tasks noticeably more painful. What will shells be like in the future?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2919629525100272287?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2919629525100272287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2919629525100272287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2919629525100272287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2919629525100272287'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/03/steve-bourne-on-bourne-shell.html' title='Steve Bourne on Bourne Shell'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5788172154773960285</id><published>2009-03-19T11:26:00.000-07:00</published><updated>2009-03-19T11:35:27.717-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Deep Typechecking and Refactoring Poster</title><content type='html'>At the &lt;a href="http://www.ucsd.edu/"&gt;UCSD&lt;/a&gt; &lt;a href="http://www.jacobsschool.ucsd.edu/"&gt;Jacobs School of Engineering&lt;/a&gt; research poster session I presented our work on &lt;a href="http://cs.ucsd.edu/~ztatlock/projects/dtar.html"&gt;Deep Typechecking and Refactoring&lt;/a&gt;:

&lt;br /&gt;&lt;br /&gt;

&lt;center&gt;
&lt;a href="http://cs.ucsd.edu/~ztatlock/share/jsoe_dtar_poster.pdf"&gt;
 &lt;img width="90%" src="http://cs.ucsd.edu/~ztatlock/share/jsoe_dtar_poster.png" /&gt;
&lt;/a&gt;
&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5788172154773960285?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5788172154773960285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5788172154773960285' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5788172154773960285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5788172154773960285'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/03/deep-typechecking-and-refactoring.html' title='Deep Typechecking and Refactoring Poster'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-1009032143108487864</id><published>2009-03-14T07:09:00.000-07:00</published><updated>2009-03-14T07:17:07.240-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ML'/><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Caml Trading</title><content type='html'>&lt;a href="http://ocaml.janestreet.com/?q=node/61"&gt;Caml Trading&lt;/a&gt; is a nice talk given by &lt;a href="http://ocaml.janestreet.com/?q=blog/5"&gt;Yaron Minksy&lt;/a&gt; at CMU. The presentation briefly explains trading, motivates the use of ML in a general purpose setting, and considers areas for improvement. The Q&amp;amp;A at the end is particularly satisfying.

&lt;br /&gt;&lt;br /&gt;

I especially appreciated this wisdom:

&lt;pre&gt;
        You can't pay people enough to carefully review dull code.
&lt;/pre&gt;

Hooray FP!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-1009032143108487864?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/1009032143108487864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=1009032143108487864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1009032143108487864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1009032143108487864'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/03/caml-trading.html' title='Caml Trading'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2305530249593475194</id><published>2009-03-03T08:24:00.000-08:00</published><updated>2009-03-03T08:26:18.632-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Equality Saturation on LtU</title><content type='html'>Our work from POPL 2009 on &lt;a href="http://www.cse.ucsd.edu/~rtate/publications/eqsat/"&gt;Equality Saturation&lt;/a&gt; is on &lt;a href="http://lambda-the-ultimate.org/node/3220"&gt;Lambda the Ultimate&lt;/a&gt;, the hottest PL blog in the universe!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2305530249593475194?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2305530249593475194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2305530249593475194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2305530249593475194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2305530249593475194'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/03/equality-saturation-on-ltu.html' title='Equality Saturation on LtU'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-755347808653981381</id><published>2009-02-26T09:47:00.000-08:00</published><updated>2009-02-26T09:58:51.664-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='coq'/><title type='text'>Coq Syntax Highlighting In Vim</title><content type='html'>To get &lt;a href="http://coq.inria.fr/"&gt;coq&lt;/a&gt; syntax highlighting in &lt;a href="http://www.vim.org/"&gt;vim&lt;/a&gt;:

&lt;ol&gt;
  &lt;li&gt;Download &lt;a href="http://www.vim.org/scripts/download_script.php?src_id=9597"&gt;coq.vim&lt;/a&gt;. &lt;/li&gt;
  &lt;li&gt;Move the downloaded coq.vim to &lt;b&gt;~/.vim/syntax/&lt;/b&gt;&lt;/li&gt;
  &lt;li&gt;Add these lines to your &lt;b&gt;~/.vimrc&lt;/b&gt; file:
&lt;pre&gt;
    " syntax highlighting for coq
    au BufRead,BufNewFile *.v set filetype=coq
&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;br /&gt;&lt;br /&gt;

Here's the &lt;a href="http://www.vim.org/scripts/script.php?script_id=2063"&gt;official vim coq syntax highlighting page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-755347808653981381?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/755347808653981381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=755347808653981381' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/755347808653981381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/755347808653981381'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/02/coq-syntax-highlighting-in-vim.html' title='Coq Syntax Highlighting In Vim'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3576009571782341184</id><published>2009-02-25T20:51:00.000-08:00</published><updated>2009-02-25T21:02:51.366-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='svn'/><title type='text'>Make Subversion Ignore Files</title><content type='html'>To make &lt;a href="http://subversion.tigris.org/"&gt;svn&lt;/a&gt; ignore files matching GLOB in directory DIR, first list the globs you want ignored, one per line, in some file FILE (e.g. &lt;b&gt;.ignore&lt;/b&gt;), and then run:

&lt;pre&gt;
    $ svn propset svn:ignore -F FILE DIR
&lt;/pre&gt;

To apply this policy recursively on all the subdirectories, add -R to the mix:

&lt;pre&gt;
    $ svn propset svn:ignore -F FILE -R DIR
&lt;/pre&gt;

&lt;br /&gt;&lt;br /&gt;

For example, if you want svn to ignore any file in the current directory matching matching &lt;b&gt;*.o&lt;/b&gt;, first edit .ignore to contain:

&lt;pre&gt;
    *.o
&lt;/pre&gt;

and then run

&lt;pre&gt;
    $ svn propset svn:ignore -F .ignore .
&lt;/pre&gt;

If instead, you want to ignore all object files in this directory and all subdirectories, run:

&lt;pre&gt;
    $ svn propset svn:ignore -F .ignore -R .
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3576009571782341184?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3576009571782341184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3576009571782341184' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3576009571782341184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3576009571782341184'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/02/make-subversion-ignore-files.html' title='Make Subversion Ignore Files'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2909137723060212630</id><published>2009-02-25T10:03:00.000-08:00</published><updated>2009-02-25T18:50:20.334-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Bash Loop Over Filenames With Spaces</title><content type='html'>It is useful to pass a script a list of filenames and have it apply some function to each of those files. Unfortunately filenames with spaces won't work correctly in &lt;a href="http://www.cyberciti.biz/faq/bash-for-loop/"&gt;bash for loops&lt;/a&gt;. Each space separated part of the filename will be treated as a separate argument. (No, putting the args in quotes won't help here.)

&lt;br /&gt;&lt;br /&gt;

To fix this, you simply need to change the &lt;a href="http://tldp.org/LDP/abs/html/internalvariables.html"&gt;IFS variable&lt;/a&gt; (internal field separator) so that it doesn't include the space character. In order to restore default behavior, you may want to save the old IFS value and reset IFS after your loop. Thus, the solution looks something like:

&lt;pre&gt;
    OLDIFS=$IFS

    IFS=$(echo -en "\n\b")

    for f in $FILES; do
        foo $f
    done

    IFS=$OLDIFS
&lt;/pre&gt;

Here's an example of good and bad for loops:

&lt;br /&gt;&lt;br /&gt;

&lt;img src="http://cs.ucsd.edu/~ztatlock/share/for_loop_filenames_with_spaces.png" /&gt;

&lt;br /&gt;&lt;br /&gt;

I originally found &lt;a href="http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html"&gt;how to handle spaces in bash loops&lt;/a&gt; on the very useful &lt;a href="http://www.cyberciti.biz/"&gt;nixCraft&lt;/a&gt; site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2909137723060212630?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2909137723060212630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2909137723060212630' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2909137723060212630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2909137723060212630'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/02/bash-loop-over-filenames-with-spaces.html' title='Bash Loop Over Filenames With Spaces'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4999639751987400694</id><published>2009-02-15T17:59:00.000-08:00</published><updated>2009-02-15T18:07:40.303-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>banner</title><content type='html'>&lt;a href="http://en.wikipedia.org/wiki/Banner_(Unix)"&gt;banner&lt;/a&gt; is useful when you need to, oh say, celebrate &lt;a href="http://www.1234567890day.com/"&gt;1234567890 day&lt;/a&gt; at your department's &lt;a href="http://cse-gsa.ucsd.edu/csewiki/SocialHour"&gt;social hour&lt;/a&gt;. Basically, it just generates nice, page size banners. Use is simple:

&lt;pre&gt;
    $ banner 'your message here' | lpr -P printer
&lt;/pre&gt;

Using -w changes the size of the letters. So if you only want them to be 80 chars wide:

&lt;pre&gt;
    $ banner -w80 'your message here' | lpr -P printer
&lt;/pre&gt;

&lt;br /&gt;

&lt;a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?banner"&gt;banner manpage&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4999639751987400694?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4999639751987400694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4999639751987400694' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4999639751987400694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4999639751987400694'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/02/banner.html' title='banner'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5643303844640128963</id><published>2009-02-14T07:19:00.000-08:00</published><updated>2009-02-14T08:15:48.621-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='terminal'/><title type='text'>Configuring urxvt</title><content type='html'>&lt;a href="http://software.schmorp.de/pkg/rxvt-unicode.html"&gt;rxvt-unicode&lt;/a&gt; is a great terminal emulator. It blows the doors off of gnome-terminal and the like in terms of performance. Commands producing significant output &lt;i&gt;actually run faster&lt;/i&gt;. However, configuring urxvt takes a little bit more than a few clicks. In particular, you should use a &lt;a href="http://en.wikipedia.org/wiki/X_resources"&gt;.Xresources&lt;/a&gt; file to specify the default options you want urxvt to run with. Here's the relevant bit of my .Xresources:

&lt;pre&gt;
    ! urxvt settings
    URxvt.background   : #202020
    URxvt.foreground   : #999999
    URxvt.font         : -*-*-*-*-*-*-18-*-*-*-*-*-*-*
    URxvt.scrollBar    : False
    URxvt.pointerBlank : true
    
    URxvt.perl-ext-common : default,matcher
    URxvt.urlLauncher     : /usr/bin/firefox
    URxvt.matcher.button  : 1 
    
    ! black
    URxvt.color0  : #202020
    URxvt.color8  : #202020
    ! red
    URxvt.color1  : #bb4444
    URxvt.color9  : #bb4444
    ! green
    URxvt.color2  : #44bb44
    URxvt.color10 : #44bb44
    ! yellow
    URxvt.color3  : #bbbb44
    URxvt.color11 : #bbbb44
    ! blue
    URxvt.color4  : #4444aa
    URxvt.color12 : #4444aa
    ! magenta
    URxvt.color5  : #bb44bb
    URxvt.color13 : #bb44bb
    ! cyan
    URxvt.color6  : #44bbbb
    URxvt.color14 : #44bbbb
    ! white
    URxvt.color7  : #999999
    URxvt.color15 : #999999
&lt;/pre&gt;

This scheme is low contrast and large font to be easy on the eyes. Crucially, the bit:

&lt;pre&gt;
    URxvt.perl-ext-common : default,matcher
    URxvt.urlLauncher     : /usr/bin/firefox
    URxvt.matcher.button  : 1 
&lt;/pre&gt;

allows you to open links from the terminal in a new firefox tab by simply left clicking on them (from &lt;a href="http://mychael.gotdns.com/blog/2008/04/getting-urxvt-to-launch-urls/"&gt;here&lt;/a&gt; and &lt;a href="http://dotfiles.org/~jbromley/.Xresources"&gt;here&lt;/a&gt;). This was one feature I sorely missed from the more bloated terminals. Once you've updated your .Xresources file, you'll need to run &lt;a href="http://publib.boulder.ibm.com/infocenter/systems/index.jsp?topic=/com.ibm.aix.cmds/doc/aixcmds6/xrdb.htm"&gt;xrdb&lt;/a&gt; so the changes can take effect:

&lt;pre&gt;
    $ xrdb ~/.Xresources
&lt;/pre&gt;

after which all new urxvt instances will use your settings. To make sure these options are loaded every time, you should add the above command to your .xsession file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5643303844640128963?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5643303844640128963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5643303844640128963' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5643303844640128963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5643303844640128963'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/02/configuring-urxvt.html' title='Configuring urxvt'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6889563753340814670</id><published>2009-02-08T20:01:00.000-08:00</published><updated>2009-02-15T18:16:50.706-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Wget Recursive Downloading</title><content type='html'>&lt;a href="http://www.gnu.org/software/wget/"&gt;GNU Wget&lt;/a&gt; is normally used from the shell to fetch a single webpage. It also has the very useful ability to fetch a directory subtree from the web by recursively following links to pages in that domain. So to get &lt;i&gt;http://foo.com/bar.html&lt;/i&gt; and all the pages under &lt;i&gt;http://foo.com&lt;/i&gt; that &lt;i&gt;bar.html&lt;/i&gt; links to, simply run:

&lt;pre&gt;
    $ wget -r http://foo.com/bar.html
&lt;/pre&gt;

To get &lt;a href="http://www.faqs.org/docs/abs/HTML/globbingref.html"&gt;globbing&lt;/a&gt; like behavior, a couple of flags do the right thing:

&lt;pre&gt;
    $ wget -r -l1 --no-parent -A.gif http://www.server.com/dir/
&lt;/pre&gt;

-r -l1 means to retrieve recursively, with maximum depth of 1. &lt;br /&gt;
--no-parent means that references to the parent directory are ignored. &lt;br /&gt;
-A.gif means to download only the GIF files. (-A "*.gif" would have worked too.) &lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6889563753340814670?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6889563753340814670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6889563753340814670' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6889563753340814670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6889563753340814670'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/02/wget-recursive-downloading.html' title='Wget Recursive Downloading'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6047221856295589164</id><published>2009-02-07T07:45:00.000-08:00</published><updated>2009-02-08T19:26:19.321-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Base Conversion Script</title><content type='html'>Here's a simple script for (somewhat) arbitrary base conversions:

&lt;pre&gt;
    #!/usr/bin/env bash
    
    if [ $# -lt 3 ] ; then
      echo "Usage: $0 &amp;lt;input base&amp;gt; &amp;lt;output base&amp;gt; &amp;lt;num&amp;gt; ... &amp;lt;num&amp;gt;"
      exit 1
    fi
    
    b0=$1
    b1=$2
    shift 2
    
    # put semis between the remaining args
    ns=$(echo $* | sed 's/ /; /g')
    
    # convert b1 from base 10 to base b0
    b1=$(echo "ibase=10; obase=$b0; $b1" | bc)
    
    # perform conversion
    echo "ibase=$b0; obase=$b1; $ns" | bc
    
&lt;/pre&gt;

Note (1) the use of sed to insert semicolons between the arguments to be converted and (2) the conversion of of the output base to the input base before the conversion of the arguments. These keep &lt;a href="http://www.gnu.org/software/bc/manual/html_mono/bc.html"&gt;bc&lt;/a&gt; happy and doing the right thing.

&lt;br /&gt;&lt;br /&gt;

Example use:&lt;br /&gt;&lt;br /&gt;

&lt;img src="http://cs.ucsd.edu/~ztatlock/share/baseconv_example.png" /&gt;

&lt;br /&gt;&lt;br /&gt;

Caveats: 
&lt;ul&gt;
  &lt;li&gt;Bases less than 2 and greater than 16 appear broken in bc.&lt;/li&gt;
  &lt;li&gt;Any digits in an input number that are &amp;gt;= the base are treated as the max digit in that base. e.g. in base 2 '123' is treated as '111'.&lt;/li&gt;
  &lt;li&gt;Hexadecimal digits need to be upper case, but this can easily be fixed by first piping the input through awk, e.g. preprocess ns with:
&lt;pre&gt;
    ns=$(echo $ns | awk '{ print toupper($0) }')
&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6047221856295589164?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6047221856295589164/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6047221856295589164' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6047221856295589164'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6047221856295589164'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/02/base-conversion-script.html' title='Base Conversion Script'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4921633337020056201</id><published>2009-02-05T08:34:00.000-08:00</published><updated>2009-02-05T09:30:29.783-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tex'/><title type='text'>Latex Landscape</title><content type='html'>To get an entire document in landscape mode, include this line in the head of the document:

&lt;pre&gt;
    \usepackage[landscape]{geometry}
&lt;/pre&gt;

Instead, to get only a specific page in landscape mode, first include the &lt;b&gt;lscape&lt;/b&gt; package in the header:

&lt;pre&gt;
    \usepackage{lscape}
&lt;/pre&gt;

and then wrap the page you want to be in landscape mode:

&lt;pre&gt;
    \begin{landscape}
    ...
    \end{landscape}
&lt;/pre&gt;

The generated pdf will have this page in landscape mode, but the page will still be in the portrait orientation. If you want the page in the pdf to be in landscape orientation, then use the package &lt;b&gt;pdflscape&lt;/b&gt; instead of &lt;b&gt;lscape&lt;/b&gt;.

&lt;br /&gt;&lt;br /&gt;

Landscape mode is good for long &lt;a href="http://en.wikipedia.org/wiki/Pipeline_(computing)"&gt;pipeline&lt;/a&gt; diagrams. This was found in the &lt;a href="http://texblog.wordpress.com/2007/11/10/landscape-in-latex/"&gt;Blog on Latex Matters&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4921633337020056201?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4921633337020056201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4921633337020056201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4921633337020056201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4921633337020056201'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/02/latex-landscape.html' title='Latex Landscape'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-7273042082598001758</id><published>2009-01-31T18:05:00.000-08:00</published><updated>2009-01-31T18:24:32.935-08:00</updated><title type='text'>Wordle</title><content type='html'>&lt;a href="http://www.wordle.net/"&gt;Wordle&lt;/a&gt; is a fun service that creates word collages based on an RSS feed or some other source of text. Here's the example for this blog:

&lt;br /&gt;&lt;br /&gt;

&lt;a href="http://cs.ucsd.edu/~ztatlock/share/wordle_20090131.png"&gt;
&lt;img src="http://cs.ucsd.edu/~ztatlock/share/wordle_20090131.png" width="450px" /&gt;
&lt;/a&gt;

&lt;br /&gt;&lt;br /&gt;

I initially saw this on &lt;a href="http://wadler.blogspot.com/"&gt;Wadler's blog&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-7273042082598001758?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/7273042082598001758/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=7273042082598001758' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7273042082598001758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7273042082598001758'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/wordle.html' title='Wordle'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-1163762246732234526</id><published>2009-01-28T06:57:00.000-08:00</published><updated>2009-02-08T20:17:15.591-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='papers'/><category scheme='http://www.blogger.com/atom/ns#' term='compcert'/><title type='text'>Formal Certification of a Compiler Back-end</title><content type='html'>&lt;a href="http://pauillac.inria.fr/%7Exleroy/publi/compiler-certif.pdf"&gt;Formal Certification of a Compiler Back-end&lt;/a&gt; (or: Programming a Compiler with a Proof Assistant) describes &lt;a href="http://pauillac.inria.fr/~xleroy/"&gt;Xavier Leroy&lt;/a&gt;'s technique for building a compiler that is formally guaranteed to be &lt;i&gt;semantically transparent&lt;/i&gt;. In other words, if this compiler generates assembly program A for some input program P, then A and P are guaranteed to be equivalent. The approach centers around using the &lt;a href="http://coq.inria.fr/"&gt;Coq proof assistant&lt;/a&gt; to both program the compiler and reason about the compiler's implementation. The paper is very well written and enjoyable to read.

&lt;br /&gt;&lt;br /&gt;

In the first two sections the problem of compiler correctness is well motivated and a high level overview of certified, certifying, and verified compilation is provided. The author unifies these three approaches to compiler correctness and shows how they can safely be composed. The third section describes the intermediate representations (IRs) used in the compiler, which helps the reader understand the compiler's high level structure:

&lt;pre&gt;
    Cminor    The C-like source language
              Attempts to capture subset of C most useful to embedded developers

    RTL       Register Transfer Language
              Functions are represented as CFGs with an unlimited set of registers
              Nodes in the CFG are instructions, not basic blocks
              Optimizations are performed on this IR

    LTL       Location Transfer Language
              Nodes in the CFG changed from instructions to basic blocks
              Pseudo registers changed to machine registers or stack slots

    Linear    The CFG is flattened to a list of instructions 
                  with explicit labels and branches
              
    Mach      Stack slots are mapped to actual memory locations

    PowerPC   The output language
              PowerPC chips are widely used in embedded systems
              Some pseudo-instructions (macros) are used
&lt;/pre&gt;

At the time of writing, the compiler supported &lt;a href="http://en.wikipedia.org/wiki/Constant_folding"&gt;constant propagation&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Common_subexpression_elimination"&gt;common subexpression elimination&lt;/a&gt; optimizations. The operational semantics of each IR are fully formalized, and example rules are provided in the paper.

&lt;br /&gt;&lt;br /&gt;

The fourth section provides details on the compiler passes and their correctness proofs. Intuitively, the proofs work by showing that if a program P0 in IR0 is equivalent to program P1 in IR1 and P0 evaluates down to P0' and P1 evaluates down to P1', then P0' and P1' are equivalent. The paper uses simulation diagrams to help make this idea clear:

&lt;pre&gt;
                  P0   ==========   P1

                  |                 |
                  |                 |
                  v                 v

                  P0'  ==========   P1'
&lt;/pre&gt;

where the = signs signify a correspondence and the arrows show evaluation.

&lt;br /&gt;&lt;br /&gt;

When everything is said and done, the compiler weighs in at roughly 36 KLOC that took "one man year" to develop (I use scare quotes because one year of Xavier Leroy hacking is probably worth significantly more that "one man year"). The quality of generated code is very good as is compile time. Next, the paper provides a nice overview of lessons learned during the development process. Some highlights include the success of Coq as a programming language and the relative difficulty of certified transformation (prove transformer correct, once-and-for-all) vs. certified verification (untrusted transformations are checked by correct verifier). Interestingly, the author suggests that certified verification should have been employed more frequently.

&lt;br /&gt;&lt;br /&gt;

The final sections compare related work (where &lt;a href="http://www.cs.ucsd.edu/~lerner/"&gt;Sorin&lt;/a&gt; gets a shout out), and conclude. Great paper. Well worth the read.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-1163762246732234526?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/1163762246732234526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=1163762246732234526' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1163762246732234526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/1163762246732234526'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/formal-certification-of-compiler-back.html' title='Formal Certification of a Compiler Back-end'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2889133831628331148</id><published>2009-01-27T15:25:00.000-08:00</published><updated>2009-01-27T19:57:25.336-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Equality Saturation Talk</title><content type='html'>&lt;a href="http://www.cs.ucsd.edu/~rtate/"&gt;Ross Tate&lt;/a&gt; recorded his talk from our &lt;a href="http://www.cs.ucsd.edu/popl/09/"&gt;POPL 2009&lt;/a&gt; paper, &lt;a href="http://cs.ucsd.edu/~ztatlock/publications/eqsat_tate_popl09.pdf"&gt;Equality Saturation: a new Approach to Optimization&lt;/a&gt;:

&lt;br /&gt;&lt;br /&gt;

&lt;script type="text/javascript" src="http://cs.ucsd.edu/~rtate/publications/eqsat/swfobject.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
        swfobject.registerObject("csSWF", "9.0.115", "expressInstall.swf");
&lt;/script&gt;
&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="456" height="360" id="csSWF"&gt;
  &lt;param name="movie"
  value="http://cs.ucsd.edu/~rtate/publications/eqsat/Equality%20Saturation_controller.swf" /&gt;
  &lt;param name="quality" value="best" /&gt;
  &lt;param name="bgcolor" value="#1a1a1a" /&gt;
  &lt;param name="allowfullscreen" value="true" /&gt;
  &lt;param name="scale" value="showall" /&gt;
  &lt;param name="allowscriptaccess" value="always" /&gt;
  &lt;param name="flashvars" value="autostart=false&amp;thumb=http://cs.ucsd.edu/~rtate/publications/eqsat/FirstFrame.png&amp;thumbscale=45&amp;color=0x1A1A1A,0x1A1A1A" /&gt;

  &lt;object type="application/x-shockwave-flash"
    data="http://cs.ucsd.edu/~rtate/publications/eqsat/Equality%20Saturation_controller.swf" width="456" height="360"&gt;
    &lt;param name="quality" value="best" /&gt;
    &lt;param name="bgcolor" value="#1a1a1a" /&gt;
    &lt;param name="allowfullscreen" value="true" /&gt;
    &lt;param name="scale" value="showall" /&gt;
    &lt;param name="allowscriptaccess" value="always" /&gt;
    &lt;param name="flashvars" value="autostart=false&amp;thumb=http://cs.ucsd.edu/~rtate/publications/eqsat/FirstFrame.png&amp;thumbscale=45&amp;color=0x1A1A1A,0x1A1A1A" /&gt;
  &lt;/object&gt;
&lt;/object&gt;


&lt;br /&gt;&lt;br /&gt;

It is a great talk, and weighing in at thirteen minutes, it is well worth your time to check out. If the flash version above doesn't show up, try this &lt;a href="http://www.cs.ucsd.edu/~rtate/publications/eqsat/Equality%20Saturation.mp4"&gt;mp4 version&lt;/a&gt;. A more thorough description of this work is available on &lt;a href="http://www.cs.ucsd.edu/~rtate/publications/eqsat/"&gt;Ross's Equality Saturation page&lt;/a&gt;.

&lt;br /&gt;&lt;br /&gt;

BTW, doing a screencast of your talk after the conference is a GREAT idea.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2889133831628331148?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2889133831628331148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2889133831628331148' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2889133831628331148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2889133831628331148'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/equality-saturation-video.html' title='Equality Saturation Talk'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4515873286927900609</id><published>2009-01-27T13:18:00.000-08:00</published><updated>2009-01-27T13:21:41.987-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>PLDI 2009 Accept</title><content type='html'>Our work on proving compiler optimizations correct once-and-for-all got into PLDI! The other two papers from our group got in too. Hooray &lt;a href="http://www.cs.ucsd.edu/groups/progsys/"&gt;UCSD progsys&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4515873286927900609?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4515873286927900609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4515873286927900609' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4515873286927900609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4515873286927900609'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/pldi-2009-accept.html' title='PLDI 2009 Accept'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8932246796335117452</id><published>2009-01-25T11:04:00.000-08:00</published><updated>2009-02-08T19:36:02.253-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haha'/><title type='text'>Snoring Joke</title><content type='html'>&lt;a href="http://www.cs.ucsd.edu/~rtate/"&gt;Ross&lt;/a&gt;: So Zach's snoring was soft for a while. Then it gradually got REALLY loud, like I could hear it over my headphones loud. Then it died back down till it stopped. And that repeated.

&lt;br /&gt;&lt;br /&gt;

&lt;a href="http://www.cs.ucsd.edu/~mstepp/"&gt;Mike&lt;/a&gt;: So it was kind of &lt;a href="http://en.wikipedia.org/wiki/Periodic_function"&gt;periodic&lt;/a&gt;?

&lt;br /&gt;&lt;br /&gt;

&lt;a href="http://www.cs.ucsd.edu/~ztatlock"&gt;Zach&lt;/a&gt;: Yeah, I have a &lt;a href="http://en.wikipedia.org/wiki/Paranasal_sinus"&gt;sinus&lt;/a&gt;-&lt;a href="http://en.wikipedia.org/wiki/Sine_wave"&gt;oidal&lt;/a&gt; problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8932246796335117452?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8932246796335117452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8932246796335117452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8932246796335117452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8932246796335117452'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/snoring-joke.html' title='Snoring Joke'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5629665962813839471</id><published>2009-01-22T06:48:00.000-08:00</published><updated>2009-01-22T06:50:32.988-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mutt'/><title type='text'>mutt URL Color</title><content type='html'>Add this to your .muttrc to highlight URLs:

&lt;pre&gt;
    # colors
    color body magenta black "(http|https|ftp)://[^ ]+" # picks up URLs
&lt;/pre&gt;

Lifted from a more complete &lt;a href="http://blog.kevinmeltzer.com/archives/000636.html"&gt;mutt colors specification&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5629665962813839471?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5629665962813839471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5629665962813839471' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5629665962813839471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5629665962813839471'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/mutt-url-color.html' title='mutt URL Color'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6756611910139515126</id><published>2009-01-19T09:56:00.000-08:00</published><updated>2009-01-19T10:49:05.667-08:00</updated><title type='text'>Podracer : A GNU/Linux Podcast Aggregator</title><content type='html'>&lt;a href="http://podracer.sourceforge.net/"&gt;Podracer&lt;/a&gt; plus &lt;a href="http://en.wikipedia.org/wiki/Cron"&gt;cron&lt;/a&gt; seems like a nice tool to keep all your podcasts up to date without relying on a pesky X app. Set up is simple:

&lt;pre&gt;
    $ sudo apt-get install podracer
    $ mkdir ~/.podracer
    $ touch ~/.podracer/podracer.conf
    $ touch ~/.podracer/subscriptions

&lt;/pre&gt; 

Edit ~/.podracer/podracer.conf (/etc/podracer.conf has full options):

&lt;pre&gt;
    # where to save podcasts
    poddir=$HOME/media/podcasts
    
    # where to look for subscriptions
    subscriptions=$HOME/.podracer/subscriptions
    
    # how many times to retry a download
    retries=5

&lt;/pre&gt;

Edit ~/.podracer/subscriptions and add your favorite feeds:

&lt;pre&gt;
    Car Talk
    http://www.npr.org/rss/podcast.php?id=510208 car_talk
    
    A Way With Words
    http://feeds.waywordradio.org/awwwpodcast a_way_with_words
    
    This American Life
    http://feeds.thisamericanlife.org/talpodcast this_american_life
    
    The News From Lake Wobegon 
    http://americanpublicmedia.publicradio.org/podcasts/xml/prairie_home_companion/news_from_lake_wobegon.xml lake_wobegon
    
    The Writer's Almanac
    http://www.npr.org/rss/podcast.php?id=510101 writers_almanac
    
    Software Engineering Radio
    http://feeds.feedburner.com/se-radio se_radio
    
&lt;/pre&gt;

Note that any line not beginning with a feed URL is considered a comment and any tokens after a URL are taken to be the download directory for that feed. 

&lt;br /&gt;&lt;br /&gt;

If you want avoid downloading all the old episodes from your feeds, run:

&lt;pre&gt;
    $ podracer -c
&lt;/pre&gt;

This updates podracer's log so that it thinks it has already downloaded all the old podcasts. Finally, edit your crontab and add a line to have podracer fetch new podcasts twice a day:

&lt;pre&gt;
    # at midnight and noon fetch new podcasts
    0 0,12 * * * /usr/bin/podracer
&lt;/pre&gt;

Now update your crontab with and check it with:

&lt;pre&gt;
    $ crontab /path/to/your/crontab
    $ crontab -l
&lt;/pre&gt;

All this is based on Matt Cutt's &lt;a href="http://www.mattcutts.com/blog/download-podcasts-on-linux/"&gt;podracer setup&lt;/a&gt; post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6756611910139515126?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6756611910139515126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6756611910139515126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6756611910139515126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6756611910139515126'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/podracer-gnulinux-podcast-aggregator.html' title='Podracer : A GNU/Linux Podcast Aggregator'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6086693859670830599</id><published>2009-01-17T12:29:00.000-08:00</published><updated>2009-02-08T19:37:07.966-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haha'/><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><category scheme='http://www.blogger.com/atom/ns#' term='English'/><title type='text'>Paul Graham and Parody</title><content type='html'>I really enjoy reading &lt;a href="http://www.paulgraham.com/"&gt;Paul Graham&lt;/a&gt;'s essays. He is an excellent writer and often explores simple, interesting hypotheses. For example the idea that &lt;a href="http://www.paulgraham.com/power.html"&gt;succinctness is power&lt;/a&gt; in programming languages has a couple of good basic arguments that seem well motivated. Essentially, the idea is that we do not code in assembly because it is a waste of time. We can get basically the same result (or sometimes better) by spending less time writing shorter programs; the principle being that succinctness is the power programming languages provide.

&lt;br /&gt;&lt;br /&gt;

Unfortunately, Paul Graham often extends his approximations past the regime in which they were intended to operate. This has led to an excellent parody, &lt;a href="http://www.xach.com/lisp/taste-for-the-web.html"&gt;Taste for the Web&lt;/a&gt;, and a call of "bullshit" in &lt;a href="http://www.idlewords.com/2005/04/dabblers_and_blowhards.htm"&gt;Dabblers and Blowhards&lt;/a&gt;. Both are humorous reads if you're familiar with Graham's essays.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6086693859670830599?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6086693859670830599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6086693859670830599' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6086693859670830599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6086693859670830599'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/paul-graham-and-parody.html' title='Paul Graham and Parody'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8427589125053304801</id><published>2009-01-16T08:53:00.000-08:00</published><updated>2009-01-16T08:57:27.245-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='papers'/><title type='text'>The History of the Microcomputer</title><content type='html'>Ever wonder why the stack grows down? How the first single chip computers came about? Why x86 is little endian? Well, then you should definitely check out &lt;a href="http://cs.ucsd.edu/~ztatlock/share/papers/Microcomputer_History_Mazor.pdf"&gt;The History of the Microcomputer -- Invention and Evolution&lt;/a&gt; by &lt;a href="http://www.invent.org/hall_of_fame/100.html"&gt;Stanley Mazor&lt;/a&gt;. Not exactly a gripping read, but great historical value.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8427589125053304801?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8427589125053304801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8427589125053304801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8427589125053304801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8427589125053304801'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/history-of-microcomputer.html' title='The History of the Microcomputer'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8915878612904832941</id><published>2009-01-14T08:45:00.000-08:00</published><updated>2009-01-14T09:01:22.518-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Vim Single Character Insert</title><content type='html'>Here's a nice mapping to add to your .vimrc for single character insert from command mode in vim:

&lt;pre&gt;
    " single character insert
    nmap &amp;lt;Space&amp;gt; i_&amp;lt;Esc&amp;gt;r
&lt;/pre&gt;

Now to insert the character C to the position under the cursor simply hit the space bar and type C. Any existing characters are shifted to the right. The way it works is pretty neat: it inserts an underscore and then starts a command to replace a single character. Thus when you type the character you want, it replaces the underscore inserted by the mapping. Credit for this goes to &lt;a href="http://www.cse.ucsd.edu/~ngouldin/"&gt;Nathan Goulding&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8915878612904832941?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8915878612904832941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8915878612904832941' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8915878612904832941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8915878612904832941'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/vim-single-character-insert.html' title='Vim Single Character Insert'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2878951349542548124</id><published>2009-01-13T08:38:00.000-08:00</published><updated>2009-02-08T20:16:44.434-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Sed Reference</title><content type='html'>&lt;a href="http://www.grymoire.com/Unix/Sed.html"&gt;This sed page&lt;/a&gt; is a great introduction and reference for using &lt;a href="http://en.wikipedia.org/wiki/Sed"&gt;sed&lt;/a&gt;. In &lt;a href="http://en.wikipedia.org/wiki/The_Unix_Programming_Environment"&gt;The Unix Programming Environment&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Brian_W._Kernighan"&gt;Kernighan&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Rob_Pike"&gt;Pike&lt;/a&gt; relate the tale of &lt;a href="http://en.wikipedia.org/wiki/Lee_E._McMahon"&gt;Lee McMahon&lt;/a&gt; hacking sed together using the &lt;a href="http://en.wikipedia.org/wiki/Ed_(Unix)"&gt;ed&lt;/a&gt; source. I always thought that story was a great example of the benefits derived from *nix tradition of having access to the source.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2878951349542548124?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2878951349542548124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2878951349542548124' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2878951349542548124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2878951349542548124'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/sed-reference.html' title='Sed Reference'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4655022735613038407</id><published>2009-01-12T11:15:00.000-08:00</published><updated>2009-01-13T08:59:16.672-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='papers'/><title type='text'>Cramming More Components Onto Integrated Circuits</title><content type='html'>The original &lt;a href="http://cs.ucsd.edu/~ztatlock/share/papers/Moores_Law_Paper.pdf"&gt;Moore's Law paper&lt;/a&gt; by &lt;a href="http://en.wikipedia.org/wiki/Gordon_Moore"&gt;Gordon Moore&lt;/a&gt; is a pretty fast, enjoyable read. It's amazing how long the &lt;a href="http://en.wikipedia.org/wiki/Moore%27s_law"&gt;trend&lt;/a&gt; he predicted in 1965 has &lt;a href="http://www.intel.com/technology/mooreslaw/index.htm"&gt;held up&lt;/a&gt;. Note that Moore talks about &lt;a href="http://en.wikipedia.org/wiki/Linear_circuit"&gt;linear circuits&lt;/a&gt; which I guess are some kind of &lt;a href="http://en.wikipedia.org/wiki/Analogue_electronics"&gt;analog circuit&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4655022735613038407?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4655022735613038407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4655022735613038407' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4655022735613038407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4655022735613038407'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/cramming-more-components-onto.html' title='Cramming More Components Onto Integrated Circuits'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5857523159484865743</id><published>2009-01-10T14:08:00.000-08:00</published><updated>2009-01-11T05:28:05.068-08:00</updated><title type='text'>Harbor Freight</title><content type='html'>&lt;a href="http://www.harborfreight.com/"&gt;Harbor Freight&lt;/a&gt; looks like a great place to get supplies for projects. Examples: 
&lt;ul&gt;
 &lt;li&gt;&lt;a href="http://www.harborfreight.com/cpi/ctaf/displayitem.taf?Itemnumber=90599"&gt;45 Watt Solar Panel&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://www.harborfreight.com/cpi/ctaf/Displayitem.taf?itemnumber=46900"&gt;Industrial Suction Cups&lt;/a&gt; (think scaling a skyscraper)&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://www.harborfreight.com/cpi/ctaf/Displayitem.taf?itemnumber=97212"&gt;Motion Detection Soap Dispenser&lt;/a&gt;&lt;/li&gt;
 &lt;li&gt;&lt;a href="http://ww2.harborfreight.com/cpi/ctaf/Category.taf?CategoryID=738&amp;pricetype="&gt;Various Electrical Switches&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
There is also a lot of neat junk for presents.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5857523159484865743?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5857523159484865743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5857523159484865743' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5857523159484865743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5857523159484865743'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/harbor-freight.html' title='Harbor Freight'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5955865542663181062</id><published>2009-01-08T15:35:00.000-08:00</published><updated>2009-01-08T15:38:42.311-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='make'/><title type='text'>GNU Make Automatic Variables</title><content type='html'>Somehow, the page for make's automatic variables is never very high on my searches. Here it is once and for all: &lt;a href="http://www.gnu.org/software/automake/manual/make/Automatic-Variables.html#Automatic-Variables"&gt;GNU Make Automatic Variables&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5955865542663181062?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5955865542663181062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5955865542663181062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5955865542663181062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5955865542663181062'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/gnu-make-automatic-variables.html' title='GNU Make Automatic Variables'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-7141708840630587196</id><published>2009-01-08T13:24:00.000-08:00</published><updated>2009-01-08T13:27:51.286-08:00</updated><title type='text'>Incentivizing IPv6</title><content type='html'>To make the transition to IPv6 happen, there needs to be a killer app that demands IPv6. A group of individuals has decided to create that incentive: &lt;a href="http://www.ipv6experiment.com/"&gt;http://www.ipv6experiment.com/&lt;/a&gt;

&lt;br /&gt;&lt;br /&gt;

Hilarious.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-7141708840630587196?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/7141708840630587196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=7141708840630587196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7141708840630587196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7141708840630587196'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/incentivizing-ipv6.html' title='Incentivizing IPv6'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8454595159499995795</id><published>2009-01-07T08:56:00.000-08:00</published><updated>2009-01-07T11:21:26.745-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Volume Control With amixer and osd_cat</title><content type='html'>This script controls volume from the shell, although I typically invoke it with keybindings in &lt;a href="http://xmonad.org/"&gt;xmonad&lt;/a&gt;. By default, the PCM channel is selected, but an argument changes which channel the script controls. The use of &lt;a href="http://www.ignavus.net/software.html"&gt;xosd&lt;/a&gt; is due to &lt;a href="http://www.scs.stanford.edu/~stutsman/"&gt;R&lt;/a&gt;.

&lt;pre&gt;
    #!/usr/bin/env bash
    
    CHANNEL=PCM
    
    if [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then
      p=$(basename $0)
      cat &amp;lt;&amp;lt;HERE
    
      Usage: $p &amp;lt;channel&amp;gt; &amp;lt;option&amp;gt;
      where option is in {+, -, m, u} or is a percent
      e.g. $p 50       # sets $CHANNEL to 50%
           $p Front m  # mutes the channel Front
    
    HERE
      exit 0
    fi
    
    if [ $# -eq 2 ] ; then
      CHANNEL=$1
      shift
    fi
    
    function vol_level {
      amixer get $CHANNEL |\
      grep 'Front Left:'  |\
      cut -d " " -f 7     |\
      sed 's/[^0-9]//g'
    }
    
    function vol_osd {
      killall osd_cat &amp;amp;&amp;gt; /dev/null
      osd_cat -d 2 -l 2 -p bottom -c green \
        -f '-*-terminal-*-*-*-*-*-*-*-*-*-*-*-*' \
        -T "Volume ($CHANNEL)" -b percentage -P $(vol_level) &amp;amp;
    }
    
    function osd {
      killall osd_cat &amp;amp;&amp;gt; /dev/null
      echo $* |\
      osd_cat -d 2 -l 1 -p bottom -c green \
        -f '-*-terminal-*-*-*-*-*-*-*-*-*-*-*-*' &amp;amp;
    }
    
    case "$1" in
      "")
        vol_level
        ;;
      "+")
        amixer -q set $CHANNEL 5%+
        vol_osd
        ;;
      "-")
        amixer -q set $CHANNEL 5%-
        vol_osd
        ;;
      "m")
        amixer -q set $CHANNEL mute
        osd $CHANNEL mute
        ;;
      "u")
        amixer -q set $CHANNEL unmute
        osd $CHANNEL unmute
        ;;
      *)
        amixer -q set $CHANNEL $1%
        ;;
    esac
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8454595159499995795?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8454595159499995795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8454595159499995795' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8454595159499995795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8454595159499995795'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/volume-control-with-amixer-and-osdcat.html' title='Volume Control With amixer and osd_cat'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5119843946562727913</id><published>2009-01-06T09:33:00.000-08:00</published><updated>2009-01-13T22:55:19.925-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Hex Editor Via xxd</title><content type='html'>&lt;a href="http://gd.tuwien.ac.at/linuxcommand.org/man_pages/xxd1.html"&gt;xxd&lt;/a&gt; is an external program in the vim package that provides hex dumping and &lt;i&gt;hex dump parsing&lt;/i&gt;. Because of the parsing, xxd allows you to use any editor as a hex editor, even a stream editor:

&lt;pre&gt;
    $ xxd foo.pbm | sed 's/ffff/5555/g' | xxd -r &gt; bar.pbm
&lt;/pre&gt; 

&lt;br /&gt;

In general, to use xxd and EDITOR as a hex editor for file FOO, one would:

&lt;pre&gt;
    $ xxd FOO &gt; BAR
    $ EDITOR BAR
    $ xxd -r BAR &gt; FOO
&lt;/pre&gt;

Note that while you are editing the intermediate file produced by xxd, you can ignore the first and last columns of the file. So in the example above, while you are editing BAR you can ignore the line number and ASCII columns. You can also use xxd to perform hex editing &lt;a href="http://lists.freebsd.org/pipermail/freebsd-questions/2003-July/012019.html"&gt;directly in vim&lt;/a&gt; by running xxd over the buffer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5119843946562727913?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5119843946562727913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5119843946562727913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5119843946562727913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5119843946562727913'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/hex-editor-via-xxd.html' title='Hex Editor Via xxd'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4553182014774890987</id><published>2009-01-05T14:46:00.000-08:00</published><updated>2009-01-05T15:03:07.730-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='compcert'/><title type='text'>Linux CompCert Build</title><content type='html'>&lt;a href="http://compcert.inria.fr/"&gt;CompCert&lt;/a&gt; only supports Max OS X, but can trivially be built for Linux:

&lt;ol&gt;
  &lt;li&gt;Install &lt;a href="http://coq.inria.fr/"&gt;Coq&lt;/a&gt; and &lt;a href="http://caml.inria.fr/"&gt;OCaml&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Get the latest source from the &lt;a href="http://compcert.inria.fr/download.html"&gt;CompCert download page&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Unpack the tarball and cd into it.&lt;/li&gt;
  &lt;li&gt;./configure -prefix ~/projects/compcert&lt;/li&gt;
  &lt;li&gt;Edit Makefile.config and remove any occurrence of '-arch ppc', i.e.
&lt;pre&gt;
    PREFIX=/home/ztatlock/projects/compcert
    BINDIR=$(PREFIX)/bin
    LIBDIR=$(PREFIX)/lib/compcert

    CC=gcc
    CPREPRO=gcc -U__GNUC__ -E
    CASM=gcc -c
    CLINKER=gcc
    LIBMATH=
    ARCHOS=x86_LINUX

    #CC=gcc -arch ppc
    #CPREPRO=gcc -arch ppc -U__GNUC__ -E
    #CASM=gcc -arch ppc -c
    #CLINKER=gcc -arch ppc
    #LIBMATH=
    #ARCHOS=x86_LINUX
&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;make all&lt;/li&gt;
  &lt;li&gt;make install&lt;/li&gt;
&lt;/ol&gt;

&lt;br /&gt;&lt;br /&gt;
The resulting &lt;b&gt;ccomp&lt;/b&gt; will not generate useful executables (unless you have a cross compiler and emulator handy), but you can get the PPC assembly with &lt;b&gt;ccomp -S&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4553182014774890987?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4553182014774890987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4553182014774890987' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4553182014774890987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4553182014774890987'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/linux-compcert-build.html' title='Linux CompCert Build'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8099896147375522439</id><published>2009-01-04T15:43:00.000-08:00</published><updated>2009-01-04T15:55:14.800-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freedom'/><title type='text'>Amtrak Police Abuse Photographer</title><content type='html'>&lt;a href="http://photos.duanek.name/gallery/6905238_LgEPL#441825476_Va42A"&gt;Duane Kerzic&lt;/a&gt; was injured and detained by Amtrak police for &lt;a href="http://carlosmiller.com/2008/12/27/amtrak-police-arrest-photographer-participating-in-amtrak-photo-contest/"&gt;taking photos&lt;/a&gt; from within a station. Other railways are &lt;a href="http://www.trainorders.com/discussion/read.php?4,1221026,nodelay=1"&gt;banning photography&lt;/a&gt;, which is probably not Constitutional. From browsing comments and a few quick searches, it seems that many people are getting arrested for taking images and video from public locations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8099896147375522439?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8099896147375522439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8099896147375522439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8099896147375522439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8099896147375522439'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/amtrak-police-abuse-photographer.html' title='Amtrak Police Abuse Photographer'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8514410560016100798</id><published>2009-01-01T15:54:00.000-08:00</published><updated>2009-01-01T16:04:12.728-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='freedom'/><title type='text'>FSF Member</title><content type='html'>A tremendous amount of important work is built on top of free software. I tend to ramble on this topic quite a bit, so for the holidays my parents got me a membership to the FSF:

&lt;br /&gt;&lt;br /&gt;
&lt;a href="http://www.fsf.org/register_form?referrer=7246"&gt;&lt;img src="http://cs.ucsd.edu/~ztatlock/share/fsf_member_7246.png" alt="[FSF Associate Member]" width="88" height="31" /&gt;&lt;/a&gt;
&lt;br /&gt;&lt;br /&gt;

It is about time I joined. Thanks Mom and Dad!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8514410560016100798?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8514410560016100798/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8514410560016100798' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8514410560016100798'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8514410560016100798'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/fsf-member.html' title='FSF Member'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5395018381365387486</id><published>2009-01-01T15:38:00.000-08:00</published><updated>2009-01-01T17:06:30.376-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzles'/><title type='text'>Gordian's Knot</title><content type='html'>My brother-in-law got me a &lt;a href="http://www.thinkfun.com/PRODUCT.ASPX?PageNo=PRODUCT&amp;Catalog=By%20Category&amp;Category=7SERPZLR&amp;ProductId=6820"&gt;ThinkFun Gordian's Knot&lt;/a&gt; puzzle for the holidays. The name is taken from a &lt;a href="http://en.wikipedia.org/wiki/Gordian_Knot"&gt;legend&lt;/a&gt; involving Alexander the Great, and even inspired some &lt;a href="http://www.maa.org/devlin/devlin_9_01.html"&gt;interesting mathematical programming&lt;/a&gt;. Here are the rainbow colored (ROYGBIV) pieces:

&lt;br /&gt;
&lt;img width="500px" src="http://cs.ucsd.edu/~ztatlock/share/gordian_knot_pieces.jpg" /&gt;
&lt;br /&gt;

and the assembled puzzle:

&lt;br /&gt;
&lt;img width="500px" src="http://cs.ucsd.edu/~ztatlock/share/gordian_knot_together.jpg" /&gt;
&lt;br /&gt;

This took some hours to disentangle and reconstruct, very fun and well made! I really believe that anyone could solve the puzzle. It is simply a matter of refusing to quit until you have found the solution (thanks &lt;a href="http://www.cs.purdue.edu/homes/mja/"&gt;mja&lt;/a&gt;!).

&lt;br /&gt;&lt;br /&gt;

The pictures above were taken on Anne and my brand new &lt;a href="http://www.usa.canon.com/consumer/controller?act=ModelInfoAct&amp;fcategoryid=145&amp;modelid=16718"&gt;PowerShot SD790 IS&lt;/a&gt; which we got from her parents for the holidays. So far it seems really excellent.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5395018381365387486?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5395018381365387486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5395018381365387486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5395018381365387486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5395018381365387486'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2009/01/gordians-knot.html' title='Gordian&apos;s Knot'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8594469526345207800</id><published>2008-12-31T08:10:00.000-08:00</published><updated>2008-12-31T08:17:18.810-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>txt2img</title><content type='html'>It's nice to generate a png from stdin, e.g. when putting an email address on the web. &lt;a href="http://netpbm.sourceforge.net/doc/pbmtext.html"&gt;pbmtext&lt;/a&gt; basically provides this, but here's a small wrapper with good default options and the ability to generate any image type that the excellent &lt;a href="http://www.imagemagick.org/script/index.php"&gt;imagemagick&lt;/a&gt; package can handle:

&lt;pre&gt;
#!/usr/bin/env bash

pbmtext -builtin fixed -space 1 -lspace 5 &gt; $$.pbm
convert $$.pbm $1
rm $$.pbm
&lt;/pre&gt;

Overall, I'm a big fan of the simple formats provided by the &lt;a href="http://netpbm.sourceforge.net/"&gt;netpbm project&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8594469526345207800?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8594469526345207800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8594469526345207800' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8594469526345207800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8594469526345207800'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/txt2img.html' title='txt2img'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-8632702410394506293</id><published>2008-12-30T09:50:00.000-08:00</published><updated>2008-12-30T10:00:43.126-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzles'/><title type='text'>Hat Puzzles</title><content type='html'>There seem to be several great &lt;a href="http://www.google.com/search?q=hat+puzzle"&gt;hat puzzles&lt;/a&gt;. Two good ones (&lt;a href="http://orion.math.iastate.edu/burkardt/puzzles/hats_puzzle.html"&gt;cite&lt;/a&gt;):

&lt;blockquote&gt;
&lt;b&gt;Puzzle 1&lt;/b&gt;: The king blindfolds three ministers, places a white or black hat on each one and removes the blindfolds. "If you can see a black hat, raise your hand", he says. They each raise a hand. "If you can tell what color your hat is, raise your hand." All the hands drop. Then suddenly, one minister raises his hand. What color was his hat?

&lt;br /&gt;&lt;br /&gt;

&lt;b&gt;Puzzle 2&lt;/b&gt;: The king has four ministers. He shows them a table with two white hats and two black ones. He blindfolds them, and places a hat on each. Then, he puts one on one side of a wall, and the other three in a line on the other side, facing the wall, like so:
&lt;pre&gt;
        A  |  B  C  D
&lt;/pre&gt;
A and B can see nothing but the wall. C can see B's hat. D can see B's hat and C's hat. Assuming the ministers are good thinkers, will someone be able to determine their hat color?
&lt;/blockquote&gt;

&lt;a href="http://en.wikipedia.org/wiki/Prisoners_and_hats_puzzle"&gt;Prisoners and Hats Puzzle&lt;/a&gt;
&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Hat_Puzzle"&gt;Hat Puzzle&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-8632702410394506293?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/8632702410394506293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=8632702410394506293' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8632702410394506293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/8632702410394506293'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/hat-puzzles.html' title='Hat Puzzles'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2878335337908854290</id><published>2008-12-30T09:04:00.000-08:00</published><updated>2008-12-30T09:33:33.778-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>cycle and uncycle</title><content type='html'>This snippet is for rotating the lines of a file. The script should be invoked as cycle or uncycle and works on either stdin or a single file argument. &lt;b&gt;cycle&lt;/b&gt; prints lines 2 through N and then prints the first line. &lt;b&gt;uncycle&lt;/b&gt; prints line N and then prints lines 1 through N-1. Obviously, each of these functions is the other's inverse.

&lt;pre&gt;
#!/usr/bin/env bash

function cycle {
  tail -n +2 $1   # print lines 2 to N
  head -n  1 $1   # print line 1
}

function uncycle {
  tail -n  1 $1   # print line N
  head -n -1 $1   # print lines 1 to N -1
}

f=$(basename $0)

if [ $# -eq 0 ] ; then # output to stdout
  tf=$(tempfile)
  cat &gt; $tf
  $f $tf
  rm $tf
elif [ $# -eq 1 ] &amp;&amp; [ -f $1 ] ; then # perform in place
  tf=$(tempfile)
  $f $1 &gt; $tf
  mv $tf $1
else
  echo "ERROR: bad args"
  exit 1
fi
&lt;/pre&gt;


Put this in ~/bin as cycle and then symlink uncycle to it:
&lt;pre&gt;
  $ wget http://cs.ucsd.edu/~ztatlock/share/cycle -O ~/bin/cycle
  $ ln -s ~/bin/cycle ~/bin/uncycle
&lt;/pre&gt;

Examples:&lt;br /&gt;
&lt;img src="http://cs.ucsd.edu/~ztatlock/share/cycle_example.png" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2878335337908854290?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2878335337908854290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2878335337908854290' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2878335337908854290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2878335337908854290'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/cycle-and-uncycle.html' title='cycle and uncycle'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5161647811731640641</id><published>2008-12-22T14:44:00.000-08:00</published><updated>2008-12-22T14:52:08.062-08:00</updated><title type='text'>Popular Science / Mechanics Archives</title><content type='html'>Google has archives from over 100 years of &lt;a href="http://books.google.com/books?id=_icDAAAAMBAJ"&gt;Popular Science&lt;/a&gt; and &lt;a href="http://books.google.com/books?id=gtkDAAAAMBAJ"&gt;Popular Mechanics&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5161647811731640641?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5161647811731640641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5161647811731640641' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5161647811731640641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5161647811731640641'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/popular-science-mechanics-archives.html' title='Popular Science / Mechanics Archives'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3260778556516438991</id><published>2008-12-20T18:12:00.000-08:00</published><updated>2009-02-08T19:38:40.778-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haha'/><category scheme='http://www.blogger.com/atom/ns#' term='circuits'/><title type='text'>Prank: Stealth USB CapsLocker</title><content type='html'>This could be immensely hilarious: &lt;a href="http://macetech.com/blog/?q=node/46"&gt;usb capslocker&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3260778556516438991?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3260778556516438991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3260778556516438991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3260778556516438991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3260778556516438991'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/prank-stealth-usb-capslocker.html' title='Prank: Stealth USB CapsLocker'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-5198796670227540902</id><published>2008-12-19T11:42:00.000-08:00</published><updated>2009-02-08T20:11:36.123-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>youtube-dl : Download YouTube Videos</title><content type='html'>&lt;a href="http://www.arrakis.es/~rggi3/youtube-dl/"&gt;youtube-dl&lt;/a&gt; (&lt;a href="http://cs.ucsd.edu/~ztatlock/share/youtube-dl"&gt;2008.11.01&lt;/a&gt;) is a nice bit of python to suck down youtube videos so that you watch them, say, on a plane. Found on &lt;a href="http://www.hermann-uwe.de/blog/download-videos-from-youtube-google-video-and-others-using-linux"&gt;this list&lt;/a&gt; of Linux tools to download video from the web.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-5198796670227540902?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/5198796670227540902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=5198796670227540902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5198796670227540902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/5198796670227540902'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/youtube-dl-download-youtube-videos.html' title='youtube-dl : Download YouTube Videos'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-7175577259369190565</id><published>2008-12-17T15:32:00.000-08:00</published><updated>2008-12-17T15:39:08.700-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tex'/><title type='text'>Fine Tuning Tex</title><content type='html'>Getting a paper into camera ready form can be a massive pain. &lt;a href="http://pho.ucsd.edu/rjhala/"&gt;RJ&lt;/a&gt; showed me a great trick to help with the fine tuning:

&lt;ol&gt;
&lt;li&gt;latex foo.tex&lt;/li&gt;
&lt;li&gt;kdvi foo.dvi&lt;/li&gt;
&lt;li&gt;Click Settings -&gt; Configure KDVI -&gt; DVI Specials.&lt;/li&gt;
&lt;li&gt;Select your favorite editor from the Editor drop down.&lt;/li&gt;
&lt;li&gt;Click Apply and then OK.&lt;/li&gt;
&lt;/ol&gt;

Now you can middle click anywhere in the DVI and it will open your editor to the correct position in the correct source file. This can save a lot of time when you're removing those dangling, one-word lines in order to meet a page limit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-7175577259369190565?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/7175577259369190565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=7175577259369190565' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7175577259369190565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7175577259369190565'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/fine-tuning-tex.html' title='Fine Tuning Tex'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3939951808562600676</id><published>2008-12-13T18:13:00.000-08:00</published><updated>2009-02-08T19:36:46.182-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='haha'/><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Holiday Lambda Lights</title><content type='html'>My lab's way of decorating for the holidays:

&lt;br /&gt;
&lt;br /&gt;

&lt;img src="http://cs.ucsd.edu/~ztatlock/share/lambda_lights.jpg" width="500px" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3939951808562600676?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3939951808562600676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3939951808562600676' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3939951808562600676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3939951808562600676'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/holiday-lambda-lights.html' title='Holiday Lambda Lights'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4868630198713771320</id><published>2008-12-12T09:23:00.000-08:00</published><updated>2008-12-12T09:54:52.462-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='circuits'/><title type='text'>SR Latch to Debounce Switch</title><content type='html'>Pushbutton switches are nice for clocking circuits, but the signal is extremely bouncy (ie. it really goes high, low, and in between many times each push). This can be fixed with an &lt;a href="http://www.robotroom.com/DebouncedCounter.html"&gt;SR&lt;/a&gt; &lt;a href="http://www.play-hookey.com/digital/rs_nand_latch.html"&gt;Latch&lt;/a&gt;, which looks like:

&lt;br /&gt;

&lt;img src="http://www.robotroom.com/DebouncedCounter/Figure627.gif" width="500px" /&gt;

&lt;br /&gt;

and can be implemented with a 74HC00 as:

&lt;br /&gt;

&lt;a href="http://cs.ucsd.edu/~ztatlock/share/rslatch.jpg"&gt;
&lt;img src="http://cs.ucsd.edu/~ztatlock/share/rslatch-500.jpg" width="500px" /&gt;
&lt;/a&gt;

&lt;br /&gt;

This past week I went to &lt;a href="http://www.usenix.org/events/osdi08/"&gt;OSDI 08&lt;/a&gt; with &lt;b&gt;R&lt;/b&gt; and some of the &lt;a href="http://www.cse.ucsd.edu/groups/sysnet/"&gt;UCSD systems&lt;/a&gt; guys. It was a lot of fun and very interesting. &lt;b&gt;R&lt;/b&gt; and I went to Fry's on the Saturday before the conference and restocked my electronics kit, largely for the &lt;a href="http://cse-gsa.ucsd.edu/csewiki/LedDisplay"&gt;LED Display&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4868630198713771320?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4868630198713771320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4868630198713771320' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4868630198713771320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4868630198713771320'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/sr-latch-to-debounce-switch.html' title='SR Latch to Debounce Switch'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-7411893005319889041</id><published>2008-12-11T08:35:00.000-08:00</published><updated>2008-12-11T08:42:55.708-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>ANSI C Quoting in Bash</title><content type='html'>Getting the right number of backslashes to properly escape strings in the shell can be a pain. This is particularly true when you want control codes for things like &lt;a href="http://ztatlock.blogspot.com/2008/10/color-output-script.html"&gt;color&lt;/a&gt;. A nice way to express such strings is the &lt;a href="http://www.gnu.org/software/bash/manual/bashref.html#ANSI_002dC-Quoting"&gt;ANSI C Quoting&lt;/a&gt; mechanism in bash. Essentially the raw ANSI C string &lt;b&gt;foo&lt;/b&gt; will just be &lt;b&gt;$'foo'&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-7411893005319889041?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/7411893005319889041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=7411893005319889041' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7411893005319889041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7411893005319889041'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/ansi-c-quoting-in-bash.html' title='ANSI C Quoting in Bash'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-3331694748700459896</id><published>2008-12-10T17:33:00.000-08:00</published><updated>2008-12-10T20:38:31.659-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Vim Command Mode Keybinding</title><content type='html'>Use &lt;b&gt;jj&lt;/b&gt; to change from insert mode to command mode more quickly in vim. Just add

&lt;pre&gt;
    imap jj &amp;lt;ESC&amp;gt;
&lt;/pre&gt;

to your vimrc. Now typing &lt;b&gt;jj&lt;/b&gt; while you're in insert mode is the same as hitting escape. Courtesy of &lt;a href="http://www.cse.ucsd.edu/~prondon/"&gt;pmr&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3331694748700459896?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3331694748700459896/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3331694748700459896' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3331694748700459896'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3331694748700459896'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/vim-command-mode-keybinding.html' title='Vim Command Mode Keybinding'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-7282694823893969316</id><published>2008-12-05T08:34:00.000-08:00</published><updated>2008-12-12T11:09:37.857-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='circuits'/><title type='text'>Control Power Outlet</title><content type='html'>&lt;a href="http://www.sparkfun.com/commerce/categories.php"&gt;SparkFun&lt;/a&gt; has a very well written tutorial on &lt;a href="http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=119"&gt;using a relay to control a power outlet&lt;/a&gt; (&lt;a href="http://cs.ucsd.edu/~ztatlock/share/control_power_outlet.pdf"&gt;pdf&lt;/a&gt;). This would allow one to control all their appliances with bash. &lt;b&gt;R&lt;/b&gt; said that he found some remote control power outlets (presumably IR) that could be hacked as well, but a quick googling turned up nothing.

&lt;br /&gt;&lt;br /&gt;

The &lt;a href="http://cse-gsa.ucsd.edu/csewiki/LedDisplay"&gt;LED display project&lt;/a&gt; has got me thinking about hardware hacking again. &lt;a href="http://hackaday.com/"&gt;Hack a Day&lt;/a&gt; should provide an endless supply of projects if I do decide to rebuild my lab.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-7282694823893969316?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/7282694823893969316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=7282694823893969316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7282694823893969316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7282694823893969316'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/control-power-outlet.html' title='Control Power Outlet'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6453879566899732263</id><published>2008-12-04T10:03:00.001-08:00</published><updated>2008-12-04T12:13:19.492-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Interactive Map</title><content type='html'>Sometimes it is useful to transform, rename, or otherwise change a file based on properties that are hard to extract programmatically. A pretty good solution is to loop over the files, display each one, and then read input to determine what to do. For example, if I only want images containing a particular person this would work:

&lt;pre&gt;
 for p in *.jpg ; do
   display $p
   read -p "remove $p [y/N] ? " ans
   if [ "$ans" == "y" ] ; then
     rm $p
   fi
 done
&lt;/pre&gt;

A more general form:

&lt;pre&gt;
 #!/bin/bash

 disp=$1
 func=$2
 shift 2
 fs=$*

 for f in $fs ; do
   $disp $f
   read -p "$func $f [y/N] ? " ans
   if [ "$ans" == "y" ] ; then
     $func $f
   fi
 done
&lt;/pre&gt;

Voila! We now have an interactive version of &lt;a href="http://en.wikipedia.org/wiki/Map_%28higher-order_function%29"&gt;&lt;i&gt;map&lt;/i&gt;&lt;/a&gt; in bash. I have the above script saved as &lt;i&gt;mapInter&lt;/i&gt; on my path, which allows me to do things like:

&lt;pre&gt;
 $ mapInter display rm $(find . -name '*.png' -or '*.jpg')
&lt;/pre&gt;

to interactively remove files after I have viewed them. Note that regular old &lt;i&gt;map&lt;/i&gt; is just:

&lt;pre&gt;
 #!/bin/bash

 func=$1
 shift 1
 fs=$*

 for f in $fs ; do
   $func $f
 done
&lt;/pre&gt;

Finally, pointers to the &lt;a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html"&gt;shift&lt;/a&gt; and &lt;a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_08_02.html"&gt;read&lt;/a&gt; built-ins since I always forget exact details. &lt;a href="http://en.wikipedia.org/wiki/Higher-order_function"&gt;Higher-order&lt;/a&gt; &lt;a href="http://www.cse.unsw.edu.au/%7Een1000/haskell/hof.html"&gt;functions&lt;/a&gt; in bash FTW!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6453879566899732263?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6453879566899732263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6453879566899732263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6453879566899732263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6453879566899732263'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/interactive-map.html' title='Interactive Map'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2067182980320851854</id><published>2008-12-03T16:47:00.000-08:00</published><updated>2008-12-03T17:47:15.685-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL'/><title type='text'>Frink</title><content type='html'>&lt;a href="http://futureboy.homeip.net/frinkdocs/"&gt;Frink&lt;/a&gt; is a fun language designed for quickly performing back-of-the-envelope style calculations. Importantly, it knows many facts about the natural world (e.g. the density of water). For some examples, check out the amusing &lt;a href="http://futureboy.homeip.net/frinkdocs/#SampleCalculations"&gt;sample calculations&lt;/a&gt;.

&lt;br /&gt;&lt;br /&gt;

The language is named after a Simpson's character who quoted decades ago:

&lt;blockquote&gt;
"I predict that within 100 years, computers will be twice as powerful, ten thousand times larger, and so expensive that only the five richest kings of Europe will own them."
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
-- Professor John Frink
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2067182980320851854?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2067182980320851854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2067182980320851854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2067182980320851854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2067182980320851854'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/frink.html' title='Frink'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-661523491561218481</id><published>2008-12-01T18:39:00.000-08:00</published><updated>2008-12-01T18:47:56.806-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Length of Longest Line in a File</title><content type='html'>&lt;b&gt;&lt;a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?wc"&gt;wc -L&lt;/a&gt;&lt;/b&gt; gives the longest line in a file. This is very useful if you want pad all lines of a file up to the same width:

&lt;pre&gt;
  #!/usr/bin/env bash

  tf=$(tempfile)
  
  cat $* &gt; $tf

  L=$(cat $tf | wc -L)

  awk "{ printf(\"%-${L}s\n\", \$0) }" $tf
&lt;/pre&gt;

Note that by using the tempfile, this script works on a list of file arguments or on standard input. Also, the above version is left aligned. If you want a right aligned version, simply change the line:

&lt;pre&gt;
  awk "{ printf(\"%-${L}s\n\", \$0) }" $tf
&lt;/pre&gt;

to:

&lt;pre&gt;
  awk "{ printf(\"%${L}s\n\", \$0) }" $tf
&lt;/pre&gt;

(ie. remove the negative sign in the format string).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-661523491561218481?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/661523491561218481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=661523491561218481' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/661523491561218481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/661523491561218481'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/12/length-of-longest-line-in-file.html' title='Length of Longest Line in a File'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-322078708581367666</id><published>2008-11-30T10:52:00.000-08:00</published><updated>2008-11-30T13:19:51.328-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webcam'/><title type='text'>Logitech QuickCam in Ubuntu 8.10</title><content type='html'>Unfortunately Logitech QuickCams do not work out of the box in Ubuntu 8.10. This thread allowed me to get the camera up and running:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://answers.launchpad.net/ubuntu/+question/49739"&gt;problems with logitech quickcam&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

Basically, &lt;a href="http://hansdegoede.livejournal.com/3636.html"&gt;hansdegoede&lt;/a&gt; is a hero and wrote a user land library to wrap all the video for linux (v4l) calls into a smart version of the code that solves multiple problems. Thanks!

&lt;br /&gt;&lt;br /&gt;

The short version of the solution:
&lt;ol&gt;
&lt;li&gt;wget &lt;a href="http://people.atrpms.net/%7Ehdegoede/libv4l-0.5.0.tar.gz"&gt;http://people.atrpms.net/~hdegoede/libv4l-0.5.0.tar.gz&lt;/a&gt; (&lt;a href="http://cs.ucsd.edu/%7Eztatlock/share/libv4l-0.5.0.tar.gz"&gt;mirror&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;tar xvzf libv4l-0.5.0.tar.gz&lt;/li&gt;
&lt;li&gt;cd libv4l-0.5.0&lt;/li&gt;
&lt;li&gt;make&lt;/li&gt;
&lt;li&gt;sudo make install&lt;/li&gt;
&lt;li&gt;export LD_PRELOAD=/usr/local/lib/libv4l/v4l1compat.so&lt;/li&gt;
&lt;li&gt;run your favorite webcam app&lt;/li&gt;
&lt;/ol&gt;

The export for LD_PRELOAD must be repeated every time you open a shell that is going to run a webcam app. So, you could do this:

&lt;pre&gt;
  $ echo export LD_PRELOAD=/usr/local/lib/libv4l/v4l1compat.so &gt;&gt; ~/.bashrc
&lt;/pre&gt;

and every bash session would have the LD_PRELOAD environment variable correctly set for the v4l library. Alternatively, you could write wrappers for each webcam app. e.g. wrapping &lt;a href="http://projects.gnome.org/cheese/"&gt;cheese&lt;/a&gt; :

&lt;pre&gt;
  #!/bin/bash

  export LD_PRELOAD=/usr/local/lib/libv4l/v4l1compat.so
  cheese
&lt;/pre&gt;

You can also use &lt;b&gt;camgrab&lt;/b&gt; to get images from the webcam using the shell:

&lt;pre&gt;
  $ sudo apt-get install camgrab
  $ export LD_PRELOAD=/usr/local/lib/libv4l/v4l1compat.so
  $ camgrab -output foo.jpg
&lt;/pre&gt;

Which should be useful for my upcoming super secret project. Thanks again &lt;a href="http://hansdegoede.livejournal.com/"&gt;hansdegoede&lt;/a&gt;!

&lt;br /&gt;&lt;br /&gt;

&lt;img width=200px src="http://cs.ucsd.edu/~ztatlock/share/thumbs-up.jpg" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-322078708581367666?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/322078708581367666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=322078708581367666' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/322078708581367666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/322078708581367666'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/logitech-quickcam-in-ubuntu-810.html' title='Logitech QuickCam in Ubuntu 8.10'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4042891097236366992</id><published>2008-11-29T14:22:00.000-08:00</published><updated>2008-11-29T14:25:18.607-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='man'/><title type='text'>Man Section 2 in Ubuntu</title><content type='html'>To get section 2 of the man pages in Ubuntu:

&lt;pre&gt;
  $ sudo apt-get install manpages-dev
&lt;/pre&gt;

I cannot believe section 2 is excluded by default. WTF?!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4042891097236366992?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4042891097236366992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4042891097236366992' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4042891097236366992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4042891097236366992'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/man-section-2-in-ubuntu.html' title='Man Section 2 in Ubuntu'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-4658450952937296877</id><published>2008-11-29T10:18:00.000-08:00</published><updated>2008-11-29T14:25:40.524-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Extract File Extension</title><content type='html'>Here's a useful bash function that invokes awk to get a file's extension:

&lt;pre&gt;
  # yield the file extension or nothing if there is no extension
  function ext {
    echo $1 | awk 'BEGIN { FS="." } { if(NF &gt; 1) {print $NF} }'
  }
&lt;/pre&gt;

It is useful if you want to convert file type but keep the name. For example:

&lt;pre&gt;
  for i in $(find . -name '*.png' -or -name '*.jpg' -or -name '*.gif') ; do
    convert "$i" "$(basename $i .$(ext $i)).ppm"
  done
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-4658450952937296877?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/4658450952937296877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=4658450952937296877' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4658450952937296877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/4658450952937296877'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/get-file-extension.html' title='Extract File Extension'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2233341701752614230</id><published>2008-11-24T21:19:00.000-08:00</published><updated>2008-11-24T21:31:02.764-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Reverse the lines of a file: rev vs. tac</title><content type='html'>"Reverse the lines of a given file." is an ambiguous command. The two obvious parsings are:

&lt;ol&gt;
&lt;li&gt;Reverse the order lines appear in a file. For example:
&lt;pre&gt;
    0
    1
    2
    3
&lt;/pre&gt;
should become:
&lt;pre&gt;
    3
    2
    1
    0
&lt;/pre&gt;
This is done by &lt;a href="http://www.ss64.com/bash/tac.html"&gt;tac&lt;/a&gt;. (Get it? "cat" in reverse... haha). &lt;br /&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Reverse the order of characters in each line of the file. For example:
&lt;pre&gt;
    0123
    abcd
&lt;/pre&gt;
should become:
&lt;pre&gt;
    3210
    dcba
&lt;/pre&gt;
This is done by &lt;a href="http://unixhelp.ed.ac.uk/CGI/man-cgi?rev"&gt;rev&lt;/a&gt;.
&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2233341701752614230?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2233341701752614230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2233341701752614230' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2233341701752614230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2233341701752614230'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/reverse-lines-of-file-rev-vs-tac.html' title='Reverse the lines of a file: rev vs. tac'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-7382883804604431526</id><published>2008-11-22T11:18:00.000-08:00</published><updated>2009-01-23T04:07:10.194-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Bash vs. Python</title><content type='html'>&lt;a href="http://pho.ucsd.edu/rjhala/"&gt;Someone&lt;/a&gt; whom I respect very much has been making the claim that &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; renders &lt;a href="http://www.gnu.org/software/bash/"&gt;BASH&lt;/a&gt; obsolete. I frequently make similar assertions, and it's interesting to be on the other side of a such a strong statement. Many of my &lt;a href="http://www.stallman.org/"&gt;personal&lt;/a&gt; &lt;a href="http://www-cs-faculty.stanford.edu/~knuth/"&gt;heroes&lt;/a&gt; consistently make strong claims that rub many people the wrong way. They still manage to impact history and change the world for the better.

&lt;br /&gt;&lt;br /&gt;

At any rate, here is an example where bash shines and I doubt python can match: create a directory of 150x150 px thumbnails of all the images below the current directory.
&lt;pre&gt;
    #!/bin/bash
    
    if [ ! -d "thumbs" ] ; then
        mkdir thumbs
    fi

    for i in $(find . -name '*.jpg' -or -name '*.png' -or -name '*.gif') ; do
        convert -resize 150x150 "$i" "thumbs/$(basename $i)"
    done
&lt;/pre&gt;
This is the sort of thing I dash off a dozen times a day. Even if it were possible to express this as easily in Python, I would have to look at several pages of python documentation to get the correct incantations out of &lt;b&gt;os.*&lt;/b&gt;. Furthermore, if I want to extend the above script to set permissions, start the search at a given dir, or generate thumbs for only certain directories (eg. by timestamp or name) then simple calls to standard shell tools make the addition trivial. The same extensions in Python involve more documentation grepping and more code. The shell has been tuned for this sort of simple extensibility over a long a period of time.

&lt;br /&gt;&lt;br /&gt;

To be clear, I am a big fan of Python. If the problem you're solving (1) requires real data structures and (2) does not need to be correct, then python is great. If you need real data structures and correctness, go to &lt;a href="http://mlton.org/StandardML"&gt;ML&lt;/a&gt;. If you're doing something non-critical that is filesystem based then bash is a good choice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-7382883804604431526?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/7382883804604431526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=7382883804604431526' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7382883804604431526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/7382883804604431526'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/bash-vs-python.html' title='Bash vs. Python'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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><entry><id>tag:blogger.com,1999:blog-393915387617254561.post-3100483107455419450</id><published>2008-11-21T10:41:00.000-08:00</published><updated>2009-02-08T20:16:29.006-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Awk Primer</title><content type='html'>The &lt;a href="http://www.vectorsite.net/tsawk.html"&gt;Awk Primer&lt;/a&gt; is a great intro tutorial and reference. I used it to first learn &lt;a href="http://en.wikipedia.org/wiki/Awk"&gt;awk&lt;/a&gt; along with the also great &lt;a href="http://www.grymoire.com/Unix/Awk.html"&gt;Awk Tutorial Introduction&lt;/a&gt;. Awk's name comes from the authors: Alfred Aho, Peter Weinberger, and Brian Kernighan. But I always forget the damn "W" one. It cost us the CS Trivia competition vs. the faculty last year. It's weird because &lt;a href="http://en.wikipedia.org/wiki/Peter_J._Weinberger"&gt;PJW&lt;/a&gt; is actually pretty cool, at one time heading CS research in the legendary Bell Labs. He worked on many of the classic Unix tools and hackers even put his face on a &lt;a href="http://spinroot.com/pico/pjw.html"&gt;water tower&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-3100483107455419450?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/3100483107455419450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=3100483107455419450' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3100483107455419450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/3100483107455419450'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/awk-primer.html' title='Awk Primer'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-933145149052518913</id><published>2008-11-19T18:56:00.000-08:00</published><updated>2008-11-20T09:26:30.168-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>One Line Bash Functions</title><content type='html'>In a one line bash function, the last command must be followed by a semicolon. So this is OK:

&lt;pre&gt;
  function hello { echo "Hello World"; }
&lt;/pre&gt;

while this is not:

&lt;pre&gt;
  function hello { echo "Hello World" }
&lt;/pre&gt;

&lt;a href="http://tldp.org/LDP/abs/html/functions.html"&gt;Reference here.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-933145149052518913?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/933145149052518913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=933145149052518913' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/933145149052518913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/933145149052518913'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/one-line-bash-functions.html' title='One Line Bash Functions'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2764227379896337539</id><published>2008-11-08T10:09:00.000-08:00</published><updated>2008-11-08T10:16:11.227-08:00</updated><title type='text'>jUploadr</title><content type='html'>&lt;a href="http://juploadr.org/"&gt;jUploadr&lt;/a&gt; is a really useful tool for uploading pictures to a &lt;a href="http://flickr.com"&gt;Flickr&lt;/a&gt; account. A big plus is that it works on all major platforms (all the other uploaders are Windows / OS X only). Unfortunately, you &lt;b&gt;MUST&lt;/b&gt; drag and drop photos onto jUploadr, which is a pain when you're running &lt;a href="http://xmonad.org/"&gt;xmonad&lt;/a&gt; and have thrown away the mouse.

&lt;br /&gt;&lt;br /&gt;

Make sure to check out the &lt;a href="http://www.flickr.com/photos/ucsdcse/"&gt;UCSD CSE Flickr photostream&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2764227379896337539?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2764227379896337539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2764227379896337539' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2764227379896337539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2764227379896337539'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/juploadr.html' title='jUploadr'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-6757818726628463627</id><published>2008-11-02T18:06:00.000-08:00</published><updated>2008-11-02T18:14:20.661-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><title type='text'>Thesaurus in Vim</title><content type='html'>Ever working on TeX in vim and really wish you could automatically get synonyms for the word under the cursor? Inspired by &lt;a href="http://dailyvim.blogspot.com/2008/08/making-k-useful.html"&gt;this post&lt;/a&gt; over at the &lt;a href="http://dailyvim.blogspot.com/"&gt;Daily Vim&lt;/a&gt;, I added just such a feature.

&lt;br /&gt;&lt;br /&gt;

&lt;b&gt;Step 1:&lt;/b&gt; Write the &lt;i&gt;thesaurus&lt;/i&gt; script:
&lt;pre&gt;
  #!/usr/bin/env bash

  firefox http://thesaurus.reference.com/search\?q=$1
&lt;/pre&gt;
Save it somewhere on your PATH, and make it executable (chmod +x thesaurus).

&lt;br /&gt;&lt;br /&gt;

&lt;b&gt;Step 2:&lt;/b&gt; Bind K to the thesaurus script. In vim simply issue the command:
&lt;pre&gt;
  :set keywordprg=/home/ztatlock/bin/thesaurus
&lt;/pre&gt;
Obviously, you should replace 'home/ztatlock/bin' with the path to where your copy of thesaurus lives.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-6757818726628463627?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/6757818726628463627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=6757818726628463627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6757818726628463627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/6757818726628463627'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/11/thesaurus-in-vim.html' title='Thesaurus in Vim'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2479789012853267994</id><published>2008-10-30T18:24:00.001-07:00</published><updated>2008-10-30T18:25:05.878-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='game of life'/><category scheme='http://www.blogger.com/atom/ns#' term='quine'/><title type='text'>Conway's Game of Life in a Quine</title><content type='html'>&lt;a href="http://blog.makezine.com/archive/2008/10/selfprinting_game_of_life.html"&gt;
&lt;img src="http://blog.makezine.com/MAKE_PT1108.jpg" /&gt;
&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2479789012853267994?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2479789012853267994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2479789012853267994' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2479789012853267994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2479789012853267994'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/10/conways-game-of-life-in-quine.html' title='Conway&apos;s Game of Life in a Quine'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-9183461050014336949</id><published>2008-10-30T09:38:00.000-07:00</published><updated>2008-10-30T10:24:48.664-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Parse Command Line Args</title><content type='html'>One can write their own argument parsers with &lt;b&gt;while&lt;/b&gt;, &lt;a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_03.html"&gt;case&lt;/a&gt;, and &lt;a href="http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_07.html"&gt;shift&lt;/a&gt;. However, &lt;a href="http://aplawrence.com/Unix/getopts.html"&gt;getopt and getopts&lt;/a&gt; provide a faster and more robust solution. &lt;a href="http://www.mkssoftware.com/docs/man1/getopts.1.asp"&gt;getopts&lt;/a&gt; just "does the right thing" and has saved me considerable effort the past few days. It is really worth RTFM and saving yourself time and headache.

&lt;br /&gt;&lt;br /&gt;

Like many great shell tools, getopts uses its own &lt;a href="http://en.wikipedia.org/wiki/Domain_Specific_Language"&gt;DSL&lt;/a&gt; for input. In this case, you simply provide a string that indicates what flags your script expects (eg. "vrd" to accept "-v", "-r", "-d", or combinations like "-rdv") and insert a colon after a flag that should have an argument (eg. "i:" if you expect "-i arg"). A simple example :

&lt;pre&gt;
#!/usr/bin/env bash

while getopts "abc:" OPT ; do
  case "$OPT" in
    "a") echo "handling flag -a" ;;
    "b") echo "handling flag -b" ;;
    "c") echo "handling flag -c with arg $OPTARG" ;;
    *)   echo "invalid argument"; exit 1 ;;
  esac
done
&lt;/pre&gt;

Running it:

&lt;br /&gt;

&lt;img src="http://cs.ucsd.edu/~ztatlock/images/getopts_example.png" /&gt;

&lt;br /&gt;

Notice that getopts will complain if it sees unrecognized arguments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-9183461050014336949?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/9183461050014336949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=9183461050014336949' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/9183461050014336949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/9183461050014336949'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/10/parse-command-line-args.html' title='Parse Command Line Args'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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-393915387617254561.post-2539251155885703889</id><published>2008-10-25T07:13:00.000-07:00</published><updated>2008-10-25T07:21:36.569-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Color Shell Script</title><content type='html'>Following up on the previous post, here is a general script to change the color of certain words in a file or from stdin:

&lt;pre&gt;
#!/usr/bin/env bash

BKPAT=black
RDPAT=red
GRPAT=green
YLPAT=yellow
BLPAT=blue
MGPAT=magenta
CYPAT=cyan
WTPAT=white

# ANSI color codes
BK=$'\033[1;30m' # black
RD=$'\033[1;31m' # red
GR=$'\033[1;32m' # green
YL=$'\033[1;33m' # yellow
BL=$'\033[1;34m' # blue
MG=$'\033[1;35m' # magenta
CY=$'\033[1;36m' # cyan
WT=$'\033[1;37m' # white
NC=$'\033[0m'    # no color

sed -e "s/$BKPAT/${BK}${BKPAT}${NC}/g" \
    -e "s/$RDPAT/${RD}${RDPAT}${NC}/g" \
    -e "s/$GRPAT/${GR}${GRPAT}${NC}/g" \
    -e "s/$YLPAT/${YL}${YLPAT}${NC}/g" \
    -e "s/$BLPAT/${BL}${BLPAT}${NC}/g" \
    -e "s/$MGPAT/${MG}${MGPAT}${NC}/g" \
    -e "s/$CYPAT/${CY}${CYPAT}${NC}/g" \
    -e "s/$WTPAT/${WT}${WTPAT}${NC}/g" $*
&lt;/pre&gt;

Here is an example of colorize in action:

&lt;br /&gt;&lt;br /&gt;
&lt;img src="http://cs.ucsd.edu/~ztatlock/images/colorize_example.png" /&gt;
&lt;br /&gt;&lt;br /&gt;

If you want to use this for a specific purpose, just copy the code and edit the PAT variables to correspond to your desired coloring. For example, if I wanted to make FAIL show up in red, I would simply change the line:

&lt;pre&gt;
RDPAT=red
&lt;/pre&gt;

to:

&lt;pre&gt;
RDPAT=FAIL
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/393915387617254561-2539251155885703889?l=ztatlock.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ztatlock.blogspot.com/feeds/2539251155885703889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=393915387617254561&amp;postID=2539251155885703889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2539251155885703889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/393915387617254561/posts/default/2539251155885703889'/><link rel='alternate' type='text/html' href='http://ztatlock.blogspot.com/2008/10/color-output-script.html' title='Color Shell Script'/><author><name>Zachary Tatlock</name><uri>http://www.blogger.com/profile/08177930944363090376</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>
