|
|
51CTO旗下网站
|
|
移动端

Python的替代品?我尝试了你从未听说过的优秀编程语言

几周前,我在GitHub上浏览时遇到了一个引起我注意的回购。 它托管了一个完全用Nim编写的项目。

作者:闻数起舞来源:今日头条|2020-07-20 07:16

 认识Nim:具有类似Python语法和C效率的语言

Python的替代品?我尝试了你从未听说过的最佳编程语言

几周前,我在GitHub上浏览时遇到了一个引起我注意的回购。 它托管了一个完全用Nim编写的项目。

Nim到底是什么? 我想。

我立刻得出结论,这是很多人使用的许多编程语言之一,但是我只是一个愚蠢的人,不知道它。 但是我没有把它放在一边,而是决定:让我们对此有所了解。

然后,我有了两个主要认识:

  • 不,很多人不使用这种语言。
  • 但也许应该如此。

因此,这里简要介绍了我在快速编程教程Nim方面的经验,以及为什么该语言对我来说非常有前途。

给我看代码!

这是我在Nim中编写的一个无用的程序:

Python的替代品?我尝试了你从未听说过的最佳编程语言

看起来很干净。 它也是如此简单,即使您以前可能从未听说过Nim,您也可以毫不费力地弄清楚它的作用。 (提示:它打印数字:5我:5。)

因此,让我们分解一下这里似乎熟悉的内容:

变量声明

JavaScript开发人员非常熟悉。 虽然某些语言使用var,有些语言使用let,但是JS和Nim都允许使用两者之一进行声明。 请务必注意,两种语言的含义并不相同。 但是稍后会更多。

块语法

要在Nim中标记一个新块,我们使用冒号,后跟缩进线。 那就是Python。

关键词

这两个循环以及if语句看起来都像是从Python中拔出来的。 实际上,从第5行开始的所有内容实际上都是有效的Python(假设我们定义了echo函数)。

因此,是的,Python中的许多关键字和运算符在Nim中也有效,例如not,is,and或or等。

到目前为止,Nim完全没有什么特别的。 由于我们需要使用let或var,因此它看起来像是Python的较差版本(在语法上)。

但是,如果我告诉您的话,该怎么办:Nim是一种静态类型的语言,其运行速度几乎与C一样快。

哦,现在我们在说话。

一场友好的比赛

在深入探讨Nim语法(尤其是静态类型的部分,我们仍然没有看到它)之前,让我们尝试备份有关其速度的声明。 为此,我编写了一个程序来天真地(即不进行动态编程)计算Nim,Python和C中的第n个斐波那契数。

为了公平起见,我根据针对此问题的建议Leetcode解决方案(方法1)对实现进行了标准化,并确保在三种语言中尽可能地坚持下去。

为了计时执行时间,我在Bash shell中使用了时间输出中的"真实"值。

以下是计算第40个斐波那契数的结果:

Python的替代品?我尝试了你从未听说过的最佳编程语言

是的,那件事发生了。

现在,这是非常有限的,并且离科学实验还很遥远,但这与其他进行了更严格基准测试的人的发现一致[1] [2] [3]。

不过,我将在本文中运行的所有代码都可以在GitHub上找到,包括有关如何进行此实验的说明。

那么,为什么Nim比Python快得多?

好吧,我要说有两个主要原因。 大大简化,这些是:

  • Nim是在解释Python时编译的(不同意?请单击链接)。 这意味着在运行Python程序时,除了仅运行该程序外,还有更多的工作要做,因为在实际执行之前需要对其进行解释。 这通常会使语言慢很多。
  • Nim是静态键入的。 虽然我之前显示的示例没有单一的类型声明或注释,但稍后我们将看到它确实是静态类型的语言。 对于动态类型的Python,解释器需要做更多的工作来找出并适当地处理类型,这会减慢执行速度。

运行更快,编写速度更慢

这是Python文档关于解释语言必须说的话:

"尽管解释型语言的程序运行通常也较慢,但它们通常具有比编译型语言更短的开发/调试周期。"

例如,这句话很好地总结了Python和C之间的折衷。 您可以使用Python进行的任何操作,也可以使用C进行的操作,程序的运行速度将提高多个数量级。

但是,您将花费更多的时间用C编写和调试代码,并且代码更长且可读性更差。 这就是为什么C不再流行的原因,Python如此流行。 简而言之:Python是"简单的"(当然,相对而言)。

因此,如果Python在频谱的一端,而C在另一端,则Nim试图处于中间位置:有点快又容易吗? 这样的事情。

但是,使Nim脱颖而出的原因是,乍一看,它似乎已使权衡最小化。 换句话说,它比Python快得多,但是编程起来却不像C那样困难(或者感觉像经过简短检查一样)。

为了说明这一点,让我们看一下斐波那契实验中的代码。

这是C代码:

  1. #include <stdio.h> 
  2.  
  3. int fibonacci(int n) { 
  4.     if (n <= 1) { 
  5.         return n; 
  6.     }  
  7.     return fibonacci(n-1) + fibonacci(n-2); 
  8.  
  9. int main(void) { 
  10.     printf("%i", fibonacci(40)); 
  11. }  

Python:

  1. def fibonacci(n): 
  2.     if n <= 1: 
  3.         return n 
  4.     return fibonacci(n-1) + fibonacci(n-2) 
  5.  
  6. print(fibonacci(40)) 

和Nim:

  1. proc fibonacci(n: int): int =  
  2.     if n <= 1: 
  3.         return n 
  4.     return fibonacci(n-1) + fibonacci(n-2) 
  5.  
  6. echo(fibonacci(40)) 

尽管Nim拥有奇怪的proc东西,亲爱的上帝,还是使用=声明函数(或过程,称呼它们),但它仍然比C干净得多。

因此,也许这是一个值得权衡的问题? 比Python难写一点,但是要快几十倍-我可以接受。

Nim语法

以下是有关Nim语法的一些关键点的简要概述:

  1. import strformat 
  2.  
  3. # Example taken from the Nim Website: https://nim-lang.org/ 
  4.  
  5. type 
  6.   Person = object 
  7.     name: string 
  8.     age: Natural # Ensures the age is positive 
  9.  
  10. let people = [ 
  11.   Person(name"John", age: 45), 
  12.   Person(name"Kate", age: 30) 
  13.  
  14. for person in people: 
  15.   # Type-safe string interpolation, 
  16.   # evaluated at compile time
  17.   echo(fmt"{person.name} is {person.age} years old"

变量

变量使用var,let或const声明。

var和const基本上就像JavaScript一样工作,但是让我们有一个不同的故事。

尽管JavaScript中的let与var在范围上有所不同,但Nim中的let表示一个变量,其值在初始化后不能更改。 有人告诉我,这显然类似于Swift。

但这不是常数吗?

好吧,在Nim中,区别如下:

对于const,编译器必须能够在编译时确定该值,而let可以在运行时确定。

文档提供了以下示例:

  1. const input = readLine(stdin) # Error: constant expression expected 
  2.  
  3. let input = readLine(stdin) # works 

此外,您还可以像这样声明变量:

  1. var 
  2.  
  3. a = 1 
  4.  
  5. b = 2 
  6.  
  7. c = 3 
  8.  
  9. x, y = 10 # Both x, y are assigned to 10 

函数

Nim中的函数称为过程,它们的声明是这样完成的:

  1. proc procedureName(parameterName: parameterType):returnType = 
  2.  
  3. return returnVar 

鉴于该语言在很多方面看起来都像Python,因此当您初次看到它们时,过程肯定显得有些怪异。

用=代替{或:尤其奇怪。 但是,在单线过程中看起来更好一些:

  1. proc hello(s: string) = echo s 

此外,您还可以从以下函数返回:

  1. proc toString(x: int): string = 
  2.  
  3. result = 
  4.  
  5. if x < 0: "negative" 
  6.  
  7. elif x > 0: "positive" 
  8.  
  9. else"zero" 

感觉您仍然应该返回结果,但结果不是变量,而是一个关键字。 上面的代码段是完全有效的Nim。

而且您还可以重载过程:

  1. proc toString(x: int): string =    
  2.     result =      
  3.         if x < 0: "negative"      
  4.         elif x > 0: "positive"      
  5.         else"zero"   
  6. proc toString(x: bool): string =    
  7.     result =      
  8.         if x: "yep"      
  9.         else"nope" 
  10. echo toString(true) # Calls the second version, prints "yep" 
  11. echo toString(5) # Calls the first version, prints "positive" 

控制流

很像Python。

  1. # if true
  2.  
  3. # while true
  4.  
  5. for num in nums: 

要遍历某个范围,可以使用countup(start,finish)或countdown(start,finish)代替一个范围。 或者,您可以简化整个过程并使用:for i in start..finish。

打印并获取用户输入

  1. let input = readLine(stdin) 
  2.  
  3. echo input 

与Python比较时,readLine(stdin)等效于input(),echo等效于print。

echo可以带或不带括号。

我的目标是给您带来Nim的品味,而不是通读其完整手册。 因此,我想我将在此处停止使用简单的语法,然后略过一些其他功能。

附加功能

面向对象编程

Nim不是面向对象的,但是对对象的支持极简。 但是,它们不像Python类那么整洁。

Nim支持宏和元编程,实际上,它似乎非常强调它。 由三部分组成的教程系列的整个部分都专门针对它。

这是一个简单的示例:

  1. import macros 
  2.  
  3. macro myMacro(arg: static[int]): untyped = 
  4.  
  5. echo arg 
  6.  
  7.  
  8.  
  9. myMacro(1 + 2 * 3) 

基本类型

Nim中的基本类型为:字符串,字符,布尔,整数,整数和浮点数。

这些也是有效的:

int8 int16 int32 int64 uint8 uint16 uint32 uint64 float32 float64

另外,与Python不同,字符串在Nim中是可变的。

注释

您可能已经在上面的Python语法中看到了我的注释,但是与Python不同,多行注释也使用了哈希符号(后接[或]):

  1. # a comment#[ 
  2. multi 
  3. line 
  4. comment 
  5. ]# 

JavaScript编译

从Nim网站:

" Nim包括一流的JavaScript后端,因此您可以轻松地同时定位客户端和服务器。"

尽管我不确定有多少人会实际使用它,但是这很酷。 但是,如果您要播放用Nim编写的Browser Snake,则可以这样做。 不过这次我没有建造它。

迭代器

除了定义一个proc之外,还可以定义一个迭代器。 但是,Nim迭代器实际上更像Python生成器。 这是一个例子:

  1. iterator countup(a, b: int): int =  
  2.     var res = a  
  3.     while res <= b:  
  4.         yield res  
  5.         inc(res) 

不区分Case和下划线

Nim不区分大小写和下划线(第一个字符除外)。

因此,HelloWorld和helloWorld是不同的,但是helloWorld,helloworld和hello_world都相同,因此有效:

  1. proc my_func(s: string) = 
  2.     echo s 
  3. myFunc("hello"

人气度

Python的替代品?我尝试了你从未听说过的最佳编程语言

也许您阅读了标题并对自己说:嗯,我听说过Nim或使用Nim!

那样的话,嘿,我为你感到高兴。 但是,我确实尝试获得了有关该语言受欢迎程度的一些信息,而且肯定不是那么高。

例如,在2020年堆栈溢出调查中甚至没有提到Nim。 我在LinkedIn上找不到Nim开发人员的工作(位置设置为Worldwide),并且该语言的Stack Overflow标签只有349个问题。 (与Python的1,500,000或更新语言(例如Swift的270,000)进行比较。)

因此,可以肯定地说,大多数开发人员都没有使用过它,而且许多开发人员甚至从未听说过Nim这个名字。

真正的Python替代品?

我对你说老实话,我觉得Nim很酷。

在撰写本文时,我已经研究了最低限度,因此还没有深入到最低限度,但是我可以看到自己将来会用到它。

但是,尽管基本语法与Python非常相似,但是它变得相当复杂,而且速度很快,我相信这会吸引很多Python用户/开发人员。

就我个人而言,我是Python的忠实拥护者,也是静态类型语言的忠实拥护者,因此对我而言,在某些情况下,性能的提高将足以弥补所增加的冗长性。

然后,通过撰写本文,我意识到:Go呢?

我敢肯定,你们中的许多人在阅读时都在考虑这一点,这是有道理的。 尽管Nim的语法可能更接近于Python,但它确实在Go语言主导的高性能但比C ++语言更激烈的竞争中。

有趣的事实:我还偷偷地用Go进行了速度测试。 特别是对于fibonacci(40),它的速度与C一样快。

那么,Nim可以与Python竞争吗? 我对此表示高度怀疑。 正如我所指出的那样,我们看到了计算机变得越来越快,编程变得越来越容易的趋势,以至于即使Nim提供了很好的权衡,我也认为采用干净而通用的Python还不够。

编辑:我与Nim Core Devs的一位发言人交谈,他告诉我他认为Nim比从Python过渡的人更适合从C ++过渡的人。

但是,它可以与Go竞争吗? 也许(如果Google不落后于Go)。 语法友好,语言功能强大,并且比Go提供的功能(例如宏和重载)更好地支持C / C ++功能。

也许那是我接下来要写的文章。

谢谢阅读!

【编辑推荐】

  1. Python 3000字编程风格指南
  2. 为了更好的代码:12个Python小窍门
  3. Python Debug(调试)的终极指南
  4. Python用27行代码绘制一幅满天星
  5. 少有人知的 Python "重试机制"
【责任编辑:华轩 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

大数据安全运维实战

大数据安全运维实战

CDH+Ambari
共20章 | 大数据陈浩

86人订阅学习

实操案例:Jenkins持续交付和持续部署

实操案例:Jenkins持续交付和持续部署

微服务架构下的自动化部署
共18章 | freshman411

176人订阅学习

思科交换网络安全指南

思科交换网络安全指南

安全才能无忧
共5章 | 思科小牛

108人订阅学习

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微