原文:https://akehrer.github.io/nim/2015/01/05/getting-started-with-nim.html
作为使用很长时间python的用户,我发现Python已经不能满足我的需求了。当我在Hacker News上看到Nim版本0.10.2发布的消息时,它引起了我学其他语言的兴趣,特别是编译到c 和可执行文件的语言。我有一些用c 和 c++语言开发Arduino项目的经验,但是我最深的印象是在本科阶段的一门数据结构课。所有的内存管理在某种程度上不符合我的大脑的思维方式,它改变了我对编程作为一种职业的想法。
当然这并没有阻止我学习编程,它只是让我转向了解释型语言像PHP和Python。我记得当我学习python时谷歌了“垃圾回收”,然后就说:“对于我来说这看起来像是一门语言”。随之而来的是14年以上的愉快的编程。现在我的水平已经提高到了这个点,我想扩大我的语言天赋和Nim看起来是一个很好的补充。
Nim吸引我的有以下几点:· 和python 相似的语法
· 静态类型与基本类型推理
· 垃圾回收
· 编译到C让后生成可执行文件。
我希望语法和垃圾收集会让我很快的得到比运行“Hello World”更有用的程序。静态类型和编译应该使事情不容易出错和变得快,程序工作执行的方式应该比Python更方便。
我的第一个Python项目涉及到创建一个线性回归,用最小二乘法拟合校准线从一个传感器阵列收集数据。由于SciPy和NumPy不在/在时机成熟时我打开我的统计学课本写了所有需要拟合数据的函数。由于Nim似乎没有统计学模块,还有考虑到我的统计学知识有点生疏的情况下,我认为从基础的 nim-statistics模块开始将使我能够更好的理解Nim的基本知识和刷新我的统计数据。
我将不会重新安装Nim 或者学习基础,因为这个将会在其他地方出现。我在这里将会展示很多基于其他人的代码和阅读标准库的内容。所以,从最简单的东西开始,高斯分布。首先我们将导入内置的math模块,因为我们知道需要用它里面的过程。然后,我们将定义一个对象来持有分布的参数。
import math
type
GaussDist* = object
mu, sigma: float
一些事情需要注意:
· GaussDist 继承了基本类 object 和 有两个float型参数。
· 带*号表示模块中GaussDist出口(能被其他模块通过improt 调用)。因此 improt math 导入了math 模块中所有的带*号事物,这个模块的GaussDist 同样也会被导出。
import math
type
GaussDist* = object
mu, sigma: float
proc NormDist*(): GaussDist =
## A Normal Distribution is a special form of the Gaussian Distribution with
## mean 0.0 and standard deviation 1.0
result.mu = 0.0
result.sigma = 1.0
proc mean*(g: GaussDist): float =
result = g.mu
proc standardDeviation*(g: GaussDist): float =
result = g.sigma
proc variance*(g: GaussDist): float =
result = math.pow(g.sigma, 2)
when isMainModule:
var n = NormDist()
var gnorm = GaussDist(mu: 0.0, sigma: 1.0)
assert(n.mean == gnorm.mean)
assert(n.standardDeviation == gnorm.standardDeviation)
assert(n.variance == gnorm.variance)
echo "SUCCESS: Tests passed!"
注释:
·mean,standardDeviation和variance 过程来自math模块都是可用的,但是不知道怎样使用GaussDist 类,所以我们用重载来实现它们。
·在NormDist 过程中你能看到一个使用Nim 默认返回值的例子。因为rusult和过程定义类型同样为GaussDist类型,所以在参数赋值时不必在创建一个中间变量。
·pow可以代替math.pow,因为pow包含在导入的模块中。但是用math.pow可以清楚的知道它来自哪里。
·When isMainModule 检测给我们的测试带来了方便,因为当模块被导入时是不能被执行。
最后,我们来添加分布函数
import math
## Some additional functions from math.h are needed
## that aren't included in the math module
proc erf(x: float): float {.importc: "erf", header: "<math.h>".}
## computes the error function (also called the Gauss error function)
type
GaussDist* = object
mu, sigma: float
proc NormDist*(): GaussDist =
## A Normal Distribution is a special form of the Gaussian Distribution with
## mean 0.0 and standard deviation 1.0
result.mu = 0.0
result.sigma = 1.0
proc mean*(g: GaussDist): float =
result = g.mu
proc standardDeviation*(g: GaussDist): float =
result = g.sigma
proc variance*(g: GaussDist): float =
result = math.pow(g.sigma, 2)
## The distribution functions are from
## http://en.wikipedia.org/wiki/Normal_distribution
proc pdf*(g: GaussDist, x: float): float =
var numer, denom: float
numer = math.exp(-(math.pow((x - g.mu), 2)/(2 * math.pow(g.sigma, 2))))
denom = g.sigma * math.sqrt(2 * math.PI)
result = numer / denom
proc cdf*(g: GaussDist, x: float): float =
var z: float
z = (x - g.mu) / (g.sigma * math.sqrt(2))
result = 0.5 * (1 + erf(z))
when isMainModule:
var n = NormDist()
var gnorm = GaussDist(mu: 0.0, sigma: 1.0)
assert(n.mean == gnorm.mean)
assert(n.standardDeviation == gnorm.standardDeviation)
assert(n.variance == gnorm.variance)
assert(n.pdf(0.5) == 0.3520653267642995)
assert(n.cdf(0.5) == 0.6914624612740131)
echo "SUCCESS: Tests passed!"
最后一些注意事项:
· Nim 的 math 模块没有包含erf 过程,但是它在C标准库中时可用的,它很容易导入到这里。
· 有很多种方法调用Nim 过程,在这篇文章的例子中我已经使用了这种调用语句方法(obj.method()), 因为这对于我来说更加自然。
这是一个好的开始,虽然没有真正练习一些令人赞赏的特性,但是它让我很好的了解了Nim语言,这是我成长的起点。希望我能够写出统计模块,学会更多关于Nim知识并且继续发布文章。
引用: