【问题标题】:What programming language features are well suited for developing a live coding framework?哪些编程语言功能非常适合开发实时编码框架?
【发布时间】:2011-12-14 14:27:39
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 好吧...为什么投反对票?
  • en.wikipedia.org/wiki/… 它有热代码加载。 OTP 框架的设计考虑到了这一点。
  • 这个问题可以用事实、参考资料和具体专业知识来回答。不知道为什么它被关闭了。我的目的当然不是征求辩论或争论。
  • 不确定您的问题为何被关闭,但已经有类似的框架。例如,我使用 clojure 以这种方式使用 compojure 和 leiningen 开发了一个 Web 应用程序。您可能还想看看 Racket。

标签: python ruby clojure lua livecoding


【解决方案1】:

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

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

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

【讨论】:

  • 这是一个非常有趣的观点,正是我希望获得的信息。
【解决方案2】:

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

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

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

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

【讨论】:

  • 乔恩,感谢您的见解。像 Erlang 这样的函数式语言对我来说非常陌生,所以我肯定需要研究这个消息传递的概念。有什么好的链接或图表说明这样的系统如何工作?
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

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

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

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

    【讨论】:

    • Clojure 看起来确实是一个不错的解决方案。它肯定需要转变思维,因为它来自 OOP 背景。似乎也有一个很棒的社区和大量的外部库。
    • Clojure 有这么多库的原因之一是它们中的许多都是 Java 库,它们封装在足够的 Clojure 中,可以为它们提供一个很好的类似于 Clojure 的 API。这是一个非常简单的任务,所以人们一直都在这样做......可能不久所有主要的 Java 库都会有 Clojure 版本。
    【解决方案5】:

    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
    

    【讨论】:

      【解决方案6】:

      作为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. 将新代码注入应用程序的能力(这种机制也使用协同例程,但我确信还有其他选择)。也有可能只注入一个修改过的片段,但它需要在函数级别,如果这个函数是其他函数的本地函数,你也需要包含它等等。

      【讨论】:

        【解决方案7】:

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

        该项目托管在GitHub,我已经发布了demo video,以及tutorial

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

        我还没有实现其他答案讨论的交换功能。相反,我总是将代码运行到完成或超时。我将实时编码设想为对测试驱动开发的增强,而不是作为破解实时应用程序的一种方式。不过,我会更多地考虑更换实时应用程序的各个部分可以让我做什么。

        【讨论】:

          【解决方案8】:

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

          【讨论】:

            猜你喜欢
            • 2011-01-13
            • 1970-01-01
            • 2010-12-31
            • 1970-01-01
            • 1970-01-01
            • 2010-10-07
            • 2012-02-29
            • 1970-01-01
            • 2010-10-16
            相关资源
            最近更新 更多