26
votes

No matter how much you love a programming language, there are always a few details in it that aren’t quite as nice as they could be.

In this question, I would like to specifically focus on syntax elements. In a programming language that you use frequently (perhaps your favourite programming language, or perhaps the one you are forced to use at work), which syntax element do you find most unreadable, unclear, inconvenient or unpleasant?

6
  • @Nathan Taylor, not for this question, but for another question.
    – finnw
    Sep 11, 2010 at 23:49
  • Did this question get modified? Because when I answered, it wasnt focused on "syntax elements"... I will have to modify my answer now. Sep 20, 2010 at 0:08
  • @Talvi: No, it was about syntax right from the start.
    – Timwi
    Sep 20, 2010 at 11:35
  • @Timwi weird, it must be a case of 'answering a question thinking it was a different one' then. Sep 21, 2010 at 11:27
  • If you can vote and think this is a useful question or it have useful answers below, please vote up. StackExchange sites need votes to build a good community. You can give 30 votes per day, don't waste them. Specially users with high reputation and low counting votes given please read this: meta.programmers.stackexchange.com/questions/393/…
    – Maniero
    Oct 5, 2010 at 19:30

36 Answers 36

39
votes

Semicolon insertion in JavaScript.

I haven't really been bitten by it often, but it's just such a phenomenally bad idea it makes my head spin.


Here's the rules (from ECMA-262 Section 7.9)

  1. When the program contains a token that is not allowed by the formal grammar, then a semicolon is inserted if (a) there is a line break at that point, or (b) the unexpected token was a closing brace.
  2. When the end of a file is reached, if the program cannot be parsed otherwise, then a semicolon is inserted.
  3. When a "restricted production" is encountered and contains a line terminator in a place where the grammar contains the annotation "[no LineTerminator here]", then a semicolon is inserted.

Example:

return 1; // returns 1

return
1; // returns undefined
8
  • 2
    JavaScript:The World's Most Misunderstood Programming Language ~Douglas Crockford
    – pramodc84
    Sep 9, 2010 at 4:20
  • Yes, many expect JavaScript to be a "free-form language", but it isn't. Sep 13, 2010 at 15:23
  • 13
    It makes sense once you realize that JavaScript was designed for creating HTML, which also has a long history of trying to interpret what your code "really means" when it isn't syntactically valid. (Look up the Robustness Principle sometime--the biggest disaster in the history of computing.) Sep 17, 2010 at 18:18
  • 7
    These types of errors, to me are a code-smell that the programmer is sloppy and has never worked with most formal "strict" languages that would normally cause a syntax error for leaving the semi-colon out. Sep 20, 2010 at 0:06
  • 7
    Wohoo, finally someone else who also thinks Robustness Principle is a disaster that has made HTML the utter mess that it is. Nov 21, 2010 at 10:10
39
votes

Java-bean syntax due to lack of C# properties

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}

GAH!!!

Issues I have with this

  • Too much code - Have a field that's documented, a getter method that's documented, and a setter method that's documented. This extremely basic example has 20 lines of code for a single property
  • Clutters method lists - "Let me find that method, hand on: getX, getY, getZ, getAnotherAnnoyingField, getWhyIHateJavaBeans, getThisIsVerbose, getGAH... ah there it is, hashCode.
  • Multiple area's of documentation lead to poor, outdated, or missing documentation - Annoying when trying to understand what code does
  • So annoying a 3rd party had to come up with a plugin to do this easily - Spoon, Shark, among others.
17
  • 9
    Once again when code is so verbose that it needs auto generating tools, something is wrong. I'm a NetBeans guy, but it also has the ability to auto generate getters and setters. But Javadoc falls out of syn, it's still verbose, it still clutters javadoc, etc
    – TheLQ
    Sep 4, 2010 at 19:13
  • 11
    If you need getters for everything then something is wrong with the client code.
    – finnw
    Sep 10, 2010 at 19:51
  • 7
    Having getters and setters breaks encapsulation. The field might as well be public. Members should be private and should be manipulated sensibly by the class with higher-level logic, not with getters and setters from client code.
    – greyfade
    Sep 18, 2010 at 5:54
  • 6
    @greyfade: If it's public, you can't easily change what the setting code does (you'll have to change all code that sets the field from the outside). Sep 18, 2010 at 10:41
  • 3
    @SHiNKiROU: Java looks clean? I've never heard that one before! My main gripe with Java is the fact that seemingly simple thing takes dozens of lines of code I need to mentally ignore. Sep 29, 2010 at 6:31
32
votes

The switch statement (in C, C++, C#, Java, etc.)

Here is an example of why I find it highly inconvenient:

switch (someVariable)
{
    case 1:
        int i = something();
        doSomething(i);
        break;

    case 2:
        int i = somethingElse();
        doSomethingElse(i);
        break;
}

This doesn’t compile because the variable i is redeclared in the same scope. This seems like a minor detail, but it bites me really often. I can add curly brackets to mitigate it, but it would have been nice if the curly brackets had been mandatory part of the syntax, and there was no redundant extra level of indentation. I also really hate having to write the extra break. This would be much nicer:

switch (someVariable)
case 1
{
    int i = something();
    doSomething(i);
}
case 2
{
    int i = somethingElse();
    doSomethingElse(i);
}
default
{
    ...
}

This makes it look more like an if/else chain, which is a good thing because it is semantically similar too. At least in C# it would still not be the same thing however, because in a switch statement the order of the case labels doesn’t matter, but in an if/else it does.

16
  • 1
    Unfortunately, your improved syntax does away with what is, arguably, switch's biggest feature in most of these languages: Fall-through. "Duff's Device" in C is a perfect example of the value of this particular "mis-feature." It is also common in C-like languages to use fall-through in interpreters and similar programs.
    – greyfade
    Sep 4, 2010 at 20:50
  • 7
    No, it doesn’t do away with it. It only requires that it be made more explicit (using a goto or similar), as is already the case in C#.
    – Timwi
    Sep 4, 2010 at 21:06
  • 8
    @greyfade: Any code using duff's device in C needs to die a horrible death. Compilers make better decisions about these kinds of things than you do. Sep 18, 2010 at 3:34
  • 4
    @greyfade: Delphi gets around the multiple value issue by simply allowing multiple indices in the case: case Foo of 1,3: Result := 'odd'; 2,4: Result := 'even' end;. Sep 24, 2010 at 16:18
  • 3
    @jkerian: Now imagine break was the default and only fallthrough needed to be specified. No more need to remember to comment it! :)
    – Timwi
    Sep 27, 2010 at 18:54
32
votes

Whitespace Sensitivity.

Python annoys me in this respect. I mean, I indent properly anyway, but it bugs me that I should have to. Making presentation part of the syntax irks me.

2
  • 8
    you'll learn to love it
    – user10008
    Aug 18, 2011 at 4:59
  • 2
    syntax is presentation Jan 3, 2012 at 3:41
27
votes

Array Declarations in VB.NET

I always manage to forget that when initializing fixed arrays in VB.NET, you're specifying the upper bound of the array and not the number of elements like in C/C++, PHP, or Java. Besides VB6 (we won't go there...), I can't think of another language that does it this way:

Dim myArray(20) as Integer  '# Creates an array with 21 elements,
                            '# indexed from 0 to 20
2
  • I think all the BASIC languages do this...I know taht orginal BASIC and QBasic do.
    – Michael K
    Mar 17, 2011 at 15:59
  • OMG that is truly horrendous.... +1
    – mikera
    May 26, 2011 at 20:41
24
votes

VB6 - Separate Variable Declaration and Assignment

Most languages let you declare a variable and assign it in one line of code; VB6, on the other hand, forces you to use two.

Dim i as Integer
i = 0

Dim derpderp as Collection
Set derpderp = new Collection

You can use a colon to put two commands on one line, but it quickly turns messy in actual code.

Dim i as Integer: i = 0
Dim derpderp as Collection: Set derpderp = new Collection
8
  • 7
    +1 for having to use VB6 as your most frequent language.
    – Walter
    Sep 2, 2010 at 23:10
  • 9
    I use it daily..sob. Sep 3, 2010 at 18:19
  • Doesn't Pascal have a similar syntax? I always thought it was nasty.
    – greyfade
    Sep 4, 2010 at 20:59
  • 1
    There's a special case: if you Dim Hurp As New Collection, if you access Hurp when it refers to Nothing, it will be magically initialized before the access. If you explicitly set it to Nothing and touch it again, it gets resurrected... gasp! Sep 18, 2010 at 4:04
  • 1
    +1million for Derp. Derp de derp de tiddly tum de derp.
    – MVCylon
    May 26, 2011 at 19:21
24
votes

Commenting in CSS

// doesn't comment out lines of code like it does in many other languages, like PHP and Javascript. Although /* this is commented out */ works, I prefer to use //.

Its a nuisance, because half the time I forget I am editing CSS and then have to go back and fix the error.

3
  • You would of thought in this day and age that raw CSS would be considered object code. Dec 7, 2010 at 14:35
  • // works just fine to comment out CSS. I do it all the time. All I'm really doing is typing garbage. but it seems to work by skipping the unparseable line.
    – MVCylon
    May 26, 2011 at 19:22
  • 1
    @MVCylon If you use // to comment out a line, anything after that following line also is skipped. {within that specific style} In other words, it FAILS because those lines should not be skipped. Oct 2, 2012 at 1:26
20
votes

PHP - consistent ordering of arguments

PHP has a number of handy functions for doing pretty much every operation you could think of on an array or string. Many of these operations require using both a $needle and a $haystack, but different functions take them in different orders. Which function requires which arguments is one of those facts my brain refuses to absorb, no matter how often I come across them!

Take the functions in_array and strstr:

// Check whether $needle occurs in array $haystack
bool in_array (mixed $needle, array $haystack [, bool $strict])

// Check whether $needle is a substring of $haystack
string strstr (string $haystack, mixed $needle [, bool $before_needle=false])

Funnily enough, PHP seems to be internally consistent with these orderings in that all string functions seem to use $haystack, $needle while array functions are the other way around, but this can take a bit of getting used to for someone new to PHP. There's a good post on ExpressionEngine talking about this particular quirk in more detail, as well as a discussion on the PHP bugs list, which features a very short response from the PHP team!

[email protected]
Use a decent IDE then.
9
  • 2
    It's easier to remember the order $needle, $haystack as it reminds the way of saying find a needle in a haystack.
    – apaderno
    Sep 3, 2010 at 1:40
  • 3
    Protip: in array functions, needle comes first. in string functions, haystack comes first.
    – GSto
    Sep 9, 2010 at 2:05
  • 17
    I love the name strstr. So beautifully meaningless. Sep 29, 2010 at 6:32
  • 5
    Just read the linked entry in PHP's bugtracker. Seriously, wtf? oO Imho consistency is a valid issue for any API and just responding with "use a decent IDE then" is just not a valid reply. At least it could have been worded less inflammatory by the devs.
    – Baelnorn
    Oct 1, 2010 at 16:08
  • 2
    Honestly, what drives me crazy about this is that it shouldn't be a function at all! It should just be a method: $haystack->find($needle). Done deal.
    – riwalk
    May 26, 2011 at 20:30
19
votes

Python

self parameter in instance method definitions

6
  • In a classmethod, it's usually named cls and using self goes against convention.
    – Roger Pate
    Sep 9, 2010 at 3:25
  • It actually make sense if you think about it. It's the same as declaring a private method in other languages, the self parameter is just explicit in python where it's implicit in other languages. If you want it to be implicit add the @classmethod decorator before the method declaration. See docs.python.org/library/functions.html#classmethod. Learning the details of how this works will give you some insight as to how it's done in other languages implicitly. Sep 11, 2010 at 13:48
  • 4
    I understand the reasons and why it is left there neopythonic.blogspot.com/2008/10/… but I still don't like it Sep 11, 2010 at 21:23
  • @Evan Plaice: 'self parameter is just explicit in python where it's implicit in other languages' That's only one part of the story. The other part is python being weekly typed. Together it's terrible, forgetting self happens to easily and costs time.
    – maaartinus
    Apr 26, 2011 at 22:04
  • @maaartinus Then add a classmethod decorator to your instance methods. Has nothing do with 'weakly typed'. It just makes the relationship between static methods/functions (no 'self' parameter) and instance methods (includes 'self') obvious. An instance method isn't aware of it's parent class unless you give it a reference to do so. In other languages the distinguishing characteristic I outlined is just hidden behind syntactic sugar. If I had a choice to do it all over I would have started learning OOP in Python first. Jan 17, 2012 at 7:27
18
votes

Java

Period. Full stop. End of story.

Where to start? Oh, I know where to start: Java’s insanely complicated and ugly and stupid and inherently broken generics. Need I say more? :( Ok fine, then: type erasure.

Then there’s non-deterministic resource management. Kewl feetcher!

What’s next up? Oh yeah: Java’s stupid regexes are my most irritating, seething beef. I cannot count how many times I’ve been hosed by not having enough backslashes. This is even worse than not having access to any Unicode properties from this millennium — which is complete bull. Ten fricking years out of date!!! Completely useless. Trash it.

Then there’s the bug that the character class shortcuts don’t work on non-ASCII. What a royal pain! And don’t even consider using \p{javaWhiteSpace}; it doesn’t do the right thing with several very common Unicode whitespace code points.

Did you know there’s a \p{javaJavaIdentifierStart} property? Whatwhatatat wereere they thinkinking? So glad they got such smart peepers wurkin on dis tough.

Ever tried to use the CANON_EQ flag? Do you know that really does, and what it doesn’t do? How about so-called “Unicode case”? A bunch of normal casing things just don’t work at all.

Then they make it hard to write maintainable regexes. Java still hasn’t figured out how to write multiline strings, so you end up writing insane things like this:

    "(?= ^ [A-Z] [A-Za-z0-9\\-] + $)      \n"
  + "(?! ^ .*                             \n"
  + "    (?: ^     \\d+      $            \n"
  + "      | ^ [A-Z] - [A-Z] $            \n"
  + "      | Invitrogen                   \n"
  + "      | Clontech                     \n"
  + "      | L-L-X-X                      \n"
  + "      | Sarstedt                     \n"
  + "      | Roche                        \n"
  + "      | Beckman                      \n"
  + "      | Bayer                        \n"
  + "    )      # end alternatives        \n"
  + ")          # end negated lookahead   \n" 

What are all those newlines? Oh, just Java stupidity. They used Perl comments, not Java comments (idiots!) which go till end of line. So if you don’t put those \n’s there, you chop off the rest of your pattern. Duh and double duh!

Don’t use regexes in Java: you’ll just end up wanting to smash things, it’s all so painful and broken. I can’t believe people put up with this. Some don’t.

Then we can start talking about Java’s idiot nonsense with encodings. First, there’s the fact that the default platform encoding is always some lame 8-bit encoding even though Java’s charchars are Unicode. Then there’s how they don’t raise an exception on an encoding error. You’re guaranteed to get crap. Or how about this:

OutputStreamWriter(OutputStream out) 
          Creates an OutputStreamWriter that uses the default character encoding.
OutputStreamWriter(OutputStream out, Charset cs) 
          Creates an OutputStreamWriter that uses the given charset.
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 
          Creates an OutputStreamWriter that uses the given charset encoder.
OutputStreamWriter(OutputStream out, String charsetName) 
          Creates an OutputStreamWriter that uses the named charset.

What’s the difference? Did you know that only one of those will raise an exception if you have an encoding error? The rest just muzzle them.

Then there’s the idiocy of Java chars not being sufficient to hold a character! What the hell are they thinking? That’s why I call them charchars. You have to write code like this if you expect it work right:

private static void say_physical(String s) { 
    System.out.print("U+");
    for (int i = 0; i < s.length(); i++) {
        System.out.printf("%X", s.codePointAt(i));
        if (s.codePointAt(i) > Character.MAX_VALUE) { i++; }  // UG!
        if (i+1 < s.length()) { System.out.printf("."); }
    }
}

And who ever thinks to do that? Next to nobody.

How many characters are there in "\uD83D\uDCA9"? One or two? Depends on how you count them. The regex engine of course deals with logical characters, so a pattern ^.$ will succeed and a pattern ^..$ will fail. This insanity is demonstrated here:

String { U+61, "\u0061", "a" }  =~ /^.$/ => matched.
String { U+61, "\u0061", "a" }  =~ /^..$/ => failed.
String { U+61.61, "\u0061\u0061", "aa" }  =~ /^.$/ => failed.
String { U+61.61, "\u0061\u0061", "aa" }  =~ /^..$/ => matched.
String { U+DF, "\u00DF", "ß" }  =~ /^.$/ => matched.
String { U+DF, "\u00DF", "ß" }  =~ /^..$/ => failed.
String { U+DF.DF, "\u00DF\u00DF", "ßß" }  =~ /^.$/ => failed.
String { U+DF.DF, "\u00DF\u00DF", "ßß" }  =~ /^..$/ => matched.
String { U+3C3, "\u03C3", "σ" }  =~ /^.$/ => matched.
String { U+3C3, "\u03C3", "σ" }  =~ /^..$/ => failed.
String { U+3C3.3C3, "\u03C3\u03C3", "σσ" }  =~ /^.$/ => failed.
String { U+3C3.3C3, "\u03C3\u03C3", "σσ" }  =~ /^..$/ => matched.
String { U+1F4A9, "\uD83D\uDCA9", "💩" }  =~ /^.$/ => matched.
String { U+1F4A9, "\uD83D\uDCA9", "💩" }  =~ /^..$/ => failed.
String { U+1F4A9.1F4A9, "\uD83D\uDCA9\uD83D\uDCA9", "💩💩" }  =~ /^.$/ => failed.
String { U+1F4A9.1F4A9, "\uD83D\uDCA9\uD83D\uDCA9", "💩💩" }  =~ /^..$/ => matched.

That idiocy is all because you can’t write the perfectly reasonable \u1F4A9, nor of course do you get any warning that you can’t do that. It just does the wrong thing.

Stoooopid.

While we’re at it, the whole \uXXXX notation is congenitally brain dead. The Java preprocessor (yes, you heard me) gets at it before Java does, so you are forbidden from writing perfectly reasonable things like "\u0022", because by the time Java sees that, its preprocessor has turned it into """, so you lose. Oh wait, not if it’s in a regex! So you can use "\\u0022" just fine.

Riiiiiiiight!

Did you know there’s no way in Java to do an isatty(0) call? You aren’t even allowed to think such thoughts. It wouldn’t be good for you.

And then there’s the whole classpath abomination.

Or the fact that there’s no way to specify the encoding of your Java source file in that same source file so you don’t lose it? Once again I demand to know: WHAT THE HELL WERE THEY THINKING‽‽‽

Stop the madness! I can’t believe people put up with this garbage. It’s a complete joke. I’d rather be a Walmart greeter than suffer the slings and arrows of outrageous Java insanity. It’s all broken, and they not only can’t fix it, they won’t fix it.

This by the same foxy-grapey people who prided themselves on a language that made it illegal to have a printf() function. Gee, that sure worked out real well, didn’t it though!?

Sheer numbskulls. Bitch-slapping is too kind for them. If I wanted to program in assembler, I would. This is not a salvageable language. The emperor has no clothes.

We hates it. We hates it forever. Let it die die die!

8
  • Haha, good one, I don't touch java because it's too unpolished like you describe. As for \uD83D... well I suppose a better way of saying this is that you'd rather strings were not UTF-16 but UTF-32 instead. If you accept UTF-16-ness then the regex do the right thing; it's the .length call that fucks up. Nov 21, 2010 at 10:07
  • 4
    -1. With the exception of regexp comments and Unicode escapes, not a single one of the things you mentioned is a syntax element. Nov 21, 2010 at 11:25
  • 3
    @Jörg, you want syntax? Ok fine: Java allows you to put control characters, include ESC and NUL, in identifiers. WTH were they thinking???
    – tchrist
    Nov 22, 2010 at 22:12
  • 4
    @tchrist: Wow! If I ever write a Java program again, all my variables will have names consisting of varying numbers of backspace characters (^H) :) Nov 29, 2010 at 12:44
  • 1
    @tchrist, feeling better now?
    – user1249
    Jun 23, 2011 at 9:25
16
votes

Function pointer declaration syntax in C and C++:

(int)(*f)(int, int);

That declares a function pointer named f whose pointee can take two ints and return an int.

I'd much prefer a syntax like this:

f: (int, int) => int

Say you want to declare a function pointer g whose pointee can take two ints and a function from int and int to int, and return an int.

With C or C++ notation, you'd declare it as:

(int)(*g)(int, int, int(int, int));

With the above-proposed notation same thing can be declared as:

g: (int, int, (int, int) => int) => int

Latter is much more intuitive IMO.


Aside: The programming language called OOC fixes this syntax (and various other syntactical issues in C and C++). Check out its homepage here.

2
  • Agree, some "plain C" / "C++" doesn't support it, or support it with different syntax. A special syntax, helps indicate when a programming language feature is supported. That's why C# added "delegate" syntax.
    – umlcat
    Mar 15, 2011 at 18:32
  • Delegates are not only syntactic sugar because they also store the object (contrary to C++ member function pointers, that have even worse syntax than regular function pointers) May 26, 2011 at 20:13
14
votes

Verbosity in Java.

ie:

public static final int 
12
  • 6
    Compared to? (15 chars)
    – TheLQ
    Sep 3, 2010 at 1:44
  • 7
    Compared to: const int for instance.
    – OscarRyz
    Sep 6, 2010 at 23:27
  • 11
    "public static final int x = 4;" compared to "x = 4" in Haskell. Sep 8, 2010 at 23:52
  • 24
    That's not verbosity. Try writing a+(b*c)/d*e+f/g^20 using BigInteger in Java. Why does this language not allow operator overloading?
    – MAK
    Sep 20, 2010 at 10:07
  • 4
    @Michael: programmers who need to be protected from themselves at this cost can best protect themselves (and reduce the pain for everyone else) by not programming at all :D.
    – MAK
    Mar 18, 2011 at 3:03
12
votes

\we\wouldnt\fix\our\parser namespace syntax in PHP

The syntax is not only ugly, it leads to confusion when newer developers have to think about namespaces in strings. (PHP interpolates backslashes in double-quoted strings as escape sequences. Trying to represent a namespace like \you\should\never\do\that in a double-quoted string instead of a single-quoted string will lead to newlines, tabs and disaster.)

2
  • Yeah, someone thought of a better::way to do this, but PHP insist that every operator must be different. I am curious as to what the misuse issue is here though. Sep 24, 2010 at 17:20
  • Agree. PHP require namespaces, but that syntax screw it up
    – umlcat
    Mar 15, 2011 at 18:35
9
votes

I despise the fact that curly braces can be optional after an if/while/for statement.

Especially when I see code like,

if (...)
    for(...)
        ... One line of stuff ...

Please just put the braces in and be done with it.

12
  • 6
    Hmm.. this depends. For "Abort Ifs" which merely check a condition and return an error code (or throw an exception), I'd much rather not see the braces. Sep 18, 2010 at 3:48
  • 4
    I would agree if you limited yourself to extreme multi-level cases, but your statement is too blanket. There is great utility in the ability to have short forms for simple, single-statement ifs and loops.
    – Timwi
    Sep 18, 2010 at 12:12
  • 2
    My rule: only if a statement requires multiple substatements or if it contains such a statement should it be wrapped in braces. Thus for (...) while (...) if (...) { x(); y(); } is better rewritten as for (...) { while (...) { if (...) { x(); y(); } } }, with appropriate indentation, of course.
    – Jon Purdy
    Sep 20, 2010 at 12:10
  • 6
    I'm rather the opposite -- I despise people who insist on putting in braces when they're completely unnecessary. Just learn to program. Oct 16, 2010 at 18:42
  • 3
    I really like the brackets even in single if statements. It makes me follow the flow of a program better. Dec 29, 2010 at 16:32
9
votes

VBScript Doesn't Have Logical Operators

Unlike nearly every sensible language, VBScript uses bitwise operators instead of logical operators. What does this mean in practice? Well, as Eric Lippert points out:

If Blah = True Then Print "True!" Else Print "False!"

and

If Blah Then Print "True!" Else Print "False!"

are NOT the same in VBScript!

Even worse, though, this means that there is no short-circuit evaluation in VBScript so that the following statement will crash your program if Blah is Nothing

If (Not Blah Is Nothing) And (Blah.Frob = 123) Then
...

That's right, VBScript will evaluate both parts of the AND comparison, even if the first one is false! Just let that sink in...

1
  • 3
    Until the day you've hunted a bug inside an If x Then ... If Not x Then ... End If ... End If and figured out that x is 2, you haven't really programmed in VB/VBScript. Sep 29, 2010 at 6:54
7
votes

EDIT: Following the discussion in the comments I decided to update this answer to explain myself better.

I really hate the way function pointers look in C. Usually any variable declaration looks like a tuple of: type varname; Function pointer declarations on the other hand look like a declaration of the function with * before the function name. I can accept this as a description of a pointer type, but in C this declares both the type and the name of a variable of that type. This looks inconsistent to me because type declarations are otherwise distinct from variable declarations. struct myStruct{int X; int Y;} only defines a type, it does not define a variable named myStruct. Likewise I see no reason for type declarations and variable declarations to be grouped into one atomic statement in function pointers, nor do I appreciate the deviation from the type varname; structure.

Someone pointed out that it's consistent with some spiral rule, and that may be the case, but the mark of a good syntax is that it is self explanatory and its internal logic is obvious. The spiral rule is not obvious by any means.

9
  • 1
    It's consistent with the rest of the language, so maybe your gripe is about the syntax of C declarators in general? Do you prefer the syntax used in Go?
    – finnw
    Sep 3, 2010 at 5:10
  • Consistent in what way? Usually it goes: type varname; And when we create a new composite type, like a struct, first comes the declaration, maybe with a typedef, and then we create a variable of that type. When we declare a function pointer, it's int (*foo)(int arg1, int arg2), which is then used as the type of an argument passed to a function: void newFoo(int (*foo)(int arg1, int art2)).... and as a variable: foo=a_compatible_func; I think that a function declaration first, and then a var declaration next would be more consistent, like so: typedef int (*foo)(int, int) MyFoo; MyFoo myfoo; Sep 3, 2010 at 15:31
  • That's why you got typedef.
    – zneak
    Sep 3, 2010 at 15:56
  • 4
    @EpsilonVector: I tend to agree that function pointer syntax is nasty, but there is a simple rule to follow that makes it easier to read. The clockwise spiral rule (perhaps you've seen it?): c-faq.com/decl/spiral.anderson.html
    – greyfade
    Sep 4, 2010 at 20:57
  • 1
    EpsilonVector: I'm not sure what you'd expect from a pointer variable declaration to declare other than the name of the variable.
    – Roger Pate
    Sep 9, 2010 at 3:29
6
votes

Semicolons in VBScript - or the lack thereof

I spend all day working in languages that expect semicolons at the end of each line. Add one to the end of the line in VBScript and your code doesn't run anymore.

1
  • 4
    up-voting this, not because I particularly like semicolons, but because I really hate the way VB encourages really long lines by making linebreaks so inconvenient.
    – Shog9
    Sep 18, 2010 at 3:57
6
votes

In/out arguments. I'm all for in arguments (good thing I am), out arguments are fine too, but an argument that must convey these two states pisses me off.

What I target here are functions that take input from a parameter then overwrite that input with some output. It's okay to pass an object by reference to update it. But, mostly for primitive types, taking an object, use it, then change it completely, is not right by me. You shouldn't change the meaning of the argument through an inout.

7
  • What language do you have in mind? If C# then I would disagree that it's annoying because it's always explicit (unlike in C++.) Also I don't know of any mainstream language where your are forced to declare arguments as in/out.
    – finnw
    Sep 3, 2010 at 5:07
  • @finnw I've never seen a language where you had to say in for in arguments either, I'm just talking about them. Also, in my opinion, nothing can excuse an in/out argument, and making them explicit does not relieve the pain. There should be no reason to have to initialize a local variable with a value helpful to the function, and have this same variable then suddenly contain whatever the function decided to put there. These two should be distinct. Always.
    – zneak
    Sep 3, 2010 at 15:52
  • Sorry I was not very clear there. I meant to say "I don't know of any language where all arguments are implicitly in +out" i.e. you are not forced to use that feature, but there are legitimate use cases (e.g. updating a struct where the new value depends on the value of another field of the same struct.)
    – finnw
    Sep 3, 2010 at 19:52
  • @finnw Objects passed by reference (like instances of class objects in C#) being modified by a function are fine to me. Aside that I dislike non-constant structs, passing a struct with the ref keyword to update it is okay, too. What I really hate is when input is overwritten with output. The best example I can think of is Berkeley socket's accept function: it needs a socklen_t* argument that, on input, must contain the size of the struct sockaddr* you've passed; and on output, will contain the number of bytes that have been written to it. This should be criminal.
    – zneak
    Sep 3, 2010 at 20:12
  • I agree that is bad (IIRC some Win32 I/O functions do the same) but that is misuse of the feature (the function call changes the meaning of the passed-in variable, not just its value) and it does not mean the feature itself is bad.
    – finnw
    Sep 3, 2010 at 20:20
6
votes

Array declarations in C and C++.

Typically, a variable declaration is of the format type variable_name. You can easily read those declarations in a left-to-right manner. But int foo[size] looks at first like it's declaring foo as an int, and then you read further and see that foo's of type "array of integers." int[size] foo reads much better.

And I also hate it when programmers declare pointers like this for a similar reason: int *foo. For some reason I haven't figured out, that's the typical way it's written.

8
  • 1
    Re pointer declarations: they're written like that because the '' binds to the variable name, not the type. So int* a, b; does *not declare a and b as pointers; only a is. Hence it's better to write it as int *a, b; (or even better to write them as two declarations). Sep 17, 2010 at 21:35
  • Good point. It's too bad * doesn't bind to the type.
    – Jacob
    Sep 17, 2010 at 22:49
  • 2
    And this is to say nothing of function pointers... void(int) *f;? Nope: void (*f)(int); Sep 18, 2010 at 17:01
  • In modern C++ there is very little need for pointers and arrays. Sep 26, 2010 at 21:51
  • 2
    @Steve Melnikoff: Although I +1ed this answer, I think that int* a, b; issue you mentioned is much more egregious. Nov 29, 2010 at 12:40
5
votes

Redundant parameterization in Java:

HashMap<String,HashMap<String,String>> foo = new HashMap<String, HashMap<String, String>>();

What other type parameterization does the compiler think foo could have?

5
  • 4
    I hope you are aware of Java's (limited) type inference? HashMap<String,HashMap<String,String>> foo = Maps.newHashMap();
    – finnw
    Sep 10, 2010 at 19:49
  • 1
    Java 7: HashMap<String,HashMap<String,String>> foo = new HashMap<>(); Sep 18, 2010 at 10:50
  • 5
    Well it can have any type it wants, the types are erased anyway... Sep 29, 2010 at 6:58
  • Lack of type inference, you mean? Oct 16, 2010 at 10:26
  • What other type parameterization does the compiler think foo could have? - For whatever reason it things it's raw type - as if anybody sane would even mix raw and parametrized types.
    – maaartinus
    Apr 26, 2011 at 22:21
5
votes

Since people have already complained about = vs. ==, let me point out a much worse alternative. PL/I had both := and =, but when something was "obviously" an assignment, it would let you get away with using = to do it. Using := let you force something to be an assignment in a situation where the compiler would otherwise interpret it as a comparison.

Unfortunately, the compiler didn't always decided on things quite the way you might expect. Consider just one obvious example:

A = B = 0;

Now, to most people familiar with most "ordinary" languages, the meaning of this is pretty obvious -- assign 0 to both A and B. PL/I is just a bit...different though. For reasons known only to the (insane) designers of the language, the first = is interpreted as an assignment, but the second = is interpreted as a comparison. Therefore, this compares B to 0, and then assigns the result of that comparison to A (following the C-style convention that "false" results in 0 and "true" in 1).

So, if B was 0, then A becomes 1. Otherwise, A becomes 0. In other words, rather than assigning the same value to A and B, this actually ensures that A cannot have the same value as B.

Bottom line: even though the C/C++/PHP style initially seems like a pain, the alternative is much worse1.

1Well, technically, there's another alternative: Pascal style, where = always means comparison and assignment always requires :=. After using that for a while, it's pretty obvious (at least to me) that assignment is enough more common than comparison that if you're going to require extra "stuff" to disambiguate the two, you should definitely keep assignments clean and simple and require the extra "grunge" on comparisons, not vice versa.

2
  • 1
    I'd even propose to use == for equality and := for assignment. This way you have more to type, but avoiding the lonely = helps to avoid bugs.
    – maaartinus
    Apr 26, 2011 at 22:20
  • @maartinus: at least to me, that sounds like the absolute worst possibility, but such is life... Apr 26, 2011 at 22:22
3
votes

Perl

  1. I wish Perl let me write if($x < 10) do_something();. At the moment, you have to write that as either do_something() if($x < 10); or as if($x < 10) { do_something(); }.
9
  • 9
    do_something() if ($x < 10); isn't that bad.
    – zneak
    Sep 3, 2010 at 20:23
  • It isn't, and in many cases is much cleaner than if(..) ... to boot, as you can get all the expressions to line up on the right. But there's times I really want to say if($x < 10) do_something();, and it's unfortunate that Perl won't let me.
    – Gaurav
    Sep 4, 2010 at 5:54
  • 7
    It's unfortunate until you write if ($x<10) do_something(); and_call_me(); and then wonder why you never get a call. I wish C and family would require the braces, to prevent that type of error.
    – AShelly
    Sep 4, 2010 at 17:13
  • 2
    @AShelly: or why you always get a call, actually.
    – zneak
    Sep 10, 2010 at 1:04
  • 1
    @zneak Except no elses. (I wish it has EXPR1 if COND else EXPR2 like Python has)
    – Ming-Tang
    Sep 21, 2010 at 3:53
3
votes

reinterpret_cast<unsigned long> in c++. This operation is useful in dealing with foreign APIs and ensuring numerical precision, why should it be such a pain to type and so ugly to look at?

3
  • 17
    It's ugly to remind you that you should strive to write code that doesn't require it. :)
    – greyfade
    Sep 4, 2010 at 20:58
  • To me that's a good theoretical computer science kind of argument, but in my experience, it's too useful to avoid (However, much of my experience is plain old C, so I probably have a bias).
    – AShelly
    Sep 7, 2010 at 4:36
  • 5
    It's not really a theoretical CS argument: Using a reinterpret_cast in C++ is a very strong code smell. 99% of the time, when you are about to use it, chances are, you shouldn't need to - you probably did something wrong. The other 1% of the time, you're interfacing with C. reinterpret_cast breaks the type system to make something work when it otherwise can't. That's usually a bad thing.
    – greyfade
    Sep 18, 2010 at 5:52
3
votes

The for ... in construct in JavaScript and the foreach construct in PHP when looping over arrays. Both of them make it easier to write bugs than correct code.

3
  • If I have to write extra code to use them safely, they're easier to use wrong in my book. For ... in requires extra checks to make sure you're not iterating over objects from the prototype, and foreach requires you to clean up references afterwards or risk overwriting the last value in the array. Oct 16, 2010 at 7:47
  • the foreach with changing references (& operator) is a famous bug...
    – umlcat
    Mar 15, 2011 at 20:41
  • 1
    I'm confused, I thought it was common knowledge that the "for..in" construct in javascript is broken... why is this offensive?
    – lvilnis
    Jan 15, 2012 at 8:40
2
votes

Pointers of arrays or arrays of pointers in C/C++. I am still confused about these.

6
  • 3
    Read the type backwards. int[]* is a pointer to an array of integers, and int*[] is an array of pointers to integers. Works well with consts too: int* const is a constant pointer to integers, whereas const int* and int const* are pointers to constant integers (or to integer constants).
    – zneak
    Sep 2, 2010 at 22:42
  • @zneak: "Right to left" doesn't work, see the mentioned "clockwise spiral" / "inside out" rule.
    – Roger Pate
    Sep 9, 2010 at 3:31
  • Or, just use typedefs and there's no confusion. Sep 18, 2010 at 3:49
  • In modern C++ there is very little need for pointers and arrays. Sep 26, 2010 at 21:49
  • 4
    @tchrist: Not true. int (*p)[10]; declares p to be a pointer to an array of 10 ints. If sizeof (int) == 4, then p++ will advance p by 40. Nov 29, 2010 at 12:35
2
votes

The fact that Python relies on text formatting.

1
vote

Javascript/Java etc, equals comparison, eg if(a==1)

How many times do I write if(a=1) ?

As a human I read that perfectly. But the darn interpreter/compiler says, "hey I'll assign 1 to a, then check if a is equal to 1, and would you believe it yes it is!

Drives me up the wall.

if(a==1) is far less readable, and the interpreter/compiler should know what I mean anyway; many other lesser languages (VB) have been working it out successfully for hundreds of years.

5
  • What is if (a = true) supposed to mean? Sep 20, 2010 at 17:07
  • 2
    Assignment just shouldn't return a value. It's sometimes useful, but in most cases it's just a pain in the neck. Sep 29, 2010 at 6:59
  • in Javascript JSLint will catch that one for you.
    – Zachary K
    Feb 27, 2011 at 10:55
  • The trouble is, assignment in conditions can be useful. I find <tt>while( element = list->next() )</tt> quite legible. So I am not sure I would like te have it removed.
    – Inca
    Feb 27, 2011 at 10:59
  • 3
    @Tom: It means you don't understand booleans. If you meant if (a == true), just write if (a). If you meant a = true, then the if statement is redundant.
    – dan04
    Feb 27, 2011 at 16:27
1
vote

Verbosity in Java anonymous classes. Will hopefully be fixed soon.

1
0
votes

structPointer->member in C/C++ . May be good for reading someone else's code, but I don't like it. Two characters instead of one... what a waste of space!

11
  • 2
    Unfortunately, it must be distinguished from ., which applies to members of a non-pointer object. Ambiguous syntax is bad, mmmkay?
    – greyfade
    Sep 4, 2010 at 20:54
  • 2
    @greyfade: Yep! Because the compiler can't possibly use its type system rules to tell when you're using a pointer-to-struct type and apply the dereference implicitly. Nope, that's crazy talk! (And yet it can still somehow give you an error message when you get it wrong.) There's nothing ambiguous about the syntax. It's just C being a braindead mess, as usual. Delphi does implicit dereferences just fine, if you're actually working in dark corners that require pointers-to-records, so it can certainly be done without confusing a parser... Sep 17, 2010 at 18:33
  • 5
    @Mason: What about cases like shared_ptr, where -> accesses the contained type and . accesses properties of the shared_ptr itself? I'm sorry, but I completely disagree here. Sep 18, 2010 at 3:50
  • 2
    could be worse. Could be PHP, where you have to use -> to access members of anything. Dec 7, 2010 at 4:11
  • 1
    @maaartinus: Any code which relies that heavily on non-obvious order of operations is not code I will be writing. Apr 27, 2011 at 18:27
0
votes

Scala multi-line code in brackets

For instance:

class Foo(
         val bar: String,
         val baz: Int,
         val bing: String,
         val bong: Boolean
 ) extends Model {
   // body here
 }

What you actually get from it is terrific. It generates the constructor and the getters and setters for you. But it sure is ugly and breaks all my mental models of how to indent code and basically leaves me feeling like I'm in a sort of bizarre sandwich with Java on one side and Lisp on the other. (Oh, wait... that is rather the point of Scala.)

5
  • I'm confused -- do you mean the portion in the parenthesis (val bar and so on) or the portion in curly braces (the part following extends Model)? (There are no brackets in that code) Sep 18, 2010 at 3:36
  • 3
    The portion in the parentheses. I'm English. We refer to those as brackets, damnit, because in that situation they aren't serving a parenthetical role.
    – Tom Morris
    Sep 22, 2010 at 11:39
  • 2
    It doesn't look all that bad if indented this way: pastebin.com/h9qC8XGg Oct 15, 2010 at 17:52
  • I find it more readable to write these constructor parameter lists horizontally, especially when I only have a few parameters.
    – MJP
    Jan 9, 2011 at 21:08
  • Looks like a method to me. Like Simula. Good old school. Feb 27, 2011 at 14:21

Not the answer you're looking for? Browse other questions tagged or ask your own question.