-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathchinese-based-programming-languages.html
50 lines (49 loc) · 17.9 KB
/
chinese-based-programming-languages.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>中文编程的前世今生 | 耗子么</title>
<meta name="generator" content="VuePress 1.4.1">
<link rel="apple-touch-icon" href="avatar.png">
<meta name="description" content="耗子的个人世界,喜欢不喜欢,就那样">
<link rel="preload" href="/assets/css/0.styles.98f1cd6e.css" as="style"><link rel="preload" href="/assets/js/app.a88ffa1a.js" as="script"><link rel="preload" href="/assets/js/3.8223bd71.js" as="script"><link rel="preload" href="/assets/js/7.89d0b4a8.js" as="script"><link rel="prefetch" href="/assets/js/10.d7711095.js"><link rel="prefetch" href="/assets/js/2.7670f5a9.js"><link rel="prefetch" href="/assets/js/4.9c619a18.js"><link rel="prefetch" href="/assets/js/5.8aac9a74.js"><link rel="prefetch" href="/assets/js/6.7af12a4f.js"><link rel="prefetch" href="/assets/js/8.23b22c29.js"><link rel="prefetch" href="/assets/js/9.3bc49734.js">
<link rel="stylesheet" href="/assets/css/0.styles.98f1cd6e.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div id="global-layout"><header><a href="/" class="router-link-active">耗子么</a></header> <div id="global-content" class="g-wrap"><nav id="global-nav"><a href="/" class="router-link-active">~</a> <code>cat ./中文编程的前世今生.md</code></nav> <div class="content content__default"><h1 id="中文编程的前世今生"><a href="#中文编程的前世今生" class="header-anchor">#</a> 中文编程的前世今生</h1> <hr> <p><img alt="" width="700" height="394" data-src="https://img.alicdn.com/tfs/TB1UkzIDxz1gK0jSZSgXXavwpXa-1400-788.jpg" loading="lazy" class="lazy"></p> <h2 id="引子"><a href="#引子" class="header-anchor">#</a> 引子</h2> <p><img alt="" width="700" height="394" data-src="https://img.alicdn.com/tfs/TB19brJDxn1gK0jSZKPXXXvUXXa-1400-788.jpg" loading="lazy" class="lazy"></p> <p>写这篇文章前,我想先放一张图这是 1946 年,人类发明的第一台计算机 ENIAC,它占地 170平方米,按照杭州将近 3 万一平的地价,放置它需要花 500 万。这台计算机上如何写代码?它靠的是<a href="https://www.digitaltrends.com/computing/remembering-eniac-and-the-women-who-programmed-it/" target="_blank" rel="noopener noreferrer">六位小姐姐<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>通过改变接线来实现。</p> <p><img alt="格蕾丝·赫柏" width="700" height="394" data-src="https://img.alicdn.com/tfs/TB1CurJDpT7gK0jSZFpXXaTkpXa-1022-575.jpg" loading="lazy" class="lazy"> <cite>格蕾丝·赫柏,不仅是世界上第一位女程序员,还是一名将军,发明 bug 一词并写下千年虫 bug 的女神</cite></p> <p>第二台 EDVAC 开始,想必大家也有耳闻,用的打孔卡。
<img alt="" width="700" height="394" data-src="https://img.alicdn.com/tfs/TB1pGnPDxv1gK0jSZFFXXb0sXXa-1400-788.jpg" loading="lazy" class="lazy"></p> <p>其实原理也很简单:众所周知,我们的电脑无论手机还是 PC,都没有超出冯·诺伊曼架构。底层是由 0 和 1 两个电位构成。我们所有的编程指令,最终都要变成 0 和 1 计算机才能理解。计算机本质是计算器,CPU 只负责计算,本身不具备智能。你输入一条指令,它就运行一次,然后停下来,等待下一条指令。这些指令都是二进制的,称为操作码(opcode),打孔机输入的就是这些<a href="https://zh.wikipedia.org/zh-cn/%E4%BA%8C%E8%BF%9B%E7%A0%81%E5%8D%81%E8%BF%9B%E6%95%B0" target="_blank" rel="noopener noreferrer">二进码的十进数<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>。</p> <p>一系列操作指令,形成一套指令集(ISC),目前世面上常见的指令集有 RISC (简单指令集)和复杂指令集(CISC)。简单地说,简单指令集 就是只规定非常简单的二进制处理器指令,复杂的指令也只是最基本的指令的叠加组合。复杂指令集本身就有一个很庞大的指令集库,内置了很多指令库,只需要调用即可。
前者主要代表有 ARM 架构,后者主要代表有 X86 架构。ARM 架构凭借着内核简单带来的低功耗,在移动和 5G 时代备受欢迎。</p> <h2 id="经典的分层"><a href="#经典的分层" class="header-anchor">#</a> 经典的分层</h2> <p>当然,对于人类来说,二进制是不可读的,人类又发明了汇编。汇编其实就是二进制指令的助记形式,与指令基本上是一一对应的(有很少的一些抽象),只要把汇编映射成二进制,就可以被 CPU 直接执行,所以它是最底层的低级语言。</p> <p><img alt="" width="700" height="394" data-src="https://img.alicdn.com/tfs/TB1i.HQDAT2gK0jSZPcXXcKkpXa-1280-720.jpg" loading="lazy" class="lazy"> <cite>吹牛能直接看二进制的反派第一部就领了便当</cite></p> <p>计算机的分层架构设计思想,绝对是人类历史上的精妙设计。从半导体物理学到云计算,每一层都是对下一层的抽象,上层不需要关心下层的实现,只需要知道自己要给下一层的输入输出是什么。</p> <p><img alt="" data-src="https://img.alicdn.com/tfs/TB1tENQfcKfxu4jSZPfXXb3dXXa-1134-960.png" loading="lazy" class="lazy"></p> <p>在汇编语言之上,出现了对人类更友好的高级语言如 C 语言,它使用近似英语的语法描述代码来表达代码,然后由 gcc 编译器编译成汇编。
以下是一段简单的 C 代码及它在 i7 的 macbook 编译的汇编形式:</p> <div class="language-c extra-class"><pre class="language-c"><code><span class="token keyword">int</span> <span class="token function">main</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token number">1</span> <span class="token operator">+</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language- extra-class"><pre class="language-text"><code>_main:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movl $0, -4(%rbp)
movl $3, %eax
popq %rbp
retq
.cfi_endproc
</code></pre></div><p>我们可以看到,C 比汇编更接近自然语言,而汇编,则是在和指令和寄存器打交道。</p> <h2 id="中文编程"><a href="#中文编程" class="header-anchor">#</a> 中文编程</h2> <p>事实上,世界各国的开发者都进行了<a href="https://en.wikipedia.org/wiki/Non-English-based_programming_languages" target="_blank" rel="noopener noreferrer">基于母语设计编程语言语法的尝试<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>,有些已经商用且活跃至今。中文圈内比较有名的当属<a href="http://www.eyuyan.com/" target="_blank" rel="noopener noreferrer">易语言<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>了,还有前阵子产生话题性的<a href="https://wy-lang.org/" target="_blank" rel="noopener noreferrer">文言文编程<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>。</p> <p>很多人听到易语言有些不屑,然而这门语言在一个灰色领域却是 top 级的语言。这个领域就是游戏外挂和黑产木马,国内超过八成以上的外挂和盗号程序来自于易语言。</p> <p>一门语言的是否能火起来,和进入这个子领域的契机有关。比如 C 语言,解决了源代码跨的可移植性问题,C 成为编写操作系统和底层协议的首选语言;Java 赶上企业信息化大潮,强类型、垃圾回收及面向对象的高级抽象,使得架构大型企业级应用不会成为灾难;js 的存活在于各大浏览器厂商谈不拢,js 遂成为唯一跨浏览器开箱即用的语言,恰好赶上 Web2.0 技术兴起,具备了不可取代性,之后只能进一步对这门本身设计有缺陷的语言向后兼容升级。node 的兴起,则是 js 这门语言在向浏览器之外宿主扩张的自然行为,受益于不错的性能和庞大的用户群体;Python 则凭借着强大的表现力和数学库,在人工智能领域大受欢迎。中文编程,则命中了一个小的群体,这些人不是科班出身,甚至很多没有学历,对英语有天生排斥,有一点小聪明,有强烈意愿的要做成某件事的人。</p> <p>易语言官方论坛注册人数近百万,能在一个小众领域做成功,肯定有一些过人之处,虽然易语言的用户群偏离了开发者初衷。</p> <p><img alt="" width="700" height="589" data-src="https://img.alicdn.com/tfs/TB1pnsqDuH2gK0jSZFEXXcqMpXa-1141-960.jpg" loading="lazy" class="lazy"></p> <p>不吐槽年代感的 Win98 风格,易语言的 ide 提供了非常友好的可视化布局界面及调试能力。从基础编程能力到几乎涵盖了操作系统的所有库函数的调用。可以开发下载工具,即时通讯、播放器、网站等众类型程序,并且都有官方和第三方模板。ide 的代码编辑部分也做得很用心 ,常被人吐槽的打「如果」快还是 'if' 快,其实在 ide 里只要输入 rg 的拼音首字母就能快速补全语句块了,整个 ide 体验下来,完全不需要切中文输入法。</p> <p>然而其实外挂的开发难度并不简单,从 LSP 注入到驱动注入,甚至内核重载,VT 调试,用内联汇编来劫持内存数据。这些根本不是一个连英语单词都拼不来的半吊子能搞定的事。易语言在外挂界流行,其实还有个外行人不了解的内情:做外挂是在法律的边缘试探,黑客一般不直接出售外挂,而是打包成 dll 非完整的程序形式输送到黑产下游逃避制裁。易语言核心做的事情就是 —— 调库。</p> <h2 id="扩展-js"><a href="#扩展-js" class="header-anchor">#</a> 扩展 JS</h2> <p>讲了这些,似乎做为中文编程的一哥易语言也不是多光彩的事。然而,这件事对我们来说却有一些正向启发。</p> <p>易语言做为封闭的商业软件,注定无法成为主流,但我们其实可以简单地为 js 做一些定制来做到类似的事情。以下是一个可以直接正常运行的 js 程序:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> 画布 <span class="token operator">=</span> <span class="token function">获取画布</span><span class="token punctuation">(</span><span class="token string">'#canvas'</span><span class="token punctuation">,</span> <span class="token string">'2d'</span><span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">存在</span><span class="token punctuation">(</span>画布<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
画布<span class="token punctuation">.</span><span class="token function">填充颜色</span><span class="token punctuation">(</span><span class="token string">'红'</span><span class="token punctuation">)</span>
画布<span class="token punctuation">.</span><span class="token function">绘制矩形</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>代码如果觉得还不够友好,我们可以通过词法分析再简单地扩展一下 js:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> iamotherjs<span class="token operator">...</span>
<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">很容易语言
设 画布 为 获取画布('#canvas', '2d')
如果 (存在(画布)):
画布.填充颜色('红')
画布.绘制矩形(10, 10, 50, 50)
</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span>
</code></pre></div><p>我们定义了一个叫「很容易语言」的文法边界,然后将边界内的字符串通过词法分析拆解成 token,再将 token 生成抽象语法树 AST,再通过 AST 转回普通 JavaScript,我们就可以很容易扩展 js,使其更具备更好的中文书写能力,又能依托 js 的完善生态。</p> <h2 id="更自然的语言"><a href="#更自然的语言" class="header-anchor">#</a> 更自然的语言</h2> <p>以上的方式,只能降低编程入门的门槛,但还是需要严格的语法界定符。从信息论的角度看,降低熵就要做功,这部分复杂度并没有减少和转移。我们需要更自然的语言来描述逻辑来减少做功,这就是自然语言处理(NLP)。</p> <p>自然语言有 5 个难点,使得计算机处理很困难:</p> <ul><li><strong>多样性:</strong> 如「我打了小明」,「小明被我打了」自然语言没有太多规律,但我们能对多种句式理解一致,说明仍有内在规律。</li> <li><strong>岐义性:</strong> 如果不联系上下文,缺少环境的约束,语言有很大的歧义性,如「播放美人鱼」,是想看周星驰电影,想听周杰伦的歌,还是要读安徒生童话。</li> <li><strong>鲁棒性:</strong> 语言多字少字错字噪音,如比这话句你并不会得觉无发理解。</li> <li><strong>常识:</strong> 自然语言有知识依赖,比如开车,到底是开车还是开车?</li> <li><strong>上下文:</strong> 对话的上下文,用户身份,用户画像。</li></ul> <p>对于上小结的代码,我们用一种更说人话的方式表达就是:「在页面 xx 位置画一个红色正方形」。</p> <p>这句话,转成代码,有信息是丢失的。比如,xx 位置,对应 DOM 选择器是啥?红色具体色号是啥,蔷薇红还是直男斩?正方形多少大小合适?用 Canvas 画还是 SVG 画?</p> <p>对于实践,我们可以多增加一些上下文约束来使得样本处理简化:</p> <ul><li><strong>编程语言:</strong> 如中文编程语言,它本身是非常结构和强约束的</li> <li><strong>模板:</strong> 适用于限定类的场景,将需要填的变量以表单的方式收集</li> <li><strong>可视化编排:</strong> 比如通过流程图或者搭积木语言表达逻辑,本质还是强结构约束</li> <li><strong>专家系统 :</strong> 需要通过规则,分析到丢失信息,再进一步对话提问</li></ul> <h2 id="思考"><a href="#思考" class="header-anchor">#</a> 思考</h2> <p>为什么我们需要中文编程?</p> <p>传统的开发工具链路提效,本质上没有解决任何问题,只是用机器代替了部分人力劳动,而机器是高效且不会出错的。
一个需求的生命周期,从业务方提出想法,到产品经验梳理成 PRD,再到灌输给程序员,逼着程序员上线。这个过程,我们发现,我们都是在讨论同一件事,只是通过不同的方式来描述这件事。这个过程中,有很大的一部分工作量是双方重复的,只是表达语言不同。
我们是否可以在需求详审的早期,更多地识别出信息缺失的部分?是否可以找到更多的共性部分,通过更结构化地方式表达,或者更智慧的方式去理解?</p></div> <div class="i-disqus"><!----></div></div></div><div class="global-ui"></div></div>
<script src="/assets/js/app.a88ffa1a.js" defer></script><script src="/assets/js/3.8223bd71.js" defer></script><script src="/assets/js/7.89d0b4a8.js" defer></script>
</body>
</html>