核心的JRuby开发者及书籍Practical JRuby on Rails Projects的作者Ola Bini为JVM开发了一种名为Ioke的新语言这种强类型动态基于原型的面向对象语言的目标在于给予开发者Lisp与Ruby的力量同时其拥有优雅小巧及规则的语法 Ola解释了Ioke的基本特性 Ioke是一个强类型动态基于原型的面向对象语言它很容易理解并且内置了对几种宏的支持对Ioke产生重要影响的语言有IoSmalltalkSelfRuby及Lisp(尤其是Common Lisp) Ioke目前构建在JVM上但我现在正考虑将其编译为JavaScript并在V上运行它 对于Ioke我有几个目标但最明确的一个是创建一种能将Ruby和Lisp中我所喜欢的那些特性组合起来的语言结果我发现Io已经实现了我所期望的大多数特性但有些地方实现的还不完美我还需要一种适合表达内部DSLs的语言我想要一种不会妨碍我反而会助我完成工作的语言根据以上几点我设计出了一个宏系统有些人可能会觉得这个系统很差劲 就Ioke的设计向Ola Bini提出了几个问题 看起来Ioke的关键特性之一就是它使用了基于原型的继承相比于占主导地位的基于类的继承你认为这种继承方式更强大么? 是的这是Ioke的一个特性但我不确定它是否是一个关键特性它在很大程度上改变了一些东西的设计我对此感到很满意我认为它实际上比基于类的系统要好既然开发Ioke的主要目的是为了我自己的使用那么我的感觉当然就很重要了 在Ruby中你可以使用单例类实现基于原型的OO同时我发现可以用这种方式清晰地对一些算法建模从功能上来说这没有什么明显的问题只要你想你总可以根据规约实现基于类的OO Ioke的一个主要指导原则是我所采取的决定并不是为了获得大家的认可仅仅因为基于类的OO占据着主导地位我就要使用它么?不一定吧确实有很多原因要求我们使用基于类的OO然而历史已经证明对很多应用来说这样做的意义并不大因此在Ioke的开发过程中我尝试了各种可能 因为在主流的语言中只有JavaScript采取了基于原型的继承你认为这种形式会被大家所理解并应用到实践中么? 实际上我认为基于原型的OO要比基于类的OO更自然也更容易理解我觉得基于类的OO是需要学习的而大多数人都会发现基于原型的OO更加直观前提是他们并没有被人灌输基于类的OO的所谓优点当然JavaScript可能并不是最好的参照物因为语言的基于原型的本质很容易被掩盖在该语言模型的边边角角之下这意味着大多数开发者实际上并不知道如何以正确的方式使用语言的这些特性 看起来Ioke从一开始就被设计成一种JVM语言你认为在最近一段时期内这会成为新语言的必经之路么? 我现在的想法是没必要从头构建一个新的虚拟机例如大多数新语言都带垃圾回收但我不理解为什么创建这些新语言的人要编写自己的GC呢这需要花费数月的时间而它只是一项重复的工作而已看看Ruby GC的那些问题吧显然这种想法对很多其他的事情也适用——尤其是库因此Ioke是一个JVM语言(但是Ioke的大部分内容是不依赖于JVM的你可以在另一个平台上重新实现这些内容这很简单核心内容非常小)我认为面向JVMCLRParrott及LLVM的语言都应该这样从头构建一个新的虚拟机几乎没有任何意义 你为Ioke实现的条件(Condition)系统看起来与Java的异常处理系统很相似但更灵活你能否提供几个例子来更好的说明其价值呢? 你可以认为异常所具有的功能是条件系统的一个子集有两点区别其一是从协议和抽象的角度来看异常所处理的东西不见得非得是异常或是错误警告也行大多数动态语言都有基于adhoc日志的警告系统但是如果你想做其他事情呢?在Ruby中你可以改变warn方法以抛出一个异常然而这仍然表示警告和异常的处理方式存在着分歧要么采取系统拦截要么采取线程拦截所有这一切仅仅是表面上的不同而已本质上是一回事 条件可以将这一切统一起来他们为上面提到的那些事情提供了一致的协议 条件所提供的功能是双重的首先就是restart它实际上几乎是完全独立的 所谓restart就是可以注册到块中的一些东西它基本上就是调用restart时所执行的一些代码块然后有一些方法会去调用命名的restart找到所有活动的restartrestart几乎可以看作是一种异常机制从范围上来说它是动态的 凭借条件我们可以为某些可能发生的事情注册处理器当条件发生时处理器可以选择去处理它或是把它交给下一个处理器处理然而这并不是堆栈展开(unwinding the stack)(至少现在不是)如果某个处理器想去处理某个条件(处理器也是一块代码)处理器上下文中相应的代码就会被执行执行的位置是动态的就在条件第一次发生的地方这意味着几个方法从某个条件发生的地方所调用的处理器实际上可以在相应的上下文中进行叠加 这没什么好奇怪的你可以在纯Ruby环境下完成这件事但如果标准库没有提供相应的支持那效果就要大打折扣了 在Common Lisp中这非常强大当你以交互的方式使用Common Lisp时条件的默认处理器会将你带到调试器中该调试器运行在错误发生的上下文中同时它可以完成处理器所能完成的事情——包括为变量提供新的值等等该调试器无需做任何特别的事情实际上它只是条件系统一个具体的用例而已 这实在是太强大了 你认为Ioke符合维护和重构的标准么?它是动态的又具有强类型你是怎么看的? 这很难说既然它很简洁同时又为这种简洁性提供了强大的特性那么它应该很容易维护同样的原因自动化的重构现在还不完善 就像Lisp一样Ioke提供了语法抽象有两种形式第一种是宏它就像是具有延迟参数的方法调用一样这些参数可用特殊的方式计算出来另一种是语法它与Common Lisp的defmacro差不多这两种方式为创建新的控制结构和定义新的抽象提供了可能语言本身是足够强大的你可以用其创建自己的方法类型如果你不喜欢关键字参数你可以定义一种新的不包含关键字参数的方法类型当前Ioke中的DefaultMethod可以用纯Ioke实现出来使用宏就行 对于Ioke的语法来说你遵循了Lisp和Smalltalk的方式例如space的使用一些人可能会觉得这么做会令那些熟悉C语言代码风格的开发者敬而远之你觉得是这样的么? 很早以前我就已经是一个CC++及Java开发者了我并没有觉得哪里不舒服Ioke的语法确实很麻烦之前有很多人都觉得这对于强大的抽象来说是个绊脚石当你有一个像以上那些语言的AST时你会发现要想实现语法宏是多么的不方便语法占很大的比重因为他们很不统一 因此大家可能在一开始会觉得它不那么自然但我真的很喜欢它我相信你也会的比如我发现Ioke的可读性就非常好而Java就不行了Ioke中没有太多的标点字符妨碍我们阅读下面对JavaRuby及Ioke进行了一下比较 ArraysasList(foo bar quux) map(new Function<String Pair<String Int>>(){ public Pair<String Int> call(String str){ return new Pair<String Int>(str strlength()); }})select // this gets too long ok? [foo bar quux]map {|str| [str strlength]}select {|n| n[] > } [foo bar quux] map(str [str str length]) select(second > ) 在这个例子中Ruby的区别不那么明显但它实际上也有很大的差别我发现当方法用空格分隔开时阅读起来会更方便使用圆点来终止表达式同样会造成很大的差别 因此作为Lisp的使用者这么说有点另类但语法真的是很重要我为Ioke设定的目标就是让其拥有Lisp和Ruby的力量同时保持其语法优雅小巧及规则 |