Alex Rivera | Logout

What are five things you hate about your favorite language?

Asked 2008-11-11T22:14:43.663
401

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 progra

Edit
Report

27 Answers

215

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)?
answered 2008-11-13T13:38:32.870
73

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.

answered 2008-11-11T23:29:13.840
25

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.

answered 2008-11-11T22:38:47.593
24

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.

answered 2010-05-26T06:33:28.197
23

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].
answered 2008-11-11T23:44:18.833
18

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.
answered 2008-11-12T03:54:41.697
16

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.

answered 2008-12-07T15:19:00.240
15

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.

answered 2008-11-12T01:25:07.320
6

My language du jour is Java. Here is what I hate about it:

5.) Lack of pointers
4.) Exception catching
3.) The Boolean type
2.) BigDecimal type
1.) C# fanboys and Java fanboys

Boolean can be null. I find this counterintuitive.

BigDecimal is a library and not a language feature. My annoyance with BigDecimal and Exception catching stems mainly from writing test classes that have to jump through a bunch of hoops to get actual work done. I should clarify I'm annoyed by these things, I'm not about to lobby for changes.

answered 2008-11-11T22:24:56.357
6

Groovy/Grails

  1. Duck-Typing
  2. Convention over Configuration, assuming you know the Convention
  3. Everything you hate about Spring
  4. Everything you hate about Hibernate
  5. [Groovy] common operations across collections aren't (but recent releases improve this)
answered 2008-11-11T22:40:53.140
6

ColdFusion

  1. Compile Time for large Flash Forms.
  2. Dynamic Variable Types (Sometimes I hate them.)
  3. Lack of features in CFScript.
  4. CFTable (Can never get it to display right).
  5. The lack of chart types left out of CFChart.
  6. Complete lack of NTLM support (enterprise ready - yeah right)
  7. Moronic var scoping in CFCs
  8. No concept of a true NULL - your variable just vanishes!
  9. No way to test for the existence of certain things (like scopes, just members inside them)
answered 2008-11-11T23:34:47.883
6

C#

It's a great language, especially with LINQ, but generics support is poor compared to C++. It had so much potential, but the current implementation is only useful for strongly-typed collections and similar trivial things. Some examples of where it falls down:

  • A generic argument cannot be restricted to enums (only classes or structs).
  • A generic argument cannot be a static class. Why? This seems like a completely artifical restriction.
  • You cannot specify that a generic type must have a constructor with a certain signature because you cannot have constructors on interfaces. Why not? It's just another method with the special name ".ctor".
  • Similarly, you cannot specify that a generic type must have a static method, because those also cannot be declared on interface. Something like static T Parse(string s) would often come in useful.
  • The compiler is too eager in prohibiting some casts which the programmer knows would actually work, so they require uglyness like (TheRealType)(object)value
  • No covariance, eg. IList<string> cannot be converted to IList<object>, even though string[] can be converted to object[]. (Microsoft might be fixing this in C# 4.0, though.)
answered 2009-01-04T01:33:35.633
5

Perl 5 In order from most annoying to least.

1.) Backwards compatibility police. Yes backcompat is a strength but Perl 5 takes it too far. Now we don't really even get new features in our language without having to enable them explicitly. I'm much prefer the inverse, if a new feature causes a problem let me disable it or enforce old behavior. e.g. perl 5.10 added say I'd rather have no feature 'say' if I have my own say implemented than have to put use feature 'say'; or use 5.010; also if 5.8 worked but 5.10 didn't. I'd rather have use 5.008; to restrict my code to only use features available up to and including 5.8 if no use version; was defined then it should be defaulted to whatever version you're running, and a recommended practice of not to restrict it unless you have to.

2.) Excessive Boilerplate.

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use autodie;
use English '-no_match_vars';
use 5.010;
package Package::Name;

BEGIN {
    Package::Name::VERSION = 0.1;
}

sub somesub {
    my $self = shift;
    my ( $param1, $param2 ) = @_;
}
1;

now you may start coding. This won't change due to #1. of course there are shortcuts to this stuff like use common::sense; or use modern::perl; which will shorten the above and you may want some slightly different modules or pragma's. But because of #1 we'll never be able to reduce it to.

#!/usr/bin/perl
package Package::Name 0.01;

sub somesub ( $param1, $param2 ) {
}

some modules are helping with this, and there is the new package version in 5.0.12 which allows exactly that syntax though I think it requires use 5.012; first, and Method::Signatures but it'll never be completely resolved, (in language).

3.) Poor variable choices

slurp

answered 2010-07-16T03:37:30.217
4

Self

  • No real code browser, instead hundreds of small windows flying around.
  • Only a research project, not stable enough, no active community.
  • No decently fast version for Linux or Windows. Only Mac OS X.
  • No support of standard keyboard commands.
  • Oh! And the documentation on writing native plugins is so outdated!
answered 2009-01-08T15:09:33.083
2

C++:

  • Lack of symbolic import.
  • Over-obsession with C compatibility.
  • Ridiculously complicated preprocessor.
  • Template errors are nearly incomprehensible.
  • No garbage collection.
answered 2009-01-03T03:08:09.563
2

C#

  • Lack of multiple dispatch based on the runtime type of the method arguments. dynamic should solve most of this, but it hasn't been released yet.
  • Interface implementation is declarative not structural. I really like the way Google's Go language is doing types
  • Making asynchronous method calls is really bulky (and I'm pretty sure all threads are OS threads, not lightweight threads)
  • No macro system. I'm not talking about C-style macros here; I'm talking LISP/Scheme style macros
  • Operators are static methods and their signatures are overly constrained (and you can't create new ones).

  • answered 2010-03-22T17:58:56.880
    2

    Python, again:

    1. No switch keyword. And NO, dictionary is not a replacement for it. Not even a bunch of elif statements.

    2. Inconsistent line break handling. Why can I do:

       test = (1,
               2,
               3)
      

      And not:

      from itertools import cycle,
                            islice,
                            izip
      

      Why can't I do:

      if stuff \
         and foo \
         or bar:
          return "Formated string with %(arg)s" % \
                 {'arg': "bloody slash"}
      

      without using slashes?

    3. There is not one obvious and only one way to do it. Python fails on its motto just like Java failed on "Write once run anywhere".

      # what somebody from an another language would do
      if not test.has_key('foo'):
          test['foo'] = 0
      n = test['foo'] = test['foo'] + 1
      

      vs

      # what an agnostic beginer would do 
      try:
          test['foo'] += 1
      except KeyError:
          test['foo'] = 1
      n = test['foo']
      

      vs

      # what you end up after looking for dictionary default value in the python doc
      test.setdefault('foo', 0)
      n = test['foo'] = test['foo'] + 1
      

      vs

      # what I would do
      n = test['foo'] = test.get('foo', 0) + 1
      

      And the worst is that they don't do exactly the same thing. There are subtle differences.

    4. Choice between spaces and tabs. There should be no choice. Pick on, set it in stone and stop fighting.

    5. Why can you do that:

      test = {}
      test['foo'] = 0
      

      but not:

      test = []
      test[] = 0
      

    P.S: " ".join(l) is fine people. Stop complaining about it, it's not obvious but with the iterator pattern in mind, it's just the right way to do it.

    answered 2010-05-23T13:27:45.457
    2

    Python

    1. There is no Django for Python 3.
    2. Static typing. Yes, dynamic typing is great thing, but sometimes I do want to make it static.
    3. Proper unicode support (fixed in Python 3)
    4. Construtors naming. I hate all this underscores __in__ my code.
    5. Threads are not very efficient
    answered 2010-05-26T01:53:17.677
    1

    I can add another one for Python:

    Given a list l = [l1, l2, ..., ln], then repr(l) = [repr(l1), repr(l2), ..., repr(ln)], but str(l) != [str(l1), str(l2), ..., str(ln)] (str(l) = repr(l)). This was decided because there could be obscure entries in the list like l = ["foo], [bar,", "],["] and str(l) would return "[foo], [bar, ], []" which "could confuse users". However, this makes str impossible to use for just dumping data, since list kills the "just dump data in a readable format". Augh!

    answered 2008-12-07T02:33:46.680
    1

    C#

    The number one all time pet hate of C# has to be:

    (1) Events have strong references to all listeners thus preventing garbage collection of anything that listens to an event. If you want to see the problems this has caused just search on the net for all the people who have tried to solve the problem by creating some sort of "weak referenced event handler".

    (2) Needing to check if an event equals null before you call it seems like something that should be handled by the language.

    (3) The XML serializer has no way of reading/writing comments in an XML file. Not great in an environment where XML files are modified both by hand and by the tool written in C#. Can be worked around by just using a raw XmlDocument, but would be nicer to be able to abstract that away to a class.

    (4) The build process doesn't let you directly access things like xsd files, instead you need an intermediate step where you create a C# partial class. This also causes issues with XAML files where you need to rebuild twice sometimes to get changes to flow through properly.

    (5) No support for CPU intrinsics like MMX and SSE 1,2,3,4 and thus these valuable CPU features go unutilised when running C# apps.

    Others that didn't make my top 5:

    (6) Can't tag fields as properties, all properties have to be explicitly implemented from the get go:

    E.g. currently has:

    public class MyClass {
        private int someInt;
    
        public int SomeInt {
            get {
                    return someInt;
            }
            set {
                    someInt = value;
            }
        }
    }
    

    Would like

    public class MyClass {
        [IsProperty(public, get, set)]
        private int someInt;
    }
    

    (7) No support for multiple return values e.g:

    public int, string, d
    answered 2010-01-02T08:27:14.147
    1

    Python 3

    • both tabs & spaces allowed for indentation
      And you'd think people learn from the past (Makefile). Just pick spaces and forbid tabs. YAML got it right.
    • lack of popular third-party libraries
      The standard library is great, but a lot of what makes Python 2 so powerful lies in the third-party realm. Python 2 got this right :-).
    • IEEE floats
      Floating points in programming languages are confusing because they're different from the way we use them in math. Instead, the number operations should be viewed as expressions that are only converted to a decimal point format when needed (i.e. printing to a screen). Maple and Mathematica did this right I think.
    • the character set for identifiers is too restricted
      list.empty? is better than list.is_empty or even len(list) != 0. Similarly, process.kill! would be better than process.kill. Ruby and lisp got this right.
    • when calling a function you must always write parentheses
      It would be nice if we could omit them in unambiguous cases. How is it again? dict.items or dict.items()? Ruby got this one right, too.
    answered 2010-05-25T22:06:21.207
    1

    Python:

    1. No standard GUI toolkit (the community goes round and round about this but never seems to settle on anything).

    2. The evolution of tools and methods to distribute and install Python apps and libraries has been, well, rocky. (Although lately this seems to be moving closer to getting fixed.)

    3. CPython is still slow as interpreters go (although PyPy is looking pretty good these days, if it becomes the "standard" Python this problem goes away).

    4. You can't subclass built-in classes (e.g., list and dict) without overriding a lot of methods, even if all you want to do is a simple hook into an event (e.g., to hook into an item being added to or removed from the list, you need to override delitem, append, extend, insert, pop, and remove--there's no subclassable "change" event notification, nor any "protected" methods that factor out common code used by all the above methods).

    5. Up until virtualenv was invented, keeping separate Python environments for different purposes on one machine was a real pain.

    answered 2010-05-26T00:03:02.190
    0

    Python

    Ones that I just don't understand ...

    • math.ceil() and math.floor() return floats, not integers (probably to avoid an integer overflow in the underlying C function - but why not cast to a Python long?)
    • len() is a function not a method
    • reload() is very limited, does not reload a module 9 times out of 10, only reloads an imported label if it is a module - i.e. cannot do from bar import foo; reload(foo) if foo is not itself a module
    • Mutable default arguments have a single reference (why not a new instance each function call?!)
    • All these underscored variables - if they are so private, how come we see inbuilt ones so much in code? Get a namespace!
    • Strings are not mutable - maybe there is a good reason for this but I have come across many situations where I would like to tweak one particular character ...

    Ones that make sense based on the implementation but are annoying ...

    • array.sort() does not return an array (I suppose it happens in-place)
    • List/generator comprehensions don't define a new scope (Is just syntactic sugar for a for loop, right?)

    and a couple that are fixed in Python 3

    • Integer division by default
    • global can only refer to the top level namespace
    answered 2010-02-07T21:23:28.320
    0

    Lua

    • If you do foo.bar(1,2) then 'self' is nil inside the bar method. You must remember to do foo:bar(1,2) instead. I'd rather have that switched ('self' should be defined by default unless you use the ':' operator, or you call a function that isn't a method).
    • Variables are global by default. I'd rather ditch the 'local' keyword and have a 'global' one instead.
    • Undeclared variables are assigned the nil. I'd rather receive an error message. You can sidestep this by manipulating the global env's metatable, but I'd rather have it implemented by default and be able to deactivate it.
    • Multiple returned values on parameters are not handled very nicely. Say you have a function foo() that returns 1,2,3 (three values) and bar() returns 4,5 (two values). If you do print(foo(),bar()) you will get "1,4,5" ... only the "last" tuple is expanded on calls.
    • The # (table length) operator only works in tables indexed with continuous integers. If your table isn't like that and you want to know how many elements does it have, you need to either parse it with a loop, or update a counter each time you insert/remove an element from it.
    answered 2010-05-04T09:39:28.760
    0

    C#

    • Cannot create a reference (var &t = struct)
    • No local scope destructors (IDispose comes close but its not the same)
    • ToString, i almost dislike that every object has it but it turns out i dislike everything using it like string.format does. I rather have things that accepts a certain type (like ints, floats, text, chars only). So instead of passing in any object i need to pass in something with a implicit typecast or interface. I ended up writing something like this to safely escape text for html which worked great.
    • Cannot use a virtual typecast (blah)obj; does not work if obj does not inherit/has an interface of blah. Simple workaround is to supply an interface with a convert function.
    • Has no local creation. Instead of writing var o = new Item(); i would like to write (something like) Item o() (with an automatic dispose if it has one).
    answered 2010-05-08T21:37:48.807
    0

    Python:

    • no delimiter signaling the end of blocks introduces ambiguity such that automatic indentation will not work with poorly formatted code.
    • no macros (decorators don't count)
    • no library auto-fetch like haskell's cabal, or perl's CPAN
    • can't declare variables const (yeah it's possible to role your own but ... )
    • meta-programming is nerfed
    • almost forgot the Global Interpreter Lock
    answered 2010-05-26T05:31:06.500
    -1

    Python

    • slow
    • I finally got used to the print statement, and now there's this print function??? (py3k)
    • never got py2exe or cxFreeze working
    • not standardized (minor nitpicking)
    • recursion depth only 100 (iirc)
    answered 2009-02-19T06:48:55.353

    Your Answer