如何流式传输程序代码?

发布于 2024-10-05 11:22:21 字数 581 浏览 0 评论 0原文

我最近一直在学习Lisp(不同程度的Scheme、Racket和Clojure),并且阅读了著名Playstation开发商Naughty Dog的相应文献。

这篇 Gamasutra 文章 提到他们的流引擎除了游戏之外实际上还在游戏代码中进行流传输数据。 现在,他们有一种名为 GOAL 的 Lisp 方言,并广泛使用。 我知道 Lisp 的“代码即数据”,尽管我还没有完全理解这个概念。所以,我想知道流代码的能力是否是 Lisp 数据或编译机器代码的代码的属性,而不是可以在多种语言中使用的通用设计模式?

有人可以向我指出有关该主题的文献吗?

奖励:有人可以向我指出维基百科文章?

I've been learning Lisp recently (Scheme, Racket and Clojure to various extents) and have read the corresponding literature on famous Playstation developer Naughty Dog.

This Gamasutra article mentions that their streaming engine actually streams in game code in addition to game data.
Now, they have a dialect of Lisp called GOAL which they use extensively.
I know of Lisp's "Code as Data", although I have yet to grok this concept fully. So, I was wondering if the ability to stream code is a property of their code being Lisp data or compiled machine code, as opposed to being a generic design pattern that can be used in many languages?

Can someone point me to literature on this topic?

Bonus: Can someone point me to literature on long-term-listening-compilers as mentioned in the Wikipedia article?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

请你别敷衍 2024-10-12 11:22:21

Lisp 语言中的“监听器”是 REPL(读取评估打印循环)。侦听器通常提供多种服务,例如集成调试器、命令历史记录、命令解释器等。在许多情况下,监听器在正在使用的 Lisp 内部运行。在某些情况下,输入到 REPL/Listener 的所有代码都会在执行之前进行编译(例如 Clozure CL、SBCL)。如果不是这种情况,可以根据需要编译代码(请参阅 Common Lisp 中的 COMPILE 或 COMPILE-FILE 函数)。

这里我猜测开发环境是在 Allegro Common Lisp 中实现的,运行时在 Playstation 上运行。开发环境提供了一个与运行时对话的接口,并允许编译代码并将其下载到运行时中。我猜测编译器不是在 Playstation 上运行,而是在开发环境中运行。然后,侦听器还提供查看 Playstation 上正在运行的应用程序状态的功能,包括符号表。因此,我们可以将开发环境连接到 Playstation 正在运行的应用程序,并且可以与之交互,包括更改数据和代码。

由于典型的 Lisps 可以在运行时加载源代码和编译后的代码,因此“流式传输”代码并不那么困难。它只是意味着当玩家在游戏中移动时加载代码(可能在后台)。如果代码以某种方式组织,那么一旦不再需要它也可以被垃圾回收。例如,如果游戏中的“房间”是一个对象,并且该房间通过名称指向各种功能,则如果玩家在房间中,则可以根据需要自动加载这些功能。如果玩家离开房间,代码可以自动或半自动卸载。在典型的 Lisp 中,垃圾收集器会收集未引用的代码。在游戏中,这可能不是 GC 的任务,而是其他一些更“手动”过程的任务。这将是 GOAL 运行时的一项功能。与无法对卸载的代码进行垃圾收集的普通 JVM 进行比较(AFAIK)。

A 'Listener' in Lisp speak is a REPL (Read Eval Print Loop). Listeners usually provide several services like integrated debugger, command histories, command interpreters, and more. In many cases the Listener runs inside the Lisp one is using. In some cases all code typed to a REPL/Listener is compiled before executing (examples are Clozure CL, SBCL). If that is not the case, the code can be compiled on demand (see the COMPILE or COMPILE-FILE functions in Common Lisp).

Here I would guess that the development environment was implemented in Allegro Common Lisp and the runtime runs on a Playstation. The development environment provides an interface to talk to the runtime and allows to compile code and to download it into the runtime. I would guess that the compiler does not run on the Playstation, but inside the development environment. The Listener then also provides functionality to look at the state of the running application on the Playstation, including the symbol table. So, one connects the development environment to the Playstation's running application and one can interact with that, including changing data and code.

Since Lisps typical can load both source and compiled code at runtime, 'streaming' code is not that difficult. It just means that one loads the code (possibly in the background) while the player moves around in the game. If the code is organized in a certain way, it can also be garbage collected once it is no longer needed. For example if a 'room' in a game is an object and the room points to various functions by name, the functions can be autoloaded on demand if the player is in the room. If the player leaves the room the code can be automatically or semi-automatically unloaded. In a typical Lisp the garbage collector would collect unreferenced code. In a game that might not be a task of the GC, but of some other more 'manual' process. This would be a functionality of the GOAL runtime. Compare that with the stock JVM which could not garbage collect unloaded code (AFAIK).

〗斷ホ乔殘χμё〖 2024-10-12 11:22:21

他们的流引擎或多或少复制了 DLL (windows)、SO(Linux) 或 Dylib 加载在更通用的操作系统上所做的事情,除了他们自己实现它之外,并没有那么有趣。这与他们使用的语言没有任何关系。就长期监听编译器而言,这是我第一次听到编辑并继续归因于编译器,这通常是调试器的一个功能。

Their streaming engine more or less replicates what DLL (windows), SO(Linux), or Dylib loading does on more general OSes, and isn't all that interesting outside of the fact that they implemented it themselves. It doesn't have anything to do with the language they use. As far as long term listening compilers go that is the first time I have heard edit and continue ascribed to the compiler it is usually a feature of the debugger.

甜中书 2024-10-12 11:22:21

我在 Common Lisp 中对这类事情进行了一点点的研究,你的代码可能看起来像这样:

on connection:
   read Lisp form
   eval Lisp form
   close connection

它在概念上与粘液并没有太大的不同。

另请注意,由于 Common Lisp 的性质,热插拔代码并不是什么大问题。

I've mucked about with this sort of thing a very little bit in Common Lisp, and what your code might look like is this:

on connection:
   read Lisp form
   eval Lisp form
   close connection

It's not massively different conceptually from, say, slime.

Also note that due to the nature of Common Lisp, hot-swappable code is no biggie.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文