你讨厌你最喜欢的语言是什么?

Stack Overflow最近出现了一堆Perl讨厌的东西 ,所以我想我会把Stack Overflow的“ 五件你讨厌你最喜欢的语言 ”的问题带到这里。 把你最喜欢的语言,告诉我你讨厌的五件事。 这些可能是令你烦恼,承认devise缺陷,认可性能问题或任何其他类别的事情。 你只需要讨厌它,它必须是你最喜欢的语言。

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

每当有人试图将自己喜欢的语言推向我时,我都会问这个问题,有时候还会作为一个面试问题。 如果有人找不到五件令他讨厌他最喜欢的工具的东西,那么他就不太清楚它是否鼓吹它,或者使用它赚大钱。 他没有在足够多的情况下使用它来充分探索它。 他主张把它作为一种文化或宗教,这意味着如果我不select他最喜欢的技术,我错了。

我不在乎你使用哪种语言。 不想使用特定的语言? 那么不要。 你经过尽职调查做出明智的select,但仍然不使用它? 精细。 有时候,正确的答案是“你有一个强大的编程团队,有很好的实践经验,在Bar里有很多的经验,换到Foo会很愚蠢。”


这对于代码评论来说也是一个很好的问题。 真正了解代码库的人会对此有各种各样的build议,而那些对此不甚了解的人会有非特定的投诉。 我问的问题是:“如果你可以重新开始这个项目,你会做什么不同的事情? 在这个奇幻的土地上,用户和程序员可以抱怨任何他们不喜欢的东西。 “我想要一个更好的界面”,“我想从视图中分离出模型”,“我会用这个模块来代替这个模块”,“我会重命名这个方法集合”,或者他们真的不喜欢目前的情况。 这就是我如何处理特定开发人员对代码库的了解程度。 这也是一个关于程序员的自我与他告诉我的有多大关系的线索。

讨厌不是找出有多less人知道的唯一方面,但我发现它是一个很好的。 他们讨厌的东西也给了我一个线索,他们对这个问题的思考有多好。

我讨厌Java的五件事:

  • 没有一stream的function。
  • 没有types推断。
  • 在graphics中缺乏合理的默认值。
  • NullPointerException不包含什么是null的更多信息。
  • 毫无意义的“可configuration”框架/服务提供者接口/工厂类/dependency injection系统的扩散。 可configuration性几乎从未被使用,DRY被严重违反,代码大小增加了四倍,可读性减半。

我知道,我应该看看斯卡拉。

哇,我很惊讶SQL还没有成功。 猜猜这意味着没有人喜欢它:)

  • 实现中的语法不一致
  • 细微的代码差异会导致看似模糊的原因,导致巨大的性能影响
  • 对文本操作的支持不佳
  • 简单的入门成本,但掌握语言陡峭的学习曲线
  • 在整个社区最小规范化的最佳实践,这包括语法风格。

…和一些额外的理由恨它,没有额外的费用

  • WHERE子句进入最后,使得过早地执行UPDATE或DELETE变得容易,破坏整个表。 相反,WHERE应该在前面的某个地方。
  • 关系分工很难实现。
  • 我可以设置一个值为NULL,但我不能testing它与NULL相等。 我可以检查IS NULL,但这只是使代码复杂化 – 不必要的,所以,在我看来。
  • 为什么我们需要完全重新指定GROUPed列的公式,而不是在列上设置别名,然后在别名(或列索引和SORT)上设置GROUP BY?

JavaScript

  1. 所有最酷的事情都是非常复杂的,但是,所有的冷静也都包含在这么一小部分的代码中,所以你觉得自己很愚蠢

  2. “+”是弱types语言中连接操作符的荒谬select。 他们试图吓跑小菜吗?

  3. 这是一个跨浏览器的兼容性雷区(不用担心,如果它甚至打开或不)

  4. 它通常不受信任 – 与像背部button阻塞,永不死亡的popup等一样的sc </s>声有关。

  5. debugging几乎是不可能的,因为只有几个不同的错误消息和一些不同的types(数字,string,对象等)

如果不是用于jQuery的话,我可能仍然会像以前那样讨厌它:)

PHP:

1)强迫我做不必要的variables:

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

2)lambda的实现如此蹩脚,大致相当于使用eval() ,所以很可怕,我从来没有用过它(见http://www.php.net/create_function )。

3)try / catch系统只能捕获大约80%可能发生的错误。

4)正则expression式支持与lambda支持一样不好,因为它必须写在常规string中,这是最困难的编程工具之一,难度是三倍。 而PHP应该是一种“简单”的语言?!?!?

5)没有办法安全地拉出$ _POST的东西,而不写两次或build立自己的function,或使用“@”运算符:

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

6)奖金回答:“@”。 如果您不能正确地编写代码,只需添加“@”,对于任何稍后需要debugging代码的人来说都太糟糕了。

C ++

  • 随机地破坏内存并创build几乎不可能发现的错误太容易了(尽pipeValgrind在修复这个问题上有很长的路要走)。
  • 模板错误消息。
  • 当使用模板时,很容易导致不得不将所有内容都包含在一个文件中,然后编译时间变得很愚蠢。
  • 标准库在现代是一个笑话(默认还没有线程或networking?)
  • 很多令人讨厌的C通过(特别是,短/整数/无符号/等之间的转换)

C#/ .NET:

  • 类应该被默认密封
  • 应该没有lock语句 – 相反,你应该有特定的locking对象,并且应该有方法,如Acquire返回一次性locking令牌。 推论:每个对象都不应该有一个监视器。
  • GetHashCode()Equals()不应该在System.Object – 不是一切都适合哈希。 相反,有一个IdentityComparer可以执行相同的操作,并为自定义比较保留IComparer<T>IComparable<T>IEqualityComparer<T>IEquatable<T>接口。
  • 对不变性的支持不力
  • 发现扩展方法的不好的方法 – 它应该是一个更有意识的决定,而不仅仅是我正在使用一个命名空间的事实。

那些是我的头顶 – 明天问我,我会拿出一个不同的5 🙂

C

  • string操作。

不得不手动处理string缓冲区是一个容易出错的问题。 由于如此之多的计算实际上正在移动和修改string(计算机并没有像人们认为他们会回来的时候那样使用大数据量的东西),所以能够使用托pipe语言或C ++的string对象来处理这些。 当我不得不直接做C时,感觉就像在stream沙中游泳一样。

我讨厌“我讨厌某些语言的东西”列表的五件事呢? :d

5-涂橙红不会使它成为一个苹果。

当devise语言时,devise人员通常会考虑到它的用途。 用它来完全不同的东西可以工作,但抱怨时不是愚蠢的。 以Python。 我敢肯定有人有人或有人会有一天做一个实用工具,从Python代码创buildEXE的。 为什么在上帝的世界你这样做? 这将是整齐 – 不要误会我 – 但它没有用。 所以不要再抱怨了!

一个devise良好的项目可能会包含来自多种语言的代码。 这并不是说你不能用一种语言来完成一个项目。 有些项目可能在您使用的任何语言的能力范围内。

4-你站在木腿上吗?

该平台可以是语言可以做的一个很大的影响力。 与现在的垃圾收集器,甚至pascals早期尝试在“垃圾收集”,可以帮助记忆淡入淡出(也许malloc更多内存?)。 电脑速度更快,当然,我们期望更多的语言。 坦率地说,我们可能应该。 然而,为编译器创build哈希表或string或其他各种概念的便利性付出巨大的代价。 这些东西可能不会被inheritance到它们所使用的平台上。 说他们很容易包含一种语言只是告诉我,你可能没有一个腿站在。

3-真的是谁的错?

错误。 你懂。 我爱错误。 为什么我爱错误。 因为这意味着我能保住我的工作。 没有错误,会有很多封闭的比萨店。 但是,用户讨厌错误。 但是这里有一点冷水。 每个bug 都是程序员的错误。 不是语言的。 一种语言严格的语言将大大减less可能产生的错误的数量,这是一种完全无用的语言。 这个能力大概可以算作一方面。 你想要灵活性还是力量? 你有错误。 为什么? 因为你不完美,而你犯错误。 在C中以一个真正可识别的例子:

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

我们都知道该怎么做。 然而,我们可能有些人没有意识到的是,这个function可能是非常有益的。 取决于你在做什么。 缓冲区溢出是该function的成本。 上面的代码。 如果我真的把它公之于众。 那又一次..和我说……“我的错”。 不是C允许我这样做的。

我们不应该把它放在回收站吗?

用一种我们不明白的语言来说明一个特性是很容易的,因为我们不经常使用它,并把它称为愚蠢的。 抱怨它在那里等Goto总是招待我。 人们总是抱怨goto的语言。 然而我敢打赌,你最后一个节目包括一个types的转到。 如果你曾经使用过rest或继续,你已经使用了一个转到。 就是这样。 当然,这是一个“安全的”转到,但它是什么。 转到有他们的用途。 是否使用“隐式”gotos(如continue或break)或明确的gotos(对于任何语言,使用实际的关键字“goto”)。 不是语言开发人员是完美的,但通常…如果function已经存在(从那个语言)。 这方面可能是该语言的定义质量。 意思..它正在被使用,可能不会因为向后兼容性而悬在身边。 它今天正在使用。 和5分钟前一样。 并正确使用。 那么..可以说有人也不正确地使用它,但是这涉及到我的名单上的#3。

1. – 一切都是一个对象。

好吧..这个是真的#2的一个子集。 但这是迄今为止我在仇恨列表中看到的最令人讨厌的投诉。 不是一切都是一个对象。 有许多概念不属于或不需要是对象。 把东西放在不属于他们的地方只是丑陋的,会降低程序的效率。 当然。 取决于语言可能不多。 这也涉及#5。 这意味着…是的。 全球都可以。 函数静态方法是可以的。 将OO编程和全局function相结合是可以的。 现在..这并不意味着我们都应该出去,从我们的对象模型中“释放”我们的代码。 在devise一段代码或整个项目时,在把它们放在一起时应该考虑幕后发生的事情。 不仅在这个概念的生活和其他许多因素。 为什么在类或名称空间概念中包含全局函数? 采取静态成员variables。 这大大地让我感到好笑,因为..好的。取决于当然的语言和实现,但是一般来说,你只是宣布了一个全局的。 是的,在OO包装中包装这些非OO概念有一些原因。 其中之一是自我logging代码。 这是有道理的。 所以…就像我说的 不要出去“免费”你的代码。 但是任何好的现代语言都会在OObuild模之外有一个全球性的概念。 是的,我特别要指出的是,没有全局概念的OO编程语言很可能存在严重的devise缺陷。 虽然..依赖于语言的意图和devise,所以我不试图select任何特定的语言,有太多的分析在这里。 任何人,请考虑代码应该在哪里生存并且是最有效的。 添加一堆flare到不增加function或支持的东西只是更快地磨损键盘。 这对任何人都没有好处。 好吧..除非你喜欢那个可能误导你的人的布朗尼点,说什么都是对象。

简而言之,编程不仅仅是在键盘上无意识地敲击。 任何项目都有很多devise考虑因素。 我知道这是陈词滥调,但你必须从各个angular度来看待它。 即使是现在的types安全的语言。 你不只是挑出代码,并期望它运作良好。 当然,这可能会奏效,但这可能不是正确的方法。 总的来说,select最适合具体工作和环境的语言和格式。 但没有任何一种语言会把它背后的想法带走。 如果你没有想到,你只是在打字。

我讨厌Java的五件事(现在是我最喜欢的语言),没有特别的顺序。

  1. 尽pipe我是Javagenerics的粉丝,但是从devise的方式来看,还有很多古怪的东西。 同样的,generics也有很多令人讨厌的限制(其中一些是types擦除的结果)。
  2. Object.clone()和Cloneable接口的工作方式完全被破坏了。
  3. Sun并没有走高速公路,把所有的东西都当成一个对象(a.la. SmallTalk),而是创build了两种不同types的数据types:对象和原语。 因此,现在有两种基本数据types的表示和奇怪的好奇心,比如装箱/取消装箱,并且不能将原语放在集合中。
  4. Swing太复杂了。 不要误会我的意思:Swing有很多很酷的东西,但是它是过度工程的一个很好的例子。
  5. 最后的抱怨同样也是Sun和那些为Java编写XML库的人的错。 Java XML库太复杂了。 为了简单地读取XML文件,我经常不得不担心我正在使用的parsing器:DOM还是SAX? 每个API都同样令人困惑。 在语言中的原生支持,以便轻松parsing/编写XML将是非常好的。
  6. java.util.Date糟透了。 它不仅不必要地复杂,而且所有有用的方法都被弃用(并被其他增加复杂性的方法所取代)。

Ruby有很多与其速度有关的缺陷,但我并不讨厌这些缺陷。 社区传福音也有缺陷,但是这并没有让我感到困扰。 这些是我讨厌的:

  • 闭包(块)具有4种不同的创build语法,并且它们都不是最佳的。 优雅的语法是不完整的,哈希模糊,完整的语法是丑陋的。
  • 社区往往是反对真实的文件,有利于“阅读代码”。 我觉得这个幼稚和懒惰。
  • 编程滥用,特别是在图书馆中,使错误成为追查的噩梦。
  • 在一个相关的说明中,普遍的元编程使得综合的IDE难以(如果不是不可能的话)做出来。
  • 阻止传递给函数的方式是愚蠢的。 没有理由块应该被传递到参数列表之外,或者有奇怪的特殊语法来访问(yield)。 我认为块应该被赋予一个不太明确的语法(或者哈希可以使用不同的分隔符;也许是<>而不是{}),并且作为parameter passing给方法应该和所有其他参数一样。

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

    这些古怪的东西,就像块一定是传递的最后一个参数,传递多个块不一样,语法较长,真让我烦恼。

Perl的

  • 印记的混合使用

     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; 
    • 例如,这些都不是一样的:

       $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' 

    Perl6是这样写的 :

     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; 
  • 缺乏真正的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'} } 

    Perl6是这样写的 :

     class Dog is Mammal { has $.name = "fido"; has $.tail is rw; has @.legs; has $!brain; method doit ($a, $b, $c) { ... } ... } 
  • devise不正确的正则expression式

     /(?=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 /[AZ]/; # character class /[^AZ]/; # 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 

    Perl6是这样写的 :

     / <?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 
  • 缺乏多派遣

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

    Perl6是这样写的 :

     multi sub f( int $i ){ ... } multi sub f( num $i ){ ... } multi sub f( $i where $i == 0 ){ ... } multi sub f( $i ){ ... } # everything else 
  • 可怜的运营商超载

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

    Perl6是这样写的 :

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

我会做PHP,因为我喜欢它,而且Python会做得太多。

  • 没有命名空间; 一切都在一个非常大的命名空间,是在更大的环境中的地狱

  • 当涉及到函数时,缺乏标准:数组函数将针作为第一个参数,haystack作为第二个参数(请参阅array_search )。 string函数经常先拿草垛,再拿第二根(参见strpos )。 其他函数只是使用不同的命名scheme: bin2hex , strtolower , cal_to_jd

    一些函数有一些奇怪的返回值,超出了正常的范围:这会强制你有第三个variables被声明,而PHP可以有效地将空数组解释为false,并且types变化。 几乎没有其他function在做同样的事情。

     $var = preg_match_all('/regexp/', $str, $ret); echo $var; //outputs the number of matches print_r($ret); //outputs the matches as an array 
  • 语言(直到PHP6)尽最大努力来尊重近乎迟缓的向后兼容性,这使得它在不需要的时候会带来坏习惯和function(请参阅mysql_escape_string与mysql_real_escape_string )。

  • 语言从模板语言发展到后端语言。 这意味着任何人都可以输出任何他们想要的东西,并被滥用。 你最终得到一个模板语言的模板引擎…

  • 它吸收导入文件。 你有4种不同的方式来做(include,include_once,require,require_once),它们都很慢,很慢。 事实上整个语言都很慢。 至less,比python(甚至有一个框架)和RoR从我收集的慢。

不过,我仍然喜欢PHP。 这是networking发展的电锯:你希望一个中小型网站能够真正做到真正快速,并确保任何人都可以托pipe它(尽pipeconfiguration可能不同)? PHP就在那里,它无处不在,只需要5分钟就可以安装完整的LAMP或WAMP堆栈。 那么,我现在要回到与Python合作…

这里有一些我不喜欢的Java(这不是我最喜欢的语言):

  • genericstypes擦除(即没有泛化的generics)
  • 无法捕获单个catch块中的多个exception(不同types)
  • 缺乏析构函数(finalize()是一个非常糟糕的替代品)
  • 不支持封闭或将数据视为数据(匿名内部类是一个非常冗长的替代品)
  • 通常检查exception,或更具体地说,检查不可恢复的exception(例如,SQLException)
  • 对文字集合没有语言级别的支持
  • 当调用generics类的构造函数时,没有types推理,即types参数必须在'='的两边重复,

C ++

  1. 模板语法
  2. 钻石inheritance问题
  3. 现代语言所具有的过多/缺乏标准库(尽pipe提高幅度接近)。
  4. input输出stream
  5. 在IOStreams周围使用的语法

python

  1. 空间是有意义的(有时)
  2. 下划线的关键字
  3. 有限的线程支持(至less目前)
  4. “自我”而不是“这个”
  5. 空间是有意义的(有时)

Objective-C的

1)没有命名空间,只是手动命名约定 – 我不介意类分离方面的问题,但我确实错过了能够在一行中导入名称空间中的所有类定义(如import com.me.somelibrary。 *)。

2)图书馆在RegEx支持等重要领域仍然存在一些漏洞。

3)属性语法有点笨拙,需要三行(在两个单独的文件中)来声明一个属性。

4)我喜欢保留/释放模式,但比发布引用更容易,然后意外地使用引用。

5)虽然不是一个真正的语言function,Xcode是如此交织在一起的使用Objective-C我不禁想到这方面…基本上自动完成,是非常可能的。 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.

C ++

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

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

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

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

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

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


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

JavaScript

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

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

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

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

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

  • Both null and undefined exist, with subtly different, yet redundant meanings. 为什么?

  • 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.

python:

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

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.

PHP

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

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

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

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

Common Lisp:

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

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的

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

PHP:

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

Nevertheless PHP is the (scripting) language. 😉

VB6

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

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

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

Delphi:

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

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:

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

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

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

Interesting Posts