哪些编程语言功能非常适合开发实时编码框架?

时间:2011-10-25 02:20:45

标签: python ruby clojure lua livecoding

我想构建一个“实时编码框架”。

我应该解释“实时编码框架”的含义。我将通过将实时编码与传统编码进行比较来实现。

一般来说,在传统编程中,您编写代码,有时编译代码,然后启动可执行文件或在某种解释器中打开脚本。如果要修改应用程序,则必须重复此过程。实时编码框架使代码能够在应用程序运行时更新并按需重新加载。每次更改包含代码的文件或执行其他操作时,可能会发生此重新加载。然后,代码中的更改将在应用程序运行时反映出来。无需关闭程序并重新编译和重新启动它。

在这种情况下,应用程序是一个带窗口的应用程序,它有一个更新/绘制循环,最有可能使用OpenGL进行图形处理,一个音频库用于声音处理(SuperCollider?),理想情况下是一个网络库。

当然我有首选语言,但我不确定它们中的任何一种都适合这种架构。理想情况下,我会使用Python,Lua,Ruby或其他更高级别的语言。然而,一位朋友最近建议将Clojure作为一种可能性,所以我也在考虑它。

我不仅想知道哪种语言适合这种框架,而且一般来说,哪种语言功能可以构成这样的框架

8 个答案:

答案 0 :(得分:5)

我在Lua中实现了一个实时编码功能,作为ZeroBrane Studio IDE的一部分。它完全按照您所描述的方式通过在代码更改时重新加载应用程序来工作。我正在研究可能的改进,以便在运行时修改值,以避免完全重新加载应用程序。它是一个纯粹的基于Lua的解决方案,不需要对VM进行任何修改。

您可以在此处看到当前实施的实时编码演示:http://notebook.kulchenko.com/zerobrane/live-coding-in-lua-bret-victor-style

就所使用/需要的语言功能而言,我依赖:

  1. 中断/恢复正在运行的应用程序的能力(这是基于debug.hook和error()调用),
  2. 远程与(未修改的)应用程序交互的能力(这是基于debug.hook,与select()支持的TCP交互来检测是否正在从主机发送新请求,以及协同程序在主应用程序和实时编码模块之间切换,和
  3. 将新代码注入应用程序的能力(这种机制也使用协同例程,但我确信有其他选择)。也有可能只注入一个修改过的片段,但它需要处于一个函数的级别,如果这个函数是某个其他函数的局部函数,你也需要包含它等等。

答案 1 :(得分:4)

使这项工作成为必要的唯一方法是动态绑定,例如,在Erlang中传递消息或在许多其他语言中传递eval

如果您有动态绑定,那么您可以在不影响消息的情况下更改消息的目标,或者在不影响目标的情况下更改消息 - 前提是 当您尝试发送目标时给它发送消息,并为你发送它的目标定义一条消息,当你发送它时。

更改目标时,您所要做的就是在新版本到位之前将消息提供给先前版本,然后执行小型锁定更新以转换到新版本。同样,在更改消息时,您只需提供旧版本,直到新版本可用。

易于热插拔的代码仍然必须这样设计,但是应用程序必须足够模块化,以替换组件的实现不会导致中断,而这只能来自小心编程。

答案 2 :(得分:4)

Clojure几乎拥有您作为实时编码语言可能需要的一切。主要亮点:

  • 交互式REPL - 这样您就可以直接与正在运行的程序进行交互。即使我正在进行“传统编程”,我也倾向于以交互方式编写代码,然后将我喜欢的位复制到源文件中。 Clojure的设计就是以这种方式工作 - 程序中的所有内容都可以在运行时检查,修改和替换。
  • 出色的并发支持 - 您可以使用(future (some-function))之类的代码轻松启动并发后台任务。更重要的是,Clojure的STM和对高性能不可变数据结构的强调将关注更微妙的并发方面(例如,如果我在渲染过程中更新实时数据结构会发生什么?)
  • 库可用性 - 它是一种JVM语言,因此您可以从Java生态系统中获取所需的所有音频,视觉,IO或计算工具。很容易将它们包装在Clojure的一行或两行中,以便您获得所需功能的简洁界面
  • - 由于Clojure是homoiconic language,您可以利用Lisp功能编写扩展语言的强大宏。您可以有效地构建要在实时环境中使用的确切语法,并让编译器完成在幕后创建完整代码的所有艰苦工作。
  • 动态类型 - 这样做的好处可以双向争论,但在尝试快速简洁地编写代码时,这无疑是一个巨大的好处。
  • 拥有大量精彩项目的活跃社区 - 您可能会发现很多人对Clojure社区中的类似实时编码技术感兴趣。

您可能会感兴趣的几个链接:

答案 3 :(得分:2)

在您的开发盒上进行“实时编码”非常好,但是直接与已部署的服务器进行交互的方式使其更接近“真实”。为此,您需要网络感知REPL

clojure socket repl的形式很好地提供了这个功能。这允许您远程连接到已部署的tomcat服务器上的代码的运行版本(例如)。然后,您可以附加您最喜欢的支持swank的开发工具并进行黑客攻击。

答案 4 :(得分:1)

Tcl已经有了这样的事情。例如,您可以编写一个gui程序,创建一个具有交互式提示的单独窗口。从那里,您可以重新加载代码,输入新代码等。

您可以使用任何gui工具包执行此操作,但有些工具包会比其他工具包更难。使用python应该很容易,但缩进的东西 - 恕我直言 - 使交互式使用具有挑战性。我有理由相信大多数其他动态语言可以毫不费力地做到这一点。

以这种方式看待它:如果你的工具包允许你打开多个窗口,那么没有理由为什么其中一个窗口不能成为交互式提示。您只需要能够打开一个窗口,以及某种“eval”命令,该命令将代码作为字符串运行到​​它。

答案 5 :(得分:1)

google appengine上的python有repote_api_shell.py。这不是一个完整的实时编码套件 - 对于emacs w / swank-clojure上的clojure在将“livecoding”整合到日常开发节奏中有更多的现实使用 - 但是很多人都没有意识到这是可能的在某些python环境中。

$ PYTHONPATH=. remote_api_shell.py -s dustin-getz.appspot.com
App Engine remote_api shell
Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)]
The db, users, urlfetch, and memcache modules are imported.

dustin-getz> import models
dustin-getz> models.BlogPost(title='a modern take on automated testing', link='https://docs.google.com/document/pub?id=1DUxQogBg45rOTK4c5_SfEHiQcvL5c207Ivcy-gDNx2s', dont_publish_feed=False).put()

dustin-getz> items = models.BlogPost.all().filter('dont_publish_feed =', False).order('-published_date').fetch(100)

dustin-getz> len(items)
58

dustin-getz> for item in items[:5]: print item.title
a modern take on automated testing
Notes: Running a startup on haskell
the [un]necessity of superstar middle management in bigcos
"everything priced above its proper value"
stages of growth as a software engineer

答案 6 :(得分:1)

我正在为PyDev的Python编辑器开发一个实时编码功能。它的灵感来自Bret Victor的Inventing on Principle talk,我实现了一个程序状态显示以及乌龟图形。当您在Eclipse中键入Python代码时,它们都会更新。

项目托管在GitHub上,我发布了demo videotutorial

我使用的Python的主要功能是抽象语法树和动态代码执行。我获取用户的代码,将其解析为树,然后检测任何赋值语句,循环迭代和函数调用。一旦我对树进行了检测,我就会执行它并显示报告或绘制所请求的龟图形。

我没有实现其他答案讨论的交换功能。相反,我总是运行代码完成或超时。我认为实时编码是对测试驱动开发的增强,而不是一种破解实时应用程序的方法。但是,我会更多地考虑更换实时应用程序的内容会让我这么做。

答案 7 :(得分:1)

Smalltalk可能是最好的选择。与其他产品不同,它有一个完整的IDE用于实时编码,而不仅仅是一个REPL