真不敢相信我在称赞TCL(2008)

2020-09-06 23:49:58

所以前几天我自己定义了Tcl过程,并交互地使用它们,我很喜欢它,感觉就像是某种局部最优。这篇文章试图通过合理化的方式来应对喜欢TCL带来的创伤。我将首先讲述我迷人的冒险故事,然后我会进行合理化(跳过哦,那么个人化的第一部分,直截了当地说出要点),我会先说出我迷人的冒险经历,然后我会做合理化解释(跳过哦,那么个人化的第一部分,直截了当地说出要点)。

这就是我在做的事情。我有这块冲浪板。电路板上有一个芯片。芯片里有几个处理器。那里有一个处理器,它是一个内存映射设备,我使用CPU加载/存储命令与其通信。CPU本身就是一个JTAG目标,我通过一个探测器与其通信,发出那些加载/存储命令。我通过USB与探头交谈,使用的是一个甚至不能正确处理剪贴板的丑陋控制台。控制台支持TCL。

最终结果:为了与内存映射处理器对话,我必须使用Tcl。或者,我可以在图形调试器中使用内存视图窗口。只是有些地址在读取时会改变处理器状态(从后进先出中弹出一个项目,诸如此类)。所以不,内存视图窗口不是一个好主意--你必须瞄准特定的地址,而不是瞄准整个地址范围。该死,到底是谁想到用这么愚蠢的方式来定义硬件呢?为什么,是我干的。我一点也不知道,我正因此把TCL强加给自己。

不管怎样,我现在必须调试这个错误,据我所知,它可能在至少三个不同的软件或两个不同的硬件中,我不是很喜欢这5个选项中的任何一个,我想找出它已经是什么了。因此,在丑陋探测控制台上,我键入诸如word 0x1f8cc000(读取处理器状态)、word 0x1f8cc008 2(暂停执行)、word 0x1f8cc020 0x875(放置断点)之类的内容。我在大约2分钟内就厌倦了这一点,此时命令历史足够大,以至于在错误的自动完成命令时按Enter键的概率非常恼人。运行错误的命令很烦人,因为如果我破坏了处理器状态,我将需要几分钟来重现该状态,因为程序通过JTAG读取输入,这是最慢的。

因此,我认为这不是我要用这种方式处理的最后一个错误,因此现在是扩展我的环境的时候了,利用系统的脚本功能,为我的工作量身定做合适的工具。我讨厌那样,真的很讨厌。有什么比为单个开发者的大众市场开发开发工具更令人苦恼的事吗?当真正的、具体的问题太难解决时,程序员还有比倾向于解决简单的泛型元问题更可悲的弱点吗?对于一个丑陋的基础系统,有没有比插件和扩展更恶心的软件呢?但是你知道吗,我真的不记得0x1f8c断点地址是什么了。这个故事有一个十六进制值,对我的大脑来说太多了。那好吧。TCL。

我决定使用一个入口点过程PMEM,它将获得一个内存映射的处理器ID,因为它们很多,然后使用正确的基址调用几个函数中的一个,这样PMEM0PC就可以执行与PMEM_PC 0x1f8c0000相同的操作。嗯,在TCL中,这是最简单的。Tcl喜欢生成和计算命令字符串。更广泛地说,Tcl喜欢字符串。事实上,它喜欢它们胜过任何其他东西。在普通编程语言中,缺省情况下是变量和表达式。在Tcl中,它们是字符串。ABC不是变量引用-它是字符串。$abc是变量引用。A+b/c不是表达式-它是字符串。[expr$a+$b/$c]是表达式。你能相信吗?[表达式$a+$b/$c]。这不是很荒谬吗?

事实上,这是我对Tcl的主要应用之一:嘲笑它。我记得有一次和我的朋友一起读过布伦特·韦尔奇(Brent Welch)的Tcl/Tk巨著。当时停电了,最后一台UPS发出最后一声吱吱响的时间已经过去了。这本书就在那里,因为硬件人员用它来编写他们的Lovecraftian工具链的脚本。我们确实玩得很开心。我笑得热泪盈眶。即使人们对那些看着TCL书笑得前仰后合的极客有着惯常的恐惧/刻薄的评论,也没有破坏这一点。所以,嘲笑TCL,我对它的头号用途。另一个用途是偶尔使用硬件黑客编写Lovecraftian工具链的脚本。总体而言,我不太使用TCL。

Tcl的好处是,它仍然是一种动态语言,并且在这方面相当简洁,模引用和转义。因此,我使用tclsh<;脚本进入通常令人上瘾的编辑/测试周期。沿着这条路走了几分钟(我真的不知道N是什么),我已经看完了我的两个TCL屏幕,有趣的事情开始了。我真的开始调试那该死的东西了。$PMEM 0状态空闲$PMEM 0 bkpt 0 0xbff$PMEM 0 b

你不知道这让我有多高兴。是的,我知道,我反应过度了。我来告诉你:花几个月的时间调试各种硬件故障,你将能够认同通过这样的过程获得的价值1的扭曲概念。转念一想,我不知道我是否真的会推荐它。还记得我说过低级编程很容易吗?从根本上讲,这是一项相当肮脏的努力,但从另一个角度来看,这是一项相当肮脏的努力。我保证会把这件事写在博客上。这要归功于那些不断告诉我低级是那么容易的人。每次他们听我说,都会对退化的硬件设置满怀怨言,不管你怎么努力,都不管用。这是我欠自己的--我想在这里画上句号。为什么我要容忍在我最深刻的职业宣泄时刻经常被错误引用呢?

不管怎样,在短短N分钟内,我引导了一些类似于gdb的迟钝版本,就像我的程序的符号表被剥离时的工作方式一样。不过不要紧,我有addr2line可以帮你解决这个问题。关于我的延迟调试器前端,好的一面是它看起来像shell命令:废话。与之相对的是废话(";废话#34;,废话#34;废话#34;)。各位,这就是我认为Tcl作为一种工具命令语言的正确之处。

我来自流行中缀语言世界(C/Java/Python/Ruby/你能想到的)。Tcl的两个基本选择基本上把我吓坏了:

Tcl喜欢命令,而不是表达式。TCL:做这个那个,[表达式$这个+$那个]。POP INFIX:doit(";this";,";那个";),This+That。

因此,基本上,POP中缀语言(我使用这个术语的方式是最不带偏见的、事实的),POP中缀语言是针对编程而优化的(没错,它们是编程语言)。编程就是定义。定义一个变量会很容易使用,从变量计算复杂的表达式也很容易。Tcl针对使用进行了优化。大多数情况下,用户给出的命令很简单。命令名和文字参数很简单。如果您是一位经验丰富的用户,并且想要执行PMEM 0 bkpt[expr[PMEM 0 PC]+1],请继续执行此操作。有点难看,但另一方面,简单的命令真的、真的很简单。

最终,简单的命令成为用户最重要的东西,因为经验丰富的用户增加了个人快捷方式,这些快捷方式抽象了变量和表达式,因此您最终得到的是PMEM 0 bkpt nextpc或其他东西。显然,带有文字参数的平面函数调用就是交互式程序使用的全部内容。

我并不是说我会使用Tcl作为我下一个自制的Lovecraftian工具链的扩展语言(我考虑的更多的是用D语言做这个,并使用D作为我的脚本语言,因为它的编译速度足够快,而且显然也足够高级别)。(注:我不是说我会用Tcl作为我的下一个自制的Lovecraftian工具链的扩展语言(我更倾向于用D语言做这个扩展语言,因为它的编译速度足够快,而且显然也足够高级)。我还没有充分考虑过这一点,但是Tcl中怪诞的转义/引用仍然让我抓狂;我不想那样编程。我想说的是我喜欢互动的部分。具体而言:

很多人已经注意到,保持代码简短是极其重要的。更令人惊讶的是,许多人没有注意到这一点,可能是因为第1行比第5行听起来不那么令人信服。好的,想一想100K行和500K行的对比,你就会明白了。哦,还有那些肮脏的Perl/Shell一行程序让人怀疑这一点。我认识一个混蛋程序员,他使用2K bash一行程序作为他的首选武器。那么好吧,所以实际的规则必须是短码是好的,除非它是由一个混蛋写的。但这是相同的核心理念。

所以我们有架构师类型,他们喜欢很多相互委托工作的类,我们有启蒙类型,他们想要更少地写和读。而且,启蒙类型可以整天大肆宣扬Python、Ruby或Lisp如何让定义数据结构文字变得非常容易,或者使用元编程提取内容,或者其他架构师永远不会得到的东西。我完全同意这一点。

然后我们就有了互动的贝壳。在Python中,它是doit(#34;xx&34;,";yy&34;)。在Lisp中,它是(doit";xx&34;";yy&34;),或者(doit:xx:yy),或者(Doit Xxyy)(如果您将其设置为宏)。在Ruby中,如果您使用符号并省略括号,它就是doit:xx:yy。在不使用您自己的解析器的情况下,这差不多就是最好的结果,就像在doit;xxyy&34;中那样,当您确实需要在传递参数之前计算表达式,并且没有完全消除开销时,它可以吸收(更罕见的)情况。还要注意所有这些语言是如何使用()的,这会让您按Shift键,而不是按[]键。Ruby和Perl允许您省略(),但这会降低可读性。和[]一致保留给比函数调用更不重要的内容。

短代码的全部意义在于节省人的带宽,这是在一个不遵守摩尔定律、18个月内不翻一番的计算环境中唯一的事情。那么,哪种带宽最有价值呢?我来告诉你是哪一个。它是交互式命令带宽。这是因为(1)你经常与你的工具互动,(2)这种互动不是你想要做的,而是你想要做的,所以当它不是非常简单的时候,它就会让你分心,也会让人非常沮丧。(2)这种互动不是你想要做的,而是你想要做的,所以当它不是非常容易的时候,它就会让人分心,而且非常令人沮丧。

这就是为什么一个没有常用命令键盘快捷键的编辑器是一个愚蠢的垃圾,应该现在就去厕所。这就是为什么Matlab向量-[1 2 3]-比Python列表-[1,2,3]要好得多(您有没有注意到空格键比逗号更容易点击,您是开明的动态语言爱好者吗?大小确实很重要)。不要让我开始进一步包装数值Python的向量文字。

当你编程时,小开销是可以容忍的,虽然很糟糕,因为你只写了一次代码,当你在做的时候,你就会把注意力集中在任务及其细节上,比如语言语法。不过,当您与命令shell交互时,这是件大事。你不是在写程序--你是在看文件,解方程式,或者单步执行处理器。我有一个bug,我他妈的很着急,我必须尽快找出它已经是什么了,你认为现在是时候键入括号、逗号和引号了吗?!你这混蛋!。我的意思是,简短的代码很重要,简短的命令是必须的。

这就是为什么我从来没有喜欢过IPython或者闲置。也许Ruby可以做得更好,因为省略了父母等等。Ruby似乎较少受到语言律师伪正确思维的影响。但是基本的普通函数调用文字参数语法仍然达不到*sh或Tcl的纯度。嗯,shell是一种缺陷极大的编程语言,所以它甚至不能用于任何非交互式的东西。但是Tcl离编程语言又近了一步。这就引出了下一个问题:

许多调试器都有脚本语言。GDB有一家,绿山多家也有一家。特殊命令语言通常获得命令-语法-应该是容易的部分对它的命令arg…。然后他们就会把其他一切都搞错。也就是说,您通常没有任何或一些东西:数据结构、循环、条件和用户定义函数、在所有上下文中进行表达式求值的选项、与主机操作系统的接口,以及基本上可以使其成为编程语言的所有东西。或者你把所有这些东西都变成了一种你在其他任何地方都看不到的奇特的、有缺陷的形式。

我希望人们不要再这么做了。我理解为什么很多人做得很好--他们不懂任何不是第三代语言(大概是C++或Java)的语言。他们不知道脚本是如何工作的,除非是在理论层面上。他们知道如何构建一个大型软件系统,包括对象以及对象与对象工厂之间的关系。然而,在系统/外部世界的边界上,他们是无能为力的。在系统之外,我们的对象消失了。这是一个寒冷、多风、残酷的世界,到处都是用户、文件和其他东西。必须有一个AbstractInputParser来守卫进入我们漂亮、温暖、小系统的大门,嗯,实际上它是一个大系统,不,让它成为一个大系统。

这些都是被开明的动态语言爱好者嘲笑的建筑师。他们通常对脚本语言不屑一顾,认为它不严重,因此,当面临为他们的系统创建命令语言的需要时,他们会从创建一种不严重(也就是残缺的)语言的计划开始。即使他们想让它成为一种好的脚本语言,他们也从来没有考虑过制作一种好的脚本语言的考虑因素,也没有意识到嵌入现有的脚本语言是多么容易/多么有益。

因此,基本上我们有3GL人员,他们意识到命令应该很短(这是我们在这里做的一件简单的事情),但他们不认为你需要一种真正的图灵完整的编程语言来处理复杂的情况。我们有4GL人员,他们针对复杂的编程情况进行优化(什么是脚本语言-它是编程语言,该死的!),他们不在乎额外的参数或引号。

然后我们有了Tcl,它让简单的事情变得非常容易,并且可以扩展到处理复杂的情况(嗯,差不多,或者我认为是这样)。它不仅使普通函数变得简单--它为嵌套函数保留了[],其前缀形式为outcall arg[innercall arg]arg...。[]比()好。按下Shift键很糟糕。自定义键盘映射可以在不按Shift键的情况下输入父母,这完全是愚蠢的,因为你不能使用任何人的机器。这狗屎很重要,如果你整天都在编程,它就会变得很重要。

我不知道我是否会使用TCL。它不像典型的POP中缀4GL那样是一种编程语言。首先,[Expr]是个婊子。此外,还有一些我认为TCL缺乏的高级功能,比如闭包。不过,从语言学的角度来看,它也有有趣的一面。它几乎没有核心语法,这使得它比上述的POP中缀类更接近Lisp和Forth。因此,您可以使用Tcl,并为贵族索赔。当然,这样做只会惹恼最优秀的程序员;平庸的人不会知道你在说什么,因为只知道Tcl看起来不够像C,不配当一门语言的名字。

在将Tcl作为我的工具的脚本语言嵌入之前,我会考虑很多,因为语言问题和营销问题(你应该给他们一些足够接近C的语言,无论他们是客户还是室友)。因此,对我来说,实际的收获是适度的:

我不会再嘲笑Tcl可编写脚本的工具了。我理解是什么让作者选择了TCL,不,这不仅仅是一个坏习惯。在某种程度上,他们可能选择了当今最好的东西来权衡编程简易性/易用性(假设他们捆绑了一个交互式命令shell)。如果我需要自动化一些与这些工具相关的东西,我会比以前更愉快地钻研。情绪自我调整到此为止。

我会让它沉下去,然后试着找出你是否有更好的取舍。例如,如果Ruby有宏(不计算其输入的函数),您可以说doit x y而不生成x和y符号对象,这会强制您在它们前面加上冒号。我不知道这类宏应该如何在中缀语言中工作(这不是我想得太多,但仍然是这样)。无论如何,我一定会把TCL添加到我应该更好理解的事情列表中,以克服我的语言无知。作为一名业余编译器编写者,这似乎是我的职责之一。

不,我们在Tcl中没有闭包-关于这一点的一些讨论可以在http://wiki.tcl.tk/3330找到。是的,[expr]有点笨重-在Tcl8.5中,也可以使用前缀运算符:%Namespace import::tcl::mathop::*%*3[+1 2]9

我很高兴你抛开了语言偏见,公正地评估了TCL--当你这样做的时候,就很容易看到它对于某些任务是多么方便。

当然,我有偏见,但我也认为Tcl是开发Web应用程序的一种很棒的语言--因此,我对AOLserver很有亲和力。

当您将Web开发简化为消耗数据源中的位、转换字符串、将位输出到网络套接字…的简单过程时。Tcl的简单性真的让快速开发变得轻而易举,再加上AOLserver的Tcl pros库,可以简化一些常见的任务。

我希望更多的人给Tcl一个公平的评价,因为它是最古老的,也可以说是最成熟的脚本语言之一。

[...]хорошязыкtcl,我真不敢相信我会称赞tcl。Уменябылоченьпохожийопытивоспоминанияоттикль[...]。

嘿,谢谢你给我这个。我在10年前看过TCL,我对它不屑一顾,认为它是Python和Ruby(我现在甚至记不清为什么了)。无论如何,我最近一直希望我的主要图形用户界面编程语言(HyperTalk-http://www.runrev.com)的现代版本是a)更具可扩展性,b)支持多线程。本周,我偶然发现了另一篇为Tcl辩护的文章,进一步阅读后,我发现Tcl几乎是最具可扩展性的语言,并且以我认为线程应该实现的方式实现了线程。然后我开始阅读TCL8.6中新的面向对象核心特性,它们看起来是我见过的最吸引人的面向对象方式。

有趣的是,你正在做的事情。很久以前,我就对自然编程语言失去了希望,但我仍然很好奇,想找个时间看看你的东西。

只有在某些布局(如美国布局)上,[才比';(';)容易。例如,在瑞典语键盘上,仍然需要Shift键才能使用';(';,但要获得';[';,您需要右键ALT(也就是。Alt GR)。现在,哪一个更好呢?

这表明,在键盘之后设计语法是一件棘手的事情。一些国家的布局清楚地表明,它们是在没有考虑到编程需求的情况下做出的。我绝对认为应该有几个针对特定需求进行调整的布局(但要足够相似,以便不同的用户仍然可以使用)。程序员使用国家字符的频率低于操作员,那么为什么我们要被迫使用有专用键的键盘,但最多只能压缩3个重要的操作符字符呢?这就是为什么我们必须在键盘上工作,这些键盘上有专门的键,但最多只能压缩3个重要的操作符字符。

.