9.2 Paul Tagliamonte 访谈
Paul是Debian开发人员,在Sunlight基金会工作。2013年他创建了Hy,作为Lisp的爱好者我随后加入了这个美妙的冒险。
最初你为什么会创立Hy项目?
最初,我创立Hy这个项目是源自一次关于如何将Lisp代码编译成Python而不是Java的JVM(Clojure)的谈话。不久之后,我开发了Hy的第一个版本,有些像Lisp,甚至执行起来就像Lisp一样,但它却运行缓慢。我是说,非常慢。比原生的Python要慢一个数量级,因为这个Lisp运行时本身是用Python实现的。
非常受挫,我几乎要放弃了,继续推进只是因为向一个同事承诺了要用抽象语法树实现这个运行时,而不是用Python实现。这个疯狂的想法实际上激发了整个项目。这发生在2012年假期前不久,所以我整个假期都在忙着开发Hy。大概一周之后,做出来的东西和现在的Hy代码库已经非常接近了,大部分Hy的开发人员甚至已经知道如何围绕这个编译器进行开发了。
就在实现了一个简单的Flask应用之后,我在波士顿Python大会上做了一场关于这个项目的演讲,并收到了热烈的反馈,非常热烈。实际上,我已经开始将Hy作为讲解Python内部机制的一个很好的途径,例如,REPL是如何工作的3,PEP 302导入钩子,以及Python抽象语法树,都是关于用代码写代码这一概念的很好的诠释。
在那次演讲之后,我对有些小节不太满意,所以我重写了编译器的很多代码,以解决一些流程上的原则问题,从而得到当前这个代码库的迭代,它已经运行了相当长一段时间了。
此外,Hy(这门语言)是帮助人们理解如何阅读Lisp代码的一种很好的方式,因为这样他们就可以在自己熟悉的环境中舒服地使用s表达式(甚至使用他们已经依赖的一些库),平滑地过度到其他(真正的)Lisp,如Common Lisp、Scheme或者Clojure,以及试验一些新的想法(如宏系统、单调性和没有语句的概念)。
你是怎么知道该如何正确地使用抽象语法树的呢?对于查看抽象语法树的人,有什么提示、技巧和建议吗?
Python的抽象语法树是很有意思的。它并不是非常私密(事实上,它明显不是私密的),但是也并非公开的接口。版本之间并不保证稳定,事实上,Python 2和Python 3之间有些非常烦人的不同,甚至Python 3的不同版本间也有不同。此外,不同的实现对抽象语法树的解释也不同,甚至有独特的抽象语法树。更不用说Jython、PyPy或者CPython要以一致的方式处理Python抽象语法树。
例如,CPython能够处理抽象语法树实体的轻微的乱序(通过lineno 和 col_offset)。然而PyPy会抛出一个断言错误。尽管有时令人抓狂,但抽象语法树一般都很正常。构造一个可在不同Python实例上运行的抽象语法树不是完全不可能的。通过一两个条件,就可以使这个工具变得非常顺手,不过创建一个在CPython 2.6到3.3以及PyPy都能运行的抽象语法树还是挺让人抓狂的。
抽象语法树的文档极度缺乏,所以大部分知识来自于对生成抽象语法树的逆向工程。通过编写简单的Python脚本,可以使用类似import ast; ast.dump(ast.parse("print foo"))这样的代码生成等价的抽象语法树,来辅助理解。伴随着一些猜测和坚持,最终形成了对这种方式的基本理解。
将来我也许会将我对抽象语法树模块的理解记录下来,但是我发现写代码是学习抽象语法树的最好方式。
Hy现在处于什么状态?未来的目标是什么?
Hy仍然在开发中。仍有一些需要解决的细小问题以及需要修复的一些bug,以便使Hy同其他的LISP-1的变种没有显著区别。这是一项艰巨的任务,但其时机已经成熟。
我还希望能保持Hy的效率,目前看还行。
长期来说,我希望Hy能成为一个教学工具,用来解释一些即便对有经验的Python支持者来说也比较陌生的概念。我也希望它能证明,对这些我们尽力提供的工具产生兴趣可以令这些Python的支持者得到更多乐趣。
我希望人们可以将Hy看做是一个绝好的教学工具,以便能让人们对Common Lisp、Clojure或者Scheme产生兴趣。我希望人们回家之后能读一下为什么Lisp的变量这样工作,以及在他们的日常编码工作中如何借用这种哲学思想。
Hy和Python的互操作性如何?代码分发和打包呢?
绝对是极好的、令人震惊的互操作性。事实上,甚至可以通过pdb调试Hy而无需任何修改。为了彻底测试它,我写乐Flask应用、Django应用和各种模块。Python可以导入Python,Hy可以导入Hy,Hy可以导入Python,Python可以导入Hy。这是Hy非常独特的地方,即使是Clojure也无法做到这一点,因为Clojure的互操作是绝对单向的(Clojure可以导入Java,但是Java导入lojure却有问题)。这也充分证明了我们的工具有多强大。
Hy几乎是直接将Hy代码(以s表达式)转换为Python抽象语法树。这个编译步骤也证明了生成字节代码相当明智(以至于通过看由Python抽象语法树生成的Python源代码就可以调试Hy的一些讨厌的问题),这也意味着Python在处理非Python语言编写的模块时非常困难。
Common Lisp主义,如完全支持将*earmuffs*和using-dashes翻译成Python的对等物(在这种情况下,*earmuffs*会变成EARMUFFS,using-dashes会变成using_dashes),这意味着Python处理它们并不难。
确保良好的互操作性是我们最高优先级的工作之一,所以如果你发现任何bug,请给我们看bug。
选择Hy的优点与缺点各是什么呢?
这是个很有意思的问题,我立场并不中立,所以我持保留态度。
青出蓝但胜于蓝,Hy通过一些特殊的方式表现得比Python要好。因为我们做了大量的努力去使Python不同版本间的行为更顺畅以使新的Python 3的future实现得更快。主要通过使用如Python 2中future的除法,以及确保两个版本间语法的标准化这类方式实现。
此外,Hy有一些Python很难处理的东西(即使有抽象语法树这样优秀的模块),就是一个完整的宏系统。宏是非常特殊的函数,它能在编译阶段修改代码,不同于有ast.NodeVisitor作为一级函数的语言。这使得创建你的特定领域语言(DSL)非常简单,特定领域语言由基本语言(在这里就是Hy/Python),以及额外的许多表现力独特、代码简洁的宏组成的。
许多时候,聪明的特定领域语言可以替代语言来扮演这个角色,如Lua。
至于说缺点,给予Hy力量的东西也可能会伤害它。从社会层面而非技术层面说,凭借s表达式编写的Lisp,背负着难于学习,、阅读和维护的恶名。出于对Hy复杂性的恐惧,人们可能不愿意工作于使用Hy的项目上。
Hy就是人们由爱到恨的Lisp——Python开发者不喜欢它的语法,Lisp开发者不愿意使用Hy,因为它是Python。Hy直接使用Python的对象,所以对于经验丰富的Lisp开发者可能会对基础对象的行为感到惊讶。
希望人们可以透过Hy的语法,并考虑将其利用到项目中,从而拓展其视野,并探索Python中一些之前未曾接触的部分。
1如果还没有,值得考虑一下。
2尽管它有一些限制性。
3code.InteractiveConsole
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论