Coding Style Part 4

By Shamus Posted Monday Jan 28, 2013

Filed under: Programming 73 comments

splash_frustrated.jpg

And so we come to the end of the Office document that describes the internal coding conventions of id Software. This last section is pretty non-controversial and so I don’t have a lot to say about it. But here are the last of my notes, for what it’s worth…

As before, the style guide is in bold, and everything else is me blathering.

Variable names start with a lower case character. In multi-word variable names the first word starts with a lower case character and each successive word starts with an upper case.

float x;
float maxDistanceFromPlane;

Another holy war topic. How do we name our variables? There are a lot of systems.

For years, I heard about, encountered, and put up with “Hungarian” notation. That’s a system where you begin you variable names with a letter to indicate what kind of variable it is:

fHealth = 0.0f; //A float
iHealth = 0; // An integer
szHealth = "Dead"; //A string

I never liked this, and I dismissed it as superfluous, overly verbose, and annoying to type. I went around saying things like, “Hungarian Notation is superfluous, overly verbose, and annoying to type. Also it sucks.” The irony is that I’ve actually been using Hungarian notation this whole time without knowing it.

What I didn’t learn until I began this series is that this is not how Hungarian Notation was supposed to work. This is a misunderstood, bastardized offshoot of the original system. This notation scheme is properly called “Systems Hungarian”.

Actual Hungarian Notation – that is, the system devised by the man from Hungary himself – was intended to be a system where the first few letters would describe, roughly, how a variable is used or perhaps in what context.

For an example that applies to me: I often find myself working with a lot of different coordinate systems. There are local coordinates. (Steve’s gun model is attached to the hand of his character, which is 0.1 units from his center.) There are global coordinates. (Steve is standing 10m north, 103m west of the world origin.) And screen coordinates. (Steve’s health bar is drawn 5 pixels from the left edge of the screen.)

I’ll be dealing with a lot of X, Y, and Z variables, each of them mapped to a particular coordinate system. If I get confused about what kind I’m dealing with, I’ll end up accidentally attaching Steve’s gun to the world origin instead of his hand, or something similarly absurd. So if I see a variable named “x” in the code, I have to wonder which coordinate system it’s in. To figure it out, I sometimes have to backtrack and read a bunch of code. This sort of review is time consuming and cuts down on the time you’ll be able to spend on more important things, like arguing over brace positioning and tab sizes.

The solution here is to come up with a naming system that lets you know how a variable is being used. Perhaps localX, worldX, or screenX.

I actually began doing this on my own during Project Frontier. Although, you can find many spots in the source where I didn’t follow this because I forgot or because the code was borrowed from an older project. When Project Octant came along I was a little more careful about it. I’m pretty sure all of my new code follows this, and the only places where I should see unadorned X and Y values is in legacy code.

It seems to be paying off. I’ve run into a few situations where the variable name rescued me from a bit of confusion or foolishness.

This way of naming things is now called “Apps Hungarian”. I’m going to be more intentional about following it in the future. (Systems Hungarian still sucks.)

This goes to show that it’s sometimes worth reading some of those obscure, jargon-laden, theory-heavy essays on coding. Usually I’d rather write code than follow long debates about code, but I could probably stand to pay a bit more attention to theory.

On the upside, we got you a new monitor so you don’t need to use that green monochrome one anymore.

Defined names use all upper case characters. Multiple words are separated with an underscore.

I’ve read my share of code in my lifetime. Code from big companies. Code from small contractors. Code by old timers. Code by college pups. Production code, beta code, prototype code, example code, and legacy code. And I’ve never seen a codebase where anyone deviated from this rule. This rule is so common and so universal that it feels like part of the language itself.

(Okay, there’s a debate over using consts or #defines. The id doc doesn’t get into that, and we already did a few laps around that particular mulberry bush the other day. Let’s just assume we’re talking about consts OR #defines, whichever tickles your particular fancy.)

When you’re coding, you will often need magic numbers. Sure, most of us can recognize the usual suspects like pi, but less famous numbers like 0.017453292 (the number you multiply by to convert degrees into radians) are harder to spot. Your code is going to need a lot of very specific numbers. The number of milliseconds in a minute. Falling acceleration and terminal velocity in Earth gravity. The number of rounds you can put in a revolver. The aspect ratio of a movie screen. The point size of the default font. Whatever.

You can just stick the numbers in your code as literals if you want to make people crazy.

 
if (drop_distance > 768) {
    damage = 14 * (drop_distance / 768);
    if (armor > 0) 
      damage *= 0.5f;
    health -= damage;
    if (health <= 0)
        GameOver ();
}

You can tell what this code does, but the magic numbers make it a little harder to sort out. By using #defines

#define PLAYER_HEIGHT     768
#define FALLING_DAMAGE    14
#define ARMOR_PROTECTION  0.5f
 
if (drop_distance > PLAYER_HEIGHT) {
    damage = FALLING_DAMAGE * (drop_distance / PLAYER_HEIGHT);
    if (armor > 0) 
      damage *= ARMOR_PROTECTION;
    health -= damage;
    if (health <= 0)
        GameOver ();
}

Now we can see what that number 768 is all about. That’s how tall the player is. Now we can see that you take 14 points of damage for every body length you fall. Even better, if you need to change something later – like perhaps someone says the player should be 640 units tall instead of 768 – you’ll just need to change it in one place. Contrast this with the the first case, where you would need to change all instances of 768 to the new value. If you miss some, then you’ll have this strange bug where the game has differing ideas about how tall you are based on what it’s doing. Sure, you can use find & replace, but just wait until you have two magic numbers with the same value. Congratulations, you just made the player shorter but also changed the number of bullets they can carry from 768 to 640. Oops.

Having words in ALL_CAPS with underscores is almost universally understood to mean “this is a #defined value”. Seeing this spelled out in the id Software guide is like seeing a “All employees must wash hands before returning to work” sign in the scrub room where everyone gets ready for surgery. Yes, I would hope this is the case, but I’m kind of alarmed that it needed to be said.

Wrapping Up

So that’s the guide. I’ll say that the document strikes me as being very general, brief, and relaxed. I’ve seen longer and much pickier guides at smaller companies. Then again, I’ve never worked anywhere that could boast of having id Software-level employees. I suppose in a place like that they can give the programmers more liberty. After all, the rules are supposed to guide you, not hamstring you.

I’m guessing that these style guides are also more detailed when they come from larger companies. (I’ll bet Microsoft has many guides that approach novella size.) The larger your team, the more important it is to enforce a rigorous system. Two programmers can quickly learn to spot and accept each other’s eccentricities and habits. On a twenty person team, all those little “personal touches” can seem like chaos.

 


From The Archives:
 

73 thoughts on “Coding Style Part 4

  1. krellen says:

    I’m sure all programmers everywhere are very glad I got out of coding, because I’m not sure I ever had a consistent style.

    1. Raygereio says:

      You probably would have eventually.
      I constantly changed things around, until I found what worked for me and it grew into a habit.

      1. Asimech says:

        My habits every time I start getting back into coding:

        No Apps or Systems Hungarian.
        Names that are descriptive only in-context.
        That context is not necessarily related to the code in an intuitive or even vaguely sensible way.
        Bad commenting, when there are any comments.
        Magic numbers all the way.
        Temporary pieces of code that may or may not do anything and are not commented or have outdated comments.
        Abuses of functions, objects etc. If there’s no list within a list for no good reason that’s because I haven’t yet gotten around to it.
        I always use brackets, but I can’t remember the rules I’ve used.
        No goto, but I didn’t really like it when I had to use it in Basic and haven’t done anything where I felt like using it made sense.

        They’ve all been tiny programs and the shortest time I got back to the code and didn’t have a clue: one day.

        Disclaimer: Not intentionally obfuscated, not drunk coding. I start with the thought “this time I’m not making a huge mess of the whole thing” and usually within a week it’s a full-blown clusterduck.

        1. pneuma08 says:

          FYI goto is typically used in the context of a multiple nested loop, where the alternative is to include an “if(done) break;” statement at some point in each loop level. It’s really pick your poison at that point, IMO.

          But yeah, you can do whatever you want with your code and no one will care, right up until the point when someone else – or you yourself a couple months from now – has to figure out what you were thinking. Suddenly all that stuff matters a lot.

    2. Rick says:

      The better way to think of this is always evolving :p

    3. wererogue says:

      I’ve always fallen in with the style of the codebase I’m using. I have my own preferences, but when I’m working, I naturally check for examples as I read.

  2. NCB says:

    I’m interested to see how much a coding convention could change for a company that makes extensive use of proprietary software in their system, such as Star Wars: The Force Unleashed.

    Or whether it doesn’t make a difference at all.

    Also found this fun fact on wikipedia: “According to the Doom 3 manual, GUI designer Patrick Duffy wrote over 500,000 lines of script code, and generated more than 25,000 image files to create all of the graphical interfaces, computer screens, and displays throughout Doom 3.”

    Oh dear.

    1. X2-Eliah says:

      25 thousand image files? … how does that even make sense?

      1. Primogenitor says:

        He probably did many of them using the half a million lines of script – rotation, lighting, level-of-detail, etc.

      2. WJS says:

        My guess would be some procedural systems that were baked for better run-time performance.

  3. Trithne says:

    Actually, I have the joyful situation of maintaining a few legacy apps where consts aren’t ALL_CAPS_WITH_UNDERSCORES. Instead they’re just ciPlayerHealth, for an example. So the worst of all worlds.

    1. Esteis says:

      At least the variables were still marked as constants. (Assuming the c stands for const, and not for ctring, cumeric, cash, or coolean.)

      1. anaphysik says:

        A coolean’s possible values are ‘hip’ and ‘square’.

        The 1986 update to hueylewisandthenews.sys unfortunately wrecked havoc with most implementations of cooleans.

      2. Guvnorium says:

        Or cash’s subtype, coin.

    2. Khizan says:

      See, this is where the argument is. I don’t capitalize const variables, but do capitalize #defines.

      This is because, to me, all-caps says “THIS IS A PRE-PROCESSOR STATEMENT.”

      1. Wedge says:

        I’ve carried the ALL_CAPS_CONSTANTS notation into languages which don’t have preprocessor macros (read: basically all of them) and it’s still a useful convention. In fact, it’s useful in languages like Python which don’t have semantically constant variables, as a way to indicate that a given variable is *intended* to be constant so you won’t go do something stupid like change it.

        1. Khizan says:

          When you want to indicate a variable is const, the proper way to do that, imo, is the prefix ‘k’, the one acceptable use of systems Hungarian.

          “kPlayerHeight” says, to me, “This is a constant variable. It has a place in memory.” “PLAYER_HEIGHT” says “This is a pre-processor macro and it has no place in memory and treat it just like a literal.”

          They’re two entirely different things, and should have two different forms of notation.

          1. Anachronist says:

            Those of us coming from a Fortran background would think the “k” prefix defines an integer when that may not be your intent. For the graybeards, any variable beginning with i, j, k, l, m, or n is assumed to be an integer. Even to this day, I tend to name my integer variables that way, and anything else simply mustn’t begin with those integer-designation characters. Occasionally I’ll catch myself going out of may way to avoid naming a float something like “micrograms” even when that would be the most sensible name for the context.

      2. Phill says:

        I agree. caps says I_AM_A_PREPROCESSOR_MACRO. I’m quite happy to define some constants that way, but when it comes to actually declaring a constant I’ll call it kDefaultHeight or some such thing. I don’t feel too bad about the systems hungarian use in that one case, since it can be useful to know whether something is const or not without having to scroll back up to the top of the file to find out.

        I’m not personally a fan of having constants written in ALL_CAPS like #defines are because they behave differently and (more to the point) there are bugs that crop up in macro replacements that don’t happen with consts, so it is useful (in my mind) not to get them mixed up.

  4. Robyrt says:

    This series has been a lot of fun to read. Thanks!

    Looking at that last piece of code, it’s amazing how much the practice of making games has changed over the last decade. People are far less likely to implement this kind of linearly scaling fall damage system, except in MMOs. Most games will use invisible kill boxes in the level design, maybe with a flat “if height > 2000, player health -= 50%” calculation. The impetus is probably the introduction of a special falling animation (probably the hero drops to one knee and grunts), which implies that you should take damage if and only if you are seeing the special animation.

    1. WJS says:

      Really? I can only think of two times I would expect to see an exception to fall damage proportional to fall distance: games with no fall damage at all, and games where fall damage is related to fall velocity (so roughly proportional to distance squared).

  5. Daniel says:

    “I'll bet Microsoft has many guides that approach novella size.”

    From personal experience: Oh, you have NO idea.

    1. SteveDJ says:

      Oh come on now – it is time the truth be told…

      Whether or nor there ever was/is a universal MS style, each team at Microsoft seems to have their own unique flavor.

      And even on the same team, devs will have their style, while automation written by testers can sometimes have a different style. Or worse, they cannot even share the same language – i.e. dev product code written in C++, while test automation code written in C#

      Yes, that’s the ugly truth.

      1. Kevin says:

        Now with that said, if you ever want to know something about C#/.NET PINVOKE, their testers are the people to ask. Since most of the OS code is written in “C++”*, and all of the testing is written in C#, they are doing some crazy, crazy stuff.

        *The quotes are intentional. C++ with COM, with goto’s inside macros, and without C++-strings (or the rest of the STL. They have their own internal version and it’s not bad, once someone points you at the API’s) is, in my opinion, not actually C++. It’s C pretending to be C#.

      2. WJS says:

        There’s no “seems” about it; that’s where the whole Apps/Systems Hungarian split came from from what I’ve read; the Office team used Apps, the Windows team used System (hence the names).

  6. Nano Proksee says:

    Interesting read. Even for a non coder like me.

  7. Chris says:

    Thanks Shamus for the review. It has been interesting to read and see the discussion that followed. Look forward to the next programming article.

  8. HiEv says:

    Am I the only one who saw the “Matrix” image and thought, “Blond, brunette, redhead, … Yourwallpaper.com?”

  9. Nicksaurus says:

    “I'll bet Microsoft has many guides that approach novella size.”

    These are the standards they use, apparently.

  10. Esteis says:

    Also: that Matrix joke is excellent.

    1. anaphysik says:

      It is excellent, but the pedant in me still glances at it at says “Those are Japanese characters (possibly not meaning too much semantically, based on the odd katakana placement (they look to be mostly isolated between kanji & hiragana, rather than clumped together as they ought be found)) – AHEM, those are Japanese characters, Shamus, not Wingdings, you uncultured SWINE.”

      :P

      1. Steve C says:

        Code written by computers that hate humans… why wouldn’t it be wingdings?

        1. X2-Eliah says:

          Because it should be Webdings, the clearly superior type of dings.

      2. pneuma08 says:

        Actually, if I remember my Matrix lore correctly, it’s reversed katakana that shows up in the movie(s?). But it appears the picture Shamus found is homebrew that uses regular Japanese (i.e. both kana alphabets with kanji) with the occasional (same) English sentence.

    1. Mike C says:

      Bah, thought I had aborted this post in time to post the nicer looking link below.

    1. lethal_guitar says:

      “Novella”? More like “encyclopedia”, actually..

  11. Brandon says:

    I just wanted to say that Systems Hungarian style is made even more irrelevant because some languages nowadays allow really loosely typed variables. Some languages don’t even have any concept of variable types at all.

    Apps Hungarian is still relevant in those languages, because of the emphasis on what the variable is being used FOR, not what kind of data it is storing.

    1. Alan says:

      Weak typing could be an argument for Systems Hungarian. Sure the language allows you to pass in the string “Fred” to calc_sales_tax, but it’s probably not going to do something sensible. If calc_sales_tax is well written, it will probably raise an exception in some way, but all the better to notice the bug before the program is actually running. Systems Hungarian provides a sort of strong typing, where the type verification is done by the human instead of the compiler. Of course this

      Personally, this is all hypothetical. I use several weakly types languages (Perl, Python, Bourne shell), and I don’t use Systems Hungarian there. But I could see an argument for it.

      1. silver Harloe says:

        IMHO, every argument for Systems Hungarian is an argument for Apps Hungarian, except Apps Hungarian has additional arguments for it being superior.

      2. Wedge says:

        Dynamic typing doesn’t mean that there is no longer such a thing as type, it just means that type-checking is done at run-time rather than compile-time. I don’t know about Perl, but Python is strongly typed (dynamic typing is NOT the same thing as weak typing!) because it does not allow you to do operations that don’t make sense: in your example, calculating the tax of something will generally involve doing something like this

        >>> def calculate_tax(val):
        … return val * 1.04

        >>> calculate_tax(“foo”)
        Traceback (most recent call last):
        File “”, line 1, in
        File “”, line 2, in calculate_tax
        TypeError: can’t multiply sequence by non-int of type ‘float’

        Which fails because multiplying a string by a float doesn’t make sense. A weakly typed language (e.g. Javascript) will instead try to convert the string to a number to do the operation, and if it cant it will evaluate to something like NaN, letting the program to continue on its merry way–this is why weak typing SUCKS, and this is where I could probably see a good case for Sys Hungarian.

        1. Alan says:

          I’m being sloppy with my terminology, I do mean static/dynamic typing. My core point stands, “all the better to notice the bug before the program is actually running.”

          Dynamic typing means the compiler can’t help you get it right, so it’s up to the humans to get it right. And some form of Hungarian can certainly help the humans spot problems. (Or, if applied consistently, could allow you to write a tool to do the validation. Something akin to Fog Creek’s Thistle.)

          Arguably, that dynamic typing makes it easy for a serious type bug to hide in a rare code path is evidence that dynamic typing SUCKS. Personally I find dynamic typing, weak typing, and even manual memory management, to not be as terrible in practice as opponents suggest.

          1. Wedge says:

            My experience is that in Python, which has (mostly) strong typing, errors based on type mismatch are rarely difficult to find and debug, because they tend to either do the right thing or immediately explode in your face (i.e. raise an exception). With weakly typed languages, however, weak typing often creates headaches because it tends to hide those same errors by doing something nonsensical and continuing merrily along, so by the time your program crashes (if it crashes at all!) it’s hard to figure out where the problem actually started. At the same time, I don’t find that weak typing actually gives any benefit to offset the problems it causes, whereas dynamic typing is a huge productivity boon. That’s why I say that dynamic typing is good and weak typing is evil, and get annoyed when people conflate the two :)

            You make a good point about Apps Hungarian being useful in static code analysis–I’ve recently begun to love SCA after developing a large Javascript codebase. JSHint has saved my life quite a few times.

            1. Jimmy Bennett says:

              Part of the problem is that “weakly typed” is a subjective term. I’m learning Clojure, and, while I enjoy working with the language, I find that it does implicit type-casting a little more often than I’d like.

              As an example, I recently had an array out of bounds error in my code. The error happened because I was using a floating point number as an index to the array and, when the float rounded up, it accessed the index one level higher than I expected it to.

              I feel like a sane type system should have thrown an error as soon as I used a float to index an array, but I guess the guy who made Clojure feels differently.

              1. WJS says:

                Well, I’d argue that different types of numeric data is where transparent casting makes the most sense, since not being able to multiply 1.5 by 2 (for example) is horribly unintuitive. I can see merit to disallowing floats in the specific case of array indices, however that sounds like the kind of thing that’s harder to implement that it sounds.
                (Also, am I the only one that thinks it’s weird that a float should round up that much? They shouldn’t be that imprecise)

      3. nmichaels says:

        Python (and Perl, I believe) are strongly typed. There is a difference between strong typing and dynamic typing.

    2. MrPyro says:

      As Alan said, weakly typed languages are actually where there is a purpose to Systems Hungarian: that variable could contain anything from an integer to a float to a 512 character string, so knowing what type the developer intended it to contain can help with spotting problems.

      That’s not to say that it always helps, but it can make it slightly easier to spot problems caused by the programming language performing implicit casts when you try to treat it as the wrong data type.

  12. Alex Broadhead says:

    The code I worked on at Microsoft (WMA several years ago) used (really awful & inconsistent) systems Hungarian.

    That choice in particular was the bane of my job, which involved porting floating point code to fixed point as ‘example’ code for third-party embedded firmware writers (who presumably might not have access to floating point). Some of the relevant variables were defined as unions of floats and ints. Some were just float (or occasionally just int). Some were already implemented as switchable despite being named as float. I regularly needed to change the names of variables used all over the code base, because the names were, in effect, bugs, as they didn’t reflect the actual types or usage of the underlying variables. And changing large segments of the code base is a big no-no, as it makes building and testing very difficult. So yeah, systems Hungarian == the suck.

    I regularly create ‘virtual’ namespaces in C by prefixing all the functions and or variables in a file with ‘NAME_’ or similar, and I’m quite happy with kVariable or gVariable or mVariable or similar for constants or globals or structure members – those are handy, and I didn’t even know that they constituted a type of Hungarian. (I first experienced the latter when I interned at Apple, BTW…) That sort of thing is essentially another form of commenting. But building the types of variables into their names? That way lies madness.

  13. MichaelG says:

    Does anyone still use “m_thing” for class elements? I saw that in MS code when I first started doing apps for Windows, but I’m not sure it’s still in use. I don’t remember you covering that in this series.

    1. Alan says:

      I still see it occasionally, but usually in the context of Windows programs or people with a Windows background. My personal initial exposure was in the Microsoft Foundation Classes, which use it as part of their (Systems) Hungarian notation. I still find it occasionally useful when I have a fistful of member variables with names I’ll likely want to use as local variable names (especially arguments), and the thought of piles of this->varname makes me tired.

    2. Shamus says:

      We used that at Activeworlds. I didn’t like it because it was fiddly to type. In my own work I just just an underscare. From looking at other code, I think mVariable is the accepted format for member variables.

      1. lethal_guitar says:

        Some C++ gurus recommend using trailing instead of leading underscores: Reserved names (by the compiler or standard libs) usually also start with an underscore, which could lead to name clashes in rare cases. Since trailing underscores aren’t exactly easy to see at first glance, using mIdentifier seems like a goodncompromise.

      2. MichaelG says:

        Since public member names are part of the interface to a class, I’d actually prefer a naming convention that distinguishes local variables. I haven’t seen one that’s in general use though.

    3. MNF says:

      My previous job (a Java trading client) required the m_ prefix. The reason was consistency with existing code.

      I expect that their next-gen client will drop the prefix.

    4. Wedgebert says:

      I use m_ for member variables for a couple of reasons.

      Visual Studio these days likes to automatically insert horizontal lines to help make your code easier to read. However often times this can make underscores hard to read if they’re followed by a one of these lines. So just doing _MyMemberVariable can look the same as MyMemberVariable (which is typically the property name). Of course, these days I tend to use automatic properties whenever possible, so the members are irrelevant.

      Also, I cannot overstate my hatred of case sensitivity as a way to differentiate things. I’ve seen some coding guidelines that say “foo” is the member and “Foo” is the property. Makes me want to cry. And don’t get me started if you have a local variable foo in a method. This is one of the many reasons I prefer VB.NET over C#.

    5. ClearWater says:

      I’ve gone back and forth between liking and naming member variables differently from local variables. Now I mostly rely on the IDE to show member variables in a different colour, or I use this.memberVariable (in Java) to make it explicit. Not sure if there’s any disadvantage to that.

      1. Wedge says:

        After using Python and Javascript, where using self/this is required, I’ve brought the explicit style back with me to Java/C++ and friends because it makes it much clearer what’s going on.

    6. Phill says:

      I use m_Whatever for member variables. My coding style is based around the principle of whether it makes it easier to understand code and spot mistakes. A good coding style will make it harder to write incorrect code without realising it (which is the principle of apps hungarian). Unambiguously indicating member variables avoids the problem of name clashes and variable hiding. If I assign to m_Length I know I am storing a value in the member variable for future use. If I assign to Length, which is the name of the member of variable, then I might not notice that some muppet has declared a local variable Length at the top of the function which has hidden the member variable, and my calculation is in fact being thrown away. (Some compilers warn you about hiding variables, some don’t…)

    7. Deadfast says:

      I consider that to be redundant in the age of IDEs. Not only will the IDE color member variables differently, the prefix also actively sabotages auto-completion. If my variable is called just timeCreated all I have to do is type t and it’s readily available as a suggestion, usually as one of the top results because IDEs (can be configured to) prefer member variables. With m_timeCreated I’d have to type m_t to achieve the same result. I do find the idea of using an underscore as a postfix much more appealing.

      1. Shamus says:

        To be fair, not all IDE’s do this. I’ve used Qt and Visual Studio, and neither one highlights member vars differently by default. (Maybe you can set it to do so in the options, but then there’s the question of the Other Programmer who is using the defaults.)

      2. Wedgebert says:

        While m_ does mess with autocomplete to some extent (vs2010+ use a *term* search for intellisense, so you can type var and it will find m_Var as well), I use the m_ as a sign I might be doing something wrong.

        m_Foo means I’m not accessing the property Foo, which means I’m skipping any validation or other logic the property provides (like setting an IsDirty flag). While sometimes this is desired, more often than not, I want property. Even if it does nothing now, it’s easier to refactor than search/replacing all m_Foos

        1. Yeah the IDE is critical. The PureBasic IDE for example does pretty good highlighting (you can also change the colors), you can also use a EnableExplicit directive and the compiler will insist that you defined all vars. Together this keeps any messy coding and issues from cropping up.

          Personally I do not use f or l at the start of variables (it also messes up autocomplete for me).

          I do however do something when I work with my own functions.
          If it’s a include file or a library (dynamic or static) I’m making, then all functions belonging to that library will start with a name tied to that library.

          This is a pain if I ever move a function from one library to another, or from one include to another.
          But as multiple projects rely on these, and the functions are pretty much core functions that rarely happens.

          It also avoids a lot of conflicts with Win32 API names or names of functions from third party libs (dynamic and static).

          The Ideal could would be “readable code”, by that I mean, with no comments at all you should be able to scroll through the code and understand (by just reading it) what is going on, even if you do not usually code in the language the source is written in.

          Sadly a lot of the sources out there is so odd that I find it easier to reformat and rewrite the darn things just to make sure I understand everything that is going on in them. I usually end up with writing smaller faster code than the original source as well.

  14. RandomPhysicist says:

    Actually, I’m glad id/you mentioned the thing about style for defined values. I’m a physics grad student and do all my coding in FORTRAN 90. I think computational scientists have more of a loosey-goosey approach to style and formatting of code than our computer scientist brethen. I’ve been planning to brush up on C++ before I hit the job market and it’s good to hear about standard formatting stuff that isn’t intuitive but is nearly universal.

  15. RandomPhysicist says:

    Actually, I’m glad id/you mentioned the thing about style for defined values. I’m a physics grad student and do all my coding in FORTRAN 90. I think computational scientists have more of a loosey-goosey approach to style and formatting of code than our computer scientist brethren. I’ve been planning to brush up on C++ before I hit the job market and it’s good to hear about standard formatting stuff that isn’t intuitive but is nearly universal.

  16. nmichaels says:

    I don’t believe you’ve got the right definition of hungarian notation there. Yes, systems hungarian (since everyone’s using Joel’s terminology) is stupid and looks the way you described, but what you showed as an example of apps hungarian is not hungarian at all. That’s called naming your variables sanely.

    The unifying principle of hungarian notation is that it uses individual letters at the beginning of variable names to encode some sort of information about the variable (the difference between apps and systems is what kind of information) in a way that is not immediately obvious to someone unfamiliar with the practice. I didn’t reread the article, but I believe Joel Spolsky’s examples used “s” and “us” to indicate that variables were safe or unsafe to store in a database. Your example with X would be lX, wX, and sX instead of localX, worldX, and screenX. Then, everywhere in your code that you made a variable that referred to the screen, you’d stick an s at the beginning of it. Seem silly?

    Putting more meaning into variable names is great. Saving characters by making a little code that only you and your friends understand is not. I still say all hungarian notation is bunk, though I’ll cede that the concept as introduced by Simonyi (the Hungarian) was not a totally idiotic idea.

    1. WJS says:

      The point of Hungarian is that if you ever see

      PrintS(usName);

      then you don’t need to know what “s” and “us” mean, you can still see that it’s wrong. You don’t need to know what either mean to know that

      PrintS(SFromUS(usName));

      is probably what it should be. Although, if you don’t understand the variable naming convention, what the hell are you doing screwing around with someones code?

  17. Paul Spooner says:

    This kind of “style guide” applies anywhere that unambiguous communication is necessary. We have dictionaries for language, drawing standards for drafting, and so forth.
    What is lacking in many standards is the concept of “tolerances”. If only a “nominal” value is given, how far off can you be before you’re violating the standard? Dictionaries offer multiple definitions to try to give a range of meaning. Dimensional drawings often have a +- value to indicate how far off the actual product can be and still be useful.

    Software standards, though, often ignore this concept completely. True, it’s possible to have objectively perfect code… but just because a document can be in perfect conformance to an unyielding standard, does not mean that it is worth the effort.

    Of course, the shorter and less involved the standard is (like the ID Code Style Conventions) the easier it is to conform. But even there, I’d be happy to see more thought given to “how close” something needs to get before it is acceptable. Nothing is perfect, and robust standards take this into account.

    1. WJS says:

      This is ridiculous. Dictionaries offer multiple definitions of words because they describe, not prescribe, the language. Technical specifications prescribe tolerances because it’s impossible to manufacture something exactly as prescribed. Neither is comparable to a coding style guide. A guide that just says “Names should be capitalised this way. Or not. Y’know, if you don’t feel like it.” is completely useless.

  18. Deoxy says:

    Systems Hungarian is nice for weakly typed languages.

    Personally, I also like it when I’m dealing with literals, as I can easily realize, “Hey, that 2.75 is going to have a problem going into iWhatever”, but that’s mostly one-off kinds of things.

    Another thing that I see in your code… what if ARMOR_PROTECTION needs to get put into an integer variable? No one would see anything wrong with that in the code.

    THAT is why I like Systems Hungarian. Apps Hungarian is better, but it doesn’t always apply.

    1. nmichaels says:

      If someone tries to assign ARMOR_PROTECTION to a variable of type integer, the compiler (or, in an interpreted language, static analysis tool) will complain. As soon as the hapless someone sees the compiler warning, they’ll realize what they’ve done and come up with a less broken solution to their problem.

      Weak typing (which C and JavaScript have, but C++ and Python do not) is just a mess. Dynamically typed languages that are also strongly typed like Python can (and do) have static analysis tools for catching that sort of error. In fact, JSLint will catch abuses of the type system too.

  19. Skye says:

    Heh. I tend to program mostly in assembly. (MSP430 mainly.) This has lead my coding style in ‘normal’ languages to be somewhat eccentric. I comment like mad though.

  20. HeroOfHyla says:

    I can never really keep a consistent variable naming standard. For my current project (a text adventure in Java), I’ve been trying to follow the Apps Hungarian guidelines, but I’ve realized that most of m variables are obvious enough that it isn’t generally that necessary. Mostly I just have different prefixes on strings to indicate whether they’re a “mixed case” string with punctuation, capitalization, and such, or a “stripped” string (all lower case, no punctuation) which is used whenever I need to see if a string matches the name of one of my entities.

    For my GUI stuff, what I’ve been doing is [purpose of this thing]_[component type] so for instance, in my script editor I have showMessage_button which runs a showMessage_action when clicked.

    I wind up getting into this stuff at first, but get tired of typing my prefixes. entity.name() is much easier to type than entity.mc_name().
    On a related note, I hate putting “get” in the name of my getters for some reason. If I want a function that returns the value of a private variable called variableName, I just call it variableName(). I do keep “set” in the name of my setter functions. Though lately I’ve found that I really haven’t needed very many setters.

Thanks for joining the discussion. Be nice, don't post angry, and enjoy yourself. This is supposed to be fun. Your email address will not be published. Required fields are marked*

You can enclose spoilers in <strike> tags like so:
<strike>Darth Vader is Luke's father!</strike>

You can make things italics like this:
Can you imagine having Darth Vader as your <i>father</i>?

You can make things bold like this:
I'm <b>very</b> glad Darth Vader isn't my father.

You can make links like this:
I'm reading about <a href="http://en.wikipedia.org/wiki/Darth_Vader">Darth Vader</a> on Wikipedia!

You can quote someone like this:
Darth Vader said <blockquote>Luke, I am your father.</blockquote>

Leave a Reply to Wedge Cancel reply

Your email address will not be published.