Thursday, January 17, 2008

Required Reading: The Role of the Study of Programming Languages...

Via the always excellent Patrick Logan -- Daniel Friedman: The Role of the Study of Programming Languages in the Education of a Programmer.

Some key quotes:

  • On the lack of tail call support in Java:
    Guy Steele...was promised back in 1997 that this flaw would be fixed. Here it is 2001 and there is still no resolution of this problem on the horizon.
    Emphasis mine. The more things change...

  • On Friedman's own background and educational goals:
    Later, I wanted to be able to implement a language per week.
    Followed later by:
    I want the student to be able to implement (perhaps crudely) every language that they study...
    Now that's Thinking Different.

  • Friedman quoting Jonathan Sobel, a former student who successfully used (uses?) these concepts in practice:
    Efficiency comes from elegant solutions, not optimized programs. Optimization is just a few correctness-preserving transformations away.

  • Finally, and perhaps my favorite, Patrick Logan's cogent take:
    Probably programming in C itself (or Java or Scala) is a kind of premature optimization.
WARNING: Refers to -- and poses some examples in -- the lambda calculus. Implementations in Scheme. Don't let either of those put you off, though. I don't understand every line of code (yet), but I've seen enough to be inspired to figure it out.

Challenge yourself.

Friday, January 04, 2008

Java Generics Broken? We Report, You Decide.

Since I've been taken to task in the past for my cogent observations of Java's, um, shall we say "unintuitive" behavior, particularly in the era of generics and autoboxing, I'm just going to put this one out there without making any (public (explicit)) value judgments.

So it seems that if you define a method thusly (note: requires Java 5 ("Gangly Geek") or better greater having a numerically higher version number):
public void doSomethingGenerically(Collection<Supertype>){...}
and you attempt to call it thusly:
List<SubtypeOfSupertype> bogus = new ArrayList<SubtypeOfSupertype>();
doSomethingGenerically(bogus);
you get a compiler error saying you can't call that method with those arguments.

So my question here is: why the heck not?

Inheritance 101: a List isa Collection, right? A SubtypeOfSupertype isa Supertype, right? So why am I being told that an instance of type List<SubtypeOfSupertype> isn'ta Collection<Supertype>?

Paging Dr. Liskov...

Monday, November 12, 2007

Blast From the Past: HP 11C

Whilst doing some major cleaning up / throwing away of some of my accumulated junk this weekend, I came across my scientific calculator from college.


"Big deal", you say? Maybe so. But this thing is 23-24 years old, which is about 2400 in computer years, which puts it close to the technical definition of "antique". (Author's Note: We won't get into what that makes me...)


Still not impressed? The thing still works. With the original batteries.

You read that right. After a year or so of use, every time I turned the thing on I would wonder if this was the day I was going to have to change the batteries. Nearly 25 years later, that day still hasn't come. Now granted, for the past several years I wasn't even sure I still had it. But when I came across it in my junk-cleaning I couldn't resist the temptation to try it out. I suppose I should've been surprised, but I wasn't really.

I'm telling you, this is the Calculator That Time Forgot. This is the Calculator of Dorian Gray. I'm going to have to hold some kind of ceremony when it finally does give up the electronic ghost. But I'm not holding my breath.

Tuesday, November 06, 2007

Strike!

Dear Striking Writers Guild of America People,

First off, let me just say that I in no way want to impede your constitutionally protected right to effectively quit your jobs and be guaranteed that you'll get them back once your demands are met. That is some constitutionally protected right, right there. Anyways, God love you and I hope you get your residuals. Power to the proletariat, and all that.

But I do have a favor to ask. You see, the only new thing on TV for a while is going to be news footage of your picketing, and I think you owe it to yourselves (not to us, don't get me wrong here; you're on strike, I get that) to punch up your picketing chants a little. Maybe it's just me, but I kind of expect your strike chants to be more...I don't know...pithy? Trenchant? Heart-wrenchingly but ultimately stirringly observational of the Human Condition?

I mean (this is an actual WGA picket line chant): "Why make the viewers wait? Why won't you negotiate?". Really? That's the best the WGA -- the WGA! -- could come up with? I realize you're doing what you do best -- rehash old material -- but come on. You have so much better old material to work with. Some suggestions:
We won't write another role! *bleep* you, *bleep*hole!
More new films for Jean-Claude Van Damme? Frankly, my dear, I don't give a damn!
Did Tony Soprano's family get whacked? We won't tell you, 'cause we're so hacked!
No more Die Hard on Blu-Ray! Mother *bleep*er, yippie-ki-yay!
Won't give us the money we lack?! Then the Terminator will never be back!

You could go the nostalgic route, and remind us of everything you've done for us in the past, and what we'd be missing without you:
Star Trek! Numb3rs! Stand By Me! No Wil Wheaton on TV!

Or, and this is my favorite option, you could go beyond the traditional chant-based approach and actually stage your picket lines like the different genres you write for. You guys are writers, for pity's sake! You need to keep your chops up. Everyone who isn't actually walking a picket line at the moment could meet in the bullpen:

Fade In. Cue cutesy beginning-of-scene jingle. A group of writers are sitting around a table.

Head Writer: Okay, people, we've got a strike to write here. Who's got some ideas? Let's shoot it around the room!

Writer 1: We could get the cast of Friends to sit around on some comfy chairs on the picket line and make wisecracks about how lame it is that the producers won't give us any more money! David Spade could guest star, which will eventually get us Heather Locklear! And Jerry Stiller could walk in and start yelling his lines incoherently until Jason Alexander gets so worked up that he has to leave. Let's leave what's-his-name-the-guy-who-played-Kramer out of this one, though, huh?

Writer 2: Oooh! Crime drama! We could get David Caruso to do that thing he does in, like, every SINGLE SCENE where he has any dialogue! You know -- he stares moodily into the distance while delivering the line and then, at the very end, just when you think he's not going to, HE SWIVELS HIS HEAD to look directly at whoever he's talking to! It's brilliant, I tell you!

Smash cut. David Caruso is standing at the counter at a Starbucks.

Perky Starbucks Babe: (perkily) Can I take your order, sir?

David Caruso: (staring moodily into the distance) Yeeessssssss. I believe I'll have a (swivel) latte.

Wipe transition. We are back in the bullpen.

Other Writers: (all at once)...Caruso...brilliant...NYPD...movie "career"...hahahahahahahahahahahahahahahahaha!

Writer 3: How about a reality TV angle? We could have one of the picketing writers get ragged on by all the others until he snaps and puts Billy's hand in warm water while he's sleeping and then schemes with Maggie and Amber to get Chuck and Bruce voted out of the picket line only to double-cross them by "accidentally" tripping Maggie during their mambo and telling Amber she's too fat for him to marry her so she bursts into tears and can't do her Billy Idol tribute number so she runs off to build houses and stuff for the poor until she gets noticed by Donald Trump who makes her his new wigtender! Simon Cowell could be the judge!

Writer 4: I've got it! Let's get the writers for Saturday Night Live! They've been on strike for, like, eight years now, only no one told Lorne Michaels so they still get paid...

Fade out. Mercifully.

Remember now, I'm asking this favor for your sake, not mine. I'm not going to be affected one way or the other. You think you're "hunkered down for a long one"? Kid, I've got all the Harry Potters and the Lord of the Rings trilogy on DVD. Extended Director's Cut Version With Commentaries and Making-Of Featurettes. You won't be seeing me for months!

Monday, November 05, 2007

LaTeX For The Win!

Yeah, yeah -- I feel a little silly making a big deal about having just now become a convert to LaTeX. It's like wandering into a room of World-of-Warcraft-playing geeks and bragging about "this super-cool game I found; it's called 'NetHack'!"

But dang! I can't believe I made it through two-thirds of a Master's degree in computer science without even trying this brilliant tool. I mean the quality of the output (okay -- the quality of the typsetting; the actual semantic content is still GIGO) makes even the most mundane homework assignment look like something that's going to be published in some major journal any day now.

The key was in resolving to take the first step. I was dreading it, but I found that forcing myself to do that first assignment in LaTeX let me pick up probably 80% of the formatting tricks I'll ever need. Definitely worth the effort.

LaTeX strikes me as a perfect example of what Kathy Sierra used to blog about (Author's Note: Hi, Kathy! Come back! We miss you!): software that lets you (me) KICK A**! It's a software tool, but it has one key characteristic of the best physical tools as well -- it takes a modest force as input (your (my) typing), and amplifies and concentrates that force to shape an output that you (I) could not have achieved with your (my) bare hands.

Simply put: LaTeX rocks.

I just hope TeXShop -- which is the front-end I use on my Macs -- plays well with Leopard. There aren't a lot of issues I can think of that would keep me from upgrading, but losing LaTeX/TeXShop would definitely be a showstopper.

Thursday, November 01, 2007

Fun With Scala: Reading Scala

No, I haven't given up on my quest to learn more about Scala by perusing the guts of the liftweb source code. It's just that Iteration 3 at work, along with Hallowe'en with my two-year-old and Exam Two in Theory of Automata have all combined to kick my butt for the past couple of weeks. Not to mention all of the other life stuff that's intervening.

But no excuses! Let's have a look at some specific Scala code and see what we can figure out in general from it.

Today's snippet of Scala code is brought to you by net.liftweb.util.Helpers.scala, for those of you following along in the book. I've elided a lot of it, for the purposes of this post. Here are the relevant lines of code, suitable for entering into your scala interpreter:

import java.text.SimpleDateFormat
import java.util.TimeZone
val utc = TimeZone.getTimeZone("UTC")
def internetDateFormatter = {
val ret = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z")
ret.setTimeZone(utc)
ret
}

Besides the lack of semicolons (yea!) and the use of some standard Java classes (likewise yea!), one of the first things to notice is that utc is declared as a val, while internetDateFormatter is declared as a def. You can probably intuit the difference, but we'll see some examples in a moment of just how they're different. Also, notice that neither utc nor internetDateFormatter is given an explicit type. Each has a specific type, determined by the type of what's on the right hand of the assignment, but the compiler doesn't need to see the type declared on the left hand side. This has some consequences that we'll see too.

Finally, the definition of internetDateFormatter ends simply with the line ret. This idiom will be familiar to the Ruby programmers in the audience, as it simply declares what the ultimate value is of the block that constitutes the right hand side of the assignment to the variable internetDateFormatter. That is, in Scala, as in Ruby, the value of a block is the value of the last statement executed within the block.

Try entering the above code, line by line, in a scala interpreter. The imports aren't that interesting, but notice what you get as a result of entering the declaration of utc:

scala> val utc = TimeZone.getTimeZone("UTC")
utc: java.util.TimeZone = sun.util.calendar.ZoneInfo[id="UTC",
offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]

Which says that utc is of type java.util.TimeZone, and in particular it is equal to a sun.util.calendar.ZoneInfo with the corresponding id, offset, etc. Whereas when you finish declaring internetDateFormatter, you simply get:

scala> def internetDateFormatter = {
| val ret = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z")
| ret.setTimeZone(utc)
| ret
| }
internetDateFormatter: java.text.SimpleDateFormat

Now you can start using internetDateFormatter as you would any instance of SimpleDateFormat. For example:

scala> internetDateFormatter.toPattern()
res8: java.lang.String = EEE, d MMM yyyy HH:mm:ss z

Even more fun is this: now you have a result (res8, or whatever pops up for you), which is a java.lang.String, and can be treated as such:

scala> res8.split("\\s")
res9: Array[java.lang.String] = [Ljava.lang.String;@66718

scala> res9.toString()
res10: String = Array(EEE,, d, MMM, yyyy, HH:mm:ss, z)

(Author's Note: Have you ever wanted an irb (the interactive ruby interpreter) for Java? Download Scala, and get one for free today!)

So what about the difference between declaring with val and declaring with def? Let's find out:

scala> utc = TimeZone.getTimeZone("GMT-7")
line19$object.$iw.$iw.utc = TimeZone.getTimeZone("GMT-7")
:6: error: assignment to non-variable
val res12 = {utc = TimeZone.getTimeZone("GMT-7");utc}
^

Uh-oh. Looks like Scala considers vals to be constant. Although:

scala> val utc = TimeZone.getTimeZone("GMT-7")
utc: java.util.TimeZone = sun.util.calendar.ZoneInfo[id="GMT-07:00",offset=-25200000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]

It also looks like some constants are more constant than others. But before you start thinking you can just reassign internetDateFormatter with impunity:

scala> internetDateFormatter = "impunity"
:5: error: value internetDateFormatter_= is not a member of object $iw
val res13 = {internetDateFormatter = "impunity";internetDateFormatter}
^

Whatever that means. I'm going to have to track that one down and report on it later. Right now it's time for more life (read: "sleep") to intervene.

Monday, October 22, 2007

Fun With Scala: Things I'm Learning From Lift #2

Thanks to astute reader Ken (Author's Note: I have a reader! An astute one! Who knew?!), I learned something about a feature I was bragging about in my last post; namely, the ability to import members of a class. As it turns out, not only is this feature present in Java 5 -- see the documentation for static imports -- the Scala version of it is pretty much equivalent.

Ken points out that my example of lift importing the members of the net.liftweb.util.Helpers "class" maps exactly to the corresponding Java import. I waved my hands around the fact that Helpers is actually an object, which is, simultaneously and at the same time, Scala's way of denoting a singleton and providing static members (all of the members of an object are effectively static). But it turns out that the import syntax I was bragging about works precisely because Helpers is an object and not a class.

Here's some lame, contrived, forced-example, somewhat-minimal Scala code to demonstrate:

Mixee.scala

package bogus;

class Mixee {
def weird: String = {"Weird Al!"}
def twentySeven: String = {"27!"}
}


Mixer.scala

package bogus;

import Mixee._;

object Mixer {
def main(args: Array[String]): Unit = { Console.println(weird); Console.println(twentySeven) }
}

As described here, Mixer.scala will refuse to compile, with the error: "not found: value Mixee". This is because Mixee is defined as a class. Change class to object and it compiles (and runs) just fine.

Bonus Discovery: While researching this, I also learned that Eclipse with the Scala plugin is not as smart as it should be about building my bogus project. If I start with a clean compile (i.e., defining Mixee as an object), Eclipse is happy. If I then change the definition of Mixee from object to class, the error doesn't show up until I force a rebuild by selecting Project -> Clean... If I then change class back to object, the error goes away without my forcing the rebuild.

Anyone got a line on that? Ken? Anyone?

Anyway, just for the record, my purpose with these posts is not to bury Java, but to praise Scala and learn how it's different. I'll leave the determination of whether Scala is "better" than Java up to you, my readers. Both of you (hi, Mom!). ;-)