JOB REFERRALS
    ON THIS PAGE
    ARCHIVES
    CATEGORIES
    BLOGROLL
    LINKS
    SEARCH
    MY BOOKS
    DISCLAIMER
 
 Friday, March 10, 2006
What you never want to see from your services

"The request could not be completed because the service is too busy. Please try again later." (From MSMessenger, about thirty seconds ago.)




Friday, March 10, 2006 7:32:43 PM (Pacific Standard Time, UTC-08:00)
Comments [0]  | 
 Sunday, March 05, 2006
Check it out...

The new home page is alive and kicking...


.NET | C++ | Conferences | Development Processes | Java/J2EE | Ruby | XML Services

Sunday, March 05, 2006 7:35:08 AM (Pacific Standard Time, UTC-08:00)
Comments [1]  | 
Rules for enjoyable flying

My dad sent me this:

In today's world, we typically spend a good deal of time traveling, and with a lot of that travel by air, I thought you might enjoy the attached. Jerry Cosley is an acquaintance of mine, someone I worked with at TWA, and among his other positions he was the Staff Vice President of Public Relations. Now that TWA is gone, Jerry is involved with others in sifting through some of the memorabilia and historical items. He ran across this item, provided by Stout Air Services, a predecessor of TWA, and wanted to share it. In 1929, TWA was the hot ticket - you could get from New York to California in only 48 hours, flying by day and riding on the train through the night. #4 of course is difficult on today's airplanes. By way of comparison, in 1979 I flew in a 747 from LA to JFK in 3 hours, 58 minutes.
The rules read like this:

How to Get the Maximum Enjoyment Out of Flying

(These simple rules are provided by the Stout Air Services, Inc.)
  1. DONT WORRY. Relax. Settle back and enjoy life. If theres any worrying to do let the pilot do it. Thats what hes paid for.
  2. The pilot always takes off and lands into the wind. Be patient while the plane taxies to a corner of the field before taking off.
  3. The pilot always banks the plane when turning in the air. Just as a race track is banked at the corners, so is an airplane tilted when making a perfect turn. Take the turns naturally with the plane. Dont try to hold up the lower wing with the muscles of your abdomen; its unfair to yourself and an unjust criticism of your pilot.
  4. The atmosphere is like an ocean. It supports the plane just as firmly as the ocean supports a ship. At the speed you are traveling the air has a densitypractically equivalent to water. To satisfy yourself, put your hand out of the window and feel the tremendous pressure. That ever-present pressure is your guarantee of absolute safety.
  5. The wind is similar to an ocean current. Once in a while the wind is gusty and rough, like the Gulf Stream off the coast of Florida. These gusts used to be called air pockets, but they are nothing more than billows of warm and cool air and are nothing to be alarmed over.
  6. The air pressure changes with the altitude. Some people have ears that are sensitive to the slightest change in air density at different altitudes. If yours are, swallow once in a while, or breathe a little through the mouth. If you hold your nose and swallow, your will hear a little crack in your ears, caused by the suction of air on the ear drums. Try it.
  7. Dizziness is unknown in airplanes. There is no discomfort in looking downward while flying, because there is no connection with the earth. Owing to the altitude you may think you are moving veryslowly, although the normal flying speed is above 105 miles an hour.
  8. WHEN ABOUT TO LAND: The pilot throttles the engine preparatory to gliding down to the airport. The engine is not needed in landing and the plane can be landed perfectly with the engine entirely cut off. FROM AN ALTITUDE 0F 2,500 FEET IT IS POSSIBLE TO GLIDE WITH ENGINE STOPPED TO ANY FIELD WITHIN A RADIUS OF FOUR MILES!
I asked Dad about the LA to JFK trip in less than 4 hours; turns out, it was a record. When they reached Chicago and realized just how fast they'd been flying, they called ahead to JFK ATC (Air Traffic Control) to ask them for a straight vector in, and were granted it on the grounds of (in Dad's words), "Eh, why not?". I don't know what tornado they rode to make that trip, but... wow. By comparison, on a trip back from the UK (Heathrow -> JFK -> SeaTac), it took 6 hours to go from Heathrow to JFK, and then 6.5 hours to go from JFK to SeaTac. (We must've run into the same tornado Dad did, but going the other way.)




Sunday, March 05, 2006 1:56:05 AM (Pacific Standard Time, UTC-08:00)
Comments [4]  | 
 Saturday, March 04, 2006
Scala pt 3: "Everything's an object"

In the Scala documentation, they make a point of calling out the idea that "everything's an object", including numbers and (most importantly) functions. Smalltalk had this same perception/assumption in its design, and Scala, as a result, sometimes feels very Smalltalk-ish.

For example, when Scala sees this expression:

2 + 4 * 7
Scala actually translates that into a sequence of method calls as follows:
2.+(4.*(7))
Yes, in Scala, there is operator overloading, but the rules are slightly different than what you might expect from C++ or C#. In Scala, there really is no predetermined set of symbols that are defined as "operators", per se. Instead, Scala simply sees any collection of tokens (within reason) as methods to be invoked. (I should point out here that the case of integer constants being used as parameters to methods on integer constants is a special case that the Scala compiler recognizes and generates more efficient bytecode around, so the overhead of a method call isn't present. It's an obvious optimization, when you think about it.) This means that Scala can make use of some "operators" that traditionally C# and Java have eschewed:
val nums = 1 :: 2 :: 3 :: 4 :: Nil;
In this case, nums will be List (specifically, a List[T], where "T" is of type Integer), and the "::" operator is used to concatenate an element from the right and return a new List; "Nil" is, like "true" and "false", a special constant signifying the empty list. So, written out, the above turns into:
val nums = 1.::(2.::(3.::(4.::(Nil))));
Since the Scala compiler recognizes both "::" and ".::" as being equivalent, and has no predetermined since of operators, this means that any given method definition can be used in either its "dot" form, or its "operator" form; this means that in cases where the method expects a single operand, we can write the method without the "dot" notation as well. So, for example...
> val msg = "Hello World"
val msg: java.lang.String("Hello World") = Hello World
> msg equals "Hello World"
true: scala.Boolean
Note that here I'm using the Scala interpreter instead of the traditional class; Scala is equally at home as either compiled code or interpreted, and running the interpreter to test certain snippets is just a delight, compared to having to cruft up class scaffolding just to test a simple language concept.

Thus far, this concept of everything being an object may not seem all that powerful; in fact, arguably, the above section should probably have been mentioned in the previous post than this one, since the ability to recognize new operators is itself an extension of the idea of expressing exactly what you want, nothing more. In fact, in the "Scala by Example" document that comes with the Scala download, they show a traditional Java (but which could easily be written to read in C++ or C#) quicksort implementation:

def sort(xs: Array[int]): unit = {
  def swap(i: int, j: int): unit = {
    val t = xs(i); xs(i) = xs(j); xs(j) = t;
  }
  def sort1(l: int, r: int): unit = {
    val pivot = xs((l + r) / 2);
    var i = l, j = r;
    while (i <= j) {
      while (xs(i) < pivot) { i = i + 1 }
      while (xs(j) > pivot) { j = j - 1 }
      if (i <= j) {
        swap(i, j);
        i = i + 1;
        j = j - 1;
      }
    }
    if (l < j) sort1(l, j);
    if (j < r) sort1(i, r);
  }
  sort1(0, xs.length - 1);
}
and then show a later version of the exact same implementation, but written more "Scala-ish":
def sort(xs: List[int]): List[int] =
  if (xs.length <= 1) xs
  else {
    val pivot = xs(xs.length / 2);
    sort(xs.filter(x => x < pivot))
    ::: xs.filter(x => x == pivot)
    ::: sort(xs.filter(x => x > pivot))
  }
which is clearly more terse and defined. (Note that the second example uses lists instead of arrays, and that in Scala, List[int] is Scala's syntax for a generic type, in this case List, parameterized on "int". In other words, Scala uses "[T]" notation instead of Java/C++/C#'s angle-bracket notation. Takes some getting used to, but it's easier to adjust to than you might think.) The last example really demonstrates what I'm about to discuss next: the use of functions as first-class citizens in the language, because the above implementation makes use of three anonymous functions passed in to the List's filter method. So, translating the second example into pseudocode for a second (again, taken from the Scala By Example document):
  • If the list is empty or consists of a single element, it is already sorted, so return it immediately.
  • If the list is not empty, pick an an element in the middle of it as a pivot.
  • Partition the lists into two sub-lists containing elements that are less than, respectively greater than the pivot element, and a third list which contains elements equal to pivot.
  • Sort the first two sub-lists by a recursive invocation of the sort function.
  • The result is obtained by appending the three sub-lists together.
This is only possible because we can pass in the anonymous functions "x < pivot", "x == pivot" and "x > pivot" into the "filter" function on List.

As hinted, functions are full objects in of their own right, and are just as easily accessible as parameters as any other object passed into a method. So, for example, consider the above sort implementation again. The only thing that really "ties" it to sorting lists of integers is the comparison that goes on to determine if the item inside the list is less-than, equal-to, or greater-than other elements in the list. If we could somehow genericize that decision-making, we could make the quicksort be entirely generic and applicable to lists-of-anything. (As it turns out, it's sometimes easier to do this by simply having any types that wish to be sorted implement the <, == and > methods in Scala, and this is possible to enforce via interfaces and mixins and such, but bear with me on this example.)

We'll start by making sort generic:

def sort(xs: List[T]): List[T] =
  if (xs.length <= 1) xs
  else {
    // ...
  }
The first part of the test is entirely generic already--if we're at the point where the list is 1 or 0 elements long, just return the list as it is. Now we examine the else block:
def sort(xs: List[T]): List[T] =
  if (xs.length <= 1) xs
  else {
    val pivot = xs(xs.length / 2);
    sort(xs.filter(x => (x less-than pivot) )
    ::: xs.filter(x => (x equal-to pivot) )
    ::: sort(xs.filter(x => (x greather-than pivot) )
  }
So in other words, we just need syntax to allow a caller to pass in the implementations for less-than, equal-to, and greater-than. Turns out we can do that by specifiying the following:
def sort[T](xs: List[T], lt: (T, T) => boolean, 
            eq: (T, T) => boolean, gt: (T, T) => boolean) : List[T] =
  if (xs.length <= 1) xs
  else {
    val pivot = xs(xs.length / 2);
    sort(xs.filter(x => lt(x, pivot)), lt, eq, gt)
      ::: xs.filter(x => eq(x, pivot))
      ::: sort(xs.filter(x => gt(x, pivot)), lt, eq, gt)
  }
Notice the signature for "lt", "eq" and "gt"--this says lt should be a function that takes two arguments (of the generic type T) and returns a boolean. "eq" and "gt" are defined similarly. This, then, means we can use it thusly:
object App with Application {

  def lessThan(lhs: int, rhs: int) : boolean =
    if (lhs < rhs) true else false;

  def equalTo(lhs: int, rhs: int) : boolean =
    if (lhs == rhs) true else false;

  def greaterThan(lhs: int, rhs: int) : boolean =
    if (lhs > rhs) true else false;

  val nums : List[int] = 1 :: 4 :: 3 :: 2 :: Nil;
  val sorted = Test.sort(nums, lessThan, equalTo, greaterThan);
  System.out.println(sorted);
}
Unfortunately, looking at this particular implementation, it's not really convincing that this is any better than the first approach--we have to define three functions that return less-than, equal, and greater-than for each type T that we want to sort. Ugh.

This is where the notion of an anonymous function becomes important, however. Instead of defining those three functions outright and referencing them by name in the sort call, we can instead define them "on the fly" in the call itself:

object App with Application {
  val nums : List[int] = 1 :: 4 :: 3 :: 2 :: Nil;
  val sorted = Test.sort(nums, (lhs:int, rhs:int) => if (lhs < rhs) true else false, 
                               (lhs:int, rhs:int) => if (lhs == rhs) true else false,
                               (lhs:int, rhs:int) => if (lhs > rhs) true else false );
  System.out.println(sorted);
}
Here, the notation is a bit complicated, but once you get used to it, it's fairly straightforward. The "=>" indicates that we're defining a function inline. The parentheses before it contain the expected parameters to the function, and the statement that follows defines the body of the function. Note that we don't have to explicitly offer a return type, because Scala's type inference capabilities can deduce that the function returns "boolean". Which, as it turns out, is exactly what the sort function was expecting in the first place: a function that takes two T's (int's, since this is a List[int]) and returns a boolean. Boo-yah!

Er... maybe.

If you're like a lot of developers, you're looking at the above and you're not necessarily won over. There's a couple of things that could be red-flagging at the back of your head:

  • "I thought that the Don't-Repeat-Yourself principle says it's better to collect this stuff into one place, for easier maintenance?" True. But consider this: how often have you written a method in a class because you HAD to, not because it satisfied the DRY principle? Java's use of nested inner classes (and C++'s inability to allow you to define functions in-line) forces the use of methods, even in those situations where you know, without a doubt, that you will never execute or reference this code more than once.
  • "Shouldn't this be making the sort shorter to use?" False. Anytime you genericize something, you run a (strong) risk that you're actually making it more complicated, and therefore more difficult to use. If we really wanted to make sort easier, I'd ask for a function parameter "compare" that does the traditional C-style comparison (return -1 for less-than, 0 for equal, 1 for greater-than), and write the necessary code inline in the sort() to use that method to determine if something fit the less-than, equal, or greater-than filters. That's not really the point, though... so I didn't.
  • "That syntax is just ugly." True. To a Java, C++ or C# programmer. To a LISP programmer, though, there's clearly some parentheses missing. :-) Seriously, the syntax isn't what you're used to, perhaps, but like most syntactic decisions, it has deeper meaning and rules around it that makes it look that way. The same is true of Java, C++ (remember the ">>" rule in multiple template usage?) and C#, and will remain so for as long as computers are what's interpreting our source code.
  • The thing is, the use of functions-as-objects is just the tip of the iceberg. Turns out there's some more interesting tidbits that we can make use of when using functions as objects, one of which is called "currying".

    One frequently useful idiom in functional languages is to return a function, rather than the results of applying that function. This means that we can delay actually executing the function until later--this is what we're doing (sort of in reverse, passing it in rather than returning it) in the sort example above. We pass in the comparator function into the filter routine, who then executes it. Returning a function is of the same mindset--hand back a function to be executed by the caller (either implicitly or explicitly) that produces the results desired.

    In some situations, however, the full inputs of the function aren't known at the time the function is returned. Or, as is often the case, some of the inputs are known, but others aren't. So the compiler, when handed a partially-called function, defers execution and uses parameters found in the caller's scope (wherever that may be) to fill out the remainder of the necessary functional inputs and carry out execution. Make sense?

    Probably not; currying takes a while to ingest. At least it did for me. An example may serve to help cement this down.

    def sum(f: int => int) = {
      def sumF(a: int, b: int): int =
        if (a > b) 0 else f(a) + sumF(a + 1, b);
      sumF
    }
    
    Here, we see a function "sum", which takes a function "f" that takes an int and returns an int. It in turn uses a nested function, "sumF", that takes two integer arguments "a" and "b" and applies the function "f" to them so long as "a > b". Notice, however, that sum neither takes the parameters "a" and "b", nor does it manufacture them from someplace in order to pass them in; in fact, it noticeably excludes them when it returns, without decoration, the function "sumF" as the return value of the "sum" function. (Notice again how we don't need to specify the return value of "sum", because Scala's type inference can figure it out without additional help from the programmer.)

    So how does one use the sum function? By applying both parameters--the function to apply to each argument, and a pair of ints to supply bounds to be summed up:

    sum(x => x * x)(1, 10)
    
    Which, in this case, summarizes the expression 1^1 + 2^2 + 3^3 + ... + 10^10. (Readers with a background in mathematics will recognize it as a sequence, the "big E" notation, as I used to call it back in sophomore Advanced Algebra. Probably has a more formal name than that, but my background isn't in math.) To understand where the currying takes place, look at how the compiler sees this expression:
    (sum(x => x * s))(1,10)
    
    Which means, of course, pass the function "x * x" into sum, which then returns the sumF function with f(a) replaced by "a * a". sumF still expects two integer parameters, however, so the compiler takes the next expression "(1, 10)" and applies those as "a" and "b", respectively. From there, it's a simple exercise in recursion to arrive at the answer.

    The power of currying becomes more apparent when you see that because the compiler is willing to accept partially-evaluated functions as first-order types, we can partially-define functions in terms of other functions, as in:

    def sumInts = sum(x => x);
    def sumSquares = sum(x => x * x);
    def sumPowersOfTwo = sum(powerOfTwo);
    
    and then use them as top-level functions without any special syntax:
    > sumSquares(1, 10) + sumPowersOfTwo(10, 20)
    267632001: scala.Int
    
    Now, if for some reason the definition of sum() needed to change, it would ripple throughout this tiny framework by making one change in one place. (Don't know why sum() would need to change, mind you, but that's the problem with simple examples--it's sometimes hard to see the really positive benefits unless you get more complicated, but more complicated examples are harder to use to present the concept.) And I'd be lying to you if I said that I "get" how to use this in code more practical than summations yet--I still have a lot of internalizing to do. But I can see the outskirts of where it might be useful, and if I can get working samples of how and where it would, believe me, they're going up here. :-)

    In the meantime, next is traits and mixins, which are both features that are definitely easier to see applicability.


    Java/J2EE

    Saturday, March 04, 2006 7:52:49 PM (Pacific Standard Time, UTC-08:00)
    Comments [5]  | 
 Friday, March 03, 2006
Don't fall prey to the latest social engineering attack

My father, whom I've often used (somewhat disparagingly...) as an example of the classic "power user", meaning "he-thinks-he-knows-what-he's-doing-but-usually-ends-up-needing-me-to-fix-his-computer-afterwards" (sorry Dad, but it's true...), often forwards me emails that turn out to be one hoax or another. This time, though, he found a winner--he sent me this article, warning against the latest caller identity scam: this time, they call claiming to be clerks of the local court, threatening that because the victim hasn't reported in for jury duty, arrest warrants have been issued. When the victim protests, the "clerk" asks for confidential info to verify the records. Highly credible attack, if you ask me.

Net result (from the article):

  • Court workers will not telephone to say you've missed jury duty or that they are assembling juries and need to pre-screen those who might be selected to serve on them, so dismiss as fraudulent phones call of this nature. About the only time you would hear by telephone (rather than by mail) about anything having to do with jury service would be after you have mailed back your completed questionnaire, and even then only rarely.
  • Do not give out bank account, social security, or credit card numbers over the phone if you didn't initiate the call, whether it be to someone trying to sell you something or to someone who claims to be from a bank or government department. If such callers insist upon "verifying" such information with you, have them read the data to you from their notes, with you saying yea or nay to it rather than the other way around.
  • Examine your credit card and bank account statements every month, keeping an eye peeled for unauthorized charges. Immediately challenge items you did not approve.
In other words, don't assume the voice on the other end of the phone is actually who they say they are. I think it's fairly reasonable to ask to speak to a supervisor or ask for a phone # to call back on after you've "assembled the appropriate records" and what-not. Who knows? Some scammers might even be dumb enough to give you the phone # back, and then it's "Hello, Police...?", baby....

Remember, it's always acceptable to ask for verification of THEIR identity if they're asking for confidential information. And most credible organizations are taking great pains to not ask for that information over the phone in the first place. Practice the same discretion over the phone that you would over IM or email; the phone can be just as anonymous as the Internet can.


.NET | C++ | Conferences | Development Processes | Java/J2EE | Reading | Ruby | XML Services

Friday, March 03, 2006 10:00:57 PM (Pacific Standard Time, UTC-08:00)
Comments [2]  | 
 Thursday, March 02, 2006
Scala reactions

Apparently, I touched a nerve with that last post; predictably, people started counting the keystrokes and missing my point. For example, Mark Blomsma wrote:

Looks to me like you're comparing apples and pears.

C# does not force you to use accessors. The following is already a lot closer to Scala.

public class Person
{
public string firstName; public string lastName; public Person spouse;

public Person(string fn, string ln, Person s)
{
firstName = fn; lastName = ln; spouse = s;
}

public Person(string fn, string ln) : this(gn, ln, null) { }

public string Introduction()
{
return "Hi, my name is " + firstName + " " + lastName +
(spouse != null ?
" and this is my spouse, " + spouse.firstName + " " + spouse.lastName + "." :
".");
}
}

This is only 356 keystrokes, compared to 287 for Scala. Now in Scala the default accessor for classes and members seems to be public, if this were not the case then you'd need 323 keystrokes in Scala.
Only a very minor difference. And definately not enough to make a case that Scala is more efficient for a developer.

Another consideration if you start talking keystrokes is that the tooling suddenly becomes a factor. With C# and VS2005 I only type 'prop,tab,tab' and then the type and name info. Skipping quite some keystrokes.
Mark, with all due respect, I gotta admit to believing that you're doing the apples-to-pears comparison here, at least with your definition of the Person class in C#. The Scala implementation does NOT define a public field, but accessor methods, thus preserving encapsulation in the same way that the property methods do in C# and Java and C++. The thing is, Scala just realizes that 80% of those methods are always coded the same way, so it assumes a default implementation when it sees that syntax. (Ruby does the same thing.)

All that sort of misses the point, though: the purpose of the comparison was not to count keystrokes, per se, but to look at the expressiveness of the language and how concisely the language can express a concept without requiring a great deal of scaffolding. C, for example, could always be used to build object-oriented systems... but you had a lot of work to do on your own to do it. As a result, a huge amount of complexity was spent in manaing the relationships between "classes" by hand (by tracking pointer relationships and so on). C++ solved a lot of that by baking those concepts in as a first-class concept, thus reducing the surface area requirment in the programmer's mind devoted to "plumbing", and making room for more business-level complexity. Java did the same to C++ by introducing GC and other VM-level support, and so on. Scala and Ruby (and other hybrid and/or dynamic languages) are now seeking to do the same to Java and .NET.

The question of tooling is an interesting one, though: is a language just the language by itself, or the language plus the tools that support it? Is Lisp still Lisp if you take Emacs out of the equation? Or is Smalltalk interesting without the Smalltalk environment and/or browser? Can we separate the two? Should we? That's a question to which I don't have an easy answer.


Java/J2EE | .NET | C++ | Ruby | XML Services

Thursday, March 02, 2006 10:41:16 PM (Pacific Standard Time, UTC-08:00)
Comments [9]  | 
Scala pt 2: Brevity

While speaking at a conference in the .NET space (the patterns & practices Summit, to be precise), Rocky Lhotka once offered an interesting benchmark for language productivity, a variation on the kLOC metric, what I would suggest is the "CLOC" idea: how many lines of code required to express a concept. (Or, since we could argue over formatting and style until the cows come home, how many keystrokes rather than lines of code.)

Let's start with a simple comparison. The basic concept we want to express is that of a domain object type, my favorite example, that of a Person type. In domain lingo,

A Person has a first name, a last name, and a spouse. Persons always have a first and last name, but may not have a spouse. Persons know how to say hi, by introducing themselves and their spouse.
which, as domain logic goes, is pretty simple and lame, but serves to highlight the metric pretty effectively.

In Java, we express this class like so:

public class Person
{
    private String lastName;
    private String firstName;
    private Person spouse;
    
    public Person(String fn, String ln, Person s)
    {
        lastName = ln; firstName = fn; spouse = s;
    }
    public Person(String fn, String ln)
    {
        this(fn, ln, null);
    }
    
    public String getFirstName()
    { 
        return firstName;
    }
    
    public String getLastName()
    { 
        return lastName;
    }
    
    public Person getSpouse()
    { 
        return spouse;
    }
    public void setSpouse(Person p) 
    { 
        spouse = p;
            // We ignore sticky questions of reflexivity and
            // changing last names in this method for simplicity
    }
    
    public String introduction()
    {
        return "Hi, my name is " + firstName + " " + lastName +
            (spouse != null ? 
            " and this is my spouse, " + spouse.firstName + " " + spouse.lastName + "." :
            ".");
    }
}
Relatively verbose, and while I'm certain people will stand up and argue that any modern IDE can code-generate some of this basic scaffolding for you, the fact is that the language itself requires this much degree of verbosity in order to express the concept. And this is a fairly basic concept; consider a much more complex domain object that has dozens of attributes associated with it. Code-generation and templates can mitigate some of the pain, but it can't remove it entirely, unfortunately.

This isn't just a Java problem; the C# version of this type isn't much better:

public class Person
{
    private string lastName;
    private string firstName;
    private Person spouse;
    
    public Person(string fn, string ln, Person s)
    {
        lastName = ln; firstName = fn; spouse = s;
    }
    public Person(string fn, string ln)
        : this(fn, ln, null)
    {
    }
    
    public string FirstName
    {
        get { return firstName; }
        set { firstName = value; }
    }
    
    public string LastName
    {
        get { return lastName; }
    }
    
    public Person Spouse
    {
        get { return spouse; }
        set { spouse = value; }
    }
    
    public string Introduction()
    {
        return "Hi, my name is " + firstName + " " + lastName +
            (spouse != null ? 
            " and this is my spouse, " + spouse.firstName + " " + spouse.lastName + "." :
            ".");
    }
}
and the Visual Basic version arguably gets even worse since VB prefers to use keywords to symbols:
Class Person
  Dim _FirstName As String
  Dim _LastName As String
  Dim _Spouse As Person

  Public Sub New(ByVal FirstName As String, ByVal LastName As String, ByVal Spouse As Person)
    Me._LastName = LastName
    Me._FirstName = FirstName
    Me._Spouse = Spouse
  End Sub

  Public Sub New(ByVal FirstName As String, ByVal LastName As String)
    Me.New(FirstName, LastName, Nothing)
  End Sub

  Public ReadOnly Property LastName() As String
    Get
      Return _LastName
    End Get
  End Property

  Public Property FirstName() As String
    Get
      Return _FirstName
    End Get
    Set (ByVal Value As String)
      Me._FirstName = Value
    End Set
  End Property

  Public Property Spouse() As String
    Get
      Return _Spouse
    End Get
    Set (ByVal Value As Person)
      Me._Spouse = Value
    End Set
  End Property

  Public Function Introduction As String
    Dim temp As String
    temp = "Hi, my name is " & _FirstName & " " & _LastName
    If _Spouse <> Nothing Then
      temp = temp & " and this is my spouse, " & _Spouse.FirstName() & " " & _Spouse.LastName() & "."
    Else
      temp = temp & "."
    End If
    Return temp
  End Function
End Class
A lot of what makes Ruby interesting to people is the fact that Ruby makes this a lot simpler (and I'll bet my Ruby here isn't the most terse it could be):
class Person
  def initialize(firstname, lastname, spouse = null)
    @firstname = firstname
    @lastname = lastname
    @spouse = spouse
  end

  attr_reader :lastName
  attr_writer :firstName, :spouse
  
  def introduction
    if spouse == nil
      "Hello, my name is #{firstName} #{lastName}"
    else
      "Hello, my name is #{firstName} #{lastName} and this is my spouse, #{spouse.firstName} #{spouse.lastName}"
    end
  end
end
Scala, similarly, simplifies the definition of the type. Take a look:
class Person(ln : String, fn : String, s : Person)
{
    def lastName = ln;
    def firstName = fn;
    def spouse = s;
    
    def this(ln : String, fn : String) = { this(ln, fn, null); }

    def introduction() : String = 
        return "Hi, my name is " + firstName + " " + lastName +
            (if (spouse != null) " and this is my spouse, " + spouse.firstName + " " + spouse.lastName + "." 
             else ".");
}
There's a couple of things to notice here. First off, like Ruby, Scala defines the backing store for a field and simple accessor around those fields; note that since this is a functional language, Scala assumes immutable objects by default, so there are no mutators. (It turns out to be fairly trivial to write a mutator method to set the state of those attributes, but that starts to wander away from the intent of functional languages; this is clearly a difference between Scala and a more traditional O-O language like Java or C#.) You may be curious to know where the three-argument constructor went; as it turns out, it's considered the "primary constructor", and is defined in the same line as the class declaration itself. The only reason we need the "this" method (another constructor) is because of the domain rule that says we can have a Person with no spouse.

This is hardly an exhaustive comparison of the languages, but it does give you a little taste of Scala's object flavor. Ruby's syntax is arguably of the same length as Scala's (and frankly, to my mind, they're too close to call... or care), but clearly Scala's length is much much smaller than that of the equivalent C#, Java, Visual Basic or C++ class. (C++ could make things interesting with judicious use of templates to handle backing store, accessor and mutator, but that's considered too advanced by many C++ devs, and therefore too obscure to use in common practice, rightly or wrongly.)

When next we look at this, we'll look at what Scala means when they say "everything's an object"... and how that, in many ways, this means that Scala is more object-oriented than Java itself.


Update: Glenn Vanderburg pointed out that my Ruby wasn't quite correct, and also suggested a bit more "Rubification":

     class Person
       def initialize(firstname, lastname, spouse = null)
         @firstname, @lastname, @spouse = firstname, lastname, spouse
       end

       attr_reader :lastName
       attr_accessor :firstName, :spouse  # attr_writer *just* makes a writer.  You really want this.

       # I would typically use the more explicit "if" that you used here, but for terseness I've
       # put this in the form you used with the Scala version:
       def introduction
         "Hello, my name is #{firstName} #{lastName}" + (spouse ? " and this is my spouse, #{spouse.firstName} #{spouse.lastName}" : "")
       end
     end

Thanks, Glenn. Again, I'm struck by how Ruby's strength lies not in the core language itself, but the various "macros" that they've defined (such as attr_reader and attr_accessor or attr_writer). This notion of "core language with user-defined extensions" is a powerful one, and I hope to show how Scala does much the same in its language definition.


.NET | Java/J2EE | Ruby | XML Services

Thursday, March 02, 2006 1:45:52 AM (Pacific Standard Time, UTC-08:00)
Comments [6]  | 
 Wednesday, March 01, 2006
Victoria .NET User Group topic

As Joel before me, I'm going to be in beautiful Victoria, British Columbia, on April 4th to present at the Victoria .NET Developers Association, and as usual, the topic of what to present has come up.

Normally, this is a subject that the user group lead and I sort of hash out in private beforehand, but in this case, Nolan Zak (the user group lead) suggested I post here and call for suggestions. So, here's a list of topics I can present on, send me your thoughts.

  1. Pragmatic XML Services: you know about SOA, you've heard the Four Tenets.... now what?
  2. Intro to WCF: All you need to know about Microsoft's latest communication stack.
  3. Web Services: Overview of the specs, the stacks, and the standards. What's critical, what's useful, what's vendor hype and fluff.
  4. C# 3/LINQ: What's in their heads for C# v.Next
  5. (Or suggest your own idea.)
(I won't promise to take the most heavily-voted suggestion, but it'll weigh in pretty heavily. So no racketeering with the other members to rope me into speaking on FoxPro or something. ;-) )


.NET

Wednesday, March 01, 2006 7:05:35 PM (Pacific Standard Time, UTC-08:00)
Comments [7]  | 
 Thursday, February 23, 2006
A personal moment

I know that many readers of this blog complain when I take time out from technical topics to talk about personal stuff, so if you're one of those folks, move along. This is about as personal as it gets, and fair warning: if you're going to complain about this post, I'm going to ignore you, at best.

Daniel Steinberg, a fellow No Fluff Just Stuff speaker, lost his seven-year-old daughter not too long ago, and he wrote the story up in a really poignant and moving piece he called "Dear Elena".

Dan, you can't imagine how terrible I feel for you right now--that's every parent's worst nightmare. I wish there were something I could do or say to make this time easier or less tragic for you, but of course there isn't. She sounds like she was a wonderful little girl, and I'm saddened by the fact that I didn't get the chance to meet her. My thoughts and prayers are with you and your family right now.

Now, if you'll all excuse me, I'm going to Skype my six-year-old son at home. For what I would hope to be a fairly obvious reason, I feel the need to give him a hug from here in London.




Thursday, February 23, 2006 2:49:37 PM (Pacific Standard Time, UTC-08:00)
Comments [5]  | 
 Wednesday, February 15, 2006
It's dogma that's bad... not Spring

Several people have commented on my recent posting about Spring, and I want to make something clear: I'm not saying that Spring (or Hibernate, or EJB, or anything else) is a bad technology. I'm saying that walking up to every project, assuming that Spring will be THE answer, is bad. This kind of dogmatic approach--which, by the way, more than anything else is what led to the downfall of EJB as a popular technology--is bound to bite you in an uncomfortable place sooner or later.

One commenter, in particular, chastised me for not providing specific examples regarding where Spring may fail; I'm not going to stand here and make an exhaustive analysis of Spring's strengths and weaknesses. Besides being something that's already being done elsewhere, it would be beside the point that I'm trying to make--that dogma of any form is bad.

Look, so you've been successful with Spring on a few projects--that's good, and I encourage you to consider Spring again for your next couple. But don't make the dangerous assumption that using Spring will always yield success. In fact, let's take this out of the realm of Spring entirely and restate the point: "Look, so you've been successful with [[TECHNOLOGY-X]] on a few projects--that's good, and I encourage you to consider [[TECHNOLOGY-X]] again for your next couple. But don't make the dangerous assumption that using [[TECHNOLOGY-X]] will always yield success." (Where [[TECHNOLOGY-X]] can be, but isn't limited to, one of Spring, Hibernate, EJB, J2EE, COM+, WCF, CORBA, XML services, relational databases, stored procedures, managed-code-inside-the-database, highly denormalized relational data, highly normalized relational data, ....)


Java/J2EE

Wednesday, February 15, 2006 1:39:59 AM (Pacific Standard Time, UTC-08:00)
Comments [5]  | 
 Tuesday, February 14, 2006
Want Ruby-esque features on the JVM (or CLR)? Introducing Scala

Recently, while cruising the Internet (and, in particular, the Lambda-the-Ultimate site), I ran across the Scala programming language, latest brainchild of Martin Odersky (of GJ fame, which of course was derived from Pizza, among others). It's another entry in the hybrid functional/object language space, and as such, has a lot of interesting features that Ruby holds, but runs on the JVM (and can actually cross-compile into a .NET assembly, though it does require some slightly different mappings), and as such means developers don't have to make a wholesale commitment to the Ruby interpreter.

I thought I'd share some of the more interesting bits of Scala in this and a few more blog posts.

The high-level stuff

First of all, from the Scala website, let's get the high-level overview stuff out of the way:

  • Scala is object-oriented. Scala is a pure object-oriented language in the sense that every value is an object. Types and behavior of objects are described by classes and traits. Class abstractions are extended by subclassing and a flexible mixin-based composition mechanism as a clean replacement for multiple inheritance.
  • Scala is functional. Scala is also a functional language in the sense that every function is a value. Scala provides a lightweight syntax for defining anonymous functions, it supports higher-order functions, it allows functions to be nested, and supports currying. Scala's case classes and its built-in support for pattern matching model algebraic types used in many functional programming languages. Furthermore, Scala's notion of pattern matching naturally extends to the processing of XML data with the help of regular expression patterns. In this context, sequence comprehensions are useful for formulating queries. These features make Scala ideal for developing applications like web services.
  • Scala is statically typed. Scala is equipped with an expressive type system that enforces statically that abstractions are used in a safe and coherent manner. In particular, the type system supports generic classes, variance annotations, upper and lower type bounds, inner classes and abstract types as object members, compound types, explicitly typed self references, views and polymorphic methods. A local type inference mechanism takes care that the user is not required to annotate the program with redundant type information. In combination, these features provide a powerful basis for the safe reuse of programming abstractions and for the type-safe extension of software.
  • Scala is extensible. The design of Scala acknowledges the fact that in practice, the development of domain-specific applications often requires domain-specific language extensions. Scala provides a unique combination of language mechanisms that make it easy to smoothly add new language constructs in form of libraries: any method may be used as an infix or postfix operator, and closures are constructed automatically depending on the expected type (target typing). A joint use of both features facilitiates the definition of new statements without extending the syntax and without using macro-like meta-programming facilities.
I'll be the first to admit, a lot of these features are new to me, but the set as a whole is impressive, even more so because they all seem to derive from some core features inherent to functional languages, and the overall impression I get is that despite the language feature set, it doesn't feel "cluttered" or "clumsy", which is a feeling I got from Groovy in some places.

Enough overview. Let's look at code.

Hello, Scala

OK, Scala really isn't all that interesting as a Hello World program, but it does highlight one of the more interesting elements of Scala that I already like:

object Hello {
  def main(args: Array[String]): Unit = {
    Console.println("Hello, Scala!");
  }
}
First, we see the "object" keyword where "class" would be expected in Java; this means that this is a singleton object, and Scala will handle the construction of the singleton instance as well as the prevention of any further constructions. Singletons have become so prevalent in Java (and other OO languages) that it just makes a lot of sense to make it a first-class language entity. There's some other interesting elements in that sample that differ from the traditional Hello Java program, but we'll leave that alone for now. Put this code into App.scala (once again, another language has corrected Java's requirement that filename-match-classname, which I've always found odious and annoying), compile it with scalac, and you get a slew of .class files out the other end. Run the program with the "scala launcher" (which is a simple batch file around the Java launcher, to ensure the Scala support libraries are on the classpath) with scala Hello, and you get the expected result.

Some of what's interesting to see here is that the Scala compiler actually produced two .class files--one entitled App.class, another called App$.class, the second App$ class apparently to provide "module" behavior (which I suspect is related to the singleton-ness of the object declaration in the code). As you might expect, Scala injects some additional support methods into both classes, including getScalaType, which is obviously intended to return the type of the object to Scala, just as the .class or getClass does for Java. Which brings up another interesting point.

Scala presents a unified type hierarchy, such that scala.Any is the root of the type system, and (like the CLR) is bifurcated into two basic elements, one being the object-family of types (java.lang.Object, known to Scala as scala.AnyRef) and the "primitive type" family of types, known to Scala as scala.AnyVal. Scala calls these reference classes and value classes, respectively--the same monikers the CLR uses. There's also reference to a type scala.All, which the introduction/tutorial page puts at the bottom of the type hierarchy, apparently inheriting from everything, but I'm can't find documentation on it or what purpose it serves. *shrug* More on that later, I guess.

Another interesting tidbit is that we can run Scala interpretively, the same way we can do to Groovy:

> scalaint -nologo HelloWorld.scala
> HelloWorld.main(null)
Hello, world!
(): scala.Unit
>:q
Which implies, then (though I haven't done it yet), that the Scala language could be used as a DSL to analysts and/or domain experts within an existing Java application.

Update: Forgot to mention, Scala has another interesting element to it that makes it very interesting to Ruby in much the same way:

object HelloWorld2 with Application { 
  Console.println("Hello, world!"); 
}
The with Application clause makes the entire content of the class basically a single script, as if the def main method has been declared to be the entire body of the class. This makes Scala very interesting as a potential scripting language, since now no explicit entry point need be defined; you can assume it's already present and accounted for, yet still relies on the underlying rules of the JVM (that the entry point must be defined as a static method, blah blah blah). Describing how with Application works is a bit difficult to describe without going into larger detail on other topics, so I'll leave that for a future discussion or (as book authors are so fond of writing) as an exercise to the reader to figure out. :-)

I consider myself a relative newbie to Scala, but as I progress through the language and see some useful applications of features, I will blog more. I'll also blog some of the features themselves, but you can find that for yourself by working through the Scala tutorial material on the site, if you're so inclined. In the meantime, catch the presentation I'm doing on Scala at the No Fluff Just Stuff symposiums, starting 2Q this year.

And, by the way, for those of you in the .NET space, Scala does, as I mentioned before, cross-compile to .NET assemblies, though I haven't spent much time exploring this. Frankly, I'd be more comfortable using Scala in the .NET world if there was a .NET-based compiler for it, rather than having to install a JRE just to run the compiler, but F# serves much the same space in the .NET world that Scala does here, and that's another language I'm pursuing with some vigor, as well. More on that later. :-)


Java/J2EE | .NET | Ruby

Tuesday, February 14, 2006 12:50:17 PM (Pacific Standard Time, UTC-08:00)
Comments [0]  | 
 Monday, February 13, 2006
My interview with Joshua Bloch and Neal Gafter from JavaPolis 2005 is now live

There are a few things, I've found, that are fun about being a speaker and general rabble-rouser, but none of them are nearly as much fun as when I get an opportunity to interview industry icons and ask them all my questions on camera. :-) In this case, while at JavaPolis2005, my victims were the well-known pair Joshua Bloch and Neal Gafter, who, more than anyone else in the world, are most directly responsible for the language features that came in Java5. I tried to keep the interview pleasant and friendly, but I did ask the questions that've bothered me for a while, like "Why did generics end up the way they did?", "Is Java too complicated and hard to use now?" and "What are you doing at Google these days, anyway?"

Online (registration required) at the JavaPolis2005 site. Keep an eye on the site for the other interviews Dion did, as well as one more I did with Brian Goetz, who's got a GREAT book on Java Concurrency coming out in 2006.


Java/J2EE

Monday, February 13, 2006 5:05:26 PM (Pacific Standard Time, UTC-08:00)
Comments [4]  | 
 Wednesday, February 01, 2006
From the "Yeah, what he said" Department

CrazyBob just wrote about how he "doesn't get Spring", and although it runs the risk of sounding like something from the "Me, too" bandwagon, I have to say, I agree with him (and have been saying this in conferences and panels for a while now):

Even worse, I've noticed what I consider to be a dangerous and blind increase in the rate of Spring adoption. I've yet to read a critical article or book on Spring. It seems like everyone loves Spring except me.
More importantly, I think Bob nails it with this:
Maybe Spring adoption is a knee-jerk reaction to J2EE. "J2EE is bad, and the Spring guys say their stuff is better, so Spring must be good." It doesn't work that way.

For starters, I'm with Bob on the statement that blind adoption of Spring is dangerous. I wrote once before that dogma of any form is bad, and Spring dogma is just as bad and just as dangerous as J2EE dogma ever was, for much the same reason: dogma discourages thinking. Walking onto a project, prepared already to believe that Spring is the best solution to the problem, without considering the context, is just as bad as when we did that with J2EE. In fact, any technology can fall into that trap, be it Ruby, .NET, J2EE, Spring, LAMP, Vista, COM/DCOM/COM+, you name it. ANY kind of dogma that allows developers to shut off the analytical part of their brain is dangerous. Spring is a useful technology, no question. But so is J2EE, and so is .NET, and so is LAMP, and...

Don't ever make the mistake of letting dogma drive your technology decisions, period. No matter who justifies them. I thinke states it best when he says

If you do [adopt Spring], go in with your eyes wide open. Be skeptical, critical. Just because someone has a popular Open Source framework, they have slick marketing, and they're supported by a big vendor (IBM pushed Struts on me for a number of years after all), it doesn't necessarily mean they know what's best for you or even that they know better than you.
Dogma, of any form, is not to be trusted.

Bob then goes into how he likes the setter-injection that Spring provides; I personally don't have the same degree of fondness for dependency injection, to be honest: I find JNDI (and Service Locator) to be a superior approach, mostly because with the Service Locator, I can control when the resource moniker is resolved, meaning that if the resource should fail somewhere during the call, I can control where and how I go back to the Service Locator for a failover attempt. More importantly, I can re-resolve the resource as my failover policies permit, and I'm not held hostage to how--or mre importantly when--the container decides to inject the dependency.

At the end of the day, it's important to remember that "lightweight" and "testable" doesn't have to mean "Spring". In-process testing of EJB components is possible thanks to the in-proc nature of the OpenEJB stack. Testability of JNDI is easily accomplished with unit tests that use the Hashtable JNDI provider that Sun makes available in the Java Tutorial, if you want or need to test the Service Locator code itself. Or, you take the "black box" approach (as some recommend for servlet containers), and test your code through the container itself by doing the heavierweight communication through the communication stack from out-of-process calls. In the end, it's not the APIs that define the tool's testability, but the ability to embed the tool inside a unit-test environment.

Would I recommend Spring? Certainly, under the same circumstances and for the same reasons I'd recommend J2EE: when it's appropriate, because there's some good stuff there, and it's well-known and an official (in J2EE's case) or de-facto (in Spring's case) standard.

Oh, and let's not forget, this applies to any technology, including the upcoming rise of dynamic languages...


Java/J2EE

Wednesday, February 01, 2006 1:08:13 AM (Pacific Standard Time, UTC-08:00)
Comments [4]  | 
 Friday, January 13, 2006
Billy Hollis on the history of programming languages

Billy Hollis, famed Visual Basic lecturer and secret programming language anthropologist, has compiled a succinct history of programming languages. As he puts it,

If you like VB, look at the history of the C family [of languages] first. If you like C#, Java or C++, look at the history of the BASIC family first.
Definitely something to quote next time you're in a (friendly) raging debate about "which language is better". :-)

Happy Friday.


.NET | C++ | Java/J2EE | Ruby

Friday, January 13, 2006 7:47:18 PM (Pacific Standard Time, UTC-08:00)
Comments [2]  | 
 Wednesday, January 11, 2006