Wednesday, February 07, 2007

My save-excursion

A friend of mine on a neighboring team at Google presented me with an interesting math problem the other day. It went like this:

Friend: Hey Stevey!

Me: Uh, you know people don't actually call me that to my face, right? Only behind my back.

Friend: (cheerily) But you're Stevey! Look at your badge!

Me: Sigh. OK, fine already. What's this math problem?

Friend: Let's say there's this hypothetical blogger who writes for 4 hours a month, and he desperately needs an editor who will never materialize, and in those 4 hours he produces very... large... ummm...

Me: And what exactly are you trying to say there, ex-friend?

Ex-friend: Oh, nothing! It's purely hypothetical! I'm just saying that I, er, well, I've been reading for hours and I'm only half done with your last blog entry, and I accidentally fell asleep and had a wonderful dream that I was finished reading it, and then I woke up and my keyboard was gone. Plus I'm still not done yet.

Me: That was a pretty long story.

Ex-friend: (reading what I wrote) That's not what I said! What do you mean the keyboard was gone?

Me: Uh, never mind. I'll fix it in the real blog.

Ex-friend: Fine. Whatever. Anyway, we were all thinking...

Me: Oh! So it's "we" now, is it? And who are my other ex-friends in this particular hypothetical situation?

Ex-friend: Jared and Todd and Jeremy.

Me: B-b-but — you can't say their names in my blog!

Ex-friend: Oopsie.

Me: There are people listening!

Ex-friend: No, Stevey, I think your readers all died of starvation on account of trying to finish your blogs in one sitting.

Me: D'oh! OK. Yeah. I think I get it. You're saying — and correct me if I'm wrong here — that if I write for an hour a week, I'll produce blogs that are only like 600 times too long, rather than the usual, ah...

Really-ex-friend-now: 2400.

Me: Ouch! That's just... low. (frowning vaguely, looking at my fingers) I know how to multiply, you know. I was just thinking about something else, that's all.

Really-ex-friend-now: Well, we think maybe you should give it a try! Just one hour a week. You could be, like, a columnist.

Me: Yeah! I won't get paid, and nobody will read any of it, but otherwise it's pretty much exactly the same as a columnist in all respects. I can be like... like Paul Graham, and sit around in my underwear writing articles about how I get to sit around in my underwear writing articles about stuff, on account of having written everything in Lisp. Except I'll still have to wear pants.

Friend: Um. (edging nervously towards the door) So does this mean I don't have to finish that last blog about Cinderella?

Me: *sigh* Pinocchio. And no, you don't have to finish it. He dies at the end, anyway.

Friend: (sympathetic frowny-face) Sad. (runs out)

Stevey's Blog... Column... Thing.

So! I'm going to try writing for an hour a week, and also try limiting my blog to a certain number of words that columnists apparently never actually discuss but which appears to be around 800, and we'll see if it nets me fewer complaints. And I'm going to start... last Friday! This blog is officially 3 days late, but I figured apologizing could get me a couple of extra words.

As of that last paragraph, I was at 2338 chars, or 437 five-letter words, at least in the first draft. I'll spend the rest of today's entry explaining how I knew that.

Since I'm writing this in Emacs (where else?) I need an Emacs command that will count the non-whitespace characters in the current buffer and tell me how many there are so far, plus divide by five to show how many "words" I've written, since as we all know from fifth-grade English class, words are always five letters.

First I type C-x 2 and switch to my *scratch* buffer. You can write lisp code there. When it's tested, you can copy it into a file somewhere that's loaded by your .emacs.

I start with the basic interactive function skeleton:

(defun blog-column-length ()
"Print stats on current blog column, or blogollum, or whatever"
(interactive)
(message "hi there"))

That's pretty much the minimal command you can invoke with M-x. After typing it out, I put the cursor anywhere inside the function definition and type M-C-x (i.e., Ctrl-Alt-x) to evaluate it. Note that we don't have to restart Emacs to do this. *Ahem*. At least Eclipse comes with free bullets.

Now we can type M-x blog-column-length to see the "hi there" message printed to the minibuffer. If I were doing lots of output, I could use with-output-to-temp-buffer, but I figure this can just be a one-liner. The (message) function takes arguments similar to C's printf.

Note: by evaluating my function, I've fully integrated it into Emacs. I can tab-complete the command name, do M-x describe-function to read the help string, do M-x apropos blog to find it in the list of commands that have 'blog' in the name, and so on. Emacs is cool. Why aren't all editors like this?

I mean, if you were trying to follow along with our little exercise in Eclipse, at this point you might have it out of the box, maybe, but there would be parts all over the floor, styrofoam everywhere, and you'd be staring at the 10-page Hello, World demo trying to figure out where main() goes. Good ole Eclipse. And I hear the Visual Studio team was jealous of Eclipse's "lightweight" plugin system. (Is it any wonder that developers never customize their tools? Jeez.)

Anyway, all that's left is to count the characters. It helps to know one wacky thing about Emacs: most functions are written as scripted versions of exactly what you would have done by hand. That's how it got to be called "Emacs" — Editor Macros. As you learn the editor commands, you're also learning how to program Emacs, because you can use all those commands in your elisp code. Sweet!

There are lots of ways to count the non-whitespace characters in the buffer, but the first one that came to mind is to go to the beginning of the buffer and start looking at each character, incrementing some counter if it's not whitespace, and keep going until we get to the end of the buffer.

So that's what we'll do. First, go to the beginning of the buffer:
(goto-char (point-min))

You could also use
(beginning-of-buffer)
if you prefer. No biggie.

Then we need a loop. How about "while"? Sounds good to me. Let's loop while we're not at the end of the buffer:
(while (not (eobp))
)
It's good to know all the little functions for testing if you're at the beginning of the line (bolp), end of line (eolp), beginning of buffer (bobp), end of buffer (eobp), etc. 'p' means predicate; i.e. a function that returns true/false. It's just a lispy naming convention.

Oh, let's wrap the whole thing in a save-excursion. That's an emacs macro that saves/restores the point and mark around any editing operations. If you want to be able to run your command without affecting the user's actual cursor position, use save-excursion. You see it all over. There's even a haiku about it:
The friends chat gaily,
I stand up to join their talk.
My save-excursion.

Really. It's a real Emacs haiku. Look it up! The only Eclipse haiku I know goes like this:
startApplication()
thenWaitFriggingForever()
thenItGoesRealSlow()

That's what they used to say about Emacs, but then hardware got faster so they needed a new elephant.

Anyway, here's what we've got so far:
(defun blog-column-length ()
"Print stats on current blog column, or blogollum, or whatever"
(interactive)
(save-excursion
(goto-char (point-min))
(while (not (eobp))
;; we're going to increment a counter in here
)
(message "count will be displayed here")))

First, we need to declare a variable. I'm tellin' ya: declaring your variables is all the rage these days.
(let ((char-count 0))

This declares a variable char-count, initialized to zero, within the scope of the let-block, which is sort of like a curly-brace block in C or Java. The extra parens date back to 1955, and they get real grumpy if you mention them, so let's not.

Next we need to say "unless we're looking at a whitespace char, increment char-count". Here's how:
(unless (looking-at "[ \t\r\n]")
(incf char-count))

Gosh. And everyone always says they despise Lisp. It's not that hard, is it? The only trick is knowing where to put the parentheses, and that's easy. It's just (function arg arg arg). If arg is a call to a function, then you parenthesize it, and it all nests nicely, sorta like XML but without all the yelling.

Plus those extra ones around the let-declaration, but we don't talk about them, remember? That's how you remember them.

Then we move the cursor forward:
(forward-char 1)

Putting it all together:
(defun blog-column-length ()
"Print stats on current blog column, or blogollum, or whatever"
(interactive)
(save-excursion
(goto-char (point-min))
(let ((char-count 0))
(while (not (eobp))
(unless (looking-at "[ \t\r\n]")
(incf char-count))
(forward-char 1))
(message "%d chars, %d words" char-count (/ char-count 5)))))

Et voila. Almost exactly 1 hour. Well, 90 minutes, but who's counting.

6936 chars, 1387 words. OK, it's a little longer than my target, but what's a few words in the pursuit of Emacs education between friends? Plus I got a couple of jabs in at Eclipse, so it's not a total loss.

See you all next week!

45 Comments:

Blogger rsc said...

One word, and a number: wc(1)

5:04 AM, February 07, 2007  
Blogger Unknown said...

> (message "%d words" (/ char-count 5))

I see what you did there stevey... (come on you could at least have given us a real word-counting facility not that hack)

> One word, and a number: wc(1)

One line, and an error:

$ wc *scratch*
wc: *scratch*: open: No such file or directory

Oh jeez, doesn't work on random Emacs buffer, how surprising...

5:29 AM, February 07, 2007  
Blogger Tom said...

He he, I like your humorous post.
Disguising a lisp/emacs tutorial inside a purposely flawed labour-intensive method of doing a word count is brilliant. I would laugh out loud except there's noone near to hear me.

What version of emacs do you use cos your macro doesn't work on Emacs 21.3.1 on Windows until the (incf char-count)) is replaced with (setq char-count (+ 1 char-count))).

Also, the code that you've got after you say "Anyway, here's what we've got so far:" puts emacs into an infinite loop. Thanks for that. :-)

Cheers,
Tom Fotherby

5:30 AM, February 07, 2007  
Blogger Aubrey Keus said...

Good luck on the weekly blogging. I think I still prefer the monster novel length posts. Going to miss them.

5:51 AM, February 07, 2007  
Blogger kdsfjaskldf said...

:! wc %

Oh the humanity! ;]

6:26 AM, February 07, 2007  
Blogger Andrew Stein said...

C-x h M-| wc

Spelled out: mark-whole-buffer then shell-command-on-region with wc.

Works on *scratch* and any other buffer.

7:27 AM, February 07, 2007  
Blogger Matt Brandt said...

Hey, you don't have to use wierd, obscure editors like emacs to have decent programmability. I use TextMate on the mac and I can do my macros in ruby, perl, shell script, or just about anything else (probably even lisp). Emacs is cool, but it's only cool in a retro 1970 kind of way...

8:17 AM, February 07, 2007  
Blogger Unknown said...

Aw, I tried to resist the urge..

Why characterize Emacs as weird and obscure? I know *tons* of developers who use it (and use it well) and coincidentally are some of the smartest, best developers I know. Perhaps it's not the editor for the masses...

9:03 AM, February 07, 2007  
Blogger Ethan Herdrick said...

First of all, your 'pinocchio' essay is one of the very best things I've ever read on software, especially in the 'programmer general interest' category. I'm currently annoying all my programmer friends by demanding they read it immediately (and I think it's better than that, BTW; I think it's moved into the special category of writing where people outside the field should try reading it, too.)

Second, how in the heck did you write so much in an hour? And did you really write the pinocchio essay in 6 1/2 hours? This seems basically impossible. There are a ton of original thoughts there, well organized, and completely accessable to people living outside your brain. I can't imagine that you knew everything that you wrote before you started; people who write on difficult topics end up learning a lot while doing it. That takes time. And did you not have to rewrite it? Are you saying that it just flowed out on the page in an easy conversational tone like that?

For the record, this crummy little post took me some twenty minutes (including glancing at the pinocchio post again, editing, reading it at a speaking pace, etc.)

9:20 AM, February 07, 2007  
Blogger Jesse Millikan said...

I wondered the same thing as Tom the *last* time you taught us Emacs Lisp. It's Emacs 22. I got it from here, for Windows:

http://ourcomments.org/Emacs/EmacsW32.html#form3

10:24 AM, February 07, 2007  
Blogger Peter said...

Having powerful scripting support is really nice to have in a programmer's text editor. I use TextMate for this purpose, and in it you can do automation in any language that your machine can run. I threw together a little script that does something similar to the one you outline here that uses ruby and displays its result as a tooltip.

It ended up being relatively elegant, but I wish that ruby's String.to_a method behaved like split("").

10:42 AM, February 07, 2007  
Blogger Derek said...

I usually use the strategy suggested by `andrew'. The disadvantage, of course, is that you need `wc', which means on w32 you need to install something extra. In any case, it can be pretty easily command-ized:

(defun blog-column-length ()
(interactive)
(shell-command-on-region (point-min) (point-max) "wc"))

11:11 AM, February 07, 2007  
Blogger Unknown said...

Does your Emacs not come with count-words-region and count-words-buffer?

11:14 AM, February 07, 2007  
Blogger Unknown said...

FWIW, I prefer the "tsunami of wisdom"-style prose of your previous posts. People are claiming to fall asleep, when, in reality, they're fleeing in terror. Why change a winning formula?

11:20 AM, February 07, 2007  
Blogger Benjamin said...

What's kind of funny is that there is an exercise to develop count-words-region in Programming in Emacs Lisp, which results in this:

;;; Final version: while
(defun count-words-region (beginning end)
"Print number of words in the region."
(interactive "r")
(message "Counting words in region ... ")

;;; 1. Set up appropriate conditions.
(save-excursion
(let ((count 0))
(goto-char beginning)

;;; 2. Run the while loop.
(while (and (< (point) end)
(re-search-forward "\\w+\\W*" end t))
(setq count (1+ count)))

;;; 3. Send a message to the user.
(cond ((zerop count)
(message
"The region does NOT have any words."))
((= 1 count)
(message
"The region has 1 word."))
(t
(message
"The region has %d words." count))))))

12:13 PM, February 07, 2007  
Blogger Dan Nugent said...

This is precisely why Lisp gets a bad name Steve. Re-inventing circular devices for the purpose of movement for no god damned good reason other than to, ostensibly demonstrate how much of a Lisp weenie the author is.

1:07 PM, February 07, 2007  
Blogger Steve Yegge said...

Huh. Dan, it doesn't seem like that big a deal to me, since writing the Lisp function took less than a minute. You can invoke shell commands from Emacs, but it's not as portable (e.g. I run NT Emacs on Windows boxes using my same elisp files).

The thing is, the word stat function I wrote is just a placeholder. Each time I write a blog I'll add some new stat to it. I may fundamentally change the way I'm processing the buffer, but at least I'll have the boilerplate and the command name that I'm already used to.

Don't you people ever script your environments? Seriously, I don't care if it's elisp or perl or ruby or python or tcl or -anything-, as long as you write scripts. I mean, hell, you should do it once in a while just for the practice. (That's how this function took me less than a minute from idea to working implementation - I practice!)

As far as writing it in 90 minutes (and Pinoccio in 6 hours), well, I have an absolutely huge backlog of stuff I'm thinking about that I haven't blogged about. A lot of it is in random email threads I've had going with friends for (sometimes) years. Sometimes it's discussions that keep recurring at work. In any case, I'm not sitting around trying to think of things to say when I blog - I'm trying to shove a whale through a keyhole.

2:32 PM, February 07, 2007  
Blogger Derek said...

Yes, I script my environment ... and what fun it is, too. :)

(defun exists-in-exec-path (exact-name)
(catch 'found
(dolist (dir exec-path)
(when (file-exists-p (concat (file-name-as-directory dir) exact-name))
(throw 'found t)))
nil))

(defun blog-column-length ()
(interactive)
(let ((w32 (string-equal system-type "windows-nt")))
(if (or (not w32) (exists-in-exec-path "wc.exe"))
(shell-command-on-region (point-min) (point-max) "wc")
(browse-url "http://gnuwin32.sourceforge.net/downlinks/coreutils.php"))))

4:10 PM, February 07, 2007  
Blogger Unknown said...

peter: I'm starting to understand how textmate can be appealing.... very nice..

5:19 PM, February 07, 2007  
Blogger Jacob Gabrielson said...

I would like to point out a few problems with your code, and Emacs Lisp in general. You have to admit, it's not very object-oriented. It's like you're using a language that's 30+ years old and somehow suggesting that it's actually better than more recent languages like Java? Do you really expect anyone to believe that? In fact, I'm going to prove Java's vast superiority right here and now!

For one thing, there's no compile-time type checking going on here. What if you had made a mistake and called looking-at on the wrong type of object? Well, you wouldn't find out until run-time, and in the intervening moments between writing the code and actually running it, the Earth might spontaneously combust. I hope you have a clear conscience. Anyway, there's just no way for Emacs Lisp to catch this at compile time! In Java this wouldn't be possible because lookingAt() would have to be declared to take a String argument. I.e., it would be strongly typed. And stronger is better than weaker.

That brings me to another criticism. There's no public/private/protected declarations here! Maybe (eobp) shouldn't be called by just any old code. What if the programmer didn't know what they were doing, or in some way were not authorized to call eobp? Did you ever think of that? eobp should have to be declared public in order for you to call it. And who's allowed to call your blog-column-length function? Is it meant to be publicly exposed to the unwashed programming masses, or is it in fact intended exclusively to be used only by the elite masters of the art? Again, another concept you cannot readily express in Emacs Lisp.

Furthermore, your function doesn't declare what exceptions it might throw, so someone calling the function could be horribly surprised. Or even if it doesn't throw any exceptions, how are they suppopsed to know that? If I were trying to call your function from a method I was writing (BTW I can't believe you'd write a function that wasn't part of an object; cool programmers stopped writing bare functions about 20 years ago), I'd be quaking in my proverbial boots the whole time, wondering if it might throw an exception! I don't think I'd be able to get to sleep that night, and in fact might wind up having insomnia for the better part of the fiscal year.

Anyway, I could go on like this but I think you get the idea. Learn a modern language like Java and start blogging about that, please.

6:26 PM, February 07, 2007  
Blogger Unknown said...

j4g:

exactly right, but I think you left out a few key criticisms of the aforementioned approach.

What if this function needed to be made available to outside processes? I see virtually no framework in place that would make this function easily executable via XML-RPC or SOAP.

I think we can all agree that nothing of any consequence exists without this capability.

7:21 PM, February 07, 2007  
Anonymous Anonymous said...

Hammers and nuts ;-)

[C-home] M-x how-many RET \> RET

I think a word count function could be the basis of a good Emacs/Elisp tutorial though - perhaps one that demonstrates how to put stuff in the modeline or in a tooltip.

7:28 PM, February 07, 2007  
Blogger bairui said...

Thought I'd see how it looked in my ruby-enabled vim (as a single ex command line):

:rub c=0.0; b=VIM::Buffer.current; b.count.times {|l| c += b[l+1].squeeze.size}; print "#{c} chars, #{c/5} words"

And, yes, others have said that :!wc % is simpler, but that misses the point. What if there's no binary/script out in shell-land for what you want to do? Steve demonstrates how to extend your(self and) editor with a familiar example that only seems overly complex because of the very simplicity of the example.

Had Steve used a more complex example that warranted this and actual extreme coding, the comments would instead range from "it looks like it could be cool, but I don't quite grok it yet..." to "...stupid lisp weenie!".

Oh, wait...

Oh well, for what it's worth (and I don't use Emacs, clearly), good stuff, Steve. I'd be interested in seeing more ideas you have for scripting your editor, and I'll try them in vim too. :-)

However, as some of the others have lamented, I too curse the days between installments of the Stevie Monolithologues. So, you know, a return to the Pinocchio posts would be cool too...

11:40 PM, February 07, 2007  
Blogger kathy said...

jg4

Why on earths name do you want everything OO. it's just a simple function and going OO is complete overkill.
A programmer that's not knowing what he is doing should not be a programmer that's why you have documentation. If you try to write the same sub in Java you would need at least 2 times as much code. And why use a not native language for scripting a tool if you can accomplish the same thing in a native one. Broaden your horizons there's more then OO and TS. Flexibility has other advantages, not writing lots of large Interfaces for the benefit of only a few classes and don't forget the implementation of all the needed interfaces in classes.
Steve has written a nice easy example on how it can be done and I think he used the way that's the easiest for him to use at this moment, it's like premature optimization, don't do it unless it's one of the basic tricks.
Can't wait to read "next" weeks entry.

12:19 AM, February 08, 2007  
Blogger yehnan said...

I like your style. Blazing lengthy. That's you.
Suggestion: print the blog in dead-wood format and treat it like a chapter, digest it step by step.

3:14 AM, February 08, 2007  
Blogger stromboli said...

j4g and fawlty: I agree, but I would add in to the design maybe an abstract factory, a data access object, separate some concerns and inject some dependencies, or you'll never get this proposal past the architecture team.

4:13 AM, February 08, 2007  
Blogger Unknown said...

Stephan: No way, you can't just go around writing your own DAOs when the architecture team is working on the ORM framework that's almost completely but not quite different from Hibernate.

And you forgot the security issues: where's the authentication and authorization code for accessing the scratch buffer? Then again, it's okay as long as you're planning to bolt it on afterwards using AOP.

4:41 AM, February 08, 2007  
Blogger Unknown said...

Personally I never find your posts too long. I would rather that you posted more frequently myself.

5:48 AM, February 08, 2007  
Blogger ndimiduk said...

I will miss your epic "Monolithologues"!! (nice word barry) I fear you will be unable to convey your ideas as clearly or as thoroughly in a restricted format and the last thing we need is another talking head "paid" by the (5-character) word.

Indeed not! I propose, as a community service, Google should provide you with no less than a full day each work week in which to organize your thought sand produce these works. Surely the cost to the company could be mitigated via their ad service. For the community!

7:24 AM, February 08, 2007  
Blogger laz said...

Barry, in your vim example wouldn't you want to use gsub(/[ \r\n\t]/, '') instead of squeeze to match what the Emacs code is doing?

9:22 AM, February 08, 2007  
Blogger Unknown said...

"Pedants Anonymous" is opening a new chapter for the Internet City. Thank you for providing a place where we can find SO MANY potential new members. Scanning your comment log weekly will swell our ranks for sure. And remember, denial is the first step to recovery.

Keep on Bloggin'

3:45 PM, February 08, 2007  
Blogger Olie said...

Hey, I was just bitching to friends about how you don't blog enough -- 1/week is GREAT!

And I don't care about long. I *LIKE* your long -- it's part of your ...uh... "charm" (you know what I mean.) As far as I'm concerned, the best thign would be if you accidentally started blogging 4 hrs/week.

But we understand that life is busy, too -- so if there have to be cliff-hangers & "to be continued..." and whatnot, that's ok!

Yay, Stevie!

A fan.

9:50 PM, February 08, 2007  
Blogger bairui said...

haha... D'Oh!

Larry, you are so right.

I clearly haven't actually *used* squeeze in any of my rubying (it's a lame excuse, I know, but I am still transitioning from perl... :-) ), but when I was browsing through the built-ins and I saw 'squeeze' I thought to myself: how cool! a method to rip all whitespace out a string!

I mean, strip sees to the ends, why not squeeze out the middle bits too...?

Is there such a beast in the standard libs / builtins (apart from the gsub swis army method)? It's a shame, really: squeeze looks prettier than the gsub way. :-)

So, thanks for the correction. I'll update my code.

Cheers.

4:29 AM, February 09, 2007  
Blogger Olie said...

An idea that may help those of us concerned about SteveY's (<g>) 1000-word style:

* As Steve points out, "every kindergardener knows that a word is 5 letters".

* It's well accepted that smarter people use bigger words.

* I think I'll get little argument that Steve is at least three times as smart as your average kindergardener ;)

THEREFORE, he should adjust his counter to divide his word-counter to divide text-length by 15, instead of 5.

Also, every good blogger knows that this is NOT a print medium, and you don't have an editor breathing down your neck trying to make things come out to EXACTLY 983 words, so they can squeeze in the latest ad for NuSoap. THAT is the miracle of the rubber-paper on which we blog...!

So go ahead and let those 1000 15-letter words turn into 1250 or 1500 or, heck, even 2000. Remember: you brilliant people need to take time to spell things out for the rest of us!

(And thanks for doing so -- huge fan, here. I can't tell you how often I use your stuff to try to invigorate folks at work :)

7:07 AM, February 09, 2007  
Blogger Steve Yegge said...

Olie, dammit, you beat me to it. I was going to make an argument for 23-letter words in my next blog.

Didn't anyone else find j4g's comment hysterically funny? It was beautiful satire. Everyone seems to think it was serious.

Come to think of it, I think I know who j4g is... yup. Heya Jacob. :)

6:49 PM, February 10, 2007  
Blogger Drew @ Cook Like Your Grandmother said...

Steve, two people extended j4g's satire, only one seemed to take it seriously. (Unless that was also satirical, though I didn't read it that way.)

9:55 AM, February 12, 2007  
Blogger B said...

--What is your goal in writing this blog? Is it to maximize shareholder value or get ideas out?

Me, I just finished a post on my own blog on judicial activism, and ya know what?

$ wc -w 207-judicial_theories.tex
2145

Add in the picture worth a thousand words and it's actually 3,145 words.

Ya know how many people are going to click through on that link above? None, and do I ever not care. I've got my readers, I've got my intent for writing, and none of it is about pleasing all the people all the time.



--Editing takes time, but is worth it, in my opinion. I've written loads of 700-750 word essays for newspapers and magazines that you have read, and the hard part is not writing the thing in the first place, but cutting it down and still getting across a complex sentiment.

Newspapers care, because if you spend ten minutes rewriting to save save ten thousand readers ten seconds each, then you've saved [shell to bc here] over twenty-seven person hours with a ten minute investment.

Summing up a comment that needs editing, I'd recommend one of two options:

--Your readers are smart enough to skim, so write like you're comfortable. If you only write short essays, you'll only get across simple ideas. Between a 1,000 word EMACS tutorial and a 4,000 word commentary on the future of distributed computing, I know which I'd pick.

--Spend your four hours with three hours writing and one hour editing. The more practice you get editing, the easier and more pleasant it'll be, and the better your output will be. After mercilessly commenting out long blocks of text, you'll be able to produce 2,000 word essays that have the force and content of the 4,000 word essays.

Whatever you do, don't restrict yourself only to ideas that can only be expressed within the attention span of the average loser on the Net. The medium is not about winning over the lowest common denominator.

2:29 PM, February 16, 2007  
Blogger Ryan said...

I have finally figured out why I dislike Java.

Essentially it boils down to the fact the language treats you like a child. Also as an unfortunate side effect people write endless amounts of code to make up for ... well who knows.

Remember: the bugs per line of code is a constant. Therefore a system with less lines is also therefore a less buggy system. QED.

2:26 AM, February 17, 2007  
Blogger Unknown said...

Thanks, Steve, for such an entertaining and educational post.

(Steve Yegge is my soul mate!!)

2:24 PM, February 17, 2007  
Blogger Anupam Kapoor said...

,----
| startApplication()
| thenWaitFriggingForever()
| thenItGoesRealSlow()
`----
is it java ?

12:14 AM, February 21, 2007  
Blogger Kevin Pauli said...

I use Eclipse for Java development, but I am open minded. It would be nice to be proficient on a lean, mean, extendable IDE... I would invest the time to learn Emacs but there are some things I need from my IDE that I'd rather not have to write the plugins for myself. Can you Emacs gurus tell me if Emacs would give me:

* full featured interactive debugger with breakpoints, watch expressions, ability to change variable values, etc.

* code completion

* jump to method or variable declaration (i.e. F3 on Eclipse)

* type hierarchy browser (i.e. F4 on Eclipse)

* method call hierarchy (i.e. ctrl-alt-H on Eclipse, which shows a tree structure showing who calls this method, and then expanding another level shows who calls that method, ad infinitum)

* Type browser (i.e. ctrl-shift-T in eclipse) which lets me quickly find classes regardless of what package they are in

* automatic refactoring operations (renaming members, extracting/inlining methods, changing method signatures, etc.)

* auto background compilation that gives rollup indications of errors and warnings (i.e. the little red x's and caution signs in Eclipse)

* collapsed "outline" views of my classes

* ability to store runtime configs that specify the arguments, classpath, JRE, working directory, etc.

* plugins for CVS/SVN with visual diffs

* incremental, forgiving compilation which allows refactoring and code completion even for classes that are currently "broken" and won't officially compile

There are lots of other features of course, but these are the ones I seem to depend upon on a daily basis.

This is not a troll, I really am curious if Emacs is suitable for use as an IDE on a large Java project.

3:45 PM, March 08, 2007  
Blogger Donnie Cameron said...

How about this?

(count-matches "[a-zA-Z0-9]+")

10:16 AM, March 30, 2007  
Blogger Richard said...

donnie, if Steve did that, then he could pad his blog with @%#%* expletives without going over his target wordcount.

2:09 PM, April 30, 2007  
Blogger kaldrenon said...

I like the part where you imply that your posts are too long.

Your Drunken Blog Rants, for the most part, had few to no comments on them, so I was used to the end of the article lining up with the scroll bar hitting the bottom of the window. Now that you've enabled comments on this site, I have a tendency to get about halfway down the page and then go, "Oh. Darn. Other people."

Long entries would only be a problem if you weren't, y'know...interesting.

12:37 PM, July 06, 2007  
Blogger quasi said...

this comment is in context with your older rant about text processing and lisp. :) Common Lisp has a complete Perl compatible REGEX library which is much faster than perl. We use CL in production for the past 13 months and it has proven to be extremely stable, fast and mature. Yes, it lacked a few standard type libraries - but if you get stuck with minor hassels, you got no one to blame but yourself. But CL allowed a motley crew of 3 to do stuff which was impossible otherwise...

2:44 PM, August 27, 2007  

<< Home