Random Post: Why a "not-a-blog"?
RSS .92| RSS 2.0| ATOM 0.3
  • Home
  • About
  •  

    Code Snippets Vs DRY

    March 25th, 2009

    Code snippet support in an editor can be very useful, but it does seem to carry a certain risk of discouraging advancements in DRY practices. For example, I was just working on a Haxe class (I refuse to use the goofy “haXe” capitalization) that has 14 (and that number is growing) accessors like this:

    private var _assetBaseUrl:String;
    public var assetBaseUrl(get_assetBaseUrl, null):String;
    private function get_assetBaseUrl():String
    {
        return _assetBaseUrl;
    }

    Might not seem like much to someone who’s accustomed to Haxe, but that’s an enormous amount of code just for a single privately-writable, publically-read-only member variable (For the record, Haxe has the ugliest, most verbose accessor definition syntax I’ve ever seen). Considering I have 14 of these (so far), just in this one class alone, that’s a lot of mess.

    Of course, this is where the code snippet users come in and say “Just use a code snippet!”. I don’t know for certain, of course, but I can’t help suspect that the existence of code snippets is part of why Haxe’s creators allowed the accessor syntax to be so verbose in the first place. And considering that most of those differ only by name and type, well shit, so much for the idea of “Don’t Repeat Yourself”!

    Contrast that with the same code in C#:

    private String _assetBaseUrl;
    public String assetBaseUrl()
    {
        get { return _assetBaseUrl; }
    }

    Or better yet, D programming language:

    // getter is defined in a utility module I wrote
    mixin(getter!(char[], "assetBaseUrl"));

    And holy crap, all of a sudden we have actual DRY!

    Problem is, code snippets tend to get used as an excuse to ignore DRY (it’s really only about one small step above outright copy-and-paste coding). If the early programmers used editors with code snippet support, we probably wouldn’t even have functions today.

    Of course, I’m not suggesting that we get rid of code snippets, or stop using them. We just shouldn’t be considering them a proper substitute for real DRY.


    The Problem With Implicit Variable Declarations

    September 16th, 2008

    Implicit variable declarations (ex: Visual Basic without “Option Explicit”) can seem like a good idea if you look at them a certain way. I can understand what language designers are probably thinking when they decide to implement implicit declarations.

    “Let the computer do the work for you.”

    That’s a favorite mantra of mine, one of my cardinal rules. To a programmer, a computer with a compiler is like having an army of robots at your disposal. Why do things manually when you send send off a drone or a function or a script to do it for you while you get on with other things? So whenever possible, automate whatever you can. Efficiency: it’s nice.

    So I think I can understand what language designers are thinking when they decide to include the feature of implicit declarations. They’re thinking “Hey, why should I have to explicitly point out that I’m going to use a variable? If I’m using the variable somewhere in the code, the computer should be able to figure out on it’s own that the label is supposed to be a variable. Saves me the bother.” Sounds good. Same result, less effort. Efficiency. Nice.

    But there’s an ugly assumption hidden in that reasoning. What that developer is really saying is “Hey computer, anytime you come across an undeclared label being used as a variable, just go ahead and assume it’s a new variable”. We all know what happens when we make assumptions, right? “ASSumptions will make an ass outta ya.”

    What do you really want to happen when you mistype a variable name? (Oh, sure, you’d never do anything like that? Riiight? It happens to the best. Deal with it.) There’s two choices: A. The compiler grabs you, points at your error, and yells “Hey! You screwed this up! Fix it!”. or B. The compiler pretends everything is ok, processes the bad code, and leaves you with a bug which, only if you’re very luckly, will manifest itself immediately and in a way that makes the exact nature and location of the problem obvious. Hmm, which is a better way to write code…?

    “But I might have really wanted it to be a new variable!” Ok fine. How about you go rewrite your “rm” command to never ask for confirmation just because, well hey, we can’t let the potential downfall of accidentially loosing files force us to endure a much, much lesser inconvenience when we really do want to delete. Doesn’t make much sense does it? Point being: Assumptions are bad. Bad enough even to outweigh convenience.

    Language design, and heck, API design in general, are more than just programming. There is code involved, yes, but there’s a large amount of psychology that needs to go into it as well. When you’re writing an ordinary function, you’re basically thinking “automation” (ie, that “army of robots”). But when you’re designing an interface for programmers, even yourself, the real important thing suddenly becomes “How can I prevent the programmer from messing up?”. It’s like designing any interface, the weakest link is always the human factor. Even if it’s the best programmer in the world, a highly unreliable computer will still make that human look like a giant pile of shoddy engineering. So it’s your job, as the language/interface/API designer, to do whatever you can to minimize that risk of programmer error.

    Another way to think of the issue is in terms of “good redundancy versus bad redundancy”. There tends to be a lot of value placed on eliminating redundancy. Often this is good. But sometimes redundancy can improve reliability, which is a very important concern. Manditory explicit variable declarations are one form of “good redundancy” that improves reliability. Walter Bright explains it best:

    “Variable declarations are one [example of good redundancy in langauge design]. But since the compiler can figure the need for declarations from the context, declarations seem like prime redundancies that can be jettisoned. This is called implicit variable declaration. It sounds like a great idea, and it gets regularly enshrined into new languages. The problem is, the compiler cannot tell the difference between an intended new declaration and a typo - and the poor maintenance programmer can’t tell, either. After a while, though, the lesson about redundancy is learned anew, and a special switch will be added to require explicit declaration.”
    - Walter Bright: Redundancy in Programming Languages

    Visual Basic developers learned this lesson a long time ago. Even though VB supports implicit variable declarations, it’s extremely rare to come across a professional VB developer that doesn’t strongly recommend turning it off (with “Option Explicit”) and religiously does so in their own code. It’s a shame there are so many newer languages that haven’t learned from this.


    Putting the “Engineering” back into “Software Engineering”

    September 16th, 2008

    (I wrote this a while ago, but didn’t post it for some reason. So I’m posting it now.)

    I’ve been very vocal about my distaste towards many of the features of various dynamic programming languages (at least for the purposes of any non-trivial program). Recently, while reading the first chapter of “Practical Cryptography” (by Niels Ferguson and Bruce Schneier), it occurred to me that authors’ explanation of “The Evils of Performance” was very relevant to my opinions of these languages.

    In that first chapter, the authors stress the importance of security being made the single top priority. They make this point by looking at security as an engineering discipline. As they point out, good engineering has always been about making safety and reliability the primary concerns. No other concern should ever be optimized to a point where it could interfere with safety or reliability.

    The authors go on stating that, in the same way, the computer industry needs to prioritize security far ahead of efficiency. To illustrate, they present the explanation: “We already have enough fast, insecure systems. We don’t need another one.”

    I’d argue that in computer programing, reliability deserves a similar status ahead of efficiency. Just as in other forms of engineering though, this doesn’t just mean placing reliability ahead of the actual product’s efficiency. This also means placing it ahead of the efficiency of the development process itself. We already have enough unreliable software being churned out.

    Which brings me back to dynamic programming languages: The reason I so strongly dislike many (albeit, not all) of the characteristics of these languages is because they treat short-term programmer productivity as a holy grail (sometimes even stating it as the single primary goal), while allowing good engineering principles like reliability to fall by the wayside. The real irony, though, is that maintaining an unreliable program is itself a drain on programmer productivity, thus hijacking any long-term productivity gains. So for any non-trivial project, these languages would have been more productivity-friendly by going the engineering route and making design decisions that focused on aiding the creation of reliable software at a reasonable speed rather than potentially buggy software at rapid speeds.


    I Want My IArithmetic!

    March 10th, 2008

    Here’s a new language rant for me: If the .NET Framework has had an IComparable interface since version 1.1, why in the world does it still not have an IArithmetic? Or even operator constraints. We’re now on version 3.5, and there’s still no sign of this stuff. What in the world are they waiting for? Implementing IArithmetic would take what, about one person a couple of hours?

    If you don’t know what I’m complaining about, try this: Add two objects of type ‘T’ in a C# generic function…without using some esoteric work-around. Go ahead, I dare you. One hell of an oversight, innit?


    Type Systems and Indentations Are Weak

    March 10th, 2008

    I’ve complained about weak and dynamic typed languages before. But damnnit, I’m just so crotchety I’m gonna do it again:

    Weak and dynamic typing are bad because type safety is good.

    Weak and dynamic typing are bad because compile time errors are better than run time errors.

    Obviously, weak typing and dynamic typing can be very useful in moderation. But like they say in booze commercials: only in moderation. Moderation, of course, means “Don’t base the whole damn language on it”.

    I’ve also whined about semantically-meaningful indentation before. Guess what? I still feel crotchety. *Ahem*:

    Semantically-Meaningful Indentation: It’s bad. Don’t do it.
    That means you, Python and SPIN.


    Language Rants Part 2: Language-Enforced Indentation

    August 5th, 2007

    Using indentation to define scope is a bad, bad idea. I’m looking at you, Python and SPIN. Like weak/dynamic-typing, it’s fine for trivial programs, but as soon as you use it for anything more substantial it becomes a maintenance nightmare.

    Let me clarify one thing: Of course you should always properly indent your code. However, the problem is when a language is designed to interpret that indentation as having semantic meaning rather than just ignoring it.

    “But, if code should always be indented, shouldn’t the compiler enforce that?” Not exactly. We should (and do) have tools that optionally enforce proper indentation. But such tools belong in places like the editor or the compiler’s warnings, not in the language definition itself.


    Language Rants: Weak Typing and Misc.

    July 4th, 2007

    Years of condemnation to the seething underbelly of the programming world known as “web application development” has driven me to this plea:

    Please, for the love of god, no more weak-typed languages!!! I can’t take it anymore! That includes you too, duck-typing. (Yes, I realize many of those languages optionally allow strong types, but that’s just a bandage, and often an afterthought.)

    Here’s the generalized rule of thumb these weak-typed languages are breaking:

    Anything that CAN be handled at compile-time, SHOULD be handled at compile-time.

    (Obviously, I’m counting “parsing interpreted-language code” as compile-time here.)

    Why is this a good rule of thumb? For one thing, optimization. If you offload certain calculations (such as arithmetic on numerical literals, ie ‘2 + 3′) to the compilation process, then your program doesn’t have to, thus speeding it up. Fortunately, this sort of thing is already handled by most compilers, so you don’t have to worry about it. (If you’re wondering: yes, I have come across one notable exception: SPIN)

    But there’s another more important reason for this rule of thumb: Bugs. Bugs are bad. There are two types of bugs: compile-time bugs and run-time bugs. Compile-time bugs are always brought to your attention automatically, whenever your code is compiled. That makes them easy to fix. Good bugs. Or at least as good as bugs get. Run-time bugs only show themselves if you’re lucky. These bugs hide and fester. That makes them hard to fix. Bad bugs.

    I don’t like weak typing because, while it might seem to eliminate type concerns, all it really does is change the type errors from compile-time (good) errors into run-time (bad) errors. This may not be a problem when you’re whipping up “Lil’ Coder’s First PHP Page”, but when you have a full-blown web application to maintain, you’ll just waste your time hunting down bugs that could have been pointed out to you the moment they were introduced.

    Languages that religiously force everything into the latest silver-bullet paradigm have also got to go. I’m looking at you, Smalltalk and Java (Clarification: I like OOP. I don’t like religious OOP.) Here’s an excellent explanation of one of the reasons I can’t stand Java.

    As long as I’m ranting on languages, VB6 is obnoxiously verbose. (Yes, I know VB6 has been replaced by VB.NET. But I’m still condemned to it anyway.) Behold:

    In most C-based languages:

    int var = 5;

    In VB6:

    Dim var As Integer
    var = 5

    How clunky. I have other examples of VB insanity (yea, I know, who doesn’t?), but they’ll have to wait for now.


    Build Environment Poll For GBA/DS Homebrewers

    April 3rd, 2007

    GBA/DS homebrew developers: Please take a moment to answer this poll I’ve posted at the gbadev.org forums. I’d like to further my efforts at making GBA/DS development easy to get set up and going, but I’m not sure what the most popular tools are. I’d like to continue progress on GBAForVS6, but I don’t know if anyone’s even using Visual Studio 6/MSVC 6 anymore.


    D on GBA/NDS Progress, Thanks to OOPMan

    April 2nd, 2007

    This time around I didn’t have much success combining GDC with DevKitARM on my own. But, OOPMan has gotten it working on Linux (minus standard libraries like Phobos or Tango).

    Fortunately, I was able to use OOPMan’s instructions to successfully build native Windows binaries of GDC+DevKitARM (again, minus standard D libraries) using MSYS/MinGW. So hats off to him :) (FYI, I haven’t had a chance yet to actually test the binaries I built)

    Regarding specific versions, I was able to build off of GCC 4.1.1/GDC 0.22/DKA r20, and off of GCC 4.1.2/GDC 0.23/DKA r20 (the latest versions at the time I’m writing this).

    I’ll upload the Windows binaries for GCC 4.1.2/GDC 0.23/DKA r20 when I get a chance later today, so anyone who wants to can play around with it.

    After that, I plan to combine OOPMan’s instructions and buildscript into the actual DevKitARM buildscripts, and write up some *very* detailed how-to-build documentation for any Windows users who have no experience building any form of GCC (Something I could have used a year or so ago. The information is out there, but it usually requires some strong familiarity with Unix-like systems and the open source scene).

    [UPDATE 2:00a 4/3/2007]: I’ve uploaded the windows binaries. I didn’t build the crts or tools, just the compiler, so you should extract the archive over top of an existing installation of DevKitARM r20. I haven’t tried using this for any DS apps, but it seems to work with a simple C GBA app (the small sample included in GBAForVS6, although I had to change the generated makefile to use “arm-eabi-*” instead of “arm-elf-*”).

    It also works with a simple D GBA app, but with a caveat: The lack of phobos or tango prevents many of the language’s features from being usable (for instance, trying to use structs and classes will generate linker errors).

    I’ve uploaded the D GBA app I used, including project files for Visual Studio 6 and the pre-built ROM image. If you want to compile it yourself, you will have to edit the makefile to point to your DevKitARM-with-D directory. The makefile also assumes that you have GBAForVS6 installed (you’ll also have to specify the directory for that in the makefile, too). If you don’t want to use GBAForVS6, or don’t have Visual Studio 6, you’ll probably need to make additional changes to the makefile.

    D on GBA Screenshot

    [Update 11:00a 4/3/2007] : If you try to compile the sample D app, there’s one other thing I forgot to mention. You’ll need to first download a regular (ie, non-GBA/DS) D compiler like DMD. Then go into the sample app’s makefile and change DINCDIR (below the “Nothing below here should need to be changed” line, ironically) to point to the regular D compiler’s phobos directory. For DMD this should be “{your dmd dir here}\src\phobos”.

    Note that this doesn’t mean you’ll be able to use phobos. The compiler just needs to be able to grab the “object.d” file there. If you don’t do this, you’ll get the error: “object.d: module object cannot read file ‘object.d’”

    Yes, setting up to compile a D app on GBA does take some work at the moment. But it should get easier as this “D for GBA/DS” project progresses. One of my personal goals on this project is to make it as easy as possible to get a D project up and running on GBA/DS.


    Trying for D on GBA/NDS, Redux

    March 3rd, 2007

    I found (or rather, he found me) a person trying to get D going on the GBA/NDS by combining GDC with devkitARM. I’ve attempted this before a while back (before NDS homebrew, and before GDC eliminated the Java requirement for garbage collection) with partial success (got a limited subset of D working). This has motivated to get back into the project.

    I’m on Windows with MSYS/MinGW, the other guy’s on Linux, so hopefully we can get this working on both platforms. I’m a bit behind at the moment though, I’ve lost/forgotten all of the old work I did, and never made notes (like I meant to do), so I’m back at the beginning still trying to get all the necessary tools installed and working right in MSYS. This part is every bit the pain in the ass I remember it to be, hopefully the rest will go smoother this time (should be at least somewhat easier, now that GDC is no longer borrowing it’s garbage collection from Java). But I’m taking notes this time ;) I’ll report on any progress I make.