Skip to content

Commit c736232

Browse files
committed
more comments about emacs; .map to (flip map) relationship
1 parent 06ae1a2 commit c736232

1 file changed

Lines changed: 63 additions & 9 deletions

File tree

rxjava/expt1/src/expt1/core.clj

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,28 @@
22
;;; with 'project.clj' in it) and saying 'lein repl'.
33

44
;;; 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).
1027

1128
(ns expt1.core
1229
(:require [expt1.k2 :as k2 ]
@@ -131,7 +148,8 @@
131148
;;; longer one. Filters typically shorten sequences; maps leave
132149
;;; sequences the same length. Most methods that lengthen sequences
133150
;;; 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.
135153

136154
(-> (Observable/toObservable [1 2 3])
137155
(.take 2)
@@ -367,14 +385,50 @@
367385
(defn flip [f2] (fn [x y] (f2 y x)))
368386

369387
(-> (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)]))
373391
(.filter (fn [[a b]] (= 0 (mod b 7))))
374392
subscribe-collectors
375393
pdump
376394
)
377395

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+
378432
;;; _ _
379433
;;; /_\ ____ _ _ _ __| |_ _ _ ___ _ _ ___ _ _ ___
380434
;;; / _ \ (_-< || | ' \/ _| ' \| '_/ _ \ ' \/ _ \ || (_-<

0 commit comments

Comments
 (0)