最近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.

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


当前回答

我讨厌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)。

其他回答

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

Python:

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

Poor thread support and GIL. If you'd like to take use of multicore platform, most of the python programmers would probably recommend multiprocessing or some sort, don't use threading. It wouldn't give you the performance you are expecting. property only for instance variable. _class_var = property(classmethod(some_method)) just wouldn't work. How can I get a property wrapped class variable? no access control. All access controls are syntax mangling. Like private is __private, protect is _protected, etc... And hope that everyone programs python follows the naming convention. Come on, we can do better than that. I agree the python philosophy of being simple and clear syntax but some simple and clear syntax not being supported seems lock of good judgement, in my opinion. Such as, a++, ++a, a-- and --a, self-de/increment, what's wrong with those? foo = (a > b ? a : b) unary operation, what's wrong with those? (I know py2.6 has something similar introduced, but given the massive support of almost every other language for those simple syntax, why reinventing the wheel? why not just follow the best practice? Shouldn't a good thing just keep in its good "form"?) Program to interface. Python has no interface or abstract class concept (py3k has something called abc), everything is concrete. Providing an "interface" or "abstract" keyword to build class skeleton and guard class inheritance and extension wouldn't be a bad idea I think. It helps on top-down design. Currently, I just have to fill the each of methods with NotImplementedError, quite a tedious job. I have to add this. version less than 3.x has str and unicode types. This is a true nightmare. It makes ascii and non-ascii/unicode mixing most likely to fail (bad, bad)

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

那"我讨厌某些语言的五件事"清单呢?: 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.

F#

Type inference is limited. It propagates forward only. F# won't try to infer an object type based on the methods and properties used: you'll get "lookup of indeterminate object type" errors when it doesn't have a clue. One cannot mix floats and ints: 1 + 2.3 is a type error. It's a little awkward to have to create a builder object in order to define a monad or computation expression. In Haskell or Scala, you can define the monad operations directly on the monadic object. Though the #light syntax is preferred, the indentation rules are sometimes not very intuitive or become cumbersome.

PHP:

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

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