Monday, May 25, 2009

Efficiency at the Cost of Freedom?

This is indeed a mindless rant.

When you get used to something and then it's no longer around, it can be a bit irritating to deal with. That's as true for programming as anything else in life. I bounce between several scripting languages, but mostly KiXtart, VBScript and PowerShell (as if you couldn't tell from my mindless rants already). But prior to this I worked primarily with LISP (AutoLISP and some CommonLISP or Franz LISP, no not Franz Liszt). One thing I run into quite often is the rather limiting single-expression nature of SELECT CASE or SWITCH CASE or SWITCH {} or whatever. I was used to the (COND) statement in LISP, and it was good.

Most people that have never used (cond) look at the code examples I give them and smirk to each other and say something like "so?". But imagine if PowerShell suddenly removed the "default" option from the Switch{} statement? Sure, you could code around that, but you'd probably ask yourself (or some other helpless victim at the coffee mess) "what happened to it? my precious?  why did they take it away?" at least once, anyway.
Here's an example of PowerShell vs LISP switch-case condition branching:
switch ($a) {
1 {action...}
2 {action...}
"a" {action...}
default {action...}

I don’t mean to pick on PowerShell.  It’s just the example I chose from a hat (ok, proverbially speaking, my hat is the size of my head, which isn’t big enough to hold more than one example).  The variable $a is the driving (determinant) variable which is being evaluated.   VBScript takes a similar approach…

Select Case a
Case 1: action...
Case 2: action...
Case "a": action...
Else: action...
End Select

It’s funny (ok, to me anyway) that some uses of VBScript look a lot like COBOL.  Wordy wordy wordy.

LISP doesn’t take that approach.  It lets you invoke a variable, or an expression, anywhere in the conditional branching.  This can save lines of code in many situations, and comes in handy for other things...

( (= a 1) (action...) )
( (expression) (action...) )
( (> (* a 500) 1000) (action...) )
( (= (setq x (expression)) "ABC") (action...) )
( T (action...) )

Metaphorically, or euphorically (coffee kicking in), having another capability opens up a world of potential for new directions and approaches to solving problems.  By the way, other useful features of LISP include statements like (mapcar), (apply) and my favorite of favorites (lambda). Of course, you can perform Lambda expressions in many languages. But sprinkling more LISPness on it you can easily code for conditional lambda definitions. You can also code for dynamic functions and dynamic recursion. Since most of the work I did "back then" was with respect to drawing geometry on screen, these kinds of capabilities really came in handy. Interpolating intersecting ellipse shapes and defining specific pick-points to perform explicit edit operations, all are much easier to do with these dynamic capabilities than with stronger-typed languages like VBA, VSA/VB.NET or even C#.

It seems that the dynamic, fluid, free-form aspect of languages are giving way to more strongly typed, rigidly defined languages like the .NET family and even Ruby, Python, etc. Seems odd that we wait until 2009 to get all clean-shaven in wrapped in a suit with our programming, when software and hardware advancements have all but eliminated the performance overhead "drag" we worried so much about in the 1990's. Sure, I know that there are situations where that gap is noticeable, but I've seen some insane number crunching in my time, and the relativity factor is almost laughable when it comes to desktop computing. There were "problems" that in the 90's required parallel Cray boxes to crunch for days, even weeks, to achieve a result. That same problem category can be solved on a standard HP/Dell desktop now for under a thousand dollars (USD). The performance overhead gap has shrunk to miniscule scale. So, rather than focusing on processor efficiency, why don't we instead focus on the human nature of coding? Get rid of strong typing. Leave that for compiled languages.

Even if it's not practical to remove the pre-compile definition of variables, which I think is absurd, why can't we at least make the compiler/runtime smart enough to read variable names to interpret symbol types? iSomething could easily guide the JIT or compiler to define as "Integer".  sSomething = string/char type.  dSomething = date value, and so on.  Save a line of code here and there. And get rid of DIM and SET and GET. Why we have GET and SET for the same objects and classes in 2009 is beyond me.

In 1995 we were writing C++ class templates in college, which overloaded functions based on a return value. It's not that difficult. So you could GET or SET with the same line of code, but the one that captured a return value into a variable was the one that invoked the GET member of the class.  Why are we still having to explicitly tell the compiler/runtime what we’re doing?  What we need to include or import?  This just seems like we’re going backwards.  Is it really 2009? It seems more like 1999.

I told you it was a mindless rant. I had too much coffee and someone let me near a keyboard. That was a mistake. :)
Post a Comment