<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.3.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>briancarper.net</title>
	<link>http://briancarper.net</link>
	<description></description>
	<pubDate>Fri, 05 Dec 2008 08:13:18 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.2</generator>
	<language>en</language>
			<item>
		<title>Clojure, Qt4, memory leaks</title>
		<link>http://briancarper.net/2008/12/05/clojure-qt4-memory-leaks/</link>
		<comments>http://briancarper.net/2008/12/05/clojure-qt4-memory-leaks/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 08:13:18 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Clojure]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Qt4]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/12/05/clojure-qt4-memory-leaks/</guid>
		<description><![CDATA[I'm still exploring Clojure + Qt Jambi as a nice way to build GUI apps.  I have some code to upload, if I can ever figure out how github works.  The learning process really never ends for a programmer, does it?  Not that I mind it, I actually love it.  I [...]]]></description>
			<content:encoded><![CDATA[<p>I'm still exploring Clojure + Qt Jambi as a nice way to build GUI apps.  I have some code to upload, if I can ever figure out how github works.  The learning process really never ends for a programmer, does it?  Not that I mind it, I actually love it.  I love learning new tools and new languages.  Git seems interesting and so many people say such good things about it that I almost have to learn it now.</p>
<p>Anyways, anyone who uses Qt Jambi should be aware of <a href="http://www.mail-archive.com/qt-jambi-interest@trolltech.com/msg00592.html">issues with memory leaks</a>.  Turns out you need to explicitly dispose of toplevel Qt objects or else they're never garbage collected.  (This isn't as bad as it might be... most Qt objects aren't toplevel, they have parent objects.)  I made a long-running system tray app and I noticed it slowly but steadily increasing in memory usage over the course of a week.  I added a few calls to <strong>dispose</strong> and so far so good.</p>
<p>On that note, while Clojure is awesome and I think a lot of people's "OMG it's on the JVM, run!" reaction is unwarranted, the JVM still does seem to have some memory issues, on my system anyways.  You do pay a RAM tax for using the JVM.  A simple Clojure Qt4 app that just sits in the system tray and checks my email every couple seconds:</p>
<pre>  PID  PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  TTY      COMMAND
 3282  20   0  282m  54m  17m S    0  2.7  11:08.75 pts/3    /usr/lib/jvm/sun-jdk-1.6/bin/java ...</pre>
<p>54MB seems excessive.  I need to look into ways of reducing that.  I've passed in all kinds of parameters to the JVM limiting the heap size etc.; it was actually MORE than that before, which is even sadder.</p>
<p>One of the things that's either really good or really bad about Clojure, depending on your perspective, is that it forces you to learn Java and the JVM better.  You don't need much Java knowledge to use Clojure, but it surely helps as soon as you want to interoperate with Java libraries.   As much as I dislike Java, I recognize the need to have a job and acquire money with which to purchase such things as food and shelter.  Java is good for that kind of thing.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/12/05/clojure-qt4-memory-leaks/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Uptime</title>
		<link>http://briancarper.net/2008/12/02/uptime/</link>
		<comments>http://briancarper.net/2008/12/02/uptime/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 02:29:35 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Windows sucks]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/12/02/uptime/</guid>
		<description><![CDATA[How about that...
$ uptime
 18:19:53 up 208 days,  2:51,  2 users,  load average: 0.32, 0.16, 0.10
Not bad for my old crappy desktop machine running on the floor in my apartment without any kind of backup power supply or anything.  I run it with the case off all the time, and wires [...]]]></description>
			<content:encoded><![CDATA[<p>How about that...</p>
<pre>$ uptime
 18:19:53 up 208 days,  2:51,  2 users,  load average: 0.32, 0.16, 0.10</pre>
<p>Not bad for my old crappy desktop machine running on the floor in my apartment without any kind of backup power supply or anything.  I run it with the case off all the time, and wires and components are spilled out all over the floor.  It's a wonder I haven't crashed it yet just by stepping on it.</p>
<p>Every couple months I notice my machine is running slow and look at <strong>top</strong> and it turns out X or some stray KDE app is using half a GB of RAM or something, so I restart it and I'm back to normal.  Takes a long time to get to that point though.</p>
<p>Weird thing is, this doesn't even impress me any longer.  I just take it for granted that Linux works.  </p>
<p>Meanwhile my Vista machine locks up constantly.  How can anyone at Microsoft sleep at night?  (Answer: On top of huge piles of ill-gotten money.)</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/12/02/uptime/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Books are our friends</title>
		<link>http://briancarper.net/2008/11/30/books-are-our-friends/</link>
		<comments>http://briancarper.net/2008/11/30/books-are-our-friends/#comments</comments>
		<pubDate>Mon, 01 Dec 2008 06:22:01 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Books]]></category>

		<category><![CDATA[Haskell]]></category>

		<category><![CDATA[Lisp]]></category>

		<category><![CDATA[Scheme]]></category>

		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/11/30/books-are-our-friends/</guid>
		<description><![CDATA[I went on a reading binge over Thanksgiving break.  Read on for reviews.

First I read Test-Driven Development By Example.  This is a very short book, especially given the hefty price tag.  I would probably not have bought this if I'd seen it on a shelf at the store rather than online.
That said, [...]]]></description>
			<content:encoded><![CDATA[<p>I went on a reading binge over Thanksgiving break.  Read on for reviews.</p>
<ul>
<li>First I read <a href="http://en.wikipedia.org/wiki/Test-Driven_Development_by_Example">Test-Driven Development By Example</a>.  This is a very short book, especially given the hefty price tag.  I would probably not have bought this if I'd seen it on a shelf at the store rather than online.
<p>That said, it's a good book if you want to understand the mindset behind the whole test-driven development fad.  The book is heavy on mindset and light on mechanics; it doesn't tell you how to set up an environment, how to compile and run tests, or any such thing.  It just goes through some examples and explains what the programmer was thinking, and how to tackle the problem from a TDD point of view.  The intended audience therefore is someone who has plenty of experience programming and wants to learn a new way to look at problem solving.</p>
<p>The book goes through writing some terrible code (admittedly terrible by the author) to solve a simple problem, then refactoring the code to be less and less terrible by means of tests.  The writing style is engaging and casual and he describes mistakes as well as successes, which is a nice way to write a tutorial book.  The alternate writing style, belting out the correct answer the first time every time, is not as enlightening, and I appreciate it in this book.</p>
<p>The book places a heavy emphasis on writing tests FIRST, making small incremental changes, and refactoring as you go.  It also explains how TDD can be related to various OOP design patterns, which I didn't find all that helpful.  And it describes some "test patterns", which I found even less helpful.  But it's mostly an aesthetic objection; something about "design patterns" sits less and less well with me the more I get away from Java-like languages.  The information is still good, straightforward and to the point, take it or leave it.</p>
<p>I have been unable to drink the TDD Kool-Aid, but I can see where it'd probably result in an improvement in some of my code for certain specific kinds of problems.  I'll probably try it out again next time I have to write a little library at work.</p>
<p>This book is expensive and short, but the alternative for learning about TDD are half-baked blog posts, which is why I bought a book.  I don't know of a better book because this is the only one I have, and I'm unsure at this point whether I really want to buy another book on this topic.  But this book is highly recommended by many TDD <del>fanatics</del> enthusiasts, so I don't know.</li>
<li>Next I read <a href="http://www.ccs.neu.edu/home/matthias/BTLS/">The Little Schemer</a>.  The style of this book can best be described as "cute".  Examples all use food, and it instructs you at various points to go make yourself a sammich (even leaving room in the book for "jelly stains").  This somehow makes the topics, which can be rather intimidating, somehow less scary.  The book is very short, and not very dense (not many words on a page), but they somehow cram a lot of information into the book anyways, via the many examples.  It's a very focused and methodical book.
<p>This book goes through developing a simplified dialect of Scheme, with a focus on recursion and building up parts of the language from very simple primitives.  There are some neat little things along the way, like using s-expressions to represent numbers, and building up a full set of arithmetic functions using nothing but "add 1", "subtract 1", and recursion.  It'd be insane to do in real life because of performance, but it's really neat from a "hey look what you can do, isn't this cool!" point of view.</p>
<p>The first half of the book is pretty simplistic (at least for me, with some basic knowledge of Lisp and Scheme), but the second half really starts delving into some crazy things, passing lambdas around to lambdas and writing evaluators and stuff.  But you almost don't even notice because of how solidly the foundations are built up to that point, and how well the examples are explained.  (You probably will notice once you hit the y-combinator, on account of your brains detonating.)</p>
<p>This not a good book for "learning Lisp" in terms of learning the gritty details of to use a real-life implementation of Lisp.  But it's a good book for learning some of the concepts that make Lisp and functional languages powerful.   This is a very interesting and unique book, also highly recommended by many in the Lisp world.  I'm already planning to try <a href="http://www.ccs.neu.edu/home/matthias/BTSS/">The Seasoned Schemer</a> next.</li>
<li>Finally I started plowing through the recently-released <a href="http://book.realworldhaskell.org/">Real World Haskell</a>.  This book is freely available online, which is great.  It also allows readers to make comments on every paragraph in the book, which is a highly collaborative and probably very intelligent way to write a book, and also can provide insight for readers who don't understand the text at any given point.  I may buy a hard copy, I haven't decided.  (The online version has some FIXME notes and typos that I can only hope are fixed in the real thing.)
<p>I'm only up to chapter 11, but it's good so far.  It gives a ton of examples and goes slow enough for people completely new to Haskell to pick the language up.  And it includes some of the mechanics of compiling and/or running programs in <a href="http://www.haskell.org/ghc/">GHC</a>, which is extremely helpful.  I did start getting lost around the time monads were introduced, but that's to be expected.  It usually takes me two or three good reads of this kind of book before I grok it all, which is no fault of the book.</p>
<p>Haskell.  Last time I used it, I wrote Pong in Haskell in one of my college classes.  It was an immensely painful experience.  I'm going back to re-learn Haskell now because I find myself edging more and more toward functional languages and away from the C/Java world.  </p>
<p>Haskell is far too much to swallow if you have no experience with functional programming, which is probably why I hated it in college.  (That said, a smarter person than I may have fewer problems.)  After graduating school, I got my first whiff of this world again via Perl's <strong>map</strong> and <strong>grep</strong> and friends.  Then Ruby pushed it home for me with its widespread use of block parameters (lambdas in disguise).  And after learning Lisp (and especially later, Clojure) I can't live without higher-order functions.  If I had to write a classic for-loop and manually keep track of a counter variable I'd probably vomit at this point.  Haskell takes function manipulation to an even greater extreme, which I still haven't fully wrapped my head around, but I like what I've learned so far.</p>
<p>Laziness is awesome, function currying is awesome, and this is the first time I've read about folding, apart from brief struggles with Ruby's (poorly named) <strong>Enumerable#inject</strong>.  Pattern matching strikes me as vaguely similar to Common Lisp's / Clojure's destructuring-binding, which is one of the nicest features I've seen in any language when it comes to making a programmer's life easier.</p>
<p>Maybe it's all just interesting because it's still new to me.  But I like the whole idea of functional programming.  I like the idea of functions that always produce the same output from a given input.  How and when to handle side-effects and object mutation is a problem that's always nagged at the back of my mind even when writing Ruby code.</p>
<p>That said, Haskell still (at this point in the book) does not strike me as a practical or real-world language in the slightest.  You've got to jump through some crazy hoops to get a lot of things to work, especially when it comes to I/O.  The book describes how to write a pretty-printer, and how to parse a binary file, both of which require some acrobatics to write concisely in Haskell.  In particular the parser library lost me entirely; functions were being chained to functions in all directions and I couldn't follow it.</p>
<p>I think one reason Java is so popular is that you don't have to be a genius to write it.  To write Haskell (or even Lisp) well, to take advantage of the language and use it smoothly, you really do need to do some deeper thinking.  The abstractions are more powerful and more "abstract".  It's not too hard to understand a world made of objects with a bunch of knobs you turn via method calls.  Lambdas and recursive functions and monads and typeclasses are a more ephemeral thing.</p>
<p>That said I plan to stick with the book.  Practice makes perfect.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/11/30/books-are-our-friends/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Qt4 in Lisp?!</title>
		<link>http://briancarper.net/2008/10/31/qt4-in-lisp/</link>
		<comments>http://briancarper.net/2008/10/31/qt4-in-lisp/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 00:31:43 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Clojure]]></category>

		<category><![CDATA[KDE]]></category>

		<category><![CDATA[Lisp]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/31/qt4-in-lisp/</guid>
		<description><![CDATA[Imagine Qt4 bindings for Lisp that are:

Officially supported
Thoroughly documented, with tons of examples
Cross-platform
Consistently up-to-date

Keep dreaming, right?  Your first thought might be to check CLiki for some Common Lisp bindings.  There is indeed a Qt project there.  Except at a glance, it's listed as working only for CMUCL.  And the last update [...]]]></description>
			<content:encoded><![CDATA[<p>Imagine Qt4 bindings for Lisp that are:</p>
<ol>
<li>Officially supported</li>
<li>Thoroughly documented, with tons of examples</li>
<li>Cross-platform</li>
<li>Consistently up-to-date</li>
</ol>
<p>Keep dreaming, right?  Your first thought might be to check CLiki for some Common Lisp bindings.  There is indeed a <a href="http://www.cliki.net/Qt">Qt</a> project there.  Except at a glance, it's listed as working only for CMUCL.  And the last update was 2003.  And the download link is 404'd.  Oops!</p>
<p>But there's a link to a some <a href="http://sourceforge.net/projects/lisp-cffi-qt4">QT4 bindings, CFFI style</a>.  Much more promising.  Except... last update: March 2007.  <em>"Project status: dead."</em>  Never mind.  There's also <a href="http://uint32t.blogspot.com/2008/07/simple-cffi-qt4-integration-attempt.html">this</a> and maybe a few others you could Google up, but I haven't tried them and I'm not going to.  </p>
<p>Kudos to the people who wrote the above; providing bindings for all of Qt4 is a daunting task and it's no wonder it's not done for Common Lisp.  Doesn't change the reality of the fact that Qt4 (like many other libraries) is a no-go in Common Lisp.  There's nothing stopping Common Lisp from having great libraries except lack of manpower; but lack of manpower and lack of mature, tested, up-to-date libraries is still a real problem when you want to write an application today.</p>
<h2>Enter Clojure</h2>
<p>Luckily, it turns out there ARE Qt4 bindings that you can use from Lisp.  That Lisp is <a href="http://clojure.org/">Clojure</a>, and the bindings are <a href="http://doc.trolltech.com/qtjambi-4.4/html/com/trolltech/qt/qtjambi-index.html">Qt Jambi</a>.  Many people are excited about Clojure nowadays, and this is one big reason (of many).  It's hard to beat Java when it comes to libraries, and Clojure gets them all for free.</p>
<p>Let's try to write one of the <a href="http://doc.trolltech.com/qtjambi-4.4/html/com/trolltech/qt/qtjambi-tutorial2.html">official Qt4 examples / tutorials</a> in Clojure and see how it goes.  Keep in mind that I'm still learning Clojure, so this may be far from ideal, but it should give you a bit of a taste of Clojure and Qt Jambi if you've never seen it before.  </p>
<p>To spoil the ending a bit: It works!  In Vista and Linux (I don't have an OS X box to try, but it'll probably work there too):</p>
<p><img src="/clojure/clojure-windows-demo.png" alt="Clojure Qt4 demo" /> <img src="/clojure/clojure-linux-demo.png" alt="Clojure Qt4 demo" /></p>
<h2>Setup</h2>
<p>To set up Clojure, follow the directions on the <a href="http://en.wikibooks.org/wiki/Clojure_Programming">Clojure wiki</a>.  Be sure to get the SVN version of Clojure, because it's being developed very rapidly and is often updated many times per week.  You can also check out some recent posts on <a href="http://bc.tech.coop/blog/081023.html">Bill Clementson's blog</a>, and <a href="http://lispcast.com/drupal/node/79">this movie on LispCast</a> which walks through setting up Clojure and Emacs/SLIME.</p>
<p>To make Qt Jambi available to Clojure, you may have some options.  If you use Linux, your distro may make this available via your package manager.  Otherwise go to the <a href="http://trolltech.com/downloads/opensource/appdev">Qt download site</a> and download "Qt for Java" for your OS.  This is a freaking huge download, but it includes all the documentation and source code and plugins; all you need out of it are a couple of JAR files.  There are two JARs you need, one cross-OS and one specific to your OS.  </p>
<p>You have to put these JARs on your CLASSPATH so Clojure can find them.  There are lots of ways to do this; one way is on the commandline:</p>
<pre>java -cp qt-jambi-4.4.3_01.jar:qtjambi-linux32-gcc-4.4.3_01.jar:clojure-lang-1.0-SNAPSHOT.jar clojure.lang.Repl</pre>
<p>There's also <strong>add-classpath</strong> in Clojure, which lets you edit the classpath while Clojure is running.  I was unable to get this to work with Qt Jambi, but I didn't try very hard.  In reality I just use a <a href="http://briancarper.net/clojure/clojure.sh.txt">shell script</a> so I can dump a bunch of JARs into a directory, and they will all be added to CLASSPATH automatically when I start Clojure.</p>
<p>That's it.  Installing libraries in Clojure couldn't be much easier.</p>
<h2>The Code</h2>
<p>Here's the <a href="/clojure/clojure-qt4-demo.clj">complete example code for download</a>.  Let's walk through it a bit.  First we have to import the Qt Jambi apps into Clojure.  Qt Jambi is on our CLASSPATH and available to Clojure, but we still have to explicitly <strong>import</strong> the bits of it we want:</p>
<pre>(ns clojure-qt4-demo
  (:import (com.trolltech.qt.gui QApplication QPushButton QFont QFont$Weight)
           (com.trolltech.qt.core QCoreApplication)))</pre>
<p><strong>ns</strong> creates a new namespace, and provides convenience syntax to import Java classes at the same time.  It can also import other Clojure files or Clojure libraries, among other things.</p>
<p>Note immediately how this is nicer than Java.  In Java you would be writing something like</p>
<pre>import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.gui.QPushButton;
import com.trolltech.qt.gui.QFont;
...</pre>
<p>And so on, over and over.  If you're lucky you have a bloated IDE to type those things for you.  In Clojure, macros let us factor out the repetition; we name the big long path once, and pluck out the things we want.  The other option in Java is to import <strong>com.trolltech.qt.gui.*</strong>, which pollutes your namespace unnecessarily; Clojure lets us succinctly take just what we want.</p>
<p>One thing I couldn't find documentation for is the way to import a static inner subclass of another class.  To do this you have to use syntax like <strong>SomeClass$SomeSubClass</strong>.  My first thought was <strong>QFont/Weight</strong> or <strong>QFont.Weight</strong>, but those don't work.</p>
<p>If you're typing all of this at a REPL, you now have to do:</p>
<pre>(in-ns 'clojure-qt4-demo)</pre>
<p>to switch to the namespace we just created.  Next we set up some convenience functions:</p>
<pre>(defn init []
  (QApplication/initialize (make-array String 0)))</pre>
<p>In Qt4, the first thing you always do is initialize QApplication. <strong>QApplication</strong> is essentially a singleton class, and it has to be initialized via <strong>QApplication.initialize()</strong>, a static method call, before you do anything else.  In Clojure this becomes <strong>(QApplication/initialize)</strong>, which says to call the function or static method called "initialize" in the namespace called "QApplication".  Static methods in Java become functions in a class-namespace in Clojure.</p>
<p>This function expects an array of Strings, which in a normal app would be commandline parameters.  In Clojure we can make a native Java Array of Strings via <strong>make-array</strong>.  I just pass in an empty one because I'm running this from a REPL.  Note, a native Java Array of Strings is different from a Clojure persistent array, <strong>[ ]</strong>.  This is a bit nasty, but necessary for Java interop.  Most of the time you will be able to get by with <strong>[ ]</strong>.  Next:</p>
<pre>(defn exec []
  (QApplication/exec))</pre>
<p>This function (again a static method call) is generally the LAST thing you do in a Qt application.  It starts displaying widgets and fires up the event loop.</p>
<p>A gotcha here is that certain things must happen in a certain order.  A Qt app looks something like this:</p>
<ol>
<li>QApplication.initialize()</li>
<li>Initialize and set up all of your widgets etc.</li>
<li>QApplication.exec()</li>
<li>Either the program exits, or go to step 1 to start over.</li>
</ol>
<p>For example if you try to exec() before you initialize(), it does nothing at all.  If you call initialize() more than once,  it dies with a <strong>RuntimeException</strong>.  When I was playing around with this at the REPL, it was very common that I called initialize multiple times by mistake.  It's often safe to swallow the exception though.</p>
<p>All of that bookkeeping really wants to be made into a macro.  Here's a simple macro:</p>
<pre>(defmacro qt4 [&amp; rest]
  `(do
     (try (init) (catch RuntimeException e# (println e#)))
     ~@rest
     (exec)))</pre>
<p>This kind of thing lets you avoid the insanity of Java, which forces you to re-type exception-handling code and other boilerplate code over and over and over.  You can abstract that all away in Clojure.</p>
<p>Macros in Clojure are much like Common Lisp macros.  <strong>~@</strong> is a splicing-unquote, like <strong>,@</strong> in Common Lisp.  Another interesting thing here is <strong>e#</strong>, which is a shorthand way to create a gensym.  It creates a unique symbol; this prevents our macro from stepping on the toes of any other symbol called "e".</p>
<p>Using this macro we can finish our simple example:</p>
<pre>(defn hello-world []
  (qt4
   (let [app (QCoreApplication/instance)
         button (new QPushButton "Go Clojure Go")]
     (.. button clicked (connect app "quit()"))
     (doto button
       (setFont (new QFont "Deja Vu Sans" 18 (.. QFont$Weight Bold value)))
       (setWindowTitle "Go Clojure Go")
       (resize 250 100)
       (show)))))</pre>
<p>The <strong>hello-world</strong> function is pretty straightforward.  It makes a button, sets up an event handler that closes our app when the button is clicked, then sets its title and font, resizes it and shows it.  Note how seamless this is.  Aside from all the <strong>new</strong>'s and <strong>.</strong>'s, you could barely tell this was Java.  It's all tasty Lisp.</p>
<p>Clojure has a bunch of simple convenience macros that make writing Java less painful, two of which I show here.  One of the biggest problems with Java is its extremely verbose and punctuation-heavy C-like syntax.  Compare:</p>
<pre>button.resize(250, 100);
button.setFont(new QFont("Deja Vu Sans", 18, QFont.Weight.Bold.value()));
button.setWindowTitle("Go Clojure Go");
button.show();</pre>
<p>Look how much repetition there is in the code.  button.blah, button.blah, button.blah.  Repetition is bad.  Clojure has the <strong>doto</strong> macro which says "take this thing, and do a bunch of stuff to it" without having to retype it every time:</p>
<pre>(doto button
  (resize 250 100)
  (setFont (new QFont "Deja Vu Sans" 18 (.. QFont$Weight Bold value)))
  (setWindowTitle "Go Clojure Go")
  (show))</pre>
<p>Another macro is <strong>..</strong> which says "take these things and put dots between everything", chaining method calls.  So instead of  <strong>QFont.Weight.Bold.value()</strong>, you can say <strong>(.. QFont$Weight Bold value)</strong>.  Handy.</p>
<p>To run this from a REPL, type</p>
<pre>(hello-world)</pre>
<p><br/></p>
<h2>Verdict</h2>
<p>This app of course is a silly toy and just scratches the surface.  But in my opinion, Clojure already beats all other Lisps by providing access libraries like this one.  This is one of its killer features for me.  The fact that you can seamlessly and easily use any Java library from Clojure is pretty amazing.</p>
<p>Why would you want to run Qt4 apps from Lisp anyways?  Java (and thus Clojure) already have other GUI frameworks, like Swing and SWT and AWT, so why bother with this?  Well, a few reasons...</p>
<ol>
<li>Because I can.</li>
<li>Qt4 has a lot of impressive features nowadays.  <a href="http://dist.trolltech.com/developer/download/webstart/">Run this Qt Jambi example</a> to see some of those features.</li>
<li>Qt's design may appeal more to you than Swing's, which can be clunky at times.</li>
<li>Maybe you want to integrate well into KDE.  I first started exploring GUI programming in Clojure when trying to make an icon sit in the system tray, and while Swing can do this, it's a bit painful to get it to look just right.  It's trivial to do in Qt4.</li>
<li>If I'm forced to write a Qt4 app, I'd much rather write it in a highly interactive and iterative way using Clojure than struggle with a write/compile/debug/recompile/wait-for-hours cycle.  At the very least Clojure would be ideal for prototyping.</li>
<li>Because I can!</li>
</ol>
<p>Verdict: Clojure rules.  But Java interop is just one reason it rules.  Clojure has native Perl/Ruby-like reader support for hashes/arrays/sets/regexes/etc., support for easy and safe concurrency, cross-platform-ness galore, and a much more modern feel than Common Lisp.  It's being worked on by some very smart people and the community is vibrant, enthusiastic, and welcoming.  It has all the strengths of Java and Common Lisp, and very few of their weaknesses.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/31/qt4-in-lisp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Westinghouse: behind the scenes (the horrors of a call center)</title>
		<link>http://briancarper.net/2008/10/27/westinghouse-behind-the-scenes-the-horrors-of-a-call-center/</link>
		<comments>http://briancarper.net/2008/10/27/westinghouse-behind-the-scenes-the-horrors-of-a-call-center/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 02:03:50 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Westinghouse]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/27/westinghouse-behind-the-scenes-the-horrors-of-a-call-center/</guid>
		<description><![CDATA[Recently someone purporting to be a phone rep from a Westinghouse call center left me a comment.  After the months of pain, I appreciate getting some more information from behind the scenes.  Given how many times I called Westinghouse, chances are good I maybe even talked to this guy once or twice (so [...]]]></description>
			<content:encoded><![CDATA[<p>Recently someone purporting to be a phone rep from a Westinghouse call center left me a comment.  After the months of pain, I appreciate getting some more information from behind the scenes.  Given how many times I called Westinghouse, chances are good I maybe even talked to this guy once or twice (so hello again, anonymous Westinghouse guy!).</p>
<p>The situation at Westinghouse is largely as I imagined.  Here is the comment, and my response follows.</p>
<blockquote><p>Heads up for everyone ever trying to deal with a Westinghouse RMA.</p>
<p>I “currently” work for the call center for Westinghouse. It is not our fault the service center will not ship you a tv, or even tell us why. Our database only lists information that has been typed in by other tech support reps, and occasionally things like a logged reciept, tracking number, or RMA number. And yes, it is true that we cannot transfer you to a manager, they do in fact have to call you back. Also, we literally do not have access to any contact information for the corporate office or the RMA center in any way, and even if we did, we are expressly forbidden from given it out. You'd have a much easier time searching for the contact on Google. We also have no way to change any of the Warranty policies, or give you free shipping labels for RMA. Those don't even come from a “manager” at the call center, that all is done through corporate.</p>
<p>Basically, 95% of all of the RMA issues arise from the fact that a)the Westinghouse corporate warranty policy does not allow us any deviation on our level and b)the RMA center is the slowest, shittiest facility I have ever dealt with. Last I heard, there were litterally 5 people working there. Also, the fact is, there are far more returned RMA tvs than there are available to ship back to customers, and that is causing most of the shipping problems. But please don't call us at the customer service and expect us to be able get you a tv faster. We are in NY and ME, and the service center is in TX, we cannot “walk downstairs” like some people would like to think.</p>
<p>If you do want to buy a Westinghouse tv for some reason, please PLEASE purchase it at Best Buy. We have an exclusive deal with Best Buy that if your tv breaks during the warranty period, you can call us to get a return authorization and bring it back to the store directly and get an exchange/store credit, even 11 months 3 weeks and 6 days after you bought the tv. Other than that, DO NOT buy one online, and I'm sorry to say it but, even at Woot, E-Cost, or any other online discount store. ESPECIALLY if it is a refurbished television.</p>
<p>And also, please, everyone, read the warranty policy on ANY expensive item you purchase, especially TVs. You'd be surprised what isn't covered under most electronics companies warranties. Almost every major TV manufacturer requires you to ship a defective tv back to them at your cost.</p>
<p>For all I know I can get fired for posted this online, but to be honest at this point, I could give a shit. Sorry everyone who has had to deal with a Westinghouse RMA, but please remember that if you have to call the tech support line, it really is not our fault, and there is almost nothing we can do.</p></blockquote>
<p>I worked at a call center too (tech support and general billing/service for a residential satellite TV company); I lasted about four months.  I remember very well the horrors of that job.  Working at a call center should be classified as a form of torture by the Geneva Convention.</p>
<p>The main criteria of whether we were doing our job "properly" was how fast we finished the calls.  Call volume mattered, not making customers happy.  The second criteria was how closely we followed the scripts.  We were told to never, ever deviate from the scripts, even when the scripts were completely bogus, redundant, or insulting to the customer's intelligence.  And the scripts ARE insulting; they are written to appeal to the lowest common denominator of customer, by necessity.  If I as a phone rep knew how to fix a problem and it deviated from the script, tough crap.  Deviate from the script at your own risk.  If someone was monitoring that call, you're in trouble.</p>
<p>At any given time, there was approximately one manager per 15-20 phone reps.  If a customer asked to speak to a manager, s/he often got put on hold for a good 10-15 minutes by necessity; this is because I was 30 cubicles away looking for someone to take the call.  And yet putting people on hold was a HUGE no-no, per company policy.  It was a lose-lose situation.</p>
<p>The company under-staffed the center to save money, so the hold queue was always filled to the brim.  By the time the customer got to us, they had been sitting and fuming on hold for 15 minutes or more.  We also had an offshore call center in general vicinity of India, and those reps were only trained to take the most basic of calls.  If there was a tech support issue or anything complex, it was transferred to us (resulting in another 15 minutes of hold before they talked to me).  THOSE weren't fun calls.</p>
<p>We had to take calls non-stop for hours, until we got a specified 15-minute or 30-minute break.  Breaks were measured DOWN TO THE SECOND.  Aside from your breaks, you couldn't stop taking calls even to go to the bathroom or get a sip of water.</p>
<p>Phone reps are hated by customers, because they are the voice of the company for the customer.  They are also abused by the company; the pay is terrible, the people doing it are desperate (few people take that job if they can find any other), and the company knows they're replaceable.  Attrition rates at call centers are through the roof.  Even people how stay at the call center aspire to become managers themselves as fast as humanly possible, so they can stop taking calls, so at any given time, the person you're talking to when you call a call center has probably only been working for 3 or 4 months tops.  Phone reps are seen as little better than cattle by their employers.</p>
<p>So I definitely sympathize.  In all of my lengthy dealings with Westinghouse, I was always polite, and the phone reps were generally polite back to me.</p>
<p>One thing that absolutely IS the phone reps' fault, though, is when <strong>I'm promised a call back, and then I never get one</strong>.  This happened to me many times when dealing with Westinghouse, and there's no excuse for that.  Or when someone says <strong>"Call back tomorrow and we'll have more information for you!" knowing full well that they won't.</strong>  This also happened to me many times.  Once the phone reps determined that they had no information for me, I was often told anything that would get me to hang up quickly.</p>
<p>If one girl at Westinghouse hadn't finally taken 15 minutes to somehow track down my first (lost forever) monitor, I'd never have known what happened.  I don't know how they did it, but if a phone rep had done that sooner instead of two months of dodging my questions, I may have been able to get UPS to track down the first package.</p>
<p>If someone is unable to help me, they should say "Sorry, I'm completely unable to help you."  A little honesty goes a long way.  If I'd have contacted the corporate office sooner I could've gotten things done a lot faster, without all the run-around.</p>
<p>But yes, this comment reaffirms what I already suspected.  Don't buy expensive electronics online; the price savings aren't worth the disaster you face when it breaks.  And remember you're taking a huge gamble when you buy Westinghouse or any other "bargain" (i.e. cheap) brand.</p>
<p>(Read the entire Westinghouse saga, if you dare: <a href="http://briancarper.net/2008/03/15/westinghouse-do-they-suck/">The beginning</a>, <a href="http://briancarper.net/2008/03/22/blah-blah-blah/">Update 1</a>, <a href="http://briancarper.net/2008/04/08/westinghouse-closer-to-sucking-every-day/">Update 2</a>, <a href="http://briancarper.net/2008/04/14/westinghouse-the-saga-continues/">Update 3</a>, <a href="http://briancarper.net/2008/05/05/westinghouse-fail/">Update 4</a>, <a href="http://briancarper.net/2008/06/10/westinghouse-still-sucks/">Update 5</a>, <a href="http://briancarper.net/2008/06/16/westinghouse-the-saga-continues-2/">Update 6</a>, <a href="http://briancarper.net/2008/08/14/westinghouse-bbb-rating-cc-and-falling/">Update 7</a>, <a href="http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/">Update 8</a>, <a href="http://briancarper.net/2008/09/24/westinghouse-it-never-ends/">Update 9</a>, <a href="http://briancarper.net/2008/10/04/westingouse-victory/">VICTORY</a>, <a href="http://briancarper.net/2008/10/27/westinghouse-behind-the-scenes-the-horrors-of-a-call-center/">aftermath</a>.)</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/27/westinghouse-behind-the-scenes-the-horrors-of-a-call-center/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ignorance is bliss</title>
		<link>http://briancarper.net/2008/10/24/ignorance-is-bliss/</link>
		<comments>http://briancarper.net/2008/10/24/ignorance-is-bliss/#comments</comments>
		<pubDate>Sat, 25 Oct 2008 03:54:00 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Internet]]></category>

		<category><![CDATA[Rant]]></category>

		<category><![CDATA[Stupidity]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/24/ignorance-is-bliss/</guid>
		<description><![CDATA[I remember the good old days of web-browsing, when I'd just zoom around the internet without a care in the world.  The first time I got a small whiff of something foul was in college one day, when a professor yelled at the class because someone was using telnet to connect to remote machines. [...]]]></description>
			<content:encoded><![CDATA[<p>I remember the good old days of web-browsing, when I'd just zoom around the internet without a care in the world.  The first time I got a small whiff of something foul was in college one day, when a professor yelled at the class because someone was using telnet to connect to remote machines.  <em>"Are you crazy?  It sends everything in plaintext!  Use SSH!"</em></p>
<p>Then eventually I put together a website where I had access to the server logs, and oh boy, it was not fun reading those the first time.  Line after line of bots in Ukraine, trying to access vulnerable scripts that may or may not exist on my server.    Then I checked some of my SSH logs, and saw the same thing.  Thus my innocence was destroyed forever.</p>
<p>Nowadays all of my email traffic is SSL-encrypted, and FTP is disabled on every server I have root access to, in favor of SFTP.  I cringe every time I set up a wireless network (even <a href="http://www.scmagazineuk.com/WiFi-is-no-longer-a-viable-secure-connection/article/119294/">WPA</a> is being cracked nowadays).  My passwords are long, nearly impossible to remember, and legion.  My browser cache is cleared daily.  I reject all cookies by default, and Javascript is run on an as-needed basis.</p>
<p>One day I read on Slashdot about <a href="http://yro.slashdot.org/article.pl?sid=08/10/14/1656251&from=rss">Flash cookies</a>.  So I had a really bright idea:</p>
<pre>ln -s /dev/null ~/.macromedia</pre>
<p>That'll teach them!  No more flash cookies.  (Note, don't do this if you like watching Flash movies in your browser.  They stop working on certain websites.  Annoying.  Next best thing is <a href="http://objection.mozdev.org/">a plugin to let you delete them</a>.)</p>
<p>The bad thing is that I still don't know very much about network security and privacy.  If I knew more, I'm sure I'd worry more.  On the other hand, if I was a locksmith, I might feel bad with the quality of the lock on my front door.  And yet my house has never been robbed (yet) and my computer has never been hacked (yet).  People tend to worry about what's right in front of them.  Maybe what you don't know can't hurt you.</p>
<p>But I still cringe when someone sits down in an airport or a Starbucks and logs into their bank account or work email.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/24/ignorance-is-bliss/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Vim - escaping quotes</title>
		<link>http://briancarper.net/2008/10/16/vim-escaping-quotes/</link>
		<comments>http://briancarper.net/2008/10/16/vim-escaping-quotes/#comments</comments>
		<pubDate>Fri, 17 Oct 2008 00:52:25 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Regex]]></category>

		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/16/vim-escaping-quotes/</guid>
		<description><![CDATA[This Vim regex escapes (by doubling) every double-quote on a line except the first one, last one, or any that are already doubled:
:s/\v(^[^"]*)@&#60;!"@&#60;!""@!([^"]*$)@!/""/g
Sometimes I kind of understand that old humorous quote: Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.  But regexes are still [...]]]></description>
			<content:encoded><![CDATA[<p>This Vim regex escapes (by doubling) every double-quote on a line except the first one, last one, or any that are already doubled:</p>
<pre>:s/\v(^[^"]*)@&lt;!"@&lt;!""@!([^"]*$)@!/""/g</pre>
<p>Sometimes I kind of understand that old humorous quote: <em>Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.</em>  But regexes are still pretty darn useful.  I can't imagine a good replacement for them that wouldn't have all the same problems with escaping and magic characters and whatnot, without the replacement being so verbose that no one would ever use them.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/16/vim-escaping-quotes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Vim &#8220;Align&#8221; plugin</title>
		<link>http://briancarper.net/2008/10/13/vim-align-plugin/</link>
		<comments>http://briancarper.net/2008/10/13/vim-align-plugin/#comments</comments>
		<pubDate>Mon, 13 Oct 2008 18:22:15 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/13/vim-align-plugin/</guid>
		<description><![CDATA[There are some Vim plugins I don't know how I lived without before I found them.  One I found just last week is Align, which turns this:
@label = Label.new&#40;@frame, -1, &#34;Choose an option:&#34;, DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER&#41;
@selector = ListBox.new&#40;@panel, -1, DEFAULT_POSITION, DEFAULT_SIZE, &#91;&#93;, LB_SINGLE&#41;
@button = Button.new&#40;@frame, -1, 'OK'&#41;
into this:
@label    = Label.new  [...]]]></description>
			<content:encoded><![CDATA[<p>There are some Vim plugins I don't know how I lived without before I found them.  One I found just last week is <a href="http://www.vim.org/scripts/script.php?script_id=294">Align</a>, which turns this:</p>
<pre class="ruby">@label = Label.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>@frame, <span style="color:#006666;">-1</span>, <span style="color:#996600;">&quot;Choose an option:&quot;</span>, DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER<span style="color:#006600; font-weight:bold;">&#41;</span>
@selector = ListBox.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>@panel, <span style="color:#006666;">-1</span>, DEFAULT_POSITION, DEFAULT_SIZE, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>, LB_SINGLE<span style="color:#006600; font-weight:bold;">&#41;</span>
@button = Button.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>@frame, <span style="color:#006666;">-1</span>, 'OK'<span style="color:#006600; font-weight:bold;">&#41;</span></pre>
<p>into this:</p>
<pre class="ruby">@label    = Label.<span style="color:#9900CC;">new</span>  <span style="color:#006600; font-weight:bold;">&#40;</span>@frame, <span style="color:#006666;">-1</span>, <span style="color:#996600;">&quot;Choose an option:&quot;</span>, DEFAULT_POSITION, DEFAULT_SIZE, ALIGN_CENTER<span style="color:#006600; font-weight:bold;">&#41;</span>
@selector = ListBox.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>@panel, <span style="color:#006666;">-1</span>, DEFAULT_POSITION   , DEFAULT_SIZE    , <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>          , LB_SINGLE<span style="color:#006600; font-weight:bold;">&#41;</span>
@button   = Button.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#40;</span>@frame, <span style="color:#006666;">-1</span>, <span style="color:#996600;">&quot;OK&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre>
<p>These mappings are helpful to quickly align some visually-selected lines of code by comma, left paren or equal sign:</p>
<pre>vmap &lt;silent&gt; &lt;Leader&gt;i= &lt;ESC&gt;:AlignPush&lt;CR&gt;:AlignCtrl lp1P1&lt;CR&gt;:'&lt;,'&gt;Align =&lt;CR&gt;:AlignPop&lt;CR&gt;
vmap &lt;silent&gt; &lt;Leader&gt;i, &lt;ESC&gt;:AlignPush&lt;CR&gt;:AlignCtrl lp0P1&lt;CR&gt;:'&lt;,'&gt;Align ,&lt;CR&gt;:AlignPop&lt;CR&gt;
vmap &lt;silent&gt; &lt;Leader&gt;i( &lt;ESC&gt;:AlignPush&lt;CR&gt;:AlignCtrl lp0P0&lt;CR&gt;:'&lt;,'&gt;Align (&lt;CR&gt;:AlignPop&lt;CR&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/13/vim-align-plugin/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Emacs annoyance #448,546</title>
		<link>http://briancarper.net/2008/10/12/emacs-annoyance-448546/</link>
		<comments>http://briancarper.net/2008/10/12/emacs-annoyance-448546/#comments</comments>
		<pubDate>Sun, 12 Oct 2008 23:04:12 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Emacs]]></category>

		<category><![CDATA[Rant]]></category>

		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/12/emacs-annoyance-448546/</guid>
		<description><![CDATA[From the Emacs docs:
Each buffer has a default directory which is normally the same as the directory of the file visited in that buffer. When you enter a file name without a directory, the default directory is used. If you specify a directory in a relative fashion, with a name that does not start with [...]]]></description>
			<content:encoded><![CDATA[<p>From the <a href="http://www.gnu.org/software/emacs/manual/html_node/emacs/File-Names.html">Emacs docs</a>:</p>
<blockquote><p>Each buffer has a default directory which is normally the same as the directory of the file visited in that buffer. When you enter a file name without a directory, the default directory is used. If you specify a directory in a relative fashion, with a name that does not start with a slash, it is interpreted with respect to the default directory. The default directory is kept in the variable default-directory, which has a separate value in every buffer. </p>
<p>The command M-x pwd displays the current buffer's default directory, and the command M-x cd sets it (to a value read using the minibuffer). A buffer's default directory changes only when the cd command is used. A file-visiting buffer's default directory is initialized to the directory of the file it visits.  If you create a buffer with C-x b, its default directory is copied from that of the buffer that was current at the time. </p></blockquote>
<p>This is extremely annoying.  Vim leaves my working directory the hell alone, why doesn't Emacs?  Vim lets you set a global working directory, and selectively (and explicitly) change it on a per-buffer basis.  This is what I want.</p>
<p>But in Emacs, every time you open a file, the working directory automatically changes to the directory of that file.  If you have multiple files open in Emacs (which of course you do), every time you move the cursor between windows, or look at a new file in your current window, your working directory just changed out from under you.</p>
<p>So say you open some files.  Then you want to start SLIME.  So you <strong>C-x 2</strong> to split and open a new window, in which to start SLIME.  Except (annoyance #448,547) Emacs doesn't open a window with a new BLANK file, as Vim sanely does via <strong>CTRL-W n</strong>; instead it puts the file you're looking at into BOTH windows, which is absolutely never what you want.  As a result, the working directory of BOTH windows is the directory of whatever file you were looking at.   So every time you start SLIME, you have to make sure you <strong>M-x cd</strong> back to the proper working directory first, because otherwise your Lisp process is randomly going to start in the wrong directory.</p>
<p>But you can change the directory of the SLIME buffer after you start SLIME.  Just <strong>M-x cd</strong> or <strong>,cd</strong>.  Except if you're unlucky enough to be using SLIME for Clojure, which may have set its classpath based on its working directory when you started it.  In that case you have to restart SLIME.  </p>
<p>But if you kill SLIME, Emacs (annoyance #448,548) jams another random file into the window where SLIME just was.  So your working directory just changed again!  Or did it?  Depends what Emacs decided to put into your window.  You may think that, while SLIME is running, <strong>M-x cd</strong> and/or <strong>,cd</strong> and then <strong>,restart-inferior-lisp</strong> may do what you want, but you would be wrong; it always reverts back to the original working directory from when SLIME was first started.</p>
<p>Lost?  Confused?  tl;dr?  Welcome to Emacs.  So now I'm looking through the encyclopedic tangled mess of Emacs documentation to try to figure out how to get Emacs not to change my working directory, ever, unless I say so.  This is hindered as always by (annoyance #448,549) Emacs' arcane and non-standard terminology.  So far, I have committed to memory that "current directory"/"working directory" in Emacs is instead called "default directory".  And you don't open files, you "visit" them.  Command line?  No, "minibuffer".</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/12/emacs-annoyance-448546/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Crap&#8230; I fixed them</title>
		<link>http://briancarper.net/2008/10/06/crap-i-fixed-them/</link>
		<comments>http://briancarper.net/2008/10/06/crap-i-fixed-them/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 00:24:58 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Hardware]]></category>

		<category><![CDATA[Headphones]]></category>

		<category><![CDATA[Music]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/06/crap-i-fixed-them/</guid>
		<description><![CDATA[I couldn't give up on my precious Grado SR-80s.  Turns out the cable was only broken in three places; nothing a couple hours and a lot of electrical tape couldn't fix.  Now I can't justify buying a replacement.

They really do sound amazing.  If only they weren't so fragile and difficult to transport. [...]]]></description>
			<content:encoded><![CDATA[<p>I couldn't give up on <a href="http://briancarper.net/2008/10/05/grado-labs-sr-80-rip/">my precious Grado SR-80s</a>.  Turns out the cable was only broken in three places; nothing a couple hours and a lot of electrical tape couldn't fix.  Now I can't justify buying a replacement.</p>
<p><a href="/screenshots/photos/img_2177.jpg"><img src="/screenshots/photos/thumbs/img_2177.jpg" alt="Fixed headphones" /></a></p>
<p>They really do sound amazing.  If only they weren't so fragile and difficult to transport.  And ugly, for that matter.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/06/crap-i-fixed-them/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Grado Labs SR-80: RIP</title>
		<link>http://briancarper.net/2008/10/05/grado-labs-sr-80-rip/</link>
		<comments>http://briancarper.net/2008/10/05/grado-labs-sr-80-rip/#comments</comments>
		<pubDate>Mon, 06 Oct 2008 07:00:46 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Hardware]]></category>

		<category><![CDATA[Headphones]]></category>

		<category><![CDATA[Music]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/05/grado-labs-sr-80-rip/</guid>
		<description><![CDATA[My precious Grado SR-80 headphones died today.  :(  I hardly new thee.  
This picture may not be suitable for small children or those with a heart condition:

These headphones sounded really great, best I've ever owned.  They should, for how much they cost.  But they were designed so so so poorly. [...]]]></description>
			<content:encoded><![CDATA[<p>My precious Grado SR-80 headphones died today.  :(  I hardly new thee.  </p>
<p>This picture may not be suitable for small children or those with a heart condition:</p>
<p><a href="/screenshots/photos/img_2173.jpg"><img src="/screenshots/photos/thumbs/img_2173.jpg" alt="Headphones" /></a></p>
<p>These headphones sounded really great, best I've ever owned.  They should, for how much they cost.  But they were designed so so so poorly.  The cups can rotate 360 degrees, which means no matter how well you take care of them, the cables from the cups to the Y-splitter will get twisted.  Once I realized this I electrical-taped the cables together to avoid some of the twisting, but it didn't help.  No matter how carefully I wrapped the cords up and stored them in my briefcase, 10 minutes later I'd pull them out and they'd look like a tornado hit.</p>
<p>Today I plugged them in and the left cup was sputtering and hissing in its death rattle.  I immediately put the headphones on life support and performed emergency surgery, but the left wire snapped in my hands.  You can only twist copper so many times before it gives.  What followed was a good 45 minutes of hacking away at the plastic Y-splitter to get to the wires.  But it was no good.  I think something broke in the cup too, and that thing is impossible to get apart no matter how much force I applied.  I tried heating it up to melt the glue but that didn't work either.  I made it hot enough that the working parts are probably a puddle in there.</p>
<p>I'm almost glad this DIDN'T work, because then I'd be wearing that mess on my head for another year.  Now at least I can justify possibly buying a replacement.  </p>
<p>I absolutely need music while writing code.  Depending on my mood, either angry German music or cheerful Japanese music.  Foreign-language music seems to be just the right mix of brain-stimulation without the distraction of needing to pay attention to the lyrics.  So yeah, I'm now in dire need a of replacement.  I have backups but they're the in-ear bud sort and aren't the comfiest thing for an 8-hour session.  Plus they cancel noise too well and I can't hear my boss talking to me.</p>
<p>It took me MONTHS of research to find these, but I can't justify buying another set after these broke in a few short years of heavy daily use.  I need something sturdy and comfy that sounds really good.  I need good bass in particular.  Back to the drawing board I guess.</p>
<p>EDIT: <a href="http://briancarper.net/2008/10/06/crap-i-fixed-them/">Crap, I fixed them.  :(</a></p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/05/grado-labs-sr-80-rip/feed/</wfw:commentRss>
		</item>
		<item>
		<title>KDE4 disaster</title>
		<link>http://briancarper.net/2008/10/05/kde4-disaster/</link>
		<comments>http://briancarper.net/2008/10/05/kde4-disaster/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 21:49:10 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Gentoo]]></category>

		<category><![CDATA[KDE]]></category>

		<category><![CDATA[Themes]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/05/kde4-disaster/</guid>
		<description><![CDATA[From reading the bug it sounds like KDE4 is getting close to being ready to hit the tree, which is awesome.  Foolishly, I decided to try it early from the overlay last night.  It was a total disaster.  Things were crashing left and right, panels would resize themselves to be fullscreen (with [...]]]></description>
			<content:encoded><![CDATA[<p>From reading <a href="http://bugs.gentoo.org/show_bug.cgi?id=234773">the bug</a> it sounds like KDE4 is getting close to being ready to hit the tree, which is awesome.  Foolishly, I decided to try it early from the overlay last night.  It was a total disaster.  Things were crashing left and right, panels would resize themselves to be fullscreen (with hilarious results), half of my apps didn't work at all.  I found three or four ways to bring down the entire X server.  It took me many hours to get KDE3 running again.  This is totally to be expected from installing masked packages as I did, so it's my own dumb fault, it was amusing and I wanted to get a taste.</p>
<p>I'm afraid it's going to be inevitably difficult or impossible to migrate cleanly from KDE3 to KDE4.  I had the same problem in Kubuntu when I tried a while back.  KDE is so huge and so many things link to it or interact with it that it's going to take a year to track down and remove all the cruft after the switch.</p>
<p>I couldn't even import my old KDE3 color schemes or Konsole color schemes into KDE4, which was surprising.  QtCurve was un-configurable, dekorator didn't work, and so on.  I didn't get far enough to figure out if my preferred icon themes work or not.  I didn't realize they broke backwards compatibility to that large an extent, but I maybe it's to be expected.</p>
<p>There were other problems that were seemingly due to the lingering immaturity of KDE4.  I can see all the pieces there which are going to allow people to do really neat stuff eventually.  In the meantime KDE4 feels horrible.</p>
<p>KDE4 fonts look nice though.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/05/kde4-disaster/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Westingouse: Victory</title>
		<link>http://briancarper.net/2008/10/04/westingouse-victory/</link>
		<comments>http://briancarper.net/2008/10/04/westingouse-victory/#comments</comments>
		<pubDate>Sat, 04 Oct 2008 23:51:33 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Hardware]]></category>

		<category><![CDATA[Westinghouse]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/10/04/westingouse-victory/</guid>
		<description><![CDATA[
It only took seven months, a report to the BBB, 30 phone calls, a half dozen emails, and threats of reporting Westinghouse to the FTC and CA Attorney General, but they finally sent me back my monitor.  It's the one on the right there (with the very slightly crappier picture quality).
I must say, 3840x1200 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/screenshots/photos/img_2170.jpg"><img src="/screenshots/photos/thumbs/img_2170.jpg" alt="Monitor" /></a></p>
<p>It only took seven months, a report to the BBB, 30 phone calls, a half dozen emails, and threats of reporting Westinghouse to the FTC and CA Attorney General, but they finally sent me back my monitor.  It's the one on the right there (with the very slightly crappier picture quality).</p>
<p>I must say, 3840x1200 resolution is pretty much a dream come true.  I can have Firefox and Vim/Emacs open and nice and big, and still have room for lots of terminals, and maybe even a file manager or two.  Multiple that by eight virtual desktops.</p>
<p>As near I can tell, it appears to e a new unit, not refurbished.  If it is refurbished, it's refurbished well enough that I can't tell one way or the other, which is fine.  However I'm still expecting this one to die too.  My first monitor died in such a way that it wouldn't power on at all.  This one is running very very hot, which scares me.  I give it 3 months tops.</p>
<p>It makes me sad every time another person posts to my blog that Westinghouse is giving them the same horrible treatment.  But hang in there.  Lessons learned:</p>
<ul>
<li>Don't buy a crappy brand just because it's cheap.  I saved $75 or $100 on this monitor compared to a better brand, but it cost me over seven months of anguish (and $25 in shipping fees to send it back to the factory, and I had to buy a replacement!)  Cheap things are cheap for a reason: The company isn't paying anyone to support their customers, or it's cutting corners in the quality of the merchandise, or something similar.  Is it worth the gamble?</il></p>
<li>Don't buy anything expensive online unless you have a very clear method of getting it replaced if it breaks.   Manufacturer standard warranties are evil.  Is the time savings of shopping online rather than going to the local big box electronics store really worth it, if you have to pack up and mail your stuff to Zimbabwe for seven months?</li>
<li>UPS sucks.  Hey UPS, how about if you don't drop off $500 pieces of electronics on a random person's front porch without a signature next time?  I hope whoever ended up with my first monitor is enjoying it.  (Actually I hope they die in a fire.)</li>
</li>
<p>Westinghouse sucks.  Suffice it to say I won't buy this brand of anything ever again.  And neither will my family or friends, who've heard me complain about this for seven months.  And neither will many people reading my blog, I hope.  Note to companies: Take care of your customers.  A new monitor costs you a few dollars, but treating your customers like garbage costs you FAR MORE in the long run.</li>
</ul>
<p>(Read the whole crappy story of Westinghouse's dishonesty and horrible customer service: <a href="http://briancarper.net/2008/03/15/westinghouse-do-they-suck/">The beginning</a>, <a href="http://briancarper.net/2008/03/22/blah-blah-blah/">Update 1</a>, <a href="http://briancarper.net/2008/04/08/westinghouse-closer-to-sucking-every-day/">Update 2</a>, <a href="http://briancarper.net/2008/04/14/westinghouse-the-saga-continues/">Update 3</a>, <a href="http://briancarper.net/2008/05/05/westinghouse-fail/">Update 4</a>, <a href="http://briancarper.net/2008/06/10/westinghouse-still-sucks/">Update 5</a>, <a href="http://briancarper.net/2008/06/16/westinghouse-the-saga-continues-2/">Update 6</a>, <a href="http://briancarper.net/2008/08/14/westinghouse-bbb-rating-cc-and-falling/">Update 7</a>, <a href="http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/">Update 8</a>, <a href="http://briancarper.net/2008/09/24/westinghouse-it-never-ends/">Update 9</a>, <a href="http://briancarper.net/2008/10/04/westingouse-victory/">VICTORY</a>, <a href="http://briancarper.net/2008/10/27/westinghouse-behind-the-scenes-the-horrors-of-a-call-center/">aftermath</a>.)</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/10/04/westingouse-victory/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gentoo still rules</title>
		<link>http://briancarper.net/2008/09/26/gentoo-still-rules/</link>
		<comments>http://briancarper.net/2008/09/26/gentoo-still-rules/#comments</comments>
		<pubDate>Sat, 27 Sep 2008 02:56:44 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Gentoo]]></category>

		<category><![CDATA[KDE]]></category>

		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/09/26/gentoo-still-rules/</guid>
		<description><![CDATA[The version of akregator I have always displays article link text in an ugly dark blue, which doesn't show up well against my dark Qt theme.  I can barely read an ebuild to save my life, and the KDE ebuilds are full of all kinds of odd KDE-specific stuff, but it still took me [...]]]></description>
			<content:encoded><![CDATA[<p>The version of akregator I have always displays article link text in an ugly dark blue, which doesn't show up well against my dark Qt theme.  I can barely read an ebuild to save my life, and the KDE ebuilds are full of all kinds of odd KDE-specific stuff, but it still took me just a couple of minutes to:</p>
<ol>
<li>Find the sources in /usr/portage/distfiles</li>
<li><a href="/kde/akregator-3.5.10-link-color.patch">Cludgily patch</a> akregator to use normal text color for links (underlines still distinguish them)</li>
<li>Copy the akregator ebuild into an overlay, throw the patch in there and add one line to the ebuild to read it</li>
<li>emerge away</li>
</ol>
<p>Et voilà, custom-patched, package-manager-managed app.  Gentoo is pretty good for this kind of thing, whatever its other shortcomings.  Does any other distro make it this easy to do such things?  (I'm genuinely curious.)</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/09/26/gentoo-still-rules/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Westinghouse: It Never Ends</title>
		<link>http://briancarper.net/2008/09/24/westinghouse-it-never-ends/</link>
		<comments>http://briancarper.net/2008/09/24/westinghouse-it-never-ends/#comments</comments>
		<pubDate>Wed, 24 Sep 2008 21:40:00 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Westinghouse]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/09/24/westinghouse-it-never-ends/</guid>
		<description><![CDATA[(If you're just tuning in, long story short: I bought a Westinghouse L2410NM monitor November 2007, it broke March 2008, I sent it to Westinghouse (paying for shipping myself), they sent it back to the wrong address and didn't tell me about it for 2 months, I filed a BBB complaint, they didn't respond to [...]]]></description>
			<content:encoded><![CDATA[<p><em>(If you're just tuning in, long story short: I bought a Westinghouse L2410NM monitor November 2007, it broke March 2008, I sent it to Westinghouse (paying for shipping myself), they sent it back to the wrong address and didn't tell me about it for 2 months, I filed a BBB complaint, they didn't respond to that for another couple of months, and seven months and 30+ phone calls later, I still don't have my monitor back.)</em></p>
<p>My last post about Westinghouse's horrendous customer service and never-ending RMA process was titled "<a href="http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/">Westinghouse: Finally getting somewhere?</a>".  The answer to that is sadly "no". </p>
<p>I got a flurry of phone calls and emails from Westinghouse's corporate office, attempting to settle my BBB complaint.  On September 12th, Westinghouse finally responded to the BBB, saying:</p>
<blockquote><p>Company states, replacement unit shipped 09/10/08</p></blockquote>
<p>Good news!  I was looking forward to posting an end to this horror story. </p>
<p>However, today is September 24th, and guess what?  No monitor.  I contacted Westinghouse last week, asking for a UPS tracking number so I'd know when to expect my monitor.  However, after being promised a phone call last Thursday that never came, and then sending an email Friday which was never answered, and then waiting three more days for good measure, it appears I'm once again being given the runaround.</p>
<p>So today I sent this email to my contact at Westinghouse:</p>
<blockquote><p>Do you have access to Google?  Please search for "westinghouse rma" and look at the top result.  I believe it will be my website.  I've been carefully documenting all of my adventures with Westinghouse for the past seven(!) months.  On my website, many other people have related their own similarly terrible experiences being kept in the dark for months by your customer service departments.  </p>
<p>You promised me a phone call on Sept 18th to provide me with a tracking number for my replacement monitor, but I never heard from you.  I also never received a reply to the email I sent you since then.  </p>
<p>The BBB was informed that a replacement monitor shipped on the 10th.  If that was the case, I probably should've had it in my hands by now, given that it's been two weeks.  Has it actually even been shipped?  I suspect not.  I feel as though I'm once again being given the runaround while nothing is done to resolve this issue.  Please understand my frustration.</p>
<p>If I don't have a UPS tracking number by Friday, I'm filing a complaint with the FTC and the California Attorney General.  They have a very easy-to-use form for filing complaints here: https://www.ftccomplaintassistant.gov/ and here: http://ag.ca.gov/contact/complaint_form.php?cmplt=CL</p>
<p>My website only has a couple thousand readers, but I'm also going to cross-post my story to every online tech news aggregate I can think of (e.g. http://reddit.com and http://digg.com), which translates to tens of thousands more potential readers.  The story I would like to tell is "Westinghouse finally sent me my monitor after seven months", but I'll tell it either way.</p>
<p>I look forward to hearing from you,<br />
--Brian</p></blockquote>
<p>Look for this story on Reddit and Digg on Friday if I don't hear anything.</p>
<p>UPDATE: Well, I got a reply already.  That was fast.</p>
<blockquote><p>Your Fed Ex tracking number is 772xxxxxxxxxxx, you can track the<br />
package at www.fedex.com/tracking to see the progress of your shipment.<br />
Please keep mind that there was a delay at our warehouse and your unit<br />
is going to ship tonight.</p></blockquote>
<p>Just a little two-week delay, I guess those things happen.  Hopefully if/when it shows up, the monitor actually works.  I've burned through seven months of my warranty and somehow I doubt Westinghouse will courteously extend it for me if this monitor fails too.</p>
<p>(Read the whole crappy story of Westinghouse's dishonesty and horrible customer service: <a href="http://briancarper.net/2008/03/15/westinghouse-do-they-suck/">The beginning</a>, <a href="http://briancarper.net/2008/03/22/blah-blah-blah/">Update 1</a>, <a href="http://briancarper.net/2008/04/08/westinghouse-closer-to-sucking-every-day/">Update 2</a>, <a href="http://briancarper.net/2008/04/14/westinghouse-the-saga-continues/">Update 3</a>, <a href="http://briancarper.net/2008/05/05/westinghouse-fail/">Update 4</a>, <a href="http://briancarper.net/2008/06/10/westinghouse-still-sucks/">Update 5</a>, <a href="http://briancarper.net/2008/06/16/westinghouse-the-saga-continues-2/">Update 6</a>, <a href="http://briancarper.net/2008/08/14/westinghouse-bbb-rating-cc-and-falling/">Update 7</a>, <a href="http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/">Update 8</a>, <a href="http://briancarper.net/2008/09/24/westinghouse-it-never-ends/">Update 9</a>, <a href="http://briancarper.net/2008/10/04/westingouse-victory/">VICTORY</a>, <a href="http://briancarper.net/2008/10/27/westinghouse-behind-the-scenes-the-horrors-of-a-call-center/">aftermath</a>.)</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/09/24/westinghouse-it-never-ends/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Practicality: PHP vs. Lisp?</title>
		<link>http://briancarper.net/2008/09/22/practicality-php-vs-lisp/</link>
		<comments>http://briancarper.net/2008/09/22/practicality-php-vs-lisp/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 09:17:25 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Lisp]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/09/22/practicality-php-vs-lisp/</guid>
		<description><![CDATA[Eric at LispCast wrote an article about why PHP is so ridiculously dominant as a web language, when arguably more powerful languages like Common Lisp linger in obscurity.
I think the answer is pretty easy.  In real life, practicality usually trumps everything else.  Most programmers aren't paid to revolutionize the world of computer science. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.lispcast.com/drupal/node/69">Eric at LispCast wrote an article</a> about why PHP is so ridiculously dominant as a web language, when arguably more powerful languages like Common Lisp linger in obscurity.</p>
<p>I think the answer is pretty easy.  In real life, practicality usually trumps everything else.  Most programmers aren't paid to revolutionize the world of computer science.  Most programmers are code monkeys, or to put it more nicely, they're craftsmen who build things that other people pay them to create.  The code is a tool to help people do a job.  The code is not an end in itself.  </p>
<p>In real life, here's a typical situation.  You have to make a website for your employer that collects survey data from various people out in the world, in a way that no current off-the-shelf program quite does correctly.  If you could buy a program to do it that'd be ideal, but you can't find a good one, so you decide to write one from scratch.  The data collection is time-sensitive and absolutely must start by X date.  The interface is a web page, and people are going to pointy-clicky their way through, and type some numbers, that's it; the backend just doesn't matter.  For your server, someone dug an old dusty desktop machine out of a closet and threw Linux on there for you and gave you an SSH account.  Oh right, and this project isn't your only job.  It's one of many things you're trying to juggle in a 40-hour work week.</p>
<p>One option is to write it in Common Lisp.  You can start by going on a quest for a web server.  Don't even think about mod_lisp, would be my advice, based on past experience.  Hunchentoot is good, or you can pay a fortune for one of the commercial Lisps.   If you want you could also look for a web framework; there are many to choose from, each more esoteric, poorly documented and nearly impossible to install than the last.  Then you get to hunt for a Lisp implementation that actually runs those frameworks.  Then you get to try to install it and all of your libraries on your Linux server, and on the Windows desktop machine you have to use as a workstation.  Good luck.   </p>
<p>Once you manage to get Emacs and SLIME going (I'm assuming you already know Emacs intimately, because if you don't, you already lose) you get to start writing your app.  Collecting data and moving it around and putting it into a database and exporting it to various statistics packages is common, so you'd do well to start looking for some libraries to help you out with such things.  In the Common Lisp world you're likely not to find what you need, or if you're lucky, you'll find what you need in the form of undocumented abandonware.  So you can just fix or write those libraries yourself, because Lisp makes writing libraries from scratch easy!  Not as easy as downloading one that's already been written and debugged and matured, but anyways.  Then you can also roll your own method of deploying your app to your server and keeping it running 24/7, which isn't quite so easy.  If you like, you can try explaining your hand-rolled system to the team of sysadmins in another department who keep your server machine running.  </p>
<p>Don't bet on anyone in your office being able to help you with writing code, because no one knows Lisp.  Might not want to mention to your boss that if you're run over by a bus tomorrow, it's going to be impossible to hire someone to replace you, because no one will be able to read what you wrote.  When your boss asks why it's taking you so long, you can mention that the YAML parser you had to write from scratch to interact with a bunch of legacy stuff is super cool and a lovely piece of Lisp code, even if it did take you a week to write and debug given your other workload.</p>
<p>Be sure to wave to your deadline as it goes whooshing by.  If you're a genius, maybe you managed to do all of the above and still had time to roll out a 5-layer-deep Domain Specific Language to solve all of your problems so well it brings tears to your eye.  But most of us aren't geniuses, especially on a tight deadline.</p>
<p>Another option is to use PHP.  Apache is everywhere.  MySQL is one simple apt-get away.  PHP works with no effort.  You can download a <a href="http://www.apachefriends.org/en/xampp.html">single-click-install LAMP stack for Windows</a> nowadays.   PHP libraries for everything are everywhere and free and mature because thousands of people already use them.  The PHP <a href="http://www.php.net/docs.php">official documentation</a> is ridiculously thorough, with community participation at the bottom of every page.  Google any question you can imagine and you come up with a million answers because the community is huge.  Or walk down the hall and ask anyone who's ever done web programming.</p>
<p>The language is stupid, but stupid means easy to learn.  You can learn PHP in a day or two if you're familiar with any other language.  You can write PHP code in any editor or environment you want.  Emacs?  Vim?  Notepad?  nano?  Who cares?  Whatever floats your boat.  Being a stupid language also means that everyone knows it.  If you jump ship, your boss can throw together a "PHP coder wanted" ad and replace you in short order.</p>
<p>And what do you lose?  You have to use a butt-ugly horrid language, but the price you pay in headaches and swallowed bile is more than offset by the practical gains.  PHP is overly verbose and terribly inconsistent and lacks powerful methods of abstraction and proper closures and easy-to-use meta-programming goodness and Lisp-macro syntactic wonders; in that sense it's not a very powerful language.  Your web framework in PHP probably isn't continuation-based, it probably doesn't compile your s-expression HTML tree into assembler code before rendering it.  </p>
<p>But PHP is probably the most powerful language around for many jobs if you judge by the one and only measure that counts for many people: wall clock time from "Here, do this" to "Yay, I'm done, it's not the prettiest thing in the world but it works".</p>
<p>The above situation was one I experienced at work, and I did choose PHP right from the start, and I did get it done quickly, and it was apparently not too bad because everyone likes the website.  No one witnessed the pain of writing all that PHP code, but that pain doesn't matter to anyone but the code monkey.</p>
<p>If I had to do it over again I might pick Ruby, but certainly never Lisp.  I hate PHP more than almost anything (maybe with the exception of Java) but I still use it when it's called for.  An old rusty wobbly-headed crooked-handled hammer is the best tool for the job if it's right next to you and you only need to pound in a couple of nails.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/09/22/practicality-php-vs-lisp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Copy/paste in Linux: Eureka</title>
		<link>http://briancarper.net/2008/09/16/copypaste-in-linux-eureka/</link>
		<comments>http://briancarper.net/2008/09/16/copypaste-in-linux-eureka/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 01:42:53 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Vim]]></category>

		<category><![CDATA[Windows sucks]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/09/16/copypaste-in-linux-eureka/</guid>
		<description><![CDATA[It's been a few years since I officially grasped Linux's (well, X Windows') weird concept of copying and pasting, with its multiple discrete copy/paste methods: the highlight + middle click version, and "clipboard" Edit->Copy" + "Edit->Paste version.
But once in a blue moon, copying and pasting in X still surprises me.  Try this:

Open Firefox and [...]]]></description>
			<content:encoded><![CDATA[<p>It's been a few years since I officially grasped Linux's (well, X Windows') weird concept of copying and pasting, with its multiple discrete copy/paste methods: the highlight + middle click version, and "clipboard" Edit->Copy" + "Edit->Paste version.</p>
<p>But once in a blue moon, copying and pasting in X still surprises me.  Try this:</p>
<ol>
<li>Open Firefox and a text editor.  I'm trying with Vim.</li>
<li>Highlight some text in Firefox.</li>
<li>Middle-click paste it into the editor.  The highlighted text is pasted, as expected.</li>
<li>Close Firefox.</li>
<li>Middle-click into the editor again.</li>
</ol>
<p>Can you guess what happens at the end?  If you said "Some random text from another application and/or nothing at all is pasted rather than the stuff from Firefox", you're right!</p>
<p>But today I read <a href="http://www.jwz.org/doc/x-cut-and-paste.html">this article</a> on jwz.org and finally understood how copy/paste works in X.  Highlighting text doesn't copy anything, it just announces to the world "If any applications want to middle-click paste something, come ask me for it".  So if you close the application you wanted to paste text from before you actually do the pasting, the application isn't around to give you the text you wanted any more, so you can't get it.  The Edit->Copy / Edit->Paste version of copy/paste behaves the same way.  You can't "Copy", close app, "Paste".</p>
<p>Note, this is different from how MS Windows works.  When you copy some text in Windows it really copies to another location.  You can close the app and still paste away.  But Windows has a different (inconsistent) behavior when copy/pasting files in Explorer.  There, it behaves like X in Linux: if right click a file and "Copy", it doesn't actually do anything with the data until you paste.  If you right-click, "Copy", delete the file, "Paste", you don't get an error until you try to Paste. </p>
<p>In Vim in Linux, the <strong>"*</strong> register lets you access the "primary selection" (highlight / middle click selection), and the <strong>"+</strong> register lets you access the clipboard.  </p>
<p>In Vim in Windows, <strong>"*</strong> and <strong>"+</strong> do the same thing, and use the clipboard.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/09/16/copypaste-in-linux-eureka/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Westinghouse: Finally getting somewhere?</title>
		<link>http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/</link>
		<comments>http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 00:43:15 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Westinghouse]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/</guid>
		<description><![CDATA[I finally got not one, but two phone calls from Westinghouse today, inquiring as to the status of my Better Business Bureau complaint against their company.  This is of course in connection with the big expensive L2410NM computer monitor I sent off for repairs in March and never got back.  
I actually have [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got not one, but two phone calls from Westinghouse today, inquiring as to the status of my <a href="http://briancarper.net/2008/08/14/westinghouse-bbb-rating-cc-and-falling/">Better Business Bureau complaint against their company</a>.  This is of course in connection with the big expensive L2410NM computer monitor I sent off for repairs in March and never got back.  </p>
<p>I actually have three different people's names to get in contact with at Westinghouse now, two or more of which are apparently supervisors.  After I returned one call and was told all the supervisors went home for the day, I then received an unprecedented second call back from a different supervisor, saying she was on her way out the door but that I should call her tomorrow, and she gave me a direct line to contact her.</p>
<p>Some supervisors must be rooting through old BBB complaints and responding to them all, would be my guess.  A phone rep let slip that there's someone working on "all of these cases... er, I mean, your case".  The LA BBB still lists <a href="http://www.labbb.org/BBBWeb/Forms/Business/CompanyReportPage_Expository.aspx?CompanyID=100038066">69 unanswered complaints</a> against Westinghouse, so I'm sure there's plenty of work to go around.</p>
<p>After six months of bullcrap, I can't get my hopes up at this point that I'm going to actually have this resolved but hey, you never know.  In spite of my 21 phone calls to Westinghouse (and counting) and many promises of a return call, this is the FIRST TIME I've ever heard from anyone at the company.  I'll be posting the result of my phone call tomorrow.</p>
<p>(Read the whole crappy story of Westinghouse's dishonesty and horrible customer service: <a href="http://briancarper.net/2008/03/15/westinghouse-do-they-suck/">The beginning</a>, <a href="http://briancarper.net/2008/03/22/blah-blah-blah/">Update 1</a>, <a href="http://briancarper.net/2008/04/08/westinghouse-closer-to-sucking-every-day/">Update 2</a>, <a href="http://briancarper.net/2008/04/14/westinghouse-the-saga-continues/">Update 3</a>, <a href="http://briancarper.net/2008/05/05/westinghouse-fail/">Update 4</a>, <a href="http://briancarper.net/2008/06/10/westinghouse-still-sucks/">Update 5</a>, <a href="http://briancarper.net/2008/06/16/westinghouse-the-saga-continues-2/">Update 6</a>, <a href="http://briancarper.net/2008/08/14/westinghouse-bbb-rating-cc-and-falling/">Update 7</a>, <a href="http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/">Update 8</a>, <a href="http://briancarper.net/2008/09/24/westinghouse-it-never-ends/">Update 9</a>, <a href="http://briancarper.net/2008/10/04/westingouse-victory/">VICTORY</a>, <a href="http://briancarper.net/2008/10/27/westinghouse-behind-the-scenes-the-horrors-of-a-call-center/">aftermath</a>.)</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/09/09/westinghouse-finally-getting-somewhere/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Perl6 features borrowed from Lisp</title>
		<link>http://briancarper.net/2008/09/09/perl6-features-borrowed-from-lisp/</link>
		<comments>http://briancarper.net/2008/09/09/perl6-features-borrowed-from-lisp/#comments</comments>
		<pubDate>Tue, 09 Sep 2008 23:28:57 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Lisp]]></category>

		<category><![CDATA[Perl]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/09/09/perl6-features-borrowed-from-lisp/</guid>
		<description><![CDATA[Via PerlMonks I found a couple of articles discussing in good detail some of the new features of Perl6.  
Perl6 steals even more things from Common Lisp than Perl5 did: it has multimethods / multiple dispatch for example, which is a huge plus.  Via this interview with Damian Conway we learn that Perl6 [...]]]></description>
			<content:encoded><![CDATA[<p>Via PerlMonks I found a <a href="http://www.dlugosz.com/Perl6/index.html">couple of articles</a> discussing in good detail some of the new features of Perl6.  </p>
<p>Perl6 steals even more things from Common Lisp than Perl5 did: it has multimethods / multiple dispatch for example, which is a huge plus.  Via <a href="http://fyi.oreilly.com/2008/08/the-mind-of-damian-conway-scie.html">this interview with Damian Conway</a> we learn that Perl6 will also have named, optional, and "rest" parameters to subs, just like in CL.  That's also a good thing; CL's parameter-passing styles are nice, and it's awesome how you can combine them.  Certainly better than Perl5 (but everything is better than Perl5).  There's also apparently special Perl6 syntax for applying functions to lists and currying functions, and weird Capture objects to explicitly deal with multiple-value returns from subs.  Good stuff.</p>
<p>Perl6 is also apparently taking first-class functional objects to an extreme; blocks, subs, and methods are all objects and there are all kinds of metaprogramming hooks to screw around with them.  This is one area where Ruby is just a little bit lacking: functions and methods aren't <em>quite</em> first-class enough in Ruby.  Most people seem to pass around symbols / names of methods rather than pass around methods as objects themslves.  Anonymous blocks are used liberally but mostly via <strong>yield</strong>, limiting you to one block per method and largely hiding away the block objects themselves.</p>
<p>I'm honestly a bit excited about Perl6, but largely as a curiosity or new toy to play with.  It is kind of interesting how languages keep creeping more and more toward Common Lisp.  If Perl is a nicer-looking Common Lisp which I can edit properly in Vim, it'll be almost a dream come true; I hate Emacs and Common Lisp tends to be butt-ugly.  (Not talking about the parens, mostly about the verbosity and cruft and inconsistencies.  Larry Wall famously said that Common Lisp looks like (paraphrased) "oatmeal with toenail clippings mixed in".  Perl is certainly at the other extreme.)</p>
<p><a href="http://rakudo.org/">http://rakudo.org/</a> is a good site for keeping up on Perl6 news.  It's pretty active.  Here's hoping we see a real release of Perl6 someyear.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/09/09/perl6-features-borrowed-from-lisp/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Vim + screen + REPL = win</title>
		<link>http://briancarper.net/2008/09/06/vim-screen-repl-win/</link>
		<comments>http://briancarper.net/2008/09/06/vim-screen-repl-win/#comments</comments>
		<pubDate>Sat, 06 Sep 2008 08:36:48 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Emacs]]></category>

		<category><![CDATA[Lisp]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://briancarper.net/2008/09/06/vim-screen-repl-win/</guid>
		<description><![CDATA[Via the Clojure wiki I found a great page describing how you can use GNU screen and some Vim magic to let Vim play nicely with an interactive commandline program like a Common Lisp REPL, Ruby's irb, or Python's, well, python.
That page is a very stripped-down and simpler version of what Limp does for Vim+Lisp. [...]]]></description>
			<content:encoded><![CDATA[<p>Via the <a href="http://en.wikibooks.org/wiki/Clojure_Programming">Clojure wiki</a> I found a <a href="http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/">great page</a> describing how you can use GNU screen and some Vim magic to let Vim play nicely with an interactive commandline program like a Common Lisp REPL, Ruby's <strong>irb</strong>, or Python's, well, <strong>python</strong>.</p>
<p>That page is a very stripped-down and simpler version of what <a href="http://mikael.jansson.be/hacking/limp">Limp</a> does for Vim+Lisp.  But Jonathan Palardy's version has the benefit of being so simple that you can set it up yourself manually in a second or two.  I still have never gotten Limp to work quite right and I don't have the time to debug a big mess of Vim script.</p>
<p>The idea is to start up a named screen session via e.g. <strong>screen -S foo -t bar</strong>, then start an irb session (or whatever) in there, and then in Vim you can simply yank some text into a named register and send it off to screen via a system call.  Download <a href="http://s3.amazonaws.com/mps/slime.vim">Jonathan's code</a> and see.</p>
<p>It's not a full-blown SLIME; it doesn't have tab-completion or weird interactive debugging windows or such bullcrap.  It doesn't capture the output of your command and feed it back into your Vim buffer.  But hey, it's pretty good for something you can throw together in 2 minutes, and it works.</p>
<p>So there goes my last reason to ever use Emacs.  Good riddance, I must say.  </p>
<p>Honestly, Emacs just frustrates the living hell out of me.  Oh how I tried to like it.  I really did.  I've used it on and off constantly over the past year.  I have Emacs shortcuts written all over the whiteboard in my office.  But its braindead window management, its terrible broken undo/redo system, its finger-crippling key-chord combos, its lack of features I need (like line numbering), its reliance on broken 3rd-party elisp hack scripts for things Vim has built in (like line numbering!), its ugly fonts and GUI elements, and so on and so forth.  Vim is such a joy in comparison.</p>
]]></content:encoded>
			<wfw:commentRss>http://briancarper.net/2008/09/06/vim-screen-repl-win/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
