<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc=" http://purl.org/dc/elements/1.1/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>briancarper.net (λ) (Tag: Perl)</title><link>http://briancarper.net/tag/61/perl</link><description>Some guy's blog about programming and Linux and cows.</description><item><title>Let's parse</title><link>http://briancarper.net/blog/lets-parse</link><guid>http://briancarper.net/blog/lets-parse</guid><pubDate>Tue, 15 Dec 2009 20:46:07 -0800</pubDate><description>&lt;p&gt;Is there anything more fun than parsing strings?  I submit to you that there is not.  I'm currently reading my way through &lt;em&gt;&lt;a href=&quot;http://www.cs.vu.nl/~dick/PTAPG.html&quot;&gt;Parsing Techniques - A Practical Guide&lt;/a&gt;&lt;/em&gt;, which has a first edition free online.  (I'm hoping Santa brings me a copy of the 2nd edition this year.)  &lt;/p&gt;

&lt;p&gt;This is a good book, with enough math to be rigorous but not so much that it's completely unreadable.  It starts from the absolute basics (&quot;What's a grammar?&quot;) and goes through the Chomsky hierarchy and then dives into parsing techniques in great detail, in a language-agnostic way.&lt;/p&gt;

&lt;p&gt;Languages and grammars are fascinating.  In high school I studied Spanish, French, Latin and German, largely in my spare time.  When I was 16, if people asked what I wanted to do for a living, I said &quot;translator&quot;.  &lt;/p&gt;

&lt;p&gt;The plan to become a translator failed partly because the quality of my early education was horrendous and partly because mastering a language is extremely difficult and at 16 I wasn't motived enough.  And then computers showed up in my life, which gave me a never-ending supply of languages to play with, while being fun (and profitable) in so many other ways.  But I still took two years of Japanese classes in college for no reason other than enjoyment, and I'm still trying (and failing) to learn Japanese in my spare time 8 years later.&lt;/p&gt;

&lt;p&gt;Perl was my first favorite language probably for no reason other than regular expressions.  I can understand how people call PCRE syntax line-noise, but to me it's beautiful line noise.  I live and breathe regular expressions nowadays.  My favorite CS class in college was one where we went through and laboriously built finite-state automata and pushdown automata and Turing machines.  Seeing the equivalence of these simple machines with the different classes of grammars was a huge epiphany.  Such a simple concept with such huge consequences.&lt;/p&gt;

&lt;p&gt;Dijkstra said:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Besides a mathematical inclination, an exceptionally good mastery of one's native tongue is the most vital asset of a competent programmer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I strongly agree with that sentiment.  People tell me at times that I'm good at written communication.  I have my doubts, and anyways I find it funny because I'm so terrible at verbal communication.  I think if I have any success at writing, it's because I view writing as a mechanical process.  &lt;/p&gt;

&lt;p&gt;I told a prof in college once that I felt like my papers wrote themselves once I had an idea in mind.  There are rules of grammar and style, and you learn them and follow them, or break them deliberately if you have a good reason to.  You write some prose, then you debug it until it &quot;works&quot; mentally.  I don't care about typos and I split infinitives and comma-splice on purpose, but ambiguous or awkward phrases usually stand out to me like compiler bugs in my brain.&lt;/p&gt;

&lt;p&gt;What's more important than language?  Few things.  Language is important enough to be nearly hard-wired into our brains.  Children learn it instinctively.  Human beings can still easily and effortlessly out-perform the best supercomputer at the task of parsing and interpreting speech.  We &lt;em&gt;think&lt;/em&gt; in words.  The programming languages computers understand are dirt-simple by comparison, but writing code still feels like writing &quot;thoughts for the computer&quot; sometimes.&lt;/p&gt;

&lt;p&gt;There are very few times you'll hear me say &quot;What a wonderful world we live in&quot;.  But one of those times is when I have the opportunity to explore an area of study like language.  It's such an enjoyable experience to struggle and try to master such a thing.  It's an amazing universe where we have these weird little rules and they &lt;em&gt;work&lt;/em&gt; and we can understand them and manipulate them and produce things with them.&lt;/p&gt;</description></item><item><title>Markdown</title><link>http://briancarper.net/blog/markdown</link><guid>http://briancarper.net/blog/markdown</guid><pubDate>Sat, 31 Jan 2009 11:27:19 -0800</pubDate><description>&lt;p&gt;How do you write a parser in a functional language like Clojure?  (That's a rhetorical question.)  There are parser libraries for Haskell I could use as reference but they're still a bit over my head at this point.&lt;/p&gt;

&lt;p&gt;The original &lt;a href=&quot;http://daringfireball.net/projects/markdown/&quot;&gt;Markdown.pl&lt;/a&gt; parser in Perl uses global hashes and regex-mangles strings directly.  I could actually duplicate this exactly in Clojure, because Clojure isn't purely functional.  But I'm trying to do it in a more functional way, and so far it's working out OK.&lt;/p&gt;

&lt;p&gt;One of the bad things about Markdown is that perhaps because it's originally implemented in Perl as a bunch of regex-replacements on a string, and not as a real parser with a proper grammar, all of the implementations of Markdown in various other languages give slightly different results.  So much so that someone wrote a &lt;a href=&quot;http://babelmark.bobtfish.net&quot;&gt;website&lt;/a&gt; just to compare different implementations of Markdown against each other.  So now writing a parser in Clojure, I face the difficulty of which behavior I want to duplicate.  Some things Markdown does less than ideal, but I think I have to err on the side of replicating the original.  One implementation, Pandoc, claims to be &lt;a href=&quot;http://code.google.com/p/pandoc/wiki/PandocVsMarkdownPl&quot;&gt;&quot;more accurate&quot;&lt;/a&gt; than Markdown.pl, but Pandoc seems to purposefully break from things that are laid out explicitly in the specification, which is bad.&lt;/p&gt;</description></item><item><title>Perl6 features borrowed from Lisp</title><link>http://briancarper.net/blog/perl6-features-borrowed-from-lisp</link><guid>http://briancarper.net/blog/perl6-features-borrowed-from-lisp</guid><pubDate>Tue, 09 Sep 2008 15:28:57 -0700</pubDate><description>&lt;p&gt;Via PerlMonks I found a &lt;a href=&quot;http://www.dlugosz.com/Perl6/index.html&quot;&gt;couple of articles&lt;/a&gt; discussing in good detail some of the new features of Perl6.  &lt;/p&gt;

&lt;p&gt;Perl6 steals even more things from Common Lisp than Perl5 did: it has multimethods / multiple dispatch for example, which is a huge plus.  Via &lt;a href=&quot;http://fyi.oreilly.com/2008/08/the-mind-of-damian-conway-scie.html&quot;&gt;this interview with Damian Conway&lt;/a&gt; we learn that Perl6 will also have named, optional, and &quot;rest&quot; 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.&lt;/p&gt;

&lt;p&gt;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 &lt;em&gt;quite&lt;/em&gt; 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 &lt;code&gt;yield&lt;/code&gt;, limiting you to one block per method and largely hiding away the block objects themselves.&lt;/p&gt;

&lt;p&gt;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) &quot;oatmeal with toenail clippings mixed in&quot;.  Perl is certainly at the other extreme.)&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://rakudo.org/&quot;&gt;http://rakudo.org/&lt;/a&gt; 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.&lt;/p&gt;</description></item><item><title>Wish list</title><link>http://briancarper.net/blog/wish-list</link><guid>http://briancarper.net/blog/wish-list</guid><pubDate>Tue, 17 Jun 2008 23:47:43 -0700</pubDate><description>&lt;p&gt;What's the Common Lisp version of &lt;a href=&quot;http://perlmonks.org&quot;&gt;Perlmonks&lt;/a&gt; or &lt;a href=&quot;http://ruby-forum.org&quot;&gt;Ruby-forum&lt;/a&gt;?  I have yet to find it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://groups.google.com/group/comp.lang.lisp/topics&quot;&gt;comp.lang.lisp&lt;/a&gt; is largely crap.  50% of the traffic on that list is spam about shoes and fake watches.  The other half is equally split between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;People debating tiny, silly semantic points of the &lt;a href=&quot;http://www.lispworks.com/documentation/common-lisp.html&quot;&gt;Common Lisp Hyperspec.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;People stuck in the 70's or 80's, talking about the good old days, ruminating about Lisp history.&lt;/li&gt;
&lt;li&gt;Flame wars.&lt;/li&gt;
&lt;li&gt;New people asking for help.  Some get good honest advice and helpful answers, many are flamed and ridiculed into next week if they even hint that they &lt;a href=&quot;http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/171fee6be225c833#&quot;&gt;dislike the parentheses&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Common Lisp community (if you can call it that) is a bunch of really smart guys, but they all live isolated in hermit shacks up in the mountains and they spend their time doing magic tricks with Lisp that few people ever see, and if you wander too close they throw rocks at you.&lt;/p&gt;

&lt;p&gt;What's the Common Lisp equivalent of &lt;code&gt;perldoc&lt;/code&gt; or &lt;code&gt;rdoc&lt;/code&gt;?  We have the Hyperspec.  It's an impressive document, but it's a bunch of painful HTML that looks like it was created in the early 90's, probably because it was.  It reads like a dusty, dry, technical document probably because it is.  What it's not, is friendly or easily readable.&lt;/p&gt;

&lt;p&gt;Perl has CPAN, Ruby has rubygems, what does Lisp have?  Either a hand-rolled system definition script, or if you're lucky an ASDF install file.  ASDF is the semi-standard Lisp way of installing libraries, except that it doesn't quite work in Windows, it doesn't check dependencies or handle different versions of a package very well, and it doesn't work the same on all Lisp implementations.  Many people in the so-called community think it's not very good. &lt;/p&gt;

&lt;p&gt;The fellow running &lt;a href=&quot;http://www.lispcast.com/drupal/node/29&quot;&gt;Lispcast&lt;/a&gt; makes another good point.  Where can you download Lisp?  It's not obvious.&lt;/p&gt;

&lt;p&gt;You could say &quot;OK Brian, good idea, now get to work!&quot;  The problem is that even if I had the time or willpower, I'm not the smartest guy in the world.  I honestly don't think I could design and run and maintain a CPAN.  And even if I did, would anyone use it?  But I do know that there ARE plenty of smart, enthusiastic people using Lisp.  Yet high-quality friendly code is largely not being produced.&lt;/p&gt;

&lt;p&gt;Peter Christensen wrote about &quot;&lt;a href=&quot;http://www.pchristensen.com/blog/articles/hey-language-snobs-dont-pinch-pennies/&quot;&gt;langauge snobs&lt;/a&gt;&quot; and the importance of community.  One point made is that some really ugly, horrific languages have been extremely successful simply because they've been accessible and fun.  An example given is the scripting language in Second Life, which has over 2.5 billion lines of code written in by tens of thousands of amateurs and has accurately modeled a realistic 3D environment with thousands of users at any given time.  All in an ugly language some guy invented AND implemented in one week.  The developers admit that the language is total crap, but it doesn't matter.  1) It has very good and accessible documentation, 2) it has a very newbie-friendly community, and 3) and it's easy to pick up, throw together some code and get immediate results.  Three things Common Lisp lacks.&lt;/p&gt;

&lt;p&gt;This is something I've said &lt;a href=&quot;http://briancarper.net/2008/04/07/perl-6/&quot;&gt;myself&lt;/a&gt; many times: an active, supportive, enthusiastic community is essential for the health of any programming language.  Common Lisp simply doesn't have one and it's a shame.&lt;/p&gt;

&lt;p&gt;I still secretly hope that &lt;a href=&quot;http://clojure.org/&quot;&gt;Clojure&lt;/a&gt; or &lt;a href=&quot;http://www.newlisp.org/&quot;&gt;NewLisp&lt;/a&gt; or &lt;a href=&quot;http://www.paulgraham.com/arc.html&quot;&gt;Arc&lt;/a&gt; turn out to be a huge success.  They are the kinds of things Lisp needs today.&lt;/p&gt;</description></item><item><title>Perl 6</title><link>http://briancarper.net/blog/perl-6</link><guid>http://briancarper.net/blog/perl-6</guid><pubDate>Mon, 07 Apr 2008 23:14:25 -0700</pubDate><description>&lt;p&gt;I found this &lt;a href=&quot;http://www.perlfoundation.org/perl6/index.cgi?when_will_perl_6_be_released&quot;&gt;Perl6 imaginary timeline&lt;/a&gt; hilarious.  Sadly we're in 2008 and I don't think that blue line is quite as high as it was projected to be.  Though it appears that development is still slowly chugging along.  I still check up on Perl 6 once every six months or so. You can actually download perl6 (called &lt;a href=&quot;http://www.perlfoundation.org/perl6/index.cgi?rakudo&quot;&gt;rakudo?&lt;/a&gt;) and run it nowadays.&lt;/p&gt;

&lt;p&gt;It's been a long time since I've used Perl for anything.  If Perl 6 ever sees the light of day in a big way, I'm sure I will hunt down the Perl 6 bandwagon and chain myself to the back of it.  Perl was my first religion.&lt;/p&gt;

&lt;p&gt;I don't want to consider myself fickle, rather curious and eager to try and learn new things.  But honestly, fickle may be closer to the truth.  Already my Lisp enthusiasm is starting to wear off, largely from the impracticality of writing anything in Lisp (&lt;a href=&quot;http://www.gigamonkeys.com/book/&quot;&gt;in spite of good book titles to the contrary&lt;/a&gt;).  I've written a bunch of things in the past few months, but I never even considered Common Lisp for any of them.  Mostly because I was being paid to write them, and I don't think people want to pay me to screw around with something that's going to take me 10x as long as using a language I know already.&lt;/p&gt;

&lt;p&gt;I believe the main way I came to know and love Perl and later Ruby was through all the little 5-minute throwaway scripts I wrote to get my job(s) done.  Those little scripts led to bigger scripts, which led to even bigger scripts.  Emotionally it's satisfying to actually solve a problem in a language, even a small problem.  Not so easy to do in Lisp; it doesn't seem to lend itself well to scripting.  Lisp is nice if you've come up with the perfect abstraction for your program and want to implement it exactly like you're thinking of it.  Most of the time, by the time I think up the perfect abstraction, I'd already be done if I'd written it in straightforward Ruby to begin with.  &lt;/p&gt;

&lt;p&gt;And, to rant briefly, in Ruby I wouldn't have to write my own function to fetch all the keys of a hash, or print a formatted date string, or any of the other countless little holes in Lisp that are nicely filled in Ruby by all the available libraries.  I've said it before and I'll say it again: a large active community is one of the biggest necessities for a healthy programming langauge.  It really doesn't seem like many people in the Lisp community give a crap about getting lots of new people to use Lisp.  Or if so, I never hear much about it, compared with other communities.  There's no reason a language can't be really great and powerful, and still accessible to the masses.  That's one of Ruby's strengths.  You don't have to read a few hundred pages of &lt;a href=&quot;http://www.lisp.org/HyperSpec/FrontMatter/index.html&quot;&gt;hyperspec&lt;/a&gt; and learn 50 years of history and spend a week and half setting up an arcane SLIME/Emacs environment to start writing Ruby.&lt;/p&gt;

&lt;p&gt;But yeah, Perl 6.  I want it to succeed, for entirely emotional reasons.  I want a new toy.&lt;/p&gt;</description></item><item><title>Lisp ramblings</title><link>http://briancarper.net/blog/lisp-ramblings</link><guid>http://briancarper.net/blog/lisp-ramblings</guid><pubDate>Fri, 15 Feb 2008 00:09:06 -0800</pubDate><description>&lt;p&gt;Two posts in one, just because I can.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Rambling #1&lt;/code&gt;: One thing that makes a language like Ruby easy to read is that &lt;code&gt;foo.bar&lt;/code&gt; always has the same meaning: &lt;code&gt;object.method&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In Common Lisp you don't have that.  One of CL's strengths is that everything looks the same, it's all s-expressions.  However a cost of this is that you can't tell just by looking whether &lt;code&gt;(foo bar)&lt;/code&gt; is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A special operator foo, that does something with bar (maybe assigning it a value, maybe conditionally evaluating it, who knows).&lt;/li&gt;
&lt;li&gt;A system-defined function call foo, where bar is evaluated and the result is passed in as an argument, and which you can't redefine because it's in the &lt;code&gt;COMMON-LISP&lt;/code&gt; system package.&lt;/li&gt;
&lt;li&gt;A user-defined function call foo, where bar is evaluated and the result is passed in as an argument, and which you can re-define if you want.&lt;/li&gt;
&lt;li&gt;A method call foo, where bar is possibly an object used to dispatch the method call (or maybe not).&lt;/li&gt;
&lt;li&gt;A macro foo, which can produce code that does practically anything, or nothing at all, with bar.&lt;/li&gt;
&lt;li&gt;Other?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Along the same lines, even if you know for sure that &lt;code&gt;(foo bar baz)&lt;/code&gt; is a
method call, you can't tell by looking whether bar, or baz, or both, are
objects which determine how the method call is dispatched.  You have to look
it up in documentation or inspect the method somehow.  As far as I know.
(&lt;strong&gt;EDIT: &lt;a href=&quot;http://www.pchristensen.com/blog/articles/public-beta-open-for-ultimate-n00b-slimeemacs-cheat-sheet/&quot;&gt;Slime&lt;/a&gt; has lots of tools for doing this kind of inspection., as was pointed out to me by Ivar.&lt;/strong&gt;)&lt;/p&gt;

&lt;p&gt;This is a good feature of Common Lisp, in terms of flexibility and power; multimethods are great, the consistency and lack of syntax and precedence is great in many ways.  But it can be a bad thing in terms of easy readability.  It's a bit of a tradeoff. &lt;/p&gt;

&lt;p&gt;Ruby code like &lt;code&gt;arr.reverse.sort.join(',')&lt;/code&gt; just flows right along.  And it's highly predictable.  I know &lt;code&gt;reverse&lt;/code&gt; is a method call, and it's defined in whatever class &lt;code&gt;arr&lt;/code&gt; is an instance of (or a mixin of that class, or a meta-class I guess), and it returns something that has a &lt;code&gt;sort&lt;/code&gt; method.  And I can redefine any of those things.&lt;/p&gt;

&lt;p&gt;Common Lisp non-working pseudo-code: &lt;code&gt;(join (sort (reverse arr)) &quot;,&quot;)&lt;/code&gt;.  Not as much fun to read, and oops, in this case &lt;code&gt;SORT&lt;/code&gt; is a system-defined standard function, so if I want to write this I'll have to go with &lt;code&gt;MY-SORT&lt;/code&gt; or &lt;code&gt;SORT2&lt;/code&gt; to avoid collisions (which you see a lot of in Lisp examples and literature).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Rambling #2&lt;/code&gt;: Way back in 2006, I decided to learn Common Lisp because I'd heard such nice things about it.  I ended up abandoning that project very quickly (only to try again late in 2007, and stick with it this time).  One reason (among many many others) that I gave up was the fact that it took me a good hour or two even to figure out how/where to download and install Common Lisp.&lt;/p&gt;

&lt;p&gt;I remember going to a terminal and searching the Portage tree for packages matching the name &quot;common lisp&quot;.  Zero results.  OK, how about just &quot;lisp&quot;.  One result I got back was &lt;code&gt;clisp&lt;/code&gt;, which at that time, based on the name, I assumed was &quot;just another name for the Common Lisp interpreter&quot;.  However a search of the Gentoo forums revealed that a lot of people were using SBCL, or CMUCL, or many others.  And those things were &quot;Common Lisp&quot; too?  How confusing.&lt;/p&gt;

&lt;p&gt;Little did I know that there is no THE Common Lisp.  There are a bunch of implementations of the Common Lisp standard (or varying parts of the standard).  To a newbie, this is somewhat confusing.  Which one should you pick?  What the heck is the difference?  If it's a standard, does it even matter which you pick?  So before you can even start writing code, you get to treat yourself to a history lesson to learn why there are all these different implementations, and then go on a fact-finding mission to try to find an implementation that's right for you.&lt;/p&gt;

&lt;p&gt;It wouldn't matter, if the standard was complete enough that it covered all of what you'd want to do.  But the standard is old, and arguably out-of-date.  And it doesn't cover things like threads, sockets, POSIX utilities, etc. that you're really likely to use.  And if something isn't in the standard, you can bet good money that every implementation does that thing in its own way, or not at all.  A lot of sufficiently complex code in Common Lisp will demand that you go to great lengths to get it to run on different implementations, judging by some of the library code I've read.  &lt;/p&gt;

&lt;p&gt;Consider &lt;a href=&quot;http://www.weitz.de/cl-fad/&quot;&gt;CL-FAD&lt;/a&gt;.  A function &lt;code&gt;DELETE-DIRECTORY-AND-FILES&lt;/code&gt; is used to (you guessed it) recursively delete a directory and its files.  Here are the guts of that function:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(cond ((directory-pathname-p file)
      #+:lispworks (lw:delete-directory file)
      #+:cmu (multiple-value-bind (ok err-number)
                 (unix:unix-rmdir (namestring (truename file)))
               (unless ok
                 (error &quot;Error number ~A when trying to delete ~A&quot;
                        err-number file)))
      #+:scl (multiple-value-bind (ok errno)
                 (unix:unix-rmdir (ext:unix-namestring (truename file)))
               (unless ok
                 (error &quot;~@&amp;lt;Error deleting ~S: ~A~@:&amp;gt;&quot;
                        file (unix:get-unix-error-msg errno))))
      #+:sbcl (sb-posix:rmdir file)
      #+:clisp (ext:delete-dir file)
      #+:openmcl (ccl:delete-directory file)
      #+:cormanlisp (win32:delete-directory file)
      #+:ecl (si:rmdir file)
      #+(or :abcl :digitool) (delete-file file))
     (t (delete-file file)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What's going on there?  All those &lt;code&gt;#+&lt;/code&gt; and &lt;code&gt;#-&lt;/code&gt; lines are kind of like the Common Lisp equivalent of C preprocessor macros.  #+ and #- hide (or include) a line of code from the view of the compiler, depending on which implementation you're using.  Ugh.&lt;/p&gt;

&lt;p&gt;So in this case, you have what is a pretty simple function (1-5 lines of code, in each implementation), but you get to have the fun of writing it TEN TIMES, all woven together like spaghetti.  There are many other such &lt;a href=&quot;http://www.cliki.net/compatibility%20layers&quot;&gt;compatibility layers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Kudos to people who go to the effort of writing portable code like this, but I don't see why it should be necessary.  This strikes me as a senseless and wasteful duplication of effort.    Not just on the part of the people writing code to run on all these implementations, but also on the part of the people working on the implementations themselves. Why not join forces and make one big mature official Common Lisp for everyone to use?  What benefit is there to having so many implementations?  Does the benefit outweigh the amount of work someone has to do to write portable code to share with the community?  Maybe there's a good reason for it that I'm not aware of.  But it seems to me like it defeats the purpose of having a standard in the first place.&lt;/p&gt;

&lt;p&gt;On the other hand if I want to write some Perl, I do an &lt;code&gt;emerge perl&lt;/code&gt; (substituting your package manager of choice) and then I have Perl.  The same exact Perl (barring version differences, and slight differences between Perls on different OSes) that every other Perler in the world has.  If I write a Perl script, any other person with Perl could reasonably expect to be able to run it.  Same with PHP, Python, Ruby, and many other languages.  (People are working on separate interpreters for Ruby, e.g. &lt;a href=&quot;http://jruby.codehaus.org/&quot;&gt;JRuby&lt;/a&gt; but from what I know, they're going to great lengths to make it run EXACTLY like the &quot;official&quot; Ruby, even down to copying bugs to maintain compatibility.)&lt;/p&gt;

&lt;p&gt;I know now that there are things like &lt;a href=&quot;http://common-lisp.net/project/lispbox/&quot;&gt;Lisp in a Box&lt;/a&gt; that give you an easily-installable Common Lisp environment.  Which is really nice for learning purposes.  I wish I'd have found it back in 2006 (if it existed at that time).  But it only delays the mess you're going to have to handle someday if you want to write portable code, or if you want to use anything other than CLISP or Allegro.&lt;/p&gt;

&lt;p&gt;I have an urge to start porting some of my favorite Ruby gems to Common Lisp.  But I am not going to install 10 CL implementations just so I can re-write my code 10 times to get it working on all the Lisps in the world.  Very likely my code would be ruthlessly SBCL-specific.&lt;/p&gt;

&lt;p&gt;(This is one reason I'm kind of hoping &lt;a href=&quot;http://arclanguage.com&quot;&gt;Arc&lt;/a&gt; takes off.  Hopefully there would only be one Arc implementation.)&lt;/p&gt;</description></item><item><title>PAIP, review one of probably many</title><link>http://briancarper.net/blog/paip-review-one-of-probably-many</link><guid>http://briancarper.net/blog/paip-review-one-of-probably-many</guid><pubDate>Wed, 06 Feb 2008 01:12:18 -0800</pubDate><description>&lt;p&gt;I got through the first four chapters of &lt;a href=&quot;http://norvig.com/paip.html&quot;&gt;PAIP&lt;/a&gt; yesterday and today.  It's good so far.  I had reservations about spending $80 on a book, but it's 950 pages and almost all of it is good stuff, from what I can see at a glance.  Little space is wasted on introduction material or tutorials for people who know nothing about programming.  He dives right into the good stuff in chapter four.&lt;/p&gt;

&lt;p&gt;Already I've picked up a few nice bits of info, interesting standard functions / macros like &lt;code&gt;TRACE&lt;/code&gt; which is good for debugging.  And &lt;code&gt;SUBLIS&lt;/code&gt; which takes a list of (key . value) sublists and replaces all the keys with all the values, in some other list.  Common Lisp is such a freaking huge language, in terms of its standard library of functions.  Good thing or bad thing?  It may be a bad thing if not for the fact that you load Lisp once and it persists forever.&lt;/p&gt;

&lt;p&gt;Norvig makes an interesting point about the REPL.  What do most programs need to do?  Take input from the user, do something with it, and give output back to the user.  &lt;/p&gt;

&lt;p&gt;To get input, your program can read from command-line args, or prompt to STDIN, or take it out of text fields in a QT app, or read it from a config file.  But it's generally always strings.  So you get some strings, and then what?  You have to figure out what the strings say, and either turn the strings into something usable or use the strings to figure out what action to perform.  So you may have a dedicated library to parse command-line args and a dispatch table to map them to function calls.  Or you may match the strings against a regex and depending what the strings look like, turn them into your language's representation of an integer or float using some &quot;parseInt&quot; or &quot;parseFloat&quot; functions.  Or if your strings are XML, you may parse them into some big funky XML structure, then access bits of that structure to figure out what to do.&lt;/p&gt;

&lt;p&gt;In Lisp on the other hand, you happen already to have a powerful reader/parser at your disposal: the REPL itself.  It already knows how to read string representations of lists, numbers, pathnames, and many other things, and it can turn them into Lisp objects for you with no effort on your part.  If you were using Ruby or Perl, short of &lt;del&gt;evil&lt;/del&gt; &lt;code&gt;eval&lt;/code&gt;, you wouldn't get anything close to that capability in your program.&lt;/p&gt;

&lt;p&gt;What's more, the REPL knows how to read string representations of Lisp code (new functions and function calls etc.), and evaluate the code and end up with Lisp objects.  It would be like if you wrote a C program which prompted you for input, and the input you gave could be a string representing a new C program that when run would produce a string that contained your input (or produce in-memory C structures your C program could use).  So the main program would call GCC and compile and run your input to get results and use those results as its final input.  Except that still wouldn't be nearly as powerful as what Lisp is doing.&lt;/p&gt;

&lt;p&gt;So if you can figure out how to shape your input into a form that the Lisp reader can read, you're set.  And it so happens sexps are a great representation for a great many things.  Maybe this is part of why Lispers seem to worship the REPL and shun compiling their apps into command-line, standalone executables?  Maybe this is part of what's meant by the oft-quoted-to-death &lt;a href=&quot;http://en.wikipedia.org/wiki/Greenspun%27s_Tenth_Rule&quot;&gt;Greenspun's 10th Rule&lt;/a&gt;?&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Much more PAIP to follow.  It should be enjoyable.  There's nothing like a good book.&lt;/p&gt;</description></item><item><title>False</title><link>http://briancarper.net/blog/false</link><guid>http://briancarper.net/blog/false</guid><pubDate>Thu, 13 Dec 2007 19:55:25 -0800</pubDate><description>&lt;p&gt;In Ruby, the only things that are false are &lt;code&gt;nil&lt;/code&gt; and &lt;code&gt;false&lt;/code&gt;.  This is a nice change over other languages where other things evaluate to false in boolean tests.  Like C and many others, which considers the integer 0 to be false.  So is 0.0 false?  How about 1e-999999?  Or there's Perl, which also considers an empty string to be false, and auto-casts between numbers and strings, which can make things fun.  And of course Perl has Perlish insanity like &lt;code&gt;0E0&lt;/code&gt;, &quot;zero but true&quot;.&lt;/p&gt;

&lt;p&gt;However all languages pale in comparison with PHP.  They provide these &lt;a href=&quot;http://www.php.net/manual/en/types.comparisons.php&quot;&gt;handy charts&lt;/a&gt; to help you figure out what's true and what's false.  &lt;/p&gt;

&lt;p&gt;That really sums up PHP well.  You have three standard functions (isset, is_null, empty) with completely inconsistent names.  Two equality test operators whose meaning completely changes between PHP versions.  And then a couple of 12x12 grids of crap necessary to figure out how they behave.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&quot;0&quot; == 0&lt;/code&gt;?  True. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;0 == &quot;&quot;&lt;/code&gt;?  True.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&quot;0&quot; == &quot;&quot;&lt;/code&gt;?  False...  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;null == array()&lt;/code&gt;?  True....?&lt;/p&gt;

&lt;p&gt;Really makes you appreaciate Ruby.&lt;/p&gt;</description></item><item><title>Javascript forays, PHP adventures</title><link>http://briancarper.net/blog/javascript-forays-php-adventures</link><guid>http://briancarper.net/blog/javascript-forays-php-adventures</guid><pubDate>Wed, 07 Nov 2007 00:39:42 -0800</pubDate><description>&lt;p&gt;To add yet another language to the ever-expanding list of languages I know well enough to get by but have far from mastered, in the past week or two at work I've needed to play with Javascript a lot.  I've long thought of Javascript as the bane of my existence, if only for the horrid browser incompatibilities you have to deal with.  I hate hate hate hate writing code that needs to have a bunch of silly conditionals that change the code's behavior based on differences in the underlying platform.  In this case of course the platform is a browser, but I hate it equally dealing with differences between operating systems, differences between versions of libraries, and other similar things.  &lt;/p&gt;

&lt;p&gt;The ideal situation is to use some library where someone has already worked out those platform-dependent quirks.  In the case of Javascript, there's &lt;a href=&quot;http://jquery.com/&quot;&gt;JQuery&lt;/a&gt;.  It really does work wonders.  I read recently that Google uses it for some of their sites, and I can probably see why.  JQuery gives you some helper functions that let you deal very nicely with event handling and element-selection.  &lt;/p&gt;

&lt;p&gt;To my surprise, Javascript actually is turning out to be a surprisingly powerful language.  It apparently supports closures, and functions are first-order objects.  The OOP system in Javascript is oddly different from other languages I've used, but it's workable.  I'm doing some relatively funky stuff, and Javascript is handling it well enough.  And everything I've done in JQuery so far works in IE6 and Firefox.  That's a good sign.&lt;/p&gt;

&lt;p&gt;In the course of all this, I'm also using PHP.  I had to repress a PHP-induced shudder even as I write this.  But this is my first venture into the realm of PHP5, and again it's turning out OK.  They made a lot of changes between PHP4 and PHP5, many of which made a difference.  The language is still far too verbose for my tastes; Ruby has spoiled me in terms of variable names without the need for Perl-style sigils.  And the overload of &lt;code&gt;array()&lt;/code&gt;'s in PHP still drives me batty.  But this time, I'm making heavy use of some third-party libraries, e.g. &lt;a href=&quot;http://smarty.php.net/&quot;&gt;Smarty&lt;/a&gt; templates for my interface, and &lt;a href=&quot;http://spyc.sourceforge.net/&quot;&gt;Spyc&lt;/a&gt; to read some YAML for config and input files.  It lets me do stuff in PHP without actually writing much code in PHP.  Can't beat that.&lt;/p&gt;

&lt;p&gt;Maybe that's the secret of life: to make up for deficiencies in languages I dislike by using tons of third-party libraries.  Maybe.  Well, no, probably not.&lt;/p&gt;

&lt;p&gt;In other non-news, my Gentoo box should arrive at my door via UPS on Thursday.  Sweet sweet salvation.  I'm going to put this Vista laptop in the closet and bolt the door shut.&lt;/p&gt;</description></item><item><title>Redemption, sadly.</title><link>http://briancarper.net/blog/redemption-sadly</link><guid>http://briancarper.net/blog/redemption-sadly</guid><pubDate>Mon, 29 Oct 2007 20:48:35 -0700</pubDate><description>&lt;p&gt;Today I rammed smack up against a brick wall in my C# endeavors.  The problem at hand was something that seems pretty simple: Randomly shuffle an array.  Anyone who knows Ruby knows that this is super easy. Here's one way:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;arr.sort_by { rand }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How do you do this in C#?  Search google for some tips and view the abject horror of a verbose and non-orthogonal weak language.   &lt;a href=&quot;http://www.thescripts.com/forum/thread287240.html&quot;&gt;Read if you dare.&lt;/a&gt;  Find the shuffle routine in &lt;a href=&quot;http://groups.google.com/group/Google-Code-for-Educators/browse_thread/thread/392354fabf70512d&quot;&gt;this labyrinth of code&lt;/a&gt;, and feel the pain.  Have &lt;a href=&quot;http://www.thescripts.com/forum/thread119718.html&quot;&gt;some more&lt;/a&gt; if you like.  ...&lt;a href=&quot;http://www.eggheadcafe.com/community/aspnet/2/50058/you-could-introduce.aspx&quot;&gt;cringe.&lt;/a&gt;  Then &lt;a href=&quot;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=60108&amp;amp;SiteID=1&quot;&gt;read this one&lt;/a&gt;.  And then read on Wikipedia why this &lt;a href=&quot;http://en.wikipedia.org/wiki/Shuffling#Implementation_of_shuffling_algorithms&quot;&gt;last solution is pretty much totally wrong&lt;/a&gt;.  And why the Ruby one above is very much right.&lt;/p&gt;

&lt;p&gt;So a lot of people wrote a lot of C# code, much of it ugly, to solve this problem, so what?  You can find bad code in any language.  My point is, to borrow a mantra from the world of Lisp, not all programming languages are created equal.  Sure, all programming languages are equally powerful in the Turing-complete sense; you could write a Ruby interpreter in C# and solve the above problem that way.  But there are things about some languages that make it much more difficult to solve some problems than it would be in other languages.  Passing around blocks in Ruby makes it super easy to solve a problem like randomly shuffling an array.  In C#, Java, etc. you'd at the very least have to make some kind of object that represents a sorting algorithm, some kind of method that takes and uses such an object, and you'd also have to worry about all the type compatibility between all of the above.  Or I could use some kind of delegate method, which is C#'s version of function pointers, from what little I read.  Both of those solutions are a lot more code than I really want to write to solve such a simple problem.&lt;/p&gt;

&lt;p&gt;In Perl, to do this kind of thing, you'd take the array, map it into a hash of array-element / random-number pairs, sort by the random numbers, and then re-map it into an array.  More verbose than Ruby, but better than nothing.  C# has Hashtables and ArrayLists, so why not try it the longhand Perl way?  That's what I ended up trying in C# at work.  At this point, I ran up against all the lovely limitations of statically typed languages.  First I made a hash and tried to get a list of its keys and store them in a native array.  You can't do that, because Hashtable returns an ICollection object, not a plain old array, and you can't cast one into the other.  C# apparently retains some of the ridiculous Array vs. ArrayList, primitive type vs. object type bullcrap that comes from the world of Java.  What reason is there to have a subset of things that are completely incompatible with another subset of nearly identical things?  What reason is there to have such a thing built into the very foundation of a language?  Java has the excuse (maybe) that they started off with a bunch of crap, and had to try to fix their crap without breaking all the code everyone already wrote using the old crap.  What's C#'s excuse for copying this horrendously unwieldy mess?&lt;/p&gt;

&lt;p&gt;I eventually got everything sorted out, and it didn't take THAT long, but sure it wasn't pretty.  And it was silly, unnecessary work.  The solution ended up being 20 or so lines of code to do what Ruby does in 13 characters much more elegantly.&lt;/p&gt;

&lt;p&gt;Problem number two today came when I tried to printf a string, and strftime a DateTime.  Now, there are what seem to be pretty widely accepted standards on how a formt string for &lt;a href=&quot;http://en.wikipedia.org/wiki/Printf&quot;&gt;how a printf-style function should look&lt;/a&gt;.  %d, %s, %f, and so on.  Similarly lots of languages have a strftime function that uses &lt;a href=&quot;http://us.php.net/strftime&quot;&gt;pretty standard tags&lt;/a&gt; to represent month, day, year, hour, minute, second etc.  There are some variations between languages, but the general idea is similar enough that you can pick it up very quickly.  In many cases you can drop C strings into Perl or Ruby or whatever, and it'll work just the same.&lt;/p&gt;

&lt;p&gt;Well, of course, Microsoft craps all over those pseduo-standards.  In C# rather than something like &quot;%0.8d&quot;, you get something that looks like &lt;code&gt;&quot;{0,8:#}&quot;&lt;/code&gt;.  Same deal for strings to format dates and times; they look nothing like the strftime I'm familiar with.  &lt;/p&gt;

&lt;p&gt;Why?  Why does MS have to do everything differently than everyone else in the world?  The choice of format strings is totally arbitrary, so why not use what every freaking other language in the world uses?  Is it to keep MS-only programmers mentally tied into MS-only languages so that anything non-MS looks alien to them?  Are the MS-style format strings any more powerful than printf-style?  Not that I can tell; the C# ones give you special tags for &quot;currency&quot; and to comma-separated numbers, but couldn't they have just added a &quot;%$&quot; and &quot;%,&quot; to the MS version of printf or something?  &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/dwhawy9k.aspx&quot;&gt;Read this trash.&lt;/a&gt;  I spent way too much time today reading through this small encyclopedia of documentation on MS-style format strings just to re-learn something I already knew very well. &lt;/p&gt;</description></item><item><title>Academia</title><link>http://briancarper.net/blog/academia</link><guid>http://briancarper.net/blog/academia</guid><pubDate>Wed, 03 Oct 2007 13:59:31 -0700</pubDate><description>&lt;p&gt;After I graduated college with a computer science degree, I had no idea what I wanted to do with it.  I was fortunate enough to get a great job in academia.  After almost three years in this line of work, I really can't imagine working for a for-profit company as a programmer.  Right now I work in psychological research.  I make databases and I program surveys / interviews for data collection and other such fun scripting and data-managing tasks.  It may not sound very exciting but it involves a lot more than writing SQL queries.  In my last job I wrote a huge Ruby framework to do all kinds of stuff, and I had to support Perl and Python scripts, master a statistics package, make web pages, and as an afterthought write plenty of SQL.&lt;/p&gt;

&lt;p&gt;Working in academia is a wonderful experience.  The people you get to work with are some of the smartest people in the world.  Not necessarily smart in the computer world, but smart in the world of psychology, or law, or sociology, or other things.  The people I interact with come from a completely different world than the computer world I live in, and personally I find it very refreshing and challenging to bridge that gap.  If learning to communicate technical issues to non-technical people is a skill, there's no better way of learning it.&lt;/p&gt;

&lt;p&gt;Another thing I love is that there's no pressure or drive to acquire money.  At least not in the sense of &quot;we need money money money, get it at any cost, beat the competition into submission, advertise, produce produce produce&quot;  Instead there's a drive to do good science.  It's a different kind of pressure which I find much more palatable.  Of course running a study does require funding and you usually have to convince someone somewhere to give you some, but as a computer programmer I'm far removed from such concerns and I don't have to worry about them.  If the study is valid, and if it produces good data on time, and if I do a good job of helping that happen, things works out.  &lt;/p&gt;

&lt;p&gt;The work is important, which makes me feel good at the end of the day.  I'm not trying to pad some billionaire's bank account, I'm trying to further the knowledge of the human race.  At my previous job, a lot of the work I did ended up directly contributing to law and policy decisions.  Most studies deal with things no one has ever looked at before.  It's a much more fulfilling feeling than slaving away to make other people money.&lt;/p&gt;

&lt;p&gt;The atmosphere at my current job and my previous one were very laid-back and casual.  You generally work with a small team of people, and people just do whatever needs to be done.  I've never had to punch a time card.  I don't have to wear a tie.  There usually are no deadlines where I need to get some product done by X date.  There is no product except knowledge and research papers.  I don't have to deal with customers.  There are no customers except PhDs waiting to read that papers or work with new data.&lt;/p&gt;

&lt;p&gt;In my very limited experience, there is a good demand for computer programmers who are willing and able to support a research study.  I was really needed at my last job, and I got multiple very nice offers when I started looking to move to the west coast.  If you're good, people will need you.  If anyone reading this is an up-and-coming programmer trying to figure out what to do with your degree, give academia and research a thought.&lt;/p&gt;</description></item><item><title>Education</title><link>http://briancarper.net/blog/education</link><guid>http://briancarper.net/blog/education</guid><pubDate>Sat, 07 Jul 2007 21:37:47 -0700</pubDate><description>&lt;p&gt;I've been out of college almost exactly four years.  Looking back at my Computer Science classes, I think I can see some ways that my education was woefully inadequate.  Or at least not what I wish it would have been, knowing what I (hope I) know now.&lt;/p&gt;

&lt;p&gt;My classes were in C and C++ for the first year or two.  I remember being very turned off of C++ because it didn't have a native &quot;string&quot; type and you always HAD to screw with null-terminated arrays of characters.  I never once heard mentioned the STL or the benefits of using it, so far as I remember.  Only a couple years after graduating did I learn that using C-style header files and functions in C++ was antiquated; it was tolerated in homework assignments and my professors didn't say much about it.  I remember learning about C++ templates, but it was a chapter or two blown through in a week.  We never did anything useful with them.  &lt;/p&gt;

&lt;p&gt;I remember distinctly someone asking a professor &quot;which version&quot; of C++ we were allowed to use on an assignment.  He responded &quot;standard&quot;.  When pressed further, he conceded &quot;whatever Visual C++ can handle&quot;.  My university was and as far as I know remains a Microsoft sort of place.  We all got Visual Studio &quot;for free&quot; (meaning it was included as a fee in our tuition, most probably).  Linux wasn't discouraged, but all assignments had to be done in VC++.  I wish that would have been different.  I wish I'd have used gcc or something once or twice.  Most of the professors I liked were crusty old Unix guys who advocated *nix personally if not formally in the curriculum; it's one of the things that got me interested in Linux.  I wish I'd picked their brains more.&lt;/p&gt;

&lt;p&gt;In my last year or so of classes, the entire university was in the process of phasing out C++ and teaching all the core classes in Java.  I was lucky to get a mix of Java and C and C++, if only so I could see the differences between them, and I got enough of a taste of Java to know I don't like it.  I had one Perl class (the only one offered, that I'm aware of), but it was half a term and focused on CGI.  I had some assembler language classes but they were run on a little toy MIPS emulator in (of course) Windows.  How bad must it be for the next generation of coders coming from my old college, who have Java as their primary or perhaps only language?&lt;/p&gt;

&lt;p&gt;I remember learning about object oriented programming, but the only thing I actually learned from those courses was terminology: constructor, destructor, inspector, mutator.  We learned about inheritance but nothing about how it can be useful.  We learned about overloading and overriding operators and methods but never anything about when to do it and when not to.  I think the word polymorphism was mentioned and defined, but never explained with good examples.  We never touched design patterns; I read a book about those a few months ago and it was a real revelation in many ways.&lt;/p&gt;

&lt;p&gt;I learned a lot about binary trees and stacks and priority queues and graph search algorithms.  But I never really learned about when we should use those things and when not.  I never had an assignment that said &quot;Here's some data; pick the right data structure to model and organize and query the data and write a program that does it&quot;.  In 90% of my classes I probably never wrote a program longer than 200 lines of code.  My courses had me writing and re-writing and re-re-writing implementations of singly-linked lists until I was blue in the face.  It's nice to know how those things work, but it's also nice to know that reinventing the wheel is stupid when you're trying to get a program done on a budget; they could have mentioned that tidbit at least in passing.&lt;/p&gt;

&lt;p&gt;Strangely I never had a single database class in college.  I never learned SQL until I taught myself after I graduated.  If anything I would think SQL is almost essential for any programmer to know.  I never learned shell scripting along the lines of bash scripting or Perl as a shell scripting language.&lt;/p&gt;

&lt;p&gt;How about Vim?  Vim has contributed greatly to whatever productivity I have at work (and home) nowadays.  But the one time I remember it being mentioned in college was a professor saying something about &quot;this really old and weird editor called VEE EYE, anyone ever heard of it?&quot;.  Left to my own devices, I always used the sucktastic Visual Studio IDE, since it was the best thing I knew existed at the time.  I did have one good class (again taught by one of the crusty old Unix guys) where we discussed the importance of a good editor, how syntax highlighting and auto-indentation can help a coder catch errors and be more productive.  I don't remember if Vim was mentioned by name, I think it was more an advocation of fancy IDEs along the lines of Visual Studio.  But it was something I wish we'd have gone into more detail on.&lt;/p&gt;

&lt;p&gt;The thing I probably value most from my formal education are the things that are the least practically useful.  Theory of computation stuff.  Compiler design, programming language design, things like that.  State machines and grammars and string parsing.  The history and evolution of programming languages.  How programming languages work under the hood, garbage collection algorithms, object heaps and call stacks.  Those were really interesting and I think helpful in understanding what's really going on when you write and run code.  But I'm unsure how much it helps in a practical sense, when your boss says &quot;Give me this by Friday&quot;.&lt;/p&gt;

&lt;p&gt;I'd say only within the past year have I even begun to approach the level of &quot;adequate&quot; programmer in terms of skill level, and it's almost entirely thanks to things I've learned on my own since college.  Maybe I'm misremembering, maybe college gave me some kind of magical foundation upon which all other knowledge has been built.  Maybe there isn't enough time in college to learn the things I wish I had learned.  I don't buy that.&lt;/p&gt;

&lt;p&gt;There's no doubt the piece of paper saying that I graduated has helped me in practical ways, e.g. finding and getting a job.  But I can't help but think that things I've learned privately just because I like learning them has been more useful in being able to actually do my job.  On that note, having started in high school with hideous old QBASIC, ventured through C and C++, hurried past Java, gone down the Perl path for a long while, briefly glanced at the likes of Haskell and PHP and many others, and ended up firmly in Ruby territory, I'm planning to revisit C++ again a bit now.  Maybe it'll all make more sense now.  I ordered a book last week, we'll see how it looks once it gets here.&lt;/p&gt;</description></item><item><title>Vim regexes</title><link>http://briancarper.net/blog/vim-regexes</link><guid>http://briancarper.net/blog/vim-regexes</guid><pubDate>Mon, 05 Mar 2007 19:43:37 -0800</pubDate><description>&lt;p&gt;One thing I very much miss in Gentoo is controlling what is compiled into my Vim.  You need to enable &lt;code&gt;perldo&lt;/code&gt; and &lt;code&gt;rubydo&lt;/code&gt; support at compiletime.  Gentoo had USE flags to do it.  In Ubuntu I get perldo but no rubydo by default, which is annoying.&lt;/p&gt;

&lt;p&gt;The reason I need &lt;code&gt;perldo&lt;/code&gt;/&lt;code&gt;rubydo&lt;/code&gt; is because Vim's regexes are so inconsistent.  &lt;code&gt;*&lt;/code&gt; is special when not escaped, but &lt;code&gt;+&lt;/code&gt; is special when escaped.  You can use &lt;code&gt;\{x,y}&lt;/code&gt; (escape only opening bracket), but you have to use &lt;code&gt;\( \)&lt;/code&gt; (escape both parens), and with &lt;code&gt;[]&lt;/code&gt; it's special when you don't escape either.  I simply can't remember these, especially when coding at full speed, and speed is one of the reasons to use Vim in the first place.&lt;/p&gt;

&lt;p&gt;Then Vim has &lt;code&gt;magic&lt;/code&gt; and &lt;code&gt;nomagic&lt;/code&gt;.  And you can use &lt;code&gt;\v&lt;/code&gt; to set &quot;very magic&quot;.  Very magic is almost what I want, but you can't set it in your &lt;code&gt;.vimrc&lt;/code&gt; and even if you could, the Vim manual tells you to leave the setting of &lt;code&gt;magic&lt;/code&gt; alone if you know what's good for you.&lt;/p&gt;

&lt;p&gt;PCREs are so much more consistent and easier to remember (excepting Perlisms like &quot;dot matches newline&quot; inconsistencies).  The special characters are always special, and you escape them all to make them non-special.  But perldo and rubydo in Vim can't do everything Vim regexes can do; they can't properly span lines, is the major thing.  They don't highlight text like Vim does with its builtin regexes if you have &lt;code&gt;hls&lt;/code&gt; set.&lt;/p&gt;

&lt;p&gt;I read somewhere that Vim regexes are set up to let you match C code easily, and that's why for example &lt;code&gt;{}&lt;/code&gt; are non-special by default.  I don't remember where I read it or if it's true.  Doesn't help a lot when writing non-C code though.&lt;/p&gt;</description></item><item><title>Mmmm rubygems</title><link>http://briancarper.net/blog/mmmm-rubygems</link><guid>http://briancarper.net/blog/mmmm-rubygems</guid><pubDate>Wed, 21 Feb 2007 15:51:58 -0800</pubDate><description>&lt;p&gt;I put together my first ruby gem today (for internal use at work).  &lt;a href=&quot;http://www.linuxjournal.com/article/8967&quot;&gt;Here is a good tutorial on how to do it&lt;/a&gt;.  Or else look at chapter 17 in the Pickaxe book.  Simply make a gemspec file, define a few attributes listing and describing your files and then compile it.  It was astoundingly easy and such a clean way to handle versioning and distributing Ruby code.  I always had some weird impression that rubygems was clunkier than Perl's CPAN, but I think I had it wrong.  Not at all hard to use.&lt;/p&gt;

&lt;p&gt;Setting the &lt;a href=&quot;http://rubygems.org/read/chapter/3&quot;&gt;RUBYOPT environment variable to 'rubygems'&lt;/a&gt; lets you get away with doing a &lt;code&gt;require&lt;/code&gt; on gem-provided modules without doing &lt;code&gt;require 'rubygems'&lt;/code&gt; in every program you write.  I'm sure I must've set RUBYOPT myself a year ago on this machine and forgotten.  I was sort of wondering one day, hey, how is Ruby finding those modules?  This kind of thing is good to know when you need to set up a Ruby environment on someone else's computer in the near future, I imagine.  This is one bad thing about having a computer that doesn't need to be reformatted every six months.  Who knows how many other tweaks I've done on this machine and forgot about and now silently depend on.&lt;/p&gt;</description></item><item><title>Vim brute force</title><link>http://briancarper.net/blog/vim-brute-force</link><guid>http://briancarper.net/blog/vim-brute-force</guid><pubDate>Mon, 19 Feb 2007 22:19:47 -0800</pubDate><description>&lt;p&gt;In the end all code ends up as machine language.  Generally the way to write effective code is to use a high-level language and let a smart compiler expand a tiny bit of high-level code it into a great deal of low-level machine language.&lt;/p&gt;

&lt;p&gt;But another way I seem to end up doing this is using vim.  I will generate mounds and mounds of temporary, throw-away, ugly code, but I will generate it extremely fast using vim.  It's almost like vim is acting like an extremely high-level compiler; I take a very-high-level idea and using a little bit of vim trickery, I let vim expand it out into a large amount of high-level code.  &lt;/p&gt;

&lt;p&gt;Say I have a data file with two huge tab-separated columns; I need to insert the value from the second column into a table anywhere I find the value in the first column.  There's possibly some way of doing this with one or two SQL queries to slurp the data file directly, but I don't know how to do it in MS-SQL server at work (ugh) and the brute-force vim/Perl way of doing it comes immediately to mind:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:perldo s{^([^\t]+)\t(.*)$}{UPDATE table SET field_x = '$2' WHERE field_y = '$1'}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It could also be done with a native vim regex obviously.  Either way I end up with pages upon pages of SQL commands each of which does a single update.  This is sloppy and slow, but it scales better than you'd think.  I can do many thousands of inserts in this way in a few seconds.  If I was doing millions rather than thousands I'd probably take the time to do this the right way, but I rarely if ever find myself needing to do millions of updates.&lt;/p&gt;

&lt;p&gt;Is sloppy, ugly high-level code still bad if you didn't actually WRITE it, but had a program quickly write it for you?  Machine language is sloppy-looking too, but it's sloppy for a reason (i.e. that's what computers understand).  My sloppiness is for another reason: I'm lazy and this saves me time.  But I feel like I may be developing bad habits.   Then again there are times when I only need a hammer for a few seconds to pound in a nail or two, and I'm not trying to build a whole house.  In time like those any hammer will probably do.&lt;/p&gt;</description></item><item><title>Unique-ify lines in Vim</title><link>http://briancarper.net/blog/unique-ify-lines-in-vim</link><guid>http://briancarper.net/blog/unique-ify-lines-in-vim</guid><pubDate>Thu, 11 Jan 2007 13:15:07 -0800</pubDate><description>&lt;p&gt;If I want to get rid of duplicate lines in a text file, in Linux I can simply pipe it through &lt;code&gt;uniq&lt;/code&gt;.  Windows doesn't have an equivalent (or else I don't know about it).  There may be a Vim equivalent also, but I don't know it if there is.  Instead you can use &lt;code&gt;perldo&lt;/code&gt; to do it like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:perldo BEGIN{%x={}} $_ = ' ' if $x{$_}++
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The neat thing about &lt;code&gt;perldo&lt;/code&gt; (and &lt;code&gt;rubydo&lt;/code&gt;) is that whatever you do is persistent across runs of &lt;code&gt;perldo&lt;/code&gt;.  That means if you run this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:perldo $_ = ' ' if $x{$_}++
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;it'll work the first time you run it, but the second time, &lt;code&gt;$x&lt;/code&gt; will have retained its values from the first run, and it will instead delete every line.  There are few limits to what you can do with a one-liner &lt;code&gt;perldo&lt;/code&gt; command in Vim.  It's great, if you know Perl better than you know Vim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EDIT TWO YEARS LATER&lt;/strong&gt;: How about &lt;code&gt;:sort u&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Perl vs. Ruby breaking from nested loops</title><link>http://briancarper.net/blog/perl-vs-ruby-breaking-from-nested-loops</link><guid>http://briancarper.net/blog/perl-vs-ruby-breaking-from-nested-loops</guid><pubDate>Sun, 03 Dec 2006 12:13:12 -0800</pubDate><description>&lt;p&gt;Breaking out of nested blocks is apparently done much differently in Perl and Ruby.  In Perl if you run this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;my $counter = 0;
foreach my $outer (1..5) {
    foreach my $inner ('A'..'E') {
        print &quot;$outer: $inner\n&quot;;
        last if ++$counter &amp;gt; 4
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;last&lt;/code&gt; is going to break out of the inner-most foreach loop by default.  If you want to break out of the OUTER foreach loop you can use line labels:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;my $counter = 0;
OUTER: foreach my $outer (1..5) {
    foreach my $inner ('A'..'E') {
        print &quot;$outer: $inner\n&quot;;
        last OUTER if ++$counter &amp;gt; 4
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Ruby to do the same thing, you have to use a &lt;code&gt;throw/catch&lt;/code&gt; block.  This is a completely separate mechanism from Ruby's &lt;code&gt;begin/rescue&lt;/code&gt; Exception-handling mechanism.  &lt;code&gt;throw/catch&lt;/code&gt; rather appears to be simply a flow-control mechanism.  You &lt;code&gt;raise&lt;/code&gt; Exceptions, but you &lt;code&gt;throw&lt;/code&gt; Strings or Symbols.  The equivalent of the above Perl in Ruby:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;counter = 0
catch :OUTER do
    1.upto(5) do |outer|
        'A'.upto'E' do |inner|
            puts &quot;#{outer}: #{inner}&quot;
            throw :OUTER if (counter += 1) &amp;gt; 4
        end
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt; Originally I thought that Perl's &lt;code&gt;last LABEL;&lt;/code&gt; would not find labels except in the same static scope.  It must've been a bug in my test code however, because this does work.  My mistake!  So this does work in Perl:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sub test {
    HERE: foreach my $really_outer (1..5) {
        test2();
    }
}

sub test2 {
    my $counter = 0;
    foreach my $outer (1..5) {
        foreach my $inner ('A'..'E') {
            print &quot;$outer: $inner\n&quot;;
            last HERE;
        }
    }
}

test
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can do this in Ruby also.  The other nice thing about Ruby is you can return a value from the &lt;strong&gt;throw&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def test
    result = catch :HERE do 
        1.upto(5) do |really_outer|
            test2
        end
    end

    puts &quot;RESULT: #{result}&quot;
end

def test2
    counter = 0
    1.upto(5) do |outer|
        'A'.upto'E' do |inner|
            puts &quot;#{outer}: #{inner}&quot;
            throw :HERE, &quot;YOINK&quot; if (counter += 1) &amp;gt; 4
        end
    end
end

test
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In Perl you also have the option of using &lt;a href=&quot;http://www.perl.com/lpt/a/2002/11/14/exception.html&quot;&gt;Error.pm&lt;/a&gt;, but it looks horrendously hackish to me, as Perl code often does.&lt;/p&gt;

&lt;p&gt;The only thing I can think of that's bad about Ruby is that it has two things which are really similar, one for Exceptions and one not.  People coming from a different language may think that &lt;code&gt;throw/catch&lt;/code&gt; is the Exception-handling mechanism when it's not.  But Ruby still wins here.&lt;/p&gt;</description></item><item><title>One-liner explained</title><link>http://briancarper.net/blog/one-liner-explained</link><guid>http://briancarper.net/blog/one-liner-explained</guid><pubDate>Thu, 30 Nov 2006 12:41:58 -0800</pubDate><description>&lt;p&gt;Someone asked for an explanation of my &lt;a href=&quot;/2006/11/29/one-liner/&quot;&gt;obfuscation&lt;/a&gt;, so here goes:&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;-l&lt;/code&gt; flag to Perl makes it stick a newline on the end of output.  Handy.&lt;/p&gt;

&lt;p&gt;Reformatted and indented, the code would be &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;for(0..0xb271a1){
    ++( $} ||= q|A|)
}
( $; = q;&quot;\x70\x72\x69\x6e\x74\x24\x7d&quot;; ) =~ s;.*;$&amp;amp;;eee
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A good obfuscation technique is to use odd characters as delimiters; Perl lets you get away with nearly any character to delimit the &lt;code&gt;q//&lt;/code&gt; and &lt;code&gt;s///&lt;/code&gt; operators etc.  Replacing those with &lt;code&gt;()&lt;/code&gt;, it looks much easier to understand:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;for(0..0xb271a1){
    ++( $} ||= q(A) )
}
( $; = q(&quot;\x70\x72\x69\x6e\x74\x24\x7d&quot;) ) =~ s(.*)($&amp;amp;)eee
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Perl also lets you use some fairly odd variable names.  I use &lt;code&gt;$}&lt;/code&gt; and &lt;code&gt;$;&lt;/code&gt;.  Some of these kinds of names are reserved for various builtin functionality in Perl.  &lt;code&gt;$|&lt;/code&gt; would've made my obfu much harder to read, but that variable is taken by Perl.&lt;/p&gt;

&lt;p&gt;The for loop counts from 0 to 11694497 (written as hex 0xb271a1, for no reason other than to add line noise).  &lt;/p&gt;

&lt;p&gt;The single line inside the loop initializes the variable &lt;code&gt;$}&lt;/code&gt;.  &lt;code&gt;||=&lt;/code&gt; assigns a value &quot;A&quot; to &lt;code&gt;$}&lt;/code&gt; only if &lt;code&gt;$}&lt;/code&gt; has no value; equivalent to &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$} = $} || &quot;A&quot;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The ||= is redundant and does essentially nothing 11694496 out of 11694497 iterations through the loop.  But the variable &lt;code&gt;$}&lt;/code&gt; itself is returned each time.  This is so you can chain assignments, etc. in normal programming use.  I use this to do a &lt;code&gt;$}++&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;++&lt;/code&gt; on a string in Perl will do some magic.  &lt;code&gt;&quot;A&quot;++&lt;/code&gt; = &quot;B&quot;.  Eventually, &lt;code&gt;&quot;Z&quot;++&lt;/code&gt; = &quot;AA&quot;, and &lt;code&gt;&quot;ZZ&quot;++&lt;/code&gt; = &quot;AAA&quot;.  This is a handy obfuscated method of creating words, which I saw once a while back on &lt;a href=&quot;http://www.perlmonks.org/&quot;&gt;PerlMonks&lt;/a&gt;.  After 11694497 iterations, &lt;code&gt;$}&lt;/code&gt; will hold the text &quot;YOINK&quot;.&lt;/p&gt;

&lt;p&gt;Another variable with an odd name, &lt;code&gt;$;&lt;/code&gt;, is given the value &lt;code&gt;'&quot;\x70\x72\x69\x6e\x74\x24\x7d&quot;'&lt;/code&gt;.  Note the double-quotes are part of its value.  This is just an encoding of the string &lt;code&gt;'&quot;print$}&quot;'&lt;/code&gt;.  I do a regex substitution on it, replacing .* with &lt;code&gt;$&amp;amp;&lt;/code&gt;.  &lt;code&gt;$&amp;amp;&lt;/code&gt; is a builtin variable that holds the value of everything that matched, in this case, the entire string.  I put three &lt;code&gt;e&lt;/code&gt; flags on the end of the substitution; this causes whatever is in the right side of the &lt;code&gt;s///&lt;/code&gt; to be evaluated as though you called &lt;code&gt;eval&lt;/code&gt; on it three times.&lt;/p&gt;

&lt;p&gt;Why three of them?  Well, the first one does nothing.  Evaluating a string just returns the string.  It's as though you put a line like this in a script:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;'&quot;\x70\x72\x69\x6e\x74\x24\x7d&quot;';&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;which returns the value&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&quot;\x70\x72\x69\x6e\x74\x24\x7d&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that &quot; is still part of the result at this point.  The second &lt;code&gt;eval&lt;/code&gt; evaluates the result of the previous &lt;code&gt;eval&lt;/code&gt;; seeing a string surrounded by double-quotes, it will process the string, interpolating the &lt;code&gt;\x&lt;/code&gt; codes.  Without the double-quotes, it would try to execute those &lt;code&gt;\x&lt;/code&gt;'s as Perl commands, which give all kinds of parser errors.  The above string processing results in:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;print$}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The third &lt;code&gt;eval&lt;/code&gt; evaluates that string, which actually runs the command, i.e. it prints the value of &lt;code&gt;$}&lt;/code&gt;, &quot;YOINK&quot;.&lt;/p&gt;</description></item><item><title>One-liner</title><link>http://briancarper.net/blog/one-liner</link><guid>http://briancarper.net/blog/one-liner</guid><pubDate>Wed, 29 Nov 2006 17:53:12 -0800</pubDate><description>&lt;p&gt;Been a while since I perl'ed.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;perl -le 'for(0..0xb271a1){++($}||=q|A|)}($;=q;&quot;\x70\x72\x69\x6e\x74\x24\x7d&quot;;)=~s;.*;$&amp;amp;;eee'
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Closed source woes</title><link>http://briancarper.net/blog/closed-source-woes</link><guid>http://briancarper.net/blog/closed-source-woes</guid><pubDate>Thu, 17 Aug 2006 15:37:02 -0700</pubDate><description>&lt;p&gt;I have to maintain a bunch of 3rd-party CGI scripts at work.  We pay another company for these scripts; they are compiled into .exe files (yes, ugh).  It turns out they work OK for the most part.  But there are just one or two tiny areas where things don't work like we need.&lt;/p&gt;

&lt;p&gt;These scripts are closed source.  This means that even though fixing this problem is a matter of changing an '8' to a '16' in maybe one or two lines of code, I can't do it.  I have to either ask (i.e. beg) the company to do it, or I have to live with the problem, or I have to create some kind of hideous, hackish workaround.  So far, I've been forced to take all three of these routes at least once.&lt;/p&gt;

&lt;p&gt;It's kind of irritating to have the knowledge, skill, time, and inclination to fix something, but to be prevented from fixing it by someone telling you you aren't allowed.  I don't think I have any kind of moral right to demand people give me their source code, but it is very frustrating when this kind of thing happens.  And I know it'll happen again.  Sadly this leads me to a &quot;Let's get rid of this and let me write something myself&quot; attitude, which probably isn't a good thing because rewriting things myself would cause much more work in the long run.  No problem ever has a clean solution, sadly.&lt;/p&gt;</description></item><item><title>RubyFacets</title><link>http://briancarper.net/blog/ruby-facets</link><guid>http://briancarper.net/blog/ruby-facets</guid><pubDate>Tue, 15 Aug 2006 14:45:09 -0700</pubDate><description>&lt;p&gt;Today I found a really neat site, &lt;a href=&quot;http://facets.rubyforge.org/&quot;&gt;RubyFacets&lt;/a&gt;.  Reminds me a bit of Perl's &lt;a href=&quot;http://search.cpan.org/search?query=list%3A%3Autil&amp;amp;mode=module&quot;&gt;List::Util&lt;/a&gt; and &lt;a href=&quot;http://search.cpan.org/search?query=list%3A%3Amoreutils&amp;amp;mode=module&quot;&gt;List::MoreUtils&lt;/a&gt;; it's a bunch of methods to extend core classes in interesting ways.&lt;/p&gt;

&lt;p&gt;A while back I posted about a way to prevent Ruby from raising an exception when trying to access an un-initialized subarray of a multidimensional array by &lt;a href=&quot;/2006/06/05/nilclass/&quot;&gt;extending NilClass&lt;/a&gt;.  At RubyFacets I found something arguably more interesting: &lt;a href=&quot;http://facets.rubyforge.org/api/core/classes/Hash.html#M000165&quot;&gt;auto-initializing sub-hashes of a multi-dimensional hash&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def self.auto(*args)
  leet = lambda { |hsh, key| hsh[key] = new( &amp;amp;leet ) }
  new(*args,&amp;amp;leet)
end&amp;lt;/pre&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It took me a couple minutes to figure out what this is doing.  The standard &lt;a href=&quot;http://www.ruby-doc.org/core/classes/Hash.html#M002129&quot;&gt;new&lt;/a&gt; method for class Hash takes a block; if you reference an uninitialized hash element (via the &lt;code&gt;[]&lt;/code&gt; method) that block will be called, which presumably assigns the element a default value (thought it doesn't have to).&lt;/p&gt;

&lt;p&gt;The above method assigns a default value to any uninitialized Hash elements referenced via &lt;code&gt;[]&lt;/code&gt;.  The default value is a new Hash object.  The new Hash object's constructor is also passed a block which assigns new Hash objects to uninitialized Hash elements.    You can see above that the &quot;leet&quot; anonymous function contains a reference to itself.  I find that mighty clever.  This lets you do crazy things like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;h = Hash.auto
h['a']['lot']['of']['dimensions'] = true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and you'll get hashes the whole way down.&lt;/p&gt;</description></item><item><title>Lisp, part 2</title><link>http://briancarper.net/blog/lisp-part-2</link><guid>http://briancarper.net/blog/lisp-part-2</guid><pubDate>Mon, 14 Aug 2006 00:22:47 -0700</pubDate><description>&lt;p&gt;Everyone I know who does Lisp says &quot;Learn Lisp and it will change how you look at all other programming languages!&quot;  I don't know if that's true or not, but I think I'm starting to learn a bit.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;a href=&quot;http://www.gigamonkeys.com/book/macros-defining-your-own.html&quot;&gt;Chapter 8&lt;/a&gt; of &lt;em&gt;Practical Common Lisp&lt;/em&gt; discusses macros.  As has been pounded into my brain by the author, macros in Lisp aren't like macros in other languages.  Nosirree.  Nope.  Not like them.  I definitely won't forget that Lisp macros are different than macros in other languages.  And you won't forget that either.  If you read this book.&lt;/p&gt;

&lt;p&gt;Macros in Lisp let you write code that writes code.  Quoth one of my professors in college, &quot;Code that writes code is some of the neatest code there is!&quot;.  I'll agree with that.  Writing a whole database or a whole test unit framework in Lisp in 50-odd lines is pretty impressive.  Lisp doesn't even seem like that concise a language, compared to Ruby for example.  But it's powerful.  I'm reminded of Haskell, where everything is recursion.  When you start layering recursion on top of recursion, things tend to branch out and get &quot;big&quot; very quickly; that &quot;bigness&quot; equals power and efficiency, if used properly.  That seems to be one of Lisp's strengths; it lets you do that pretty easily.&lt;/p&gt;

&lt;p&gt;Well, a lot of languages let you write &quot;code that writes code&quot;.  Perl has eval() which can take a custom-built string of code and execute it somewhat dynamically.  The thing is though, eval sucks.  If it dies, it dies at runtime, not compiletime.  And you can only put things together via string manipulation.  Lisp's code-building macros are more &quot;built into the language&quot;, for lack of a better term.&lt;/p&gt;

&lt;p&gt;Ruby lets you do some neat things too though.  I found &lt;a href=&quot;http://www.randomhacks.net/articles/2005/12/03/why-ruby-is-an-acceptable-lisp&quot;&gt;this article&lt;/a&gt; to be a pretty good description.  Ruby lets you throw blocks of code around all over the place, and the more I learn of Lisp, the more I'm reminded of Ruby, or the more I think of ways I could be doing things Lisply in Ruby.  Ruby has the added advantage of letting you do all kinds of horribly powerful things at runtime.  Chopping up classes and methods and rebuilding them as you see fit, etc.  The book hints that this is something Lisp lets you do too, since so much of Lisp is actually written IN Lisp.&lt;/p&gt;

&lt;p&gt;To draw a nice contrast, today I was forced to do a lot of PHP programming.  Oh sweet Jeebus.  It burns.  I hate PHP with a passion.  Lisp is wonderfully consistent.  The parentheses do get on my nerves, but there's never any doubt what your syntax should look like at a given time.  It's always parentheses.  PHP on the other hand is both very verbose, and very inconsistent, which is the worst possible combination.  It's never predictable or discoverable.  It's impossible to program PHP without PHP.net open in another window to constantly look crap up.&lt;/p&gt;

&lt;p&gt;Any time I'm forced to use a traditional for() loop now, I start freaking out.  That is something Ruby and Lisp both thankfully avoid.  Ruby's iterators are my best friend.  Looping through an array copying things to temp variables seems so barbaric now that I've seen alternatives.   It's just one of the little things that gets to you; in general in PHP I feel like I'm trying to build a scaffold with pieces that can't be cut to the right size.  Ruby gives me pieces that bend easily, and Lisp gives me really tiny pieces that fit together in all kinds of interesting ways.&lt;/p&gt;</description></item><item><title>Thank you, Google groups</title><link>http://briancarper.net/blog/thank-you-google-groups</link><guid>http://briancarper.net/blog/thank-you-google-groups</guid><pubDate>Fri, 04 Aug 2006 10:36:28 -0700</pubDate><description>&lt;p&gt;I just had a nasty run-in with &lt;a href=&quot;http://search.cpan.org/~smueller/PAR-0.942/lib/PAR.pm&quot;&gt;PAR&lt;/a&gt;.  Activestate Perl doesn't play as nicely with CPAN as I'd like, so I usually use its own built-in &quot;Perl Package Manager&quot;.  The problem with that is that installed packages aren't rebuilt (from what I can tell), they're just downloaded in binary form and unpacked.  So you often don't get the latest version that's on CPAN.  &lt;/p&gt;

&lt;p&gt;PAR was choking on Scalar::Util, because it couldn't find a method named &quot;refaddr&quot;.  But the program worked fine when run as a .pl; it only choked after being pp'ed into a .exe via PAR.  I only need to make a TINY change to this script and re-compile it into a .EXE, so I wasn't really looking forward to rewriting this Perl application just so PAR could read it correctly. &lt;/p&gt;

&lt;p&gt;Thankfully I found an answer on &lt;a href=&quot;http://groups.google.com/group/perl.par/browse_thread/thread/4cfec27c14cc8f60/09008ad431aa0e5e?lnk=st&amp;amp;q=&amp;amp;rnum=1&quot;&gt;Google groups&lt;/a&gt;.  I coulnd't tell you how many times Google groups has saved me a heck of a lot of time and/or effort.  In this case it probably saved me a day worth of work.  Even on such an obscure question as this.  &lt;/p&gt;

&lt;p&gt;Now that I think of it, some advice: Don't use PAR for applications that are going to be used by anyone, or relied upon by anyone.  It's not a lot of fun.&lt;/p&gt;

&lt;p&gt;Actually, some better advice: Don't use Windows for applications that are going to be used by anyone, or relied upon by anyone.  That's better.&lt;/p&gt;</description></item><item><title>Ruby > Perl</title><link>http://briancarper.net/blog/ruby-perl</link><guid>http://briancarper.net/blog/ruby-perl</guid><pubDate>Tue, 27 Jun 2006 13:36:49 -0700</pubDate><description>&lt;p&gt;A while back I stopped coding in Perl and starting using Ruby for mostly everything.  Today I had occassion to use Perl again, because there's no good working equivalent to Perl's &lt;a href=&quot;http://search.cpan.org/~jmcnamara/Spreadsheet-WriteExcel-2.17/lib/Spreadsheet/WriteExcel.pm&quot;&gt;Spreadsheet::WriteExcel&lt;/a&gt; that works well in Ruby;  this &lt;a href=&quot;http://rubyspreadsheet.sourceforge.net/&quot;&gt;Ruby spreadsheet package&lt;/a&gt; is a bit too buggy.  (It's not my choice to use Excel, but they're paying me to use it.  I can't complain.  Well, I can complain here I guess.  And will.)&lt;/p&gt;

&lt;p&gt;One thing I notice about Perl is that Perl sure does give your fingers a workout.  I looked at the fairly simple 103-line Perl script I wrote, and it has exactly 118 dollar signs.  That's a lot of Shift-$ finger reaching, if you think about it.  Ruby doesn't even use curly braces around blocks; it uses &lt;strong&gt;do&lt;/strong&gt; and &lt;strong&gt;end&lt;/strong&gt;, which type quite nicely.   Ruby does use a lot of pipes, but I can easily do a one-handed Shift-| maneuver if I lift my right hand off the home row.  Think of the potential gains I will have when I'm older from the avoidance of arthritis alone.&lt;/p&gt;

&lt;p&gt;Try to come up with a more petty gripe than this.  &lt;em&gt;I dare you.&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Data</title><link>http://briancarper.net/blog/data</link><guid>http://briancarper.net/blog/data</guid><pubDate>Mon, 19 Jun 2006 09:52:25 -0700</pubDate><description>&lt;p&gt;This will be one of my few &quot;happy&quot; rants.  &lt;/p&gt;

&lt;p&gt;I've known I wanted to be a code monkey since I was in high school.  But if you'd asked me what I wanted to do back then, I'd have likely said &quot;program games!&quot; or &quot;something flashy having to do with graphics!&quot;.&lt;/p&gt;

&lt;p&gt;When I got to college and studied computer science, I was at first horrified to learn that most of computer science was pushing data around.  A whole class on how to store data in hashes, stacks, and trees.  Another whole class on how to sort data once it was in those structures.  It was terribly boring to me at the time.  &lt;/p&gt;

&lt;p&gt;How interesting that pushing data around turned out to be so darned fascinating.  I think perhaps it was boring because I was no good at it before.  I just spent a couple days turning a flat HTML table into a normalized SQL table.  A couple years ago I'd have sat there copying and pasting from one file into phpmyadmin.  Now, I bang out some Perl, parse up the HTML, turn it into a SQL query, and run it.  I'm probably at least an order of magnitude more productive now at nearly EVERYTHING than I was even a few years ago.&lt;/p&gt;

&lt;p&gt;No matter what you want to do with computers, whether it be designing games or GUI design or web design or general software engineering or whatever, a huge part of it is going to end up being &quot;playing with data&quot;.  Getting data from here to there, and translating it along the way.  Storing and organizing the data so that you can do something with it.  Your source code itself is just another form of data, on one very important level.  The fact that I find all this so much fun is possibly one of the reasons I so love Perl.&lt;/p&gt;</description></item></channel></rss>

