Clojurescript第一步疑惑和问题
Clojurescript first steps doubts and problems
我刚开始接触clojurescript,有很多疑惑,我想做的只是用clojurescript解决基本问题,暂时与web无关。
如果我去掉 Web 开发部分,用 Clojure 和 ClojureScript 编码会有什么区别吗?还是完全一样?
另外我想知道我是否可以使用命令 cat DATA.lst | clj program.cljs 到 运行 clojurescript 代码?还是编译器不同?如果是这样,我如何编译 clojurescript 代码
关于官方页面,它提供了一个非常有限的hello world!,下面这行是页面提供的编译clojurescript的命令。
clj --main cljs.main --compile hello-world.core --repl
如果我使用 --repl 命令它只打印一些东西,如果我删除它,控制台停止打印结果,问题是,它打印的东西非常不同,如果打开另一方面,它使用 clojure cat DATA.lst | 命令编译代码。 clj program.cljs
它完全是面向网络的,所以它一直在我的浏览器中打开并显示与该主题相关的内容,这与我的案例无关。
我想知道如何执行我的代码,以确保我是为 clojurescript 而不是 clojure 编译的(以防它们不同)
有必要创建公开页面的复杂项目树,或者我可以通过简单的方式将其放在文件夹中。 (这就是我使用 clojure 的方式)?
我正在尝试编译的代码是下面的代码,很简单,我只是读取标准输入并按照我希望的方式处理信息
(defn get-data []
(let [input-string (read-line)]
(lazy-seq
(if (seq input-string)
(cons (clojure.string/split input-string #" ") (get-data))
nil))))
(defn get-mod [data]
(lazy-seq
(if (seq data)
(cons (map (fn [x] (rem (Integer. x) 12)) (first data))
(get-mod (rest data)))
nil)))
(defn main []
(def data (rest (get-data)))
(def module (get-mod data))
(println module))
当我使用给出官方 clojure 脚本页面的代码行时,vscode 在终端中给我的结果如下:
WARNING: When invoking clojure.main, use -
ClojureScript 1.10.758
cljs.user=> 33
cljs.user=> 50
57
54
69
cljs.user=> 72
80
68
56
63
cljs.user=> 47
71
40
56
59
52
cljs.user=> 74
59
78
66
cljs.user=> 74
62
94
82
77
cljs.user=> 50
66
57
54
cljs.user=> 68
72
63
44
56
cljs.user=> 60
48
79
75
63
cljs.user=> 67
51
58
cljs.user=> 66
78
51
60
54
cljs.user=> 56
52
49
25
61
cljs.user=> 36
53
45
48
cljs.user=> 58
61
42
49
54
cljs.user=> 76
80
68
68
60
cljs.user=> 63
58
54
51
58
cljs.user=> 42
50
54
54
58
cljs.user=> 50
59
54
62
66
54
cljs.user=> 65
41
61
49
56
cljs.user=> 27
48
43
55
cljs.user=> 35
43
35
47
28
cljs.user=> 49
44
52
32
44
cljs.user=> 74
58
65
70
53
cljs.user=> 52
56
40
60
52
cljs.user=> 54
69
69
62
cljs.user=> 52
49
56
76
cljs.user=> 58
66
50
70
50
cljs.user=> 82
70
73
77
70
cljs.user=> 56
51
63
35
cljs.user=> 59
67
52
71
79
cljs.user=> 72
72
76
84
57
cljs.user=> 66
61
58
61
cljs.user=> 49
32
52
32
cljs.user=> 64
33
52
64
49
这与我在 stdin 中输入的信息完全相同,也就是说,它没有执行我的代码指示的内容,它应该提供的内容如下:
((2 9 6 9) (0 8 8 8 3) (11 11 4 8 11 4) (2 11 6 6) (2 2 10 10 5) (2 6 9 6) (8 0 3 8 8) (0 0 7 3 3) (7 3 10) (6 6 3 0 6) (8 4 1 1 1) (0 5 9 0) (10 1 6 1 6) (4 8 8 8 0) (3 10 6 3 10) (6 2 6 6 10) (2 11 6 2 6 6) (5 5 1 1 8) (3 0 7 7) (11 7 11 11 4) (1 8 4 8 8) (2 10 5 10 5) (4 8 4 0 4) (6 9 9 2) (4 1 8 4) (10 6 2 10 2) (10 10 1 5 10) (8 3 3 11) (11 7 4 11 7) (0 0 4 0 9) (6 1 10 1) (1 8 4 8) (4 9 4 4 1))
Clojure 是 运行 在 Java 虚拟机上的一种语言。 ClojureScript 在外观和功能上是一种类似的语言,但它被编译为 JavaScript 并将 运行 on JavaScript 运行例如 NodeJS 或 Web 浏览器中的 JS 引擎。因为他们针对的运行次不同,所以有区别,这里解释一下:https://www.clojurescript.org/about/differences
像 readline
这样的一些函数在 ClojureScript 中不可用,您需要使用 JS 互操作编写您自己的函数,创建您自己的事件处理程序。您可以使用 core.async 库之类的东西为 Node 编写阻塞和等待输入的代码,但这远远超出了初学者的水平。
您的代码实际上看起来可以在 Clojure 中运行,因此,除非您有某种理由坚持使用 Node 并避免使用 JVM,否则我会坚持使用普通的 Clojure 以利用所有可用资源来学习该语言。
这是一个简单的示例项目和程序,它对从标准输入输入的数字求和:
项目结构如下:
.
├── data.txt
└── src
└── demo
└── core.clj
主程序:
(ns demo.core)
(defn -main [& args]
(loop [total 0] ;; initialize a total sum to 0
(if-let [line (read-line)] ;; keep any input as `line`, otherwise else branch
(let [n (read-string line)] ;; parse `line` to number
(recur (+ n total))) ;; loop, 'updating' the total
(println total)))) ;; else branch: no input, print the total so far
数据文件data.txt
:
11
22
33
... 最后是一个示例 运行:
cat data.txt | clj -m demo.core
WARNING: When invoking clojure.main, use -M
66
听起来你真的想为这个项目使用普通的 Clojure 而不是 ClojureScript。
除了上面的好答案,您可能对这两个可以帮助您入门的模板项目感兴趣:
- Clojure 模板项目:https://github.com/io-tupelo/clj-template\
- ClojureScript 模板项目:https://github.com/io-tupelo/cljs-template
更新
你想在CLJS中解决的“基本问题”是什么???你能补充更多细节吗?
ClojureScript 作为一种语言几乎可以做 Clojure 可以做的任何事情。 JVM 与浏览器中的 JavaScript 运行 相比,最大的不同在于:
JVM 可以处理超过一千个线程。 JS 只有 1 个线程(尽管你可以使用 clojure/core.async and/or 回调伪造多个线程)。
CLJ 具有真正的动态变量(即 Clojure var
)。 CLJS 变量在运行时是静态的。
I/O 在 JVM 上是无限的。浏览器和 JS 不适用于磁盘 I/O,并且在网络上受限 I/O。
- 中的详细差异列表
我刚开始接触clojurescript,有很多疑惑,我想做的只是用clojurescript解决基本问题,暂时与web无关。
如果我去掉 Web 开发部分,用 Clojure 和 ClojureScript 编码会有什么区别吗?还是完全一样?
另外我想知道我是否可以使用命令 cat DATA.lst | clj program.cljs 到 运行 clojurescript 代码?还是编译器不同?如果是这样,我如何编译 clojurescript 代码
关于官方页面,它提供了一个非常有限的hello world!,下面这行是页面提供的编译clojurescript的命令。
clj --main cljs.main --compile hello-world.core --repl
如果我使用 --repl 命令它只打印一些东西,如果我删除它,控制台停止打印结果,问题是,它打印的东西非常不同,如果打开另一方面,它使用 clojure cat DATA.lst | 命令编译代码。 clj program.cljs
它完全是面向网络的,所以它一直在我的浏览器中打开并显示与该主题相关的内容,这与我的案例无关。
我想知道如何执行我的代码,以确保我是为 clojurescript 而不是 clojure 编译的(以防它们不同)
有必要创建公开页面的复杂项目树,或者我可以通过简单的方式将其放在文件夹中。 (这就是我使用 clojure 的方式)?
我正在尝试编译的代码是下面的代码,很简单,我只是读取标准输入并按照我希望的方式处理信息
(defn get-data []
(let [input-string (read-line)]
(lazy-seq
(if (seq input-string)
(cons (clojure.string/split input-string #" ") (get-data))
nil))))
(defn get-mod [data]
(lazy-seq
(if (seq data)
(cons (map (fn [x] (rem (Integer. x) 12)) (first data))
(get-mod (rest data)))
nil)))
(defn main []
(def data (rest (get-data)))
(def module (get-mod data))
(println module))
当我使用给出官方 clojure 脚本页面的代码行时,vscode 在终端中给我的结果如下:
WARNING: When invoking clojure.main, use -
ClojureScript 1.10.758
cljs.user=> 33
cljs.user=> 50
57
54
69
cljs.user=> 72
80
68
56
63
cljs.user=> 47
71
40
56
59
52
cljs.user=> 74
59
78
66
cljs.user=> 74
62
94
82
77
cljs.user=> 50
66
57
54
cljs.user=> 68
72
63
44
56
cljs.user=> 60
48
79
75
63
cljs.user=> 67
51
58
cljs.user=> 66
78
51
60
54
cljs.user=> 56
52
49
25
61
cljs.user=> 36
53
45
48
cljs.user=> 58
61
42
49
54
cljs.user=> 76
80
68
68
60
cljs.user=> 63
58
54
51
58
cljs.user=> 42
50
54
54
58
cljs.user=> 50
59
54
62
66
54
cljs.user=> 65
41
61
49
56
cljs.user=> 27
48
43
55
cljs.user=> 35
43
35
47
28
cljs.user=> 49
44
52
32
44
cljs.user=> 74
58
65
70
53
cljs.user=> 52
56
40
60
52
cljs.user=> 54
69
69
62
cljs.user=> 52
49
56
76
cljs.user=> 58
66
50
70
50
cljs.user=> 82
70
73
77
70
cljs.user=> 56
51
63
35
cljs.user=> 59
67
52
71
79
cljs.user=> 72
72
76
84
57
cljs.user=> 66
61
58
61
cljs.user=> 49
32
52
32
cljs.user=> 64
33
52
64
49
这与我在 stdin 中输入的信息完全相同,也就是说,它没有执行我的代码指示的内容,它应该提供的内容如下:
((2 9 6 9) (0 8 8 8 3) (11 11 4 8 11 4) (2 11 6 6) (2 2 10 10 5) (2 6 9 6) (8 0 3 8 8) (0 0 7 3 3) (7 3 10) (6 6 3 0 6) (8 4 1 1 1) (0 5 9 0) (10 1 6 1 6) (4 8 8 8 0) (3 10 6 3 10) (6 2 6 6 10) (2 11 6 2 6 6) (5 5 1 1 8) (3 0 7 7) (11 7 11 11 4) (1 8 4 8 8) (2 10 5 10 5) (4 8 4 0 4) (6 9 9 2) (4 1 8 4) (10 6 2 10 2) (10 10 1 5 10) (8 3 3 11) (11 7 4 11 7) (0 0 4 0 9) (6 1 10 1) (1 8 4 8) (4 9 4 4 1))
Clojure 是 运行 在 Java 虚拟机上的一种语言。 ClojureScript 在外观和功能上是一种类似的语言,但它被编译为 JavaScript 并将 运行 on JavaScript 运行例如 NodeJS 或 Web 浏览器中的 JS 引擎。因为他们针对的运行次不同,所以有区别,这里解释一下:https://www.clojurescript.org/about/differences
像 readline
这样的一些函数在 ClojureScript 中不可用,您需要使用 JS 互操作编写您自己的函数,创建您自己的事件处理程序。您可以使用 core.async 库之类的东西为 Node 编写阻塞和等待输入的代码,但这远远超出了初学者的水平。
您的代码实际上看起来可以在 Clojure 中运行,因此,除非您有某种理由坚持使用 Node 并避免使用 JVM,否则我会坚持使用普通的 Clojure 以利用所有可用资源来学习该语言。
这是一个简单的示例项目和程序,它对从标准输入输入的数字求和:
项目结构如下:
.
├── data.txt
└── src
└── demo
└── core.clj
主程序:
(ns demo.core)
(defn -main [& args]
(loop [total 0] ;; initialize a total sum to 0
(if-let [line (read-line)] ;; keep any input as `line`, otherwise else branch
(let [n (read-string line)] ;; parse `line` to number
(recur (+ n total))) ;; loop, 'updating' the total
(println total)))) ;; else branch: no input, print the total so far
数据文件data.txt
:
11
22
33
... 最后是一个示例 运行:
cat data.txt | clj -m demo.core
WARNING: When invoking clojure.main, use -M
66
听起来你真的想为这个项目使用普通的 Clojure 而不是 ClojureScript。
除了上面的好答案,您可能对这两个可以帮助您入门的模板项目感兴趣:
- Clojure 模板项目:https://github.com/io-tupelo/clj-template\
- ClojureScript 模板项目:https://github.com/io-tupelo/cljs-template
更新
你想在CLJS中解决的“基本问题”是什么???你能补充更多细节吗?
ClojureScript 作为一种语言几乎可以做 Clojure 可以做的任何事情。 JVM 与浏览器中的 JavaScript 运行 相比,最大的不同在于:
JVM 可以处理超过一千个线程。 JS 只有 1 个线程(尽管你可以使用 clojure/core.async and/or 回调伪造多个线程)。
CLJ 具有真正的动态变量(即 Clojure
var
)。 CLJS 变量在运行时是静态的。I/O 在 JVM 上是无限的。浏览器和 JS 不适用于磁盘 I/O,并且在网络上受限 I/O。
- 中的详细差异列表