The Rants, Raves, Gripes, and Prophecies of Paul R. Potts

Contents by Category

Contents by Date

Favorite Links

My Wiki: main entrance
Slashdot
Boing Boing
Truthout
Gwydion Dylan
Paul Graham
Richard P. Gabriel

Wed, 02 Feb 2005 Paul's Current Reading

I used to be able to read about seven books simultaneously and make progress on all of them, keeping a stack by my bed and picking one out as the mood took me. I'm a little more tired these days, especially after cleaning up the kitchen and helping to get Isaac and baby Veronica to bed, but still managing to make slow progress on a few books. This is what is in the pile today:

Jonathan Strange and Mr. Norrell, by Susanna Clarke. This is a hefty fantasy novel. The tone and the overall conceit: that magic is real, but has fallen into disrepute and deperately needs a revival, in early 19th-century England. I love the way she puts together archaic usage. I like the few, dark, and evocative illustrations. I love the digressions told through extensive footnotes. I love the magic: subtle and clever, and far from stereotypical of the genre; very original; it feels somehow true. But the book is starting to drag, and I don't think I'm even yet halfway through it. It is a long story with many subplots. The jury is still out on whether I can reconcile this feeling of length with my enjoyment of the story. Maybe I just need to stick to shorter fare while so much is going on.

The Knight, by Gene Wolfe. Part of the Wizard Knight. I'm a Wolfe fan; I've read the Book of the New Sun books, including the Urth of the New Sun, at least three or four times, and have also read many of his one-off novels including Free Live Free and Pandora by Holly Hollander (that's the title). He writes great short stories, too. I was disappointed, though, by the Long Sun books; they didn't seem to have the depth of the Book of the New Sun, and the story seemed derivative of Phoenix Without Ashes, Harlan Ellison's screenplay for the Starlost, published as a novel in collaboration with Edward Bryant. So far, though, The Knight does not disappoint me. The prose is incredibly tight and evocative. It's written in very short chapters, which works well with the current chunks of time I have available to read. It's like a reaffirmation of just how talented a writer Wolfe really is. I'm very impressed so far.

Radix, by A.A. Attanasio. This is one of his early novels. It is a deeply strange book, filled with neologisms. It isn't a perfectly successful novel. The anti-hero, Sumner Kagan, is a multiple killer, but somehow we are expected to see him redeemed. The neologisms and world-building comes thick and fast, and a lot of it is just too far out there; some strange takeoffs on demonic posession and Zen Buddhism. But the writing is compelling and intriguing and the story, if you can follow it, is at least interesting. I've read this before, but I picked it up again wondering if it would make a little more sense this time. It does, but the ending is still a bizarre mishmash of Kafka and Christ, and I'm having trouble getting through the last few pages. The other books that are part of the Radix "tetralogy," (although they have nothing in particular in common) include Arc of the Dream, Last Legends of Earth, and In Other Worlds. All three are pretty decent, sometimes great, but very different. I should check out his older book Solis. His later work did not look at all interesting to me, but I'm always prepared to be convinced otherwise.

The Broken God, by David Zindell. Zindell wrote Neverness, a standalone novel, and then a trilogy that served as a follow-on; this is the first book of the trilogy. This is big space opera, and detailed world-building in the long "billdungsroman" tradition. I'm re-reading the set. Somehow his main character, Danlo, is very appealing. I've always been a sucker for transcendent, extropian-style stories. Zindell now seems to be writing fantasy, which didn't look interesting, but again I'm always prepared to be convinced otherwise.B

The Complete Roderick, by John Sladek. This is a pair of novels, newly published under one cover. They are deeply satirical, and the characters are fantastic. It reminds me so far of Kurt Vonnegut, but with a more vivid and less dry style.

Quicksilver, by Neal Stephenson. I love Stephenson's writing, including his non-fiction articles for Wired, and I enjoyed Cryptonomicon a lot. This one, I'm sorry to say, is getting the better of me. I may have to set it aside and start over later. I think it is an amazing story, and I love in particular the scenes in which Shaftoe goes mad and starts hallucinating a musical comedy; it reminds me of the Circe chapter of Joyce's Ulysses. But I'm starting to lose track of what is going on, and I've set it aside for too long. By the time I get back to it, maybe the next two will be out in softcover.

What We Do Now, by Dennis Loy Johnson and Valerie Merians (editor). A book of essays on the state of America after the 2004 election. A good antidote to the despair I feel listening to the 2005 State of the Union speech.

The Book of Lost Tales, part 1, by Tolkien and Tolken (Christopher, ed.) I have decided to add to my library the entire 12-volume History of Middle Earth. I've picked at it over the years and considered reading the books, but it seems that I'm finally ready, and can extract a lot of reward from the fragments and their history. I'll put some more about these books under the Tolkien topic heading. I have purchased the first five volumes, which cover the writings prior to the Lord of the Rings. I'll probably purchase the rest sometime this coming month.

I'm also working my way through the Fellowship of the Ring, which I'm reading portions of, aloud, as a bedtime story for Grace, Veronica, and Isaac. We're in the house of Tom Bombadil, which is particularly fun to read out loud, especially after the somewhat slow descriptions of the countryside and landscape that cause the first half of Fellowship to drag a little bit.

Finally, I also have Paul Graham's On Lisp in the stack. The book is out of print, although allegedly it will be reprinted soon, but until then Graham has made the PDF available on his web site, so rather than pay $100 or more for a used copy, I took the PDF file to Kinko's and had a copy printed out and bound. I've been studying Graham's examples of the use of continuations. I feel like I understand them better, although this is the kind of thing that will not be really useful until I play with the code.

[/root/books/reading] permanent link

Wed, 25 Aug 2004 Terry Pratchett's Discworld

I've finished all of Terry Pratchett's Discworld novels (with the exception of the graphic novel The Last Hero, and not counting the other Discworld collaborations like The Discworld Mapp. I have even read a few of them multiple times.

All of the reviews and notes can be found on my Wiki. See the Terry Pratchett page on my Wiki.

That makes up 28 novels, at least until Going Postal is released. I have enjoyed the Discworld books... but I don't think I'll be standing in line for the next one. I'll wait for the paperback, or get it from the library.

[/root/books/fiction] permanent link

Tue, 24 Aug 2004 abebooks

I decided to take abebooks.com for a spin and see what they could do for me. I was particularly interested in tracking down some long out-of-print juvenile science fiction books that I read as a child; I wanted to give them to my son, Isaac.

I quickly found, and ordered, the following:

Ted White, Secret of the Marauder Satellite

James R. Berry, Dar Tellum: Stranger from a Distant Planet

Alfred Slote, My Robot Buddy

Eleanor Cameron, The Wonderful Flight to the Mushroom Planet

Sylvia Louise Engdahl, Enchantress from the Stars

I also found a couple of books for me: a cookbook I used to have called Vegetarian Suppers, with some excellent recipes; an out-of-print programming text called Functional C, and a copy of the trade paperback edition of Heinlein's The Number of the Beast (late Heinlein, not his best writing, but it holds a special place in my heart because I read the first part of the book serialized in Omni magazine and then saved up my allowance to buy it).

I placed this order on the evening of August 14th, so the vendors got the orders on the 15th. The last book arrived today, the 24th. That's nine days to receive eight books from used bookstores all over the country!

I'm really impressed. I was expecting it to take at least two weeks to get everything, and wondering what I would do to track down the one or two books that would, I thought, most likely never show up, but which I'd get billed for anyway. What a pleasant surprise!

I bought Dar Tellum from Scholastic Book Services when I was in perhaps third grade; I can't remember anything about my teacher, the classroom, or the kids. I remember that I was miserable, so I probably took refuge in books. I remember the newsprint order sheets and saving my allowance to buy a few carefully chosen books. Among them were also some turkeys like the Benji movie adaptations, and some science fiction that was not terribly good, like A.E. Van Vogt's pulp Planets for Sale; I decided not to bother tracking that one down.

And I remember this book. Holding it is like looking through a tunnel to a day thirty years ago. It is all here: the psychedelic green-and-black illustrations, the weird lilac color of the title, and the soulful pair of eyes on the front cover. (It helped that I thought I looked, with my platinum blonde hair and blue eyes, a lot like the protagonist). The storyline is about telekinesis, channeling, and global warming: this book is copyrighted 1973. It is a strange and subversive story about civil disobedience and keeping secrets from adults. I feel very proud to be able to pass it on to my son, and very glad that this little piece of my formative years still exists in the world. This book shaped me.

So, I highly recommend abebooks.com. It leaves me wondering if there might be some way I could earn some money and assist some of the local used bookstores in getting their inventory listed. They are clogged with stuff they can't move; Cross Street Books in Ypsilanti, for example, is almost impossible to browse, with books crammed in every available space, piles on the floors blocking access to the shelves, and narrow aisles impossible to negotiate; you feel like you will be crushed by falling books. Surely getting all the stuff they can't move up on abebooks.com would help? I'm living proof that someone will want a book, but the hard part is delivering obscure and relatively worthless (in a monetary sense) books to buyers. It looks like abebooks.com has solved that problem.

Meanwhile, global warming is real; where is Dar Tellum when you need him?

Here's my son's book report. He's ten. I should mention that his reading level is very high but his writing level is a bit sub-par; we're working on that. It is one of the reasons we took him out of school and started home-schooling him. This is a huge improvement over last year. This is his second attempt at a book report; yesterday's was terrible, so he's rewritten it. We may ask him for one more try.

Dar Tellum is a character from the planet sidra. Dar Tellum is like a ghost, a thing, technically. He is also telepathically connected to Ralph.

Ralph is a kid who daydreams a lot. He is the kid who meets Dar Tellum. He is the main character.

Ralph meets Dar Tellum. Ralph learns the world is in danger. Ralph gets the idea. Ralph puts the idea in Dad's briefcase. Ralph and Dar Tellum save the world.

The books writing style is about eight year-old level. The story is interesting, to an extent. The age level is nine, about. The illustrations are good, but have too little color. I recommend it very much to any body who wants a introduction to science fiction.

[/root/books] permanent link

Wed, 05 Nov 2003 Three Books about Ruby

Reviewed in this article:

  1. Yukihiro Matsumoto: Ruby in a Nutshell (O'Reilly, 2002: 204 pages)

  2. Hal Fulton: The Ruby Way (Sams, 2002: 579 pages)

  3. Dave Thomas and Andrew Hunt: Programming Ruby: The Pragmatic Programmer's Guide (Addison-Wesley, 2001: 564 pages)

First she tried Papa Bear's porridge, but it was too hot. Then she tried Mama Bear's porridge, but it was too cold. Then she tried Baby Bear's porridge, and it was just right, so she ate it all up. -- Goldilocks and the Three Bears

Let's suppose that you're an experienced programmer who wants to learn Ruby, or a Ruby programmer who needs a reference. Which of these three books is "just right?"

Ruby in a Nutshell

Let's begin by looking at Ruby in A Nutshell. O'Reilly books tend to have a good reputation, and I've been quite pleased with a number of them, including several other books in the Nutshell line such as Java in a Nutshell. Therefore, it is with considerable disappointment that I'm forced to report that Ruby in a Nutshell is not only the poorest book I've seen in the Nutshell line, but also the poorest O'Reilly book I've ever examined. Obviously, as Goldilocks would say, this one is "too cold!"

To find out why, let's begin with the code sample on page 2:

ary = [1,2,3,4,5]
ary.each do |i|
   puts 1*2
end   # prints 2,3,4,8,10 for each line

Not only is the comment wrong (this example should print 2, 4, 6, 8, and 10, once each), but the code has a bug: the puts statement contains a "1" instead of an "i." That's not inspiring: I'm not sure who to blame, but clearly the editors or technical reviewers did not try the code samples as printed. Let's go on to the next example:

ary = [1,2,3,4,5]
ary = ary.select do |i|
   i %2 == 0
end   # returns array of even numbers

This example also fails! Why? Because Ruby is sensitive to whitespace in certain constructs: the lack of a space between the "%" and the "2" causes trouble. That's two critical typos in two brief examples: not a promising start! Let's move on to the next example:

begin
   f = open(path)
rescue
   puts "#{path} does not exist."
   exit 1
end

This example does not execute, because "path" is undefined. That's a trivial omission, obviously, but again it indicates that no one bothered to make these short examples runnable. That's disappointing.

The next example shows how to use a network socket to retrieve the time:

require "socket"
print TCPSocket.open("localhost", "daytime").gets

This also does not work on my system (running MacOS X). The reason is because my system is not running an appropriate server; I know that, but if I was more of a novice, I might have given up Ruby in disgust by this point (on page 3), mistakenly blaming the language or library implementation. Given that Yukihiro Matsumoto is the author of Ruby, that's obviously not a desirable outcome.

Keep in mind that we are on page 3 of this book, in the introduction, under a heading entitled "Ruby's Elegance." This Nutshell book is clearly not intended as a beginner's tutorial, but does this principle make it acceptable that four of the five code samples in this section do not run as presented? I don't think it does. I think this is just the first warning indication of the disastrous lack of quality in this book. The introduction trails off with a few additional examples, including a minor variation on the socket example already presented and a redundant example of exception handling, but with no further commentary. This entire introductory chapter seems not to whet the appetite to learn Ruby as much as ruin it. However, let's press on and see if it gets better.

The book is quite short (with 204 numbered pages), and that's good. I like short books; as the introduction to Kerninghan and Ritchie's widely-known book The C Programming Language says, a small language "is not well served by a big book." The second chapter, "Language Basics," weighs in at just 30 pages. But it turns out that it isn't the length, it is the organization and presentation of the content. The other Nutshell books do it well; Kerninghan and Ritchie's book does it well. Ruby in a Nutshell does not.

The chapter begins with a description of the command-line options to the Ruby executable and a list of the environment variables that Ruby recognizes. These things would be more properly placed in an appendix devoted to the implementation. We are now left with just 27 to pages to cover the core language. Let me point out a few specific examples that show how the text veers off track.

Under the heading "Literals" and sub-heading "Numbers," we are shown the examples "123," a decimal number, "0377," an octal number, and "0xff," a hexadecimal number. So far, so good. But included in the list is "1_234," listed as "decimal with underline." What does this mean? What is the purpose of writing a decimal number with an embedded underline? (No mention is made of "underline" or "underscore" in the index, and the text offers no clue). That's a very minor example, but it is telling. Update: it turns out this is a feature borrowed from Perl, but I'm not really a Perl expert, and the text should not assume the reader is).

Under "Strings," we're shown the difference between double-quoted and single-quoted strings. On the very next page, though, we see an example of a string in backquotes. No mention is made of backquotes in the index, and backquoted strings are never explained.

I've programmed in Scheme and other languages that support a symbol type; I thought I knew what a symbol was. Under "Symbols," we read that "A symbol is an object corresponding to an identifier or variable." In fact, that's false. A symbol never corresponds to a variable. A symbol is generally made of a string, hashed to a unique object, and usable as a distinguished value. We are shown two examples: ":foo" is described as "symbol for 'foo'." ":" is described as "symbol for variable ''." What this really means is that the first symbol is constructed out of a plain identifier, and the second out of a variable name. Any string can be used to generate a symbol using the Intern method; including a mention of that method here would reassure the user that symbols in Ruby work pretty much like symbols in other languages that support them. Instead, the book is riddled with bizarre and confusing terminology. Matsumoto may not be a native speaker, but he credits editors and reviewers; were they asleep on the job?

On page 16 under "Assigment," we read "The following elements may assign targets." What does that phrase mean? What is an "element?" Why was this text not turned into something more clear, using standard terminology? Under "Operators," we read "most operators are in fact method calls." Then, three lines later, we read "Most operators are actually method calls." Why was this redundancy left in place? Copy-editing should have caught this; this book is very, very poorly edited.

On the next page, under "Range operators," the description of the form "expr1 ... expr2" is "Evaluates expr2 on the iteration after expr1 turns true." Range operators are incredible useful and clever; it is a shame that anyone reading this description will be unlikely to gain any insight into how to use them. In a sidebar on special versions of methods that have "!" or "?" appended (in the Lisp world, methods ending in "!" are generally known as destructive, and methods ending in "?" are generally known as predicates), we read "A question mark ? is appended to a method that determines the state of a Boolean value, true or false." Why wasn't this convoluted sentence edited to say "method that returns a Boolean value?" In the next sentence, we learn that "Attempting to call a method without specifying either its arguments or parentheses in a context in which a local variable of the same name exists results in the method call being interpreted as a reference to the local variable, not a call to the method." This sentence needs at least six prepositional phrases to tell us that a local variable with the same name as a method can shadow the method, if the method call is ambiguous; an brief example here would be worth far more than this convoluted description.

As a further case study, let's take a look at the presentation of one more language construct: Ruby's version of C's switch, in Ruby called case. There are a few key points to keep in mind about the way Ruby implements this construct. The first is that there is no default fall-through, as in C and C++, and hence no need for break statements -- in fact, break may not be used here. The second is that the clauses are evaluated in the order given: this can be important, since clauses may overlap (for example, if they use ranges). The third is that to determine if a clause matches, the "===" operator is used, in a less-than-obvious way (briefly, if a and b are not the same type, then "a === b" does not necessarily imply "b === a." I'll show an example of this later).

Any Ruby reference worth the name should mention these three key points. In Ruby in a Nutshell, we are given a BNF skeleton (it is not quite real BNF, though) and a few lines of description. The lack of default fall-through is not mentioned. The use of "===" is mentioned, but without any detail. The fact that Ruby always evaluates the cases in the listed order is not mentioned. As far as I'm concerned, this presentation of the case statement is close to useless; it could serve to remind someone who already knows Ruby of the syntactical form, like a pocket reference card, but gives almost nothing of the distinguishing semantics for a programmer coming from another language.

I want to look at one more example: the use of while and until as statement modifiers. This is a clever little language feature that lets you write code like this:

greeting = true
print "Hello\n" while greeting

The above code will say "Hello" forever, while this version:

greeting = false
print "Hello\n" while greeting

never says "Hello." It is a somewhat non-obvious detail that when you use while as a modifier at the end a single statement, the condition is evaluated first. This runs contrary to C's do loop form. You can also use while at the end of a block of code:

greeting = false
begin
   print "Hello\n"
end while greeting

but in this case, "Hello" will be printed once; the block is executed once before the condition is evaluated, just like C's do loop.

It is important to me that a book on Ruby should make a clear distinction between these two modes of behavior; Ruby in a Nutshell fails to clearly differentiate the behavior of the single-statement form. Instead we get the terse description "executes code while condition is true" for the single-statement form, and this awful sentence for the second: "If a while modifier follows a begin statement with no rescue or ensure clauses, code is executed once before conditional is evaluated." It is probably technically correct, but at this point in the exposition, it does not clarify anything to bring in rescue and ensure without further elaboration. I should point out that the other two books I'll discuss do explicitly mention this behavior, albeit not necessarily in a prominent way.

Although not billed as a tutorial, by comparison, Python in a Nutshell devotes 39 pages to the Python language, and the chapter is immeasurably more readable and more complete. It is also possible to divine all the tricky parts of Java from Java in a Nutshell; I refer to this book frequently when I've forgotten a detail about, say, inner classes. That just doesn't seem possible with this book. Is this because Ruby is so irregular, with an enormous number of special "quirks?" I don't believe so; Python and Java are certainly "quirky" in places as well (just look at the semantics of bindings from within nested scopes in Python, or the syntax of anonymous inner classes in Java). In a language guide, though, it is essential that any irregular semantics be clearly pointed out, and Ruby in a Nutshell doesn't do this well.

The remainder of the book covers the built-in library (built-in to the interpreter), and the standard library (defined in separately importable modules). This material looks concise (in fact, too concise). For example, suppose I wanted to fix the example given above:

require "socket"
print TCPSocket.open("localhost", "daytime").gets

On page 113, we can find the entry for TCPSocket. It is less than a page in length, and most of the entry is taken up by a longish piece of sample code, and most of that sample is scaffolding. (Again, it isn't the space used, but how it is used). The sample code uses the spelling TCPsocket (note the altered capitalization: another typographical error, but fortunately names in Ruby are not case-sensitive). The example also uses ARGV and thus, as far as I can tell, can't be executed using irb (the command-line Ruby interactor). It uses two additional methods on TCPsocket: addr and peeraddr, but these are not listed in the class methods. It turns out the methods are part of IPSocket, which is the superclass of TCPSocket, so I turned to the entry on IPSocket. The example given for IPSocket is actually an example of how to use TCPSocket (this time with the expected capitalization). This example succeeds in opening an HTTP connection to www.ruby-lang.org. It works, and that's a start, but it's too late to do much to enhance my opinion of Ruby in a Nutshell. It doesn't have to be this way; as I'll show, other authors manage to convey far more useful information in even less space.

For comparison, let's now examine Hal Fulton's book.

The Ruby Way

Fulton's book is much wordier; his text is full of digression, but, more importantly, his text is full of working examples. Confusingly, when he is giving an abstract example to show a form, rather than a piece of executable Ruby code, such as:

case expression
   when value
      some_action
end

This abstract example is not set off in italics or boldface or BNF. In practice, it is usually clear when he is showing an abstract example, but this could be improved. On the bright side, every concrete code example I tried worked perfectly. When Fulton describes Ruby's case statement (p. 55), he provides an example of how the definition of the "===" method on the string class can confuse you.

case /Hell/
   when "Hello"
      print "We matched.\n"
   else
      print "We didn't match.\n"
end

As you might expect after that build-up, the code fragment above prints "We didn't match." Fulton also spends some time explaining the absence of the break statement and lack of default fall-through, and mentions not only that the case "limbs" are evaluated in sequence, but also how the expressions in limbs that are not reached are never evaluated. The key concepts are included, but the result of this wordiness is that Fulton takes nearly 3 pages to explain the case statement.

Would you like to see cookbook examples of using Ruby with strings and queues? Fulton's got them. Did you want to know how to use Ruby to check whether a graph is fully connected? How about whether that graph has a Euler circuit? Fulton's got an example. Sometimes his book veers towards a cookbook, but depending on your needs and skill level, these worked-out examples may be just what you need. While I can live without information on Ruby/Tk and Ruby/GTK, I find the material on threads to be very useful. Ruby has very powerful and concise support for threads, but threads can be hard to understand in any language, and clear examples of how to use them are most welcome. Chater 8, on scripting, is not currently of much interest to me, but another reader might find a great deal of value in using Ruby to write scripts for system administration tasks.

Continuing our example, let's see how Fulton does with his coverage of TCPSocket. First of all, TCPSocket is not in the index. That's a bad sign. TCPServer is, though, and his server example also includes a client that uses uses TCPSocket. Let's see if his example works (from page 420):

require "socket"

PORT = 12321
HOST = ARGV[0] || 'localhost'

server = UDPSocket.open   # Using UDP here...
server.bind(nil, PORT)

loop do
   text, sender = server.recvfrom(1)
   server.send(Time.new.to_s + "\n", 0, sender[3], sender[1])
end

And now Fulton's client code, which I will execute in a different terminal window using another instance of irb:

require "socket"
require "timeout"

PORT = 12321
HOST = ARGV[0] || 'localhost'

socket = UDPSocket.new
socket.connect(HOST, PORT)

socket.send("", 0)
timeout(10) do
   time = socket.gets
   puts time
end

And, in fact, it worked perfectly on the first try. There is something in the level of detail in Fulton's writing that inspires confidence that he has tested his code. From there on, Fulton illustrates a threaded server, and then provides a larger example: a chess server. I have not tested it yet, but so far I have reason to believe that his examples and explanation are both top-notch.

The book does have its weaknesses: the index, as I've mentioned, is not comprehensive, and the typography is also somewhat bland. There are no diagrams to be found, even when one would be useful (for example, in explaining what an Euler circuit is). This book fits my tastes well, but some may consider it "too hot," though: too wordy, and too example-heavy to be the reference I discussed earlier. I think it is great material for any Ruby developer, but is it the best book learning and reference use? To answer that, let's take a look at one more.

Programming Ruby: The Pragmatic Programmer's Guide

If you are interested in reading this book on-line (I usually prefer a paper copy), you can actually find the complete text located here and all the sample code is available here.

The book starts out well: we've got notation conventions! A roadmap! This book has something resembling a recursive structure: different aspects of Ruby are discussed (briefly), then discussed later in much more depth, and sometimes again in close-up. I like that approach. It means we can get into examples quickly. By page ten we're into arrays and hashes, and then on to a brief survey of control structures. Let's take a look at an example (page 11):

if counts > 10
   puts "Try again"
elsif tries == 3
   puts "You lose"
else
   puts "Enter a number"
end

Once again, we've been given a non-working example: the variables "counts" and "tries" are not defined. In case it isn't clear yet, I really don't like non-working examples in programming books. If an example is abstract, use BNF or italicized words; if it is concrete, put in the extra effort into testing and make a usable example. Your opinion on this matter may not be the same, and to the author's credit, it does appear that most later examples in the text are runnable; indeed, they are presented as brief interactive sessions.

Also, if look at the online version of the book's code, you'll find that the code for page 11 has a link called "See hidden code." This link will show the extra lines that make the sample runnable. This seems a bit silly, especially since most of the samples are quite short and including the extra lines in the print version would not have added significantly to the page count. But if you are like me and want to try out the samples as you read them, you might want to follow along on the web site as you read.

After the brief overview chapter, we're right into classes, objects and variables. We work through an extended, semi-real-world example that shows the definition of a toy class and how to play with it. (I don't use the term "toy" here in a disparaging way; tutorial material usually benefits from somewhat scaled-down examples so that the reader can focus on the mechanics, and not the problem domain).

The typography is excellent in this book, yielding a very clean look; arrows in the code samples indicate the results that are returned from various expressions. Diagrams are occasionally used, for example to show how references may be reassigned and objects aliased. This dynamism may be unfamiliar to programmers from coming to Ruby from, for example, C or Pascal (although Java programmers will be familiar with this mode of programming).

Another aspect of this book that I like is the occasional interjection of comparisons with other languages. It is particularly illuminating to discuss Ruby's code blocks this way. A bit like Scheme's closures, code blocks can be difficult for static-language programmers to understand. Programmers coming from languages that don't support higher-order functions may find themselves dismissive of such features. Of course, just about any language feature can be considered "irrelevant" -- why use classes, when we can simulate them with structures? Closures can be used to implement "lightweight" callbacks and maintain state without the need to define extra classes and implement them; they provide a different, highly useful abstraction. To use Ruby to its full potential, you should understand closures, and thus code blocks; this book can help. (Just don't ask me to explain my other favorite programming technique, borrowed from Dylan and Lisp-family languages: currying).

So what about that example given in Ruby in a Nutshell showing an integer containing underscores? In this book, there's an example, and the comment says "underscore ignored." Of course, there is still no "underscore" entry in the index, but at least I got my answer, and it is the answer I expected.

Now, how about that case statement again? This book covers it initially in just over a page; it shows several different (again, unfortunately, non-working) examples illustrating syntactic variations. It points out the use of the "===" operator, but it does not describe the order of evaluation, short-circuiting, the lack of default fall-through, or the specific issue likely to arise when using regular expressions as the the target of the comparison expressions. This makes the explanation a little bit weak; you'd better hope to follow the examples here, because the text will not help you much. But wait! Chapter 18 covers the language again, in yet more depth. This is almost a complete formal treatment, and it is most welcome. Here we learn that case evaluates expressions in order, that it does short-circuiting, how the else clause works, and the additional tidbit that if no case "limb" is chosen, and no else clause is present, the whole expression will silently return nil. And, especially in comparison to Ruby in a Nutshell, he exposition here is crystalline. So we do get just about everything that we need.

The second half of the book is a major reference section, and it is excellent. The layout is very usable, and very short interactive examples are embedded in most of the entries to show how they work. This is an extremely helpful approach. In format, this section is a bit like The Java Almanac. The authors provide an example (I can't quite reproduce their typography, but here is the code):

require "socket"
t = TCPSocket.new('localhost', 'ftp')
t.gets
t.close

This example did not work, at first, because I'm not running an FTP server; enabling the built-in FTP server fixed the problem.

So, is this book "just right?" It seems to be pretty close. If you buy just one of these Ruby books, this one should be it, because it is concise and contains both good tutorial and reference material; in fact, it is pretty much everything that Ruby in a Nutshell should have been, in a slightly wordier form. Sadly, Ruby does not yet have a book that is as concise and elegant as the language itself.

On the other hand, if you can buy two books, and really want to get into what Fulton calls "the Ruby way," and see lots of idiomatic Ruby code, and you don't mind extended cookbook examples and a more expository writing style, I would highly recommend that you buy this book together with Fulton's book. Between the two of them, you should be off and running. As for Ruby in a Nutshell: it seems to be a terrible anomaly in what are generally good O'Reilly books. I only wish I had saved my receipt, and not scribbled corrections and annotations all over the pages in frustration, so that I could get my money back. I also hope O'Reilly will redeem themselves as a publisher with an improved second edition.

Reviewed by Paul R. Potts, paul at the potts house dot org.

[/root/books/nonfiction] permanent link

Wed, 23 Apr 2003 Something Besides Iraq

I'm not going to talk about Iraq today; opinions are long-hardened, and I need to think about something more bearable. I've been raiding the Ann Arbor Public Library. Here's what Paul has been reading, in approximate reverse chronological order, with some brief reviews.

Connie Willis: The Doomsday Book

A beautiful book, but very grim. It uses time travel without resorting to techno-babble or paradox; it portrays the middle ages without resorting to crude stereotyping. It is a bit hard to call it "uplifting," but it does express dramatically the notion that we are all called to be saints to one another, and that ordinary people can come close to that ideal. The story is moving. It gets hold of the reader's feelings but the manipulation is deft. I'm looking forward to reading more of Willis's books.

I generally like harder science fiction, but this was a nice break from that, and reminded me that a lot of my favorite "hard" science-fiction writers are really not very good with the "writer" part.

I'm looking over the reviews on Amazon to see what others thought. A reviewer called it "fun." It seems to me that this is like calling Gorecki's Second Symphony "fun." It is a mournful, but ultimately hopeful, book.

The complaint that the book is a bit long is valid. It is almost six hundred pages; a number of the scenes and conversations that take place in the book's "present" are a bit redundant and some could be combined or trimmed. Amusingly, some Amazon readers think just the opposite; they'd like to see the account of Kirvin's time in the Middle Ages trimmed. But it does not need to be savaged, just pruned, perhaps by a hundred pages; an awful lot of books could benefit from a similar treatment.

Personally I'm a fan of many longer works and like to see what can be achieved by a long work. But I'm a fast reader; it seems to me that the complainers might weighed the book beforehand, skimmed a few pages to get the style, and then decided that they were not likely to have the stamina to make it to the end. (Then again, perhaps that what they did before giving this excellent novel a one-star revew).

Some of the minor characters are a bit flat -- but some people are a bit flat. The characterizations of the household children are amazingly real and unsentimental (her children can be obnoxious, and frequently understand more than the adults think they do). I think being slightly confused by the British English is charming rather than off-putting. The idea that historian studying Middle English today would have difficulty understanding a native of the 1300s seems not only plausible, but likely. Some readers complain that the story moves back and forth between a present- day epidemic and the time of the Black Plague: but it seems to me that this juxtaposition is precisely what makes the book's point.

Robert L. Forward: Rocheworld

This is the author's longer, preferred version of what was originally a short story, later lengthened into a somewhat longer novel. It is a bit patchy: it seems to me that the more-recently revised portions are better, and the overall result flows a little awkwardly, but I have not read the original versions to compare. I'd rate this as somewhat second-rate Forward, but this is still better-than-average hard SF.

The genre is science fiction in the tradition of Dragon's Egg, but this is not quite up to the standard of that classic novel. Forward's human characters are quite weird. They veer wildly between John Glenn test-pilot stereotypes and all-too-human lonely geeks in fuzzy pajamas. I'm not sure I would call them realistic, but they are at least entertaining.

As usual for Forward, the aliens are more interesting. In this case they are mathematical brilliant, brightly-colored underwater clouds who don't have technology, create no artifacts, and spend most of their time surfing. If you don't think too hard about the evolutionary biology (why develop great intelligence if there are no predators and you are virtually immortal?) they are great fun.

Forward is a very sharp physicist and speculates brilliantly about Rocheworld, a binary planet composed of two small planetary bodies in an extremely tight orbit, one covered with water, one dry. He's a firm proponent of the axiom that the universe is not only stranger than we imagine, but stranger than we can imagine. The humans are never quite prepared for what they find around Barnard's Star, just as I doubt we would be. His sail-based propulsion is convincingly drawn; as in Dragon's Egg, the physics are described in more detail in an appendix.

Less convincing is his solution to the problem of keeping humans alive for decades on interstellar journeys: rather than the undergoing the usual cryogenic "cold sleep" to slow the metabolism and prevent boredom and psychosis, his humans take a drug called "No-Die," which prevents them from aging, but has the unfortunate side effect of reducing them, mentally, to first-graders. This is mostly annoying, although mercifully we are not forced to endure very many scenes with of the adult crew reduced to children. There are also some minor subplots that could have been left out without harm. One of the more interesting is the ethical furor over the fact that the journey is one-way. This is of slightly more than academic interest: it may be, for example, quite feasible with existing technology to send humans to Mars. Sending them enough fuel to manage the return trip is, given the cold equations of entirely another order of difficulty. Would you volunteer for that one-way mission?

Some of Forward's predictions seem laughably out-of-date already: he's got great mobile and highly intelligent robots that assist the crew and even "live" on their shoulders or in their hair, but the equipment needed by a character to edit images and video is a bulky console that can't be moved from room to room. This is particularly funny given that I'm writing this on a five-pound portable equipped with iPhoto and iMovie. It's just more proof that science-fiction writers can't necessarily predict the real future any better than the rest of us, but it can still be a lot of fun to watch them in the attempt.

Robert L. Forward: Starquake

A somewhat less-than-stellar sequel to the wonderful and highly influential Dragon's Egg. If you've read Dragon's Egg and liked it a great deal, you will find this worth reading; if you only slightly enjoyed the first book, don't bother. Foreward doesn't come up with anything truly innovative for the sequel, and it has not aged as well as the first book.

(To come: Joe Haldeman's Forever Peace, Terry Pratchett's Moving Pictures, more...)

[/root/books/fiction] permanent link


You are here: root :: books

Creative Commons License

Viewable With Any Browser


You are here:
root :: books