如果有朋友突然想学编程,那么必问的就是学习哪门语言最好。
其实我很不喜欢回答这个问题,毕竟每门语言都有它们自己诞生的意义与目的。因此,我尤其不喜欢他们会接触到网络上一些拉踩编程语言的评论或影片。

这样说来,在没有目的的情况下推荐一门语言可能是无解的?好吧,从长看来,还是有的。不过是否真正合适就不好说了。

如果从我的技能池里挑的话,那么我大概会选这几门:C, LuaRuby

无论如何

放在前面:无论选择哪种语言,编程规范入乡随俗尤为重要。永远不要以能跑就行为学习时的首要目的。

C 语言:高级的底层语言

只有外行和根本不懂交叉编译的人才会觉得 C 太老旧了。这么说吧:如果你想学好计算机软件,即便你可以不用 C,但你不能不会 C

GCC 曾经的全称是 GNU C Compilot,但现在它有个新的全称:GNU Compilot Collotion。但这并不妨碍 GCC 仍然是 C 语言的编译器。
当一门语言兼容 C 的汇编语言层的规范,那么就能无缝的与 C 语言沟通。即便目标的语言可能不是 C 语言,但毕竟同为 C 语言规范的桥接,它们依旧可以沟通。
但是这不是没有代价的。如果想让程式码回到 C 规范,首先得熟悉 C 的库,以及 C 自身。如果一位软件工程师并不懂 C,不知道也不关心指针与汇编层发生了什么,我恐怕他无论如何学习都很容易达到瓶颈。

但这很奇怪,因为,C 并不难,也不必要去畏惧它。没有任何理由不去学习 C

当然,现在各种新的语言提供的特征都非常酷,就像开始说的,你可以不用 C,但你不能不会 C。当你完全理解 C,任何 C-Like Style 的编程语言都可以被轻松的学习。在完成 C 的入门后,去试试 Zig 语言和 Rust 语言吧!当然,GoLang 也是很不错的选择。

Lua:几乎完美的解释性语言

我花费了大量时间研究 Lua 与其精湛的设计,可以说我正在计划开发的 Pineapple Language 也深受 Lua 的影响。 Lua 是我见过最优雅的语言,这甚至在一定程度上比 D Lang 更占据我的赏识。虽然它的官方只做了 C 无缝嵌入的支持,但是它开源的解释器使得社区开发者们为它设计了各种几乎能嵌入任何语言的方式。

如果要说有什么原因让我很少写 Lua,大概是因为我更喜欢写面向对象。但如果要问我推荐什么语言,Lua 大于任何面向对象语言,而 Lua 的面向对象通常不实用,设计的角度来讲这是一个糟糕的决定——这样的面向对象让代码可读性相较于持有与传递更糟糕。这个问题稍后一些再来评价。

来看一个 Lua 使用函数作为范围处理的代码切片:

function rangeNumber(startNumber, endNumber)
  if startNumber < endNumber
  then
    startNumber = startNumber + 1
  end
  return startNumber, endNumber
end

do i, o in rangeNumber, 0, 3
  print("第 " .. i .. " 次输出:" .. o)
end

理论上,这样会输出三次相同的数。也就是从 第 0 次输出:0第 2 次输出:2
我们来看一段对比的,由 D 语言编写的:


int[] rangeNumber(int startNumber, int endNumber) {
  int[endNumber - startNumber] ints;

  while(startNumber < endNumber) {
    ints ~= ++startNumber;
  }
}

int main(string[] agrs) {
  import std.stdio : writeln;
  import std.conv: to;

  foreach(i; rangeNumber(0, 3)) {
    writeln("第 " ~ i.to!string ~ " 次输出:" ~ i.to!string);
  }

  return 0;
}

即便是对代码不是很了解也应该能看出来,Lua 的代码切片有个特点:在 do 的时候有两位参数作为输出,而 D 只有一位。多返回值也是一种利于初学者随想随做的特征之一。并且我敢打赌,如果读者对编程没有任何理解,那么 Lua 的代码切片里能看懂的部分也应该比 D 要更多。Lua 看起来就像是基本英语拼起来的内容。

至于上文提到的面向对象,Lua 这样的面向过程语言塞入面向对象是一个绝对的败笔。Lua 作为动态类型的解释性语言插入面向对象的特征就会导致在边写的时候不停的用大脑编译代码,这一点在 PythonCoffee Script 中也是同理的。程式设计最重要的不是追随潮流,而是如何避免编写代码的时候感觉自己在一刻不停的用大脑编译代码。
我想肯定会有读者反驳我,认为边写边想是常态。错!边写边想这套功能解决了什么问题才是常态,边写边编译代码是刺激大脑!

永远不要觉得自己比编译器聪明,也永远不要质疑 PLS(Public Language Services) 是否多余。

Ruby:程序员的摸鱼之选

Ruby 是一门极其依赖信仰与对面向对象理解的面向对象解释性语言。但它与 Java 不同,它的解释特征与 LuaPython 一样,是及时逐行解释。
因为 Ruby 这种糟糕特性,它仅适合任何对面向对象完全上手的开发者。

Ruby 具备静态类型,简短语句的特征,以及完全面向对象。但是问题在于:Ruby 中任何内容都是对象。

这句话听起来可能有些奇怪,Java 难道不是吗?

那还真不是。至少 Java 不会把一些过于底层的对象当作对象,就算这么做了,也会对对象内的字段所有权进行切割。
Ruby 会混淆它们,从创建文件开始,这个文件对 Ruby 来说就是一个 Object 对象。

没错,Object,面向对象的万恶之源。 任何在文件创建的字段,即便是 private(属性私有),但由于它的所有权是 Object,这种私有和没有一样。
任何没有面向对象基础的新手都会栽到这个坑里,很长一段时间大概都无法理解这种独特行为。

Ruby 诞生的意义是摸鱼。任何有面向对象基础,或者并不打算拿 Ruby 进行严肃开发的人,都可以用 Ruby 写的很爽。并且和任何解释性语言一样,在 Unix 派生系统上,可以透过加入头标来使得 Ruby 文件像 sh 一样执行。

如果读者只是想找一门休闲学习的语言,Ruby 再合适不过了。不过 Ruby 必吃部分是得自己编译。不过这对 Linux 玩家来说应该是稀疏平常的事情吧。