Programming Vexations Part 5: The Vexations Begin

By Shamus Posted Thursday Sep 26, 2019

Filed under: Programming 111 comments

One of Jon Blow’s original goals for Jai was to embrace (or perhaps restore) the “joy of programming”. I thought that while we’re waiting for Jai to come out, we could look at this idea and see what it might suggest about future languages.

“Joy of programming” is a pretty nebulous concept, but I interpret it as a desire for an overall reduction in friction and hassle. Not only do friction and hassle eat precious hours you could spend being productive, but they also drain your morale. There’s nothing worse than sitting down at your computer and realizing you’ve got a full day of soul-sucking busywork in front of you. Sure, lots of programming jobs feature this sort of vexation. The thing is, those jobs tend to pay a lot better. If you’re working in games programming then you’re probably making some sort of financial sacrifice in the name of having a “fun” job. If the job isn’t fun, you might as well ditch games and go make productivity software for more money in a city with a lower cost of living.

Things That Are Not Programming

Arg. I keep getting distracted and I can't find what I need. This is exactly how it feels when you slap together code and don't take time to add comments, tidy the formatting, and get a coherent naming scheme in place.
Arg. I keep getting distracted and I can't find what I need. This is exactly how it feels when you slap together code and don't take time to add comments, tidy the formatting, and get a coherent naming scheme in place.

Just about every job has some sort of support tasks associated with it. You need to clean the kitchen and wash dishes in order to cook foodI guess you could hire someone else to do it, but it still needs to be done., but doing dishes is not cooking. Dishwashing might be part of your job as a cook, but it’s not the point of the job. You don’t cook food because you want to wash dishes, you wash dishes because you want to cook food.

Cleaning your brushes is not painting. Stringing and tuning your guitar is not playing music. Checking spelling and formatting text is not writing a novel. Updating WordPress and sorting out CSS problems is not writing a blog. Putting gas in your car is not delivering pizzas. Those ancillary tasks need to be done and a few people might even enjoy doing them, but they don’t pay the bills. They just enable you to do the thing that does pay the bills. If you can reduce how much of your time is spent on these ancillary tasks, it will be a net win. 

I’ll admit that sometimes the line can get really blurry. An artist working on commission might have the following workflow:

  1. Promote their work on social media to generate business.
  2. Negotiate a fee with a prospective client.
  3. Enter into an agreement to produce a drawing.
  4. Look for reference photographs.
  5. Draw some rough sketches.
  6. Do some color tests.
  7. Settle on a design and provide a quick mock-up for client approval.
  8. Create the final drawing.
  9. Invoice the client.
  10. Put it in a frame and send it to the client.

I’m sure lots of people will have different ideas about which parts of this workflow fall within “creating art” and which parts are ancillary tasks. I’m willing to bet that lots of artists will wish they could do more of stuff somewhere in the 4-8 range and less of the other stuff, even if they don’t all agree on where they’d like to draw the line between “drawing” and “not drawing”.

We’re 5 entries and about 10,000 words into this series, so I guess it’s finally time to get to the main topic…

The Vexations of Modern Programming

Looks like this dude needs to spend less time in the gym and more time on StackOverflow. Then again, I usually make that same face when Google sends me to StackOverflow.
Looks like this dude needs to spend less time in the gym and more time on StackOverflow. Then again, I usually make that same face when Google sends me to StackOverflow.

Programming is no different. There are a lot of parts of this job that need to be done, even if they don’t strictly qualify as “programming”. Here are a handful of vexations that aren’t really programming:

  1. Formatting code.
  2. Compiling.
  3. Shopping for librariesIn this case “shopping” might mean buying an SDK, but it could also mean downloading source projects and testing them for suitability. These are different kinds of costs, but they’re both costs. and adding them to the project.
  4. Dealing with header files.
  5. Creating structures to obey dogmatic design paradigms.
  6. Refactoring codeRewriting or re-arranging code to keep it organized, even if the underlying logic is sound..
  7. Managing project files.

I think Blow’s idea to increase the overall joy of programming involves reducing how much time programmers spend on these sorts of tasks. Some of these things are unavoidable, but we should always be on the lookout for opportunities to mitigate them. For the rest of this series, I’m going to run through this list of time-sucking, morale-draining tasks and talk about what they involve, why they’re annoying, and how a new language might help.

This first vexation is a little bit lame and trivial. That’s fine. We’ll get to the big stuff later in the series. The first vexation is…

Vexation #1: Formatting Code is Not Programming

I don't know what language the Machines used to build the Matrix, but their code formatting was stupid.
I don't know what language the Machines used to build the Matrix, but their code formatting was stupid.

As problems go, this one is pretty trivial. The task of formatting code isn’t nearly as annoying as the arguments over how we should be formatting code. 

Most languages ignore whitespace. Whitespace is any non-printing character: Spaces, tabs, line breaks, etc. To a compiler this sentence…

This sentence is false.

…is functionally equivalent to this sentence:

This                    sentence             

is               false.

Code is very complex. Your code needs to convey a lot of concrete and precise information to the compiler. At the same time, the code must also convey a lot of abstract information to other humans. A person reading the code wants to know what it’s supposed to do, while the compiler wants to know exactly how to do it. Having the compiler ignore whitespace enables you to format the code in a way that will (hopefully) make it clearer to the human without confusing the compiler. 

In movies, they always show programmers frantically typingOften into some sort of stark terminal window with scrolling text in a terrible font with colors likely to cause eyestrain, because that looks more interesting for the audience.  lots and lots of code. In the real world, those moments of intense productivity are few and far between. Projects might start out in a rush of typing, but as soon as the program matures beyond trivial complexity you’ll find more and more of your time is being spent on reading code rather than writing code. 

Code can easily become so complex that it will act like a flytrap for other programmers. Anyone unfortunate enough to wind up in your region of the codebase will need to stop and spend a couple of minutes reading your giant messy block of code before they realize it isn’t the thing they’re looking for. If there are a lot of flytraps in the code, then those five-minute chunks of time can add up quickly, dragging down everyone’s productivity. To help mitigate this, teams devise rules and conventions about how code should be formatted. For an example of this, check out my analysis of the formatting rules used by id Software.

I know I keep bringing this up, but often code formatting arguments happen between programmers working in different disciplines. Different kinds of programming result in very different looking code, and it’s completely reasonable to adopt a coding style that suits the kind of code you’re trying to write. The problem is that once you get used to a particular style, other coding styles will look wrong. So then some ninny decides that there is ONE, AND ONLY ONE correct way to format code, and they venture out into the internet to try and convert the heretics. 

Let’s say you’re processing keyboard input for a shooter. You might have a block of code that looks something like this:

 
if (key == KEYBOARD_W)
 
  player.MoveForward ();
 
if (key == KEYBOARD_S)
 
  player.Backpedal ();
 
if (key == KEYBOARD_A)
 
  player.MoveLeft ();
 
if (key == KEYBOARD_D)
 
  player.MoveRight ();
 
if (key == KEYBOARD_SPACE)
 
  player.Jump ();
 
if (key == KEYBOARD_LCTRL)
 
  player.ToggleCrouch ();
 
if (key == KEYBOARD_LSHIFT)
 
  player.ToggleSprint ();
 
if (key == KEYBOARD_R)
 
  player.Reload ();
 
if (key == KEYBOARD_Q)
 
  player.Melee ();
 
if (key == KEYBOARD_G)
 
  player.ThrowGrenade ();
 
if (key == KEYBOARD_E)
 
  player.Activate ();
 
if (key == KEYBOARD_F)
 
  player.SpecialAbility ();

Pretty standard stuff. This is a very easy bit of code to read, and it packs a lot of easy-to-follow logic into a relatively small space. But then you wind up with some code orthodoxy like:

  • All blocks – including single-lines – must be enclosed in {brackets}.
  • Brackets must be on their own line.
  • There should be a blank line after a closing bracket.

And suddenly that code looks like this:

if (key == KEYBOARD_W)
 
{
 
  player.MoveForward ();
 
}
 
 
 
if (key == KEYBOARD_S)
 
{
 
  player.Backpedal ();
 
}
 
 
 
if (key == KEYBOARD_A)
 
{
 
  player.MoveLeft ();
 
}
 
 
 
if (key == KEYBOARD_D)
 
{
 
  player.MoveRight ();
 
}
 
 
 
if (key == KEYBOARD_SPACE)
 
{
 
  player.Jump ();
 
}
 
 
if (key == KEYBOARD_LCTRL)
 
{
 
  player.ToggleCrouch ();
 
}
 
 
if (key == KEYBOARD_LSHIFT)
 
{
 
  player.ToggleSprint ();
 
}
 
 
if (key == KEYBOARD_R)
 
{
 
  player.Reload ();
 
}
 
 
if (key == KEYBOARD_Q)
 
{
 
  player.Melee ();
 
}
 
 
if (key == KEYBOARD_G)
 
{
 
  player.ThrowGrenade ();
 
}
 
 
if (key == KEYBOARD_E)
 
{
 
  player.Activate ();
 
}
 
 
if (key == KEYBOARD_F)
 
{
 
  player.SpecialAbility ();
 
}

Some people will like this better because it follows the rules set by the rest of the code and their eye twitches when they encounter code that breaks the rules. But note how this takes up more than twice as many lines to accomplish the exact same trivial task. The information density is much lower and it’s harder to find what you’re looking for.

This article would be a chore to read if it was one giant paragraph.

It would also be annoying to read if everything was on its own line.

This would waste a lot of space.

It would make it hard to tell the end of one thought

from the beginning of another.

It would also force you to do a lot of scrolling.

At the other extreme, that sparse bracket style would be really handy in code with complicated nested conditional logic. If the flowchart of the code branches outward like a March Madness tournament bracket and all those branches contain complex algorithms, then you’ll want to adopt a spacious bracket style to put some gaps between the big blocks of math. 

Another argument is over the placement of opening brackets. This code:

if (player.hitpoints < 1)  {
 
  player.Die ();
 
  game.End ();
 
}

Is functionally identical to this:

if (player.hitpoints < 1)  
 
{
 
  player.Die ();
 
  game.End ();
 
} 

Should the opening bracket go on its own line like this? You can make a reasonable case for either one. If this is a trivial bit of code like the one above, then you might want to put the bracket at the end of the if() to save vertical space and keep the information density high. On the other hand, if you’ve got 25 lines of code inside the brackets then maybe it would be wise to give the opening bracket its own line so that it’s easy to make sure the indenting lines up properly.  

This argument over bracket style is just one of many. How do we name functions and variables? Do we create indentations using spaces or tabs? Should comments go in a big block at the top of a function or be scattered around the code?

Like I said earlier, code formatting rules are there to facilitate communication with other programmersIncluding your future self.. It’s easy to lose sight of this and take a orthodoxical approach where nothing is allowed to deviate from the mandated style. But mindlessly formatting code according to THE RULES is like going around pronouncing English words phonetically rather than using the accepted pronunciation. It might give you a warm feeling to keep everything neat and tidy, but you’re pursuing order at the expense of clarity. My formatting rules tend to favor the types of code I usually write, but if I’ve got a random block of one-off code I’m more than happy to break the rules. The is especially true in the case of large blocks of short repetitive lines. (Like the keyboard handling code above.) 

It all depends on what you’re trying to do. Too much whitespace is annoying because the information density is really low. Too little whitespace makes it harder to follow the logic and visualize the flow. If you switch between styles based on code density, then the code can feel like anarchy. 

Again, the code format rules should probably be specific to the kinds of programming problems that your team / company is dealing with. The worst thing is to be dogmatic and obsessive about it rather than tailoring the style to fit the domain.

In any case, code formatting is a really minor item in the list of things that vex programmers. It’s also the one thing that I don’t think a new language can help with. You could certainly make things worse, but I can’t think of any way to make things better. No matter what language you use, you’re still going to have to deal with the trade-off between clarity and information density. I often have a lot of gripes about how code is formattedI HATE when an ultra-spacious style is used on already simple stuff, to the point where a screen full of text will contain less than a dozen lines of actual code that does something. Hates it forever., but all of those gripes are personal, cultural, or domain-based. Say what you want about C++, but it doesn’t presume to dictate how your code should be formatted.

Next week we’re going to talk about something that matters a lot more.

 

Footnotes:

[1] I guess you could hire someone else to do it, but it still needs to be done.

[2] In this case “shopping” might mean buying an SDK, but it could also mean downloading source projects and testing them for suitability. These are different kinds of costs, but they’re both costs.

[3] Rewriting or re-arranging code to keep it organized, even if the underlying logic is sound.

[4] Often into some sort of stark terminal window with scrolling text in a terrible font with colors likely to cause eyestrain, because that looks more interesting for the audience.

[5] Including your future self.

[6] I HATE when an ultra-spacious style is used on already simple stuff, to the point where a screen full of text will contain less than a dozen lines of actual code that does something. Hates it forever.



From The Archives:
 

111 thoughts on “Programming Vexations Part 5: The Vexations Begin

  1. Daimbert says:

    It’s all on the main page again (although someone might post that before I finish posting this comment).

    I don’t care much about whitespace format, but have a practical reason to prefer always putting if blocks in brackets: if I want to add another line into that block, even if just for testing, doing that means that I’m not forced to note and add the brackets around it, since that style only works where the if block is one line long. It also avoids someone adding another line and missing that there aren’t brackets and breaking the code.

    Python enforces indentation by making that how blocks are defined. It’s a little odd at first and can be picky, but after getting used to it it’s kinda nice: the compiler will choke on code that isn’t properly aligned.

    Of course, that’s not always great either, as where I work they added that to their Javascript compilations — including that you have to put a space after an if — and it’s really, really annoying, especially if I just want to add a console log or something to see what’s going on. Of course, this wouldn’t be so bad if the rules weren’t so picky and weren’t about things that don’t make any difference whatsoever. If we were doing code generation I might buy it being that picky, but we aren’t and the rules align with the known pedantic prejudices of the people who came up with it in the first place, so it ends up coming across as their passive aggressive attempts to get everyone to format things the way they want them to.

    Then again, when you DON’T enforce rules then everyone does what they want to — or, today, does whatever their IDE defaults to — and then you have many blocks in the same function using different styles. I don’t care much about that, unless I get dinged for not following the standards while others don’t bother. Don’t demand that I follow the standards unless you’re going to make them clear and get everyone else to follow them (to be fair, at my work the complaints about following the standards happened long ago and now it seems no one cares about them anymore, so it’s not really as unfair and just more puzzling).

    1. GargamelLenoir says:

      In the teams I worked in the brackets even for one line are often mandatory, simply because too many dumb mistakes have been made because of it.

      1. Erik says:

        This. I’ve caught way too many bugs where adding a quick debug log statement to the else clause (or print, or whatever is in that domain) causes the entire logic to change… because there were no brackets, and now the “else” just logs and then *every* pass does what had been the “else” statement.

        Edit: Bah. I’ve marked this as a “code” block, but it still eats the spaces. I’ve replaced the spaces with underscores to show the indenting.

        For example:

        if (dir == left)
        ____goLeft();
        else
        ____goRight();

        gets a log line added:

        if (dir == left)
        ____goLeft();
        else
        ____printf("going right");
        ____goRight();

        will correctly only print “going right” when dir says “right”, but will execute goRight() EVERY TIME. Even though it looks like part of the else case because of indenting, And this is hard to find – the debug log looks correct so you won’t look here, but on left turns it goes left-then-immediately-right and probably goes straight.

        This is why my former company insisted on *always* bracing *every* if/else clause – it saves someone else (usually you) from making a stupid, hard-to-find bug later.

        1. Groboclown says:

          Then came the beauty of Python. Life is better without braces.

          if direction == left:
          ____go_left()
          else:
          ____print(“going right”)
          ____go_right()

          The indentation tells the language what you want.

          1. Abnaxis says:

            It also absolutely requires you to use an IDE because if you ever want to temporarily encase something in a block for testing you need to go through and indent everything by hand Jesus I’m editing in vim over a telnet shell what the hell is wrong with you people that you want to enforce coding conventions in the language!?!?!

            … What?

            1. Majromax says:

              I know you jest, but vim is a very good editor for low-bandwidth terminal connections, and with trivial configuration (mostly setting the indent size) it makes indenting blocks of code semi-automatic.

            2. Lee says:

              Vim isn’t an IDE and can easily indent an entire block without much effort.

              I suppose that’s not your point, but it’s a really bad example.

          2. Moss says:

            Blasphemy! Heresy! Braces were given to us by our gracious God Richard Stallman. How dare you defile his name with your filth?!?!

        2. Jamie Pate says:

          aka `goto fail;`

        3. Olivier FAURE says:

          For the record, gcc now issues a warning when it detects that error.

      2. DerJungerLudendorff says:

        That’s why I always put them in.
        Brackets give my brain a clear start- and endpoint for a particular subsection of code. Otherwise I start getting confused and wondering if this tab space is wrong somehow, and that leads to unnecessary mistakes.

  2. Eichengard says:

    Oh, I get to make the “whole article on the front page” comment!

    I feel like I’ve finally arrived. :)

    EDIT:Damn it! :D

    1. Daimbert says:

      Missed it by THAT much …

      And, sadly, I usually never even NOTICE that it’s all on the same page because I just click on the title as soon as I see it. This time I scrolled down to see if there was another post and so noticed, and wanted to make a comment anyway and so thought I’d toss it in.

      1. Duoae says:

        It’s funny because when I loaded up the main page, the “cut” was already in place and the article had no comments! XD

      2. Eichengard says:

        Exactly what I do, and did, too!

  3. Arkady English says:

    Stringing and tuning your guitar is not playing music.

    Entirely unrelated, but I actually enjoy unstringing, cleaning, and then restringing my guitar. Having said that, it’s a very different satisfaction to the one I get from playing it.

    On topic:

    Someone at work added Clang Tidy to our default compiler install, and enabled it. It is a) a great idea in theory, but b) really vexing in practice. It tends to jump in at times I don’t want it to, to freeze my editor for a couple of seconds, and then put a pop-up box telling me that my half-written code isn’t formatted correctly.

    But I have seen proposals for using that sort of thing at the source-control level. So:

    – I write my code using whatever formatting I see fit, and have some Clang Tidy / autoformatting tool (most IDEs have them by default these days) help me write whatever style I like.

    – When I check in, a step before check-in formats the code to same project-standard that can be anything you like. It could, for all it matters, go and delete every bit on non-required whitespace and put your entire program on one line massive line. It doesn’t matter because no-one will ever read this format because:

    – When I grab a file from the repository, it runs my formatter on it to turn it into the format I like it in.

    This way everyone on the project can format things in their favourite manner, and they get stuff back formatted in their favourite manner.

    I’ve tried suggesting this gets set up at work, but everyone kind of says “that would be nice” but the people who actually have control over our source control software shrug and say “maybe we will someday – but we have more important things to do right now.”

    1. Daimbert says:

      I think this was brought up before in some thread somewhere. There is one issue with this, though: if anyone ever tries to access it outside of an IDE, then they won’t get it in that format, so you’d need to pick a default one anyway. This may not be a big deal for game programming, though, but it is for other applications because if something breaks at a customer site you might want to look at some code but won’t have everything set up to look at it.

      It would also be really, really annoying for me since I refuse to use an IDE, mostly because the popular ones have a tendency to do the things that Clang Tidy does to you: try to format or look up things while I’m typing which breaks my chain of thought.

    2. Viruzzo says:

      That would mess up any decent type of diffing / merging for most VCSs / repository browsers.

    3. Echo Tango says:

      Golang has an auto-formatter built into the official tool-chain, to save people’s time formatting, and save time arguing.

  4. Joshua says:

    Hey, one programming article I can fully understand (as someone who is not a programmer or in an IT field). A dozen years ago or so when I was heavily involved in Neverwinter Nights, I worked with creating my own scripts and got to see these different types of formatting.

    I must confess that my preference was for always having opening and closing brackets indent with each other; ending a line with an opening bracket just makes my teeth grind.

  5. kikito says:

    The argument for “not presuming how code should be formatted” kind of falls apart when the code is being edited in collaboration with other people. Everyone has their own concept about what means “information density”. This leads to inconsistent formatting.

    I’ve struggled with this problem for a lot of time and I have decided that the liberty granted by formatting my own code as I wish does not outweigh the hassle it is to coordinate a team of people so that they format code consistently. The effort of writing, maintaining and re-reading a style guide when you are in doubt, or when you are reviewing one of your peer’s code, is just not worth it.

    I’d rather have A One True Way to format code enforced by software, and not reliant on us fiddly humans. I think Go did the right thing with the gofmt command.

    1. Viruzzo says:

      Asbolutely agreed. Autoformatting is annoying, but other people’s formatting choices are more.

    2. Dreadjaws says:

      It’s almost as if Shamus had made this exact same point in the article:

      Again, the code format rules should probably be specific to the kinds of programming problems that your team / company is dealing with. The worst thing is to be dogmatic and obsessive about it rather than tailoring the style to fit the domain.

      1. kikito says:

        I don’t think that’s the same point, at all.

        Shamus is saying that if you start a team you should write a guide, keep it up to date, and ensure that everyone follows it on every commit. He’s saying “don’t be dogmatic and obsessive, because that way you can tailor the style to fit the domain”.

        I’m saying that when a programming language comes with a “One True Way” for everyone, then you can save that effort. I’m saying “by all means be dogmatic and obsessive, as only machines can be, because the effort required to maintain a style by hand, even if loosely, is not worth the benefit”.

      2. Mistwraithe says:

        Hmmm. I think there *is* good reason to be dogmatic and obsessive about it when you have coding collaboratively.

        If you have a few million lines of code written by a dozen developers then it is far, far better to have rigid formatting rules that everyone is following than letting those dozen developers decide when to bend the rules and use the own formatting they think would be appropriate for the code they are writing.

        As Shamus has said, in a mature project developers spend far more time reading code than writing it. The reading is vastly easier if all the code looks the same rather than being in a dozen different formats.

    3. Noah says:

      It means that Go assumes there is always one answer to Shamus’s tradeoff between information density and clarity. That means that to change that tradeoff you have to change *what* code you write rather than just its spacing, which can be worse.

      1. Chad Miller says:

        I’d be interested to see examples of autoformatters forcing bad code.

        Nearly all code I write is for myself in private projects that only I use and I’ve still been slowly coming around to autoformatting my own code despite the complete lack of a need to standardize my habits with anyone else. Any time I thought “what, why is the autoformatter doing this?” I could find a trivial rewrite that made it look acceptable, OR it turned out there was actually a bug in my code.

    4. Retsam says:

      Yeah, it took me a long time to get on board with autoformatting, but I have in the last year, and I really wouldn’t want to go back.

      I largely objected for cases where the auto-formatter adds more space than needed (like Shamus’s example). Yeah, the button inputs reads a little better in a more dense format, maybe it takes me an extra second to find the line I’m looking for… but those seconds are more than made up for by the time that I don’t spend formatting code myself, or discussing it with team members in code reviews, or reading or writing team style guides.

      The autoformatter saves me time, provides a consistent style across the project, and in 95% of cases produces output that is as good (and frequently better) than what I’d write myself. If the price of that is a few sections of code with unnecessary whitespace, that’s well worth the price to me.

      I do think I still prefer if the autoformatter is its own tool, not baked into the language itself. And I also like that the autoformatter I use has escape hatches where I can use code comments to disable it for certain lines or sections of code, but I could live without those features, too.

    5. Leeward says:

      Seconded. Go convinced me when I gave it a shot, and having an Emacs mode that automatically applies it whenever I save made my life better. This is the thing programming languages can do to solve this problem.

  6. tmtvl says:

    Just hook rustfmt, perltidy,… into your VCS so code gets nicely formatted when it’s committed. Most of them are also easily integrated in your IDE so you can do something like C-x h C-M-\.

    Also, smart tabs FTW. Indentation =/= alignment.

  7. Robert Conley says:

    You know you guys just started using Visual Basic or a Basic Dialect you would have to worry about silly things like the placement of brackets or missing semicolons.
    (ducks)

    This
    if (player.hitpoints < 1) {

    player.Die ();

    game.End ();

    }

    Vs

    If player.hitpoints < 1 Then
    player.Die()
    game.End()
    End If

    1. PeteTimesSix says:

      Those are just brackets wearing a mask. Semicolons, on the other hand, I’ve always felt were kind of redundant in languages that require them; there are some use cases for them, but they come up as rarely as using a semicolon for regular punctuation does. The only one that I make use of myself is something like:

      doAThing(index); doOtherThing(index); index++;
      doAThing(index); doFunnyThing(index); index++;
      doAThing(index); index++;

      Tends to come up when bashing together a basic GUI, for example. Even then, nothing about that forces semicolons to be mandatory everywhere…

      1. Daimbert says:

        The advantage of having a semi-colon — or any explicit line ending that isn’t a newline — is for when you’re writing really long lines of code. You can break them up at appropriate points to make it readable and the compiler doesn’t have to figure out when you’re really ending the line.

        1. Lanthanide says:

          Better to just have a ‘line continuation’ symbol for that rare occurrence rather than to force every line to have a semi colon.

          C bizzarely ends up having both, since macros are assumed to be one line, so you have to put / on the end of each line for a multiline macro.

    2. Bloodsquirrel says:

      This is one of the reasons why Visual Basic makes my eye bleed. Instead of brackets, which are easily parsible as divisions in the code, we have a statement that blends in with all of the other statements.

    3. Matthew Downie says:

      Is the ‘end if’ compulsory?

      One reason putting { } around single lines in C++ became a popular standard is that programmers can introduce bugs by carelessly commenting out a line of code (perhaps indirectly though a #define), and not notice that the preceding ‘if’ statement now refers to some other random bit of code. Or, perhaps confused by indentation, they add a line of code that was supposed to be in the ‘if’ but isn’t.

    4. John says:

      Fortran does something similar with program, subroutine, function, if, and do blocks. Possibly because Fortran is just about as old as Basic. It really is brackets by another name, the distinction being that you can’t confuse an end if for an end do in poorly formatted Fortran the way you can confuse one } for another in poorly formatted C++ or Java.

    5. Leeward says:

      #define BEGIN {
      #define END }

      It’s been done.

  8. GargamelLenoir says:

    Modern IDEs usually have systems to specify a formatting. Eclipse will reformat the code automatically at each save, so nobody in the team will waste time adapting to the standards of whoever wrote on it last.

    1. baud says:

      I don’t think Eclipse reformat after the last save by default. At least it’s not happening on my install of Eclipse at work and I don’t think I would have disabled it. Perhaps it’s version-dependent, I think I’m using last year’s version.

      Personally I prefer to have the two separated, because, once’s a project is old enough, it’s likely there are files that won’t have been formatted according to the current rules and I don’t like the save action changing all the document.

  9. miroz says:

    As mentioned before, this is a job for the development environment and not for individual programmers to discuss and lose time. Ctrl+K, Ctrl+D in Visual Studio will format the current file. It also formats as you type, so after typing ; or } it will format your code. You can customize the exact formatting.

    But of course, somebody didn’t think this through. If everybody customizes their formatting, merging code is impossible. Instead of formatting parameters per instance of Visual Studio, this should be set on the project level. When you check out the project, the development environment should use the parameters specified somewhere in the source controlled text file that lives with the project.

    1. Richard says:

      Recent versions of Visual Studio support “clangformat”, so now you just check in the formatting rules et voila, everybody has the same set of rules and nobody has to think about it ever again.

      It does of course also mean that some teams have blazing rows about what those rules should be…

      Personally: Tabs are evil and egyptian braces look weird, but otherwise I don’t care much.

      And even then, consistency throughout a project is more important than my fragile ego.

  10. Groboclown says:

    My brain started twitching in the big “if” block. Not because of code formatting, but because it should be a “switch” statement to take advantage of table lookup, rather than having to spend a cycle comparing every single item if the person pressed the last key in the list.

    1. Geebs says:

      How would you handle somebody who wants to walk diagonally?

      1. Groboclown says:

        Kids and your “walk diagonally.” Why, in my day, we were lucky to have left and right arrow keys. Only those rich kids had up and down keys.

        Seriously, though, key logic is usually triggered on “key down” or “key up”, which happens in response to a single key. Depending on the requirements, you can have “key left pressed” sets a “left acceleration” value, and “key up pressed” sets a “forward acceleration” value. During the movement phase of logic, that’s turned into how the character moved.

        1. Geebs says:

          I had a bit of a think about it and figured out what my objections should have been (I’d previously had a bad time trying to use switch statements in keyboard handling, but I’d mercifully forgotten most of the details):

          1) Depending on your keyboard type and event handling system, a keypress isn’t guaranteed to generate a single unicode character*, which means you’re going to have to treat keydown and keyup events as strings for reliability. Depending on your flavour of C, you might not be able to perform string comparisons in a switch statement.

          2) I was thinking of the process of working out which keys were currently held down and adjusting the acceleration values (as opposed to raw input handling), which can’t be handled with a switch statement. My mistake.

          For 3D camera work you then have to do a bunch of trigonometry, which (depending on the age of your processor) is potentially going to render any performance gains from using a switch statement insignificant :-P

          (* I learned a bit of Swift during a time when that language’s designers were vacillating back and forth on how to handle string length and position in strings of unicode characters, changing it with each new release. It was horrible)

          1. Shamus says:

            Yeah, my example code is a bit weird because you would never handle keyboard input like this in a real-time game. You might do it using an event-based system as others have suggested. Personally, I have some code dedicated to getting events and storing them as flags. Then in the movement code, instead of:

            if (key == KEYBOARD_W) {
            do_thing();
            }

            You would have:

            if (inputsystem.KeyDown (KEYBOARD_W)) {
            do_thing ();
            }

            But that require some explanation, so I simplified it. In simplifying it, I made example code that could be a switch statement, even though the real system couldn’t.

      2. tmtvl says:

        Just keep adding switch cases until you have every case handled, that’s how you do it right?

      3. John says:

        I recognize that this is probably not a serious question, but the serious answer is event handling. Every time the user presses a key, it triggers a keyboard event and the program calls Shamus’ input-handling block. Pressing two keys simultaneously triggers two keyboard events, so the input-handling block gets called twice. I don’t know precisely what Shamus had in mind, but if it were me then, for example, MoveForward() and MoveRight() would put the player object into the movingForward and movingRight states, respectively. These states need not be mutually exclusive, and thus we obtain diagonal movement.

    2. Paul Spooner says:

      Same. I suspect the intention was to not get side-tracked explaining what a switch statement is.

  11. Joshua says:

    “if (key == KEYBOARD_G)”

    Basic coding question from a complete novice, but why again is there the == for interrogative conditions and = for declarations?
    I.e. ,If (A ==B) vs. sCandy = “Chocolate”;.

    IIRC, you’ll get compiler errors if you accidentally write If (A=B) since it’s not the correct operator, so why is there the double standard that requires two different operators instead of having the compiler determine the context of the “=”?

    1. Daimbert says:

      Actually, it’s only certain languages where that would be a compile error. Early languages, and C certainly, allowed you to do (if A=B) because the assignment would in fact return a value that could be evaluated. In C, you’d end up giving the value that was assigned, and so if it was a number you’d get the number, which evaluates to true. This, then, could allow you to do this:

      // set x to y

      if(x = y)
      // if y > 0
      doSomethingCool()
      else
      doSomethingDifferentButEquallyCool()

      I think it’s bad coding style, but some people like it, and to evaluate on the side effects of assignment is an important part of chaining things together, like x = y = z.

      1. Retsam says:

        It’s not even just an “early languages” thing, really. Python just added support for “assignment which returns the value assigned”. They did it with a separate operator (:=, the “walrus” operator), but it does the same thing as C-style `=`.

        It was really controversial, but there were some cases where people thought it made the code cleaner than without it.

        1. Daimbert says:

          Well, the “early languages” part was that if(x=y) is a valid statement. Certainly some typed languages will complain that you need something that returns a boolean value there, which wouldn’t work for numbers.

      2. Groboclown says:

        There was early research made on the frequency of equality checks vs. assignment, and it was discovered that assignment happened much more often, so it was given the single character (“=”) because it was shorter to type (at least so goes the oral history taught to me; I can’t find any reference to that). However, as Daimbert remarks, it leads to the valid expression:

        if (x = y)

        which has lead to innumerable bugs. Modern compilers can fortunately warn or generate errors on this kind of operation.

        1. Daimbert says:

          Some people, to reduce the bugs, have advocated for doing this when you have actual values:

          if(1 == x)

          Because

          if (1 = x)

          will always fail to compile because you can’t assign to a constant. However, I find that awkward and it annoys me when I see it, so I’m not convinced it’s worth the tradeoff.

          1. Retsam says:

            Ah, good old Yoda conditions.

            Also a fan, I am not. Nowadays, I think that problem is better solved by a static-analysis tool like a linter which will detect these sort of potential problems and complain about them, rather than writing code in a contrived way to avoid a potential typo.

            1. Erik says:

              Yeah, I was taught that format and used it for a long time, but these days I find it confuses people more than it helps – modern IDEs with real-time linters catch that construction and flag it for you. The confusion is now more costly than the number of bugs prevented, and in the last 5 years or so I’ve dropped it for new projects.

              Never heard it called Yoda conditions before – I like that.

          2. Paul Spooner says:

            That’s, probably a great idea? I’ve never thought to do this, but it totally makes sense. Just weird to think about it that way, but the computer doesn’t care. Does it? Does order of comparison matter?

            1. Daimbert says:

              The compiler doesn’t really care, but it’s harder to read. The other way, I can think of the line as “If x is 1”, while this way it would be “If 1 is x”, which doesn’t work as an English statement very well.

              It also doesn’t work as well if you’re going to use the specific equals method, as constants aren’t classes and may not respond to that. Still, that would be caught at compile time.

            2. Leeward says:

              The reason it’s not a good idea (or widely used) is that it’s weird to think about it that way. The computer doesn’t care if you code in bf or whitespace or binary. The reason we use higher level (or non-terrible) languages is so that we humans can understand it.

              If tools can detect the common error case (and they can) and we have more trouble thinking about comparison with the variable second and the constant first (we do) then we shouldn’t use Yoda expressions.

            3. Chad Miller says:

              Strictly speaking it can matter in a language that lets you overload ==. I can’t think of a good reason to do that, but you could.

    2. tmtvl says:

      Well, in a REAL programming language you’d do it like thus:

      (define candy “chocolate”)
      (cond ((= candy “chocolate”) eat)
      (else throw-away))

      Much more readable, I think you’ll agree.

      1. Erik says:

        Nah, I find

        if {$candy eq "Chocolate"} {eat $candy} else {throwAway $candy}

        far more readable. :)

        1. Default_ex says:

          What about mixed candy.

          if ((myCandy & Candy.Choclate) == Candy. Chocolate) { Eat(myCandy); } else { Dispose(myCandy); }

      2. Leeward says:

        The thing I miss the most in languages that aren’t Lisp or its children is separating words with `-`. The key’s right there, and so easy to press. No shift or anything.

        1. tmtvl says:

          Perl 6 has kebab-case, then again it has incorporated nearly every nicety any other programming language has and a whole boatload more.

    3. Xeorm says:

      It doesn’t always throw compiler errors as noted above, and it helps to keep things consistent. Reading this aloud:
      x=y means “X is y” or “Put y into x” etc.
      x==y means “x equals y” or “x is the same as y”

      They’re two similar, but different sentences, and so it helps that they have different markings. It also lets you do odd things like:
      x = x==y;
      as a valid line of code.

    4. John says:

      In Java, and presumably other languages, “=” is an assignment operator. If I write “x = y”, then I am giving the variable x the value y. By contrast, “==” is a logical (or relational) operator. If I write “x == y”, I am asking the program to determine whether or not the value x is equal to the value y and the computer will return a value of either true or false. Other languages, like Fortran, sometimes use a single equals sign for both the assignment and logical operators. The compiler determines what you meant from context. A Fortran compiler would interpret a single line containing “x = y” (and nothing else) as an assignment statement. However, in the line “if (x = y) then call some_subroutine(k)” the compiler interprets “x = y” as a logical operation, because it knows to expect logical values in the parentheses.

  12. Agammamon says:

    Should the opening bracket go on its own line like this?

    I’ve always hated both of those examples.

    If you’re going to use brackets, for god’s sake, put them on the same lines as the blocks they enclose.

    if (player.hitpoints < 1)

    { player.Die ();

    game.End (); }

    1. Retsam says:

      I don’t think I’ve ever seen this style. I’ve never seen a style where the statements don’t line up. The closest I can find is Pico Style: (Or maybe that’s your intention, just formatting issues in the comment)


      if (player.hitpoints < 1)
      { player.Die ();
        game.End (); }

      If nothing else, I wouldn’t like that style because it would mess up code diffs too much. If I wanted to add a line at the beginning of the block, I’d get a three line diff:


      if (player.hitpoints < 1)
      - { player.Die ();
      + { player.lastWords();
      + player.Die();
        game.End (); }

      Instead of just a single line diff from basically any other style:


      if (player.hitpoints < 1) {
      +   player.lastWords();
          player.Die();
          player.End();
      }

      1. Agammamon says:

        I don’t know why though. Its how we use braces in writing. And there’s a good reason. In my example its pretty easy to see (at least in that block size), by scanning the left side, where that block begins and where it ends.

        With both braces on their own lines its in a kind of similar place – but, IMO, still harder to parse individual blocks.

        With the open brace at the end of the first line – its just a bitch to scan through blocks because there’s no easy way to see when a block starts as the open brace will be at the end of the previous line, in a different place on the screen every time – and sometimes off screen if the line is long enough.

        But I admit that I am not a coder, just someone who goes through code sometimes to modify it for game mods.

        1. Daimbert says:

          To be honest, I think the fact that it’s how we normally use braces IS the reason we don’t do it that way: braces in this case aren’t supposed to be braces, but are instead us using braces to indicate something specific to the language and compiler, like BEGIN and END would be. If we treat them as braces, then at a glace we’d start looking at them as braces but that’s not what they’re actually doing, so we’d end up with leftover semantic interpretations confusing us.

    2. Leeward says:

      This seems like a variant of an old joke about religious wars. The two sides can at least agree that this is just wrong. It’s like the GNU curly brace style: on a line by itself _AND_ indented half way between the outer and inner blocks.

      Anyway, your coding style is objectively wrong and you’re probably a bad person because of it.

  13. Timothy Coish says:

    “In any case, code formatting is a really minor item in the list of things that vex programmers. It’s also the one thing that I don’t think a new language can help with. You could certainly make things worse, but I can’t think of any way to make things better.”

    Well this mostly falls under syntax, which Blow has stated is subject to change even at this late hour. However, I do completely understand the irritation he gets with C++ when you change some thing from pointer to value or vice versa. Having to find every little thing->x and change that to thing.x is super irritating, and find replace is dangerous. Also, that C++ has std::unique_ptr steveTheUniquePointer = make_unique(constructorOfStructType(args)), and a bajillion little irritations when it comes time to actually code things. In contrast, making a unique pointer in Jai is done with !, a single exclamation mark.

    But syntax is relatively unimportant. More important to joy of programming is not having to wait a billion years for a compile, or not having to write and refactor header files.

    1. Groboclown says:

      This is exactly the kind of thing that makes me hesitant to dive into a C or C++ project. Did this bit of memory get copied into the function, or passed as a pointer? Who owns this memory now?

      C had some standards around this – the caller creates the memory, and you never create memory and return it unless it’s highly unusual and extremely well documented, such as with Corba server calls. I’m sure if I spent some time inside C++ again I’d figure it out, but if Jai adds in very simple, strict syntax to indicate passing ownership of pointers and not hide memory allocation, that would go a long way towards reducing another big source of bugs.

      1. Richard says:

        Nope, C doesn’t have any standards about who owns memory. Not a sausage.

        You’re describing a team, project or API convention, created entirely because the C langauge had nothing to say about it.

        Many real C libraries have a huge amount of “library function allocates the memory, does the thing and return it. Caller takes ownership and must call library’s destroy() later”.

        However operating system APIs are almost always “caller allocates”, because a lot of them are actually copying data from ‘protected mode’ memory into ‘user mode’ memory, and the caller also generally has a far better idea about where it should be stored (stack, heap, other heap, re-using existing allocations) so it’s bost best and easiest to require the caller to allocate throughout.

        Modern C++ has explicit ownership syntax – “move”, “copy” – and you can even easily specify that a class simply cannot ever be copied and can only be passed as a reference or explicitly moved.
        (But you can still be vague if you wish…)

      2. Mephane says:

        This is exactly the kind of thing that makes me hesitant to dive into a C or C++ project. Did this bit of memory get copied into the function, or passed as a pointer? Who owns this memory now?

        It’s a central feature of the language that the programmer can decide who owns a piece of memory, and there are valid cases for both, caller and callee. There are clear constructs for each case, however, problems only arise here when code is ambiguous and badly documented, or deliberately written to be malicious*.

        I know a lot of code is not written like that, especially due to how many libraries aim for being C and C++ compatible simultaneously (le sigh), but if you write for C++ only there’s essentially 4 cases:

        1. Call by value:
        void f(int x);
        Generate a copy of x in memory on the stack (i.e. you don’t manually manage that at all). Simple and easy, for primitive types this is usually the best option, because copying an int does not cost more than passing a point or reference to it.

        2. Call by reference:
        void f(int& x);
        No copy is made, and f is able to modify the value of x, but does not take ownership of its memory.

        3. Call by const reference:
        void f(const int& x);
        Same as point 2, except f is not able to modify the value of x. This is the most common option when you would like to pass by value but avoid the cost of a copy of a more complex type (e.g. std::string).

        4. Hand ownership over to the callee:
        void f(std::unique_ptr<int> x);
        While this is not the only way to do it, it is imo the best one because it is unambiguous without the need for any documentation about the internals of the function, and correct handling is enforced at compile time. New code that does not need to be C compatible should always use this instead of raw pointers.

        ————————————–
        *In C++, as soon as you have a pointer or a reference to something, you can technically do anything with it. You can brute force a const reference into a non-const pointer and then delete it, for example, but you’ll most likely make the program crash mere moments later when the actual owner of the data would attempt to delete it, too.

  14. baud says:

    I don’t see formatting as a big annoyance. All the team is using the same IDE for writing the code, everyone has received the template file, so properly formatted code (following the rules), is just one shortcut away. I don’t think we’ve ever discussed formatting for the 2.5 years I’ve been on the project.

    1. Paul Spooner says:

      Templates and examples are my preference for formatting standards. Having to compile the procedural code standards into implementation every time I want to write code just sounds annoying.

      1. Richard says:

        I don’t like examples as such.

        Best to specify “we use this formatting tool, this is the formatting rules file”.

        Pretty much all IDEs have a shortcut/button for “format whole file using the specified tool and ruleset”, and every source control system has ‘pre-commit’ hooks that can be used to apply the rules before each commit, thus ensuring diffs never show formatting changes*.

        (*Unless you are changing the formatting ruleset)

      2. Echo Tango says:

        Your examples would be the other existing code that you’re adding to, since it’s all been through the same auto-formatter.

    2. Daimbert says:

      I’ve never worked on a project where the entire team was using the same IDE for writing the code …

  15. J Greely says:

    Long ago and far away, our department at the university acquired a new programmer as part of a faculty hiring agreement (“give $spouse a job, too”). The only project we had to give to $spouse was one that several folks had built in their free time, a server and set of clients designed to allow anyone to read nicely-formatted manuals from their preferred window system, with automatic hyperlinks between documents. (yes, we were intensely jealous when the Web finally came along and did all that and more)

    $spouse spent months cheerfully plugging away, until someone noticed that the various clients all had slightly different behaviors, and in fact pretty much everything was at least a little broken. The two senior people in the group asked $spouse to give them a copy of the current source code so they could review it.

    They walked into their cubes to find several reams of paper, consisting of complete printouts of the source for the server and every client. Not quite what they’d had in mind, but they dug in and started taking notes.

    I showed up a few hours later, and found them dazed and confused. Steve’s face lit up when he saw me, and he cried, “J, you were looking at the Waiter server recently, right? What does this section DO?!?”.

    I recognized it immediately, having bloodied my knuckles on it a few weeks earlier. “Nothing, it’s dead code. I think it was supposed to be a string search implemented without using any library calls, but it would never have worked, and none of the valid commands calls it.”

    $spouse was gently encouraged to accept a programming position in the AI lab, where they later discovered that the code required to keep one of their major funding grants was half-finished and all-wrong…

    -j

  16. Steve C says:

    As a non-programmer, I’ve always been surprised that programmers don’t use tools to change how the code is presented to them. IE use a quick view button to invert or simplify or condense between various styles without changing the underlining code. Like I can view this web page normally, or using different customized options. Neither changes the underlying source code. I can also view the source code using various methods, also all with customized options.

    There could be a hotkey to swap between a tight, condensed version with little whitespace. And another mode that shows it in March Madness tournament bracket style. Sure, the bottom layer has to be the same format. But that could even be two accepted formats if the project design decided it to be so. It is all fiat decisions after all. As it is a fiat, I’ve never understood why there wouldn’t be a style for ‘trivial’ code and another for ‘complex’ code within a single project.

    I have to deal with two official languages all the time. English and French. It’s not a big deal. I use one and ignore the other. I can read and speak in the other enough to make do. I don’t because it is not my preference. You see this a lot in legal documents too. Where there will be a boiler plate for laymen with a sentence or two that says “You can do stuff with our IP as long as you do it without earning money.” Then it uses 2 pages of legalize to say the exact same thing in exacting detail. And then it does the exact same thing in French. This is more difficult to with real languages as it really does need to be done twice. In code, you’d only have to do it once and cycle through various automated outputs to the screen based on the preference of the human coder.

    1. PeteTimesSix says:

      I dunno about other programmers, but I generally prefer to see what my source actually looks like. Text helpfully pretending to be something other than what it actually is generally backfires sooner or later (most recent case I can think of is a python script I edided a single line of in notepad++ instead of vscode which then refused to compile because the intendation on that line now used spaces instead of tabs despite looking exactly the same and despite me not actully changing the intendation…). You’d have to write things in complex mode anyway, and then there’s the question of what happens during debugging/which line number should a crash report send you to…
      Besides, every decent IDE Ive ever used supports folding code sections (either programmer-defined or automatic via brackets/intendation levels) which takes care of 95% of bracket-induced madness anyway.

      1. Steve C says:

        That seems like a problem of implementation, not of conception. It’s also clear nothing like that should ever happen in notepad++ regardless. Whitespace should be whitespace. To have the compiler choke on whitespace seems crazy to me. Same thing with displaying the line number. The line number is the line number. It isn’t changing.

        1. Echo Tango says:

          Didn’t you suggest changing the bracket style? That would change the line numbers.

          1. Steve C says:

            No I did not. Not all. The entire point would be that nothing is ever changed. It is just re-skinned based on user preference. I don’t think I’m being understood. Retsam does get what I’m saying though. Have a look at his reply. An easy configurable option the number of spaces a tab is equal to as displayed on screen. Two programmers with different personalized settings for tab will see two different things. That core concept can be expanded on. Again, Retsam gives a good example with Hello World and java.

            Presumably different people programmed the software known as notepad++ than say vscode. If another similar software suite of that vein was created, it could have drop down menus that make the exact same code display differently on screen using a single program. Just like how notepad++ and vscode load the same code and display it differently. Except that now it is the same program made by the same people and really really does for-reals treat the code the same way no matter how a user views it or alters it.

    2. Echo Tango says:

      If computer code has a single character out of place, it can produce a bug. Changing how the code looks could obfuscate that bug, making fixing the software more difficult, and debugging is already more difficult than writing code in the first place.

      1. Steve C says:

        Ok. I get that. That fact isn’t really relevant to what I’m saying. In fact it would be the opposite.
        In many cases it would be easier to find bugs. Because if a single character is out of place, swapping between views can make it pop out more. It might look totally normal and be obfuscated by one view. Then switching to another view drastically changes how it functionally looks to a human. Because it is a bug. It *is* functionally different than what it should be. That’s the problem. It is actually exactly the same in both views. It only appears to be right in one view… because it is bug.

        Something that is wrong (a bug) has the potential to look even more wrong to a human.

        1. Echo Tango says:

          I think your wrong here; Swapping large sections of code wholesale is going to hide small differences, not enhance them. When hundreds of characters are all jumping around, one character isn’t going to get noticed.

          As an exercise, take some paragraph of text, and get a friend to make a typo when you’re not looking. Open it in two different windows, and make sure word-wrap is turned on. Then shrink on of the windows so that the words get moved around to fit the smaller window. Now alt-tab between those two views quickly.

          1. Steve C says:

            I write messages in the white box for the comments here on this blog. I proofread them before posting them and correct any errors. After I post, I reread the post. Most of the time (like 80%+) I find an error and have to edit the post. (Including this one.) It is the same thing with printed documents. It is easier to find errors. It is an established physiological response; Reviewing work done in a different format than it was created can cause your brain to be more alert to errors.

            I also especially disagree when it comes to code. A single character that is wrong has a very good chance to throw up obvious visual errors when it shifts format. Highlighting could be different. Branches could be different. Which part of the interface that part of the code is sorted into could be different.

            Plus this would be an optional feature. Someone who chooses not to use it is literally losing nothing. Which I find very odd to argue against.

    3. Retsam says:

      There are examples of this. One reason that some advocate for tabs in “tabs vs. spaces” war is that a text editor can be configured to represent tab characters with varying numbers of spaces – some people like 2 space tabs, others like 4, but the code is the same either way.

      And I know a lot of Java IDEs will abstract certain patterns to simpler representations; mostly to let the language pretend to have clean syntax for “lambda functions”. IntelliJ will display something like:


      () -> { System.out.println("Hello World"); }

      when the real underlying code is:


      new Runnable() {
        @Override
        public void run() {
          System.out.println("Hello World");
        }

      (And folding brackets, which PeteTimesSix mentioned, are a minor example, too)

      But that really only works for simple things. For the idea of “dense” vs “sparse” whitespace style, see the discussion above for autoformatters: you’d have to essentially write two autoformatters, one for each style and constantly have your IDE translating between the two styles, and/or find a way to mark which sections of the code should use one style or the other.

      It’s a lot of complexity and effort compared to either: just having a single autoformatter that formats everything into a single consistent style, or just letting people format stuff as they think is best for each section of the code.

      1. John says:

        Huh. I haven’t used IntelliJ as much as I’ve used NetBeans (and I haven’t used either anywhere near as much as I’ve used Geany) but I’ve never seen it do anything like that. To be fair, I don’t think I’ve ever tried to implement a Runnable interace in IntelliJ. I mostly used IntelliJ for game prototypes with libGDX and libGDX handled the Runnable stuff for me. Can you think of any other examples?

        1. Retsam says:

          IntelliJ calls this code folding. As far as I can tell, lambda expressions are the main case where they actually replace the folded code with a summary. (And apparently the newer versions of Java actually added proper lambda syntax, so this isn’t necessary anymore)

  17. methermeneus says:

    But mindlessly formatting code according to THE RULES is like going around pronouncing English words phonetically rather than using the accepted pronunciation. It might give you a warm feeling to keep everything neat and tidy, but you’re pursuing order at the expense of clarity.

    *cough*Rust*cough*

  18. Mark says:

    Speaking of code formatting, what kind of monster would put a space between the function name and the opening parenthesis?????

    1. tmtvl says:

      When defining that’s fine. When calling it’s terrible.

  19. Piflik says:

    While I agree that most formatting rule can be argued for and against, anyone using spaces for indentation is wrong and a bad person.

    1. John says:

      Hm. Let’s say I want to declare and initialize a two-dimensional array in Java, something like:


      String[][] zeppelin = {{"Robert",Plant"},{"Jimmy","Page"},{"John Paul","Jones"},{"John","Bonham"}};

      I do this sort of thing all the time, although generally not with those values. If the array is big enough, or, say, the strings the array is storing are long enough, then the line can very easily extend beyond the edge of my monitor. I don’t like when that happens. The natural solution is to go to a new line after every inner array so that to the right of the equals sign I have something like


      {{"Robert",Plant"},
      {"Jimmy","Page"},
      {"John Paul","Jones"},
      {"John","Bonham"}};

      with the inner arrays stacked one on top the other. (I apologize for the formatting. I don’t know how fully reproduce the effect I want in html.) To make the second, third, and fourth inner arrays line up the way I want I can use either spaces or some combination of tabs and spaces but I cannot use tabs alone, not in any editor I’ve ever tried.

      I leave it to you, o Virtuous Apostle of the Tabs, to show me The Way.

      1. tmtvl says:

        That’s alignment, not indentation. Those are different concepts.
        (indentation)var x(alignment)= 2;
        (indentation)var aLongName = 1;

  20. Decius says:

    The compiler doesn’t care about whitespace.

    Why does the code repository care about whitespace?

    Surely the indentation type can and should be set by the individual currently looking at the code through the program they are using to look at the code, rather than by the person who last edited the code.

    1. Shamus says:

      Serious, non-flippant answer: Because humans care about whitespace. Two things come to mind. This code…

      int mHitpoints;
      float mDistance_traveled;
      int mNumBullets;
      int mExperiencePoints;
      int mGrenades;
      int mKills;
      string mName;

      …is pretty standard as part of a class definition. I’ve seen a lot of projects where you were supposed to line up all the variable names on the right. While DOING that is super-annoying* I can see a little bit of utility in it. The two-column look is rather distinctive and it helps you parse the code quickly.

      The other thing is when formatting is used inside of comments, particularly when a diagram is needed for an easy-to-misunderstand idea that needs to be conveyed visually.

      	/*       p1 *--------* p2  top_edge
      	 *          |        |  
      	 *          |        |
      	 *       p3 *--------* p4  bottom_edge
      	 *                                                           */
      

      I’ve done this a lot in my projects, and it’s saved me from a lot of hassle.

      But both of these things require that the repository respect whitepsace.

      * Oops, I added a new variable type that’s really long, so now I need to insert another tab in front of EVERY variable to move the right column over.

      1. Liam says:

        Shamus said

        now I need to insert another tab in front of EVERY variable

        Relatively straightforward with Alt-select, which visual studio, MS office and lots of text editors support

        But yes, I get your point.

        1. Shamus says:

          I…

          I did not know about alt-select.

          WHY DID NOBODY TELL ME ABOUT ALT-SELECT!?!?

          I’ve been using Visual Studio in one form or another since 1994. I wonder when this feature was added?

          1. pseudonym says:

            Sometimes editors provide cheat sheets, or at least a “hotkeys” settings page. Reading through them is very boring, but there are almost always a few hidden gems in there that are worth it.
            Reading them yearly is quite a good practice, also because a workflow is an evolving thing.

            But like all things that should be done at long time period intervals, I usually postpone it or forget about it.

            What also helps is sticking the cheat sheet in your toilet. ;-)

            For the linux terminal users out there, there are some gems here: https://www.howtogeek.com/howto/ubuntu/keyboard-shortcuts-for-bash-command-shell-for-ubuntu-debian-suse-redhat-linux-etc/

          2. emptyother says:

            At least since 2014:
            https://blogs.msdn.microsoft.com/mschray/2014/09/03/multi-cursor-in-visual-studio/

            Inspired by their new vscode editor, a late update for VS2017 gave us ctrl+alt+leftclick for multi-caret editing. Check under “Edit > Multiple Carets” for a few other usefuls (the menu changes content based on your selection and carets, btw.. Ugh.).

          3. Liam says:

            I’m pleased to have shown you something new!

            Now, if I can do that another 2 to 3 thousand more times, we’ll be even!

  21. Pinkhair says:

    What about having it all on a single line?
    if (key == KEYBOARD_W){player.MoveForward ();}

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 Chad Miller Cancel reply

Your email address will not be published.