|
2 | 2 | ;;; with 'project.clj' in it) and saying 'lein repl'. |
3 | 3 |
|
4 | 4 | ;;; If you're using emacs with nrepl (see |
5 | | -;;; http://clojure-doc.org/articles/tutorials/emacs.html for setup |
6 | | -;;; info), you can run this entire file by first "jacking in" (Ctrl-c, |
7 | | -;;; Meta-j), then running the whole file (Ctrl-c, Ctrl-k). You can |
8 | | -;;; also eval individual terms by placing the cursor at the end of a |
9 | | -;;; term and doing Ctrl-c, Ctrl-e (for "evaluate"). |
| 5 | +;;; http://clojure-doc.org/articles/tutorials/emacs.html for setup info), |
| 6 | +;;; you can run this entire file by first "jacking in" (Ctrl-c, Meta-j), |
| 7 | +;;; then running the whole file (Ctrl-c, Ctrl-k). You can also eval |
| 8 | +;;; individual terms by placing the cursor at the end of a term and doing |
| 9 | +;;; Ctrl-c, Ctrl-e (for "evaluate"). You can access documentation for any |
| 10 | +;;; clojure primitive by putting the cursore (which emacs calls "point") |
| 11 | +;;; inside or behind the primitive and typing Ctrl-c, Ctrl-d. The help for |
| 12 | +;;; the rest of the nrepl mode can be found by typing Ctrl-h, m. |
| 13 | + |
| 14 | +;;; Probably the most important thing to learn is "Paredit." It takes most |
| 15 | +;;; of the pain out of parentheses and nesting. There is a lot of info about |
| 16 | +;;; it on the web, and the help is pretty good. The two biggies are |
| 17 | +;;; paredit-forward-slurp-sexp, whose help you can find by typing Ctrl-h, k, |
| 18 | +;;; Ctrl-Shift-) and paredit-splice-sexp (Ctrl-h, k, Meta-s). Take the time |
| 19 | +;;; to learn them. Slurp has three friends: paredit-forward-barf-sexp |
| 20 | +;;; (Ctrl-h, k, Ctrl-Shift-} ) and the backwards versions of slurp and barf. |
| 21 | +;;; They're next most important. |
| 22 | + |
| 23 | +;;; You can re-indent any Clojure code that gets deranged by putting point |
| 24 | +;;; at the beginning of the code and typing Ctrl-Alt-Q. You can move around |
| 25 | +;;; at the expression level by typing Ctrl-Alt-F (forward) and Ctrl-Alt-B |
| 26 | +;;; (backward). |
10 | 27 |
|
11 | 28 | (ns expt1.core |
12 | 29 | (:require [expt1.k2 :as k2 ] |
|
131 | 148 | ;;; longer one. Filters typically shorten sequences; maps leave |
132 | 149 | ;;; sequences the same length. Most methods that lengthen sequences |
133 | 150 | ;;; rely on mapMany, which is called "SelectMany" in many Rx documents |
134 | | -;;; (.e.g., http://bit.ly/18Bot23). |
| 151 | +;;; (.e.g., http://bit.ly/18Bot23) and is similar to Clojure's "mapcat", up |
| 152 | +;;; to order of parameters. |
135 | 153 |
|
136 | 154 | (-> (Observable/toObservable [1 2 3]) |
137 | 155 | (.take 2) |
|
367 | 385 | (defn flip [f2] (fn [x y] (f2 y x))) |
368 | 386 |
|
369 | 387 | (-> (synchronous-observable (range 50)) |
370 | | - (.map #(str "SynchronousValue_" %)) |
371 | | - (.map (partial (flip clojure.string/split) #"_")) |
372 | | - (.map (fn [[a b]] [a (Integer/parseInt b)])) |
| 388 | + (.map #(str "SynchronousValue_" %)) |
| 389 | + (.map (partial (flip clojure.string/split) #"_")) |
| 390 | + (.map (fn [[a b]] [a (Integer/parseInt b)])) |
373 | 391 | (.filter (fn [[a b]] (= 0 (mod b 7)))) |
374 | 392 | subscribe-collectors |
375 | 393 | pdump |
376 | 394 | ) |
377 | 395 |
|
| 396 | +;;; Let's compare the use of rxjava's ".map" with Clojure's ordinary |
| 397 | +;;; "map". The biggest difference is that Rx's .map takes the collection in |
| 398 | +;;; the privileged first position. Such makes "fluent composition" with the |
| 399 | +;;; "->" macro automatic and brainless. Ditto rxjava/.filter and |
| 400 | +;;; core/filter: their argument lists are the flips of one another. |
| 401 | + |
| 402 | +;;; Consider the example above, and let's write a non-reactive version of |
| 403 | +;;; it. |
| 404 | + |
| 405 | +(-> (range 50) |
| 406 | + ((flip map) #(str "NonReactiveValue_" %)) |
| 407 | + ((flip map) (partial (flip clojure.string/split) #"_")) |
| 408 | + ((flip map) (fn [[a b]] [a (Integer/parseInt b)])) |
| 409 | + ((flip filter) (fn [[a b]] (= 0 (mod b 7)))) |
| 410 | + pdump |
| 411 | + ) |
| 412 | + |
| 413 | +;;; The code above looks very similar to the reactive code-block prior to |
| 414 | +;;; it. Specifically, the function arguments are identical. The device used |
| 415 | +;;; to bring the collection arguments into first position is "flip". To make |
| 416 | +;;; the resemblance even more complete, we might do the following |
| 417 | + |
| 418 | +(let [-map (flip map) |
| 419 | + -filter (flip filter)] |
| 420 | + (-> (range 50) |
| 421 | + (-map #(str "NonReactiveValue2.0_" %)) |
| 422 | + (-map (partial (flip clojure.string/split) #"_")) |
| 423 | + (-map (fn [[a b]] [a (Integer/parseInt b)])) |
| 424 | + (-filter (fn [[a b]] (= 0 (mod b 7)))) |
| 425 | + pdump |
| 426 | + ) |
| 427 | + ) |
| 428 | + |
| 429 | +;;; With these local definitions, "-map" and "-filter", the non-reactive |
| 430 | +;;; version looks just like the reactive version. |
| 431 | + |
378 | 432 | ;;; _ _ |
379 | 433 | ;;; /_\ ____ _ _ _ __| |_ _ _ ___ _ _ ___ _ _ ___ |
380 | 434 | ;;; / _ \ (_-< || | ' \/ _| ' \| '_/ _ \ ' \/ _ \ || (_-< |
|
0 commit comments