Wednesday, April 6, 2011

Is coding style mostly for readability or are there other factors?

I remember reading in Douglas Crockford's "Javascript the Good Parts" book that there is potential for error with blockless statements because of automatic semicolon insertion.

if (condition)
   foo = true;

vs

if (condition) 
{
   foo = true;
}

In the second the example it will work consistently, in the first example a semicolon will be automatically inserted by the interpreter and can lead to ambiguity in the code. As Douglas points out this is potentially bad and hard to debug, which I agree. But it got me thinking are there examples where coding "style" actually has syntax implications? In other words, examples where failing to follow a certain indentation or apparent style actually results in a bug or error. I suppose Python with its significant whitespace is an example, YML with its requirement for no tabs is another.

Feel free to respond in a wide variety of languages and idioms. I am curious to hear about the paradigm cases. In your answer I would like to know the WHAT and the WHY of the coding style or syntax behavior. I don't want to start any coding style flame wars, just matter of fact scenarios where the uninitiated would get tripped up.

From stackoverflow
  • In Python, the whitespace indentation, rather than curly braces or keywords, delimits the statement blocks. An increase in indentation comes after certain statements; a decrease in indentation signifies the end of the current block.

  • Javascript treats these two cases seperately. You have to use the first

    return {
       // code
    }
    
    return 
    {
       // code
    }
    

    If you do not the interpreter adds semi colons in the wrong places. I think it puts one after the condition. So the second would be read wrongly as.

    return;
    {
       // code
    }
    

    Which is not invalid syntax.

    Gordon Potter : Ah that's it! Now I remember reading this in Douglas Crockford's Javascript the Good Parts book. The issue with the automatic semi colons. One of the "evil" features of Javascript. Thanks!
    belugabob : I was surprised to read this answer, as I'd never come across the problem myself. I was even more surprised by the comment about the Crockford book, as I've just read it and couldn't remember this nugget of info. Couldn't find it by looking quickly through the book, so I modified some code to see for myself, and the behaviour you describe didn't take place. Am I reading this correctly - are you saying that the second way of doing things will cause the code inside the braces to always be executed? You're not confusing this with the 'Block-less statements' on pg 113, are you?
    belugabob : Ah! - now that you've edited it to use 'return' instead of 'if...', it makes more sense. Having said that, why on earth would you use that syntax in the first place - it's horrible (Both versions)
    Andreas Grech : @belugabob, refer to Crockford's book pg.102 "Semicolon Insertion"
    David Raznick : To be honest, I agree, its ugly both ways. I just thought it was the example that Gordon was after.
    belugabob : David, thanks for the page reference, now I know why I didn't remember it - I must have decided that I'd never use that construct anyway, and that remembering that rule was a waste of memory space. ;-)
    Gordon Potter : Yeah, what is the point of the brackets after the return? It is an odd construction. Does this mean you are returning some anonymous object instead of say a single value, or variable? Does seem like a goofy construction. Perhaps this has a use when returning JSON key/value stores. But it seems more clear to name your objects in a variable and return the variable.
    belugabob : Totally. By the way '{}' are braces, '()' are parentheses and '[]' are brackets. Some people refer to them as different types of brackets, but the naming convention that I gave is more common and less confusing.
  • Whitespace is not significant in any of the C family of languages, except to separate certain language tokens. The layout of the source code has no effect on the executable produced by the compiler.

  • It depends on the language. In the curly family C/C++/Java/C#, whitespace is not the restriction as long as your braces are opened and closed properly.

    In languages like VB where paired keywords are used, just because keywords delimit functions you can't have

    Private Sub someFunction() End Sub
    

    But in C, C++ and other curly languages, you can have

    void someFunction() { }
    

    In python, I guess its a completely different matter.

    It all depends on the particular language. As per your specific example, I don't think there is a syntactical or semantic difference between the two.

  • In C++, there's a difference between

    vector<pair<int,int>>
    

    and

    vector<pair<int,int> >
    

    because >> is treated as a single token by the parser.

    anon : YThe difference being the first won't compile with some older compilers. This is fixed in the future standard. The meaning of the construct and the code the compiler generates for it will be the same in both cases.
  • A coding style is not only for readability. There are some other factors like

    • Avoid common language pitfalls (silent fails, exceptions while casting etc.)
    • Ease of maintenance
    • Increase the clarity of code (e.g. private functions always starting loweCase and public beeing PascalCase)
    • Enforcing conventions (e.g. not using multiple inheritance or always inherit public in c++)

    an example for ease of maintenacne is below:

    if(x) return true;
    

    vs.

    if(x) 
    {
       return true;
    }
    

    it is clear the second is easier to maintain, because i can simply go ahead and add a new line and add a call to bla() without having to add brackets before.

  • It is language dependant. For instance in Java

    void someFunction() { }
    

    and

    void someFunction() { 
    }
    

    and

    void someFunction() 
    { 
    }
    

    will have no implication whatsoever. However Sun has enlisted a list of coding conventions if you are interested you could read them here.

    These are mainly for maintainability and readability of code but need not be strictly followed.

    Kevin Boyd : oops the braces have not shown up correctly. in my post I will try to repost later as I'm a bit caught up now.
  • No one has mentioned it before, but one point of style is to write

    if (NULL==p) // ...

    instead of

    if (p==NULL) // ...

    The two are functionally equivalent so it's a matter of style. Many prefer the style at the top, because if you type "=" by mistake instead of "==", the first won't compile whereas the second will, and creates a bug that is hard to find (though some compilers now give you a warning for if (p=NULL)).

    Gordon Potter : Ah, that would be truly evil if you were having a bad day before a deadline. Good point, and nice explanation. Thanks!
    Colin Mackay : It depends on the compiler. The C# compiler demands that the condition evaluate to a Boolean. Accidentally putting if (p=null) won't evaluate to a Boolean so the compiler will reject it. Also, many other compilers that allow non-Boolean expressions to be interpreted in conditionals will warn when an assignment is present.
  • Every time I open a parentheses, brace, single or double quote I always close it and then go back to write the statement, condition, etc... This saves me from quite some possibly big mistakes!

    belugabob : I've noticed other people doing this, as I watched them type - now I know why they do it. Personally, I prefer an editor which does this for me - maybe I've just been spoiled by year of using IntelliJ?
    Alix Axel : Old habits die hard! =)
  • The title wasn't specific to conditional blocks, so this came to mind:

    I don't see it mentioned yet, but one thing to consider is how do you find things with simple tools (like grep and its inferior implementations from windowsland).

    For example consider this (admittedly a bit contrived) example

    class Foo
    // vs.
    class
    Foo
    

    You can find former with regex "class\s+Foo", but for latter you'll have to have a specialized tool that can parse C++/C#/java.

    This applies also in C for function prototypes, some weird people prefer

    void
    bar (void)
    // to 
    void bar(void)
    

    While you can generally assume that if in front of function name are some A-Z characters, then it's very likely definiton/declaration.

    Actually when it comes to ifblocks, then placing the brace has very big impact on debugging code in Visual Studio 200x. When it steps into function/block, it will place text/execution line cursor on opening bracket. So if the bracket happens to be waaaaay on the right side, the code window has to scroll there and buggeritall stays there. Extremely annoying.

    xcramps : It's not weird. Its easier to find the function definition in example #1, using grep, for example. These choices were not made unintentionally.

0 comments:

Post a Comment