最近Stack Overflow上有一群讨厌perl的人,所以我想我应该把我的“关于你最喜欢的语言你讨厌的五件事”的问题带到Stack Overflow上。拿你最喜欢的语言来说,告诉我你讨厌它的五件事。这些可能只是让你烦恼的事情,承认的设计缺陷,公认的性能问题,或任何其他类别。你只需要讨厌它,它必须是你最喜欢的语言。

不要拿它和其他语言比较,也不要谈论你已经讨厌的语言。不要用你最喜欢的语言谈论你喜欢的事情。我只是想听到你讨厌但能容忍的东西,这样你就可以使用所有其他的东西,我想听到你希望别人使用的语言。

每当有人试图把他们最喜欢的语言强加给我时,我就会问这个问题,有时是面试问题。如果有人找不出他最喜欢的工具的5个缺点,那他对它还不够了解,不能提倡它,也不能利用它赚大钱。他还没有在足够多的不同情况下使用它来充分探索它。他把它作为一种文化或宗教来倡导,这意味着如果我不选择他最喜欢的技术,我就错了。

我不在乎你用什么语言。不想使用特定的语言?那就不要。你通过尽职调查做出了明智的选择,但仍然没有使用它?好吧。有时正确的答案是“你有一个强大的编程团队,有良好的实践和丰富的Bar经验。改成Foo是愚蠢的。”


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.

憎恨并不是衡量人们了解多少的唯一尺度,但我发现它是一个相当不错的尺度。他们讨厌的事情也让我知道他们对这个话题的思考有多好。


当前回答

我讨厌Java(目前它是我最喜欢的语言)的五个方面,排名不分先后。

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

其他回答

C++

模板的语法 钻石传承问题 现代语言所拥有的标准库过多/缺乏(尽管boost也很接近)。 iostream IOStreams周围使用的语法

Python

空格是有意义的(有时) 强调关键词 有限的线程支持(至少目前) 用self代替this 空格是有意义的(有时)

Ruby是我最喜欢的语言,以下是我不喜欢的语言:

绿色线程+阻塞C库=巨大的失败 慢得令人痛苦 标准库本身与其使用bang!方法 模块包含+扩展是混乱的。 “开放类”不能是范围-我想添加一个String#dostuff,但我不希望泄漏到所有的第三方库 没有二进制部署打包解决方案。

C++

Strings. They are not interoperable with platform strings, so you end up using std::vector half of the time. The copy policy (copy on write or deep copy) is not defined, so performance guarantees can not be given for straightforward syntax. Sometimes they rely on STL algorithms that are not very intuitive to use. Too many libraries roll their own which are unfortunately much more comfortable to use. Unless you have to combine them. Variety of string representations Now, this is a little bit of a platform problem - but I still hope it would have been better when a less obstinate standard string class would have been available earlier. The following string representations I use frequently: generic LPCTSTR, LPC(W)STR allocated by CoTaskMemAlloc, BSTR, _bstr _t (w)string, CString, std::vector a roll-my-own class (sigh) that adds range checking and basic operations to a (w)char * buffer of known length Build model. I am sick to death of all the time spent muddling around with who-includes-what, forward declarations, optimizing precompiled headers and includes to keep at least incremental build times bearable, etc. It was great in the eighties, but now? There are so many hurdles to packing up a piece of code so it can be reused that even moms dog gets bored listening to me. Hard to parse This makes external tools especially hard to write, and get right. And today, we C++ guys are lacking mostly in the tool chain. I love my C# reflection and delegates but I can live without them. Without great refactoring, I can't. Threading is too hard Language doesn't even recognize it (by now), and the freedoms of the compiler - while great - are to painful. Static and on-demand initialization Technically, I cheat here: this is another puzzle piece in the "wrap up code for reuse": It's a nightmare to get something initialized only when it is needed. The best solution to all other redist problems is throwing everything into headers, this problem says "neeener - you cannot".


诚然,其中许多内容超出了严格的语言范围,但在我看来,整个工具链都需要进行判断和发展。

经过一些思考后重写了这篇文章…

虽然我喜欢PHP,但我讨厌它的五个方面(排名不分先后):

内置函数中的命名和参数顺序不一致。 面向对象的数组方法多亏了SPL,但遗憾的是还没有字符串。 PHP本身没有真正的并发,只有通过托管web服务器的多处理 没有像JavaScript那样的异步调用 只能通过扩展进行操作码缓存。不是很糟糕,只是有点烦人。

这些是令我烦恼的语言特性(或缺乏),但更大的问题是这些与人/社区相关的东西:

事实上,很多使用PHP的人,对编程和良好实践一无所知,从而产生了非常混乱的代码。JavaScript也有同样的问题。 大量的教程/书籍传授了非常糟糕的做法和风格。这可能是第三条的主要原因。 它的坏名声主要是因为第三条和第四条。

Perl

Mixed use of sigils my @array = ( 1, 2, 3 ); my $array = [ 4, 5, 6 ]; my $one = $array[0]; # not @array[0], you would get the length instead my $four = $array->[0]; # definitely not $array[0] my( $two, $three ) = @array[1,2]; my( $five, $six ) = @$array[1,2]; # coerce to array first my $length_a = @array; my $length_s = @$array; my $ref_a = \@array; my $ref_s = $array; For example none of these are the same: $array[0] # First element of @array @array[0] # Slice of only the First element of @array %array[0] # Syntax error $array->[0] # First element of an array referenced by $array @array->[0] # Deprecated first element of @array %array->[0] # Invalid reference $array{0} # Element of %array referenced by string '0' @array{0} # Slice of only one element of %array referenced by string '0' %array{0} # Syntax error $array->{0} # Element of a hash referenced by $array @array->{0} # Invalid reference %array->{0} # Deprecated Element of %array referenced by string '0' In Perl6 it is written: my @array = ( 1, 2, 3 ); my $array = [ 4, 5, 6 ]; my $one = @array[0]; my $four = $array[0]; # $array.[0] my( $two, $three ) = @array[1,2]; my( $five, $six ) = $array[1,2]; my $length_a = @array.length; my $length_s = $array.length; my $ref_a = @array; my $ref_s = $array; Lack of true OO package my_object; # fake constructor sub new{ bless {}, $_[0] } # fake properties/attributes sub var_a{ my $self = shift @_; $self->{'var_a'} = $_[0] if @_; $self->{'var_a'} } In Perl6 it is written: class Dog is Mammal { has $.name = "fido"; has $.tail is rw; has @.legs; has $!brain; method doit ($a, $b, $c) { ... } ... } Poorly designed regex features /(?=regexp)/; # look ahead /(?<=fixed-regexp)/; # look behind /(?!regexp)/; # negative look ahead /(?<!fixed-regexp)/; # negative look behind /(?>regexp)/; # independent sub expression /(capture)/; # simple capture /(?:don't capture)/; # non-capturing group /(?<name>regexp)/; # named capture /[A-Z]/; # character class /[^A-Z]/; # inverted character class # '-' would have to be the first or last element in # the character class to include it in the match # without escaping it /(?(condition)yes-regexp)/; /(?(condition)yes-regexp|no-regexp)/; /\b\s*\b/; # almost matches Perl6's <ws> /(?{ print "hi\n" })/; # run perl code In Perl6 it is written: / <?before pattern> /; # lookahead / <?after pattern> /; # lookbehind / regexp :: pattern /; # backtracking control / ( capture ) /; # simple capture / $<name>=[ regexp ] /; # named capture / [ don't capture ] /; # non-capturing group / <[A..Z]> /; # character class / <-[A..Z]> /; # inverted character class # you don't generally use '.' in a character class anyway / <ws> /; # Smart whitespace match / { say 'hi' } /; # run perl code Lack of multiple dispatch sub f( int $i ){ ... } # err sub f( float $i ){ ... } # err sub f($){ ... } # occasionally useful In Perl6 it is written: multi sub f( int $i ){ ... } multi sub f( num $i ){ ... } multi sub f( $i where $i == 0 ){ ... } multi sub f( $i ){ ... } # everything else Poor Operator overloading package my_object; use overload '+' => \&add, ... ; In Perl6 it is written: multi sub infix:<+> (Us $us, Them $them) | (Them $them, Us $us) { ... }