几周前,我在GitHub上浏览,遇到了一个吸引我眼球的回购。它托管了一个完全用NIM编写的项目。
我立刻得出结论,这是很多人使用的众多编程语言中的一种,但我只是个不懂它的笨蛋。但我没有把它放在一边,而是决定:让我们来了解一下这方面的情况。
因此,下面来介绍一下我使用NIM的经验,这是一个快速编程教程,以及为什么这种语言在我看来非常有前途。
看起来很干净。它感觉非常简单,即使您以前可能从未听说过Nim,您也可能不费力气就能弄清楚它是做什么的。(提示:它打印num:5 i:5。)。
JavaScript开发人员对此非常熟悉。虽然有些语言使用var,有些语言使用let,但JS和NIM都允许使用这两种语言中的任何一种进行声明。然而,重要的是要注意,它们在两种语言中的含义并不相同。但稍后会有更多关于这一点的报道。
要在NIM中标记新块,我们使用冒号后跟缩进行。那边就是蟒蛇。
这两个循环以及if语句看起来都像是直接从Python中提取出来的。事实上,从第5行开始的所有内容实际上都是有效的Python。
因此,是的,Python中的许多关键字和运算符在NIM中也是有效的,如not、is、and、or等。
到目前为止,尼姆并没有什么特别之处。它看起来只是像一个更糟糕的Python版本,因为我们需要使用let或var。
但是如果我告诉你:NIM是一种静态类型的语言,它的运行速度几乎和C语言一样快,会怎么样呢?
在深入研究NIM语法(特别是静态类型部分,我们还没有看到它)之前,让我们先来支持一下有关其速度的说法。为此,我编写了一个程序,用Nim、Python和C计算第n个斐波纳契数(即不使用动态编程)。
为了公平起见,我基于针对此问题推荐的Leetcode解决方案(方法1)标准化了实现,并确保在这三种语言中尽可能地遵守它。
为了给执行计时,我在Bash shell中使用了time输出的“实际”值。
现在,这是非常有限的,远不是一项科学实验,但它与其他做过更严肃基准的人的发现是一致的[1][2][3]。
不过,我将在本文中运行的所有代码都可以在GitHub上找到,包括关于如何尝试此实验的说明。
NIM是编译的,而Python是解释的(不同意吗?单击该链接)。这意味着当运行Python程序时,除了运行程序之外,还有更多的工作要做,因为在实际执行之前需要对其进行解释。这通常会使语言变得慢得多。
NIM是静态键入的。虽然我前面展示的示例没有单个类型声明或注释,但稍后我们将看到它确实是一种静态类型语言。对于动态类型的Python,解释器需要做更多的工作来确定和适当地处理类型,这会减慢执行速度。
解释语言的开发/调试周期通常比编译语言短,尽管它们的程序运行通常也较慢。
例如,这句话很好地总结了Python和C之间的权衡。用Python可以做的任何事情都可以用C来做,并且程序的运行速度会快很多个数量级。
但是,您将花费更多的时间用C语言编写和调试代码,而且代码会更长,可读性也会更差。这就是为什么C不再流行,而Python如此流行的原因。简单地说:Python是“容易的”(当然,相比较而言)。
因此,如果Python处于这一端,而C位于另一端,那么NIM正试图介于两者之间:有点快,有些简单?差不多是这样。
然而,让Nim脱颖而出的是,乍一看,它似乎把权衡降到了最低。换句话说,它比Python快得多,但用C编程并不比它难得多(或者说,简单地看起来就是这样)。
为了说明这一点,让我们看一下斐波纳契实验中的代码。
虽然NIM有一个奇怪的proc程序,并且,亲爱的上帝,使用=来声明函数(或者它们被称为过程),但是它仍然比C语言干净得多。
因此,也许这是一个有价值的权衡?编写起来比Python稍微难一点,但速度要快几十倍--我可以接受这一点。
以下是关于NIM语法的一些要点的简要概述:
虽然JavaScript中的let在作用域上与var不同,但Nim中的let表示其值在初始化后不能更改的变量。现在有人告诉我,这显然和斯威夫特很相似。
对于const,编译器必须能够在编译时确定值,而let可以在运行时确定。
Var a=1 b=2 c=3 x,y=10#x,y都赋给10。
鉴于该语言在很多方面看起来都很像Python,当您第一次看到过程时,肯定会觉得有点奇怪。
用=代替{或:特别奇怪。但是,在一行程序中看起来要好一些:
Proc toString(x:int):string=result=if x<;0:“负”elif x>;0:“正”否则:“零”
感觉仍然应该返回结果,但是结果不是一个变量--它是一个关键字。上面的代码片段是完全有效的NIM。
对于在范围内迭代,您可以使用countup(start,Finish)或Countdown(start,Finish)来代替范围。或者,您可以简化整个过程并使用:for i in start..Finish。
与Python相比,readLine(Stdin)等同于input(),echo等同于print。
我在这里的目标是让你尝尝尼姆的滋味,而不是通读他们的整个手册。因此,我想我将在此停止讨论简单的语法,然后略读一些额外的特性。
NIM不是面向对象的,但对对象有最低限度的支持。但是,它们不像Python类那样整洁。
NIM支持宏和元编程,而且实际上似乎非常强调这一点。在他们的三部分教程系列中,有整整一部分都致力于此。
您可能已经在上面的Python语法中看到了我的注释,但与Python不同的是,多行注释还使用散列符号(后跟[或]):
“NIM包括一流的JavaScript后端,因此您可以毫不费力地同时瞄准客户端和服务器。”
这很酷,虽然我不确定有多少人会真正使用它。但是如果你想玩用NIM编写的浏览器Snake,你可以这么做。不过,这一次不是我造的。
除了定义proc之外,还可以定义迭代器。然而,NIM迭代器实际上更像是Python生成器。这里有一个例子:
迭代器Countup(a,b:int):int=var res=a while res<;=b:Year res Inc(Res)。
因此,HelloWorld和HelloWorld是不同的,但是HelloWorld、HelloWorld和hello_world都是相同的,因此这是有效的:
也许你看了书名就会对自己说:嗯,我听说过Nim,或者我用过Nim!
那样的话,嘿,我为你高兴。不过,我确实试着了解了一下这种语言的受欢迎程度,它肯定不是那么高。
例如,在2020年的堆栈溢出调查中甚至没有提到NIM。我在LinkedIn(位置设置为Worldwide)上找不到任何适合NIM开发人员的工作,而且该语言的Stack Overflow标签只有349个问题。(相比之下,Python的大约1500,000,或更新的语言,如Swift的270,000。)。
因此,可以相当公平地认为大多数开发人员没有使用过它,很多人甚至从未听说过Nim这个名字。
为了写这篇文章,我已经过了最低限度的检查,所以还没有深入研究,但是我可以预见自己将来会用它来做点什么。
然而,虽然基本语法非常类似于Python,但它很快就变得更加复杂,我确信这会让很多Python用户/开发人员望而却步。
就我个人而言,我既是Python的忠实粉丝,也是静态类型语言的忠实粉丝,所以对我来说,某些情况下的性能改进足以弥补增加的冗长。
我相信你们中的许多人在阅读的时候就是这么想的,这是一个很有道理的观点。尽管NIM的语法可能更接近Python,但它实际上是在性能优于C++语言的领域展开竞争,这一领域目前由Go主导。
有趣的事实:我还偷偷地用围棋进行了速度测试。具体地说,对于斐波纳奇(40)来说,它的速度与C。
那么,尼姆能与Python竞争吗?我对此深表怀疑。我们看到了计算机变得更快、编程变得更容易的趋势,就像我指出的那样,即使NIM提供了一个很好的权衡,我认为它也不足以与干净而多功能的Python竞争。
编辑:我采访了一位NIM核心开发人员,他告诉我他认为NIM比Python更适合从C++过渡的人。
然而,它能与围棋竞争吗?也许(如果谷歌不是围棋的幕后黑手)。它的语法很友好,语言很强大,而且它对C/C++特性的支持比Go提供的更好(例如宏和重载)。