为不同工具寻找共同语言
Tcl的早期实现形成于1988年,开发者是加利福尼亚大学伯克利分校的约翰·奥斯特豪特。不同应用往往各自附带一套命令语言,使用者很难把它们的功能接起来。Tcl把通用解释器做成可嵌入应用的程序库,由应用提供具体命令,再用共同的语言组织这些动作。
奥斯特豪特在1990年冬季USENIX会议介绍了这一方法。为次年会议撰写的Tk论文又明确记下,Tcl开发始于1988年初,自1989年起公开分发,当时的Tcl发行包尚不包含Tk。早期语言实现、公开传播和图形工具包因此有各自的进程;1988年节点指实现的起点。
一个解释器,两层功能
1990年论文把Tcl描述为C语言程序库,工作得到美国国家科学基金会部分资助。库负责解析命令,提供变量、循环和过程;宿主程序注册自己的命令,调用Tcl_Eval执行文本。编辑器mx便加入读写文件和修改文本等操作。应用作者不必重新制造完整语言,使用者也能把现有动作组合起来。
早期接口把参数和结果统一表示为字符串。例如先执行“set a 3”,再执行“expr {$a + 1}”,按论文规则可得结果字符串“4”:set保存变量,expr解释算式,花括号让内部文本作为一个参数交给命令。这是依据原规则构造的小例子,并非另一次性能测试。数值意义由运算命令确定;字符串形式不等于所有内容都只按普通文字处理。可扩展性由命令接口实现,而非仅靠增加语法符号。
参考:[1]
Tk把界面组件接到脚本上
图形工具包Tk属于接续的发展阶段。奥斯特豪特为1991年冬季USENIX会议撰写的论文,以X11窗口系统为使用环境:按钮、列表框、滚动条等组件接受Tcl命令,键盘和鼠标事件也可绑定到脚本。1990年末的稿本仍把Tk公开分发列作下一步计划,因此不能把完整图形工具包倒写成1988年的首版功能。
论文用一个21行的wish脚本展示目录浏览器。它先建立列表框与滚动条,再读取目录条目;用户按空格键,可浏览子目录或通过mx打开文件,按组合键则退出。这个例子把程序拆成数据显示、滚动控制和事件响应,各部分靠命令衔接。修改界面行为主要是调整脚本,已有组件仍能复用。作者强调的并非单纯减少字符数,而是让运行中的界面保持可编程性。
参考:[2]
Expect让既有程序接受自动对话
美国国家标准与技术研究院的唐·利布斯提供了另一种早期应用。其1991年论文介绍Expect,以Tcl为语言核心,另加启动进程、发送文字和等待输出的命令。许多Unix工具虽然能由命令行启动,运行过程中仍要求人回答问题;只把它们串成管道,不能完整处理这种交互。
Expect通过伪终端让被控程序维持熟悉的终端交互方式,再由脚本识别提示并决定下一步。论文讨论文件传输:脚本可等待连接提示、请求文件,并为失败设置重试或通知。这些步骤把“启动一个工具”扩展成“根据工具的回答继续操作”。作者还指出,遇到未知情况时可以交回人工控制。它展示了Tcl扩展机制的价值:新命令负责进程交互,原有变量与控制结构负责组织流程,无需为每项自动化工作重写语言。
参考:[3]
组件与脚本之间的分工
到1998年,奥斯特豪特在《计算机》杂志中把Tcl经验概括为组件和脚本的配合。他主张用系统编程语言建立数据结构与算法,再用脚本连接已有功能;图形界面、字符串处理和经常变化的操作流程,是这一方法适合的对象。这是开发者在特定技术环境中的论证,不能直接当成对所有语言效率的普遍定律。
他也承认代价:解释执行与动态检查可能降低速度,复杂算法和大量数据处理仍需要不同的技术安排。其集成电路工具例子尤其呼应了Tcl的起点,使用者通过脚本描述设计、控制分析与综合,而底层程序承担实质运算。Tcl的意义由此落在一种可操作的分工:应用提供能力,脚本决定如何调用和组合。早期语言实现、公开传播与图形扩展各有阶段,后来的跨领域用途建立在这个接口选择之上。
参考:[4]