A Python Substitute? I Tried Out the Best Programming Language You’ve Never Heard Of
Meet Nim: the language with Python-like syntax and C efficiency
Jul 17 ·9min read
A few weeks ago I was browsing through GitHub and encountered a repo that caught my eye. It hosted a project that was written entirely in Nim .
What the hell is Nim? I thought.
Immediately I concluded this was one of the many programming languages that a lot of people use, but I just was the stupid guy who didn’t know it. But rather than putting it aside, I decided: Let’s learn a bit about this.
I then had two major realizations:
- No, this language is not used by a lot of people.
- But maybe it should be.
So here goes a bit about my experience with Nim, a quick programming tutorial, and why the language seems extremely promising to me.
Show Me the Code!
Here’s a useless program I wrote in Nim:
Looks pretty clean. It also feels so simple that you can probably figure out what it does with no effort, even though you might have never heard of Nim before. (Hint: It prints num: 5 i: 5
.)
So let’s break down what seems familiar here:
Variable declarations
It’s extremely familiar to JavaScript developers. While some languages use var
and some use let
, JS and Nim both allow declarations using either of the two. It’s important to note that they do not have the same meaning in both languages, however. But more on that later.
Block syntax
To mark a new block in Nim, we use a colon followed by an indented line. That’s Python right there.
Keywords
Both loops, as well as the if statement, look like they were plucked right out of Python. In fact, everything from line 5 onwards is actually valid Python.
So yes, a lot of the keywords and operators from Python are also valid in Nim, such as not
, is
, and
, or
, etc.
Until now, there’s nothing special about Nim at all. It just looks like a worse version of Python, since we need to use let
or var
.
But what if I told you this: Nim is a statically typed language that runs almost as fast as C.
Oh, now we’re talking.
A Friendly Race
Before diving a little deeper into the Nim syntax (especially the statically typed part, which we still haven’t seen), let’s try to back up the claims about its speed. To do so, I wrote a program to naively (i.e., without dynamic programming) compute the n-th Fibonacci number in Nim, Python, and C.
In order to keep things fair, I standardized the implementation based on the suggested Leetcode solution for this problem (Approach 1) and made sure to stick to it as much as possible across the three languages.
To time the execution, I used the “real” value from the output of time
in the Bash shell.
Here are the results for computing the 40th Fibonacci number:
Yeah, that happened.
Now, this is very limited and far from a scientific experiment, but it is consistent with the findings of others who have done more serious benchmarks [1] [2] [3] .
Nevertheless, all the code I’ll run through in this article is available on GitHub , including instructions on how to try this experiment out.
So why is Nim so much faster than Python?
Well, I would say there are two main reasons. Simplifying heavily, these are:
- Nim is compiled while Python is interpreted (disagree? click the link). This means that when a Python program is run, there’s more work being done than just running the program, as it needs to be interpreted before it can actually execute. This generally makes languages much slower.
- Nim is statically typed. While the example I showed earlier didn’t have a single type declaration or annotation, we will see later that it is indeed a statically typed language. In the case of Python, which is dynamically typed, the interpreter needs to do a lot more work to figure out and appropriately handle types, which slows down execution.
Faster to Run, Slower to Write
Here’s what the Python Docs have to say about interpreted languages:
“Interpreted languages typically have a shorter development/debug cycle than compiled ones, though their programs generally also run more slowly.”
This sentence is a good summary of the tradeoff between Python and C, for example. Anything you can do with Python you can also do with C, and your program will run many orders of magnitude faster.
However, you will be spending a lot more time writing and debugging your code in C, as well as it will be longer and less readable. And that’s why C isn’t as trendy anymore and Python is so popular. To put it simply: Python is “easy” (comparatively, of course).
So, if Python is on one end of the spectrum and C is on the other, Nim is trying to be somewhere in the middle: somewhat fast and somewhat easy? Something like that.
What makes Nim stand out for me, however, is that at first glance it feels like it has minimized the tradeoff. In other words, it is much faster than Python, but not equally harder to program in, like C (or so it feels like upon brief inspection).
To illustrate this point, let’s look at the code from our Fibonacci experiment.
Here’s the C code:
Python:
And Nim:
While Nim has this weird proc
thing and, dear God, uses =
to declare functions (or procedures
, as they’re called), it’s still much cleaner than C.
Hence, maybe it’s a worthy tradeoff? A little harder to write than Python, but tens of times faster — I could live with that.
Nim Syntax
Here’s a brief overview of some key points about Nim’s syntax:
Variables
Variables are declared with var
, let
, or const
.
var
and const
work essentially like JavaScript, but let
is a different story.
While let
in JavaScript differs from var
in terms of scope, let
in Nim denotes a variable whose value cannot change after initialization. This is apparently similar to Swift, I’ve now been told.
But isn’t that a constant?
Well, in Nim the distinction is as follows:
For const
, the compiler must be able to determine the value at compile time, whereas let
can be determined at runtime.
The documentation offers this example:
const input = readLine(stdin) # Error: constant expression expectedlet input = readLine(stdin) # works
Additionally, you can also declare variables like this:
var a = 1 b = 2 c = 3 x, y = 10 # Both x, y are assigned to 10
Functions
Functions in Nim are called procedures, and their declaration is done like this:
proc procedureName(parameterName: parameterType):returnType = return returnVar
Given that the language looks like Python in a lot of ways, procedures definitely stand out as being a little weird when you first see them.
Using =
instead of {
or :
is especially odd. However, it looks a little better in one-liner procedures:
proc hello(s: string) = echo s
Also, you’re able to return from functions like this:
proc toString(x: int): string = result = if x < 0: “negative” elif x > 0: “positive” else: “zero”
It feels like you should still do return result
, but result
is not a variable — it’s a keyword. The above snippet is perfectly valid Nim.
And you’re also able to overload procedures:
Control flow
It’s a lot like Python.
# if true:# while true:# for num in nums:
For iterating over a range, instead of a range you can use countup(start, finish)
, or countdown(start, finish)
. Or you can simplify the whole thing and use: for i in start..finish
.
Printing and getting user input
let input = readLine(stdin) echo input
When comparing to Python, readLine(stdin)
is the equivalent of input()
and echo
is the equivalent of print
.
echo
can be used with or without parentheses.
My goal here is to give you a taste of Nim, not go through their entire manual. As such, I think I’ll stop here for plain syntax and skim over some additional features next.
Additional Features
Object-oriented programming
Nim is not object-oriented but has minimalistic support for objects . They are not as neat as Python classes, however.
Macros
Nim supports macros and metaprogramming, and, in fact, seems to heavily emphasize it. An entire part of their three-part tutorial series is dedicated to it .
Here’s a quick example:
import macros macro myMacro(arg: static[int]): untyped = echo arg myMacro(1 + 2 * 3)
Basic types
The basic types in Nim are: string
, char
, bool
, int
, uint
, and float
.
These are also valid:
int8 int16 int32 int64 uint8 uint16 uint32 uint64 float32 float64
Additionally, strings are mutable in Nim, unlike in Python.
Comments
You probably already saw my comments in Python syntax above, but unlike Python, multiline comments also make use of the hash symbol (followed by [
or ]
):
# a comment#[ a multi line comment ]#
JavaScript compilation
From the Nim website:
“Nim includes a first-class JavaScript backend so you can target the client and server effortlessly at the same time.”
That’s quite cool, although I’m not sure how many people would actually use it. But if you want to play Browser Snake written in Nim , you can do so. This time I didn’t build it, though.
Iterators
Instead of defining a proc
, one can also define an iterator
. However, Nim iterators are actually more like Python generators. Here’s an example:
iterator countup(a, b: int): int = var res = a while res <= b: yield res inc(res)
Case and underscore indifference
Nim is case- and underscore-insensitive (except for the first character).
Thus HelloWorld
and helloWorld
are different, but helloWorld
, helloworld
, and hello_world
are all the same, making this valid:
proc my_func(s: string) = echo smyFunc("hello")
Popularity
Maybe you read the title and said to yourself: Uh, I’ve heard of Nim or I’ve used Nim!
In that case, hey, I’m happy for you. However, I did try to get a bit of info on the popularity of the language, and it surely isn’t that high.
For example, Nim wasn’t even mentioned on the 2020 Stack Overflow Survey . I couldn’t find any jobs for Nim developers on LinkedIn (Location set to Worldwide), and the Stack Overflow tag for the language has only 349 questions. (Compare that to Python’s ~1,500,000, or those of a newer language, like Swift’s 270,000.)
Thus, it’s quite fair to assume most developers haven’t used it and that many have not ever even heard the name Nim.
A True Python Alternative?
I’ll be honest with you, I find Nim pretty cool.
To write this article, I went over the bare minimum, so haven’t gone too deep into it yet, but I can see myself using it for something in the future.
However, while the basic syntax is very similar to Python, it gets more complicated quite fast, which I’m sure would throw off a lot of the Python user/developer base.
Personally, I am a big fan of Python but also of statically typed languages, so for me, the performance improvement in certain cases would more than compensate for the added verbosity.
It’s through writing this article that I realized: What about Go ?
I’m sure many of you were thinking just that while reading, and it is a valid point. As much as the syntax of Nim might be closer to that of Python, it really is competing in the space of performant-yet-nicer-than-C++ languages, which is currently led by Go.
Fun fact: I also sneakily ran the speed test with Go. For fibonacci(40)
specifically, it was as fast as C.
So, can Nim compete with Python? I highly doubt it. We’re seeing a trend of computers getting faster and programming getting easier, to the point that even if Nim offers a good tradeoff, as I pointed out, I don’t think it’s enough to take on the clean and versatile Python.
Edit: I spoke to one of the Nim Core Devs, who told me he believes Nim is more suitable for people transitioning from C++ than people transitioning from Python
However, can it compete with Go? Maybe (if Google wasn’t behind Go). The syntax is friendly, the language is powerful, and it has better support for C/C++ features than Go offers (e.g., macros and overloading).
Perhaps that’s the article I’ll write next.
Thanks for reading!
以上所述就是小编给大家介绍的《A Python Substitute? I Tried the Best Programming Language You’ve Never Heard Of》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C Primer Plus(第6版)中文版
普拉达 (Stephen Prata) / 姜佑 / 人民邮电出版社 / 2016-4-1 / CNY 89.00
《C Primer Plus(第6版)中文版》详细讲解了C语言的基本概念和编程技巧。 《C Primer Plus(第6版)中文版》共17章。第1、2章介绍了C语言编程的预备知识。第3~15章详细讲解了C语言的相关知识,包括数据类型、格式化输入/输出、运算符、表达式、语句、循环、字符输入和输出、函数、数组和指针、字符和字符串函数、内存管理、文件输入输出、结构、位操作等。第16章、17章介绍C......一起来看看 《C Primer Plus(第6版)中文版》 这本书的介绍吧!