【问题标题】:Saving my running toplevel for later保存我正在运行的顶层以供以后使用
【发布时间】:2017-07-20 17:23:23
【问题描述】:

ocamlghci 顶层工作时,我经常为需要更好的词、绑定值、函数、加载的模块等建立重要的“上下文”。有没有办法保存所有这些并稍后重新加载,这样我就可以从我离开的地方继续?或者更好的是,将全部内容作为文本文件转储出来,可以重新加载或修改成可以编译成可执行文件的代码(例如通过添加 Main)?

【问题讨论】:

  • 我所希望的时代。一次又一次地设置“上下文”有时让我发疯。
  • 注意:我的赏金是关于 Haskell 的最佳答案,无论是 ghci 还是拥抱。

标签: haskell ocaml read-eval-print-loop ghci


【解决方案1】:

HOL light 的用户也有类似的需求,他们使用检查点程序来保存顶层的快照。请参阅 caml 邮件列表中的 this message,或 this HOL tutorial 的第 8 页。

一般来说,最好将定义保留为源代码,而不是二进制顶级快照。许多工具允许将 .ml 文件快速加载到顶层以便于实验(emacs 模式等)。请参阅 HOL 教程中的警告:

在 HOL 中开发大型证明时,应始终将证明脚本保留为 准备好重新加载的 OCaml 文件,而不是依赖于 ckpt。这将允许证明 以后可以修改,别人使用等。但是,制作起来很方便 中间快照,因此您不必加载大文件来进一步处理证明。 这类似于编程中的常见情况:你应该始终保持你的 完整的源代码,但不想每次使用都重新编译所有源代码 代码。

【讨论】:

    【解决方案2】:

    至少在 OCaml 中没有对此的内置支持。解决方案是使用 rlwrap 或任何其他 readline 包装器将您的输入历史记录到文件中。例如:

    > rlwrap -H mysession.ml ocaml
    

    缺点是这也会记录有语法错误的输入,所以你必须清除它。请注意,如果您在没有 -H 选项的情况下调用它,默认情况下 rlwrap 会自动将您的输入保存在 ~/.ocaml_history 中。

    【讨论】:

    • 我确实已经在我的 shell 中定义了一个别名 oc='rlwrap ocaml',所以这很容易做到,并且可以让我回到使用 #use 的位置......我猜我是什么d like 相当于 shell 的“env”命令,它会转储所有环境变量。
    【解决方案3】:

    在 Haskell 中,只需使用 :e file。这将打开标准编辑器并让您编辑一些文件。之后,使用:r 重新加载它。会自动重新编译。

    请注意,在此之后,您所有“临时”定义的功能都将丢失。有关详细信息,请参阅文档。

    【讨论】:

    • 另一种方法是在 Emacs 中以 haskell 模式工作,编辑文件并 C-c C-l 将其发送到下级进程。如果这是双向的,那就完美了。
    【解决方案4】:

    ghcihaskeline 用于命令行输入历史记录,因此您可以向上滚动以重复/编辑输入。您的输入历史通常记录在一个文件中,您可以在

    给出的目录中找到 ghci_history
    System.Directory.getAppUserDataDirectory "ghc"
    

    有各种命令可以探索“上下文”(:show bindings, :show modules, :def, ..),但它们的输出不足以重现您的会话(尽管无论如何都值得了解它们)。

    一般来说,将ghci 会话与打开的编辑器窗口相结合的建议是合理的:如果它不仅仅是一个一次性定义,即使只是出于调试目的,最好将其包含在要加载到 @ 的模块中987654327@,以便您可以重复使用。

    哦,如果“上下文”是指要加载的一些默认设置或模块,则在每个项目的基础上,还有ghciconfiguration file。也可以方便地定义您自己的 ghci 命令。

    【讨论】:

      【解决方案5】:

      在 ocaml 中,您可以构建自己的顶层。它至少解决了加载模块的问题。

      http://caml.inria.fr/pub/docs/manual-ocaml/toplevel.html#sec278

      ocamlmktop 命令构建包含用户代码的 OCaml 顶层 在启动时预加载。

      ocamlmktop 命令将一组 .cmo 和 .cma 文件作为参数, 并将它们与实现 OCaml 的目标文件链接起来 顶层。典型的用法是:

          ocamlmktop -o mytoplevel foo.cmo bar.cmo gee.cmo
      

      这将创建字节码文件 mytoplevel,其中包含 OCaml 顶级系统,加上三个 .cmo 文件中的代码。这个 toplevel 可直接执行,并由以下人员启动:

          ./mytoplevel
      

      这进入了一个常规的顶层循环,除了来自的代码 foo.cmo、bar.cmo 和 gee.cmo 已经加载到内存中,就好像 你输入了:

          #load "foo.cmo";;
          #load "bar.cmo";;
          #load "gee.cmo";;
      

      在顶层入口处。 Foo、Bar 和 Gee 模块不是 不过打开了;你还得做

          open Foo;;
      

      你自己,如果这是你想要的。

      【讨论】:

      • 我使用了这种技术,我在 Jane Street 博客上看到了一篇关于使用最有用/相关的东西构建“脚本”顶层的帖子。但我正在考虑的用例是探索性/实验性工作,我希望能够保持防止重新启动,或者转移到另一台机器并从我离开的地方继续。
      • 链接死了。下次请引用相关内容。
      【解决方案6】:

      这也一直困扰着我,所以我写了一个快速的 python/expect script 来在每个 ghci 会话开始时重播 ghci_history。

      它不是很精致。例如,它总是重播整个历史记录,这可能会很慢。

      【讨论】:

      • 总有这样的风险,即在会话中的某个时间你做了一个 :!你不想重复...
      • 可能应该过滤 :___ 命令。当然,你不能防范一切。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 2016-10-11
      相关资源
      最近更新 更多