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

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

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

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


This is a good question for code reviews too. People who really know a codebase will have all sorts of suggestions for it, and those who don't know it so well have non-specific complaints. I ask things like "If you could start over on this project, what would you do differently?" In this fantasy land, users and programmers get to complain about anything and everything they don't like. "I want a better interface", "I want to separate the model from the view", "I'd use this module instead of this other one", "I'd rename this set of methods", or whatever they really don't like about the current situation. That's how I get a handle on how much a particular developer knows about the codebase. It's also a clue about how much of the programmer's ego is tied up in what he's telling me.

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


当前回答

Python

No statements in lambdas. GRRRR foo( a for b in c if d ) feels wrong, it surprises me every time I get away with it. Shouldin't it be foo( (a for b in c if d) )? Can i have a dict comprehension? map and filter operators have special syntax in list comprehensions, how about something for reduce? or sort? Just by having a yield statement in it, a function is magically transformed into a generator, and its interface changes completely. Also, that generator cannot do any work before the first next(). at least, not without using a function that returns a generator.

JavaScript

No brief syntax for making modular code libraries. You have to call a function that returns a dictionary of public methods. And you have to edit that in (at least) two places every time you alter the interface of your module. Creating closures involves returning it from a function that returns a function from ('sup dog) yo' function. Clutter! for each ( foo ) syntax and behavior feels like an afterthought. Knowing when your code will actually run (and in what order) is more of a dark-art. The only way to get it right for sure is put everything (yes, that too) in one big file. and even then you still need to wait for a document.onload Am i missing something? is there no trivial way to get json serialized values without building them by hand? (yes jQuery can do this, sort of).

其他回答

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

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

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

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

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

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

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

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

当设计一种语言时,设计者通常会考虑它的用途。用它做一些完全不同的事情是可以的,但是当它不起作用时抱怨是愚蠢的。Python。我相信总有一天会有人用Python代码创建exe工具。你到底为什么要这么做?不要误解我的意思,这样做很好,但没有任何用处。所以别再抱怨了!

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

4-你是用木腿站着吗?

The platform can be a large influence of what the language can do. With nowadays garbage collectors, or well even pascals early attempt at "garbage collection", can aid in memory fade (maybe malloc more ram??). Computers are faster and so of course, we expect more out of our languages. And quite frankly, we probably should. However, there is a huge price to pay for the convenience of the compiler to create hash tables or strings or a variety of other concepts. These things may not be inherit to the platform of which they are used. To say they are easy to include to a language just tells me you may not have a leg to stand on.

3-到底是谁的错?

Bugs. You know. I love bugs. Why do I love bugs. Because it means I get to keep my job. Without bugs, there would be many closed pizza shops. However, users hate bugs. But here is a little splash of cold water. Every bug is the programmers fault. Not the language's. A language with such a strict syntax that would significantly reduce how many bugs were possible to generated would be a completely useless language. It's abilities could probably be counted on one hand. You want flexibility or power? You've got bugs. Why? Because you're not perfect, and you make mistakes. Take a really identifiable example in C:

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

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

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

It's very easy to point at a feature in a language we don't understand because we don't use it often and call it stupid. Complain that it's there etc. Goto's always entertain me. People always complain about goto's being in a language. Yet I bet your last program included a type of goto. If you have ever used a break or a continue, you've used a goto. That's what it is. Granted, it's a "safe" goto, but it is what it is. Goto's have their uses. Whether "implicit" gotos like continue or break are used or explicit gotos (using the actual keyword "goto" for whatever language). Not that language developers are flawless, but typically... if functionality has existed since the dawn of time (for that language). Likely that aspect is a defining quality of that language. Meaning.. it's being used and likely is not hanging around because of backwards compatibility. It's being used today. As in 5 minutes ago. And used properly. Well.. arguably someone is using it improperly as well, but that relates to #3 on my list.

1. -一切都是客体。

Ok.. this one is really a subset of #2. But this is by far the most annoying complaint I see in hate lists. Not everything is an object. There are a great many of concepts that do not belong or need to be objects. Putting things where they don't belong is just ugly and can decrease efficiency of a program. Sure. Maybe not much depending on the language. This also relates to #5. This means... yes. Global are ok. Functions as apposed to static methods are ok. Combining OO programming with global functions is ok. Now.. that doesn't mean we should all go out and "free" our code from it's object models either. When designing a section of code or a whole project, what happens behind the scenes should be considered when putting it together. Not only where that concept lives and many other factors. Why wrap global functions within classes or name space concepts if it serves no purpose? Take static member variables. That greatly amuses me because.. well..Depending on the language and implementation of course, but generally speaking, you just declared a global. Yes, there are some reasons to wrap these non-OO concepts in OO wrappers. One of course being self documenting code. That can make sense. So.. like I say. Don't go out and "free" your code. But any good modern language will have a global concept outside of it's OO modeling. Yes I'm specifically meaning to point out that an OO programming language without a global concept most likely has a serious design flaw. Again though.. depends on the intention and design of the language so I'm not attempting to pick on any specific language and there are far too many to analyze right here. Anywho, Consider where the code should live and be the most effective. Adding a bunch of flare to something which doesn't add functionality or support just wears down the keyboard faster. It doesn't do anybody any good. Well.. unless you like brownie points from the person who probably incorrectly taught you that everything is an object.

In short, programming isn't just mindlessly tapping on the keyboard. There are a lot of design considerations to any project. I know it's cliche, but you have to look at it from every angle. Even with nowadays type-safe languages. You don't just chuck code out and expect it to work well. Sure.. it may work, but it may not be the right way to go about it. Overall, pick the language and format that is best suited for the specific job AND the environment. But no language takes away the thought behind it. If you're not thinking.. you're just typing.

C

No parametric polymorphism (i.e. C++ templates). It makes writing reusable data structures and algorithms a pain (and there's hardly any static checking). See for instance the comparator argument to qsort and bsearch: the comparator takes void pointers :( No library of data structures. I really hate writing my own hash table. I also really hate scouring the web for a library of reusable data structures. Especially if it turns out to be incomplete. Strings. Inefficient representation, unwieldy if you make it sane, too hard to safely input a string. No standard for snprintf. Too hard to create a format string with sprintf, then use that to create a string with sprintf again, in a safe way. Only lexical macros. If different compilers expects function annotation in different places, I have to put the same HAS_NO_SIDE_EFFECTS in different places. Why can't I just grab the function, switch over the compiler type, and then insert it at the right place by a macro call? No portable libraries for common functionality. For sockets and threading, I use SDL---a frigging game library. For .ini-style parsers, the only library I could find which was packaged for ubuntu, I posted on the daily wtf (it calculates an array of hash values, then does a linear scan through it...)

C++

Template syntax is heavy and unweildy. Let's see, for(map<string, int>::const_iterator it = mymap.begin(); it != mymap.end(); ++it). Design errors in the STL. Should changing allocation strategy for your vector really change its type? Overly complex type system. Type T1 has a convert-to-T2 method, and T2 has an implicit from-T1 constructor. Which is called? How does overloading, overriding and multiple inheritance interact? Poorly, I guess... Incredibly long and unwieldy error messages from templates. You know what I mean... References means you can't see output parameters at call sites. In C, you can guess what foo(bar, &baz) can and can't modify.

Python:

1) It's a scripting language and not a fully compiled one (I'd prefer to be able to compile binaries—I don't care about bytecode). This is very annoying if I have to use very many libraries (i.e. everyone who uses my program has to install all the libraries, and this basically means no normal people will be able to, or have the patience to, properly set it up—unless I do a ton of work that should be unnecessary). I know ways to make binaries, but they don't always work, and I'm guessing they bundle the interpreter in the binaries anyhow (and I don't want that). Now, if I could get a bytecode compiler that would include copies of all the files that I imported (and only those) to be placed in my program's folder, that might be a suitable compromise (then no one would have to download extra libraries and such). It would also be nice if the compiled python files could be compressed into a single file with one specified as the file to run the program before this is done.

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

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

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

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

6)强制自动垃圾收集(我希望能够手动执行,尽管不一定强制执行)。

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

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

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

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

C#

Lack of multiple dispatch based on the runtime type of the method arguments. dynamic should solve most of this, but it hasn't been released yet. Interface implementation is declarative not structural. I really like the way Google's Go language is doing types Making asynchronous method calls is really bulky (and I'm pretty sure all threads are OS threads, not lightweight threads) No macro system. I'm not talking about C-style macros here; I'm talking LISP/Scheme style macros Operators are static methods and their signatures are overly constrained (and you can't create new ones).