403
votes

There's been a cluster of Perl-hate on Stack Overflow lately, so I thought I'd bring my "Five things you hate about your favorite language" question to Stack Overflow. Take your favorite language and tell me five things you hate about it. Those might be things that just annoy you, admitted design flaws, recognized performance problems, or any other category. You just have to hate it, and it has to be your favorite language.

Don't compare it to another language, and don't talk about languages that you already hate. Don't talk about the things you like in your favorite language. I just want to hear the things that you hate but tolerate so you can use all of the other stuff, and I want to hear it about the language you wished other people would use.

I ask this whenever someone tries to push their favorite language on me, and sometimes as an interview question. If someone can't find five things to hate about his favorite tool, he doesn't know it well enough to either advocate it or pull in the big dollars using it. He hasn't used it in enough different situations to fully explore it. He's advocating it as a culture or religion, which means that if I don't choose his favorite technology, I'm wrong.

I don't care that much which language you use. Don't want to use a particular language? Then don't. You go through due diligence to make an informed choice and still don't use it? Fine. Sometimes the right answer is "You have a strong programming team with good practices and a lot of experience in Bar. Changing to Foo would be stupid."


This is a good question for code reviews too. People who really know a codebase will have all sorts of suggestions for it, and those who don't know it so well have non-specific complaints. I ask things like "If you could start over on this project, what would you do differently?" In this fantasy land, users and programmers get to complain about anything and everything they don't like. "I want a better interface", "I want to separate the model from the view", "I'd use this module instead of this other one", "I'd rename this set of methods", or whatever they really don't like about the current situation. That's how I get a handle on how much a particular developer knows about the codebase. It's also a clue about how much of the programmer's ego is tied up in what he's telling me.

Hate isn't the only dimension of figuring out how much people know, but I've found it to be a pretty good one. The things that they hate also give me a clue how well they are thinking about the subject.

30
This is a really nice spin on the old "your favorite language" question. Good justification.Tom Leys
I find it interesting that despite SO having a large .NET audience, at the time of this writing there are 24 answers, only one of which (mine) is about .NET or a .NET language. I have no idea what this says about SO or .NET, but it's interesting...Jon Skeet
The first 15 years of programming with C/C++, I hated (in alphabetical order): 1. Pointers 2. Pointers 3. Pointers 4. Pointers 5. Pointersileon
I wonder how many comments people made about hating their language of choice because they didn't understand how to program in their language of choice....Kris.Mitchell
This is a fantastic question. If you're wondering what some language is like, reading 3 different replies about it on this page would be easily the best useful-information-for-time-spent you could find. Also a great way to gauge a programmer's experience (and humility) levels if you already know the language.j_random_hacker

30 Answers

182
votes

Five things I hate about Java:

  • No first-class functions.
  • No type inference.
  • Lack of sane defaults in eg graphics.
  • NullPointerException not containing more information about what is null.
  • The proliferation of pointlessly "configurable" frameworks/service provider interfaces/factory classes/dependency injection systems. The configurability is almost never used, DRY is violated egregiously, and code quadruples in size and halves in legibility.

I know, I should check out Scala.

216
votes

Wow, I'm surprised that SQL hasn't made it up here yet. Guess that means nobody loves it :)

  • Inconsistent syntax across implementations
  • Subtle code differences can have massive performance ramifications for seemingly obscure reasons
  • Poor support for text manipulation
  • Easy cost of entry but steep learning curve towards mastering the language
  • Minimal standardization across the community for best practices, this includes syntax style.

...And a few bonus reasons to hate it, at no extra charge

  • the WHERE clause goes last, making it easy to prematurely execute an UPDATE or DELETE, destroying the whole table. Instead, the WHERE should go somewhere up front.
  • It's difficult to implement relational division.
  • I can set a value to NULL, but I can't test it for equality with NULL. I can check IS NULL, but that just complicates code -- needlessly so, in my opinion.
  • Why do we need to completely respecify the formula for a GROUPed column, rather than setting an alias on the column and then GROUP BY the alias (or column index as with SORT)?
159
votes

JavaScript:

  1. All the coolest things are insanely complex, but then, all the coolness is also wrapped up in such a small amount of code that you feel stupid for struggling to follow it

  2. '+' is an absurd choice of operator for concatenation in a weakly-typed language. Were they trying to scare off the noobs?

  3. It's a cross-browser compatibility minefield (never mind if it's even turned on or not)

  4. It's generally untrusted - associated with scummery such as blocking the back button, pop-ups that never die, etc.

  5. It's nearly impossible to debug because there are only a few different error messages and a few different types (Number, String, Object, etc.)

If it wasn't for jQuery, I'd probably still hate it as much as I used to :)

148
votes

PHP:

1) Forces me to make unnecessary variables:

$parts = explode('|', $string);
$first = $parts[0];

2) An implementation of lambdas so lame it is roughly equivalent to using eval() and so hideously wrong I have never used it (see http://www.php.net/create_function).

3) A try/catch system which can only catch about 80% of errors that might occur.

4) Regex support just as lame as lambda support because it has to be written inside regular strings, making one of the most hard-to-learn programming tools about three times as difficult. And PHP is supposed to be an "easy" language?!?!?

5) No way to safely pull stuff out of $_POST without writing it twice or building your own function, or using the '@' operator:

$x = isset($_POST['foo']['bar']) ? $_POST['foo']['bar'] : null;

6) Bonus answer: '@'. If you can't be bothered writing your code correctly, just add '@', and too bad for anyone who has to debug your code later.

135
votes

C++

  • Far too easy to randomly corrupt memory and create almost impossible-to-find bugs (although, Valgrind goes a long way towards fixing this).
  • Template error messages.
  • When using templates it's easy to end up having to include everything in one file, and then get stupid compile times.
  • The standard library is a joke in the modern age (still no threads or network by default?)
  • Lots of nasty little bits of C poking through (in particular, all the conversions between short/int/unsigned/etc..)
129
votes

C# / .NET:

  • Classes should be sealed by default
  • There should be no lock statement - instead, you should have specific locking objects, and there should be methods such as Acquire which return disposable lock tokens. Corollary: there shouldn't be a monitor for every object.
  • GetHashCode() and Equals() shouldn't be in System.Object - not everything's suitable for hashing. Instead, have an IdentityComparer which does the same thing, and keep the IComparer<T>, IComparable<T>, IEqualityComparer<T> and IEquatable<T> interfaces for custom comparisons.
  • Poor support for immutability
  • Poor way of discovering extension methods - it should be a much more conscious decision than just the fact that I'm using a namespace.

Those were off the top of my head - ask me tomorrow and I'll come up with a different 5 :)

113
votes

C

  • string manipulation.

Having to deal manually with the string buffers is an error-prone pain. Since so much computing is really moving and modifying strings (computers aren't used quite as much for big number-crunching stuff as people thought they'd be way back when), it's really nice to be able to use managed languages or C++'s string objects to deal with these. When I have to do it in straight C, it feels like swimming in quicksand.

94
votes

How about five things I hate about "Things I hate about some language" lists? :D

5- Painting an orange red doesn't make it an apple.

When a language is designed, the designers typically have in mind what it's useful for. Using it for something completely different can work, but complaining when it doesn't is just dumb. Take Python. I'm sure either someone has or someone will some day make a utility to create exe's from Python code. Why on God's earth would you want to do that? It would be neat—don't get me wrong—but it has no use. So stop complaining about it!

A well-designed project would likely contain code from multiple languages. That's not to say you cannot complete a project with only one language. Some projects may be well within the abilities of whatever language you are using.

4- Are you standing on wooden legs?

The platform can be a large influence of what the language can do. With nowadays garbage collectors, or well even pascals early attempt at "garbage collection", can aid in memory fade (maybe malloc more ram??). Computers are faster and so of course, we expect more out of our languages. And quite frankly, we probably should. However, there is a huge price to pay for the convenience of the compiler to create hash tables or strings or a variety of other concepts. These things may not be inherit to the platform of which they are used. To say they are easy to include to a language just tells me you may not have a leg to stand on.

3- Who's fault is it really?

Bugs. You know. I love bugs. Why do I love bugs. Because it means I get to keep my job. Without bugs, there would be many closed pizza shops. However, users hate bugs. But here is a little splash of cold water. Every bug is the programmers fault. Not the language's. A language with such a strict syntax that would significantly reduce how many bugs were possible to generated would be a completely useless language. It's abilities could probably be counted on one hand. You want flexibility or power? You've got bugs. Why? Because you're not perfect, and you make mistakes. Take a really identifiable example in C:

int a[10];
for (int idx = 0; idx < 15; idx++) a[idx] = 10;

We all know what that's going to do. However, what maybe some of us don't realize is.. that functionality can be very beneficial. Depending on what you are doing. Buffer overruns are the cost of that functionality. That code above. If I actually released that to the public. That's again.. say it with me.. "My fault". Not C's for allowing me to do it.

2- Shouldn't we put that in the recycle bin?

It's very easy to point at a feature in a language we don't understand because we don't use it often and call it stupid. Complain that it's there etc. Goto's always entertain me. People always complain about goto's being in a language. Yet I bet your last program included a type of goto. If you have ever used a break or a continue, you've used a goto. That's what it is. Granted, it's a "safe" goto, but it is what it is. Goto's have their uses. Whether "implicit" gotos like continue or break are used or explicit gotos (using the actual keyword "goto" for whatever language). Not that language developers are flawless, but typically... if functionality has existed since the dawn of time (for that language). Likely that aspect is a defining quality of that language. Meaning.. it's being used and likely is not hanging around because of backwards compatibility. It's being used today. As in 5 minutes ago. And used properly. Well.. arguably someone is using it improperly as well, but that relates to #3 on my list.

1. - Everything is an object.

Ok.. this one is really a subset of #2. But this is by far the most annoying complaint I see in hate lists. Not everything is an object. There are a great many of concepts that do not belong or need to be objects. Putting things where they don't belong is just ugly and can decrease efficiency of a program. Sure. Maybe not much depending on the language. This also relates to #5. This means... yes. Global are ok. Functions as apposed to static methods are ok. Combining OO programming with global functions is ok. Now.. that doesn't mean we should all go out and "free" our code from it's object models either. When designing a section of code or a whole project, what happens behind the scenes should be considered when putting it together. Not only where that concept lives and many other factors. Why wrap global functions within classes or name space concepts if it serves no purpose? Take static member variables. That greatly amuses me because.. well..Depending on the language and implementation of course, but generally speaking, you just declared a global. Yes, there are some reasons to wrap these non-OO concepts in OO wrappers. One of course being self documenting code. That can make sense. So.. like I say. Don't go out and "free" your code. But any good modern language will have a global concept outside of it's OO modeling. Yes I'm specifically meaning to point out that an OO programming language without a global concept most likely has a serious design flaw. Again though.. depends on the intention and design of the language so I'm not attempting to pick on any specific language and there are far too many to analyze right here. Anywho, Consider where the code should live and be the most effective. Adding a bunch of flare to something which doesn't add functionality or support just wears down the keyboard faster. It doesn't do anybody any good. Well.. unless you like brownie points from the person who probably incorrectly taught you that everything is an object.

In short, programming isn't just mindlessly tapping on the keyboard. There are a lot of design considerations to any project. I know it's cliche, but you have to look at it from every angle. Even with nowadays type-safe languages. You don't just chuck code out and expect it to work well. Sure.. it may work, but it may not be the right way to go about it. Overall, pick the language and format that is best suited for the specific job AND the environment. But no language takes away the thought behind it. If you're not thinking.. you're just typing.

88
votes

Five things I hate about Java (which, presently, is my favorite language) in no particular order.

  1. As much as I am a fan of Java Generics, there are a lot of oddities that arise from the way it was designed. As such there a myriad of annoying limitations with generics (some of which are the result of type-erasure).
  2. The way Object.clone() and the Cloneable interfaces work is totally broken.
  3. Instead of taking the high-road and making everything an object (a.la. SmallTalk), Sun wimped out created two distinct categories of data-types: Objects and primitives. As a result there are now two representations for fundamental data types and wierd curiosities such as boxing/unboxing and not being able to put primitives in a Collection.
  4. Swing is too complex. Don't get me wrong: there's a lot of cool stuff one can do with Swing but it is a great example of over-engineering.
  5. This final complaint is equally the fault of Sun and those whom have written XML libraries for Java. Java XML libraries are way too complicated. In order to simply read in an XML file, I often have to worry about what parser I am using: DOM or SAX? The APIs for each is equally confusing. Native support in the language for easily parsing/writing XML would be very nice.
  6. java.util.Date sucks. Not only is it unnecessarily complicated but all the useful methods have been deprecated (and replaced with others that increase complexity).
73
votes

Ruby has many flaws related to its speed, but I don't hate those. It also has flaws with the community evangelism going overboard, but that doesn't really bother me. These are what I hate:

  • Closures (blocks) have 4 different creation syntaxes, and none of them are optimal. The elegant syntax is incomplete and ambiguous with hashes, and the full syntax is ugly.
  • The community tends to be against real documentation, favoring ‘read the code’. I find this childish and lazy.
  • Metaprogramming abuse, particularly in libraries, makes bugs a nightmare to track down.
  • On a related note, pervasive metaprogramming makes a comprehensive IDE difficult, if not impossible, to make.
  • The way block passing to functions is done is silly. There is no reason blocks should be passed outside the parameter list, or have odd special syntax to access (yield). I am of the opinion that blocks should have been given a less ambiguous syntax (or hashes could have used different delimiters; perhaps <> rather than {}), and passing as parameters to methods should have been just like all other parameters.

    object.method(1, {|a| a.bar}, "blah")
    

    These oddities, like the block must be the last parameter passed and passing more than one block is different with longer syntax, really annoy me.

72
votes

Perl

  • Mixed use of sigils

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = $array[0]; # not @array[0], you would get the length instead
    my $four = $array->[0]; # definitely not $array[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = @$array[1,2]; # coerce to array first
    
    my $length_a = @array;
    my $length_s = @$array;
    
    my $ref_a = \@array;
    my $ref_s = $array;
    
    • For example none of these are the same:

      $array[0]   # First element of @array
      @array[0]   # Slice of only the First element of @array
      %array[0]   # Syntax error
      $array->[0] # First element of an array referenced by $array
      @array->[0] # Deprecated first element of @array
      %array->[0] # Invalid reference
      $array{0}   # Element of %array referenced by string '0'
      @array{0}   # Slice of only one element of %array referenced by string '0'
      %array{0}   # Syntax error
      $array->{0} # Element of a hash referenced by $array
      @array->{0} # Invalid reference
      %array->{0} # Deprecated Element of %array referenced by string '0'
      

    In Perl6 it is written:

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = @array[0];
    my $four = $array[0]; # $array.[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = $array[1,2];
    
    my $length_a = @array.length;
    my $length_s = $array.length;
    
    my $ref_a = @array;
    my $ref_s = $array;
    
  • Lack of true OO

    package my_object;
    # fake constructor
    sub new{ bless {}, $_[0] }
    # fake properties/attributes
    sub var_a{
      my $self = shift @_;
      $self->{'var_a'} = $_[0] if @_;
      $self->{'var_a'}
    }
    

    In Perl6 it is written:

    class Dog is Mammal {
        has $.name = "fido";
        has $.tail is rw;
        has @.legs;
        has $!brain;
        method doit ($a, $b, $c) { ... }
        ...
    }
    
  • Poorly designed regex features

    /(?=regexp)/;           # look ahead
    /(?<=fixed-regexp)/;    # look behind
    /(?!regexp)/;           # negative look ahead
    /(?<!fixed-regexp)/;    # negative look behind
    /(?>regexp)/;           # independent sub expression
    /(capture)/;            # simple capture
    /(?:don't capture)/;    # non-capturing group
    /(?<name>regexp)/;      # named capture
    /[A-Z]/;                # character class
    /[^A-Z]/;               # inverted character class
    # '-' would have to be the first or last element in
    # the character class to include it in the match
    # without escaping it
    /(?(condition)yes-regexp)/;
    /(?(condition)yes-regexp|no-regexp)/;
    /\b\s*\b/;              # almost matches Perl6's <ws>
    /(?{ print "hi\n" })/;  # run perl code
    

    In Perl6 it is written:

    / <?before pattern>  /;   # lookahead
    / <?after pattern>   /;   # lookbehind
    / regexp :: pattern  /;   # backtracking control
    / ( capture )        /;   # simple capture
    / $<name>=[ regexp ] /;   # named capture
    / [ don't capture ]  /;   # non-capturing group
    / <[A..Z]>           /;   # character class
    / <-[A..Z]>          /;   # inverted character class
    # you don't generally use '.' in a character class anyway
    / <ws>               /;   # Smart whitespace match
    / { say 'hi' }       /;   # run perl code
    
  • Lack of multiple dispatch

    sub f(   int $i ){ ... }  # err
    sub f( float $i ){ ... }  # err
    sub f($){ ... } # occasionally useful
    

    In Perl6 it is written:

    multi sub f( int $i ){ ... }
    multi sub f( num $i ){ ... }
    multi sub f( $i where $i == 0 ){ ... }
    multi sub f(     $i ){ ... } # everything else
    
  • Poor Operator overloading

    package my_object;
    use overload
      '+' => \&add,
      ...
    ;
    

    In Perl6 it is written:

    multi sub infix:<+> (Us $us, Them $them) |
                        (Them $them, Us $us) { ... }
    
57
votes

I'll do PHP as I like it at times and Python will be done way too much.

  • No namespace; everything is in a kind of very big namespace which is hell in bigger environments

  • Lack of standards when it comes to functions: array functions take a needle as a first argument, haystack as second (see array_search). String functions often take the haystack first, needle second (see strpos). Other functions just use different naming schemes: bin2hex, strtolower, cal_to_jd

    Some functions have weird return values, out of what is normal: This forces you to have a third variable declared out of nowhere while PHP could efficiently interpret an empty array as false with its type juggling. There are near no other functions doing the same.

    $var = preg_match_all('/regexp/', $str, $ret);
    echo $var; //outputs the number of matches 
    print_r($ret); //outputs the matches as an array
    
  • The language (until PHP6) does its best to respect a near-retarded backward compatibility, making it carry bad practices and functions around when not needed (see mysql_escape_string vs. mysql_real_escape_string).

  • The language evolved from a templating language to a full-backend one. This means anybody can output anything when they want, and it gets abused. You end up with template engines for a templating language...

  • It sucks at importing files. You have 4 different ways to do it (include, include_once, require, require_once), they are all slow, very slow. In fact the whole language is slow. At least, pretty slower than python (even with a framework) and RoR from what I gather.

I still like PHP, though. It's the chainsaw of web development: you want a small to medium site done real fast and be sure anybody can host it (although configurations may differ)? PHP is right there, and it's so ubiquitous it takes only 5 minutes to install a full LAMP or WAMP stack. Well, I'm going back to working with Python now...

50
votes

Here are some things I dislike about Java (which is not my favorite language):

  • Generics type erasure (i.e. no reified generics)
  • Inability to catch multiple exceptions (of different types) in a single catch block
  • Lack of destructors (finalize() is a very poor substitute)
  • No support for closures or treating functions as data (anonymous inner classes are a very verbose substitute)
  • Checked exceptions in general, or more specifically, making unrecoverable exceptions checked (e.g. SQLException)
  • No language-level support for literal collections
  • No type-inference when constructors of generic classes are called, i.e. the type parameter(s) must be repeated on both sides of the '='
40
votes

C++

  1. Template Syntax
  2. Diamond Inheritance issues
  3. The plethora/lack of standard libraries that modern languages have (though boost comes close).
  4. IOStreams
  5. The syntax used around IOStreams

Python

  1. Spaces are meaningful (sometimes)
  2. underscored keywords
  3. Limited thread support (at least currently)
  4. "self" instead of "this"
  5. Spaces are meaningful (sometimes)
37
votes

Objective-C

1) No namespaces, just manual naming conventions - I don't mind the that in terms of class separation, but I do miss being able to import all class definitions in a namespace in a single line (like import com.me.somelibrary.*).

2) Libraries still have some holes in important areas like RegEx support.

3) Property syntax is a bit clumsy, requiring three lines (in two separate files) to declare a property.

4) I like the retain/release model, but it is easier than it should be to release a reference and then accidentally make use of it later.

5) Although not really a language feature, Xcode is so intertwined with use of Objective-C I can't help thinking about that aspect... basically the autocompletion, is very iffy. It's more like a system that rewards you for finding something you want exists, and then presents it as a choice afterwards. But then I suppose I never have liked autocomplete engines.

36
votes

C++

  • Strings.
    They are not interoperable with platform strings, so you end up using std::vector half of the time. The copy policy (copy on write or deep copy) is not defined, so performance guarantees can not be given for straightforward syntax. Sometimes they rely on STL algorithms that are not very intuitive to use. Too many libraries roll their own which are unfortunately much more comfortable to use. Unless you have to combine them.

  • Variety of string representations
    Now, this is a little bit of a platform problem - but I still hope it would have been better when a less obstinate standard string class would have been available earlier. The following string representations I use frequently:

    • generic LPCTSTR,
    • LPC(W)STR allocated by CoTaskMemAlloc,
    • BSTR, _bstr _t
    • (w)string,
    • CString,
    • std::vector
    • a roll-my-own class (sigh) that adds range checking and basic operations to a (w)char * buffer of known length
  • Build model.
    I am sick to death of all the time spent muddling around with who-includes-what, forward declarations, optimizing precompiled headers and includes to keep at least incremental build times bearable, etc. It was great in the eighties, but now? There are so many hurdles to packing up a piece of code so it can be reused that even moms dog gets bored listening to me.

  • Hard to parse
    This makes external tools especially hard to write, and get right. And today, we C++ guys are lacking mostly in the tool chain. I love my C# reflection and delegates but I can live without them. Without great refactoring, I can't.

  • Threading is too hard
    Language doesn't even recognize it (by now), and the freedoms of the compiler - while great - are to painful.

  • Static and on-demand initialization Technically, I cheat here: this is another puzzle piece in the "wrap up code for reuse": It's a nightmare to get something initialized only when it is needed. The best solution to all other redist problems is throwing everything into headers, this problem says "neeener - you cannot".


Granted, a lot of that is beyond strict language scope, but IMO the entire toolchain needs to be judged and needs to evolve.

35
votes

JavaScript:

  • The Object prototype can be modified. Every single object in your program gets new properties, and something probably breaks.

  • All objects are hash maps, but it's difficult to safely use them as such. In particular, if one of your keys happens to be __proto__, you're in trouble.

  • No object closure at function reference time. In fact, no object closure at all -- instead, this is set whenever a function is called with object notation or the new operator. Results in much confusion, particularly when creating event callbacks, because this isn't set to what the programmer expects.

    • Corollary: calling a function without object notation or the new operator results in this being set equal to the global object, resulting in much breakage.
  • Addition operator overloaded to also perform string concatenation, despite the two operations being fundamentally different. Results in pain when a value you expect to be a number is in fact a string.

  • == and != operators perform type coercion. Comparisons between different types involve a list of rules that no mortal can remember in full. This is mitigated by the existence of === and !== operators.

  • Both null and undefined exist, with subtly different, yet redundant meanings. Why?

  • Weird syntax for setting up prototype chains.

  • parseInt(s) expects a C-style number, so treats values with leading zeroes as octal, etc. You can at least parseInt(s, 10) but the default behaviour is confusing.

  • No block scope.

  • Can declare the same variable more than once.

  • Can use a variable without declaring it, in which case it's global and probably breaks your program.

  • with { }.

  • Really difficult to document with JavaDoc like tools.

34
votes

Python:

  • Lack of static typing
  • Default argument handling (specifically the fact that you can change the default argument for future callers!)
  • Too many required underscores (constructors must be called __init__)
  • Lack of proper private members and functions (convention just says that most things that start with underscore are private, except for all the stuff like __getattr__ that isn't)
  • Funny syntax for printing to a file (but they're fixing that in Python 3)
32
votes

C#

  • I wish I could switch() on any type, and that case could be any expression.

  • Can't use object initializer syntax with 'readonly' fields / private set autoprops. Generally, I want language help with making immutable types.

  • Use of {} for namespace and class and method and property/indexer blocks and multi-statement blocks and array initializers. Makes it hard to figure out where you are when they're far apart or mismatched.

  • I hate writing (from x in y ... select).Z(). I don't want to have to fall back to method call syntax because the query syntax is missing something.

  • I want a do clause on query syntax, which is like foreach. But it's not really a query then.

I'm really reaching here. I think C# is fantastic, and it's hard to find much that's broken.

26
votes

PHP

  1. No debugging features if you don't control the server, and even then they kinda suck
  2. The extreme amount of bad PHP code floating around gives all PHP programmers a bad name
  3. Inconsistent function naming
  4. Inability to have a static typed variable if I want one (I'm a big fan of dynamic typing 90% of the time)
  5. REGISTER_GLOBALS is the devil
25
votes

C (OK, it's not my favorite, but it hadn't been done yet.)

  • Socket library syntax.
  • No function overloading.
  • C-style strings.
  • Buffer overruns.
  • Cryptic syntax. I don't know how many times I've looked up stuff like atoi, slapped my forehead, and shouted "Of course!"

EDIT: I could probably come up with more if I resorted to more library code (like I did with sockets, but those are particularly bad), but I already felt like I was cheating for picking on C. So many languages exist only to take the good parts of C and replace the bad that it's kind of like beating a dead horse.

24
votes

Common Lisp:

  1. Keywords are often too wordy.
  2. Library support is pitiful.
  3. Doesn't work well in OSes that want to handle memory more strictly.
  4. Doesn't have good facilities for interacting with the OS.
  5. The "loop" facility is not well defined, and sure doesn't look Lispy.
24
votes

BrainF*ck

  • Your highlight is that you're Turing complete?! I can do more in Perl regular expressions!

  • Lack of objects. C'mon, people! It's like, hello...

  • No networking libraries. All I want is to scrape a web page, GOSH.

  • No first-class functions. Congratulations — you get to commiserate with your Java friends.

  • An infinite tape for storage and nothing else. This is so anally pretentious that we might as well be writing Lisp.

23
votes

JavaScript

  1. numbers as strings - Math can be frustrating when numbers are intpreted as strings. 5 + 2 = 52? Grrr...
  2. permissions - all the best stuff requires permission from the user!
  3. screen updates - The browser must be in the steady state to update the screen. There doesn't seem to be a way to force the screen to update in the middle of a script.
  4. Slow - although Google's Chrome is nice...
  5. Browser differences make using the language a [censored].
20
votes

PHP:

  • One can never be sure that certain almost common extensions are available on all webservers.
  • tries to be everything in future ( goto, closures, ... )
  • many security risks for unexperienced users
  • more operator overloading would be nice
  • all the poor programmers that don't learn how to make it work properly, and give it a bad name

Nevertheless PHP is the (scripting) language. ;-)

18
votes

VB6

  1. Windows only.
  2. No longer supported.
  3. Arrays can start at any number, rather then all being normalized to 0.
  4. compiled applications depends on many dll's to run properly.
  5. Many complicated controls like a browser control or complicated pieces of code tend to break the IDE when you run code uncompiled, but work just fine when compiled.
18
votes

Ruby is my favourite language, here's what I don't like:

  • Green threads + blocking C libraries = giant fail
  • SO PAINFULLY SLOW
  • The standard library itself is inconsistent with its use of bang! methods
  • Module include + extend is messy.
  • "Open Classes" can't be scoped - I want to add a String#dostuff, but I don't want that to leak into all the third party libraries
  • No binary deployment packaging solution.
17
votes

Delphi:

  • IDE is a bit unstable.
  • Code insight is sometimes confused.
  • Debugging is sometimes buggy.
  • Updating several project files can be cumbersome.
  • If starting up when one or more packages are unavailable, the error message is popped several times.
16
votes

JavaScript

  • Every script is executed in a single global 'namespace'...something which you have to look out for when working with scripts from different sources

  • If a variable is used but hasnt been defined before hand, it is considered a global variable

  • Browser vendors making up standards as they please, making coding for us developers using such a beautiful language harder than it should be

  • Case-Sensitivity - considering that there is no decent IDE for developing js with compile-time checking

  • Workarounds (such as the use of hasOwnProperty method) to perform some, otherwise simple operations.

15
votes

Haskell:

  1. Space leaks from lazy evaluation.
  2. Numeric Hierarchy not constructed with regard to mathematical abstractions.
  3. Strict monadic IO can make it harder to debug.
  4. The big implementations handle I/O in ways that don't seem quite compatible with the standard. (In particular, outputting characters only outputs the low 8 bits -- and then code gets built that uses this assumption to do binary I/O. Ick.)
  5. Associativity of ($) operator could be changed to make some expressions prettier.

Most of these don't rise to the level of hate, and there are people trying to fix or construct solid workarounds for each of these.

Edit: There's been some confusion about point 5. In particular some people seem to think I meant the order of arguments, which I don't. Rather than explaining what I meant, I'll just point people to the following link, http://hackage.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity , which expresses it well.