此操作失败:
user=> (:require [clojure.set :as set]) java.lang.ClassNotFoundException: clojure.set (NO_SOURCE_FILE:24)
而这成功:
user=> (require '[clojure.set :as cs]) nil
在加载clojure.set类。
上下文:前一行是从命名空间的源文件复制的。
我的主要问题是:我们做了什么改变,通过交换:和字符,现在允许后一个命令的成功?
我的第二个问题是,一般来说 – 什么是在REPL做事情的指导 – 与在正常clojure源文件中做事情相比?假设我们可以从LEININGEN项目的根目录加载我们的repl,所以至少jar在依赖子目录下的磁盘上可用。
Clojure(或LISP)一般工作
REPL或Read-Eval-Print循环是LISP设计的核心:
>读者将字符流转换为数据结构(称为Reader Forms)。
>评估者收集读者表单并对其进行评估。
>打印机发出评估器的结果。
因此,当您将文本输入到REPL中时,将通过每个步骤处理您的输入并将输出返回到终端。
阅读器表单
第一部分,clojure阅读器形式。这将是非常简短的,我鼓励你read或观看(part 1,part 2)。
clojure中的符号是可以表示特定值(如变量)的形式。符号本身可以作为数据传递。它们类似于c中的指针,只是没有内存管理的东西。
前面带有冒号的符号是关键字。关键字就像符号,但关键字的值总是自身 – 类似于字符串或数字。它们与Ruby的符号相同(它们也以冒号作为前缀)。
表单前面的引号告诉赋值器原样保留数据结构:
user=> (list 1 2) (1 2) user=> '(1 2) (1 2) user=> (= (list 1 2) '(1 2)) true
虽然引用可以应用于不仅仅是列表,它主要用于列表,因为clojure的计算器通常将执行列表作为一个函数式调用。使用’是对报价宏的速记:
user=> (quote (1 2)) ; same as '(1 2) (1 2)
引用基本上指定要返回的数据结构,而不是要执行的实际代码。所以你可以引用符号引用符号。
user=> 'foo ; not defined earlier foo
引用是递归的。所以里面的所有数据都引用:
user=> '(foo bar) (foo bar)
要获取(foo bar)的行为而不使用引号,可以使用eval:
user=> (eval '(foo bar)) ; Remember,foo and bar weren't defined yet. CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context,compiling:(NO_SOURCE_PATH:1) user=> (def foo identity) #'user/foo user=> (def bar 1) #'user/bar user=> (eval '(foo bar)) 1
还有更多的引用,但是这超出了这个范围。
需要
至于require语句,我假设你发现前者的形式:
(ns my.namespace (:require [clojure.set :as set]))
ns是一个macro,它会将:require表达式转换为您所描述的后一种形式:
(require '[clojure.set :as set])
以及一些命名空间工作。当在REPL中请求ns的文档时,将描述基本知识。
user=> (doc ns) ------------------------- clojure.core/ns ([name docstring? attr-map? references*]) Macro Sets *ns* to the namespace named by name (unevaluated),creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the Syntax of refer-clojure/require/use/import/load/gen-class respectively,except the arguments are unevaluated and need not be quoted. (:gen-class ...),when supplied,defaults to :name corresponding to the ns name,:main true,:impl-ns same as ns,and :init-impl-ns true. All options of gen-class are supported. The :gen-class directive is ignored when not compiling. If :gen-class is not supplied,when compiled only an nsname__init.class will be generated. If :refer-clojure is not used,a default (refer 'clojure) is used. Use of ns is preferred to individual calls to in-ns/require/use/import:
REPL使用