文档结构  
翻译进度:67%     翻译赏金:6 元     ¥ 我要打赏
参与翻译: 我呀我 (1), toypipi (1)

编程语言的效率和类型安全常常被评估,但友好呢?我在探索人类的价值观是怎样被应用于编程语言环境,特别是童子军法律中的12点:值得信赖、忠诚、乐于助人,友好,有礼貌,善良,孝顺,开朗,节俭,勇敢,干净,和虔诚的。

警告:此帖子对编程语言有很强的主观意见。观众自由定夺。

简介

在讨论编程语言时,我们倾向于关注数学/逻辑对象。这种语言精准并模块化,那种缺乏正式语义,这种严格遵循范式,那种很好匹配公式。但是,语言及其相关的编译器最终不是抽象的概念,而是人们实实在在使用的工具,带有更多的价值而不仅是纯粹的数学。作一个有趣的思想实验,如果我们把期望从别人身上得到相同的价值观这一现象归因于编程语言会怎么样?

关于良好的价值观,我们可以看到经典的组织致力于向年轻人灌输老式的美国价值观: 美国童子军[1]。具体来说,所有的童子军被要求遵守童子法,奉行以下12点价值观: “童军是值得信赖、忠诚、乐于助人,友好,有礼貌,善良,孝顺,开朗,节俭,勇敢,干净,和虔诚的。” 在本文中,我将探讨如何将这些价值观应用于编程语言的上下文中。

第 1 段(可获 2.89 积分)

APPLYING THE LAW

A brief preface: for brevity, I will lump together programming languages and compilers, referring to them interchangeably. My interpretation of broad human values like "friendliness" is obviously not authoritative, but just intended to spark further discussion on the topic. 

  1. Trustworthy. A trustworthy language is one you can believe will protect your secrets and not go behind your back to mess with your program semantics. Such a language should have ASLR enabled and should have crypto libraries made by experts so users don't roll their own. You should be able to trust that your language will make reasonable decisions on your behalf. For example, a language should notcoerce your types in unreasonable ways when you're not looking—we ought not confused dynamic typing (checking types at runtime) with weak typing (coercing types instead of failing in the presence of type errors). Trust is an essential element of productivity. When a programmer does not trust his language, he is forced to program defensively and must battle both his own bugs as well as the compiler's. A trustworthy language permits the programmer to feel comfortable in his environment and to focus on the task at hand.

  2. Loyal. A language is loyal when its design evolves with the preferences of its users, not its owners or corporate overlords. One should feel comfortable that a language will not turn around and get you sued for using its basic features.

  3. Helpful. A language can be "helpful" in a myriad of ways, but one aspect often missing from newer languages is a means to help the programmer understand his errors. It should have a battle-tested debugger. You should not need an additional piece of software to decipher your compiler's dense and enigmatic build output. For brownie points, your compiler should explain why the programmer has encountered an error, and for the gold medal it should propose a solution.

  4. Friendly. For a language, it makes the most sense to interpret this as "open to newcomers," e.g. Python is simple to start with whereas Standard ML can be aformidable foe when first learning functional languages. Having a REPL is a crucial part of a friendly language—it allows new programmers to play around with syntax and get a quick feel for a new language without having to wade through a hundred compiler errors or a monstrous IDE. As a corollary, dynamic languages often feel more friendly since they can be run in small pieces. They permit the programmer to make small errors which the user doesn't need to concern himself with until necessary.

  5. Courteous. Any language should follow common courtesy: it should clean up after itself (compiler-managed memory) and talk respectfully to its elders (have FFI out to C).

  6. Kind. For me, the distinguishing factor between kindness and other values like helpfulness and courtesy is intention. For a language to be kind, its designers need to be kind in turn. I have never met or heard of a language designer intentionally create a language harmful to its users or its community (although you have to watch people like Ken Thompson), but one should always be careful, particularly with closed-source languages. Language designers should have a clear, open dialogue with their community so as to not have their intentions misconstrued or turned against them.

  7. Obedient. Similar to being trustworthy, an obedient language will always do what it's told and no more. The language's libraries should be clearly named and documented. If a function has to fail, it should not do so silently, and the programmer should handle the error (error codes considered harmful). The language should be formally specified, and the compiler should adhere strictly to the specification, loudly telling the programmer where it does not.

  8. Cheerful. This is perhaps the least applicable to programming languages, as there's a fine line between cheer and condescension. After all, nobody wants a compiler like this: 

    However, arguably to be cheerful it means one should at least be more upbeat. Doom and gloom and vitriol are not essential parts of a compiler (or any piece of software).
  9. Thrifty. A language should do a lot with a little, or prefer a smaller number of powerful abstractions to a larger number of weaker ones. More concretely, do not make concepts first-class in the language unless they need to be, otherwise implement them in libraries. For example, Rust implements iterators as traits and Clojure implements gradual typing as a library (!). Similarly, a thrifty language should only pay for what it needs and prefer zero-cost abstractions where possible. If your quick script takes 0.5 seconds to run but 3 seconds to start the garbage collector, then the language is not thrifty. If your build takes an hour to compile against a library from which you only need one or two functions (cough OpenCV), then the language is not thrifty.

  10. Brave. As a language designer, do not be afraid to be brave when creating a new language. Although I received overwhelmingly positive feedback on one of myrecent posts on language design, there are many naysayers stuck to their paradigms and editors who will be washed away with the flow of time and progress. Make that new type system. Change up the syntax. Just do so while trying not to violate the other principles of good language design.

  11. Clean. Just as people should look and smell clean, so should the syntax of a programming language. Although programmers often like to think in abstractions, the concrete syntax of a language really does matter. In most software development, code is meant to be read and not written, so the more legible your language, the easier it is to maintain. Remember that the language designers often dictate style used by the community. Avoid the majority of naming conventions brought from mathematics (e.g. one letter variable names) unless no one will read your code or it actually improves legibility. Naming is important!

  12. Reverent. Whether you belong to the Kingdom of Nouns or the Church of Lambda, be respectful of all faiths. Better yet, take the best of all worlds when designing your language (see: my previous post). Don't force users to pick one paradigm over the other, but rather be flexible enough to accommodate all walks of life.

第 2 段(可获 13.13 积分)

结论

这篇文章不可避免的对立面是这样的:“但是,威尔,我不在乎我的语言是否友好,我只需要让它工作,我们应该关心效率,而不是这些抽象的人类观念。 这话说的不错! 我不会使用一种值得信赖的,但实际上并没有做任何事情的编程语言。 但是,我们不应该让讨论中的其他目标像效率一样消除。 如果我们推广具有上述价值观的编程语言,那么我们可以为现有的程序员以及寻求进入该技术的人创造一个更美好的世界。 语言设计师应该记住,他们的最终用户是人,而不是机器人[2],并因此进行设计。

请将您的意见发送到我的电子邮箱wcrichto@stanford.edu 或在Hacker News上讨论

参考

[1]是的,我知道童子军并不总是好的价值观的典范,是的,我知道童子军来自英国

[2]当然,除非你的语言是 LLVM

第 3 段(可获 2.15 积分)

文章评论

CY2
第二段太长啦 。。。。
Hornsey
13.13积分,这一段是不是可以再分解下呢!
CY2
拆不了了
班纳睿
:scream: