哪些编程语言特性适合开发实时编程框架?
我想要建立一个“实时编程框架”。
我需要解释一下“实时编程框架”是什么意思。可以通过将实时编程和传统编程进行对比来说明。
简单来说,在传统编程中,你需要写代码,有时还要编译它,然后启动一个可执行文件或者在某种解释器中打开脚本。如果你想修改你的应用程序,就得重复这个过程。而实时编程框架则允许在应用程序运行时更新代码,并根据需要重新加载。也就是说,每当包含代码的文件发生变化,或者通过其他某种操作时,就会进行重新加载。这样,代码的变化就会在应用程序运行时立即反映出来。你不需要关闭程序、重新编译和重新启动它。
在这个例子中,应用程序是一个窗口应用,具有更新/绘制循环,可能使用OpenGL来处理图形,还有一个音频库来处理声音(比如SuperCollider?),理想情况下还需要一个网络库。
当然,我有自己喜欢的编程语言,不过我不确定这些语言是否适合这种架构。理想情况下,我会使用Python、Lua、Ruby或其他一些高级语言。不过,最近有朋友建议我考虑Clojure,所以我也在考虑这个选项。
我想知道,不仅哪些语言适合这种框架,一般来说,哪些语言特性可以使这样的框架成为可能。
8 个回答
要让这个工作正常,唯一需要的就是一种动态绑定的方式,比如在Erlang中使用消息传递,或者在很多其他语言中使用eval
。
如果你有动态绑定,那么你可以在不影响消息的情况下改变消息的目标,或者在不影响目标的情况下改变消息——前提是你在发送消息的时候,目标是已经定义好的,而你发送的消息也要在发送时是为这些目标定义好的。
当你要改变目标时,你只需要继续给旧版本发送消息,直到新版本准备好,然后再进行一次小的锁定更新,切换到新版本。同样,当你要改变消息时,你也只需要继续使用旧版本,直到新版本可用。
不过,能够随时热更新的代码还是需要专门设计的——这个应用程序必须足够模块化,确保替换一个组件的实现不会造成中断,而这只能通过仔细的编程来实现。
我在Lua中实现了一个实时编码的功能,这个功能是作为ZeroBrane Studio IDE的一部分。它的工作方式正如你所描述的那样,当代码发生变化时,会重新加载应用程序。我正在研究一些可能的改进,想在运行时修改值,以避免完全重新加载应用程序。这是一个纯Lua的解决方案,不需要对虚拟机进行任何修改。
你可以在这里看到目前实现的实时编码演示:http://notebook.kulchenko.com/zerobrane/live-coding-in-lua-bret-victor-style。
关于所使用/需要的语言特性,我依赖于:
- 能够中断/恢复正在运行的应用程序(这是基于debug.hook和error()调用实现的),
- 能够远程与(未修改的)应用程序进行交互(这是通过debug.hook、TCP交互和select()支持来检测主机机器是否发送了新请求来实现的,同时还使用协程在主应用程序和实时编码模块之间切换),以及
- 能够将新代码注入到应用程序中(这个机制也使用了协程,但我相信还有其他替代方法)。也可以只注入修改过的代码片段,但需要在函数级别进行,如果这个函数是某个其他函数的局部函数,你也需要把它包含进去,依此类推。
Clojure几乎具备了作为实时编码语言你可能需要的一切。主要亮点如下:
- 互动式REPL - 你可以直接与正在运行的程序进行互动。即使我在做“传统编程”,我也倾向于以互动的方式编写代码,之后再把喜欢的部分复制到源文件中。Clojure就是为了这种方式而设计的——你程序中的几乎所有内容都可以在运行时检查、修改和替换。
- 出色的并发支持 - 你可以轻松启动并发的后台任务,比如用代码
(future (some-function))
。更重要的是,Clojure的STM(软件事务内存)和对高性能不可变数据结构的重视,会处理一些更微妙的并发问题(例如,如果我在渲染过程中更新一个正在使用的数据结构,会发生什么呢?) - 丰富的库可用性 - 作为一种JVM语言,你可以从Java生态系统中获取所有需要的音频、视觉、输入输出或计算工具。用一两行Clojure代码就能轻松包装这些工具,从而获得你需要的函数的简洁接口。
- 宏 - 由于Clojure是一种同构语言,你可以利用Lisp的能力编写强大的宏来扩展语言。你可以在实时环境中构建你想要使用的确切语法,让编译器在后台完成所有复杂的代码生成工作。
- 动态类型 - 这方面的好处有不同的看法,但在快速和简洁地编写代码时,这无疑是一个巨大的优势。
- 活跃的社区和许多有趣的项目 - 你很可能会在Clojure社区中找到很多对类似实时编码技术感兴趣的人。
以下是一些你可能会觉得有趣的链接:
- 保罗·格雷厄姆谈Lisp - 超越平均水平
- 使用Overtone声音合成器的实时Clojure编码示例(SuperCollider的前端)