29

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

 3 years ago
source link: https://developer.51cto.com/art/202007/621333.htm
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

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

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

 认识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. int fibonacci(int n) { 
  3.     if (n <= 1) { 
  4.         return n; 
  5.     return fibonacci(n-1) + fibonacci(n-2); 
  6. int main(void) { 
  7.     printf("%i", fibonacci(40)); 

Python:



  1. def fibonacci(n): 
  2.     if n <= 1: 
  3.         return n 
  4.     return fibonacci(n-1) + fibonacci(n-2) 
  5. 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. echo(fibonacci(40)) 

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

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

Nim语法

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



  1. import strformat 
  2. # Example taken from the Nim Website: https://nim-lang.org/ 
  3.   Person = object 
  4.     name: string 
  5.     age: Natural # Ensures the age is positive 
  6. let people = [ 
  7.   Person(name: "John", age: 45), 
  8.   Person(name: "Kate", age: 30) 
  9. for person in people: 
  10.   # Type-safe string interpolation, 
  11.   # evaluated at compile time. 
  12.   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. let input = readLine(stdin) # works 

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



  1. x, y = 10 # Both x, y are assigned to 10 

函数

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



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

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

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



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

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



  1. proc toString(x: int): string = 
  2. result = 
  3. if x < 0: "negative" 
  4. elif x > 0: "positive" 
  5. 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. # while true: 
  3. # for num in nums: 

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

打印并获取用户输入



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

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

echo可以带或不带括号。

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

附加功能

面向对象编程

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

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

这是一个简单的示例:



  1. import macros 
  2. macro myMacro(arg: static[int]): untyped = 
  3. echo arg 
  4. 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. comment 

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 ++功能。

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

谢谢阅读!

【编辑推荐】

【责任编辑:华轩 TEL:(010)68476606】

点赞 0

关注“51CTO技术栈”微信公众号获取更多精彩内容


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK