13

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

我应该解释一下“实时编码框架”是什么意思。我将通过将实时编码与传统编码进行比较来做到这一点。

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

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

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

我不仅想知道什么样的语言适合这种框架,而且一般来说,什么样的语言特性会使这样的框架成为可能

4

8 回答 8

5

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

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

在使用/需要的语言功能方面,我依赖:

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

使这项工作唯一需要的是一种动态绑定形式,例如,在 Erlang 或eval许多其他语言中的消息传递。

如果您有动态绑定,那么您可以在不影响消息的情况下更改消息的目标,或者在不影响目标的情况下更改消息—前提是在您尝试向其发送消息定义了目标,并且为您发送它的目标,您发送它时。

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

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

于 2011-10-26T02:20:40.333 回答
4

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

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

您可能会发现一些有趣的链接:

于 2011-11-01T09:20:47.190 回答
2

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

clojure以套接字 repl的形式很好地提供了这一点。这允许您远程附加到已部署的 tomcat 服务器(例如)上正在运行的代码版本。然后,您可以附加您最喜欢的支持 swank 的开发工具并破解。

于 2011-10-26T10:02:40.420 回答
2

Smalltalk is probably the best bet for this. As unlike the others, it has a whole IDE for live coding, not just a REPL

于 2016-04-17T14:20:38.047 回答
1

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

您可以使用任何 gui 工具包来做到这一点,尽管有些工具包会比其他工具包更难。使用 python 应该很容易,尽管缩进的东西 - 恕我直言 - 使交互式使用具有挑战性。我有理由确定大多数其他动态语言可以轻松做到这一点。

这样看:如果您的工具包允许您打开多个窗口,那么其中一个窗口没有理由不能成为交互式提示。您所需要的只是打开一个窗口的能力,以及某种“eval”命令,它运行作为字符串馈送给它的代码。

于 2011-10-25T23:42:11.747 回答
1

google appengine 上的 python 有 repot_api_shell.py。这不是一个完整的实时编码套件 - 带有 swank-clojure 的 emacs 上的 clojure 在将“实时编码”集成到日常开发节奏中方面已经有了更多的实际用途 - 但很多人没有意识到这是可能的在某些 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
于 2012-02-06T16:45:57.447 回答
1

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

该项目托管在GitHub 上,我发布了演示视频教程

The main features of Python that I used were abstract syntax trees and dynamic code execution. I take the user's code, parse it into a tree, then instrument any assignment statements, loop iterations, and function calls. Once I've instrumented the tree, I execute it and display the report or draw the requested turtle graphics.

I haven't implemented the swapping feature that other answers discuss. Instead, I always run the code to completion or a time out. I envision live coding as an enhancement to test-driven development, not as a way to hack on a live application. However, I will think more about what swapping out pieces of a live application would let me do.

于 2012-09-07T04:38:34.320 回答