squint-cljs 0.0.0-alpha.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ ## ClavaScript
2
+
3
+ ClavaScript is an experimental ClojureScript syntax to
4
+ JavaScript compiler.
5
+
6
+ ClavaScript is not intended as a replacement for ClojureScript but as a tool to
7
+ target JS for anything you would not use ClojureScript for, for whatever reason:
8
+ performance, bundle size, ease of interop, etc.
9
+
10
+ > :warning: This project should be considered experimental and may still undergo
11
+ > breaking changes. It's fine to use it for non-critical projects but don't use
12
+ > it in production yet.
13
+
14
+ ## Quickstart
15
+
16
+ Although it's early days, you're welcome to try out `clava` and submit issues.
17
+
18
+ ``` shell
19
+ $ mkdir clava-test && cd clava-test
20
+ $ npm init -y
21
+ $ npm install clavascript@latest
22
+ ```
23
+
24
+ Create a `.cljs` or `.clvs` file, e.g. `example.cljs`:
25
+
26
+ ``` clojure
27
+ (ns example
28
+ (:require ["fs" :as fs]
29
+ ["url" :refer [fileURLToPath]]))
30
+
31
+ (println (fs/existsSync (fileURLToPath js/import.meta.url)))
32
+
33
+ (defn foo [{:keys [a b c]}]
34
+ (+ a b c))
35
+
36
+ (println (foo {:a 1 :b 2 :c 3}))
37
+ ```
38
+
39
+ Then compile and run (`run` does both):
40
+
41
+ ```
42
+ $ npx clvs run example.cljs
43
+ true
44
+ 6
45
+ ```
46
+
47
+ Run `npx clvs --help` to see all command line options.
48
+
49
+ ## Why ClavaScript
50
+
51
+ ClavaScript lets you write CLJS syntax but emits small JS output, while still having
52
+ parts of the CLJS standard library available (ported to mutable data structures,
53
+ so with caveats). This may work especially well for projects e.g. that you'd
54
+ like to deploy on CloudFlare workers, node scripts, Github actions, etc. that
55
+ need the extra performance, startup time and/or small bundle size.
56
+
57
+ ## Differences with ClojureScript
58
+
59
+ - ClavaScript does not protect you in any way from the pitfalls of JS with regards to truthiness, mutability and equality
60
+ - There is no CLJS standard library. The `"clavascript/core.js"` module has similar JS equivalents
61
+ - Keywords are translated into strings
62
+ - Maps, sequences and vectors are represented as mutable objects and arrays
63
+ - Most functions return arrays and objects, not custom data structures
64
+ - Supports async/await:`(def x (js/await y))`. Async functions must be marked
65
+ with `^:async`: `(defn ^:async foo [])`.
66
+ - `assoc!`, `dissoc!`, `conj!`, etc. perform in place mutation on objects
67
+ - `assoc`, `dissoc`, `conj`, etc. return a new shallow copy of objects
68
+ - `println` is a synonym for `console.log`
69
+ - `pr-str` and `prn` coerce values to a string using `JSON.stringify`
70
+
71
+ ### Seqs
72
+
73
+ ClavaScript does not implement Clojure seqs. Instead it uses the JavaScript
74
+ [iteration
75
+ protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)
76
+ to work with collections. What this means in practice is the following:
77
+
78
+ - `seq` takes a collection and returns an Iterable of that collection, or nil if it's empty
79
+ - `iterable` takes a collection and returns an Iterable of that collection, even if it's empty
80
+ - `seqable?` can be used to check if you can call either one
81
+
82
+ Most collections are iterable already, so `seq` and `iterable` will simply
83
+ return them; an exception are objects created via `{:a 1}`, where `seq` and
84
+ `iterable` will return the result of `Object.entries`.
85
+
86
+ `first`, `rest`, `map`, `reduce` et al. call `iterable` on the collection before
87
+ processing, and functions that typically return seqs instead return an array of
88
+ the results.
89
+
90
+ #### Memory usage
91
+
92
+ With respect to memory usage:
93
+
94
+ - Lazy seqs in ClavaScript are built on generators. They do not cache their results, so every time they are consumed, they are re-calculated from scratch.
95
+ - Lazy seq function results hold on to their input, so if the input contains resources that should be garbage collected, it is recommended to limit their scope and convert their results to arrays when leaving the scope:
96
+
97
+
98
+ ``` clojure
99
+ (js/global.gc)
100
+
101
+ (println (js/process.memoryUsage))
102
+
103
+ (defn doit []
104
+ (let [x [(-> (new Array 10000000)
105
+ (.fill 0)) :foo :bar]
106
+ ;; Big array `x` is still being held on to by `y`:
107
+ y (rest x)]
108
+ (println (js/process.memoryUsage))
109
+ (vec y)))
110
+
111
+ (println (doit))
112
+
113
+ (js/global.gc)
114
+ ;; Note that big array is garbage collected now:
115
+ (println (js/process.memoryUsage))
116
+ ```
117
+
118
+ Run the above program with `node --expose-gc ./node_cli mem.cljs`
119
+
120
+ ## JSX
121
+
122
+ You can produce JSX syntax using the `#jsx` tag:
123
+
124
+ ``` clojure
125
+ #jsx [:div "Hello"]
126
+ ```
127
+
128
+ produces:
129
+
130
+ ``` html
131
+ <div>Hello</div>
132
+ ```
133
+
134
+ and outputs the `.jsx` extension automatically.
135
+
136
+ You can use Clojure expressions within `#jsx` expressions:
137
+
138
+ ``` clojure
139
+ (let [x 1] #jsx [:div (inc x)])
140
+ ```
141
+
142
+ Note that when using a Clojure expression, you escape the JSX context so when you need to return more JSX, use the `#jsx` once again:
143
+
144
+ ``` clojure
145
+ (let [x 1]
146
+ #jsx [:div
147
+ (if (odd? x)
148
+ #jsx [:span "Odd"]
149
+ #jsx [:span "Even"])])
150
+ ```
151
+
152
+ See an example of an application using JSX [here](https://clavascript.github.io/demos/clava/solidjs/) ([source](https://github.com/clavascript/clavascript/blob/main/examples/solidjs/src/App.cljs)).
153
+
154
+ ## Async/await
155
+
156
+ ClavaScript supports `async/await`:
157
+
158
+ ``` clojure
159
+ (defn ^:async foo [] (js/Promise.resolve 10))
160
+
161
+ (def x (js/await (foo)))
162
+
163
+ (println x) ;;=> 10
164
+ ```
165
+
166
+ ## Roadmap
167
+
168
+ In arbitrary order, these features are planned:
169
+
170
+ - Macros
171
+ - REPL
172
+ - Protocols
173
+
174
+ ## Core team
175
+
176
+ The core team consists of:
177
+
178
+ - Michiel Borkent ([@borkdude](https://github.com/borkdude))
179
+ - Will Acton ([@lilactown](https://github.com/lilactown))
180
+ - Cora Sutton ([@corasaurus-hex](https://github.com/corasaurus-hex))
181
+
182
+ License
183
+ =======
184
+
185
+ ClavaScript is licensed under the EPL, the same as Clojure core and [Scriptjure](https://github.com/arohner/scriptjure). See epl-v10.html in the root directory for more information.