34

本次演讲中,查克·摩尔(Forth 的创建者)提出了一些非常大胆、全面的主张,例如:

  1. “我见过的每个我没有编码的应用程序中的代码量是它需要的十倍”
  2. “大约一千条指令似乎对我来说是正确的,可以做任何事情”
  3. “如果你正在编写需要[局部变量]的代码,那么你就是在编写非最佳代码。不要使用局部变量。”

我试图弄清楚摩尔先生是 a) 绝对出色的天才还是 b) 疯子。但这是一个主观问题,我不是在这里寻找这个问题的答案。我正在寻找的是可以使用 Forth 在“1000 条或更少的指令”中解决的复杂现实问题的示例,以及演示如何执行此操作的源代码。仅显示一个真实世界系统的一个重要部分的示例会很好,但请不要使用可以在另一种高级语言的 5 或 10 行中复制的“玩具”代码示例。

如果您在 Forth 中编写了真实世界的系统,只使用了少量源代码,但不能随意显示源代码(因为它是专有的),我仍然想听听它。

4

5 回答 5

33

您需要了解Chuck Moore与您和我有些不同。他是在一个大型计算机由 16 KB 或同等核心内存组成的时代接受训练的,他能够用当时的计算机做很多事情。也许 Forth 最大的成功,除了他的 OKAD-II 芯片设计包(这不是错字)之外,是一个多用户多任务 Forth 系统,负责同时控制NRAO的数据采集仪器和数据分析/可视化软件。大小适中的计算机几乎无法自行编译Fortran源代码。

他所说的“应用程序”,我们可以认为是一个更大、更模糊的东西的“组件”,称为应用程序。更一般地说,最好记住一个摩尔“应用程序”或多或少等同于当今MVC三元组中的一个“视图”。为了保持较小的内存消耗,他严重依赖覆盖和即时编译技术。从一个程序界面切换到另一个程序界面时,通常涉及从源代码重新编译整个应用程序/视图。这发生得如此之快,你不知道它正在发生。有点像今天您每次激活应用程序时, Android 如何将Dalvik代码重新编译为本机ARM代码。

在任何给定时间,OKAD-II 加载到内存并运行的代码都不超过 2.5 KB。但是,OKAD-II 的磁盘源远大于 2.5 KB。尽管如此,它仍然比最接近的竞争对手SPICE更紧凑。

我经常对 Chuck Moore 的观点感到好奇,并发现他对简单的永无止境的追求令人着迷。因此,以MythBusters的方式,我通过尝试尽可能少地设计我自己的系统来检验他的主张。我很高兴地报告他在硬件和软件问题上的主张几乎是正确的。例如,在去年 9 月的 硅谷第四兴趣小组期间(SVFIG) 会议,我使用我的 Kestrel-2 本身为幻灯片生成视频。这需要我为它编写一个幻灯片演示程序,它占用了 4 KB 的内存用于代码,4 KB 用于幻灯片数据结构。每个 Forth 字的平均空间为 6 个字节(出于我不会在此详述的原因),该应用程序的“大约 1000 条(Forth)指令”的估计值与 Chuck Moore 估计的他自己的“应用程序”差不多“ 成为。

如果您有兴趣与现实世界的 Forth 编码员(或过去曾这样做过,而且似乎越来越多的人)交谈,并且您恰好在湾区,硅谷 Forth 兴趣小组仍然会遇到每一位每月的第四个星期六,11 月和 12 月除外,即第三个星期六。如果您有兴趣参加会议,即使只是采访 Forth 编码人员并了解“真实世界”的 Forth 是什么样的,请访问 meetup.com 并关注我们。我们还在 YouTube 上直播我们的会议,但我们不太擅长。我们正在滥用不合适的硬件和软件来进行竞标,因为我们对这类事情的预算为零。:)

于 2012-10-11T18:21:17.740 回答
26

Forth 确实非常紧凑!没有形式参数的字(以及硬件上的零操作数指令 - 例如GA144)可以节省很多。另一个导致其紧凑性的主要因素是调用约定和连接性质所提供的对冗余代码的绝对无情的分解。

我不知道它是否属于非玩具示例,但 Fignition 的Turtle Graphics实现(在FigForth中)仅编译了307 个字节并适合单个源块!这包括定点三角和所有正常的海龟命令。这不是可读 Forth 的最佳示例,因为它试图将其压缩到具有单字符名称的单个源代码块中,例如:

\ 8.8 fixed point sine table lookup
-2 var n F9F2 , E9DD , CEBD , AA95 , 7F67 , 4E34 , 1A c,
: s abs 3C mod dup 1D > if 3C swap - then dup E > if
  -1 1E rot - else 1 swap then n + c@ 1+ * ;

0 var x 0 var y 0 var a
0 var q 0 var w 
: c 9380 C80 0 fill ; \ clear screen
: k >r 50 + 8 << r> ! ;
: m dup q @ * x +! w @ * y +! ; \ move n-pixels (without drawing)
: g y k x k ; \ go to x,y coord
: h dup a ! dup s w ! 2D + s q ! ; \ heading
: f >r q @ x @ y @ w @ r 0 do >r r + >r over + \ forward n-pixels
  dup 8 >> r 8 >> plot r> r> loop o y ! x ! o r> o ;
: e key 0 vmode cls ; \ end
: b 1 vmode 1 pen c 0 0 g 0 h ; \ begin
: t a @ + h ; \ turn n-degrees

使用它也非常简洁。

: sin 160 0 do i i s 4 / 80 + plot loop ;

正弦波

: burst 60 0 do 0 0 g i h 110 f loop ;

爆裂

: squiral -50 50 g 20 0 do 100 f 21 t loop ;

松鼠

: circle 60 0 do 4 f 1 t loop ; 
: spiral 15 0 do circle 4 t loop ;

螺旋

: star 5 0 do 80 f 24 t loop ; 
: stars 3 0 do star 20 t loop ;

星星

: rose 0 50 0 do 2 + dup f 14 t loop ;

玫瑰

: hp 15 0 do 5 f 1 t loop 15 0 do 2 f -1 t loop ; 
: petal hp 30 t hp 30 t ; 
: flower 15 0 do petal 4 t loop ;

花

(无耻博客插件:http: //blogs.msdn.com/b/ashleyf/archive/2012/02/18/turtle-graphics-on-the-fignition.aspx

于 2012-10-09T00:32:36.760 回答
13

今天人们不太了解的是 Forth 预期在 21 世纪初与敏捷方法相关的编码方法的方式。具体来说:

  • Forth 介绍了微小方法编码的概念——用小方法使用小对象。您也可以在这里为SmalltalkLisp提供一个案例,但在 1980 年代后期,Smalltalk 和 Lisp 的实践都倾向于更大、更复杂的方法。Forth 总是接受非常小的方法,这仅仅是因为它鼓励在堆栈上做很多事情。

  • 第四,甚至比 Lisp 更普及了解释器只是一个小软件模式,而不是论文大小的砖块的概念。遇到难以编码的问题?Forth 解决方案必须是“编写一点语言”,因为这就是 Forth 编程的内容。

Forth 在很大程度上是内存和时间限制的产物,那个时代的计算机非常小而且非常慢。这是一个漂亮的设计,可以让您在火柴盒中构建操作系统和编译器。

于 2013-03-22T22:45:24.377 回答
7

Samuel Falvo 的截屏视频Over the Shoulder 1 - Forth 中的文本预处理(1 小时 06 分 25 秒,101 MB,MPEG-1 格式 - 至少VLC可以播放)就是 Forth 可以多么紧凑的一个例子 。替代来源(“链接和资源”->“视频”)。

于 2012-10-08T22:36:12.193 回答
7

Forth Inc 的 polyFORTH/32 VAX/VMS 汇编器定义需要大约 8 个源代码块。一个 VAX 汇编器,源代码为 8K。评论。30年后,我仍然感到惊讶。

我目前无法验证,但我猜测解析这些 CODE 定义的指令数可能只有几百个。当我说“花了大约 8 个区块”时,仍然需要,使用该核心的应用程序在 30 年后已经上线并投入生产。

于 2013-02-01T09:07:53.210 回答