-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathhello_repl.clj
462 lines (373 loc) · 14.1 KB
/
hello_repl.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
(ns get-started.hello-repl)
;; == Some VS Code knowledge required ==
;; This tutorial assumes you know a few things about
;; VS Code. Please check out this page if you are new
;; to the editor: https://code.visualstudio.com/docs
;;
;; == Keyboard Shortcuts Notation used in this tutorial ==
;; We use a notation for keyboard shortcuts, where
;; `+` means the keys are pressed at the same time
;; and ` ` separates any keyboard presses in the sequence.
;; `Ctrl+Alt+C Enter` means to press Ctrl, Alt, and C
;; all at the same time, then release the keys and
;; then press Enter. (The Alt key is named Option or
;; Opt, on some machines)
"Welcome to the Getting Started REPL! 💜"
;; Once you see a message in the output/REPL window ->
;; saying that this file is loaded, you can start by
;; placing the cursor anywhere on line 17 and press
;; `Alt+Enter`. (`Option+Enter` on some machines.)
;; Did it? Great!
;; See that `=> "Welcome ...` at the end of the line?
;; That's the result of the evaluation you just
;; performed. You just used the Clojure REPL!
;; 🎉 Congratulations! 🎂
(comment
;; You can evaluate the string below in the same way
"Hello World!"
;; You are in a 'Rich Comment Form' which is where
;; we Clojurians most often develop new code.
;; https://calva.io/rich-comments/
;; It is often abbreviated as RCF.
;; Evaluate the following form too (you can
;; place the cursor anywhere on any of the two lines):
(repeat 7
"I am using the REPL! 💪")
;; Only `=> ("I am using the REPL! 💪"` is displayed
;; inline. You can see the full result, and also copy
;; it, if you hover the evaluated expression. Or press
;; `Ctrl+K Ctrl/Cmd+I`.
;; Let's get into the mood for real. 😂
;; Place the cursor on any of the five code lines below:
;; `Alt+Enter`, then `Cmd+K Cmd+I`.
(map (fn [s]
(if (< (count s) 5)
(str "Give me " s "! ~•~ " (last s) "!")
s))
["an R" "an E" "a P" "an L" "What do you get?" "REPL!"])
;; Clear the inline display with `Esc`. The inline
;; results are also cleared when you edit the file.
;; Which brings us to a VERY IMPORTANT THING:
;; By default, Calva will be a Guardian of the Parens.
;; This means that the backspace and delete buttons
;; will not delete balanced brackets. Please go ahead
;; and try to delete a bracket in the expression above.
;; See?
;; TO DELETE A BALANCED BRACKET:
;; press `alt/option+backspace` or `alt/option+delete`
;; You might notice that the output/REPL window ->
;; is also displaying the results. Depending on your
;; preferences you might want to close that window or move
;; it to the same editor group (unsplit) as the files you
;; edit. But don't do that just yet, get a feel how how
;; it works having it in a split pane first.
;; BTW. That output/REPL window ->
;; You can evaluate code from its prompt too.
;; But the cool peeps do not do that very often.
;; Because the REPL lives in the files with the application
;; code! And because Rich Comment Forms (RCF).
;; It is Interactive Programming, and it is 💪.
:rcf) ; <- This is a convenient way to keep the closing
; paren of a Rich comment form from folding
; when the code is formatted.
;;
;; = HOW THIS GUIDE WORKS =
;;
;; There are three files for you to explore. For
;; everyone new to Calva:
;; 1. hello_repl.clj (this file)
;; 2. welcome_to_clojure.clj (a Beginner's Clojure Guide)
;; 3. hello_paredit.clj (intro to Calva structural editing)
;; Please don't worry if you don't understand the code
;; in the this file and in the paredit file.
;; They are short and made so that you can just follow
;; along without the actual code making sense yet. Things
;; will clear up once you dig into the Clojure Guide.
;; About commands and shortcuts:
;; Please read https://calva.io/finding-commands/
;; (It's very short.)
;; When we refer to commands by their name, use
;; the VS Code Command Palette to search for them
;; if you don't know the keyboard shortcut.
;; All Calva commands are prefixed with ”Calva”.
;; == Evaluating definitions ==
;; Alt+Enter is the Calva default keyboard shortcut
;; to evaluate the current ”top level” forms. Top
;; level meaning the outermost ”container” of forms,
;; which is the file. This function definition is on
;; the top level. Please evaluate it!
(defn greet
"I'll greet you"
[s]
(str "Hello " s "!"))
;; Forms inside `(comment ...)` are also considered
;; to be top level. This makes it easy to experiment
;; with code.
(comment
(greet "World")
:rcf)
;; Anything printed to stdout is not shown inline.
(comment
(println (greet "World"))
:rcf)
;; You should see the result of the evaluation, nil,
;; inline, and ”Hello World!” followed by the result
;; printed to the output window.
;; Maybe you wonder what a ”form” is? Loosely defined
;; it is about the same as an S-expression:
;; https://en.wikipedia.org/wiki/S-expression
;; That is, either a ”word” or something enclosed in
;; brackets of some type, parens (), hard brackets [],
;; curlies {}, or quotes "". This whole thing is a
;; form:
(str 23 (apply + [2 3]) (:foo {:foo "foo"}))
;; So is `str`, `23`, "foo", `(apply + [2 3])`,
;; `{:foo "foo"}`, `+`, `[2 3]`, `apply`, and also
;; `(:foo {:foo "foo"})`.
;; Calva has a concept of ”current form”, to let you
;; evaluate forms that are not at the top level. The
;; ”current form” is determined by where the cursor is.
;; Calva has two commands that will let you easily
;; experiment with which form is considered current:
;; * Calva: Select Current Form
;; * Calva: Expand Selection
;; == Evaluating the Current Form ==
;; Ctrl+Enter evaluates the ”current” form
;; Try it with the cursor at different places in this
;; code snippet:
(comment
(str 23 (apply + [2 3]) (:foo {:foo "foo"}))
;; `foo` is undefined until you top-level eval it.
(def foo
[1 2 "three four"])
:rcf)
;; You might discover that Calva regards words in
;; strings as forms. Don't panic if `three` causes
;; an evaluation error. It is not defined, since
;; it shouldn't be. You can define it, of course,
;; just for fun and learning: Top level eval these
;; two definitions.
(comment
(def three 3)
(def four "four")
:rcf)
;; Then eval current form inside the string above.
;; Whatever you ask Calva to send to the REPL, Calva
;; will send to the REPL.
;; == Rich Comments Support ==
;; Repeating an important concept: Forms inside
;; `(comment ...)` are also considered top level
;; by Calva. Alt+Enter at different places below
;; to get a feel for it.
(comment
"I ♥️ Clojure"
(greet "World")
foo
(range 10)
;; https://calva.io/rich-comments/
:rcf)
;; Also try the commands *Show Hover*,
;; *Show Definition Preview Hover*
;; *Go to Definition*
(comment
(println (greet "side effect"))
(+ (* 2 2)
2)
;; Here too, if you have Java sources installed
(Math/abs -1)
:rcf)
;; == You Control what is Evaluated ==
;; Please note that Calva never evaluates your code
;; unless you explicitly ask for it. So, except for
;; this file, you will have to load files you open
;; yourself. Make it a habit to do this, because
;; sometimes things don't work, and they fail in
;; peculiar ways, when your file is not loaded.
;; Try it with this file: `Ctrl+Alt+C Enter`.
;; The result of loading a file is whatever is the
;; last top level form in the file.
;; == Editing Code ==
;; A note about editing Clojure in Calva:
;; If you edit and experiment with the examples you
;; will notice that Calva auto-indents your code.
;; You can re-indent, and format, code at will, using
;; the `Tab` key. It will format the current enclosing
;; form. Try it at the numbered places in this piece
;; of code, starting at `; 1`:
(comment ; 3
(defn- divisible
"Is `n` divisible by `d`?"
[n d]
(zero? (mod n d)
)
)
(defn fizz-buzz [n] ; 2
(cond ; 1
(divisible n (* 5 3)) "FizzBuzz"
(divisible n 5) "Buzz"
(divisible n 3) "Fizz"
:else n))
:rcf)
;; === Paredit `strict` mode is on ===
;; Calva supports structural editing (editing that
;; considers forms rather than lines) using a system
;; called Paredit. By default Paredit tries to protect
;; from accidentally deleting brackets and unbalancing
;; the structure of forms. To override the protection,
;; use `Alt+Backspace` or `Alt+delete`.
(comment
(defn strict-greet
"Try to remove brackets and string quotes
using Backspace or Delete. Try the same
with the Alt key pressed."
[name]
(str "Strictly yours, " name "!"))
(strict-greet "dear Paredit fan")
:rcf)
;; (Restore with *Undo* if needed.)
;; See `hello_paredit.clj` for more. And also:
;; https://calva.io/paredit
;;;;;;;;;;;;;;;;;;; CHECKPOINT ;;;;;;;;;;;;;;;;;;;
;; You now know enough about Calva to experiment
;; with the code in `welcome_to_clojure.clj`.
;; This file continues with some more neat Calva
;; features, so you should definitely return here
;; after you learn some things about Clojure.
;; Like, what a threaded expression is.
;; == Evaluating in Threaded Expressions
;; Ctrl+Alt+Enter will evaluate the current enclosing
;; form up to the cursor. Useful in threaded
;; expressions. Say you want to calculate the average
;; ratings for the data below:
(comment
;; First you need to top-level evaluate this
(def colt-express
{:name "Colt Express"
:categories ["Family"
"Strategy"]
:play-time 40
:ratings {:pez 5.0
:kat 5.0
:wiw 5.0
:vig 3.0
:rex 5.0
:lun 4.0}})
;; And this
(defn average [coll]
(/ (apply + coll) (count coll)))
;; This too, if you like
(->> colt-express
:ratings
vals
average)
;; To see the result at each step in the thread
;; You can also Ctrl+Alt+Enter after each form.
;; Place the cursor after `(->> colt-express` and
;; try it. Then after `:ratings`, and after `vals`.
:rcf)
;; == Evaluating Top Level Form to Cursor
;; Shift+Alt+Enter will evaluate all code from
;; the start of the current top level form, up until
;; the cursor, with all open brackets closed.
;; Try it by repeating the above example, but start
;; with placing the cursor at, say, right behind
;; `:wiw 5.0`, then evaluating top level to cursor.
(comment
;; The command is useful when evaluating a block of
;; code up to a point. You might for instance wrap
;; some code in a `(do ...)` and then use the
;; *Evaluate From Start of Top Level Form to Cursor*
;; command at different places to examine the code.
;; Try it at the numbered line comment below.
; But first top-level eval this one
(defn average [coll]
(/ (apply + coll) (count coll)))
(do
(def bar-express
{:name "Bar Express"
:categories ["Family"
"Strategy"]
:play-time 40
:ratings {:pez 5.0
:kat 5.0
:wiw 5.0 ; 1, then eval `bar-express`
:vig 3.0
:rex 5.0
:lun 4.0}})
(let [foo-express (-> bar-express
(assoc :name "Foo Express")
(assoc-in [:ratings :lyr] 5.0)
(update-in [:ratings :vig] inc))]
(->> foo-express ; 2
:ratings ; 3
vals ; 4
(average) ; 5 (If this blows up you need to
; top level eval the `average`
; function definition.)
)))
:rcf)
;; == The Calva Debugger ==
;; https://calva.io/debugger/
;; The easiest way to use it is to
;; instrument a function for debugging. You do that
;; by having the cursor in the function and then
;; use the command:
;; *Instrument Current Top Level Form for Debugging*
;; Then you call the function. This will cause the
;; debugger to stop at the first breakable point in
;; the instrumented function
(comment
;; Let's try it without instrumentation first. This
;; function has a bug. Evaluate it the usual way
;; (`Alt+Enter`) first and then call it.
(defn bar
[n]
(cond (> n 40) (+ n 20)
(> n 20) (- (first n) 20)
:else 0))
(bar 2) ; works
(bar 24) ; throws, what's going on?
;; That's a strange error message (maybe you say,
;; depending on how familiar you are with Clojure).
;; Now instrument the function as described above.
;; Calva will indicate code that is instrumented for
;; debugging. Now evaluate the problematic function
;; call. The debugger will start and wait for you
;; to step through the function.
;;
;; To un-instrument the function, just evaluate it
;; the normal way (top level evaluation).
;; Debugger docs here: https://calva.io/debugger/
;; NB: If you are new to Clojure you might find some
;; familiarity noting that Calva has a debugger.
;; However, try exploring Interactive Programming,
;; using the REPL first. That's the Clojure Way.
;; This section is here for you to get aware that
;; the debugger exists, for those rare occasions
;; when it is actually needed.
:rcf)
;; == Stopping Infinite Loops ==
;; Since evaluating Clojure expressions is so
;; easy and fun, sometimes you happen to evaluate
;; something that never finishes, or takes too long
;; to finish. For this, Calva has a command named
;; *Interrupt Running Evaluations*. You will need
;; it if you top-level evaluate this:
(comment
(def tmp1 (dorun (range)))
:rcf)
;; Done? Awesome. Please consider familiarizing
;; yourself more with Paredit using the interactive
;; guide. If you are new to Clojure, please
;; continue with `welcome_to_clojure.clj`, which is an
;; interactive guide to the Clojure language.
;; Have a Clojure project you want to hook
;; Calva up to? See: https://calva.io/connect/
;; Learn much more about Calva at https://calva.io
;; This string is the last expression in this file
"hello_repl.clj is loaded, and ready with some things for you to try."
;; It is what you'll see printed in the Output
;; window when you load the file.
;; This guide downloaded from:
;; https://github.com/BetterThanTomorrow/dram
;; Please consider contributing.