bidi means "bidirectional" (routing)

Dave in Lobster Writer uses bidi to: 1) Decide what should be done for a given uri?, and 2) Given a thing that should be done, what should the uri be? Bidi’s name means “bidi-rectional”, which means the string uri can give a handler, and a handler can give a string. Both cases use the pushy library. When the uri matches a handler in the route, pushy runs a given function that generally loads a matching page.

Use an interceptor to use registered coeffects; use a kv-pair to use registered effects

Re-Frame has two rules for working with registered coffects (world input) and registered effects (output to world): 1) Pull world input with (inject-cofx :coeffect-name) in an interceptor, and 2) Call registered effects by putting a :effect-name :value kv-pair in the returned effect map. To follow these rules, you need to know that effects can pull in a vector of interceptors. These interceptors generally change the hashmap called “coffects” before going to the effect.

Interceptors are hash-map modifiers

Interceptors are hashmaps with an “:id, :before, :after” signature, where the :before and :after keys work with another hashmap of a “:coeffects, :effects, :queue, :stack” signature. Before the event fires, interceptors modify the context (hashmap) with functions mapped to the :before key. The event then fires with the modified context. The context then goes through the :after-bound functions, doing work after the main event has fired. This is useful for dealing with local storage with a Re-Frame db: pull the local storage before firing or push db state to local storage after firing.

Dual mining = less profit?

I think you’re required to mine 30% ETH and 70% another crypto in t-rex with dual-mining. I.e. you can’t flip it for 70% ETH and 30% RVN. The other crypto generally isn’t as valuable, whereas ETH constantly rises, making this less value then a strict 70% ETH operation. Further, dual-mining attempts to trick a smart hash-rate limiting program with variable shutdowns in LHR. Iiuc, solutions to this required underclocking the GPU to avoid hitting LHR limits.

Dave Martin's a Re-Frame master

How did Dave use Re-Frame to make Lobster Writer? He has the classic pages function which takes the subcription to the :active-page key of the db. This gets passed into a case which returns another component function, which gives whatever page. Clicking buttons changes this :active-page key, which updates the subscription, and gives a different page. Wielding reg-event-db, reg-event-fx, reg-fx, reg-cofx, and interceptors; using routing libraries like Bidi and Pushy; and working with misc libraries like React Quill, he makes a fluid and navigable SPA that works locally to streamline one’s writing of beautiful essays.

Git tracking differs from staging

I learned some Git principles and judo: tracking differs from staging: i.e.git commit -a stages and commits already-tracked files, and new files won’t be committed; git add . tracks and stages. by definition, files are tracked only when they are first staged/committed. There is no “track but not stage” for new files git diff is “staged - working directory”. git diff –staged is “commit - staged”. git status -s gives a concise description of what’s untracked, modified, and whether the modification is staged or not.

Files modified after staging need to be staged again to commit the latest changes in Git

A mystery of missing GitLab repo files motivated me to read the Pro Git book. I relearned the different VCS-es and models that back them: local, centralized, distributed; patch/delta vs. snapshot. I revisited the three areas a file can be in: working area, staging area, and the git repo. Per Chapter 2, I saw how a file can be both modified in the staging area and the working area at once.

Unquote splicing (`~@`) evaluates before stripping parentheses

To understand macros, I needed to understand unquote splicing. I used to think it peeled the parentheses off, but no: (= `(+ ~@(map #(+ 2 %) [1 2 3 4])) '(clojure.core/+ map #(+ 2 % ) [1 2 3 4]))`. ;;=> false Evident with the ~ unquote symbol, it lets the onion sprout (evaluate) first before peeling its layers 😄: (= `(+ ~@(map #(+ 2 %) [1 2 3 4])) '(clojure.

JS literals (`#js`) improve runtime performance over `clj->js`

I was making a “rapid-scheduling app” that uses the Google Calendar API , which required I convert Clojure maps into JS objects. This means the use of #js or clj->js I saw Paulus Esterhazy’s post which says I should do this: (def config #js {:apiKey "..."} :clientId "[...].apps.googleusercontent.com" :discoveryDocs #js ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"], :scope "https://www.googleapis.com/auth/calendar.readonly")) (.log js/console (.-discoveryDocs config)) ;; => ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'] This turned my vector to a GAPI-friendly array. The #js reader macro (also called a js literal?

Three lessons for JS interop in ClojureScript

A metaphor: I’ve turned my regular hand into this metal claw talon. That is, I’ve ironed out misunderstandings with JavaScript interop: (1) Global variables are in the js namespace (js/gapi not gapi); (2) If one . doesn’t work, use two .. 🙂 (If I’d examine the macro-expansion I’d understand why…); (3) Modeling JS’s obj.prop1.prop2.methodCall().prop3 syntax (i.e. calling all props, method calls, and subsequent props at once) seems out of reach atm– use nested forms: (-prop3 (.