Search code examples
language-designsyntactic-sugar

Why is Syntactic Sugar sometimes considered a bad thing?


Syntactic sugar, IMHO, generally makes programs much more readable and easier to understand than coding from a very minimalistic set of primitives. I don't really see a downside to good, well thought out syntactic sugar. Why do some people basically think that syntactic sugar is at best superfluous and at worst something to be avoided?

Edit: I didn't want to name names, but since people asked, it seems like most C++ and Java programmers, for example, frankly don't care about their language's utter lack of syntactic sugar. In a lot of cases, it's not necessarily that they just like other parts of the language enough to make the lack of sugar worth the tradeoff, it's that they really don't care. Also, Lisp programmers seem almost proud of their language's strange notation (I won't call it syntax because it technically isn't), though in this case, it's more understandable because it allows Lisp's metaprogramming facilities to be as powerful as they are.


Solution

  • Syntactic sugar can in some cases interact in unpleasant ways.

    some specific examples:

    The first is c# (or java) specific, Auto boxing and the lock/synchronized construct

    private int i;
    private object o = new object();
    
    private void SomethingNeedingLocking(bool b)
    {
        object lk = b ? i : o;
        lock (lk) { /* do something */ }
    }
    

    In this example the helpful lock construct which can use any object as a synchronization point, combined with autoboxing, leads to a possible bug. The lock is simply taken on a new boxed instance of the i each time. It is arguable that the lock construct is over helpful and that some other specific construct on which to lock would be better but certainly the combination is still flawed.

    Multiple variable declaration and pointers:

    long* first, second;
    

    A classic bug (though easy to spot). The sugar of multiple variables won't fit with the pointer declaration.

    Some constructs do not need other aspects of the sugar to cause issues, a classic example is the ++ operator. It neatly lets you avoid writing

    i = i + 1;
    

    A widely used construct (and one which itself has scope for bugs since you must remember to update both variables if you wish to change from using i). However since this is easy to embed within other expressions the issue of prefix and postfix rears its head. When used within a for loop this doesn't matter, the evaluation happens outside of any other evaluations, but used elsewhere it can be a source of confusion (since you may be embedding a very important aspect of the calculation (whether the current or next value should be used) into a very small and easily missed form.

    All the above (except perhaps the lock/box one which the compiler really should spot for you) are cases where the usage may well be fine, or experienced programmers may think "that's perfectly clear to me" but the scope for confusion exists, certainly for novice programmers or those moving to a different syntax.