anchor.diff:  Most people will find the most leverage in the "Connect" features, which allow you to quickly build dynamic
   query processing systems to easily satisfy client data requests.
   
  +== Aliases Used in Code Examples
  +
  +Throughout the book our code examples will use aliases instead of explicit namespaces. The aliases used are as if we
  +had the following namespace requires:
  +
  +```
  +(ns my-namespace
  +  (:require
  +    [com.wsscode.pathom.connect :as pc]
  +    [com.wsscode.pathom.core :as p]))
  +```
  +
  +So, any time you see a usage of a namespace in a keyword or function like `p/parser` or `::p/reader` you should remember
  +that these are the namespaces involved.
  +
   == Presentation
   
   If you like to learn by seeing presentations, I did one at https://www.youtube.com/watch?v=r3zywlNflJI[Dutch Clojure Days 2018].
  
positive.code:    :arya    #:character{:name "Arya Stark" :tv-show-id :got}
     :morty   #:character{:name "Morty Smith" :tv-show-id :rm}
     :ygritte #:character{:name "Ygritte" :tv-show-id :got}})
  
  ; Helper functions are always handy when parsing.
  ; In this case we only need the db from our parsing environment,
  ; but taking env as a parameter makes calling it easier and enables
  ; evolution of env without intrusive API changes.
  (defn characters-by-ids
    "Return a list of charaters for the given character IDs from the current parsing env"
    [{::keys [db] :as env} ids]
    (map (get @db :characters) ids))
  
  (def computed
    ; example of a "global attribute": returns a random character from our
    ; database, and can be fetched without regard for context.
    {:characters/random
     ; pretend the db is your datomic database or a Postgres connection,
     ; anything that would enable you to reach the data
     (fn [{::keys [db] :as env}]
       (let [character (rand-nth (-> @db :characters vals vec))]
         ; Use `join` to recursively parse the sub-query with the new to-one entity context
  
negative.code:      ; just give a count on members, and again, will raise exception if
       ; :tv-show/character-ids fails to be reached
       (count (p/entity-attr! env :tv-show/character-ids)))})
  ----
  
  Finally we can define the parser itself.  Note that we add in a `p/map-reader` to do the work of looking up any
  queried attributes that we've already placed in the environment (via `join` and `join-seq`):
  
  [source,clojure]
  ----
  (def parser
    ; This time we are using the env-plugin to initialize the environment, this is good
    ; to set the defaults for your parser to be called. Also, we are attaching the built-in
    ; reader map-reader on the game, so it will read the keys from the entity map. Check
    ; Entity page on wiki for more information.
    (p/parser {::p/plugins [(p/env-plugin {::p/reader [p/map-reader computed]})]}))
  ----
  
  Now we can call the parser any number of times with various queries. Note that this is where we're injecting our
  simple map-based database into the environment:
  
  [source,clojure]
  ----
  ; call the parser, create and send our atom database
  (parser {::db (atom {:characters characters
                       :tv-shows   tv-shows})}
  