2010-12-13 47 views
4

对不起,很长的文章,但这个论坛总是要求用例:-)。Clojure REPL哲学和实用程序应用程序

我经常被要求为我的组织编写实用程序应用程序(GUI和命令行)。我最常用Java和最近的Scala写这些。

Clojure(和其他Lisp)中的“哲学”似乎以REPL为中心,我必须同意它创造了一个很好的开发环境,但我显然不能生产那些需要用户“安装Clojure和Clojure-contrib,然后将该实用程序解压缩到硬盘上的目录中,使用以下类路径从命令行启动Clojure,...“。用户不关心该实用程序是用Clojure编写的。他们只想指向并点击,或者至多键入“java -jar Utility.jar - ?”在命令行上。

我的问题围绕着编译和将应用程序分离到许多名称空间/文件中。

我知道main方法必须是在包括(gen-class...)命令(或在ns命令:gen-class子句)一个Clojure的文件。对于额外的Clojure文件,我是否也应该这样做?还是应该将它们保留为打包在JAR中并由main文件加载的源代码?在开发过程中如何测试REPL中的附加文件?我一直在使用leiningen,cake和maven来构建自包含的JAR(包含解包的clojure.jar,clojure-contrib.jar和commons-cli.jar文件),但到目前为止,我一直在写我的代码与main方法相同的文件中。

回答

1

无论您将.clj AOT编译为.class,还是让Clojure在运行时动态执行,都由您决定。总的来说,我发现在开发过程中避免使用AOT,并且只使用AOT作为性能增强器,以适应在运行中编译.clj的代价不合理的情况(有限的环境,例如Google App Engine或启动时间的实用程序是至关重要的)。对于长时间运行的服务器进程,AOT编译没有太多优势。

在开发时间使用AOT类时有很多复杂性,这些都是特定于不同开发环境的。

AOT的一个缺点是,你编译的类可能与未来版本的Clojure不兼容,并且比你的clj文件更可能不兼容。随着时间的推移这可能会变得更加重

1

当涉及到的分离,我让他们在不同的命名空间/文件:

  • 一为:gen-class命名空间,包含-main和所有其他类似Java的东西。
  • 所有函数的其他名称空间。

理想情况下,你的主要应该包含正好从另一个命名空间中的函数调用,或者是一些逻辑,用于评估或args的重新包装。

你的问题似乎很类似于逻辑代码和UI代码之间的分离。您可以看到名为:gen-class的命名空间只是程序提供给Java代码的界面,仅此而已。


当涉及到公用事业(如命令行,或Swing应用程序等),还有与Java一般,因为JVM的一个麻烦的开始时间。

现在,你可以通过使服务器应用程序运行REPL在后台所有的时间解决这个问题,并说,不知何故收到一个S-expr来进行评估,并返回结果。这可以作为一个简单的Web应用程序来完成,它接收一个s-expr作为URL参数,并返回结果。现在,你可以使用普通的Java创建所有实用程序,甚至使用wget创建bash,因为所有你需要做的就是访问一个URL(假设带有repl的服务器在后台运行)。

很有可能像这样的东西已经存在,所以如果有人知道 - 评论是非常值得欢迎的。

哦,还有一件事,在REPL webapp的暴露可能必须要封闭外界的端口,以防止Clojure的-注射:d

+0

不能做一个Web应用程序。我们在全国各地都有服务器 - 在防火墙之外,我需要在公司和总部运行公用事业。启动时间从未成为Java应用程序的问题;大多数是DB工具,它们会在查询等方面做很多事情 - 数据库通常是瓶颈。不过谢谢你的回答。 – Ralph 2010-12-13 21:57:27

+0

@Ralph:好的,我在下半部分添加了一条分隔与您的问题相关的上半部分,这不适用于您的情况。 – 2010-12-13 22:00:13