Why IDL Sucks
Stephen St.Vincent - Swarthmore College

sstvinc2@astro.swarthmore.edu
Research Home   |   Journal   |   Articles   |   IDL code   |   Movies   |   Images
Below is a list of reasons why IDL sucks as a programming language. The reasons below have caused hours of lost productivity (much like the construction of this page), clumps of lost hair, and millions of lost brain cells for being around something so incredibly witless. Enjoy.

Have a complaint about IDL that you'd like to share with the world? Have a comment regarding one of the complaints on this list? Email me at sstvinc2@astro.swarthmore.edu.

  1. Integer-to-float conversions - Any good programming language will recognize when to use an integer as strictly an integer and when it needs to be used to a higher precision. For instace, if you divide 7 (a float) by 2 (an integer), you expect to get 3.5 as the resultant (assuming your resultant is a float type). Unless you're using IDL. In that case, 7/2=3, but 7/2.=3.5. Why? No good reason, really. Take the additional example of x^2. Now, IDL will do this, but it will yell at you. Type in x^2. and it's clear sailing. This is an example of IDL being so stupid that it actually shows a lack of common sense on the part of the language designers. On this day, I am ashamed to be a CS major.
  2. The compiler - The purpose of a compiler (besides converting your code into machine-readable instructions) is to find flaws in the code with which it is presented. Not IDL, no sir. If something compiles in C or Java, you know your code is good aside from something conceptual that you did wrong. If your code compiles in IDL, it doesn't mean jack. Congratulations, you've matched up your parenthesis. Unfortunately, you won't know about undeclared variables and class-cast exceptions until runtime. But hey, it compiled! Furthermore, when IDL actually does manage to catch an error, there's about a 0.00001 probability of it telling you what line the error is on. It knows on what line it encountered the error. Why the hell can't it just tell you? This is found particularly when encountering stuff like floating-point exceptions (see complaint #1). While you can add a bit of code to have it explicitly tell you where the errors are, I don't see why this should be necessary at all. Just tell me. Please. I'll pay you!
  3. For-loops - Something like 20% of all code at the machine level is branches, and some huge percentage of that is a result of loops. Even 10% of the code is a huge amount. Yet IDL just can't seem to struggle through it. Great at vectors? Sure, but who really cares about vectors when you're trying to perform operations on individual data points? Loops are just plain handy. Writing code without loops is like building a house without a hammer. Sure, it can be done, but it ain't gonna be pretty, and it'll probably be significantly slower as well. You shouldn't have to avoid your tools like the plague. This inadequecy is completely inexplicable.
  4. Recompilation - Any other language compiles into a new file, which can be run at will whenever. Not IDL. Even if you haven't changed a program since 1985, you've still got to recompile it. Why? Damn good question.
  5. Pass by reference... sometimes - It has been discovered that passing things into functions in IDL passes them by reference: a generally good and time-saving method. But (because there's always a "but" with IDL) this does not apply if you pass in an array element. Then it passes by value - a useless method if you actually want the value to change in your array. One site claims that this is so fundamental to the way IDL works that it probably won't ever be changed. I'm sorry, but this is just stupid. You can't expect a programmer to keep track of when he's passing by reference and when he's passing by value unless you make explicit use of pointers. Just make it consistent. Please.
  6. Column-major array ordering - Normally, one references a 2D array as [row,column] - unless you're working in IDL, in which case it's [column,row]. does this really make a difference given IDL's vectorizing nature? No. It's no harder to say a[i,*] than to say a[*,i]. Every other language in the history of mankind is row-major. Poor form, IDL. Poor form indeed.
  7. Redefinition of structures - A complaint registered by Saurav, it seems that one cannot dynamically redefine a structure. In order to change it, you have to exit your current IDL session. Honestly, if you can define it on the fly, why can't you redefine it on the fly? Am I really supposed to take this language seriously?
  8. Ugly Histograms - Check out my images page to see some seriously ugly histograms. Not my fault, mind you, I did everything I could to make them look decent. IDL has no real concept of "histogram" per se. It loves plotting stuff, and connecting lines, but not drawing the vertical lines all the way to the x-axis to actually make it look like a decent histogram. Honestly, what else would you use psym=10 for? Nothing other than histograms and bar graphs, both of which need vertical lines.
  9. Anti-parallelism - So let me get this straight... IDL wants to be the premier scientific language, made for fast computation of large amounts of data. And yet, despite the modern advent of parallel computing, IDL's compiler (see points 2 and 4 for more on this hideous piece of junk) can't compile for more than one processor, no matter how parallelizable your code is. Great job, IDL. Great job indeed.
  10. Integer indexing of for-loops - Yes, it's those stupid IDL for-loops again. Normally, in a "good" programming language, one can index a for loop (specify the number of iterations) with any old integer. It can be a standard 16-bit int, a 32-bit long, or even, dare I say, an 8-bit char. And now the punch- line you've all been waiting for -- IDL cannot do this!!! Ints, and only ints, will work. So don't even think about making a nice, long, probably useful for-loop.
    • I'm actually going to retract this one. I've found myself using long-indexed for-loops for my newest programs. This was probably my fault all along. That being said, I did find it extremely irritating to find that I indexed beyond the range of the integer data type, throwing me into negative integers and array-index out-of-bounds errors. If data-type declaration was explicit, this would not be an issue.
  11. Utter Lack of Garbage Collection - You might not notice a severe deficiency such as this unless you run highly-pimped-out programs such as mine, which has a dirty little tendency to use upwards of ALL of Ruby's 2 GB of RAM. IDL is supposed to be a computational language, and yet it doesn't do garbage collection to free up RAM? Are you kidding? Computational language=high use of RAM. Simple equation, simple solution. Poorly played once again, IDL. Poorly played indeed.
  12. Data-type comparison inconsistencies - Big thanks to Andy Skemer on this one. He found himself doing a case statement on a decimal. Originally, this decimal was some multiple of 0.5. Everything worked fine. Upon changing the values to multiples of 0.2, I believe, everything broke. Here's why: he was comparing a float to a double. As it turns out, floats and doubles can handle 0.5 equally well since it's a power of 2. But for 0.2, the float type has roundoff error. So when he checked to see if 0.2(double) equalled 0.2(float), it would return false. Hey IDL - don't allow comparisons of two different data types! You're "compiler" really should have caught this. Here's a little command-line demonstration of this inconsistency:
    IDL> x=0.2D
    IDL> y=0.2
    IDL> print, x-x
        0.0000000
    IDL> print, y-y
        0.00000
    IDL> print, x-y
        -2.9802322e-09
  13. Logical operators with floats and ints - Shout out to Prof. Eric Jensen here. One point that I want to bring up first: all of IDL's logical operators are in some sort of pseudo-English (ne is "not equal to," etc.). In most languages, these are symbols (!= for "not equals," etc.), but whatever, to each his own. Or not. The bitwise logical operators are NOT, AND, etc, while their logical counterparts are ~, &&, etc. This inconsistency is confusing, granted, but wait for the other shoe to drop. A common practice is to test the boolean value of a number, i.e. if (1) do ..., under the assumption that, for both integers and floating-point values, zero means false and everything else means true. IDL carries this through for floating-points, but NOT FOR INTEGERS. Here, even integers are false, while odd integers are true. Yes, this is as stupid as it sounds. So why is this the case? IDL only checks the last bit of an integer to test logically. The last bit of an even integer is always 0 (false), while the last bit of an odd integer is always 1 (true). Which leaves us with the two contradictory statements:
    • if (2) then begin print, 'true' -->
    • if (2.) then begin print, 'true' --> true
    Stupid? Yes indeedy.
  14. Non-existent variables still exist - Typically, if one hasn't defined a variable, and one then tries to use this variable in any way, including passing it to a function, and error is thrown (ideally by the compiler, but then this is IDL). Of course, this isn't true in IDL. just try running n_elements(stupidvariablethatIhaventdefinedyet). It returns 0. Very helpful.
  15. Global variables in for-loops - First of all, defining global variables is anything but intuitive, but I'll let IDL slide on this one since it is still very easy. However, IDL won't let you loop over a global variable. So this bit of code:

    defsysv,!i,0
    for !i=0, 5 do begin
            ;;do something here
    endfor

    is illegal. But this bit of code:

    defsysv,!i,0
    for i=0, 5 do begin
            !i=i
            ;;do something here
    endfor

    works just fine. I guess there must be a good reason for this, but I just don't understand what it could possibly be.