关于你最喜欢的语言,你讨厌哪五件事?

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

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

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

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


对于代码审查来说,这也是一个很好的问题。真正了解代码库的人会有各种各样的建议,而不太了解代码库的人会有一些不明确的抱怨。我会问这样的问题:“如果你可以重新开始这个项目,你会有什么不同的做法?”在这个幻想的世界里,用户和程序员可以抱怨任何他们不喜欢的东西。“我想要一个更好的接口”,“我想把模型和视图分开”,“我要用这个模块而不是那个模块”,“我要重命名这组方法”,或者任何他们不喜欢当前情况的东西。这就是我如何掌握特定开发人员对代码库的了解程度。这也说明了程序员的自我在多大程度上与他所告诉我的内容联系在一起。

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

80925 次浏览

c# / .net:

  • 默认情况下,类应该是密封的
  • 不应该有lock语句——相反,你应该有特定的锁定对象,并且应该有Acquire这样的方法返回一次性锁令牌。推论:不应该每个对象都有监视器。
  • GetHashCode()Equals()不应该在System.Object中——不是所有东西都适合哈希。相反,使用IdentityComparer来做同样的事情,并保留IComparer<T>IComparable<T>IEqualityComparer<T>IEquatable<T>接口用于自定义比较。
  • 对不可变性的支持很差
  • 发现扩展方法的糟糕方式——这应该是一个更有意识的决定,而不仅仅是我正在使用一个名称空间。

这些都是我想出来的,明天问我,我会想出一个不同的5个:)

我的常用语言是爪哇语。这就是我讨厌它的地方:

< p > 5)。缺少指针
4)。异常捕捉< br > 3)。布尔类型
2)。BigDecimal类型< br > 1)。c#粉丝和Java粉丝

Boolean可以为空。我觉得这是违反直觉的。

BigDecimal是一个库,而不是一个语言特性。我对BigDecimalException捕获的烦恼主要源于编写的测试类必须跳过一堆箍才能完成实际工作。我应该澄清一下,我对这些事情很恼火,我不打算游说改变。

c++

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

Python

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

Python:

  1. 太慢了!
  2. 列表操作不会返回列表,因此不能执行List .append(4).append(5)。(我指的是同一份清单的参考,而不是副本)。这是一个小抱怨;它只出现过几次。
  3. 语句不返回值(if、print、while、for等)。这只是在处理时才会出现的问题。
  4. lambda只能是一个表达式。实际上不需要这种限制,因为它们在其他方面都与函数等效。如果我想要一个按钮按事件调用两个函数?我需要创建一个命名函数来为动作侦听器提供该功能,同时执行“lambda: f1();F2()“不会有伤害。
  5. 你只能用标准的a-zA-Z_0-9作为名字。拥有像“true?”和“+”这样的函数会很棒。当然,这可能会导致严重的混淆,但我并不是说我们立即将所有函数重命名为“p@$%3”。你觉得“dec2bin”和“dec->bin”哪个读起来更清楚?("store_results"或" storeeresults ")或"store-results"?

C

  • 字符串操作。

必须手动处理字符串缓冲区是一个容易出错的痛苦。由于如此多的计算实际上是移动和修改字符串(计算机并不像人们想象的那样用于大型数字运算),因此能够使用托管语言或c++的字符串对象来处理这些非常好。当我必须在直发C时,感觉就像在流沙中游泳。

以下是我不喜欢Java的一些地方(它不是我最喜欢的语言):

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

Python:

  • 缺少静态类型
  • 默认参数处理(特别是你可以为将来的调用者change默认参数 !)
  • 需要的下划线太多(构造函数必须调用__init__)
  • 缺少适当的私有成员和函数(惯例只是说大多数以下划线开头的东西都是私有的,除了所有像__getattr__这样的东西)
  • printing到文件的有趣语法(但他们在Python 3中修复了这个问题)

PHP:

  • 我们永远无法确定某些几乎是常见的扩展在所有web服务器上都可用。
  • 试图成为未来的一切(goto,闭包,…)
  • 对于没有经验的用户有很多安全风险
  • 更多的操作符重载会很好
  • 所有不学习如何使它正常工作的可怜的程序员,给它一个坏名声

尽管如此,PHP是(脚本)语言。: -)

我使用Java,我最大的不满是字符串操作的低效率。当你使用+运算符时。说真的,难道编译器不能计算出我添加了多少字符串,然后在后台为我生成StringBuffer的东西吗?

通常,使用+的代码比StringBuffers操作序列更具可读性。

另外,我讨厌本机数组和集合框架之间的冗余。. toarray()的语法极其丑陋。

C(好吧,这不是我最喜欢的,但当时还没人做过。)

  • 套接字库语法。
  • 没有函数重载。 <李> c风格的字符串。 <李>缓冲区溢出。 <李>的语法。我不知道有多少次我查到像atoi这样的东西,拍着我的额头,然后大喊“当然!”

编辑:如果我使用更多的库代码(就像我用套接字做的那样,但那些特别糟糕),我可能会想出更多的库代码,但我已经觉得我选择C语言是在作弊。许多语言的存在只是为了取C语言的好的部分,取代坏的部分,这有点像在徒劳无益。

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

  1. 尽管我是Java泛型的粉丝,但它的设计方式产生了许多奇怪之处。因此,泛型有无数恼人的限制(其中一些是类型擦除的结果)。
  2. Object.clone()和Cloneable接口的工作方式完全被破坏了。
  3. 而不是采取高姿态,把每件事都当作一个对象(a.la。SmallTalk), Sun创建了两种不同的数据类型:对象和原语。因此,现在有两个表示的基本数据类型和奇怪的好奇心,如装箱/拆箱,不能把基元放在一个集合。
  4. Swing太复杂了。不要误解我的意思:使用Swing可以做很多很酷的事情,但它是过度工程的一个很好的例子。
  5. 最后一个抱怨同样是Sun和那些为Java编写XML库的人的错。Java XML库太复杂了。为了简单地读入XML文件,我经常不得不担心使用的解析器是DOM还是SAX?它们的api同样令人困惑。语言中对很容易解析/编写XML的本机支持将非常好。
  6. java.util.Date糟透了。它不仅不必要地复杂,而且所有有用的方法都已弃用(并被其他增加复杂性的方法所取代)。

Groovy和Grails

  1. 动态类型
  2. 约定优于配置,假设您了解约定
  3. 你讨厌春天的一切
  4. 你讨厌Hibernate的一切
  5. [Groovy]跨集合的常见操作不是(但最近的版本对此进行了改进)

c++

  • 太容易随机破坏内存并创建几乎不可能找到的错误(尽管,Valgrind在修复这个问题上有很长的路要走)。
  • 模板错误消息。
  • 在使用模板时,很容易将所有内容都包含在一个文件中,然后进行愚蠢的编译。
  • 标准库在现代是一个笑话(默认情况下仍然没有线程或网络?)
  • 大量令人讨厌的C语言(特别是所有在short/int/unsigned/等之间的转换)。

德尔菲:

  • IDE有点不稳定。
  • 代码洞察有时令人困惑。
  • 调试有时是有bug的。
  • 更新多个项目文件可能会很麻烦。
  • 如果启动时一个或多个包不可用,错误消息会弹出几次。

Smalltalk

  • 我不想再用java、delphi、c#或ruby进行开发(这是不切实际的,因为我公司的主要开发语言是c#、delphi和java)。
  • 从左到右的评估。
  • 有类注释但没有方法注释(至少在Squeak中)
  • 没有真正的标准库,在细节上有很多差异
  • 缺少名称空间

Common Lisp:

  1. 关键词往往太啰嗦。
  2. 库支持是可怜的。
  3. 在希望更严格地处理内存的操作系统中不能很好地工作。
  4. 没有与操作系统交互的良好工具。
  5. “循环”功能没有很好地定义,当然看起来也不像Lispy。

数组部分选择不能给你所要求的。

a[1]给出一个元素
A[1:2]给出一个元素,而不是[A [1], A [2]]
A[1:3]给出2个

的元素

我讨厌这样,但可能是因为我大部分时间都在Verilog上工作。

我将使用PHP,因为我有时喜欢它,而Python将使用太多。

    <李> < p >没有名称空间;一切都在一个 非常大的命名空间 大环境下的地狱

    说到…缺乏标准 函数:数组函数取a 针是第一个参数,干草堆 作为第二个(参见函数的)。 字符串函数通常采用 先干草堆,后针 大小写敏感)。其他函数 使用不同的命名方案: bin2hex 函数, cal_to_jd < / p > 一些函数有奇怪的返回值 价值观,什么是正常的:这 迫使你有第三个变量 在PHP中声明 能有效地解释一个空吗 数组的类型设置为false 杂耍。几乎没有其他的了

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

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

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

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

VBA(含MS Office IDE):

1)文件质量差
2)糟糕的错误消息
3)不充分的数组操作例程
4)必须重复DIM语句的类型
5)不会打印彩色(必须购买第三方插件)

我有一本探索SNOBOL中各种项目的书。第一章探讨了SNOBOL编程和语言的历史和文化,并花了一些时间来论证一个优秀的程序员喜欢一种语言不是因为它的缺陷,而是因为它们中的尽管

我最喜欢的语言是图标/Unicon。但还是有一些事情让我很恼火:

  1. 它不是很出名,也不是很受欢迎。
  2. 与PHP、Perl、Java等相比,它的库要小得多。数据库访问是通过ODBC完成的,这实际上非常烦人。
  3. 尽管它在其他方面有出色的列表处理,但我想念PHP内置的explode()implode()
  4. 它没有表常数。列表,是的,表格,不是。
  5. 它是一种编译(实际翻译)语言。

Ruby有许多与它的速度有关的缺陷,但我不讨厌那些。它也有社区传福音过度的缺陷,但这并没有真正困扰我。以下是我最讨厌的:

  • 闭包(块)有4种不同的创建语法,没有一种是最优的。优雅的语法是不完整的和模糊的哈希,完整的语法是丑陋的。
  • 社区倾向于反对真正的文档,而倾向于“阅读代码”。我觉得这既幼稚又懒惰。
  • 元编程的滥用,尤其是在库中,使得查找bug成为一场噩梦。
  • 与此相关的是,普及元编程使得综合IDE很难(如果不是不可能的话)实现。
  • 块传递给函数的方式很愚蠢。没有理由将块传递到参数列表之外,或者使用奇怪的特殊语法来访问(yield)。我的观点是,块应该被赋予一个不那么模糊的语法(或者哈希可以使用不同的分隔符;可能是<>而不是{}),并且作为参数传递给方法应该像所有其他参数一样。

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

    这些奇怪的事情,比如block必须是传递的最后一个参数,传递多个block是不同的,语法更长,真的让我很恼火

ColdFusion

  1. 大型Flash表单的编译时间。
  2. 动态变量类型(有时我讨厌它们)
  3. CFScript缺乏特性。
  4. CFTable(永远不能正确显示)。
  5. CFChart中缺少图表类型。
  6. 完全缺乏NTLM支持(企业就绪-是的)
  7. cfc中的低能变量作用域
  8. 没有一个真正的NULL的概念-你的变量只是消失!
  9. 没有办法测试某些东西的存在(比如作用域,只是它们内部的成员)

JavaScript

  1. 数字作为字符串-数学可以 数字令人沮丧 解释为字符串。5 + 2 = 52? 李叽阿…< / >
  2. 权限-所有最好的东西都需要用户的权限!
  3. 屏幕更新—浏览器必须处于稳定状态才能更新屏幕。似乎没有一种方法可以强制在脚本中间更新屏幕。
  4. 慢-虽然谷歌的Chrome很好…
  5. 浏览器的差异使语言的使用[审查]。

PHP:

1)强迫我创造不必要的变量:

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

2) lambdas的实现如此蹩脚,它大致相当于使用eval(),如此糟糕的错误,我从未使用过它(参见http://www.php.net/create_function)。

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

4) Regex支持和lambda支持一样蹩脚,因为它必须在常规字符串中编写,这使得最难学的编程工具之一变得困难了三倍。PHP应该是一种“简单”的语言吗?

5)没有办法安全地从$_POST中取出东西,而不写两次或构建自己的函数,或使用'@'操作符:

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

6)额外答案:“@”。如果你懒得写正确的代码,那就添加'@',这对以后调试你的代码的人来说太糟糕了。

JavaScript:

  1. 所有最酷的东西都非常复杂,但是,所有最酷的东西都被包裹在如此少量的代码中,以至于你觉得努力遵循它很愚蠢

  2. 在弱类型语言中,'+'是一个荒谬的连接操作符选择。他们尝试吓退菜鸟吗?

  3. 这是一个跨浏览器兼容性的雷区(不管它是否打开)

  4. 它通常是不可信的——与诸如阻止后退按钮、永不消失的弹出窗口等卑鄙行为联系在一起。

  5. 调试几乎是不可能的,因为只有几种不同的错误消息和几种不同的类型(数字、字符串、对象等)。

如果不是jQuery,我可能还是会像以前一样讨厌它:)

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'
      

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

    Perl6中是:

    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
    

    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
    
  • Lack of multiple dispatch

    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
    
  • Poor Operator overloading

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

    Perl6中是:

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

c++

  1. 编写一个简单的代码片段要花很多时间。
  2. 对于(std::vector::const_iterator iter =[…]
  3. Vector.remove()不移除。
  4. Vector.push_front()不存在。
  5. 头文件
  6. 没有λ
  7. 如果至少有一个虚函数,则没有自动空虚析构函数。

Haskell:

  1. 惰性计算导致空间泄漏。
  2. 数字层次结构不是根据数学抽象构造的。
  3. 严格的单元IO会使调试更加困难。
  4. 大型实现处理I/O的方式似乎与标准不太兼容。(特别是,输出字符只输出低8位——然后构建代码,使用这个假设来执行二进制I/O。我吐!)
  5. ($)运算符的结合性可以被改变以使某些表达式更漂亮。

大多数问题都不会上升到讨厌的程度,有些人试图解决或为每一个问题构建可靠的变通办法。

编辑:关于第5点有些困惑。特别是有些人似乎认为我指的是论证的顺序,但我不是。我不解释我的意思,我只指出人们下面的链接,http://hackage.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity,它很好地表达了它。

objective - c

1)没有命名空间,只有手动命名约定——我不介意在类分离方面,但我确实怀念能够在一行命名空间中导入所有类定义(如import com.me.somelibrary.*)。

2)库在像RegEx支持这样的重要领域仍然存在一些漏洞。

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

4)我喜欢保留/释放模式,但它比应该的更容易释放一个引用,然后意外地使用它。

5)虽然不是真正的语言特性,但Xcode与Objective-C的使用是如此交织在一起,我不禁想到这方面……基本上自动补全,是很可疑的。它更像是一个奖励你找到你想要的东西的系统,然后把它作为一个选择。但我想我从来都不喜欢自动补全引擎。

VB6

  1. 仅Windows。
  2. 不再支持。
  3. 数组可以从任何数字开始,而不是全部归一化为0。
  4. 已编译的应用程序依赖于许多dll才能正常运行。
  5. 许多复杂的控件(如浏览器控件或复杂的代码段)在运行未编译的代码时往往会破坏IDE,但在编译后却可以正常工作。

C / c++

  1. 缺乏完整的SWAP功能
  2. 模板的语法
  3. 你不能#define一个#define(没有多通道)
  4. 编译器之间的结构打包不兼容
  5. Char是有符号的还是无符号的?

Java

  1. 边缘上的不变性
  2. 没有像c#一样的ref关键字
  3. 到处尝试/捕捉积木
  4. 运行时性能差
  5. 所有与字符串相关的东西

Python

  1. 没有“main”(我已经习惯了!)
  2. 强调关键词
  3. 有限的线程支持
  4. 用self代替this
  5. 缺少类似C/ c++的语法

c#

  • c# 4.0为泛型类型引入了协方差和逆变性
  • 可覆盖的类成员必须显式地标记为虚拟

Java

  • 缺少无符号数字数据类型
  • 基本数据类型不是对象

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

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

VB。网

  • 行为AndAlso / OrElseAnd / Or似乎是反向的。也许他们应该交换一下。
  • When只能用于异常捕获。能够执行When条件对于其他一些事情来说是很好的。
  • 在VS IDE中没有像c#那样的重构(不是语言的错)
  • Not <obj> Is Nothing。是的,这已经被IsNot弥补了,但出于某种原因,我看到Not Is被使用得太频繁了。(我在以英语为第二语言的开发者中更常见这种情况,从这个角度来看是否更合理?)
  • 它不需要ToString()和大多数函数上的()。(导致草率的编码习惯)
  • 断行时必须执行_
  • 它允许可选参数。(导致草率的编码习惯)
  • 声明数组是通过UpperBound完成的,而不是通过容量。“Dim arr(2) as String” 实际上包含3个元素。李< / >
  • =作为比较而且赋值操作符。

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

  • 跨实现的语法不一致
  • 细微的代码差异可能会因为看似模糊的原因而产生巨大的性能影响
  • 对文本操作的支持很差
  • 入门成本低,但掌握这门语言的学习曲线陡峭
  • 最大限度地标准化社区的最佳实践,这包括语法风格。

...还有一些额外的讨厌它的理由,不需要额外收费

  • WHERE子句放在最后,很容易过早地执行UPDATE或DELETE,破坏整个表。相反,WHERE应该放在前面的某个地方。
  • 实现关系划分是很困难的。
  • 我可以将一个值设置为NULL,但我不能测试它是否与NULL相等。我可以检查IS NULL,但这只是复杂的代码-没有必要,在我看来。
  • 为什么我们需要为分组列完全重新指定公式,而不是在列上设置别名,然后根据别名进行GROUP BY(或与SORT一样的列索引)?

PHP

  1. 如果你不能控制服务器,就没有调试功能,即使这样也很糟糕
  2. 大量糟糕的PHP代码给所有PHP程序员带来了坏名声
  3. 不一致的函数命名
  4. 如果我想要一个静态类型变量,就不能有一个静态类型变量(我90%的时间都是动态类型的忠实粉丝)
  5. REGISTER_GLOBALS是魔鬼

Objective Caml

  1. 缺少名称空间。
  2. 啰嗦类和对象注释。
  3. 复杂的构建系统。
  4. 不方便制作中缀。

Python:

  • 速度
  • 静态分析(缺乏)
  • 匿名函数仅限于一个表达式

VB。网

1) If Not x Is "foo"(而不是<> "foo")
2)“OrElse”和“AndAlso”短路(而不是简单的“Or”和“and”,它们的作用不同)
3) Nothing(而不是Null)

Delphi(又名Object Pascal),我将讨论本机版本,而不是。net。

  • Var块!
  • 语言中的接口在设计时就考虑到了COM的使用——因此比c#或Java要复杂得多。ie。涉及引用计数,除非显式禁用它。
  • 没有try except finally end;
  • 对象创建过于明确:

    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.
  • 好吧,语言太好了,我真的想不出更多,所以我在这里强迫自己:内置类型,如字符串,整数..或者枚举最好有方法。ie。i.ToString代替IntToStr(i)

Ruby:

  • 重要的空白。对于解释器,行尾=语句的结束,除非看起来语句应该继续(或者显式转义换行符)。
  • 在线文档不如Python的好(为了辩护,Python的很棒)
  • 我刚才提到慢了吗?

Python:

  1. 全局解释器锁——处理这个问题会使并行处理复杂化。
  2. Lambdas函数有点笨拙。
  3. 没有内置的有序字典类型。
  4. 根据Python的编译方式,它可以使用UCS-2或UCS-4进行内部Unicode编码,对于超过默认宽度的多字节字符,许多字符串操作符和迭代器可能会产生意想不到的结果。字符串切片和迭代依赖于位宽,而不是检查和计数字符。(大多数其他编程语言也做类似的事情,并且对这些字符有类似的奇怪行为。)
  5. Python的GUI框架存在不一致性。

Python

  • 错误/异常在调试时是模糊的
  • 我工作时不用
  • 在类中使用__init__, __repr__, __str__等
  • 不能简单地编译可执行文件(.exe或其他)
  • 还有一件事我还没试过,但肯定会让我心烦

对于所有的c语言程序员来说,self对我来说更有意义,因为对象引用的是它的self

Ruby

  1. 无类型推断
  2. 方法/函数不是一级对象
  3. 变量的范围不是词法的,尽管块变量的范围是词法的
  4. Def内部的Def
  5. super和super()的区别

c++

    <李> < p > 字符串。 < br > 它们不能与平台字符串互操作,因此有一半的情况下您最终使用std::vector。没有定义拷贝策略(写时拷贝或深度拷贝),因此不能为简单的语法提供性能保证。有时它们依赖于STL算法,使用起来不是很直观。很多库都有自己的库,不幸的是,这些库使用起来要舒服得多。除非你必须把它们结合起来。李< / p > < / > <李> < p > 字符串表示形式的多样性 < br > 现在,这有点平台问题——但我仍然希望,如果更早有一个不那么顽固的标准字符串类可用的话,情况会更好。以下字符串表示我经常使用:

    • 通用LPCTSTR,
    • LPC(W)STR由CoTaskMemAlloc分配,
    • BSTR, _bstr _t
    • (w)字符串,
    • 装运箱,
    • std::向量
    • 一个自卷类(叹息),它将范围检查和基本操作添加到已知长度的(w)char *缓冲区中
    • 李< / ul > < / > <李> < p > 构建模型。 < br > 我已经厌倦了在“谁包含什么”、前向声明、优化预编译头文件和包含文件以保持至少可以承受的增量构建时间等方面花费的时间。八十年代很好,但现在呢?要将一段代码打包以便可以重用,有太多的障碍,甚至连妈妈的狗都听我说烦了 <李> < p > 很难解析 < br > 这使得外部工具尤其难以编写和正确使用。今天,我们c++的人在工具链上是最缺乏的。我喜欢我的c#反射和委托,但我可以没有它们。

      <李> < p > 穿线太难了 < br > 语言甚至不承认它(到目前为止),编译器的自由-虽然伟大-是痛苦的
    • 静态按需初始化 从技术上讲,我在这里作弊:这是“为重用而打包代码”中的另一个难题:只在需要时才初始化某些东西是一场噩梦。所有其他redist问题的最佳解决方案是将所有内容都扔到header中,这个问题表明“neeener - you cannot”


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

方案:

  • 缺乏用户/社区小

我觉得最喜欢的语言是不可能选择的。动态类型和静态类型不能进行比较,所以我只列出我使用的是哪一种类型

c++:

  • 模板元编程语法很难看。隐式::value将使它更加简洁
  • ->.为什么编译器不能知道我在做ptr.thing,而只是为我做-> ?
  • 我讨厌空格。所以整个vector<vector<int>>必须是vector<vector<int> >,这让我感到不安,然后每当我看到那行代码时,我就无法集中注意力,最后我试图找出一种使用int[][]或其他东西的方法
  • 宏。我个人很喜欢宏的概念。但是用c++,我觉得这个系统就是个黑客
  • 我讨厌;

Python:

  • 字符串是不可变的。这样我就不能用string[4]="b"
  • 通过引用隐式复制列表。哪个泄漏到[[0]*width]*height问题
  • 缺少尾递归(每当我输入错误递归函数时,我必须安装IDLE以避免吐出1000条错误消息)
  • 字典键不接受列表/字典
  • 缺乏深度范围。当我做一个列表推导时,我不希望其中的变量影响到外部作用域

Python:

  • 处理数字太慢了。这不是什么大问题,除非……
  • 不能简单地在程序中包含导入时自动编译的C代码。
  • 在py3k接管之前,我们仍然要忍受愚蠢的整数除法规则。
  • 在py3k接管之前,像imap和izip这样的好东西仍然存在于一个单独的模块中。
  • 在py3k接管之前,我们还有很多工作要做。

c#中缺少预处理器。

我知道他们把它放在一边是因为有些人会滥用它,但我认为他们把孩子和洗澡水一起倒掉了。代码生成被认为是一件好事,在c++中,预处理程序是我的第一个代码生成器。

我讨厌Java的五个方面:

  • 没有一级函数。
  • 没有类型推断。
  • 缺乏理智的默认值在eg图形。
  • NullPointerException不包含更多关于什么是null的信息。
  • 毫无意义的“可配置”框架/服务提供者接口/工厂类/依赖注入系统的激增。可配置性几乎从未使用过,严重违反了DRY,代码的大小增加了四倍,易读性减少了一半。

我知道,我应该试试Scala。

Python

  • 1-3:没有一个明显的打包/构建/文档系统的选择(例如Perl的cpanPOD或Ruby的gemrakerdoc)。

  • 4: Python 3.0是不兼容的,需要两个源分支(2。x和3.x)用于每个Python项目。但是Python 3.0是不是不兼容,足以证明它是正确的。大多数py3k的优势都太微妙了。

  • 5: Jython, IronPython, CPython不兼容。

c++

  • 库中与char*和std::string相关的不一致。所有c++库都应该接受std::字符串。

  • 对于iostream,字符不是字节。我做了很多面向字节的工作。拥有一个“字节”类型和一个“字符”类型会大大简化它。这也将允许更容易地扩展到Unicode。

  • 位操作对一个值应该很容易。我应该能够访问和设置值的第n位,而不玩and /OR舞蹈。

  • gui缺乏标准化的界面。这就是微软能够用c#很好地定位自己的地方。操作系统制造商提供的标准接口绑定对我的工作大有帮助。

JavaScript

  1. 函数对象语法:

    f = new Function( "foo", "bar", "return foo+bar;" );
    

    (它有n个参数,第一个n-1 那么,函数是参数吗 n是实际的函数,in 字符串形式。这是愚蠢的)

  2. 函数参数可以为 重复。< / p >

    f = new Function( "foo", "foo", "return foo;" );
    

    最后一次重复是唯一一次

    f( "bye", "hi" ) // returns "hi"
    f( "hi" ) // returns undefined
    
  3. 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.

  4. A standard notion of stdin/stdout/stderr (and files!) would be nice.

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

再给c++投一票…仍然是我最喜欢的语言,有几个亲密的追随者——C和Python。以下是我目前最讨厌的名单,排名不分先后:

  • 继承自C语言的过多的整数类型——有符号和无符号的错误导致了太多的问题
  • 复制构造函数和赋值操作符——为什么编译器不能自动从另一个创建一个?
  • 变量参数的疯狂——va_list只是不能与对象一起工作,我厌倦了sprintf(), snprintf(), vsnprintf()和所有它们的亲戚所产生的问题。
  • 模板实现需要在编译时完全可见——我认为缺少“导出”实现或至少可用的实现
  • 缺乏对属性的支持——我想有一个像“a.x”这样的只读成员,可以公开读取,只在内部赋值。我真的很讨厌“val=obj.getX()”和“obj.setX(val)”。我非常希望属性具有访问控制和一致的语法。

Lua

我喜欢用Lua编程,但下面是让我头疼的事情:

  1. 没有办法用这种语言编写API——不像C .h文件或Java接口
  2. 语言有一流的功能,但有人忘记告诉设计库的人。
  3. 编写函数的语法太重量级了。
  4. 语法分为语句和表达式。
  5. 表达式形式是贫乏的:没有let形式,没有真正的条件表达式,……

尽管如此,我还是坚持认为Lua非常棒:-)

f#

  1. 类型推断是有限的。

    1. 它只向前传播。

    2. f#不会尝试基于所使用的方法和属性来推断对象类型:当它没有线索时,你会得到“查找不确定对象类型”的错误。

    3. 李< / ol > < / >
    4. 浮点数和整型不能混合:1 + 2.3是类型错误。

    5. 为了定义单子或计算表达式,必须创建一个构建器对象,这有点尴尬。在Haskell或Scala中,你可以直接在monadic对象上定义monad操作。

    6. 尽管首选#light语法,但缩进规则有时不是很直观或很麻烦。

Perl 5:

  1. 现在所有真正的好东西似乎都需要mod_perl,它在我想去的任何地方都具有低可用性。
  2. 一些真正令人难以置信的功能可以封装在模块中,但隐藏在模块之下的东西往往是脆弱或可怕的:源过滤器、typeglob,无论Moose在做什么……
  3. DateTime很出色,但仍然做出了一些非常糟糕的设计决策(当减去两个DateTime对象时不返回秒表持续时间)
  4. 核心和CPAN上的双生命模块仍然会引起冲突
  5. 模块作者仍然在模块配置脚本中放入交互内容,这样就不能自动安装

Python

  • __init__
  • 有些库很笨拙,比如smtplib
  • self必须在方法声明中!!
  • (3.0之前)对unicode的支持有点差
  • 缺少内联尝试捕获
  • 没有直接引用"this"/current模块(而是必须使用sys.modules[__name__])

JavaScript:

  • Object原型可以被修改。程序中的每个对象都有新的属性,有些东西可能会坏掉。

  • 所有对象都是哈希映射,但是很难安全地使用它们。特别是,如果你的一个键恰好是__proto__,你就有麻烦了。

  • 在函数引用时间没有对象闭包。事实上,根本没有对象闭包——相反,只要使用对象表示法或new操作符调用函数,就会设置this。导致很多混乱,特别是在创建事件回调时,因为this没有设置为程序员期望的值。

    • 推论:调用函数没有对象表示法或new操作符会导致this被设置为等于全局对象,导致大量破坏。
    • 李< / ul > < / >
    • 重载的加法运算符也执行字符串连接,尽管这两个操作有本质上的不同。当您期望为数字的值实际上是字符串时,将导致痛苦。

    • ==!=操作符执行类型强制转换。不同类型之间的比较涉及到一系列的规则,没有人能完全记住。===!==操作符的存在缓解了这一点。

    • nullundefined都存在,它们的含义略有不同,但却是多余的。为什么?

    • 设置原型链的奇怪语法。

    • parseInt(s)期望c风格的数字,因此将前导0的值视为八进制,等等。你至少可以parseInt(s, 10),但默认行为是令人困惑的。

    • 无块范围。

    • 可以多次声明同一个变量。

    • 可以使用一个变量而不声明它,在这种情况下,它是全局的,可能会破坏你的程序。

    • with { }

    • 真的很难用JavaDoc之类的工具来记录。

我可以为Python添加另一个:

给定一个列表l = [l1, l2, ..., ln],然后repr(l) = [repr(l1), repr(l2), ..., repr(ln)],但是str(l) != [str(l1), str(l2), ..., str(ln)] (str(l) = repr(l))。这样做是因为列表中有可以的模糊条目,如l = ["foo], [bar,", "],["]str(l)将返回"[foo], [bar, ], []",这“可能会使用户困惑”。然而,这使得str不可能仅用于转储数据,因为list杀死了“仅以可读格式转储数据”。Augh !

JavaScript

  • 每个脚本都在单个全局“命名空间”中执行……在使用来自不同来源的脚本时,您必须注意这一点

  • 如果一个变量在使用之前没有定义,它被认为是一个全局变量

  • 浏览器厂商随心所欲地制定标准,使得我们这些开发人员使用如此美丽的语言编写代码变得更加困难

  • 区分大小写——考虑到目前还没有合适的IDE来开发带有编译时检查功能的js

  • 变通方法(例如使用hasOwnProperty方法)来执行一些其他简单的操作。

ActionScript / AS3

  • 没有抽象类
  • 没有私有构造函数(所以单例是一种hack)
  • FP10之前没有类型化数组
  • Flash IDE中的编译/发布时间慢得离谱
  • 内置函数(例如Math)的性能较慢

除此之外,它实际上是一种很好的语言——与流行的观点相反,它比JavaScript好得多,比PHP之类的语言好一百万倍。

计划

  • 缺少静态类型
  • 没有静态函数重载(由于上述原因)导致字段访问器的名称很长
  • 没有统一的对象系统
  • 有点慢
  • 相对较小的社区

MEL(玛雅表达语言):

  • 一维数组:强迫我手动同步两个或多个列表,或使用分隔字符串来模拟更复杂的数据结构。当然,它们也是不可变的。
  • 单线程慢:导致整个Maya应用程序挂起,而它完成一个任务。额外的点是不能杀死长时间的操作,而是必须关闭和重新打开玛雅。
  • 脚本来源路径不是递归的:意味着你想要存储脚本的每个目录都必须添加到脚本路径中。
  • 没有命名空间:强制使用不一致的命名约定,以确保全局过程不冲突。
  • 模态命令:每个命令都是模态的,这意味着创建、修改和查询操作都通过设置标志来处理。这也迫使开发人员使大多数命令返回数组
  • 命令风格不一致:大多数数组命令实际上返回数组,但Tokenize命令必须接受一个数组作为引用,然后填充,而不是吐出一个数组。这是其他矛盾之一。

这些以及其他几个原因是AutoDesk采用Python作为次要脚本语言的原因,这带来了其他一些令人讨厌的因素:

  • 不是所有的MEL命令都被支持:大多数是,但时不时你会发现自己不得不使用mel()函数来执行一些任意的代码。更糟糕的是,你不得不对它进行所有烦人的逃避。
  • 继承了模态命令样式:必须使用相同的create=True, query=True, edit=True的东西。

Perl代表了一种可怕的语言。

  1. 没有“公共”或“私有”或“受保护”声明/定义。
  2. “my $variable_name;”没有在子例程之外声明全局变量。
  3. “my $variable_name;”可以被子例程访问,但“use strict;”或其他“use”会产生警告。
  4. 函数原型最终无法解释,没有演示,不需要,或者其他原因。
  5. 在阅读大量符号时,过度热心地使用符号会导致“酷而快速”的结果。
  6. 当一个人热了,他们喜欢保持热,不需要任何东西来冷却他们。
  7. 在使用了一个星期的Perl之后,我最终无法编写一个函数并创建它的原型。
  8. 一个模块究竟是什么,它实际上需要一个”。点“扩展?
  9. 如果您想创建一个公共变量并从子例程内部访问它,如何在不创建警告的情况下完成这一任务?
  10. 在哪里可以找到一些简洁的脚本来教人们一些简洁的Perl代码呢?

net框架(库)

  • 嵌套类型很少使用(例如MessageBoxButton应该是MessageBox.Button)
  • 可变结构(RectPoint)
  • System命名空间中有太多东西
  • 太多不同的平等概念(Object.EqualsObject.ReferenceEqualsoperator ==operator !=IComparable.CompareTo() == 0)
  • 数组的成员是可变的,但长度是不变的。

还有一点:

  • XmlSerialization不适用于不可变类型

c#

  • 我希望我可以在任何类型上switch(),并且case可以是任何表达式。

  • 不能使用'readonly' fields / private set autoprops的对象初始化语法。一般来说,我需要语言帮助来创建不可变类型。

  • {}用于命名空间方法属性/索引块多语句块数组初始化器。当他们相隔很远或不匹配时,你很难弄清楚你在哪里。

  • 我讨厌写(from x in y ... select).Z()。我不想因为查询语法遗漏了一些东西而不得不退回到方法调用语法。

  • 我想在查询语法上有一个do子句,就像foreach一样。但这并不是一个真正的问题。

我真的到达这里了。我认为c#非常棒,而且很难发现它有什么缺陷。

c#

我的大部分抱怨都与假设c++约定自动成为c#的最佳选择有关

  • Class接口中不允许静态。它仍然是类的一部分。为什么它不能成为界面的一部分?我不得不想出这么愚蠢的变通办法。
  • 区分大小写。我知道在这一点上它会破坏遗留的应用程序,但为什么不区分大小写不是一开始的规则

net的好处之一(不是c#特有的)

  • . net 3中的编译器不够聪明。。X,编译器可以找出“var”在编译时,为什么不其他常见的优化?我们都知道string和StringBuilder / immutable和mutable的区别。为什么编译器不为你转换它在很多情况下,显然StringBuilder比多个connect .s更好?我相信在默认情况下,编译器可以为我们做大量的其他优化(带有否决选项),并为我们节省大量的时间。

c++:

  • 缺乏象征意义。
  • 过度迷恋C语言的兼容性。
  • 极其复杂的预处理器。
  • 模板错误几乎是不可理解的。
  • 没有垃圾回收。

Javascript;

  1. 如果您不知道自己在做什么,“this”的动态绑定是非常令人困惑和危险的。
  2. 函数声明需要关键字“function”。我反对的不是打字,而是当我想做一些稍微聪明的事情时阅读它。嗯,现在我想也许这是一个加分项。阻止我做聪明的事情。
  3. 第2点的结果是,如果它是一个相当短的习惯用语,那么仅仅复制/粘贴一个代码段通常比将它声明为一个函数更少的代码(就字符而言)。不幸的是,这促进了糟糕的实践,特别是在我自己的代码中。
  4. Javascript通过拥有第一类函数和闭包而成为函数式语言,但是没有办法在运行时或编译时验证函数中的引用透明性。如果没有这一点,一些体系结构要么变得危险,要么变得笨重。
  5. 它的坏名声令人难以置信,因此我无法向任何人说“我用javascript编程”而不被嘲笑。

C是我最喜欢的,但也很糟糕。

  • 它有史上最差的预处理器。为什么他们不用m4这样的东西?
  • 整个头文件vs源文件 模型坏了。帕斯卡是对的 与单位。李< / >
  • 需要大小写范围为 switch语句。李< / >
  • void*中的联合和强制类型转换将破坏类型系统。这使得垃圾收集器变得不可能。
  • 没有嵌套函数。GNU C有这个功能,但它应该是标准的。
  • 没有分配内存的边界检查。有一些工具可以发现这一点,但是 当一段代码计算错误并写入地址时,它们不会检测错误 分配到一个完全不相关的区域。我讨厌整个指针 李算术。< / >
  • 没有数组的边界检查。
  • 太多关于可移植性的问题。甚至wchar_t也因平台而异。

c#

它是一种伟大的语言,特别是与LINQ,但泛型支持很差与c++相比。它有如此多的潜力,但目前的实现只对强类型集合和类似的琐碎事情有用。下面举几个例子:

  • 泛型参数不能局限于枚举(只能是类或结构)。
  • 泛型参数不能是静态类。为什么?这似乎完全是人为的限制。
  • 不能指定泛型类型必须具有具有特定签名的构造函数,因为不能在接口上使用构造函数。为什么不呢?它只是另一个具有特殊名称“。ctor”的方法。
  • 类似地,不能指定泛型类型必须具有静态方法,因为这些方法也不能在接口上声明。像static T Parse(string s)这样的东西通常会很有用。
  • 编译器太急于禁止一些程序员知道实际上会起作用的类型转换,所以它们需要像(TheRealType)(object)value这样的丑陋类型
  • 没有协方差。IList<string>不能被转换为IList<object>,尽管string[]可以被转换为object[]。(不过微软可能会在c# 4.0中修复这个问题。)

PHP

  1. 没有构造函数重载
  2. 不一致的函数命名(str_replace,但strtolower)
  3. define()不像c++那样逐字替换全局变量。
  4. 在与XHTML组合时,像if-语句这样的语句必须以不缩进开始,即使为了保持XHTML缩进一致,XHTML是缩进的。

例:

你必须输入:

<?php
if($x == NULL)
{
?>
<p><?= $x . ' is null' ?></p>
<?php
}
?>
  1. 错误捕获非常糟糕

(不知道为什么又把5号改成了1号,随便了)

R (R- project for statistics)

  1. 糟糕透顶的字符串支撑
  2. 对于一些简单的描述任务,比如交叉表格,是非常困难的
  3. 大型数据集操作是在内存中完成的。

Emacs Lisp

  • 目前还没有足够的商业市场让人们全职用elisp编码
  • GNU Emacs vs XEmacs不兼容
  • Scheme中的嵌套函数很整洁,我希望elisp有[1]的概念
  • 用于简单遍历列表的do循环或其他一些工具不是标准的(当然,您现在可以使用lambda进行映射)[1]
  • (function (lambda(…)))[1]应该有一个简写

当然,Lisp的一个美妙之处在于,用一行代码在你自己的代码中修复这些问题并不难。但这并不是与生俱来的,这让我很恼火。

好的问题;我有点不好意思,因为我想不出更好的东西来恨,但说实话,法官大人,没什么好恨的。

自我

  • 没有真正的代码浏览器 数百个小窗户飞舞 周围。李< / >
  • 只是研究项目, 不够稳定,没有活动 李社区。< / > 没有像样的快速版本 适用于Linux或Windows。仅支持Mac OS x
  • 不支持标准键盘 李命令。< / >
  • 哦!关于编写本地插件的文档也太过时了!

Python。

虽然前面提到了python处理作用域的奇怪方式,但我觉得最糟糕的结果是:

import random


def myFunction():


if random.choice(True, False):
myString = "blah blah blah"


print myString

也就是说,if块内部的作用域与函数的其余部分相同,这意味着变量声明可以出现在条件分支内部,并且可以在条件分支外部访问。大多数语言要么阻止你这样做,要么至少为你提供某种严格的模式。

此函数有时会成功,但有时会抛出异常。虽然这是一个人为的例子,但这可能会导致一些微妙的问题。

c#(好吧,我猜一部分是VisualStudio IDE):

  • 没有协方差(还没有),比如Class<D>不能用来代替Class<B>,即使D类型派生于B类型。
  • 图形设计器不支持基于泛型的继承(或从抽象类继承),即使继承本身工作得很好,如果你通过添加额外的继承级别来解决设计器的问题,这样设计器总是能看到你代码的具体的非泛型变体。
  • 没有构造函数继承
  • 泛型类型参数的where子句中没有构造函数
  • VisualStudio在打开一个解决方案时似乎有一种神秘的检出文件(如项目文件和/或单元测试定义)的倾向,即使这些文件似乎并没有实际被修改。

如果你明天再问我,可能会有不同的名单。即使协方差和设计师的麻烦将在我的前5名,直到他们被解决(随着方差添加到c# 4.0,这似乎已经发生了至少一个…)

Lua

我喜欢这门语言,但是有一些事情困扰了我很多年!

  • 不支持(内置的)二进制操作(从5.1开始,可能会随5.2一起提供)。
  • 应该有一个内置的二进制缓冲区实现,例如允许长字符串连接。
  • 我知道它不太符合语法,但有时我会错过longVariableName++或verboseVariableName += 5。
  • 参考假设知识C(我有它,但它是一个减去新人)和推迟一些帮助C参考!有时它太简洁了。
  • 它开始有很多图书馆,但你必须从不同的地方获得它们。另一方面,下载量非常小!: -)

Lua:

  • 我明白其中的原因,但说真的。默认情况下,变量应该是本地的,使用global关键字,反之亦然。
  • 我一般不太喜欢do/end样式语义。我更喜欢c风格的牙套。
  • 动态类型。我知道,你们有些人会说“啊?”但我完全被知道给定变量中会有什么类型的数据所宠坏了。常量if (type(var) == "string") then stuff() end是一个痛苦。
  • 在使用变量之前不需要定义变量。我更愿意明确我想做什么,而不是冒着拼写错误导致我喜欢称之为“古怪的豆子”的风险。

PHP:

  • 同样,动态类型。
  • 缺少闭包。我知道,你可以做$function($arg);,但那不算数。
  • 同样,变量可以在定义之前使用。我有一个个人策略,总是在使用任何变量之前显式地将其初始化为已知值,并且我将其扩展到我可以控制的任何最佳实践文档。

C / c++:

  • 头疼=脖子疼。
  • 不支持闭包。(我对c++ 0x很兴奋,因为c++ 0x有这些功能。)
  • 静态类型。“等等,”你说。“你刚才说你不喜欢动态类型!”是的,我确实这么说过。但是静态类型也会让人头疼。(如果有选择的话,我仍然会选择静态类型。)最理想的情况是,我希望语言默认是静态类型的,但也支持动态类型。(我还想要一匹小马,500亿美元,还有整个世界。)

Ruby:

  1. 太慢了
  2. 自负的群体
  3. 这不是闲谈
  4. 在nil上调用方法时出错,而不是返回nil à la Objective C
  5. 非线程

C:

  • 缺少函数指针(可执行)和数据指针之间的区别(你真的不想执行这个)。
  • 极端unreadability。让代码看起来像它所做的事情,比让它首先完成任务要困难几个数量级。
  • 对口齿不清的思考缺乏明确的支持。做一些功能性的事情是可能的,但还不清楚。
  • 库之间关于错误代码返回方式的严重不一致。
  • 过时的字符串处理。字符串不是字符串,它们是以空结束的blobs。这完全是令人畏缩的。

Lisp:

  • ()需要按shift键。每次我口齿不清的时候,我就把它和[]交换。

Java:

  • 没有过程编码,它编译成过程代码,所以让我使用它!
  • 没有多重继承,试图用15,000个接口做同样的事情很糟糕。
  • 约会课,我还需要多说吗。
  • 我不能充分利用多态性。Java不会覆盖不同的参数类型来触发。
  • 我想不出第五个原因,如果我知道,我会回来编辑这篇文章。

Python

  • 我终于习惯了打印语句,现在有了这个打印函数??(py3k)
  • 从来没有得到py2exe或cxFreeze工作
  • 不标准化(轻微挑剔)
  • 递归深度只有100 (iirc)

Perl

我喜欢这门语言,我不想添加已经被使用过的东西,但还没有人提到过这一点,所以我就把它扔到锅上。当我使用这个特性时,我发现这是我一生中最可怕的经历(而且我用过汇编语言):

  • write()format()函数。

它们有你能想象到的最糟糕、最丑陋、最可怕的语法,然而它们并没有给你任何比你已经用一些(无限漂亮的)printf()工作所能实现的更多的功能。没有一个人应该尝试使用这两个函数来做任何输出,只是因为它们有多糟糕。

我相信有人会不同意,但是当我研究它们,希望它们能解决我的问题时,我发现它们是一个“痛苦的世界”(引用Big Lebowski的话),我希望Perl6已经消除了它们,或者更好的是完全重写它们,使它们在某种程度上更可用和有用。

Oracle SQL

  1. DUAL表。

  2. 不能GROUP BY别名。

  3. 我永远记不住分析函数的语法,所以我忘记/懒得使用它们。

  4. 缺少组合的LIKEIN条件操作符。(在10g之后,有一个REGEX_LIKE操作符可以做到这一点。)

  5. 笨拙的连接语法。

SQL并不是我最喜欢的语言,但它是我每天使用的三大语言之一。可能还有更多的项目,但这些是我脑海中最重要的。

我有一大堆的问题与SQL*PLUS。我写了一个Perl替换程序,它可以从命令行完成我想做的事情,并且我在Emacs中使用sql.el进行交互式SQL会话。这些工具帮助我解决我的SQL*PLUS问题。


说到这里:

Perl

  1. “只有perl可以解析Perl。”(但这主要是语法高亮的问题,我不喜欢在任何语言中使用它。)

  2. 我有时会惊讶于“简单的(但偶尔令人惊讶的)规则……:它看起来像一个函数,因此它是函数,优先级不重要。”(从perlfunc(1))

  3. 对复杂数据结构的解引用有时会令人困惑。我不能确定这是Perl中的一个真正的缺陷,还是拥有真正强大的数据结构工具的结果。无论哪种方式,我通常都可以花几分钟思考一下我在做什么。

  4. 没有像DBI模块那样导致系统调用引发错误的选项。(感谢brian d foy,我现在知道CPAN上的autodie模块可以做到这一点,但我希望它是内置的。)

  5. 在脚本中默认不启用警告和限制。(-e选项将关闭它们以供命令行使用。)

同样,肯定还有更多的事情,但这些是我最近注意到的问题。我将添加=over=back的需求,以及POD中古怪的L<...>语法,但也许这应该是一个单独的列表。


现在来看看三连冠:

KornShell

  1. 用参数源文件将替换父脚本参数的值。(执行. file arg1会将arg1放到$1中。)

  2. ksh不是一个理想的交互式shell,默认为vi键绑定,而不是emacs。(我的解决方案是使用bash进行交互式shell。)

  3. 常见的实用程序(比如grep)在不同的平台上以不同的方式实现,从而阻止了完美的可移植性。一些有用的命令需要安装在某些平台上,而在其他平台上则是操作系统核心的一部分。

  4. 条件句的语法过于繁杂。(if [ ... ]; then ... fi)

  5. 尽管它是图灵完备的,但您最终还是会想要升级到一种表达能力更强的语言,比如Perl。

第4个问题的一个解决方案是习惯短路评估:

[ ... ] && ...

D

  • 我们有内部运算符,但是没有,内部运算符?
  • 动态数组“长度”属性-你不能做

    array.length += 512;

  • 没有退出语句——就像在python的sys.exit()中那样。当然,您可以调用C的退出,但未刷新的输出不会被刷新
  • 关联数组字面量+字符串字面量吮吸

    在关联数组字面值中找到的字符串字面值被解释为静态,因此尽管
    ,但由于字符串字面值长度不同,如果没有一些额外的强制转换,

    char[][char[]] hash = ["hello":"world","goodbye":"angels"];

    将无法工作 a.我没有要求它被解释为静态数组
    B.关联数组中不允许使用静态数组

  • 不允许循环依赖关系(想移植Java库吗?享受重新设计类层次结构的乐趣)

谁帮我检查一下;不确定它们是否都有意义。

C

  1. 位域——它们不是由语言很好地指定的,它们的工作方式取决于编译器和体系结构。
  2. 通常很难在大量代码中找到特定符号的定义位置,特别是如果该符号是由宏生成的。这提醒了我…
  3. 预处理器是一个相当丑陋的黑客,容易受到各种滥用。
  4. 缺乏标准大小的整数(最近被uint*_t弥补了,但还有很多很多旧的代码漂浮在那里,自定义类型defs或#定义DWORD, WORD, BYTE等)。
  5. 缺少类似于Perl的cpan.org的东西(我希望在这一点上是错误的)。
< p >编辑: 在考虑C的CPAN时,我想……我该怎么称呼这样的东西,然后想到了“ccan”,然后谷歌了一下,我看到了这个: http://ccan.ozlabs.org/ < / p >

不过,它似乎还处于起步阶段。

我是在冒险,因为我不能全职使用它,但无论如何我会尝试一下!

Perl 6

  1. func("frew") != func("frew")
    • 这让我很恼火,但这是有原因的。在Perl 5打印(5 + 6)* 10 仍然得到我不时
    • 李< / ul > < / >
    • 在很多地方,它可能比Perl 5更容易解析,但有时它仍然会使我的编辑器崩溃
    • 它仍然有很多Perl 5的行噪声,这让很多人感到害怕。这意味着很难让他们兴奋等等。
    • 目前还没有库。
      • 如果Perl 6最终确实支持Perl 5,这将不是问题,但这可能是一个不值得承担的负担。
      • 李< / ul > < / > 没有REPL,或者ruby主义者所说的irb。
        • 一个具有制表符补全、颜色编码等功能的可靠的交互式Perl 6将使使用和学习它变得更加愉快。
        • 李< / ul > < / >
        • 目前,文档基本上是英文规范。并不容易阅读。
        • 我知道这是愚蠢的陈词滥调,但它还没有出来!
          • (我可以抱怨,因为我在帮忙:-P)
          • 李< / ul > < / >

前三点是语言;剩下的并不是语言本身,而是它还没有问世的事实。

c#

  1. 当被枚举的集合中的对象发生变化时,foreach命令弹出,
  2. UI控件吐出假人,因为它们在错误的线程上访问。当然是所有的调度员。调用可以移动到CLR管道,
  3. PInvoke,编组等,
  4. 我浪费了两年时间学习远程遥控,
  5. 它没有露比性感。

C

  • 它是如此的灵活和强大,以至于很容易写出非常糟糕或完全危险的代码(或者,如果你喜欢,“能力越大,责任越大”)。
  • '='表示赋值,'=='表示相等;在“如果”语句中很容易混淆。
  • 该语言的一些基本部分的实现是依赖于编译器的;例如,基本类型的大小,位域中的位顺序,并集的填充和字节顺序。
  • 位字段是不可参数化的(也就是说,你可以用整型数组,但不能用位数组)。
  • 可以改进字符串处理。

我知道我迟到了,但恨是永恒的!

Java

    所以,如果我不手动清除STDOUT和STDERR缓冲区,我的代码将挂起?哇。死,请。
  • 负责任的编程意味着我必须像对待未爆炸的炸弹一样对待大多数对象,这在面向对象的语言中是一种麻烦。当不可避免的发生时,我有点需要知道哪一个对象在我的脸上爆炸,但Java显然觉得告诉我将是作弊。
  • 文件I / O。为什么我要跳过这么多环来读取一个dang文本文件?当复制文件时,我必须将源文件导入我的代码并手动处理输出字节缓冲区?你是认真的吗?
  • 原语与原语包装器。注意,Java现在有许多特性,允许你在某些地方将原语和它们的包装器对象视为可互换的,但在其他地方则不能;别担心,编译器会告诉你哪个是哪个。这感觉像是一种围绕根本性的broketastic设计决策的破解方法。事实确实如此。实际上,编译器是一个比我想象的更糟糕的安全网,特别是在做相等性检查时。如果' a '和' b '是整数,' a == b '只有在其中至少有一个是' int '类型时才能保证像预期的那样表现。如果它们都是' Integer '类型,那么只有当这两个数字在-128和127之间时,该语句才会执行您的想法。'整数a = 1000;整数b = 1000;返回a == b; '将返回' false '。真的。)
  • XML。我有一个非常简单的XML文件需要创建,我必须做什么?

Java

  1. 已检查的异常
  2. 类型擦除
  3. 缺少操作符重载(例如BigInteger/BigDecimal)
  4. 缺少regexp/date/duration /复杂文字
  5. 对不可变性的支持很差

Python

  • __abc0中没有语句。GRRRR
  • foo( a for b in c if d )感觉不对,每次我都很惊讶。它不应该是foo( (a for b in c if d) )吗?
  • 我能了解一下词典吗?
  • Map和filter操作符在列表推导中有特殊的语法,那么reduce呢?或排序?
  • 只要在其中添加yield语句,函数就会神奇地转换为生成器,它的接口也会完全改变。而且,该生成器在第一个next()之前不能做任何工作。至少,不使用返回生成器的函数是不行的。

JavaScript

  • 没有简单的语法来创建模块化代码库。你必须调用一个返回公共方法字典的函数。每次修改模块的接口时,你必须在(至少)两个地方编辑它。
  • 创建闭包需要从一个函数返回它,该函数返回一个从(sup dog) yo'函数返回的函数。混乱!
  • for each ( foo )语法和行为感觉像是事后才想到的。
  • 知道代码何时实际运行(以及以何种顺序)更像是一种黑暗艺术。唯一正确的方法就是把所有东西(是的,也包括那个)放在一个大文件里。即使这样,您仍然需要等待document.onload
  • 我错过了什么吗?有没有简单的方法来获得json序列化的值,而不需要手工构建它们?(是的,jQuery可以做到这一点)。

Objective Caml

  1. 非并发垃圾收集器。我可以整天写多线程程序,但它们一次只能得到我八个内核中的一个。这让我很伤心。

  2. 没有类型类(或他们的道德等价物)。有Furuse-san的GCaml,但它a)不如类型类好,B)不在INRIA分布中。

  3. 急需可可桥。< / em >认真。如果我编写更多与基于dna的生命形式的实际接口的代码,那么我可能会崩溃并自己编写这该死的东西。为什么其他人还没有这样做呢?

  4. 函子是可恶的。严肃地说,模块应该是一等值。应该只有一种函数。阅读Montagu和Rémy在你燃烧我之前。

  5. 应该使用LLVM作为后端。我要杀谁才能让OCaml为我愚蠢的ARM6内核编译?

是的,我有一些问题。我仍然非常喜欢这门语言。这太棒了。

Python:

1)它是一种脚本语言,而不是一种完全编译的语言(我更喜欢能够编译二进制文件——我不关心字节码)。如果我必须使用很多库,这是非常烦人的(即每个使用我的程序的人都必须安装所有的库,这基本上意味着没有正常人能够或有耐心正确地设置它,除非我做了大量不必要的工作)。我知道制作二进制文件的方法,但它们不能总是工作,而且我猜它们无论如何都将解释器捆绑在二进制文件中(我不想要那样)。现在,如果我能得到一个字节码编译器,它将包含我导入的所有文件的副本,并将这些文件放在我的程序文件夹中,这可能是一个合适的折衷方案(这样就没有人需要下载额外的库等)。如果编译后的python文件可以压缩成一个单独的文件,并在此之前指定一个文件来运行程序,那就太好了。

2)有时看起来有点bug;有几次,应该工作的代码根本没有工作(没有程序员错误),特别是与“from moduleX import *”和其他导入相关的问题有关的代码,以及一些与全局和局部变量有关的问题。

3)最大递归深度可以更高。至少有一次,我觉得我需要它去更高的地方。

4)没有switch语句(更不用说允许数字、字符串和范围的语句)

5)新版本的Python似乎取消了很多有用的字符串操作,而且似乎没有简单的文档说明如何在没有它们的情况下做同样的事情。

6)强制自动垃圾收集(我想能力手动做,虽然不一定强制这样做)。

7)没有预先制作的定时器类没有使用GUI(好吧,可能有一个,但在我所做的所有搜索之后,它肯定不方便找到!我确实找到了一些东西,但当我尝试时,它根本不起作用。)所谓计时器,我指的是每隔x秒执行一个指定函数的排序,并能在需要时关闭它,等等。

8)社区里举例的人很少告诉我们他们导入了哪些模块,以及他们是如何导入的。

9)与Lua集成的支持并不多。

10)似乎没有办法向一个类的特定实例(而不是整个类)添加一个额外的函数,除非你动态地向该类添加一个对象变量,该对象具有所需的函数(但仍然,你必须为此创建另一个类)。

C

  1. 无参数多态性(即c++模板)。它使得编写可重用的数据结构和算法成为一种痛苦(而且几乎没有任何静态检查)。参见qsort和bsearch的comparator参数:比较器接受空指针:(
  2. 没有数据结构库。我真的很讨厌自己写哈希表。我也非常讨厌在网上寻找可重用的数据结构库。尤其是当它被证明是不完整的。
  3. 字符串。低效的表示,笨拙的,如果你让它理智,很难安全输入字符串。snprintf没有标准。用sprintf创建一个格式化字符串太难了,然后用它再次用sprintf创建一个字符串,以一种安全的方式。
  4. 只有词汇宏。如果不同的编译器希望函数注释在不同的位置,我必须将相同的HAS_NO_SIDE_EFFECTS放在不同的位置。为什么我不能抓取函数,切换编译器类型,然后通过宏调用将它插入到正确的位置?
  5. 没有用于通用功能的可移植库。对于套接字和线程,我使用SDL——一个该死的游戏库。对于。ini风格的解析器,我能找到的唯一一个为ubuntu打包的库,我在每日wtf上发布了(它计算一个哈希值数组,然后对它进行线性扫描…)

c++

  1. 模板语法笨重而笨拙。让我们看看,for(map<string, int>::const_iterator it = mymap.begin(); it != mymap.end(); ++it)
  2. STL中的设计错误。改变你的向量的分配策略真的会改变它的类型吗?
  3. 过于复杂的类型系统。类型T1有一个convert-to-T2方法,而T2有一个隐式的from-T1构造函数。叫什么?重载、重写和多重继承是如何相互作用的?糟糕,我猜……
  4. 来自模板的难以置信的长且笨拙的错误消息。你们能明白我的心情
  5. 引用意味着您不能在调用站点上看到输出参数。在C语言中,你可以猜测foo(bar, &baz)能修改什么,不能修改什么。

VBA(因为你认为你的语言不好)

  1. 一行中的空白是严格的 李执行。< / >
  2. 语句结束,需要一个“_”来切换到下一行, 但并不是每条线都能被打破。李< / >
  3. 没有++,——,+=,-=语句。严重吗?
  4. 数组可以从任意下标开始,而不仅仅是从0开始。
  5. 有些类型(例如:定点“Decimal”值)必须是Variant的子类型,并且不能作为它们自己的类型使用。
  6. = and <>。
  7. "="被同时用作比较器和赋值器,而不是分割成"="和"=="。
  8. ”选项显式”。
  9. 用户界面自2000年以来就没有更新过。
  10. Office2k7没有升级到VB。网
  11. 大多数对象模型都是无意义且过于冗长的。

REBOL

REBOL是我最喜欢的语言。我不能说我有一个最喜欢的,尽管Haskell排名也很高。

  1. 它奇怪的语法吓退了许多开发人员,甚至在他们尝试它之前。

    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."
    ]
    ]
    
    ] 通知[[a@b.com http://www.google.com] [b@c.com http://www.yahoo.com]]
  2. .
  3. 递归方言很容易用PARSE来验证,但很难求值。(堆栈在这里很有用。)

  4. REBOL与许多流行技术的集成很差,尤其是XML。我怀疑这在一定程度上是傲慢的,因为REBOL BLOCK!数据类型几乎可以做XML可以做的所有事情。然而,现实世界中有XML。
  5. 没有Unicode。
  6. 多亏了AltMe, REBOL的用户社区变得非常封闭。我能理解他们为什么要用AltMe。它是用REBOL编写的,展示了它的优点。不幸的是,这也把他们推到了自己的小岛上。

即将到来的REBOL 3有望解决许多这些问题,除了最后一个。

c#:

1)静态方法必须是类的成员

2)静态扩展方法只能添加到静态类中

3)接口函数的实现不会被标记为“override”之类的东西来显示它们来自基类或接口(这使得你很难确保你正在重写你所期望的方法(具有正确的签名))。

我只有3个。我想那很好。

第一个帖子,所以对我放松点:)…很棒的社区网站,顺便说一句!

我试着阅读其他所有的c#回复,这样我的回复就不会重叠了

c#……排名不分先后:

1) switch语句中的case没有fallthrough。如果没有转机……为什么必须显式的类型中断;呢?这只是弱智和令人困惑,因为它意味着没有休息的能力;!!

2)不能在子作用域中声明同名变量,但可以声明与类变量同名的变量?要么都允许,要么都不允许。否则,就没有意义了。

3)函数中没有可选/默认参数

4) finally{}中的异常应该隐式地捕捉每一行。或者至少,只有NullReferenceException异常。例如,在访问数据库后,应该总是清理。所以,finally块应该看起来像这样:

finally
{
if(par1 != null)
par1.Dispose();
if(comm != null)
comm.Dispose();
if(conn != null)
conn.Dispose();
}

如果可以写成这样,就会简洁得多:

finally
{
par1.Dispose();
comm.Dispose();
conn.Dispose();
}

但是,不……你必须检查你是否正在访问一个空对象,否则它可能会从finally块抛出一个NullReferenceException。谁真的需要finally块中的异常呢?

5)泛型:你可以指定new()来实例化你的泛型对象,但是这个对象需要有一个默认构造函数。为什么不能指定一个签名,这样就不需要在还没有空构造函数的情况下创建空构造函数,而只使用已有的构造函数。

Haskell。

  1. 默认情况下导入Prelude。
  2. 类型类的范围是通用的。
  3. 模块不是一流的。
  4. 类型不能依赖于值。
  5. 单子不统一Functor。

Python:

我仍然是python的一般用户,所以我的抱怨可能只是知识的锁或误用。欢迎提出意见。我很喜欢这门语言。

  1. 糟糕的线程支持和GIL。如果你想使用多核平台,大多数python程序员可能会推荐多处理或其他类型,而不是使用线程。它不会给你你所期望的表现。
  2. 属性仅用于实例变量。_class_var = property(classmethod(some_method))不能正常工作。我如何能得到一个属性包装类变量?
  3. 没有访问控制。所有的访问控制都是语法混乱。比如private是__private, protect是_protected,等等…并且希望每个人在编程python时都遵循命名约定。来吧,我们可以做得更好。
  4. 我同意python语法简单清晰的理念,但在我看来,一些简单清晰的语法不受支持似乎缺乏良好的判断力。比如,a++, ++a,和,a, self-de/increment,这些有什么问题吗?Foo = (a > b ?A: b)一元运算,这些有什么问题?(我知道py2.6也引入了类似的东西,但考虑到几乎所有其他语言都对这些简单语法提供了大量支持,为什么要重新发明轮子呢?为什么不遵循最佳实践呢?一件好东西不应该保持它好的“状态”吗?)
  5. 编程到接口。Python没有接口或抽象类概念(py3k有abc),一切都是具体的。我认为,提供一个“接口”或“抽象”关键字来构建类骨架并保护类的继承和扩展并不是一个坏主意。它有助于自上而下的设计。目前,我只需要用NotImplementedError填充每个方法,相当乏味的工作。
  6. 我要加上这个。版本小于3。X有STR和unicode类型。这真是一场噩梦。它使得ascii和非ascii/unicode混合最容易失败(不好,不好)

我看到人们抱怨速度。我不明白。它是一种解释语言,代码直到运行时才编译成机器代码,这就是它的本质。你不能比较解释语言和编译语言的速度。据我所知,在解释/脚本语言中,python并不慢。

我自己最讨厌c++的5个地方:

自动生成构造函数、析构函数和赋值操作符。天哪,每当我在类中没有声明某个东西时,它意味着我不需要,而不是我忘了。你们这些编辑们,听到了吗?!

[4]模板语法。哦,我真的需要输入所有这些“<”和“>”,每当我决定从类主体提取定义?

[3]字符串。天啊,我受够了“const char*”,我必须处理NULL情况,我必须浪费O(N)来获得它的长度,我必须为concat操作分配缓冲区。

[2] Macroprocessing。每当我不明白,什么是我的编译器,我开始寻找宏。

[1]操作符重载。我看到代码“A + B * C”,在我看到A、B和C的实际类型之前,我说不出这个代码是关于什么的。

那"我讨厌某些语言的五件事"清单呢?: D

把橙色涂成红色并不能让它成为苹果。

当设计一种语言时,设计者通常会考虑它的用途。使用它完全不同的可以工作,但抱怨时,它不只是愚蠢的。Python。我相信总有一天会有人用Python代码创建exe工具。解析:句意:你究竟为什么要做那样的事?不要误解我的意思,这是很整洁的,但这没有用。所以别再抱怨了!

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

4-你是用木腿站着吗?

平台对语言的功能有很大的影响。现在的垃圾收集器,甚至帕斯卡早期尝试的“垃圾收集”,可以帮助记忆褪色(也许malloc更多ram??)计算机速度更快,因此,我们当然对语言有更高的期望。坦率地说,我们或许应该这么做。然而,为了方便编译器创建哈希表或字符串或各种其他概念,需要付出巨大的代价。这些东西可能不会继承给它们所使用的平台。说它们很容易包含到一种语言中只是告诉我你可能站不住脚。

3-到底是谁的错?

bug。你知道的。我喜欢虫子。为什么我喜欢虫子。因为这意味着我能保住我的工作。如果没有虫子,很多披萨店都会关门。然而,用户讨厌bug。但这里有一点冷水。每个bug 都是程序员的错。不是语言的问题。具有如此严格语法的语言将显著减少可能产生的错误数量,这将是一种完全无用的语言。它的能力可能一只手就能数得过来。你想要灵活还是强大?你有虫子。为什么?因为你并不完美,你也会犯错。举一个C语言中真正可识别的例子:

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

我们都知道会发生什么。然而,也许我们中的一些人没有意识到…这种功能是非常有益的。这取决于你在做什么。缓冲区溢出是该功能的代价。上面的代码。如果我真的把它公之于众。这是再一次. .和我一起说。“我的错”。不是C,因为你允许我这么做。

2-我们不应该把它放进回收站吗?

我们很容易在一门语言中指出一个我们不理解的特性,因为我们不经常使用它,并说它愚蠢。抱怨它就在那里等等。后藤总是招待我。人们总是抱怨goto是一种语言。但我敢打赌你上一个程序里有一种goto。如果你用过break或continue,你就用过goto。就是这样。当然,这是一个“安全”的去处,但事实就是如此。后藤是有用处的。是否使用“隐式”gotos,如continue或break或显式gotos(使用任何语言的实际关键字“goto”)。并不是说语言开发人员是完美无瑕的,但通常……如果功能从一开始就存在(对于该语言)。这方面很可能是该语言的一个决定性特征。意思. .由于向后兼容,它正在被使用,很可能没有被搁置。今天还在使用。就像5分钟前那样。正确使用。嗯. .可以说有人也在不恰当地使用它,但这与我清单上的第3条有关。

1. -一切都是客体。

好吧. .这实际上是第2条的子集。但这是迄今为止我在仇恨名单上看到的最烦人的抱怨。不是所有东西都是对象。有许多概念不属于或需要成为对象。把东西放在不属于它们的地方是丑陋的,而且会降低程序的效率。当然。可能没有太多取决于语言。这也与第五点有关。这意味着……是的。全局的都可以。函数相对于静态方法是可以的。将面向对象编程与全局函数相结合是可以的。现在. .这并不意味着我们应该把代码从对象模型中“解放”出来。当设计一段代码或整个项目时,将它们放在一起时要考虑幕后发生的事情。不仅仅是这个概念存在的地方,还有很多其他因素。如果没有用,为什么要在类或名称空间概念中包装全局函数呢?取静态成员变量。这让我很开心,因为…当然,这取决于语言和实现,但一般来说,你只是声明了一个全局变量。是的,有一些理由将这些非OO概念包装在OO包装器中。其中之一当然是自文档代码。这是有道理的。所以. .就像我说的。不要出去“解放”你的代码。但是任何好的现代语言都有一个面向对象建模之外的全局概念。是的,我特别想指出的是,没有全局概念的OO编程语言很可能存在严重的设计缺陷。再次虽然. .这取决于语言的意图和设计,所以我不想挑任何特定的语言,这里有太多的语言来分析。无论如何,考虑一下代码应该在哪里,并且是最有效的。在一些没有增加功能或支持的东西上添加一堆耀斑只会更快地磨损键盘。这对任何人都没有好处。嗯. .除非你喜欢那个错误地告诉你所有东西都是物体的人给你的印象分。

简而言之,编程不只是无意识地敲击键盘。任何项目都有很多设计考虑因素。我知道这是陈词滥调,但你必须从各个角度来看。即使是现在的类型安全语言。您不能只是抛出代码并期望它能正常工作。确定. .它可能会起作用,但它可能不是正确的方法。总的来说,选择最适合特定工作和环境的语言和格式。但是没有语言带走了它背后的思想。如果你没在想…你只是在打字。

Haskell:

  • 空间泄漏——懒惰的默认代价——也许代价太高了?
  • 甚至像headtail这样的纯函数也可以调用error并引导你到IO
  • fail from Monad -带回MonadZero
  • Num类——(+)应该在AdditiveGroup或类似类中。
  • Monad不是Applicative

c++缺乏好的重构工具,缺乏受控异常

Java缺少模板,缺少const关键字

Objective-C / Cocoa / Cocoa Touch:

  • 缺少名称空间
  • 在Cocoa的任何有趣而强大的技术(如分布式对象、通知、KVO)中使用原始值都很困难
  • 与使用快捷点语法访问属性不一致,通常必须使用完整长度的访问器
  • 在iPhone上没有GC,而且通常GC对于一种高度动态的语言来说出现得比较晚
  • 不一致的库支持,至少在Cocoa Touch中;一些非常基本的东西最近才得到高级支持,例如音频处理。
  • 缺少积木!

PHP

  • 几乎每个标准函数都在全局作用域中
  • 不一致的函数参数顺序
  • 不一致的函数命名
  • 不区分大小写的函数
  • 脚本的行为可能会因php.ini文件的不同而有所不同
  • 能够使用未定义的变量
  • 在某些情况下,必须将结果赋值给变量,然后才能在函数中使用它

更主观地说:

  • 动态类型

Common Lisp

  • 缺少提供更现代功能的标准库(套接字,线程,…)
  • 是否可以使用映射到本机窗口系统的标准化UI
  • Scheme将lambda表达式赋值给变量并将变量直接作为函数调用使用的能力看起来比APPLY for FUNCALL更整洁。我猜这是使用多个名称空间的副作用
  • 标准化的库源代码级打包系统,以便可以从多个实现中轻松使用它们

我想知道强类型的口齿不清会是什么样子

Haskell(包括所有GHC扩展,而不仅仅是Haskell'98的基础规范)。

我讨厌它的一点是:它不是主流。

c#

1)缺乏为值类型编写泛型的实际能力。例如,任何白痴(好吧,大多数白痴)都可以编写一个例程,用c++计算int, float, double等列表的标准偏差,它写起来很简单,易于阅读,并作为快速的非泛型代码执行。我认为,如果你能用c#写一些东西,接近于达到这三个中的任何一个,而在其他两个上又不荒谬,你就是一个真正伟大的程序员。

2)协方差和反方差,尽管这被添加到4。

3)非常糟糕的LINQ文档(好吧,并不是语言的一部分)。

4)尝试使用foreach/迭代器,当我每次都想做同样的事情,除了上次略有不同(如连接一串字符串与逗号之间的单词和最后两个)。如果我用IEnumerable写它,它很难写和读,并且用for (int I =0 I <)它并没有好到哪里去,而且效率更低。

5)我知道我会收到抱怨,但是缺少受控的例外。这并不需要像在java中那样实现(框架开发人员确实提出了一些很好的观点,为什么他们没有这样做),但我很乐意看到编译器警告不喜欢受控异常的用户可以关闭。

我不敢相信,我最讨厌的Python竟然还没被提到:

  1. 相对导入看起来像绝对导入。

    import foo
    

    这是从你所在的目录导入foo还是从sys.path导入foo ?< / p >

  2. 拉链鸡蛋,导致系统。路上全是屎。压缩鸡蛋意味着你不能使用grepfind(调试问题1)!幸运的是,还有皮普。使用脉冲。
  3. 一些附带的电池是不pythonic的。使用它们会让人感到不快。
  4. 可能是发行版和打包器的错误,但仍然:sourcfile -encoding在安装/编译时设置为fscking ASCII。WTF ?意味着我必须把“# coding: UTF-8”的东西放在我所做的每一个.py中。

Py3k解决了我的其他几个讨厌的问题,例如坚持字符串是unicode的,8位的东西是不同的……

c#

5. 空合并运算符

的? ?运算符允许你写:

x = y ?? z;

而不是:

x = (y == null) ? y : z;

我喜欢这个运算符,但我想要另一个:

x = y ??? y.foo() : z.foo();

而不是

x = (y == null) ? y.foo() : z.foo();

我一直在使用这种东西,而且我发现输入== null部分很烦人。


4. 平等应该有更好的支持

我必须开始每个Equals(object obj)方法: MyClass other = obj作为MyClass; 如果(other == null)返回false;

你只需要写:

public override bool Equals(MyClass other) {...}
语言应该注意提供Equals(object obj)方法 注意:other必须保证不为空


3.不能使用不同类型的三元运算符

这不能编译,我认为它应该编译!

string foo = "hello";
int bar = 4;
object baz = foo == null ? foo : bar;

2. 缺少命名空间private

我喜欢internal保护,但我希望有一个保护,只允许从相同的命名空间内访问。这样可以更好地控制大型类库的访问。


1. 没有多重继承

我实际上只对接口的默认实现使用实现(类)继承,但很多时候我想这样做。

日常

社区太小了。如果附近不容易找到另一个说英语的人,想要进行一个好的语言沉浸式课程几乎是不可能的 不规则动词。是的,我知道英语和西班牙语也提到了它们,但是昆雅语是发明了。为什么还要有不规则动词呢?< br > •不支持Unicode。我的电脑上必须安装三种不同的腾华字体,才能阅读大多数邮件,其中有几个字距很差。考虑到罗马文的存在,这并不是一个大问题,但Tengwar太美了,你不会不想用它的 •并不是所有的概念都可以在昆雅语中被轻易引用,导致了令人讨厌的绕弯子,或者求助于辛达林语、Númenórean或(Manwë救救我)克林贡语来表达我的观点

我最喜欢的是c#,但是已经有很多关于c#的答案了,所以我将选择我的下一个“最喜欢的”:

t - sql

  1. GO语句,以及所有DDL/DML脚本都需要它的事实,以及它还破坏事务语义的事实,使得它比编写原子脚本要困难得多,而为了升级生产数据库,您确实需要原子脚本。
  2. 不一致的分号语义。99%的语法不需要它,MERGE语句必须以它结束,WITH语句必须以它开始……下定决心吧!
  3. __abc0 / __abc1。Uuuu-gly。
  4. udf中的可选参数实际上并不是可选的。调用者必须指定DEFAULT(甚至不要尝试使用NULL代替)。与sp相比,它们是真正可选的。
  5. "...可能导致循环或多个级联路径。” 恨,恨,恨,恨,恨,恨

TCL

这是我最喜欢的语言,几乎可以做任何事情。多年来,它已经(慢慢地,非常缓慢地)演变为解决大多数让我烦恼的事情。而且这门语言非常灵活,很容易实现语法来覆盖那些仍然困扰我的东西。但是语言中有一些东西是不能轻易改变的,只是打破了它的禅意:

  • 数组(关联类型,Perl称之为散列)没有正确的值语义。这使得它们难以传递给函数或从函数返回。另外,这意味着它们不能嵌套。由于这个原因,dicts(字典)被发明出来,但为时已晚,漂亮的数组访问语法:

    $array($foo)

    现在永远被愚蠢的数组用于向后兼容。我们现在被困在:

    dict get $dict $foo

    这更冗长,对我来说可读性更差。

  • 没有真正的闭包。虽然它可以通过全局变量或名称空间来模拟,但这首先就违背了使用闭包的原因。虽然,我现在还不能真正看到闭包如何在纯值语义系统中实现。

  • 与其他存储库工具相比,茶杯很难使用,而且一点也不直观。这更多是ActiveState的错误而不是tcl-core的错误,并且在编码时并没有真正打破tcl的Zen,但它仍然非常烦人。

c++

(除了lambda函数,我已经避免了Cpp0X中可用的东西)

  • 不强制使用"this"访问成员变量,::GlobalFunction访问全局命名空间。
  • (更具体地说,算法中缺少lambda函数,将在0x thou中修复)中的所有内容
  • 处理依赖文件/头文件和源文件
  • 基本数据类型上的愚蠢名称(应该命名为uint8, int16等)
  • const_cast功能

c#

c#最让人讨厌的是:

(1)事件具有对所有侦听器的强引用,从而防止对侦听事件的任何内容进行垃圾收集。如果你想看到这造成的问题,只需在网上搜索所有试图通过创建某种“弱引用事件处理程序”来解决问题的人。

(2)在调用一个事件之前需要检查它是否等于null,这似乎应该由语言来处理。

(3) XML序列化器无法读取/写入XML文件中的注释。在手工修改XML文件和用c#编写的工具修改XML文件的环境中,情况并不好。可以通过使用原始的XmlDocument来解决,但如果能够将其抽象到一个类中会更好。

(4)构建过程不让你直接访问像xsd文件这样的东西,相反,你需要一个中间步骤,在那里你创建一个c#部分类。这也会导致XAML文件出现问题,有时需要重新构建两次才能使更改正确地通过。

(5)不支持像MMX和SSE 1,2,3,4这样的CPU intrinsic,因此在运行c#应用程序时,这些有价值的CPU特性没有被利用。

其他没有进入我的前5名:

(6)不能将字段标记为属性,所有属性必须从一开始就显式地实现:

目前有:

public class MyClass {
private int someInt;


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

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

(7)不支持多个返回值,例如:

public int, string, double MyFunction()
{
....
return x,y,z;
}




public void TestMyFunction()
{
int x, string y, double z = MyFunction();
}

(8)不支持协变返回类型

我对泛型实现有一些不满,但我就此打住。我认为c#是一种很棒的语言,可以完成所有的GUI、网络和配置管道,并且是我的首选语言,可以以一种可以长期支持的方式快速启动和运行。

VB。网

  • 弱类型默认为(选项严格修复了这个问题,但默认情况下它没有打开)
  • 在方法(myFunction而不是myFunction()等等)上不需要括号
  • 数组定义是否使用括号/使用(myArray(12)代替myArray[12])
  • 不支持直接递增(i++)
  • 是否支持遗留On Error关键字和整个VB6-Namespace

Python

那些我不理解的…

  • math.ceil()math.floor()返回浮点数,而不是整数(可能是为了避免底层C函数中的整数溢出-但为什么不转换为Python long呢?)
  • len()是一个函数而不是一个方法
  • reload()非常有限,10次中有9次不会重新加载一个模块,只有当导入的标签是一个模块时才会重新加载——也就是说,如果foo本身不是一个模块,则不能执行from bar import foo; reload(foo)
  • 可变默认参数只有一个引用(为什么不是每个函数调用一个新实例?!)
  • 所有这些被强调的变量——如果它们是如此私密,为什么我们会在代码中看到如此多的内置变量呢?获取一个名称空间!
  • 字符串是不可变的——也许这有一个很好的理由,但我遇到过很多情况,我想调整一个特定的字符…

那些基于实现有意义但令人讨厌的……

  • array.sort()不返回数组(我假设它发生在原地)
  • 列表/生成器推导式不定义新的作用域(只是for循环的语法糖,对吗?)

以及几个在Python 3中修复的

  • 默认为整数除法
  • global只能引用顶层命名空间

Scala:

  • 标准库的奇怪之处:它并不总是显示最佳实践,而且文档不足
  • 硬编码FunctionX, TupleX类
  • 缺乏属性:getter和setter是分开的,这违反了DRY,并且使得像FRP这样的事情几乎不可能实现
  • 需要= _来初始化属性

c#

  • 缺少基于方法参数的运行时类型的多重分派。dynamic应该解决大部分问题,但它还没有发布。
  • 接口实现是声明性的而不是结构性的。我非常喜欢谷歌的语言处理类型的方式 进行异步方法调用真的很笨重(而且我非常确定所有的线程都是操作系统线程,而不是轻量级线程)
  • 无宏系统。这里我说的不是c风格的宏;我说的是LISP/Scheme风格的宏
  • 操作符是静态方法,它们的签名被过度约束(并且不能创建新的方法)。

  • 我对特尔斐的5分:

    1. 如果没有参数化,过程和函数不一定与变量有区别(例如,我可以有这样的语句x:= GetPositionOnScreen;而不是x:= GetPositionOnScreen();)
    2. Try/Finally和Try/Except需要嵌套(之前声明过一次,但它仍然是我的一个)。
    3. 不区分大小写。
    4. 可以有多个对象(函数,全局变量,局部变量)命名相同,Delphi将很乐意尝试找出你的意思。名称应该是唯一的。
    5. 奇数if条件规则。单个条件检查不需要在它周围加上一个(),但如果我进行多次检查,每一次检查都需要一个(),有时为了进行更大的检查,还需要多个嵌套集。
    6. 没有继承的包含。如果我需要在一个基本窗体和一个继承窗体中引用Windows单元的功能,我必须在这两个窗体中都包含Windows。

    HyperTalk:

    • 很久很久以前就死了
    • 没有简单的赋值(你不能只说a := 3,你必须说put 3 into a
    • 没有嵌套函数
    • 没有真正的数据结构,只有字符串。要创建“列表”,您可以使用itemDelimiter分隔条目并手动转义它们。你也可以得到像get word 2 of line 5 of txt这样的行和单词

    说句题外话,我认为HyperTalk最酷的特性之一是特殊的it变量:

    ask "How many years old are you?"
    answer "You are " & it*12 & " months old."
    

    我讨厌Python的地方:

    • 没有编译器
    • 它没有被认真对待

    Python让我恼火的地方:

    • (self,
    • 没有private
    • 打破兼容性
    人力资源> < p > < 我讨厌PHP的五个方面:

    • “按预期工作”,而这显然是一个bug
    • 没有goto
    • 有bug的引用(foreach $arr => &$valforeach $arr => $val)
    • 没有多重继承
    • 没有一个编译器能够真正工作,而不需要向黑暗之神牺牲一只羔羊

    Python

    • 没有名称空间。
    • 伪私有属性/名称混淆(主要使用getattr)。
    • 文件路径操作分布在多个模块中。串在一起的os。路径调用是丑陋的,难以读取,并且在大多数情况下违反了DRY。常见的文件路径操作仍然没有方便的函数,比如获取目录下的文件列表。用于修复此问题的path类型模块被拒绝。

    ([f for f in os.listdir('/file/path') if os.path.isfile(os.path.join('/file/path', f))])

    • Python文档(我非常、非常、非常感谢有文档,而且它的格式很好,但我讨厌费力地在5000行快速入门使用示例中找到特定模块的单个函数文档(我正在查看optparse和logging))。内置类型在近10个不同的地方被零碎地记录。

    Lua

    • 如果你执行foo。bar(1,2)那么'self'在bar方法中是nil。你必须记住用foo:bar(1,2)来代替。我宁愿将其切换('self'应该默认定义,除非你使用':'操作符,或者你调用的函数不是方法)。
    • 默认情况下,变量是全局变量。我宁愿放弃“本地”关键字,而是使用“全局”关键字。
    • 未声明的变量被赋值为nil。我宁愿收到错误消息。您可以通过操纵全局env的元表来避免这个问题,但我宁愿默认实现它,并能够禁用它。
    • 参数上的多个返回值不能很好地处理。假设你有一个函数foo()返回1,2,3(三个值)和bar()返回4,5(两个值)。如果你打印(foo(),bar()),你会得到"1,4,5"…只有“最后一个”元组在调用时展开。
    • #(表长度)操作符仅适用于以连续整数为索引的表。如果你的表不是这样的,你想知道它有多少元素,你需要用一个循环来解析它,或者每次插入/删除一个元素时更新一个计数器。

    c++:

    1:头文件。

    链接代码比编译代码更难。同样,模板在翻译单元中包含完整源代码的要求也是荒谬的。在那边的那个文件里。你两秒钟前编译的那个。去那里看看。愚蠢的编译器。

    2:空标准库。

    我的意思是,是的,在c++ 0x中有std::thread,但没有std::socket或任何类似的东西。没有跨平台代码的主要原因是,您必须为希望在多个平台上执行的每个函数学习一个新的库。没有作为标准提供的OS头文件或OS函数,c++只适合推位。

    3:没有多次返回或返回值重载

    Double x, int y, char z = func();和void func(double x, int y, char z)一样有效;请。没有返回值重载的唯一原因是我们“可能”;编写模糊的代码。可能!请在我真正写出模棱两可的代码时给我悲伤,而不是之前。

    4:不反思

    可以将反射设置为编译时反射。的确如此。没有任何库使得编写大量的库变得困难,并且严重地惹恼了我。我可以滥用预处理器,但是..

    5:在模板上鸭子打字

    Yaargh。请,概念和正确的模板错误消息。使用Boost这样的库实际上是不可能的,因为如果你用错了,你就是在瞎猜。

    我刚刚发现,在c#中创建泛型方法时,我不能使用Enum作为类型约束。

    微软有一个足够好的解释,但仍然。我疯了

    public static T MyFunc<T>(string arg) where T:Enum //wont work :(
    

    JavaFX

    • 类型推断有时不正常 如你所料,所以你经常 需要显式声明 李类型。< / >
    • def的行为类似于C中的const,而不是Java中的final
    • 您可以通过访问索引>= seq在序列中插入一个值。长度,它实际上应该抛出一个编译器错误(根据参考)。
    • 如果你将null赋值给String,它默认为""。如果将null赋值给Integer,则抛出编译器错误(与引用所述相反)。
    • 处理CheckedExceptions的方式与RuntimeExceptions相同

    c#

    • 无法创建引用(var &t = struct)
    • 没有局部作用域析构函数(IDispose很接近,但不相同)
    • ToString,我几乎不喜欢,每个对象都有它,但事实证明,我不喜欢一切使用它像字符串。格式。我宁愿有接受某种类型的东西(如int,浮点,文本,字符)。因此,我不需要传入任何对象,而是需要传入带有隐式类型转换或接口的东西。我最终写了这样的东西来安全地转义html文本,这工作得很好。
    • 不能使用虚拟类型转换(blah)obj;如果obj没有继承/有blah的接口,则不工作。简单的解决方法是提供一个带有转换函数的接口。
    • 没有本地创建。而不是写var o = new Item();我想写(类似于)Item o()(如果它有一个自动处理)。

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

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

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

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

    1. 事实上,很多使用PHP的人,对编程和良好实践一无所知,从而产生了非常混乱的代码。JavaScript也有同样的问题。

    2. 大量的教程/书籍传授了非常糟糕的做法和风格。这可能是第三条的主要原因。

    3. 它的坏名声主要是因为第三条和第四条。

    c#

    • 默认情况下,引用类型是空的;语言内null关键字是无类型的。
    • 缺乏受歧视的工会
    • 异常如默认的,非异常错误处理方法-没有太多的替代方案。
    • 陈旧的开关语句语法和限制
    • 构造函数+静态方法之间没有区别
    • 静态方法不能成为接口的一部分
    • 缺乏按形状的接口实现,而不是显式的接口实现——导致大量的语言设计hack,如linq查询语法,foreach, collection &对象初始化器——没有一个可以灵活地重用。例如,对象初始化器语法可能很好,但在不可变对象上表现不佳。
    • 不能独立于实现继承类的“接口”——导致代码重复和提供接口的过度架构代码、抽象基类、少数通用实现,并且无法选择每个实现的位来使用。也;导致过多的代码与特定的实现紧密耦合,因为通常显式引用实现类型而不是接口。
    • 不能通过组合进行多重继承,因为类的“接口”与它的实现紧密耦合;实际上缺少mixins。
    • 接口的上述限制导致了几乎相同的接口的激增,这些接口在任何类型的层次结构中都不会自然重叠。IComparable vs. IEquatable vs. IComparable<T> vs. object。等号和运算符==等等。通过扩展,创建一个满足所有这些要求的自定义类型比必要的工作量要大得多(特别是对于集合类)。显然,语言设计者意识到了这一点,因此有各种各样的变通方法,比如linq、foreach和集合初始化器,它们是根据形状而不是根据接口工作的。
    • 括号和大括号的冗余使用,而不是布局即结构。
    • 返回值可以被忽略,从而限制了类型推断的有效性。
    • 枚举不是普通类型,不能有方法。此外,枚举值不是类型安全的,尽管没有0值,也可以初始化为0。通过将标志和非标志枚举组合在一起来混合隐喻。
    • 缺少适当的值类型支持。值类型不能被继承,具有不同的构造函数语义,并且由于CLR的限制性能很差。另外,关于值类型的语义令人困惑:一些值是真正的值(不能修改),而另一些值是真正的非别名、非空引用(变量)。这在下一个问题上尤其令人困惑:
    • 字段和属性之间的语义区别,特别是在缺乏可变性修饰符的情况下(ala c++的const)
    • 不能专门化泛型
    • 不能提供默认的泛型类型参数(例如工厂泛型)
    • 缺乏typedef使得使用泛型很痛苦(using是一个有限但熟悉的替代品!)
    • 不能泛化除类型以外的东西(例如函数、普通值或名称)。这意味着你不能做一些事情,比如创建一个依赖属性的泛型实现,从而导致像依赖属性这样的糟糕的实现,以及过度使用代码片段和结果是可读性差的代码。
    • 指定泛型类型要求的能力有限,例如泛型sum方法,它同时接受int型、double型和bigint型(没有棘手且通常缓慢的hack)。
    • 接口方法实现或虚拟方法重写不能返回更特定的类型或接受更一般的类型;例如,即使在c# 4中也有限的co/逆变支持。

    我讨厌Nemerle中的五件事:

    • 局部函数不能让步
    • 编译lambda的能力有时取决于它是否内联
    • 元组的值/引用类型语义不一致
    • 数组下标和类型参数之间偶尔会出现歧义
    • 缺乏普遍采用

    不得不假设我们有语言。我们做什么?

    Clojure

    • 函数定义中缺少可选参数和关键字参数的内置语法。当然,您可以很容易地添加它,但这意味着标准库编写者不会使用它。普遍的破坏尚未被证明是一个好的替代品
    • 缺少方法组合(在Common Lisp中找到的方法之前/之后/前后)
    • 过于依赖Java互操作,例如没有内置的文件IO
    • 有时我需要静态类型。这不是纯粹的仇恨;我通常更喜欢动态的,尝试将两者混合在一起基本上不能令人满意
    • 内置数据结构没有内置的快速二进制序列化格式,尽管我听说有人正在研究它

    Python,:

    1. No switch关键字。不,字典不是它的替代品。甚至没有一堆elif语句。

    2. 断行处理不一致。为什么我可以这样做:

       test = (1,
      2,
      3)
      

      而不是:

      from itertools import cycle,
      islice,
      izip
      

      为什么我不能:

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

      不使用斜杠?< / p >

    3. 没有明显的,也只有一种方法可以做到这一点。Python没有做到它的座右铭,就像Java没有做到“写一次,随处运行”一样。

      # 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
      

      最糟糕的是它们不做完全同样的事情。

    4. 空格和制表符之间的选择。应该没有选择。挑吧,定下来,别争了。

    5. 为什么你可以这样做:

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

      而不是:

      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.

    c#

    我对c#非常满意,但这两个真的让我很恼火:

    • 对于不可变类,基于构造函数的初始化不太方便,不太直观(当你阅读代码时,你不知道你分配了什么给什么),与内联对象初始化相比,IDE支持更少。这使您不可避免地倾向于可变类。我知道之前已经提到过这一点,但我在不可变类的初始化语法方面有严格的问题。

    • switch太啰嗦。每当我看到一个开关是合适的情况,我真的倾向于使用if..else if..,只是因为它更简洁(~30%的打字少)。我认为应该没有切换,break应该是隐含的,并且case应该允许逗号分隔的值列表。

    Erlang

    • 没有静态推断 就像在哈斯凯尔发现的一样。这 会导致运行时错误和一个 有认真写代码还是使用 dialyzer(1)发现 差异。动态类型是 也被认为是缓慢的;
    • 与C、Java等语言相比,它几乎是未知的;
    • lists(3)模块有时相当精简 我缺少用于列表处理的有用函数 (比如Haskell中的Data.List)
    • 使我把,放在每个语句的末尾 .在从句中,而.在后者的末尾

    很多人认为Java很慢,但我同意一定程度的使用。

    Java是戏剧性的。他们为你想做的一件事提供了很多课程。但是你知道灵活性属性XD。

    Java一开始很难,但总是很有趣。

    当你写一个简单的代码打印“Hello,World!”请不要使用java !XD我相信我是有道理的。

    Java是一种混合,所以不要说它是纯粹的面向对象语言。

    还有很多,但我只局限于5个XD。谢谢!

    Common Lisp

    • 条件不是类(因为类是后来才出现的),尽管它们的接口几乎相同
    • 有些名字很奇怪,例如,flet / labels(唯一的区别是:作用域),和defvar / defparameter(唯一的区别是:已经定义的行为),或者任何位旋转函数(dpb, ldb等)。
    • 包装是…真的很难搞清楚——每次我以为我理解他们的时候,他们都不按我想的做
    • 内置数据结构和函数并不像它们应该的那样通用(例如,为什么我不能可移植地定义我自己的哈希函数?)
    • 函数、变量等的多个命名空间(原则上我并不反对,但CL让它太复杂了;Norvig说他不能从规范中判断,但似乎至少有7个名称空间)
    • length属性很容易与length()函数混淆;请改用size()
    • 在选择器字符串中插入变量的语法('" +$。Month + "')臭死了
    • $(event.currentTarget)并不总是适用于冒泡和捕获
    • 属性语法("[class='foot']")在选择器语法(".foot")不返回任何结果的地方起作用
    • 包含选择器([class~=done])有时会在JavaScript (this.className.search("done") > 0)工作时失败

    Haskell

    1. 有时,类型系统给人一种倒退的感觉。如果我不想让编译器为我的变量推断类型怎么办?如果我想要相反的结果呢,它对变量进行约束检查?例如,它不是推断列表元素的类型,而是确保它们都属于特定的类型类。这是一个微妙但巨大的差异,使我很难编写ui。这是可以做到的,但是要比在其他语言中花费更多的精力。对于非UI部分,Haskell非常出色,但是UI我留给非类型化语言处理。

    2. 允许构造无限值有时会导致一些令人沮丧的错误。

    3. NoMonomorphismRestriction。

    4. 字节串处理有时咬我的屁股,你不知道它直到你的程序崩溃,因为你不恰当地混合它们。这里出了问题,当我们丢失了应该防止这种情况发生的类型信息时。

    5. 对于不重要的情况,应该自动派生类型类,比如证人类型,但这里存在很大的滥用可能性。

    c#

    我知道这很愚蠢,但我希望数据类型可以自己转换为我想要的,而不需要我添加(int)Convert.ToInt32或其他任何东西。这样可以节省我的时间。让我烦恼的是,如果我写了一些东西来输出int,然后结果是我需要long,那么通常我必须从头到脚修改我所做的一切来使它工作。就为了我!

    抱歉,我想不出5个,但我是新手,所以也许我以后会回来添加更多:P

    c#

    1. 没有简单的方法来检查类型是否为Numeric
    2. 这意味着你可能会被困在使用大多数微软堆栈,IIS和MSSQL
    3. c#不是针对特定问题的特定工具,而是试图成为适用于所有范式的语言。
    4. 缺乏社区。当然,c#的开源框架和库已经开始出现了。与Java开发人员多年前使用的相同。
    5. 很难找到好帮手。互联网上到处都是用c#解决问题的糟糕例子。这又回到了问题3。

    Erlang不在此列表中。在我最喜欢的语言中,但有一些缺陷是肯定的:

    • 语法。这包括3个终止标记(,;.)和美学,但更普遍的是关于如何在文本中表达代码的语义。一个例子是关于为什么所有小写符号都是原子,所以要引用一个函数,你不能只给它命名,你必须fun my_function/1?PRECEDE_CONSTANTS_WITH_QUESTION_MARKS。来自Scheme, Haskell等,你只是希望你可以使用一个名字。

    • 库支持很蹩脚。这主要是外部库,但即使是旧的标准库。新版本的Erlang有合理的POSIX正则表达式,但是旧版本的Erlang有一个非常糟糕的用于基本字符串操作的库。你也永远不知道你什么时候得到值,或{ok, Value}

    • 相关:用于构建和分发的非统一工具。Ruby有gemrake, RSpec。Perl具有CPAN。我不知道在Erlang中有像样的对等物。

    • 少数Erlang专用工具非常奇怪。Mnesia是一个很棒的数据库,但是从SQL中来,你有很多琐碎的东西要学习。文档@spec也是一样,它用一种奇怪的方式描述签名。

    • 通常,当你只想要一点点突变时,功能范式就会伤害到你。假设你想要一个哈希表,你不能像在Scheme或SML中那样破解它。etsdets减轻了一些痛苦,但不是很多。

    第六,奖金:

    • 模块的导入和导出语法是一堆失败,与Java的80多行import语句不同。

    综上所述,Erlang是一种乐趣^_^

    下面是更多关于Perl 5的内容,来自创建了大量Perl模块,特别是在驼鹿上工作的人的观点。

    1. 重载和绑定变量的可怕破坏。这两个特性都是允许对内置类型进行透明扩展的失败尝试。

      它们都以各种方式失败,并要求像我这样的模块作者要么实现可怕的hacks来支持它们,要么说“永远不要将重载对象传递给foo()方法”。这两种选择都是不可接受的。

    2. 缺乏适当的挂钩到编译过程和元模型。如果Perl核心允许我们通过一个合理的API(允许我们与元模型(包、类等)挂钩)来影响编译过程,那么Moose总体上,尤其是角色使用,就会变得更加安全。

    3. 语言中缺少内置的命名参数。相反,每个人都在重新发明它。这是令人讨厌的。

    4. 类似地,缺少可选类型。我不想要一种静态语言,但是能够指定类型和约束,特别是函数/方法参数,将会很棒。Perl 6在这方面做得很好。类型是可选的,但非常丰富,内置类型和用户定义类型之间没有根本区别。

    5. 向后兼容警察。这更像是一个文化问题。上面的许多问题永远无法真正解决,因为Perl 5对向后兼容性有很强的承诺。因此,即使添加了一些东西,有效地取代了当前的平局和过载,这些功能也永远不会被删除。当然,向后兼容也是Perl 5最大的优势之一。

    6. Perl的内置异常机制是一个笑话。异常可能是字符串或对象,这一事实导致异常捕获代码的繁琐,而语言语法中缺乏捕获是疣上疣。

    我讨厌c++的五个方面

    • 联系时间。使用分布式构建,我可以在同一时间重新构建我们的整个项目,它需要我们的链接器运行。
    • 没有防止内存操作重新排序的标准方法。使用写组合内存通常需要滥用volatile关键字。防止读重排序(在处理SIMD数学管道时通常是优化的关键)通常是通过在例程中间注入空ASM块来实现的。
    • 多步宏来解决字符串化问题:
    #define STR_LINE2(x) #x
    #define STR_LINE(x)   STR_LINE2(x)
    #define LINE_NUMBER STR_LINE(__LINE__)

    • 做字符串操作通常是很痛苦的。
    • 大量的非标准化printf变体(vsnprintf_s vs _vsnprintf_s)。

    SAS

    • 从不有自己的想法(一切都是借来的)。

    • 贪婪于庞大的数据集。

    • 使用Java,但从未学习过什么是对象。

    • 窃取Perl,但将其隐藏在其数据步骤中。

    • 统计学家总是撒谎!

    JavaScript

    ECMAScript 5规范:

    • 7.6.1.2未来保留词:

      类,枚举,扩展,super, const,导出, 进口< / p >

      严格模式下:实现了,let, private, public, interface, package, protected, static, yield

    • 11.9.4严格等于操作符(===)对比11.9.1 TheEqualsOperator(==)
    • 11.9.6严格相等比较算法(NaN === NaN is false)
    • 8.5数字类型-没有实整数,所有都是浮点数。
    • 4.2.1对象——原型继承

    好吧,我有点喜欢最后一个,但它有7种让人困惑的地方

    c++

    • 涉及模板时的神秘错误消息
    • 缺少模板约束(在许多情况下可以使用模板元编程,但在大多数情况下这将导致不可读的代码(至少对普通程序员来说))
    • 指向成员函数语法的指针
    • c++标准委员会应该更频繁地发布官方标准(或者至少对标准库本身发布单独的更新),我的意思是真正的TR1是在2005年发布的,而我们仍然没有shared_ptr, bind之类的标准库。
    • -

    但这只是因为VB6毒害了整整一代程序员

    我在一个曾经是VB6商店的VB . net商店工作,而在这里工作的每一个曾经是VB6开发人员的人都顽固地拒绝学习任何关于. net的知识。他们编写的代码就像VB6一样,他们的应用程序就像VB6应用程序一样糟糕。我的老板非常不鼓励使用LINQ,因为她担心其他人很难理解,这是事实,因为没有人想要理解它。

    我认为如果微软只使用c#,我们会过得更好,这让我很难受,因为我认为花括号远不如VB的冗长结束语句。

    关于c#:

      我讨厌没有关键字来指定从方法抛出哪些异常 比如在java中。这是一种比使用XML注释更好的记录异常的方法
    1. 我还想要一个更好的通用约束的语法,比如约束的oring和and。
    2. 为什么一个方法不能返回多个值?
    3. 语言中缺乏对面向方面编程的支持。
    4. 为什么不能用属性注释每个属性访问器呢?
    5. 缺少内置的regexp支持,就像在perl中。

    R

    不是我最喜欢的语言,但我经常使用它,有很多抱怨……

    • S3对象只是美化了lists, S4类仍然将所有数据暴露给用户
    • 赋值操作符可以是<- ->=,参见迈克·杜瓦的咆哮
    • my.var是一个非常令人困惑的面向对象语言变量命名约定,参见谷歌的风格指南
    • 我不应该后悔使用循环
    • 神秘的错误消息

    Ruby。

    1. 奇怪的作用域规则——变量、常量和方法的行为各不相同。规则也会根据创建闭包时使用的关键字而变化。或者你是否在一个类、特征类、对象、模块或模块的self中。然后是instance_eval,它将规则更改为一组不同的规则。当一个模块被“包含”或“扩展”时,它们又会改变,这两个模块本身对作用域做了不同的事情。有些规则是元编程无法模拟的,所以你必须使用eval。除非您使用的是ruby 1.9,所有这些都是不同的。
    2. 命名空间基本上是无用的。如果你有Foo::File,那么对于所有的Foo来说,stdlib File可能已经被破坏了。
    3. Require语句被破坏。如果两个文件相互需要,这些文件的行为可能会发生巨大变化,这取决于哪个文件首先从其他地方加载。
    4. 库会戏剧性地突然改变api,所以你必须要求所有依赖项的特定次要修订号。对于系统上的每一个ruby应用程序。
    5. rubygems包系统覆盖了“require”,而不是把文件放在搜索路径中——因为当你可以替换一个系统时,为什么还要使用它呢?

    Python 3

      <李> 两个标签&允许使用空格缩进 < br > 你会认为人们会从过去吸取教训(Makefile)。只需要选择空格和禁止制表符。李YAML说对了。 < / > <李> 缺少流行的第三方库 < br > 标准库很棒,但Python 2如此强大的很多原因在于第三方领域。李Python 2是正确的:-)。 < / > <李> IEEE浮点数 < br > 编程语言中的浮点数令人困惑,因为它们与我们在数学中使用浮点数的方式不同。相反,数字操作应该被视为仅在需要时才转换为小数点格式的表达式(即打印到屏幕上)。李我认为Maple和Mathematica做得很好。 < / > <李> 标识符的字符集限制太大 < br > list.empty?list.is_empty甚至len(list) != 0更好。类似地,process.kill!process.kill更好。李Ruby和lisp在这点上是正确的。 < / > <李> 当调用一个函数时,必须always写圆括号 < br > 如果在明确的情况下我们可以省略它们,那就太好了。又怎么样了?dict.items还是dict.items()?李Ruby在这一点上也做对了。 < / >

    Python

    1. 标准库在很多地方都不遵守自己的风格指南。(PEP-8)
    2. Py3k的super关键字充满了不必要的魔法(你不能给它分配一个不同的名字,没有自我也能工作,为什么我们要有这个显式参数?)
    3. 在Py2k中Unicode支持不完整,Py3k也很糟糕(Unicode标准输入,没有二进制数据!WTF ?创建一个新的WSGI标准是很棘手的。)
    4. 吉尔。非常有限的多线程支持(使用CPython)
    5. PyPI (Python包索引)糟透了。嫉妒地看红宝石

    Python:

    1. 没有标准的GUI工具包(社区一直在讨论这个问题,但似乎从来没有确定任何东西)。

    2. 分发和安装Python应用程序和库的工具和方法的发展一直很坎坷。(尽管最近这个问题似乎正在接近解决。)

    3. 作为解释器,CPython仍然很慢(尽管PyPy现在看起来很不错,如果它成为“标准”Python,这个问题就会消失)。

    4. 你不能子类化内置类(例如,list和dict)而不重写很多方法,即使你想做的只是一个简单的钩子到一个事件(例如,钩子到一个被添加到列表或从列表中删除的项目,你需要重写delitem,追加,扩展,插入,弹出和删除——没有可子类化的“更改”事件通知,也没有任何“受保护”的方法来剔除所有上述方法使用的公共代码)。

    5. 在virtualenv发明之前,在一台机器上为不同的目的保留不同的Python环境是一件非常痛苦的事情。

    PHP:

    • 荒谬的assert()函数…它对里面的代码运行eval()
    • ?>标签删除了它后面的换行符?!
    • 奇怪的数字字符串处理(尝试将它们作为数组键)
    • 令人痛苦的unicode支持,似乎不再将由PHP 6解决
    • 入门成本低意味着95%的人给PHP程序员起了一个可怕的名字——试图在这5%中找到一个人来雇佣是疯狂的。

    Python

    1. 没有Django for Python 3。
    2. 静态类型。是的,动态类型是伟大的事情,但有时我想让它静态。
    3. 正确的unicode支持(在Python 3中修复)
    4. Construtors命名。我讨厌代码中的所有这些下划线。
    5. 线程的效率不是很高

    Scala是我最喜欢的语言。五件讨厌的事?容易:

    1. 正确地学习需要很长时间。我知道你可以把Scala写成“更好的java”。这也是我们过去对c++和C的看法。我同意这是语言中深层思想的必然结果。但是……

    2. 方法vs.函数:def f(x: Int) = x*x定义了一个方法f,而不是一个函数f。方法不是函数,尽管很多早期的Scala教程材料模糊了两者的区别。语言也试图模糊它,因为如果你在一些的地方提供一个方法,它是被接受的函数。我们必须同时拥有方法和函数吗?是的,这是基本的。但一开始我很困惑。

    3. 以“蛋糕”模式从mixin中组合类或对象很容易出现NPE。例如:trait X { val host: String; val url = "http://" + host }是一个mixin,它会在实例化时NPE,或者不会,这取决于它在类声明中的位置。编译器可以告诉你它是否会失败,但它没有。(至少在2.7中。)在复杂的继承图中很难诊断问题。

    4. 2.8中的数组依赖于隐式来与主要的scala集合类型相匹配。但隐式并不适用于所有地方。在需要Seq的地方可以提供Array。但是在需要Option[Seq]的地方不能提供Option[Array]。我知道没有完全“正确”的方法来处理java数组。

    5. 类型擦除。足够的说。

    Python:

    • 没有分隔符表示块的结束会导致歧义,这样自动缩进就不能处理格式不佳的代码。
    • 没有宏(修饰符不算)
    • 没有像haskell的cabal或perl的CPAN那样的库自动获取
    • 不能声明变量const(是的,可以自己定义变量,但是…)
    • 元编程被削弱
    • 差点忘了全局解释器锁

    BrainF * ck

    • 你的亮点是你是图灵完全?!我可以在Perl正则表达式中做更多的事情!

    • 缺少对象。来吧,人!就像,hello

    • 没有网络库。我只想刮一个网页,天哪。

    • 没有一级函数。恭喜你——你可以同情你的Java朋友了。

    • 一个无限的磁带存储,没有其他。这是如此的矫情,我们可能还在写Lisp。

    我只有一个,但我相信它值得分享。

    CSharp / .NET

    我们有Length属性来获取数组中的元素个数,还有Count属性来获取集合中的元素个数。如果考虑到CLR在后台自动将IList、ICollection、IEnumerable添加到基于零的一维数组,那么它看起来就更奇怪了。

    我相信CLR团队和BCL团队在讨论这个问题时遇到了困难;)

    c#。

    我最讨厌的是:

    1. 没有多重继承-想象你可以提供任何GUI框架基类(控件,窗口,等等)与MVC相关的东西,等等…框架/基类不可知论者!

    2. 没有“朋友”这个关键词……我知道,RAD的受害者会滥用它来处理各种糟糕的代码和滑稽的不当行为,但是对于OOD的人来说,执行得墨忒耳法则会很好

    3. 没有语言集成DBC的功能,有契约,但我宁愿有spec#风格的通用“!”-后缀运算符

    4. 没有AOP(我不明白…这种语言有属性,在编译器中添加拦截代码非常容易!)

    5. 没有弱事件委托——观察者模式变成了一个内存泄漏诱饵,就像现在一样……: - (

    对象帕斯卡:

    • 在您正在编辑的文件中有很多来回跳转的地方,因为接口和实现被分成了两个部分,但仍然挤在同一个文件中。
    • 数组的动态索引,字符串从1开始,在声明固定数组时指定起始索引,动态分配数组总是从0开始。
    • 类和对象(更不用说接口了)是固定在语言之上的,不能像记录那样进行堆栈分配。
    • 当调用不带形参的函数时,()是可选的,这会导致在处理函数指针或试图使用函数名引用函数的结果时非常痛苦。
    • 如果没有外部类型定义,形参列表无法处理固定的数组类型或函数指针类型。

    这仅仅是一种语言,一个标准库的遗憾借口,而脆弱的IDE应该有自己的列表。

    Java -不支持语言级别的合成

    德国

    我的母语……虽然它听起来比克林贡语更美,但它是一个语法地狱……

    1. 的结合:即使是规则动词也有不同的形式为每个人和时间(少数例外)…例句:我看,你看,他/她/它看,我们看,你看,他们看翻译成:Ich sehe, du siehst, er/sie/es sieht, wir sehen, ihr seht, sie sehen。
    2. 礼貌的称呼形式:等于第三人称复数,在中年用来等于第二人称复数…我真的很讨厌区分“你”和“你”的概念,因为我的哲学是,每个人都应该受到同等的尊重(我的意思是,脏话是为了什么,嗯?)
    3. 标点符号:告诉我一种经常使用逗号的语言!
    4. 缺少合适的词语:如。德语中没有“方便”的真正的等价词,也没有这个词的任何衍生词……几乎在所有情况下,你都无法把它翻译成另一个德语单词,并保留它的意思……相反,你必须组成一个完整的子集来适当地描述它……
    5. 英语和Denglish:当然,英语中有“Kindergarten”或“Poltergeist”之类的词,但德语中充斥着没有人需要的英语词……更糟糕的是:我们重新定义了一些我们使用的词,例如。在德语中“Handy”是手机的意思,在英语中和形容词没有任何关系。语法上也有大量的涌入,导致了“Denglish”表达(见维基百科上的链接文章) 还有更多,但我不想夸大这一点,这些是我个人最讨厌德语的5个地方

    我讨厌所有语言的五件事(至少就我所知):

    1. 我说的/打的不是我的意思吗
    2. 毫无疑问会遇到一些人,他们认为自己是语言专家,但只是把它搞得一团糟(例如,有人坚持删除注释/未使用的局部变量将加快程序的执行时间)
    3. 除非语言已经过时,否则它很可能会继续发展(无论是实际的语言,还是有效使用它背后的概念),要求您积极地与它一起发展,以免落后。
    4. 不能修改词法分析器/编译器(在自己的上下文敏感语法中添加)
    5. 没有完美的语言(每种语言都缺少一些有用的特性,这些特性通常要么无法模拟,要么不可避免地有一个丑陋的界面,要么只是需要太多的时间来实现并使其正确)

    objective - c 2.0

    严格遵循语言和运行时,而不是库,并且没有任何特定的顺序:

    1. 缺少cVars。
    2. 没有模块。我对缺少名称空间并不是特别不满,但是如果有模块就更好了。
    3. 基于var的属性语法要求在3个地方使用变量名进行声明。相当难看。
    4. C遗产。除了OO和GC之外,C语言的所有缺点都是存在的。
    5. 对象不能存在于堆栈中。Obj-C的问题并不像它对其他语言的编程实践的影响那么大。例如,当我在c++中获得堆栈上的返回值时,我发现这很奇怪。如果我在编写代码时没有实际查看库文档,我将假设每个函数都返回一个指针,这通常会导致稍后进行一些重要的清理。

    c# 4.0

    “动态”关键字,被滥用的时机已经成熟。如果你想要/需要使用反射,使用并让它明显地显示你正在使用它,不要试图用动态来伪装它。

    Python:

    1)连续行语法:"…“有用,但是……”“\”不存在,并且后面的空格通常是不可见的,编辑器没有不寻常的eol标记 2)一个裸的'raise'在堆栈跟踪中是不可见的,因为堆栈跟踪看起来像之前抛出的异常 3)缓慢< br > 4)与web服务器集成不良(mod_python:死,mod_wsgi:操作范围有限)。这是复杂的3],需要daemonization或某种内存持久化来执行良好 5)过度容忍混合制表符和空格,允许控制流的更改有时仍然隐藏。(可能在最近的版本中修正)

    Java:

    1. 很不一致。
    2. 图形api有时使用起来很痛苦
    3. nullpointerexception不会告诉你什么是null
    4. 我写的程序有时不能在不同的JVM上运行,这是一个巨大的痛苦,与Java的“一次编写,随处运行”语句相矛盾。
    5. Swing并没有达到应有的效果。

    Python:

      你通常在文件末尾有程序的入口点。 (因为如果它调用模块中定义的任何函数,它必须发生在源代码中那些函数之后。) 我讨厌你不得不花时间寻找程序的入口点,所以我总是有一个简单的main.py文件:

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

    Lua:

    • 元表是如此令人困惑,直到他们“点击”
    • 缺少像a += 20这样的赋值操作符是一个麻烦
    • 没有集成的面向对象的解决方案意味着每个人和他的狗都使用自己的口味
    • 用于注释的语法(--)排除了加/减前和后操作符的可能性
    • 不入侵C端就不可能有任何先发制人的多任务系统

    Perl 5从最讨厌到最不讨厌。

    < p > 1) 向后兼容警察。是的,backcompat是一种优势,但是Perl 5太过分了。现在,如果不显式地启用它们,我们甚至无法在语言中获得新特性。我更喜欢相反的情况,如果一个新功能导致了一个问题,让我禁用它或强制执行旧的行为。例如,perl 5.10添加了say,如果我有自己的say实现,我宁愿有no feature 'say',而不是不得不放use feature 'say';use 5.010; 如果5.8有效,5.10无效。我宁愿使用use 5.008;来限制我的代码只使用5.8以下可用的特性,如果没有定义use version;,那么它应该默认为你正在运行的任何版本,并且建议除非必要,否则不要限制它

    2) 过度的样板

    #!/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;
    

    现在你可以开始编码了。这不会因为第一条而改变。当然,这个东西有一些快捷方式,比如use common::sense;use modern::perl;,它们会缩短上面的内容,你可能需要一些稍微不同的模块或pragma。但因为第一条,我们永远无法把它降低到。

    #!/usr/bin/perl
    package Package::Name 0.01;
    
    
    sub somesub ( $param1, $param2 ) {
    }
    

    一些模块正在帮助解决这个问题,在5.0.12中有新的包版本,它完全允许这种语法,尽管我认为它首先需要use 5.012;Method::Signatures,但它永远不会完全解决(在语言上)。

    3) 糟糕的变量选择

    吸吸文件

    #!/usr/bin/perl
    use strict;
    use warnings;
    open my $fh, "< foo" or die $!;
    local $/; # enable localized slurp mode
    my $content = <$fh>;
    close $fh;
    

    $!$/是什么?重写为易读。

    #!/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;
    

    不要忘记,如果你不想受到性能影响,'-no_match_vars'必须在那里。

    不直接创建匿名标量怎么样?

    #!/usr/bin/perl
    my $scalar_ref = \do{ my $anon_scalar };
    

    他们就不能想出点什么办法吗?

    #!/usr/bin/perl
    my $scalar_ref = <>;
    

    哦,perl是线程不友好的,因为所有的变量(包括特殊的变量)默认是全局的。至少现在你可以用my $_;来限定它的词法范围,而用local限定其他的词法范围。

    4) 非常难看的语法

    MooseX::Declare是一个更好的语法。我也希望->被替换为。(个人喜好不太重要)

    5.) 时间太长了太多的最佳实践似乎你必须读3-5本书才能弄清楚所有的你应该怎样做事情

    6)。以前的(不再适用)。Un-sane版本。5.10.0有新功能5.10.1的新功能没有设定时间,直到下一个版本。现在是每年一次的特性发布,每季度更新一次。

    7) 象牙塔视角。社区问题,似乎是大量的开发者想要高门槛进入,并认为可以不尊重地对待是n00bs(或任何不同意他们的人)。

    8.) 疯狂的版本号/字符串 Perl有浮点版本号,它们很丑。开发人员不知道并不是所有的下游处理版本比较的方式都是一样的。不是语言问题

    0.012 # simple
    5.012001 # semantic
    4.101900 # time based + version (for multiple versions in a day)
    0.035_002 # prerelease
    

    所有有效版本的perl..我们就不能用…

    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
    

    除了

    9) 升级后没有明显的方法重新安装所有XS模块

    Python (3.1)

    • 条件语句的奇怪的无序T if C else F语法。
    • bytes字面量看起来太像str字面量了。我们应该有类似x'414243'的东西,而不是b'ABC'
    • str在某些平台上是UTF-16,在其他平台上是UTF-32。(尽管至少比2要好。x字符串。)
    • 具有相同的加法和连接运算符。这对numpy.array这样的类型很不利。
    • 运行缓慢。

    EL -表达式语言,JSP页面中的${...}#{...},以及JSF 2.0 Facelets,用于从底层Java代码中提取数据。

    • 所有有趣的事情,比如带参数的方法调用和基于注释的命名,都只存在于Java EE 6的EL中,而这只在Glassfish v3中可用。
    • 1)为早期的Servlet 2.5容器获得正确的jar, 2)让它们在不干扰容器中任何以前可用的实现的情况下工作,这是一件非常痛苦的事情。
    • 只有早期版本的JSF,比如1.2,去掉了方法调用,让你使用f:setPropertyActionListener - http://weblogs.java.net/blog/2009/07/22/say-sayonara-spal,相信我,这不是很好。
    • EL解析器有没有概念,知道它要解析和解释的代码片段来自哪里,所以你倾向于给所有内容一个id,这样你至少可以识别是哪个标签使它变得暴躁。
    • Eclipse在每次EL方法调用时都会发出警告,因为它是JSF 1.2。只有。

    Lua:

    • < p > 内置的错误系统非常可怕

      你可以通过修改Lua解释器来实现try-catch系统;但是它与内置函数抛出的错误不兼容

    • < p > 它们使用__newindex而不是__setindex作为setter

      ... 而__newindex仅在键不存在时才会被触发。如果是,则根本不调用元方法

    • < p > 没有好的类型比较系统。

      有type()函数,但它只处理基本类型(所有表都是表)。它确实需要一个元方法来进行类型比较。我之前已经用一个'is'操作符和__type元方法实现了这个方法,它工作得非常好

    • < p > 定义新的关键字很麻烦。

      你可以这样做,但是Lua中的代码并没有很好地记录,所以需要反复试验才能找到你想要的结果。当你想自己实现我上面提到的东西时,这是一个主要的问题(虽然没有太多__setindex,但那是一个简单的修改)

    • < p > 我不能在网络浏览器中使用它。

      是的,语言本身并不是问题,但是该死的,我希望能够使用Lua而不是Javascript……:) < / p >

    C

    • 字符串处理
    • 内存管理(决定谁应该分配内存,谁应该释放内存)
    • 没有名称空间(最大的)
    • 标准库中没有列表/数组和其他基本DS


    JavaScript

    • 使用不带var的变量会自动使其成为全局变量
    • 分号不是强制性的
    • 比较运算符“==”和“===”以及它们用法上的混淆
    • 没有适当的支持来处理二进制数据
    • 再一次. .没有命名空间
    • 变量没有块作用域。(来自C世界的人很讨厌)

    到目前为止,我最讨厌我最喜欢的语言的地方是我的选择总是在变。每次我认为我已经找到一个,我发现五个(或更多)的事情,我讨厌它。然后那边的草看起来更绿……