You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here are the resources and steps that I took while learning ClojureScript.
29
-
(Most resources covering Clojure also apply to ClojureScript, since they
30
-
share a significant subset with each other.)
31
-
32
-
1. Reading the book [ClojureScript Up and Running](http://synrc.com/publications/cat/Functional%20Languages/Clojure/Oreilly.ClojureScript.Up.and.Running.Oct.2012.pdf)
33
-
1. Reading the book [Clojure Programming](http://bit.ly/clojurebook)
1. Thumbing through [Clojure Core API](http://clojure.github.io/clojure/clojure.core-api.html)
39
-
1. Reading [ClojureScript - Differences from Clojure - Host Interop](https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure#wiki-host-interop) for accessing javascript properties like `(.-Infinity js/window)` and functions like `(.sqrt js/Math 25)`.
40
-
1. Reading [Javascript to ClojureScript synonyms](http://kanaka.github.io/clojurescript/web/synonym.html)
41
-
1. Experimenting in `lein repl` for Clojure REPL.
42
-
1. Experimenting in <http://clojurescript.net/> for ClojureScript REPL with a browser context.
43
-
1. Reading docstrings of functions I encounter with `(doc <funcname>)` in REPL.
23
+
open any file with a `.cljs` extension in Sublime, then select:
44
24
45
-
_What follows is my attempt to guide you through ClojureScript's fundamentals
46
-
and advantages over other languages for the web._
25
+
```
26
+
View > Syntax > Open all with current extension as... > Clojure
27
+
```
47
28
48
-
### Data Syntax
29
+
## Syntax
49
30
50
-
Though its syntax is unfamiliar and different, ClojureScript has a surprisingly
51
-
simple foundation with wide benefits. And one can it learn quickly.
31
+
#### Data
52
32
53
-
This is a __`number`__:
33
+
There is __literal data__:
54
34
55
35
```clj
36
+
; number
56
37
1.23
57
-
```
58
-
59
-
This is a __`string`__:
60
38
61
-
```clj
39
+
; string
62
40
"foo"
63
-
```
64
-
65
-
A __`keyword`__ is like a string, but it is primarily used as a "key" to
66
-
retrieve data from a `map`. (more on this later)
67
41
68
-
```clj
42
+
; keyword (like strings, but used as map keys)
69
43
:foo
70
-
```
71
-
72
-
A __`symbol`__ is used as the name of some saved value. (more on creating
73
-
these later)
74
44
75
-
```clj
76
-
foo
77
-
```
45
+
; vector (array)
46
+
[:bar3.14"hello"]
78
47
79
-
A __`list`__ is surrounded by parentheses, and its elements are separated by
80
-
whitespace. It can contain elements of any type, even other lists.
48
+
; map (associative array)
49
+
{:msg"hello":pi3.14:primes [23571113]}
81
50
82
-
```clj
83
-
(foo:bar3.14"hello")
51
+
; set (distinct elements)
52
+
#{:bar3.14"hello"}
84
53
```
85
54
86
-
A __`vector`__ is similar to a list. It uses square brackets, but keep in
87
-
mind, the actual _significant_ difference is how they are "evaluated" (covered
88
-
later).
55
+
And there is __symbolic data__:
89
56
90
57
```clj
91
-
[foo :bar3.14"hello"]
58
+
; symbol (represents a named value)
59
+
foo
60
+
61
+
; list (represents a "call")
62
+
(foo:bar3.14)
92
63
```
93
64
94
-
A __`map`__ is an associative collection that "maps" a key value to another value.
95
-
It is denoted by curly brackets. (Keys are often `keywords` but can be anything)
65
+
#### Evaluation
96
66
97
-
```clj
98
-
{:msg"hello":pi3.14:primes [23571113]}
99
-
```
67
+
ClojureScript can evaluate data to create a new "value" from it.
100
68
101
-
Since commas and newlines are considered whitespace in ClojureScript,
102
-
you can use them to make `map`s more readable:
69
+
1. Literal data evaluates to itself, of course:
103
70
104
-
```clj
105
-
{:msg"hello", :pi3.14, :primes [23571113]}
106
-
; or
107
-
{ :msg"hello"
108
-
:pi3.14
109
-
:primes [23571113] }
110
-
```
71
+
```clj
72
+
1.23; => 1.23
73
+
"foo"; => "foo"
74
+
[:bar3.14"hello"] ; => [:bar 3.14 "hello"]
75
+
```
111
76
112
-
### And that's all the syntax
77
+
1. A __symbol__ evaluates to the value bound to it:
113
78
114
-
Now this is where it gets interesting! All ClojureScript code is written in
115
-
its own Data Syntax which we just covered. The big revelation here is that
116
-
"Code is just Data".
79
+
```clj
80
+
foo ; => 3
81
+
```
117
82
118
-
In particular, it is the `list` data type that is treated as code. For
119
-
example, if `foo` is a function, then this is how you call it with some
120
-
parameters.
83
+
1. A __list__ evaluates to the return value of a "call".
121
84
122
-
```clj
123
-
(foo:bar3.14"hello")
124
-
```
85
+
```clj
86
+
(+123) ; => 6
87
+
(=12) ; => false
88
+
(iftrue"y""n") ; => "y"
89
+
```
125
90
126
-
In fact, all the usual arithmetic operators are functions too.
127
-
For example, `+``-``*``=``<``>` are all functions.
91
+
#### Calls
92
+
93
+
If the first element of a list is a __function__, then the rest of the elements
94
+
are evaluated and passed to it.
128
95
129
96
```clj
97
+
; String concatenation
98
+
(str"Hello""World")
99
+
100
+
; Arithmetic
130
101
(= a b) ; equality (true or false)
131
102
(+ a b) ; sum
132
103
(- a b) ; difference
133
104
(* a b c) ; product
134
105
(< a b c) ; true if a < b < c
135
-
```
136
-
137
-
And here is an `if` expression:
138
-
139
-
```clj
140
-
(if (= a b c) ; <-- determines if a=b=c
141
-
(foo1) ; <-- called if true
142
-
(bar2) ; <-- called if false
143
-
)
144
-
```
145
-
146
-
Notice that the `if` expression above is actually a list of lists. Let's look
147
-
at a simpler example of a list of lists to see how it is __evaluated__ step by
148
-
step:
149
-
150
-
```clj
151
-
(+ k (*24))
152
-
```
153
-
154
-
This is adding the value of `k` to the product of 2 and 4. Assuming that `k`
155
-
is a symbol representing a var of value 3, the evaluation is carried out as
156
-
follows:
157
106
158
-
```clj
159
-
(+ k (*24)) ;as we stated, k evalutes to 3
107
+
; Evaluation Steps
108
+
(+ k (*24)) ;assume k evalutes to 3
160
109
(+3 (*24)) ; (* 2 4) evaluates to 8
161
110
(+38) ; (+ 3 8) evalutes to 11
162
111
11
163
112
```
164
113
165
-
Notice that both `lists` and `symbols` are __evaluated__ to new values. This
166
-
is a crucial step in understanding ClojureScript.
167
-
168
-
__Numbers, strings, and keywords simply evaluate to themselves__, meaning
169
-
ClojureScript takes them at face value without doing anything extra.
114
+
If the first element of a list is one of 16 __special forms__, then the rest of
115
+
the elements are passed to it _unevaluated_.
170
116
171
117
```clj
172
-
123; => 123
173
-
"foo"; => "foo"
174
-
:foo ; => :foo
175
-
```
176
-
177
-
But as we saw a moment ago, __symbols evaluate to the values they are bound
178
-
to__:
118
+
(if (= a b c) ; <-- determines if a=b=c
119
+
(foo1) ; <-- only evaluated if true
120
+
(bar2) ; <-- only evaluated if false
121
+
)
179
122
180
-
```clj
181
-
(defk3) ; bind k to the value of 3
182
-
k ; => 3
183
-
```
123
+
; define k as 3
124
+
(defk3) ; <-- notice that k is not evaluated here
125
+
; (def needs the symbol k, not its value)
184
126
185
-
__A vectors evaluates to a vector of its evaluated elements.__ In other words,
186
-
it evalutes to itself, but with all its elements evaluated. Same goes for maps.
__Lists are evaluated as code__. The full nature of this evaluation depends on
197
-
the first element of the list. (functions vs macros vs special forms)
138
+
If the first element of a list is a __macro__, then the rest of the elements
139
+
are passed to it unevaluated, but the value returned by a macro evaluated.
140
+
Let's illustrate that difference:
198
141
142
+

199
143
200
-
### Complaints
144
+
This difference in evaluation allows macros to act like code-generating
145
+
functions. For example, the `defn` macro expands to `def` and `fn`, as we used
146
+
separately in a previous example:
201
147
202
-
Let's immediately address the instinctual complaints we all have when first
203
-
encountering this unfamiliar syntax and its potential for lots of parentheses.
204
-
205
-
Despite the unfamiliarity, you just learned everything you need to know about
206
-
the syntax, so it is very simple to learn and keep in one's head.
207
-
208
-
As with all other languages, readability is improved with standard indentation
209
-
practices. It is also trivial to manage parentheses in any editor. For
210
-
example, Sublime Text simply underlines matching parens touching your cursor:
148
+
```clj
149
+
; create a named function using the defn macro
150
+
(defngreet [username]
151
+
(str"Hello " username))
211
152
212
-

153
+
; the definition for the defn macro (over-simplified)
154
+
(defmacrodefn [name args body]
155
+
`(def ~name (fn ~args ~body)))
156
+
```
213
157
214
-
Some even allow you to outline all code inside matching parens (using Sublime Text's
215
-
"Bracket Highlighter" plugin with "high visibility" enabled):
158
+
App developers rarely need to create their own macros, but it is an
159
+
indispensible tool for the library developer to give app developers the full
160
+
flexibility of the language.
216
161
217
-

162
+
## Useful Resources
218
163
219
-
### Benefits
164
+
Here are the resources and steps that I took while learning ClojureScript.
165
+
(Most resources covering Clojure also apply to ClojureScript, since they
166
+
share a significant subset with each other.)
220
167
168
+
1. Reading the book [ClojureScript Up and Running](http://synrc.com/publications/cat/Functional%20Languages/Clojure/Oreilly.ClojureScript.Up.and.Running.Oct.2012.pdf)
169
+
1. Reading the book [Clojure Programming](http://bit.ly/clojurebook)
1. Thumbing through [Clojure Core API](http://clojure.github.io/clojure/clojure.core-api.html)
175
+
1. Reading [ClojureScript - Differences from Clojure - Host Interop](https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure#wiki-host-interop) for accessing javascript properties like `(.-Infinity js/window)` and functions like `(.sqrt js/Math 25)`.
176
+
1. Reading [Javascript to ClojureScript synonyms](http://kanaka.github.io/clojurescript/web/synonym.html)
177
+
1. Experimenting in `lein repl` for Clojure REPL.
178
+
1. Experimenting in <http://clojurescript.net/> for ClojureScript REPL with a browser context.
179
+
1. Reading docstrings of functions I encounter with `(doc <funcname>)` in REPL.
180
+
1.[Miscellaneous ClojureScript things to know](https://github.com/shaunlebron/ClojureSheet#clojurescript-stuff)
0 commit comments