This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here.
More info: http://stackoverflow.com/faq
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 [1]" 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.
English:
Add more in the comments if you've got 'em.
Wow, I'm surprised that SQL hasn't made it up here yet. Guess that means nobody loves it :)
...And a few bonus reasons to hate it, at no extra charge
SELECT col1,
col2,
col3,
col4,
col5,
from
- xenoterracide
Five things I hate about Java:
I know, I should check out Scala.
JavaScript:
It's fugly
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
'+' is an absurd choice of operator for concatenation in a weakly-typed language. Were they trying to scare off the noobs?
It's a cross-browser compatibility minefield (never mind if it's even turned on or not)
It's generally untrusted - associated with scummery such as blocking the back button, pop-ups that never die, etc.
Did I mention that it's fugly?
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 :)
char
s, cast anything to anything via void* pointers, etc.) It is statically typed instead of dynamically typed, and also requires explicit typing instead of type inference, but those are unrelated to strong v/s weak typing. [Random examples: Python has implicit dynamic strong typing, Haskell has (optionally explicit) static strong typing, Java has explicit (mostly static) strong typing, C has explicit static (relatively weak) typing.] "Strongly typed" and "weakly typed" are actually not well-defined. - ShreevatsaR
'3'+'2'='32'
, '3'-'2'=1
. - Thomas Ahle
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 hidiously 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.
null
instead of an object than trying to call a method results in a Fatal Error. Could you imagine trying to build a reliable Java program if the NullPointerException instantly crashed your program and there was no way to catch the exception? - too much php
substr($string, 0, strchr($string, '|'))
. - Billy ONeal
C++
C# / .NET:
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.Those were off the top of my head - ask me tomorrow and I'll come up with a different 5 :)
List<T>
's default behavoiur (specifically, I wanted to add events for Add, Remove, etc). So away I go and derive from List<T>
which worked, but then I couldn't actually do anything from there... - Matthew Scharley
C
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.
strcat
? Try using getcwd()
or readlink()
correctly. - Joey Adams
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.
for
loops and goto
are bad. - reinierpost
Five things I hate about Java (which, presently, is my favorite language) in no particular order.
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:
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.
end
S! - John Douthat
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
[1]:
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
[2]:
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
[3]:
/ <?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
[4]:
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
[5]:
multi sub infix:<+> (Us $us, Them $them) |
(Them $them, Us $us) { ... }
{COBOL, microcode, VB}
? - Longpoke
sub foo { +(1..5) }
returns 5 elements when called in list context, but ''
when called in scalar context. That's just not right. - fennec
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 [1]). String functions often take the haystack first, needle second (see strpos [2]). Other functions just use different naming schemes: bin2hex [3], strtolower [4], cal_to_jd [5]
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 [6] vs. mysql_real_escape_string [7]).
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...
[1] http://ca3.php.net/manual/en/function.array-search.phpIrregular verbs. All the common ones are irregular, too. First person of "ir" is "voy"?? That does not follow the "o" "as" "a" "an" "amos" rule at all.
What is up with the subjunctive? "El que tenga sed" - he who is thirsty, hypothetically speaking. Do we really need to conjugate this differently?
Venezuelans. How come Venezuelans are always leaving out the s in the middle of words like "mosca?" Come on people, it's right there in the spelling. I thought your language was phonetic.
Vocabulary. "Peel" and "rind" and "skin" and "husk" and "shell" are all "cascara" to you? Just "the outside part, who cares about the texture or edibility?" Sloppy.
Corazón. OK, so this is not so much linguistic as cultural. Why do all Spanish songs contain the word "corazón" (heart)? I mean seriously, even in Spanish 1101 I could understand half the song lyrics, because I knew this one word. You've got to come up with some new subject matter. Somebody start translating They Might Be Giants into Spanish - they sing about all kinds of weird stuff.
Here are some things I dislike about Java (which is not my favorite language):
except
clause. - Don O'Donnell
final Ref<Integer>
into an anon function and do myRef.set( myRef.get().intValue() + current.amount()
. Now I should go try that to make sure it actually works. - KitsuneYMG
C++
Python
import this
- crgwbr
if(condA)foo();elseif(condC)bar();
- badp
if x and y:
and if a and y:
and if a and\ny:
are perfectly equivalent. - badp
print 'hurr'; print 'durr'
. Although I wish I could make anonymous functions/classes, which is natural with braces, but hardly any big deal, plus you can use lambdas a lot of the times for this. - Longpoke
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.
YES/NO
for booleans is a bad thing? And more importantly, are you saying Named Parameters are a bad thing?? I can understand bools, but named params are possibly one of ObjC's best features (in terms of readability). - jbrennan
retain
and you don't want to leak memory. - Frank Schmitt
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:
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.
std::string
? maybe reading a good documentation and/or tutorial on std::vector
(and why you're not supposed to use std::string
in places where it was never designed for) could clear that up for you. - nebukadnezzar
std::string
if I can't use it half of the time? (C++0x at least fixes that, but I'm still stuck with dozens of libraries that use different string representations). - peterchen
but why do we have to bother with them (inclusion guards)
- because C++ doesn't have modules. How "standard" is a std::string if I can't use it half of the time?
- I think that depends on the way you use std::string
. The string class allows you to access the string data as const char*
via std::string::c_str
, which already makes std::string
perfectly compatible with every class/function that also takes const char*
arguments. - nebukadnezzar
exactly my complaint: the build model is antique
- I see how you mean it now. But seeing how it simply is not a module system, you will have to live with inclusion guards. That is, I doubt that there will ever be a module system for C++. I'm still not sure what you mean about std::string - if any function takes a const char*
argument, you just pass std::string::c_str
along, and be done with it. - nebukadnezzar
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.
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.
null
and undefined
: sometimes you really want to know if the variable has been assigned a value or not. Since null is a value, undefined is the only way to tell. Granted, the only time I've found this useful was for creating getter/setter functions. - Zach
for
as a variable name. - nickf
"for"
is valid as a hash key. __proto__
is not a reserved word. Special string values that do not work as expected when used as hash keys violate reasonable expectations about how associative arrays work in any language. They also violate the EcmaScript spec. - Daniel Cassidy
newline may or may not end a statement depending on context
is one in my top 5 list - reinierpost
Python:
__init__
)__getattr__
that isn't)print
ing to a file (but they're fixing that in Python 3)None
defaults or something like that and then check for them in the body. Annoying, but once you're aware of it, not that big a deal. - dwf
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.
switch
on any elementary type? case
as any expression? Sounds like VB.Net is better :) msdn.microsoft.com/en-us/library/cy37t14y(VS.71).aspx - MarkJ
switch
on any type. Not just int
, enum
, string
. - Jay Bazuzi
PHP
C (OK, it's not my favorite, but it hadn't been done yet.)
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.
char *(*(**foo [][8])())[];
Not to mention the standard library is a useless piece of crap. "No function overloading" is also a pretty bad point... C is meant to be a portable assembler, not an OO language. - Longpoke
*x
, while in x86, it's [x]
. Now imagine if you could expand that how Ollydbg does. double dereference would be [[x]]
, while in C it's **x
. call deref would be [x]()
, while in C it would be (*x)()
. func pointer declaration: [int function(int a, [float] b)] x
, vs int (*x)(int a, float* b) x
. clearly the former is superior. heck anything is better than C syntax. - Longpoke
Common Lisp:
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.
JavaScript
isNaN(undefined) == true
that makes perfect sense, undefined is NotaNumber you wouldn't expect isNaN('string') == true
to return false, would you? - Javier Parra
var == NaN
it tests if ` typeof var != number` - Javier Parra
PHP:
Nevertheless PHP is the (scripting) language. ;-)
VB6
}
, Pascal's/Ruby's end
, or VB's End If
? (or Wend
? har har har.) - badp
Ruby is my favourite language, here's what I don't like:
Delphi:
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.
Haskell:
($)
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.
$
. An infix right-associative identity function is the best thing ever. - Norman Ramsey
f $ x y z $ quux quaffle
becomes f (x y z) (quux quaffle)
, the utility of the right-associative $ is still present, because if you wanted the other meaning for that you can use f . x y z $ quux quaffle
. - Edward Kmett
Inspired by hilarious (yet to the fact) answer [1] on English. I feel like posting something not as original as fun facts.
lucky
. - rockacola
I know I'm late to the party, but hate is timeless!
Java
Smalltalk
I love this language, but there are some things that bug me for years!
table.concat(..)
. - kaizer.se
continue
statement when I'm using Lua. Pretty much entirely because I find less indentation levels more aesthetically pleasing. - David
VB.NET
AndAlso
/ OrElse
and And
/ Or
seems backwards. Perhaps they should be switched.When
can only be used for exception catching. The ability to do a When
conditional would be nice for some other things. Not <obj> Is Nothing
. Yes, this has been remedied by IsNot
, but for some reason I see the Not Is
being used too often. (I see it much more frequently with devs who speak english as a second language, does it make better sense from that angle?)()
on ToString()
and most functions. (Leads to sloppy coding habits)_
when breaking a line.UpperBound
and not by capacity. "Dim arr(2) as String"
will actually hold 3 elements. =
be a comparison and assignment operator. 1-3: There is no one obvious choice of packaging/build/documenting system (such as Perl's cpan
, POD
or Ruby's gem
, rake
, rdoc
).
4: Python 3.0 is incompatible enough to require two source branches (2.x and 3.x) for every single Python project. But Python 3.0 is not incompatible enough to justify it. Most py3k advantages are too subtle.
5: Jython, IronPython, CPython are incompatible.
Objective Caml
Non-concurrent garbage collector. I can write multi-threaded programs all day long, but they're only ever going to get one of my eight cores at a time. This makes me sad.
No type classes (or their moral equivalent). There's Furuse-san's GCaml [1], but it's A) not quite as good as type classes, and B) not in the INRIA distribution.
Badly in need of a Cocoa bridge. Seriously. If I wrote more code with actual interfaces to DNA-based life forms, then I'd probably break down and write the damned thing myself. Why hasn't anybody else done this yet?
Functors are abominable. Seriously, modules ought to be first-class values. There should be only one kind of function. Read Montagu and Rémy [2] before you flame me for this.
Should use LLVM for its back-end. Who do I have to murder to get OCaml to compile for my stupid little ARM6 core?
So yeah, I have some issues. I still love the language to pieces. It's totally awesome.
[1] http://web.yl.is.s.u-tokyo.ac.jp/~furuse/gcaml/VBA (including MS Office IDE):
1) Poor Documentation
2) Poor Error Messages
3) Inadequate Array Manipulation Routines
4) Having to repeat types for DIM statements
5) Won't print in color (have to buy 3rd party addin)
Delphi (aka Object Pascal), I'll talk about the native version, not .NET.
try except finally end;
Object creation too explicit:
var obj: TMyObject;
...
obj := TMyObject.Create;
try
...
finally
obj.Free;
end;
Instead something like
auto obj: TMyObject; // compiler adds the default constructor call and the destructor call in a try/finally block.
i.ToString
instead of IntToStr(i)
.My own top-5 "what do I really hate in c++":
[5] Automatic generation of constructors, destructor and assignment operator. Man, whenever I don't declare something in the class, it means I DON'T NEED IT, not I FORGOT IT. Do you, compilers, hear me?!
[4] Template syntax. Oh, do I really need to type all these "<" and ">", whenever I decide to extract definitions from the class body?
[3] Strings. Jeez, I am fed up with "const char*", I have to handle NULL situations, I have to waste O(N) to get its length, I have to allocate a buffer for concat operations.
[2] Macroprocessing. Whenever I do not understand, what is going on with my compiler, I start looking for a macro.
[1] Operator overloading. I see the code "A + B * C" and I cannot say a word what this code is about, until I see the actual types of A, B and C.
C
snprintf
. Too hard to create a format string with sprintf
, then use that to create a string with sprintf
again, in a safe way.HAS_NO_SIDE_EFFECTS
in different places. Why can't I just grab the function, switch over the compiler type, and then insert it at the right place by a macro call?C++
for(map<string, int>::const_iterator it = mymap.begin(); it != mymap.end(); ++it)
.foo(bar, &baz)
can and can't modify.*
there in front of the name. - progo
Lua:
global
keyword, not vice versa.if (type(var) == "string") then stuff() end
is a pain.PHP:
$function($arg);
but that doesn't count.C/C++:
Ruby:
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:
static T Parse(string s)
would often come in useful.(TheRealType)(object)value
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.)Python.
Although the weird way python deals with scope has been mentioned, the worst consequence of it, I feel, is that this is valid:
import random
def myFunction():
if random.choice(True, False):
myString = "blah blah blah"
print myString
That is, inside the if block is the same scope as the rest of the function, meaning that variable declaration can occur inside condional branches, and be accessed outside of them. Most languages will either prevent you doing this, or at least offer you some kind of strict mode.
This function will sometimes succeed, and sometimes throw an exception. Although this is a contrived example, this could lead to some subtle problems.
myString
needs to be declared/initialized outside of the if
scope in order to exist outside of that scope? - Don O'Donnell
myString
is obviously a string, for most use cases it would be safer to initialize it to the nul string, '', rather than None
. - Don O'Donnell
Haskell:
head
and tail
can invoke error
and boot you out to IO
.fail
from Monad
- bring back MonadZero
.Num
class - (+)
should have been in AdditiveGroup
or similar.Monad
is not an Applicative
.ActionScript / AS3
Otherwise it's actually a good language - much better than JavaScript, contrary to popular belief, and a million times better than something like PHP.
JavaScript
Function object syntax:
f = new Function( "foo", "bar", "return foo+bar;" );
(It takes n arguments, the first n-1 are arguments for the function, then nth is the actual function, in string form. Which is just silly.)
Function arguments can be repeated.
f = new Function( "foo", "foo", "return foo;" );
The last repetition is the only one ever used, though:
f( "bye", "hi" ) // returns "hi"
f( "hi" ) // returns undefined
E4X should just die. My users are always complaining that it doesn't work the way they think it will. Let's face it, when you need a page and a half of psuedocode for a setter, it's time to rethink things.
A standard notion of stdin/stdout/stderr (and files!) would be nice.
null != undefined
It's irritating to have to handle them both. Sometimes it's useful, but most languages manage to limp along fine with one.
Python
__init__
sys.modules[__name__]
)self
in the method, there is no other way to distinguish a method from a function other than context otherwise. I suppose met
could be made a keyword tho ... - Brendan
Not that I hate my mother tongue but a couple of points that humour me.
Spelling! That is, English spelling is revenge for German grammar!
Oh, and different sounds for the same spelling! Cough, bough, through, rough, thorough, thought, and hiccough.
This is why ghoti spells fish!
Groovy/Grails
Python:
if
return? ~~~ #4: Use full fledged functions instead. You can also nest them. ~~~ #5 Not being able to insert operators in variable names sounds like a good idea to me... unless you believe a = 2; b = 3; c = b-a
should raise a NameError
? ;) - badp
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.
Here's some more for Perl 5, from the perspective of someone who's created a lot of Perl modules, and in particular worked on Moose [1].
The horrible brokenness that is overloading and tied variables. Both of these features are a failed attempt to allow transparent extension to the built-in types.
They both fail in various ways, and require module authors like myself to either implement horrible hacks to support them, or to say "never pass an overloaded object to the foo() method". Neither alternative is really acceptable.
Lack of proper hooks into the compilation process and the meta-model. Moose in general, and role usage in particular, could be made much safer if the Perl core allowed us to affect the compilation process via a sane API that allowed us to hook into the meta-model (packages, classes, etc.)
Lack of named parameters built into the language. Instead, everyone reinvents this. It's annoying.
Similarly, lack of optional types. I don't want a static language, but the ability to specify types and constraints, particularly on function/method parameters, would be great. Perl 6 gets this right. Types are optional, but very rich, and there's no fundamental difference between built-in and user-defined types.
The backwards compatibility police. This is more of a cultural issue. A number of the above issues can never really be fixed, since Perl 5 has a very strong commitment to backwards compatibility. So even if something were to be added that effectively replaced the current ball of shit that is tie and overloading, those features will never be removed. Of course, backwards compatibility is also one of Perl 5's greatest strengths.
Bonus hate: Perl's built-in exception mechanism is a joke. The fact that exceptions may be a string or object makes for an eternity of fiddly exception-catching code, and the lack of a catch in the language syntax is the wart on the wart.
Scala is my favourite language. Five things to hate? Easy:
Takes a long time to learn properly. I know you can write Scala as a 'better java'. That is what we used to say about C++ and C too. I agree this is an inevitable consequence of the deep ideas in the language. But still ...
Methods vs. Functions: def f(x: Int) = x*x
defines a method f, not a function f. Methods are not functions despite a lot of early Scala tutorial material blurring the distinction. The language tries to blur it too because if you supply a method in some places where a function is expected it is accepted. Do we have to have both methods and functions? Yes it is fundamental. But it was initially confusing to me.
Composing classes or objects from mixins in the 'cake' pattern is prone to NPE's. e.g. trait X { val host: String; val url = "http://" + host }
is a mixin that will NPE on instantiation, or not, depending on its position in the class declaration. The compiler could tell you if it will fail but doesn't. (In 2.7 anyway.) It is hard to diagnose the problem in complex inheritance graphs.
Arrays in 2.8 rely on implicits to mesh with the main scala collection types. But implicits are not applied everywhere. An Array
can be supplied where a Seq
is expected. But an Option[Array]
cannot be supplied where an Option[Seq]
is expected. I know there are no completely 'right' ways to handle java Arrays.
Type erasure. Enough said.
My native language... Though it can sound even more beautiful than Klingon it's a grammar hell...
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 a file
#!/usr/bin/perl
use strict;
use warnings;
open my $fh, "< foo" or die $!;
local $/; # enable localized slurp mode
my $content = <$fh>;
close $fh;
wtf is $!
and $/
? rewrite to be legible.
#!/usr/bin/perl
use strict;
use warnings;
use English '-no_match_vars';
open my $fh, "< foo" or die $ERRNO;
local $INPUT_RECORD_SEPARATOR; # enable localized slurp mode
my $content = <$fh>;
close $fh;
and lest not forget that the '-no_match_vars'
must be there if you don't want to take a performance hit.
How 'bout no direct way to create an anonymous scalar?
#!/usr/bin/perl
my $scalar_ref = \do{ my $anon_scalar };
couldn't they have come up with something?
#!/usr/bin/perl
my $scalar_ref = <>;
oh and how about how perl is thread unfriendly because all the variables (including special ones) are global by default. At least now you can use my $_;
to lexical scope that and use local
on the others.
4.) really ugly syntax
MooseX::Declare is a much nicer syntax. Also I wish for -> to be replaced with . (personal preference doesn't matter much)
5.) Too much TIMTOWTDI or Too many best practices Seems like you have to read 3-5 books just to figure out all of how you should be doing things.
6.) Previous (no longer applies). Un-sane releases. 5.10.0 had features 5.10.1 had features no set time 'till the next release. Now it's yearly feature releases with quarterly updates.
7.) Ivory Tower perspective. community problem, seems to be a large number of devs who want high barriers to entry and thinks it's ok to treat n00bs ( or really anyone who disagrees with them ) disrespectfully.
8.) Insane Version Numbers/Strings Perl has floating point version numbers and they're ugly. Oh and the dev's don't know that not all downstream deals with version comparison the same way. Not really a language problem
0.012 # simple
5.012001 # semantic
4.101900 # time based + version (for multiple versions in a day)
0.035_002 # prerelease
all valid versions in perl.. can't we just use like...
0.12 # simple
5.12.1 # semantic
20100713 # time based (just use the date and be careful not to need to release more than 1 a day)
0.35-beta2 # prerelease
addition
9.) No obvious way to reinstall all XS modules after an upgrade
use feature
, next release use version
, and then after that it'd be just available. I'd be fine. - xenoterracide
5.8
why wouldn't it be good enough to put use 5.008;
at the top if that meant no features from future versions would work after that (unless explicitly imported). - xenoterracide
Python (3.1)
T if C else F
syntax for conditional statements.bytes
literals look too much like str
literals. We should have had something like x'414243'
instead of b'ABC'
.str
is UTF-16 on some platforms and UTF-32 on others. (Although at least it's an improvement over 2.x strings.)numpy.array
.Python:
You usually have the entry point of the program at the end of the file.
(Because if it calls any function defined in the module, it has to occur after those functions in the sources.)
I hate it when you have to spend time looking for the entry point of a program, so I always have a simple main.py
file with:
def main():
...
if __name__ == '__main__':
main()
When an exception is raised, it can only be catched by the main thread. Or something like that.
Destructors are quite useless, because when written in Python they may break garbage collection IIRC.
I've never figured out how relative imports work in Python 2.
I'd like to see more collections in the standard library. For example: linked lists, thread-safe collections, ...
I have a book exploring all sorts of projects in SNOBOL [1]. The first chapter explores the history and culture around SNOBOL programming and language and spends some time making the argument that a good programmer likes a language not because of its flaws but in in spite of them.
My favourite language is Icon [2]/ Unicon [3]. But there are still things that annoy me about it:
explode()
and implode()
.F#
Type inference is limited.
It propagates forward only.
F# won't try to infer an object type based on the methods and properties used: you'll get "lookup of indeterminate object type" errors when it doesn't have a clue.
One cannot mix floats and ints: 1 + 2.3 is a type error.
It's a little awkward to have to create a builder object in order to define a monad or computation expression. In Haskell or Scala, you can define the monad operations directly on the monadic object.
Though the #light syntax is preferred, the indentation rules are sometimes not very intuitive or become cumbersome.
C++
The inconsistencies in the libraries related to char* and std::string. All C++ libs should take std::strings.
Characters are not bytes with respect to iostream. I do a lot of byte-oriented work. Having a "byte" type and a "character" type would significantly make it simpler. That, too, would permit scaling to Unicode somewhat easier.
Bit operations should be easy on a value. I should be able to access and set the n'th bit of a value without playing AND/OR dancing.
The lack of a standardized interface for GUIs. This is where Microsoft has really been able to position themselves well with C#. A standard interface binding that OS makers provide would go really far for my work.
PHP
Ex:
You must type:
<?php
if($x == NULL)
{
?>
<p><?= $x . ' is null' ?></p>
<?php
}
?>
(not sure why SO changed #5 to #1 again but whatever)
<p><?=$x?> is null</p>
. Also, you can do <?php if (...) : ?> [HTML] <?php endif; ?>
which is a bit more readable. - DisgruntledGoat
C:
Lisp:
Emacs Lisp
[1] Of course, one of the beautiful things about Lisp is that it's not hard to fix these things in your own code with a one-liner. Still it irks me that it's not built in.
Good question; I'm a bit embarrassed that I couldn't come up with better things to hate, but honestly, your honor, there is not much to hate.
#'(lambda (...))
- Trey Jackson
Self
C# (well, part of it is the VisualStudio IDE, I guess):
Class<D>
cannot be used in place of Class<B>
even though type D
derives from type B
. Could be different list if you ask me again tomorrow. Even though the covariance and designer trouble will be in my top 5 until they are solved (with variance added to C# 4.0, this seems to have happened for at least one of them...).
The DUAL
table.
Can't GROUP BY
an alias.
I can never remember the syntax for analytic functions and so I forget/am too lazy to use them.
Lack of combined LIKE
and IN
conditional operator. (After 10g there's a REGEX_LIKE
operator that could do the trick, though.)
Awkward concatenation syntax.
SQL isn't really my favorite language, but it's one of the top three I use everyday. There are probably more items, but these are the ones at the top of my mind.
I have a whole slew of problems with SQL*PLUS
. I wrote a Perl replacement that does what I'd like from the command line and I use
sql.el
[1] in Emacs
for interactive SQL
sessions. These tools help me work around my SQL*PLUS
issues.
Speaking of which:
"Only perl
can parse Perl." (But this is mostly an issue in syntax highlighting, which I don't prefer to use much anymore for any language.)
I'm sometimes surprised by "the simple (but occasionally surprising) rule...: It looks like a function, therefore it is function, and precedence doesn't matter." (From perlfunc(1)
)
Dereferencing complex data structures can be confusing at times. I can't decide if this is a true flaw in Perl or just a consequence of having really powerful data structure facilities. Either way, I can normally get it right by taking a few minutes to think about what I'm doing.
No option to cause system calls to raise their errors like the DBI module. (Thanks to brian d foy, I now know the autodie
module on CPAN does this, but I'd like it built-in.)
Warnings and strictures not enabled by default in scripts. (The -e
option would turn them off for command line use.)
Again, there are bound to be more things, but these are issues I've noticed recently. I'd add the need for =over
and =back
and the quirky L<...>
syntax in POD
, but maybe that ought to be a separate list.
Now for the trifecta:
Sourcing a file with arguments replaces the values of the parent script's arguments. (Executing . file arg1
puts arg1
in $1
.)
ksh
is not an ideal interactive shell and defaults to vi
key-bindings, rather than emacs
. (My solution is to use bash
for interactive shells.)
Common utilities (such as grep
) are implemented differently across different platforms thereby preventing perfect portability. Some useful commands need to be installed on some platforms and are part of the OS core on others.
The syntax for conditionals is overly heavy. (if [ ... ]; then ... fi
)
Although it is Turing Complete, you are eventually going to want to move up to a more expressive language like Perl.
One solution for #4 is to get used to short circuit evaluation:
[ ... ] && ...
[1] http://www.emacswiki.org/cgi-bin/wiki/sql.eluse strict;
no it won't you have to use 5.012; to get strict in 5.012 (or use strict). which imo is not the same as default. - xenoterracide
D
array.length += 512;
string literals found as is inside an associative array literal are interpreted as static, thus this
char[][char[]] hash = ["hello":"world","goodbye":"angels"];
doesn't work without some extra casting due to different length string literals despite
a. I didn't ask it to be interpreted as static arrays
b. static arrays aren't allowed in associative arrays anyways
Someone check me on these; not sure if they are all still relevant.
a not_in b
is the same as not (a in b)
in all the languages which i use that have an 'in' operator. - Wallacoloo
First post, so take it easy on me :) ... Awesome community site, btw!
I tried reading all other C# replies just so mine doesn't overlap
C# ... In no particular order:
1) No fallthrough for cases in switch statements. And if there is no fallthrough ... why does one have to explicitly type break; anyway? It's just retarded and confusing since it implies the ability to not have the break;!!!
2) Can't declare a variable with the same name in a child scope, but you can declare a variable by the same name as a class variable? Either allow both or disallow both. Otherwise, it doesn't make sense.
3) No optional/default parameters in functions
4) Exceptions in finally{} should be implicitly caught for every line. Or at least, just the NullReferenceException exception. For instance, after accessing a db, one should always clean up. So, the finally block should look something like this:
finally
{
if(par1 != null)
par1.Dispose();
if(comm != null)
comm.Dispose();
if(conn != null)
conn.Dispose();
}
It would be so much cleaner if it could be written as:
finally
{
par1.Dispose();
comm.Dispose();
conn.Dispose();
}
But, no ... you have to check if you are accessing a null object, otherwise it may throw a NullReferenceException from the finally block .. and who really needs exceptions in the finally block anyway?
5) Generics: you can specify new() to be able to instantiate your generic objects, but that object needs to have a default constructor. Why can't you specify a signature instead so one doesn't need to create empty constructors if it doesn't already have them and just use the constructors it does have.
using
block for that. - ssg
Java
I can't believe it, my favorite Python pet peeves still haven't been mentioned:
(Prior to 3.x) Relative imports look like absolute imports.
import foo
Does this import foo from the directory you're standing in or from the sys.path?
grep
and find
(to among other things debug problem 1)! Fortunately, there's pip. Use pip.Py3k fixes several of my other pet peeves, by for instance insisting that strings are unicode and that 8-bit-stuff are treated differently...
latin-1
, then to ascii
after Python 2.3 or 2.4, and now to UTF-8
in Python 3! - kaizer.se
C++:
Linking your code is harder than compiling it. Also, the requirement of templates to have the full source in that translation unit is absurd. It's over in that other file there .. the one you compiled two seconds ago. Go look there. Stupid compiler.
I mean, yes, there's std::thread in C++0x, but no std::socket or anything of the sort. The primary reason there's no cross-platform code is because you have to learn a new library for every function that you want to perform on more than one platform. Without OS headers or OS functions provided as standard, C++ is only good for pushing bits around.
double x, int y, char z = func(); is just as valid as void func(double x, int y, char z);. Please. The only reason ever given for no return value overloading is because we "might" write ambiguous code. Might! Please, give me grief when I actually write ambiguous code, not before.
It's ok to make reflection compile-time. It really is. Not having any makes writing a lot of libraries difficult, at best, and seriously annoys me. I could abuse the preprocessor but..
Yaargh. Please, concepts and proper template error messages. It's practically impossible to use a library like Boost, just because if you get it wrong, you're shooting in the dark.
Python:
from __future__ import division
to work - J.F. Sebastian
Python
And to all those C-ish language programmers, self makes more sense to me than this, because the object is referring to its self
Lua:
a += 20
is a pain--
) precludes the possibility of pre- and post- increment/decrement operatorsErlang is absent from this list. Among my favorite languages, but a few flaws for sure:
Syntax. This includes the 3 terminating tokens (,;.) and aesthetics, but more generally on how the semantic meaning of the code is expressed in text. An example is on how all lowercase tokens are atoms, so to refer to a function you can't just name it, you have to fun my_function/1
, and ?PRECEDE_CONSTANTS_WITH_QUESTION_MARKS
. Coming from Scheme, Haskell, etc. you just wish you could use a name.
Library support is lame. This is mostly external libraries, but even the old standard library. Newer versions of Erlang have sensible POSIX regexes, but the old one had a pretty horrible library for basic string manipulation. You also never know when you're getting the value, or {ok, Value}
.
Related: non-uniform tools for building and distribution. Ruby has gem
and rake
, RSpec. Perl has CPAN. I'm unaware of decent equivalents in Erlang.
The few Erlang specific tools are pretty strange. Mnesia is a great database, but coming from SQL you have lots of trivialities to learn. Same with the documentation @spec
, which has a strange way of describing signatures.
Often the functional paradigm hurts when you just want that little bit of mutation. Supposing you want a Hash Table, you can't just hack it as in Scheme, or SML. ets
and dets
alleviate some of the pain, but not much.
Sixth, bonus:
import
statements.All that being said, Erlang is a joy ^_^
R
Not my favorite language, but I use it a lot and there is plenty to complain about...
lists
and S4 classes still keep all data exposed to user<-
->
or =
, see
Mike Dewar's rant
[1]my.var
is a very confusing variable naming convention for an OO language, see
Google's style guide
[2].
character in a variable name is not special and is completely ignored by the parser. Except that it's critically important to S3 method dispatch! Who thought that was a good idea? - Harlan
sample(10:12, 3)
gives three numbers between 10 and 12; sample(10:10, 3)
gives three numbers less than or equal to 10! Who thought that was a good idea? (And no, the fact that the behavior is documented is no excuse!) - Harlan
Five things I hate about all languges (that I know of at least):
C#.
What I hate most:
No multiple inheritance - imagine you could provide whatever GUI framework base class (Control, Window, whatever) with MVC - related stuff, etc... framework / base class agnostic!
No "friend" keyword... I know, the RAD - victims would abuse it for all kinds of stinky code and for hilarious malpractices, but it would be nice for the OOD - guys to enforce the law of demeter
No language integrated DBC features, there are the Contracts, but I would rather have that Spec# - style with a general purpose "!" - postfix operator
No AOP (I don't get it... this language has attributes, it would have been SO EASY to add interception code in the compiler!)
No weak event delegates - the observer pattern becomes nothing but a memory leak bait as it is now... :-(
Another vote for C++ here... still my favorite with a few close followers - C and Python. Here's my current hate list in no particular order:
.NET framework (the libraries)
MessageBoxButton
should be MessageBox.Button
)Rect
, Point
)System
namespaceObject.Equals
, Object.ReferenceEquals
, operator ==
, operator !=
, IComparable.CompareTo() == 0
)And one more:
C#
Most of my gripes have to do with assuming C++ conventions were automatically the best choice for C#
Bonus one for .NET (not C# specific)
C/C++
Java
Python
def main(): ...
solves the 1st point. - J.F. Sebastian
int a, b; std::swap(a, b);
. - Billy ONeal
std::swap
does, and therefore isn't much (if any) of an optimization. - Billy ONeal
dialyzer(1)
to discover
discrepancies. Dynamic typing is
also considered to be slow;lists(3)
module is pretty lean, sometimes
I lack useful functions for list processing
(like ones in Data.List
in Haskell for example);,
at the end of an every statement
within clause, and .
in the end of the latter.Common Lisp
I wonder what a strongly-typed lisp would be like
Haskell (with all GHC extensions, not just the base Haskell'98 spec).
There's exactly one thing that I hate about it: it's not mainstream.
My favourite is really C#, but there are already a ton of answers for C#, so I'll go with my next "favourite":
GO
statement, and the fact that you need it for all manner of DDL/DML scripting, and the fact that it also breaks transaction semantics, making it far more difficult than it needs to be to write an atomic script, which you really need to have in order to upgrade a production database.MERGE
statement has to end with it, WITH
statement has to begin with it... make up your mind!WITH CHECK CHECK
/ WITH NOCHECK CHECK
. Uuuu-gly.DEFAULT
(and don't even try using NULL
instead). Compare to SPs where they are truly optional.TCL
This is my absolute favourite language for doing almost everything. Over the years it has evolved (slowly, very slowly) to address most of the things that annoy me. And the language is so flexible it's easy to implement syntax sugar to cover things that still annoy me. But there are things about the language that can't easily be changed just breaks its Zen:
Arrays (of the associative kind, what Perl calls hash) don't have proper value semantics. This makes them awkward to pass to and return from functions. Also, this means that they can't be nested. For this reason dicts (dictionaries) were invented but too late, the nice array access syntax:
$array($foo)
is now forever taken by stupid arrays for backwards compatibility. We're now stuck with:
dict get $dict $foo
which is much more verbose and to me feels less readable.
No real closures. Though it can be emulated somewhat by globals or namespaces but that defeats the reason for closures in the first place. Although, I can't really see for now how closures can be implemented in a pure value semantics system.
Teacup is hard to use and is not at all intuitive compared to all other repository tool out there. This is more ActiveState's fault than tcl-core and doesn't really break tcl's Zen when coding but it is still very annoying.
C++
(Except for lambda functions, I've avoided things that will be available in Cpp0X)
1 - indentation
2 - indentation
3 - indentation
4 - indentation
5 - indentation
I'll let you guess the language. :-)
Perl
I love this language, and I don't want to add things that have already been used, but no one has mentioned this yet, so I'll throw it on the pot. When I used this feature, I found it to be the most horrible experience of my life (and I've worked in assembly language):
write()
and format()
functions.They have the single worst, ugliest, most horrifying syntax imaginable, and yet they don't manage to give you any more functionality than you could already achieve with some (infinitely prettier) printf()
work. No one should ever try to use those two functions to do any output, simply because of how bad they are.
I'm sure someone will disagree, but when I looked into them, hoping they would solve my problem, I found them to be a "world of pain" (to quote the Big Lebowski), and hope that Perl6 has either done away with them or, better, completely rewritten them to be somewhat more usable and useful.
Objective-C / Cocoa / Cocoa Touch:
C#
C
C
Edit: While thinking about a CPAN for C, I thought... what would I call such a thing, and thought of "ccan", and googling it, I came across this: http://ccan.ozlabs.org/
It seems to be as yet in its infancy though.
I'm going out on a limb since I can't really use it full time, but I'll try anyway!
Perl 6
The first three are the language; the rest aren't really the language itself but the fact that it's not out yet.
[1] http://svn.pugscode.org/pugs/docs/Perl6/Spec/R (R-Project for statistics)
PHP
And far more subjectively:
C++ lack of good refactoring tools, lack of checked exceptions
Java lack of templates, lack of const
keyword
const
keyword in Java, but you can acomplish the same just declaring a method, a variable, or even a Class! using final
keyword - unkiwii
c#:
1) static methods must be a member of a class
2) static extension methods can only be added to static classes
3) The implementation of interface functions are not marked with something like 'override' to show they are from a base class or interface (making it hard to ensure you're overriding the method you expect (with correct signature) with just code review).
I just have 3. I guess thats pretty good.
Python:
I am still a moderate user for python, so my complaints might just well be lock of knowledge or mis-usage. Comments are welcome. I do love this language.
I saw people complains about speed. I don't get that. Its an interpret language, code not compile to machine code until runtime, that's just the nature of it. You can't compare speed from an interpret language to a compiled one. As far as I can see, among the interpret/scripting languages, python isn't slow.
a=b*++a+c[a++]
, which IMO is hard to predict the resulting value of a. I have no problem with just a++
(even though you're only saving 1 character). But if it was chosen to allow the later and not the former, it could be more confusing to programmers with background knowledge of a language that has full support for pre/post increment. - Wallacoloo
VBA (because you thought your language was bad)
=
for comparison and assignment sounds horrible! I use == all the time in math expressions, and I'm guessing something like x=x+(x=0)
is a syntax error (or unpredictable)(Though I'd never actually use this example). - Wallacoloo
Python
lambda
s. GRRRRfoo( a for b in c if d )
feels wrong, it surprises me every time I get away with it. Shouldin't it be foo( (a for b in c if d) )
? yield
statement in it, a function is magically transformed into a generator, and its interface changes completely. Also, that generator cannot do any work before the first next()
. at least, not without using a function that returns a generator.JavaScript
for each ( foo )
syntax and behavior feels like an afterthought.• Community is too small. It's next to impossible to get a good language-immersion program going when there's no easy to find another speaker nearby.
• Irregular verbs. Yes, I know English and Spanish mentioned them, too, but Quenya was invented. Why does there still need to be irregular verbs?
• No Unicode support. I have to have three different Tengwar fonts on my computer before I can read most messages, and several of them are poorly kerned. This wouldn't really be a huge issue given the existence of a Romanized transcription, but Tengwar is so beautiful, you don't not want to use it.
• Not all concepts can be easily referenced in Quenya, leading to annoying circumlocutions, or resorting to Sindarin, Númenórean, or (Manwë save me) Klingon to get my point across.
C#
dynamic
should solve most of this, but it hasn't been released yet.
Common Lisp
C#
IComparable
vs. IEquatable
vs. IComparable<T>
vs object.Equals vs. operator == etc. etc. By extension, making a custom type that satisfies all these things is a lot more work than necessary (in particular for collection classes). Obviously, the language designers realize this, hence the various workarounds for things like linq, foreach and collection initializers which work by-shape rather than by-interface.const
)using
is a limited but good-to-know substitute!)(Class)
and as Class
. Mainly to do with the whole null
able-or-not thing. - Nick Bedford
Five things I resent in Nemerle:
Clojure
Python, again:
No switch keyword. And NO, dictionary is not a replacement for it. Not even a bunch of elif
statements.
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?
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.
Choice between spaces and tabs. There should be no choice. Pick on, set it in stone and stop fighting.
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.
Japanese
This was inspired a bit by the Chinese and English responses
1) Has not one, not two, but three writing systems.
2) For every verb you can do about 50 conjugations to mean almost 50 different things
3) Sooooooo many double negatives
4) Particles
5) on-yomi and kun-yomi
Funny enough 1, 2, and 4 are reasons I also like it.
Objective Caml
I use Java, and my biggest beef is the inefficiency of string operations. when you use the + operator. Seriously, can't the compiler figure out how many strings I'm adding and then generate the StringBuffer stuff in the background for me?
Often code that uses + is more readable than a sequence of StringBuffers operations.
Also, I hate the redundancy between native arrays and the collection framework. The syntax for .toArray() is extremely ugly.
C++:
Javascript;
Perl 5:
Scheme
Lua
I love programming in Lua, but here's what burns me:
Despite all of which I will insist that Lua is fabulously great :-)
Scheme:
Python:
multiprocessing
or similar. - J.F. Sebastian
EL - Expression Language, the ${...}
and #{...}
thing in JSP pages and JSF 2.0 Facelets which is used to pull data up from the underlying Java code.
Regarding C#:
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.dict.items
or dict.items()
? Ruby got this one right, too.Python
PHP:
Python
C++
Five things I hate about C++
#define STR_LINE2(x) #x
#define STR_LINE(x) STR_LINE2(x)
#define LINE_NUMBER STR_LINE(__LINE__)
Haskell
Sometimes the type system feels backwards. What if I don't want the compiler to infer types for my variables? What if I want the opposite, where it does constraint checking on said variables? For example, instead of inferring the type of the elements of a list, it instead makes sure that they all belong to a particular typeclass. This is a subtle but huge difference that makes it difficult for me to program UIs. It can be done, but it takes more effort than it does in some other languages. Haskell rocks for the non-UI parts, but the UI I leave to an untyped language.
Allowing the construction of infinite values leads to some really frustrating errors sometimes.
NoMonomorphismRestriction.
Bytestring handling bites me in the ass sometimes and you don't know it until your program crashes because you mixed them up improperly. Something is wrong here, when we are losing type information that should have prevented this.
Typeclasses should be automatically derived for trivial cases, like witness types, but there's a strong potential for abuse there.
foo :: SomeTypeClass a => [a]
? - j_random_hacker
C#
I know its stupid, but I'd like datatypes to convert to what I want on their own, without me having to add (int)
or Convert.ToInt32
or whatever. It would just save me time. And it annoys me that if I write something to output an int
and then it turns out that I need a long
, then often I have to go through and change everything I've done to make it work. Just do it for me!
Sorry, couldn't think of five, but I'm new to it, so maybe I'll come back and add more later :P
By far the thing that I hate most about my favourite language is that my choice keeps changing. Every time I think I've found The One, I find five (or more) things that I hate about it. And then the grass looks greener over there...
C#
VB .NET, but only because VB6 poisoned an entire generation of programmers
I work in a VB .NET shop that used to be a VB6 shop, and every person working here who used to be VB6 developers stubbornly refuses to learn anything about .NET. They code as if it’s still VB6, and their apps suck just like VB6 apps did. My boss actively discourages any use of LINQ because she fears it’s too difficult for others to understand, which is true because nobody wants to understand it.
I think we would have all been better off if MS just went with C#, which kills me to say because I think curly braces are far inferior to VB’s verbose closing statements.
JavaScript
From the ECMAScript 5 spec:
7.6.1.2 Future reserved words:
class, enum, extends, super, const, export, import
In strict mode: implements, let, private, public, interface, package, protected, static, yield
OK, I kinda enjoy the last one, but it's 7 kinds of confusing
Python:
No standard GUI toolkit (the community goes round and round about this but never seems to settle on anything).
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.)
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).
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).
Up until virtualenv was invented, keeping separate Python environments for different purposes on one machine was a real pain.
Ruby.
Java - no support for composition on language level
Java:
Ruby
Ruby:
I feel that a favorite language is impossible to choose. Dynamic typing and static typing can't quite be compared, so I'll just list which of which I use
C++:
::value
would make it much more concise->.
Why can't the compiler figure out that I'm doing a ptr.thing
and just do ->
for me?vector<vector<int>>
has to be vector<vector<int> >
makes me get the jitters and then I can't focus whenever I see that line of code and I end up trying to figure out a way to use int[][]
or something;
Python:
MEL (Maya Expression Language):
These and several other reasons are why AutoDesk adopted Python as a secondardy scripting language, which brings up a few other annoying factors:
C is my favorite but it is also horrible.
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!
Python: Array part-selection doesn't give you what you asked for.
a[1] gives you one element
a[1:2] gives you one element, not [ a[1], a[2] ]
a[1:3] gives 2 elements
I hate that, but maybe that's just because I mostly work in Verilog.
iterator.end()
is pointer after the last element; in C: for (int *p = a; p != &a[n]; ++p)
here's &a[n]
points to next to the last array element. See Dijkstra's article is.gd/6fIZ - J.F. Sebastian
Python:
C#
Java
C++
Rewrote this after some more thinking ...
Five things I hate about PHP although I love it (in no particular order):
Those are the language features (or lack of) that annoy me but the much bigger problems are these more people/community related things:
The fact that a lot of people who use PHP, don't know anything about programming and good practices in general and produce really messy code. JavaScript has the same problem.
The huge amount of tutorials/book that teach really bad practices and style. This may be the main cause of #3.
The bad reputation it has developed mostly because of #3 and #4.
I'm very happy with C# but these two really annoy me:
Constructor-based initialization for immutable classes is less convenient, less intuitive (when you read the code you don't understand what you assign to what), has less IDE backing than inline object initialization. This makes you lean towards mutable classes inevitably. I know this has been mentioned before, but I strictly have problems with initialization syntax for immutable classes.
switch
is too verbose. Whenever I see a situation where a switch would be proper, I'm really inclined to use an if..else if..
just because it's more terse (~30% less typing). I think there should be no fallthrough for switch, break
should be implied, and case
should allow comma separated list of values.
Having to assume we have a language. Do we?
Java is slow according to many but I agree to a certain to degree of usage.
Java is dramatic. They have lots of classes just for a single thing you wanted to do. But you know flexibility property XD.
Java is hard at first but fun as always.
When you are writing a simple code for printing "Hello,World!" PLEASE DO NOT USE JAVA! XD I'm sure I am justified.
Java is a mixture so don't say it is purely an OOP language.
There's many more but I am only restricted to five XD. Thanks!
My 5 for Delphi:
a := 3
, you have to say put 3 into a
itemDelimiter
and escape them manually. You can also get lines and words like get word 2 of line 5 of txt
As an aside, I think one of the coolest features unique to HyperTalk is the special it
variable:
ask "How many years old are you?"
answer "You are " & it*12 & " months old."
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 methodreload()
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 moduleOnes that make sense based on the implementation but are annoying ...
array.sort()
does not return an array (I suppose it happens in-place)for
loop, right?) and a couple that are fixed in Python 3
global
can only refer to the top level namespace__len__()
should just be aliased to len()
- Brendan
Math.Floor(double.MaxValue) > int.MaxValue
returns true in C#. - Robert Davis
floor
and ceil
and the step of converting to appropriate Python variables was not implemented. - Brendan
math
module is just a very thin shell over C's math.h. - kaizer.se
Scala:
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, double MyFunction()
{
....
return x,y,z;
}
public void TestMyFunction()
{
int x, string y, double z = MyFunction();
}
(8) No support for covariant return types
I have some gripes about the generics implementation, but I'll cut it there. I think C# is a great language for doing all the GUI, networking and configuration plumbing and is my number one language for getting things up and going quickly in a way that can be supported in the long run.
C#
1) Lack of practical ability to write generics for value types. For example, any idiot (well most idiots) can write a routine that calculates the standard deviation of a list of int, float, double, etc in C++, it is straightforward to write, easy to read and performs as fast non-generic code. I think if you can write something in C# that is close to hitting any one of these 3 without being ridiculous on the other 2, you are a really great programmer.
2) Covariance and contra variance, although this is being added to 4.
3) Extremely poor documentation of LINQ (alright, not really part of the language).
4) Trying to use foreach/iterators when I want to do the same thing every time except something slightly different the last time (such as concatate a bunch of strings with commas between them and the word and between the last two). If I write it with an IEnumerable, it is hard to write and read, and with a for (int i=0 i < ...) it isn't much better and it is less efficient.
5) I know I am going to get complaints about this, but lack of checked exceptions. This does not need to be implemented the way it is in java (The framework developers do make some very good points on why they didn't do this), but I would be happy with a compiler warning users who don't like checked exceptions can turn off.
REBOL
REBOL is among my favorite languages. I can't say that I have a favorite, though Haskell ranks pretty high as well.
Its odd syntax scares off many developers before they even give it a try.
use [email rules url] [
; A small DSL that sends email to people about URLs.
rules: [
some [
into [
set email email!
set url url!
(send/subject email url reform [ "Check Out" url ])
]
]
]
; Global context
notify: func [ [catch] dsl [block!] ] [
unless parse dsl rules [
throw make error! "You screwed up somehow."
]
]
]
notify [ [ a@b.com http://www.google.com ] [ b@c.com http://www.yahoo.com ] ]
Recursive dialects are very easy to validate with PARSE
but very difficult to evaluate. (Stacks can be helpful here.)
BLOCK!
datatype can do almost everything XML can do. However, the real world has XML in it.The upcoming REBOL 3 will hopefully fix many of these issues, except for the last one.
Python:
1) It's a scripting language and not a fully compiled one (I'd prefer to be able to compile binaries—I don't care about bytecode). This is very annoying if I have to use very many libraries (i.e. everyone who uses my program has to install all the libraries, and this basically means no normal people will be able to, or have the patience to, properly set it up—unless I do a ton of work that should be unnecessary). I know ways to make binaries, but they don't always work, and I'm guessing they bundle the interpreter in the binaries anyhow (and I don't want that). Now, if I could get a bytecode compiler that would include copies of all the files that I imported (and only those) to be placed in my program's folder, that might be a suitable compromise (then no one would have to download extra libraries and such). It would also be nice if the compiled python files could be compressed into a single file with one specified as the file to run the program before this is done.
2) It seems a bit buggy at times; there have been a few times when code that was supposed to work simply did not (there were no programmer errors), particularly code relating to such as "from moduleX import *", and other import-related issues, as well as some issues pertaining to global and local variables.
3) Maximum recursion depth could be higher. There has been at least one time when I felt that I needed it to go higher.
4) No switch statement (let alone one that allows for numbers, strings and ranges)
5) The newer Python versions seem to be doing away with a lot of useful string operations, and they don't seem to have simple documentation on how to do the same things without them.
6) Forced automatic garbage collection (I'd like to be able to do it manually, although not necessarily forced to do so).
7) No pre-made Timer class without the use of a GUI (well, there might be one, but after all the searching I've done, it's sure not convenient to find! I actually did find something, but it didn't work at all when I tried it.) By a timer, I mean the sort that will execute a specified function every x seconds, with the ability to turn it off when desired, etc.
8) People in the community who give examples rarely tell what modules they imported, and how they imported them.
9) There's not a lot of support for integration with Lua.
10) There doesn't seem to be a way to add an extra function to a particular instance of a class (and not the entire class at large), unless you dynamically add an object variable to that class with the object having the needed function (but still, you have to make another class just for that).
__new__
, or __metaclass__
. - Brendan
Class.method = some_method
. I just tested it with IronPython, and I think it works with CPython as well. - Bastien Léonard
Java:
5. The null-coalescing operator
The ?? operator allows you to write:
x = y ?? z;
instead of:
x = (y == null) ? y : z;
I like this operator, but I want another one:
x = y ??? y.foo() : z.foo();
instead of
x = (y == null) ? y.foo() : z.foo();
I use this kind of thing all the time, and I find it annoying to type the == null
part.
4. Equals should have better support
I have having to start every Equals(object obj)
method with:
MyClass other = obj as MyClass;
if (other == null) return false;
You should only have to write:
public override bool Equals(MyClass other) {...}
And the language should take care of providing the Equals(object obj)
method.
NOTE: other should be guaranteed to not be null.
3. Cannot use ternary operator with different types
This doesn't compile, and I think it should!
string foo = "hello";
int bar = 4;
object baz = foo == null ? foo : bar;
2. Lack of namespace private
I like the internal
protection, but I wish there was a protection which would only allow access from within the same exact namespace. This would be nice to better control access in large class libraries.
1. No multiple inheritance
I really only use implementation (class) inheritance for default implementations of an interface, but there are plenty of times when I want to do just that.
Python
path
- type module to fix this was rejected.([f for f in os.listdir('/file/path') if os.path.isfile(os.path.join('/file/path', f))]
)
Lua
I just discovered I cannot use Enum as a type constraint when creating a Generic method in c#.
Microsoft has a good enough explanation as to why, but still. I'm MAD
public static T MyFunc<T>(string arg) where T:Enum //wont work :(
JavaFX
C#
Item o()
(with an automatic dispose if it has one).VB.NET
1) If Not x Is "foo" (instead of <> "foo")
2) "OrElse" and "AndAlso" short circuit (instead of simply "Or" and "And", which act differently)
3) Nothing (instead of Null)
The lack of a preprocessor in C#.
I know they left it out because some folks can abuse it, but I think they threw the baby out with the bathwater. Code generation is regarded as a good thing, and in C++ the preprocessor was my first-line code generator.
Python:
1) line continuation syntax: "...\" works, but "...\ " does not, and that trailing space is generally invisible, without unusual eol-marking by editer.
2) a bare 'raise' is invisible in the stack trace, as the stack trace looks like the previous raised exception.
3) slow
4) poor integration into web-servers (mod_python: dead, mod_wsgi: limited scope of operation). This is complicated by 3], requiring daemonization or some sort of memory-persistance to perform well.
5) overly tolerant of mixed tabs and spaces, allowing changes to control flow to sometimes remain hidden. (maybe fixed in recent versions)
Lua:
The built-in error system is absolutely horrendous
You can implement a try-catch system by modifying the Lua interpreter; but it has no compatibility with the errors that are thrown by the built in functions.
The fact they have __newindex instead of __setindex as the setter
... and __newindex is only fired when the key doesn't already exist. If it does, no metamethod is called at all.
No good type comparison system.
There's the type() function but it only handles the basic types (all tables are tables). It really needs to have a metamethod for type comparisons. I've implemented this before with an 'is' operator and a __type metamethod and it works really nicely.
It's a bitch to define new keywords.
You can do it, but the code inside Lua isn't well documented so it's kind of trial and error to find out how to get the result you want. This is a major issue when you want to implement the things I mentioned above yourself (not so much __setindex though, that's an easy modification).
I can't use it in a web browser.
Yeah not really a problem with the language itself, but damn, would I love to be able to use Lua instead of Javascript... :)
C
JavaScript
Object Pascal:
This is just the language, the sorry excuse for a standard library and flaky IDE deserve their own lists.
I have only one but I believe it worth sharing.
CSharp / .NET
We have Length property to get number of elements in array and Count property to get number of elements in collection. It looks more stranger if you consider the fact that CLR automatically adds IList, ICollection, IEnumerable to zero-based one-dimenssonal arrays behind the scene.
I believe CLR team and BCL team had hard times discussing this subject ;)
Objective-C 2.0
Sticking strictly to the language and runtime, and not the libraries, and not in any particular order:
Python:
C# 4.0
The "dynamic" keyword, ripe for abuse. If you want/need to use Reflection, use and make it obvious that you're using it, don't try and disguise it with dynamic.
VB.NET
On Error
keywords and the whole VB6-NamespacePython
sys.getrecursionlimit()
; and you can change it with: sys.setrecursionlimit()
. - Don O'Donnell
Things I hate about Python:
Things that annoy me about Python:
(self,
private
goto
foreach $arr => &$val
... foreach $arr => $val
)goto
is sometimes useful. Many people don't know how to use it, use it in a bad manner, abuse it, or blindly teach other people that goto
is the Dark Lord Satan. It isn't. It's just a tool, which you have to know to use properly, that's all. Anti-goto crusaders are just retarded people that don't know how to do something hence want nobody to be able to do it. - Lo'oris
SAS [1]
Never has own ideas (every thing is borrowed).
Greedy for huge datasets.
Uses Java, but never learned what it is to be an object.
Steals Perl, but hide it in its data step.
Lie always with statisticians!