Clojurescript first steps doubts and problems

359 views Asked by At

I just started with clojurescript and I have many doubts, what I want to do is use clojurescript only to solve basic problems, for now nothing to do with web.

If I eliminate the web development part, would there be any difference between coding in Clojure and ClojureScript? or is it exactly the same?

Also I was wondering if I can use the command cat DATA.lst | clj program.cljs to run clojurescript code? Or is the compiler different? If so, how can I compile clojurescript code

Regarding the official page, it presents a very limited hello world !, the following line is delivered by the page as a command to compile clojurescript.

clj --main cljs.main --compile hello-world.core --repl

  1. It only prints something if I use the --repl command, if I delete this, the console stops printing the result, the problem is that, things it prints is very different, to if on the other hand, it compiled the code using the command for clojure cat DATA.lst | clj program.cljs

  2. It is totally web-oriented so all the time it is opening in my browser and showing something related to that topic, which would have nothing to do with my case.

  3. I would like to know how I can execute my code so that I am sure that I am compiled for clojurescript and not for clojure (in case they were different)

  4. It is necessary to create the complex project tree that exposes the page or I can leave it in a folder in a simple way. (This is how I work with clojure)?

  5. The code I'm trying to compile is the one below, it's simple, I just read stdin and process the info as I want it to be at the end

(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))

What vscode gives me in the terminal when I use the line of code that gives the official clojure script page is the following:

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

Which is exactly the same information that I enter in stdin, that is, it did nothing of what my code dictates, what it should deliver is the following:

((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))
2

There are 2 answers

1
Denis Fuenzalida On BEST ANSWER

Clojure is a language that runs on the Java Virtual Machine. ClojureScript is a similar language in appearance and features, but it is compiled to JavaScript and will run on JavaScript runtimes such as NodeJS or the JS engines in web browsers. Because they target different runtimes, there are differences, explained here: https://www.clojurescript.org/about/differences

Some functions like readline are not available in ClojureScript and you'll need to write your own using JS interop, creating your own event handler. You can write code for Node that blocks and waits for input using something like the core.async library but it's way beyond beginner level.

Your code actually looks like it would work in Clojure so, unless you have some reason to stick to Node and avoid the JVM, I'd stick to plain Clojure to learn the language with all the resources that are available.

Here's a simple example project and program that sums the numbers that are entered from the standard input:

The project has this structure:

.
├── data.txt
└── src
    └── demo
        └── core.clj

The main program:

(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

The data file data.txt:

11
22
33

... and finally an example run:

 cat data.txt | clj -m demo.core
WARNING: When invoking clojure.main, use -M
66
1
Alan Thompson On

It sounds like you really want to use plain Clojure for this project instead of ClojureScript.

Besides the good answer above, you may be interested in these 2 template projects that can help you get started:


Update

What are the "basic problems" that you want to solve in CLJS??? Can you add more detail?

ClojureScript as a language can do nearly anything that Clojure can do. The big difference comes in comparing the JVM to JavaScript running in the browser:

  • The JVM can handle over a thousand threads. JS has only 1 thread (although you can fake multiple threads using clojure/core.async and/or callbacks).

  • CLJ has true dynamic variables (i.e. the Clojure var). CLJS vars are static at runtime.

  • I/O is unlimited on the JVM. Browsers & JS are not meant to do disk I/O, and are limited on network I/O.

  • See the detailed list of differences at clojurescript.org