关于语法:你的语言是什么“挂起”?

What are your language “hangups”?

我感兴趣地读了一些最近的语言与语言问题…Perl与Python、Python与Java相比,一种语言能比另一种语言更好吗?

我注意到的一件事是,我们很多人都有非常肤浅的理由不喜欢语言。我们乍一看就注意到这些东西,它们把我们关了。由于我们可能会在2秒钟内学会爱上或忽略的特性,我们避开了可能是非常好的语言。

嗯,如果不是更多的话,我和下一个家伙一样有罪。下面是:

  • Ruby:我看到的所有Ruby示例代码都使用了puts命令,这是一个幼稚的意第绪语解剖学术语。因此,我不能认真对待Ruby代码,即使我应该这样做。
  • Python:我第一次看到它的时候,我笑了笑整个重要的空白。在接下来的几年里,我一直避免这样做。现在我几乎什么都不用了。
  • 爪哇:我不喜欢看起来像这样的标识符。我不知道为什么。
  • 丽斯:所有的括号我都有问题。不同重要性和目的的事物(函数声明、变量分配等)在语法上没有区别,我太懒了,不知道什么是什么。
  • Fortran:大写,一切都伤到我的眼睛。我知道现代代码不必这样写,但大多数示例代码是…
  • VisualBasic:Dim用于声明变量让我很烦,因为我记得gw-basic的好日子,那时它只用于维度数组。

我第一眼看到的是什么语言?perl、c、qbasic、javascript、汇编语言、bash shell等等。

好吧,既然我已经把脏衣服晾干了…我想听你的。你的语言障碍是什么?什么表面特征困扰着你?你是怎么克服的?


我讨厌恨"结束功能"和"结束如果"和"如果…然后是"vb的一部分。我宁愿看到一个花括号代替。


PHP的函数名不一致。

1
2
3
4
5
6
7
8
9
10
11
// common parameters back-to-front
in_array(needle, haystack);
strpos(haystack, needle);

// _ to separate words, or not?
filesize();
file_exists;

// super globals prefix?
$GLOBALS;
$_POST;


我从来没有真正喜欢在一些脚本shell中反向拼写的关键字。

如果那样的话,FI就够糟糕了,但ESAC的情况就变得越来越愚蠢了。


我只是想到另一个…我讨厌XML中用来定义名称空间的那些毫无意义的URL,例如xmlns="http://purl.org/rss/1.0/"


帕斯卡的BeginEnd。太冗长,不需要括号匹配,更糟的是,每个End都没有Begin,例如。

1
2
3
Type foo = Record
    // ...
end;


虽然我主要是一个PHP开发人员,但我不喜欢那些不允许我在内联中做足够事情的语言。例如。:

1
2
$x = returnsArray();
$x[1];

而不是

1
returnsArray()[1];

1
2
3
4
function sort($a, $b) {
    return $a < $b;
}
usort($array, 'sort');

而不是

1
usort($array, function($a, $b) { return $a < $b; });


我喜欢面向对象的风格。所以在python中,看到len(str)得到一个字符串的长度,或者像split(str,"")那样在另一种语言中拆分字符串会让我很烦。在C语言中可以,它没有对象。但python、d等确实有对象,并在其他地方使用obj.method()。(我仍然认为Python是一种很棒的语言。)

矛盾是我的另一个大问题。我不喜欢同一个库中的不一致命名:length()、size()、getlength()、getlength()、toutfindex()(为什么不toutfindex?),常数,常数等。

.NET中的长名称有时会困扰我。他们不能以某种方式缩短DataGridViewCellContextMenuStripNeedEventArgs吗?那么listviewvirtualtitemsselectionrangechangedeventargs呢?

我讨厌目录树。如果一个库/项目有一个5级深的目录树,我会遇到麻烦的。


C和C++的语法有点古怪。它们对不同的事物重用操作符。你可能已经习惯了,以至于你不会去想它(我也不会),但是想想括号有多少含义:

1
2
3
4
5
6
7
int main()        // function declaration / definition
printf("hello")   // function call
(int)x            // type cast
2*(7+8)           // override precedence
int (*)(int)      // function pointer
int x(3)          // initializer
if (condition)    // special part of syntax of if, while, for, switch

如果你在C++中看到

1
foo<bar>(baz(),baaz)

如果没有foobar的定义,你就不知道它的意思。

  • <和>可能是模板实例化,或者可能小于或大于(异常但合法)
  • ()可能是一个函数调用,也可能只是围绕逗号运算符(即,执行baz()以获得大小效果,然后返回baaz)。

可笑的是,其他语言都复制了这些特征!


Java及其检查异常。我离开Java一段时间,居住在.NET世界,然后最近回来了。

有时,我觉得我的throws子句比我的方法内容更大。


我厌恶Java的锅炉板冗长。

  • 为属性编写getter和setter
  • 检查异常处理和所有暗示
  • 长长的进口清单

那些与使用EDCOX1〔4〕的Java约定有关的,有时让我觉得我回到了80,在我的程序的顶端写EDCOX1×5。

提示:如果您可以在您的IDE中自动生成部分代码,这是一个很好的提示,表明您正在生成样板代码。使用自动化工具,写代码不是一个问题,但每次有人必须读代码时,它都是一个障碍——这更常见。

虽然我认为这种类型的官僚主义有点过分,但斯卡拉已经成功地解决了其中一些问题。


世界上没有什么比PHP更让我讨厌的了。

  • 变量与$,这是一个额外的奇数字符为每个变量。
  • 访问成员时,如果没有明显的原因,可以使用->进行访问,每个成员访问一个额外的字符。
  • 真是一场怪诞的语言秀。
  • 没有命名空间。
  • 字符串与..
  • 怪异的语言表演。

  • 目标C中的所有[]s和@s。它们的用法与底层C的本地语法非常不同,以至于我第一次看到它们时,会觉得所有的对象方向都是事后才笨拙地固定在一起的。


    (P)特别是挤奶…(p)(P)奥坎(p)

    • (P)Tuples definitions use EDOCX1 English 0 to separate items rather than EDOCX1So,EDOCX1(音乐剧2)has the Type EDOCX1(音乐剧3)(p)
    • (P)For being such an awesome language,the documentation has this haunting comment on threads:"The threads library is implemented by time-sharing on a single procesor.It will not take advantage of multi-processor machines.利用这一图书馆,将永远不会使程序运行快。"Jocaml's doesn't fix this problem.(p)
    • (P)我听过简街上的人说,他们是在努力工作,以增加相互竞争的GC和多核心威胁到OCAM,但我不知道他们是如何成功的。I can't image a language without multi-core threads and GC surviving very long.(p)
    • (P)不容易在顶层探索模块。Sure,you can write EDOCX1 niplication 4 and the toplevel will happen print out the module definition,but that just seems hacky.(p)

    (P)c.35;(p)

    • (P)Lousy type inference.超越大多数的三维表达方式,我有给类型的性别功能。(p)
    • (P)所有Linq Code I every read used method syntax,EDOCX1不是每一个用户都能用的Syntaxbetween you and me,I think expression syntax is silly,if for no other reason than that it looks"foreign"against the backdrop of all other C′35;and VB.net code.(p)

    (P)林克(p)(P)工业标准名称所使用的所有其他语文均为地图、Fold/reduce/inject和filter。Linq has to be different and uses select,aggregate,and where.(p)(P)功能编程(p)(P)Monods are mystifying.Having seen the parser monad,maybe monad,state,and list monds,I can understand perfectly how the code works;however,as a general design pattern,I can't seem to look a t problems and say"Hey,I bet a monad would be perfect here".(p)(P)鲁比(p)(P)Grrrraaaaaah!不!不!我尿…Seriously.(p)(P)VB(p)字母名称(P)And setter declarations are the bane of my existence.Alright,so I change the data type of my property--Now I need to change the data type in my setter too?Why doesn't vb borrow from C'35;and simply incorporate an implicait variable called value?(p)(P)Net Framework(p)(P)I personally like Java casing convention:classes are pascalase,methods and properties are camelacse.(p)


    团队项目中的编码样式不一致。

    我正在处理一个大型团队项目,其中一些参与者使用了4个空格而不是制表符。使用他们的代码可能非常烦人-我喜欢保持代码的整洁和一致的风格。

    对于不同的语言使用不同的标准已经够糟糕了,但是在一个包含html、css、javascript、php和mysql的Web项目中,这是5种语言、5种不同的样式,并乘以项目中工作的人数。

    当我需要修复某个问题时,我希望重新格式化我的同事代码,但是存储库会认为我更改了他们代码的每一行。


    不能完全决定数组/循环/字符串索引是基于零还是基于一的任何语言。

    我个人更喜欢基于零的语言,但是任何混合这两种语言的语言,或者让您"配置"使用的语言都会让您疯狂。(阿帕奇速度-我正朝你的方向看!)

    从vtl引用中截取(默认值为1,但可以将其设置为0):

    1
    2
    3
    # Default starting value of the loop
    # counter variable reference.
    directive.foreach.counter.initial.value = 1

    (尝试合并使用不同计数器方案的2个项目-啊!)


    我讨厌分号。我发现它们增加了很多噪声,你很少需要把两个语句放在一行上。我更喜欢Python和其他语言的风格…行尾是语句的结尾。


    如果微软不得不在C语言中发明另一种类似C++的语言,为什么他们没有纠正Java的错误并实现对RAII的支持呢?


    有时我很恼火,人们是如何期望所有工作都有一种语言的。根据您所做的任务,每种语言都有其优缺点。我喜欢基于C的语法语言,因为这是我最习惯的,我喜欢它们给开发人员带来的灵活性。当然,拥有强大的权力就意味着巨大的责任,拥有编写150行LINQ语句的权力并不意味着你应该这么做。

    我喜欢最新版本的vb.net中的内联XML,尽管我不喜欢使用vb,主要是因为我发现对于C来说,IDE没有那么有用。


    SQL,他们说你不应该使用光标,当你这样做的时候,你真的明白为什么…太沉重了!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <wyn>
        DECLARE mycurse CURSOR LOCAL FAST_FORWARD READ_ONLY
            FOR
            SELECT field1, field2, fieldN FROM atable

        OPEN mycurse
        FETCH NEXT FROM mycurse INTO @Var1, @Var2, @VarN

        WHILE @@fetch_status = 0
        BEGIN
            -- do something really clever...

            FETCH NEXT FROM mycurse INTO @Var1, @Var2, @VarN
        END
        CLOSE mycurse
        DEALLOCATE mycurse
    </wyn>


    区分大小写。

    你需要什么样的宿醉才能认为区分两个标识符是一个好主意?


    我发现Perl对"defined"和"undefined"值的使用非常有用,以至于在没有它的情况下使用脚本语言会遇到困难。

    Perl:

    1
    ($lastname, $firstname, $rest) = split(' ', $fullname);

    无论$fullname中有多少个字,此语句都能很好地执行。用python试试,如果$fullname不包含三个单词,它就会爆炸。


    在Ruby中,我非常不喜欢方法如何不需要在当前实例上调用self.,但是属性是这样的(否则它们将与局部变量冲突);即:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def foo()
       123
    end

    def foo=(x)
    end

    def bar()
        x = foo() # okay, same as self.foo()
        x = foo   # not okay, reads unassigned local variable foo
        foo = 123 # not okay, assigns local variable foo
    end

    在我看来,这是非常不一致的。我宁愿在任何情况下都要求self.,或者给当地人留个信号。


    虽然我主要用Python编程,但lambda主体必须是表达式这一点却让我无限恼火。

    我仍然在用JavaScript来包装我的大脑,从整体上来说,它是可以接受的。为什么创建一个名称空间如此困难?在TCL中,它们只是丑陋的,但在JavaScript中,它实际上是一个老生常谈,完全不可读。

    在SQL中,为什么一切都只是一个巨大的freekin select语句。


    在C/C++中,对如何编写相同的代码有不同的方式感到恼火。

    例如

    1
    2
    3
    4
    5
    if (condition)
    {
       callSomeConditionalMethod();
    }
    callSomeOtherMethod();

    VS

    1
    2
    3
    if (condition)
       callSomeConditionalMethod();
    callSomeOtherMethod();

    等同于同一件事,但不同的人有不同的风格。我希望最初的标准对这方面的决定更加严格,这样我们就不会有这种模棱两可了。它会导致代码评审中的争论和分歧!


    Java的包。我觉得它们很复杂,因为我不是一个公司。我非常喜欢名称空间。当然,我会克服的-我在玩Android SDK,Eclipse消除了很多痛苦。我以前从未有过一台可以交互运行它的机器,现在我有了它,我印象非常深刻。


    prolog的if-then-else语法。

    1
    x -> y ; z

    问题是";是"or操作符",所以上面看起来像"x表示yz"。


    爪哇

    • 泛型(Java版本的模板)是有限的。我不能调用类的方法,也不能创建类的实例。容器使用泛型,但我可以使用对象实例的容器。
    • 没有多重继承。如果多重继承使用不会导致菱形问题,则应允许使用。它应该允许编写接口方法的默认实现,这是一个问题的例子:接口mouseListener有5个方法,每个方法对应一个事件。如果我只想处理其中的一个,我必须将其他4个方法实现为空方法。
    • 它不允许选择手动管理某些对象的内存。
    • Java API使用类的复杂组合来完成简单的任务。例如,如果我想从一个文件中读取,我必须使用许多类(filereader、fileinputstream)。

    Python

    • 缩进是语法的一部分,我更喜欢使用单词"end"来表示块的结尾,而不需要单词"pass"。
    • 在类中,"self"一词不应该作为函数的参数。

    C++

    • 头是最严重的问题。我必须在头文件中列出这些函数,并在cpp文件中实现它们。它不能隐藏类的依赖项。如果A类单独使用B类作为字段,如果我包含A的头,B的头也将包含在内。
    • 字符串和数组来自C,它们不提供长度字段。很难控制std::string和std::vector是否使用堆栈或堆。如果要使用赋值,我必须将指针与std::string和std::vector一起使用,将其作为参数传递给函数或返回它,因为它的"="运算符将复制整个结构。
    • 我不能控制构造函数和析构函数。很难在没有默认构造函数的情况下创建一个对象数组,或者选择要与if和switch语句一起使用的构造函数。

    我和C的宿醉很简单:

  • 作用域块
  • 我希望我能写作

    1
    2
    3
    4
    5
    with SomeObject
    {
        .Property ="Some value";
        .Event();
    }

    而不是:

    1
    2
    SomeObject.Property ="Some value";
    SomeObject.Event();

    特别是在StringBuilder上使用Append、AppendFormat,这样可以减少代码读取的麻烦。

  • 空值
  • 我希望我能说:

    1
    var result = SomeObject.SomeCollection.First().SomeProperty ???"Default value";

    而不是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    string result = string.Empty;

    if ( SomeObject != null && SomeObject.SomeCollection.Count() > 0 )
    {
        result = SomeObject.SomeCollection.FirsT().SomeProperty;
    }
    else
    {
         result ="Default value";
    }

    我讨厌空异常,希望有一个平滑的空合并,可以在多个层次上深入工作。


    tsql begin&end…这很烦人…


    在大多数语言中,文件访问。到目前为止,vb.net是唯一对我有意义的文件访问语言。我不明白为什么我要检查文件是否存在,我应该使用file.exists(")或类似的东西,而不是创建一个文件对象(实际上是vb.net中的fileinfo)并询问它是否存在。然后如果我想打开它,我要求它打开:(假设一个名为fi的fileinfo对象)例如fi.openread。返回流。很好。正是我想要的。如果我想移动一个文件,fi.move to。我也可以做fi.copyto。在大多数语言中,不生成文件完整的对象,这是什么胡说八道?另外,如果我想遍历目录中的文件,我可以创建目录对象并调用.getfiles。或者我可以做.getdirectories,我得到了一组全新的directoryInfo对象。

    诚然,Java有一些文件的内容,但是这种无意义的东西必须有一个完整的对象来告诉它如何列出文件是愚蠢的。

    另外,我讨厌::、->、=>和除<=和>=(可能还有--和++)之外的所有其他多字符运算符。


    我最大的障碍是matlab的语法。我用它,有一些我喜欢的东西,但它有很多令人讨厌的怪癖。让我们看看。

    • 矩阵用括号作索引。所以如果你看到像image(350260)这样的东西,你就不知道我们是从图像矩阵中得到一个元素,还是我们调用了一个称为image的函数并向它传递参数。
    • 范围是疯狂的。我似乎记得for循环结束后,索引变量仍在范围内。
    • 如果在赋值后忘记使用分号,则该值将被转储到标准输出。
    • 每个文件可以有一个函数。这对组织一个人的工作是很烦人的。

    如果我考虑的话,我肯定能想出更多的办法。


    [免责声明:我对vb只是略知一二,所以请接受我的评论]

    我讨厌vb中的每个关键字都是这样大写的。前几周(月?)我看到一篇博文。关于一个试图在没有大写字母的情况下编写VB代码的人(他们对一个编译器做了一些事情,这样他们就可以编译这样的VB代码),而且这种语言看起来好多了!


    我有一个。

    我讨厌所有过于严格的静态类型语言。

    我觉得C很棒,直到我开始被迫写这样的代码:

    1
    2
    3
    void event...(object sender,EventArgs e){
      int t=(int)(decimal)(MyControl.Value); //Value is an object which is actually a decimal to be converted into an int
    }

    哦,属性很简单。微软真的不会认真考虑比[MyAttribute(Argument)] void function...更丑的事情吗?世界跆拳道联盟?甚至都不要让我开始使用XAML标记。

    因为空白的问题,我不能认真对待python。

    有时我很难认真对待鲁比,因为

    a)我从《为什么是辛酸的指南》中学到了自己。

    b)在某些情况下,标识符类型由案例决定。不过,我已经克服了这一点,因为它比const关键字更明智、更干净。现在在每一种语言中,当我使一个常数变为大写时。

    哦,我也讨厌

    1
    2
    if(a)
      b();

    语法。你不知道我刚做了多少次

    1
    2
    3
    if(a)
      b();
      c();

    不小心写了这样的代码……实际上,情况可能更糟

    1
    2
    if(a)
      b(); c();

    它唯一应该被使用的地方是

    1
    2
    if(a){ ....
    }else if(b){ ...

    (P)I hate that in python I never know if some thing is a method on an object,or some random function floating around(see built-in functions).他们的感觉是,他们首先要做的是使语言目标对准目标,但他们却被禁止使用。It makes more sense to me to have such functions be methods on some base class,like object.(p)(P)I also hate the EDOCX1 penographic 7-style methods,and that if I really want to,I can still access private studff in a class from outside the class.(p)(P)The Whitespace requirement bugs me;I don't want the language designer making me code a certain way.(p)(P)I don't like the one-right-way-to-do-some idea to which pyton adheres.I want options.(p)


    我讨厌Lisp和Scheme中的括号,因为在C、C和类似的语言之后,它看起来非常模糊,而且还不清楚事物是如何相关的。然而,既然我对Scheme有所了解,而且它是常见的格式化指导原则,我不会说我喜欢它的工作方式,但至少我理解,并且克服了阅读用clisp/Scheme编写的代码时的恐惧。

    我认为,如果你学习一些东西并使用它一段时间(也许几个小时就足够了,至少对我来说足够了),你实际上可以克服你对语法的厌恶,并且能够专注于你应该用语言这个工具做什么。


    适用于多种语言:

  • 案件敏感性-谁的主意是?!(使用不同意思的东西的人和使用不同意思的东西的人都应该被枪杀。)

  • 数组索引从0开始。我来自Fortran背景,这也是另一个原因,但是在数学数组中,索引总是以1开头,因此在实现更大的模型时,它往往会造成很多麻烦(尤其是在调试时)。

  • 分号-只是代码中的垃圾。如果您仔细编写代码(fortran、python等),就不需要它们。如果你没有,他们就不会救你。

  • 花括号-见3。

  • 另外,你们都在外面。别生气。如果你不喜欢这个答案,你就不应该问。


    我有一个实用的,从多年的代码重排和调试其他人的代码。我将删除(从所有语言中)在条件语句中对逻辑操作进行分组的能力。这来自于一个关于和操作员的特殊抱怨,例如…

    1
    2
    3
    4
    if (a and b)
    {
      do something
    }

    共有四起案件,其中三起尚未处理。程序员很可能已经考虑了所有4种情况,并故意选择用这种方式编写代码,但是除非他们对代码进行了注释,否则我们没有任何迹象表明是这样的——通常情况下他们没有。

    这可能有点冗长,但下面是明确的…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    if (a)
    {
        if (b)
        {
            do something
        }
        else
        {
            what about this case?
        }
    }
    else
    {
        if (b)
        {
            what about this case?
        }
        else
        {
            do something else
        }
    }

    作为一年后跟进的穷人,至少我会确切知道会发生什么。