杂七杂八之后,接下来,说说能够组合出程序的编程语言:

先说说这世界上有啥编程语言。对于正常人而言,计算机编程语言大概就是下面这四种类型:

计算机电子信号——>编码为二进制——>助记符(汇编)——>抽象以方便人类操作的语言(比如C)

对于前面三种,现在一般人都不需要去直接接触,对于第四种,就是我们日常需要接触掌握的,第四种是非常丰富的,有各种各样,而且,日常编程生产作业中,都是不可避免地需要同时掌握好几个编程语言,才能写出一个可用的程序的,因此,为了快速掌握它们,需要了解它们的一些共有规律。

另外,对于有些特殊要求的,比如前面说到的瘫痪的人,可能其计算机编程语言就演变成如下:

计算机电子信号——>编码为二进制——>助记符(汇编)——>摩斯码或者可能的盲文编程语言(目前还不存在这种语言)

为什么会有这么多的语言呢?

从打孔机时代一路走来

为了表达 1 + 2 + ... + 10 = 55 并打印出结果,需要:

其特点:操作 操作对象 内存位置。再复杂的逻辑,都可以简化为如此形式。 初看运算范围是有限的:不超过8位二进制所能表达的范围,当然,有办法表达所有数字,就是运用科学计数法。 这是没有资源回收的版本,会导致有三个内存位置一直被占用。

00110001 00000000 00000000
00110001 00000001 00000001
00110011 00000001 00000010
01010001 00001011 00000010
00100010 00000010 00001000
01000011 00000001 00000000
01000001 00000001 00000001
00010000 00000010 00000000
01100010 00000000 00000000

每句解释:

  1. [结果]把数字0 存放到 内存位置 0 中
  2. [运算材料]把数字1 存放到 内存位置 1 中
  3. [运算]把 内存位置1的 存放到内存位置 2 中
  4. [设定范围] 内存位置 2 的值 减去 11
  5. [设定范围] 若 内存位置2的值为0 ,则跳转到第九步
  6. [累计结果]把内存位置1的值 加入到内存位置 0 中
  7. [递增] 把内存位置1的值 加1
  8. [跳转]继续第三步
  9. [输出]把 位于内存位置 0 的值 输出。

进一步发展编程语言,利用借记符:

Set “total” to 0
 Set “count” to 1
[loop]
 Set “compare” to “count”
 Subtract 11 from “compare”
 If “compare” is zero, continue at [end]
 Add “count” to “total”
 Add 1 to “count”
 Continue at [loop]
[end]
 Output “total”

中文解释:

  1. 设 “总值” 初始值为 0
  2. 设 “累加值”初始值为 1
  3. [循环执行]
  4. 设 “范围” 为 “累加值”
  5. “范围” - 11
  6. 如果 “范围” = 0 转到 [结果]
  7. 总值 = 累加值
  8. 累加值 = 累加值 + 1
  9. 转到 [循环执行]
  10. [结果]
  11. 输出 “总值”

现代编程语言 js:

var total = 0, count = 1;
while (count <= 10) {
  total += count;
  count += 1;
}
console.log(total);
// → 55

当然,理论上还可以进一步简化:

(sum(range(1, 10)));
// → 55

问题:8位二进制可以表达多少? 示例:13,用二进制表示:

  0   0   0   0   1   1   0   1
128  64  32  16   8   4   2   1

也就是: 00001101 或者 8+4+1=13 。依此类推,8位数可以一共表达256,ascii的基础码共128(编码还不够简约,其实26个大写字母可以只用加一位即可判断,不需要硬编码进去),包含扩展码后共256个。

语言发展的动力

编程语言是不完美的,现实情况的变化,编程语言也是需要不断发展的。

编程语言进化的动力,就是不满!

  • Algol: 汇编太底层了。
  • Pascal: Algol语言缺少足够的数据类型。
  • Modula: Pascal语言对于系统应用编程来说太弱了。
  • Simula: Algol语言在仿真模拟方面不够好。
  • Smalltalk: Simula语言里并不是所有的东西都是对象。
  • Fortran: 汇编太底层了。
  • Cobol: Fortran语言不好用。
  • PL/1: Fortran语言缺少足够的数据类型。
  • Ada: 所有现存的编程语言都有缺失。
  • Basic: Fortran语言不好用。
  • APL: Fortran语言在数组操作上不好用。
  • J: APL语言需要自己的字符集。
  • C: 汇编太底层了。
  • C++: C语言太底层了。
  • Java: C++太笨重。微软在压迫我们。
  • C#: Java是Sun公司控制的。
  • Lisp: 用图灵机方式描述计算机计算太别扭。
  • Scheme: MacLisp语言太笨拙。
  • T: Scheme语言没有程序库。
  • Common Lisp: Lisp方言太多了。
  • Dylan: Scheme语言没有程序库,Lisp语法太疯狂。
  • Perl: Shell脚本/awk/sed都不像编程语言。
  • Python: Perl语言太让人受不了。
  • Ruby: Perl语言太笨拙,Lisp语法太疯狂。
  • Prolog: 编程不够逻辑。
  • js: java不适合新手
  • 易语言:你们都不支持中文编程
  • 爱编:你们都不国际化

目前处于大整合阶段:

语法流派

先说说语法,人类社会中存在大概三种下命令方式:

  1. 领导说:“甲乙丙丁!”甲乙丙丁:“在!”领导:“你们去ooxx!”甲乙丙丁:“是!”
  2. 另一种是:领导说:我们要去ooxx,嗯,甲乙丙丁,你们去做这件事吧!
  3. 简化命令法:甲乙丙丁 去xxx

第一种和第三种都是直抒式,第二种是抽象式。为什么会有这么些方式呢?

第一种和第三种是: 2+3+0=5 (需要写2个+号)

第二种是:

    2
    3
+   0
-------
    5

好处:节省笔墨,语义化易懂。(只需要写一个+号,可见设计者明显是个有办法的懒人)

前置标识表达式有很多种:比如链码,markdown,比如json,其实C和JS也算部分的前置表达,但其表达式内部都是直抒式的。

网标码的成对语义化表达方式,太过浪费笔墨。

另外几种特殊的编码,比如摩斯码、简符码等简化命令式,则很难懂。

程序的共有特征

编程语言的构成要素

一套编程语言,无非是:表达的类型+操作(读、写、查),穷尽各种组合就是了。

一般而言,编程语言之间的不同,在于抽象方式各异:各个语言为了达成自己的主要目的,在着眼点上会极尽所能的抽象方式,提供该方面尽可能大的可操控能力,该方面的稳定性,该方面的可测试性。

```

         类型 |纵坐标:操作对象
              |
         与非 |
         数字 |
         字符 |
         内名 |
    横坐标____|______________________________________
    操作      |    读     查    写
       字符串 |
       数据流 |
           树 |
           表 |
         函数 |
         向量 |
         链串 |
         拓扑 |
         闭合 |
       连续统 |
     提示信息 |
     文件路径 |
       程序包 |
              |

```

进一步细分:

【类型】:

【操作】:

【怎么操作】:

新设计语言可以参考神编和sibilant的构造经验:

  1. 设定存在的类型,
  2. 批量判断输入输出类型是否正确,逐个判断还是批量判断?,
  3. 具体设定各个函数的功能,但不判断类型,只读入读出?。

编程语言常有的机制

命名:对每个操作和操作对象都命名,以方便调用。

程序设计思路:抽象,化整为零

抽象化,自动化

化整为零,简化问题解决方式