计算机语言的实质 - 2

迭代算法

对于函数是 first-class 的语言来讲,迭代的变形不少,从 Python 的 Comprehensive 到, Perl 的 map, 迭代是最能体会函数式语言威力的地方。编程

[ x * 5 for x in [1,2,3,4] ]

       (map (fn (x) (* x 5)) [1,2,3,4])

       map { $_ * 5 } (1 .. 5);

while 守卫循环数组

while 循环是设置一个条件,内部循环执行一段代码,而且设置迭代变量。网络

while ($x > 1) {
        last if $x == 10;
        say($x);
        $x++;
    }

在 while 条件表达式中的变量是外部的,反复执行代码部分属于内部,但做用于同一个变量。数据结构

还有一种 while 守卫循环是在内部赋值:多线程

{
        my $x = 0;
        $x++;
    } until ($x > 10);

其实,只要保护好变量不被意外赋值,两种形式都是能够互相转换的。闭包

并行循环函数

在支持并行的语言中,若是循环和顺序无关,彼此之间的计算结果没有前后依存关系,就可使用并行循环。并行循环充分利用多核的计算资源,能明显提升代码的效率。线程

线程或进程设计

多个结果不互相依存的计算过程,尤为是网络读写这种耗时较长的工做,一般同时用许多独立的线程来完成,以充分利用等待的时间段,多作些工做。为了搜集和容纳这些进程的工做结果,一般会用到队列。

队列是一种特别的数据结构,有点像数组,但又有时间上的限制,防止死锁进程致使的程序终止。有一些容错机制。

有了多线程的计算模型,代码更像是一个调度,分别监控各个独立的计算模型运行结果,彼此沟通,并对结果进行判断,处理意外。这是一种更高级的编程模型,里面同时容纳多个独立运行的代码,分别管理分配不一样的变量表和命名空间。

函数

函数是最普遍应用的一种代码抽象,他把重复运行的代码片断进行命名,抽象出参数和计算过程。

大部分函数返回的参数都是一个, Lua, Golang 能够返回多个,Python 利用元组也能模拟返回多值。函数的自由变量,一般是在定义的位置,获取外部变量的值。为了隔绝这种外部变量,有了闭包的概念。

Javascript 没有块级做用域,因此他的闭包实现是用函数中的函数实现的,这也是一种没有办法的事情。但被人用来炫耀这种技能,这实际上是一种错误的语言设计致使的一种变态作法!Python 也是如此,为了增长闭包的功能,增长了 global, nolocal 两个关键字才勉强实现。

Lisp 的函数做用域是动态的,和 Scheme 不一样,也就是从 caller 来获取自由变量的值。关于这种设计有不少争论。但我认为,自由变量的存在,自己就是一种错误的设计,由此引起的语言特性的争论,不过是在裂缝上涂泥巴,颜色不一样罢了。

命名空间

命名空间让变量,函数的命名更加简单,宽容。C 语言是没有命名空间的。C++ 增长了命名空间,也添加了类。

命名空间彼此之间的变量名称是互相隔离的,即便是在一个命名空间内定义别的命名空间,也是如此。

命名空间从名字上能够有归属关系,但实现并非嵌套,只是和平行的命名空间有不一样的名字继承原则,彼此之间是互相独立的。

不一样的语言有不一样的命名空间符号导入导出原则。Java 用 public, private 来界定导入导出的权限,而 Golang 则默认使用首字母大写的符号做为 public 符号。

类的实质是命名空间,能使用这里定义的函数,一定是由这个类定义的一个数据结构模板生成的。只是调用其中的函数是用另一种句法:

my $obect = new Class_name
    $object->method(args);

由于实际上函数调用,传入的多了一个参数,就是对象自己。类没有名字导出,全部可调用的函数,都是经过对象调用的,只有不能调用的方法,没有能够导出的方法。

类中定义的函数,又叫方法,由于处理的第一个参数,老是固定数据结构的对象,因此有些语言就干脆省略,用 self 代替,由此方法和函数使用不一样的关键字。

默认,类和其子类有继承方法的原则,这样一个类可能拥有的方法可能来自不少,这让类设计很容易变得复杂而庞大,由于检索一层层的方法而让面向对象的语言的速度下降。

即便量子计算机和神经元计算机面世,更大的需求出现,计算机能作的事情也变化不大,只是处理的数据多了些,硬件快了些,算法复杂了些罢了。

相关文章
相关标签/搜索