Fork me on GitHub
#mount
<
2017-02-02
>
bill00:02:33

I think I’m understanding Mount better now. From the examples:

(ns app
  (:require [above :refer [conn]]))
I can refer to conn in my fn bodies just fine. It’s just that there will be only one value ever bound to above/conn.

bill00:02:20

This seems to me kind of like Leiningen profiles but without: a) Leiningen profiles (that is, an extra EDN config file on disk) b) the overhead of Leiningen (Mount does a lot less than lein does)

bill00:02:59

For my use case, if I wanted to have a single db-access ns talking to two databases I’d have to do that in separate Yurts. Otherwise I could add that db parameter back to all the fns in my ns and then that ns wouldn’t be using Mount.

tolitius01:02:01

yes, mount creates a "managed var" that besides abilities to be "managed" on start / stop behaves like a regular Clojure var. hence

(defn people []
  (query db "select * from people"))
would only use one instance of db, unless of course it is rebound for the scope, which I would not recommend doing, since db is a resource, and it would make it more complex to follow

tolitius01:02:15

I don't see anything wrong with having this fun taking a db:

(defn people [db]
  (query db "select * from people"))
since it makes this function to be "independent" of the db

tolitius01:02:04

when you create multiple yurts they are just multiple maps of components. here is one:

{:components
 {"neo.conf/config" {:www {:port 4242},
                     :nrepl {:host "0.0.0.0",
                             :port 7878} ...},
  "neo.db/db" {:conn #object[datomic.peer.LocalConnection...]},
  "neo.www/neo-app" #object[org.eclipse.jetty.server.Server...],
  "neo.app/nrepl" <#C03S1KBA2|clojure>.tools.nrepl.server.Server{:server-socket #object[java.net.ServerSocket... },
 :blueprint
 {"neo.conf/config" {:order 1},
  "neo.db/db" {:order 2},
  "neo.www/neo-app" {:order 3},
  "neo.app/nrepl" {:order 4}}}

tolitius01:02:53

so I am not sure how you would make:

(defn people []
  (query db "select * from people"))
work if it does not take db

tolitius01:02:05

what yurt does, it uses mount to "collect" all the state names and state start/stop functions and then detaches them from vars: i.e. they are no longer attached to any namespace / var.

tolitius01:02:37

just curious, why are you after removing db argument from db functions?

bill14:02:34

@tolitius I see the benefit of pure functions so I see why passing db to people is good. On the other hand I like the brevity that a dynamic var gives me within a namespace. The traditional, and awful, way, that I often see the db-access ns implemented is with a dynamic var holding db. This lets callers use the ns with-bindings to change the default db. The downside, of course, is that with-bindings operates per thread. But the upside is that if I have 20 functions in the ns and they all need the db, none of the fns have a db arg. Instead they get their db from the dynamic scope.

bill14:02:55

It seems that Mount will support this just fine. I can build up db as state and I can require it wherever it is needed. When I require it, I put it into the lexical scope, where it (`db`) can be accessed from function bodies. I understand that this is arguably inferior to pure functions, but it would be valuable for existing namespaces that are written using dynamic vars for config data. It’s also valuable for new namespaces where I do not want to require the caller to provide (global) config state like db. If, as you say, there can be only one db per VM/Pod, then it seems reasonable that some developers might choose to leave that argument off of their argument lists.

tolitius16:02:52

cool. I would be curious to see: > When I require it, I put it into the lexical scope, where it (`db`) can be accessed from function bodies. once you done (have some examples) 🙂

bill16:02:47

Just saying that e.g. start-nyse here: https://github.com/tolitius/mount/blob/master/dev/clj/app/www.clj#L32 Could have referenced the conn from the lexical scope instead of making it part of the arg list. Doing so would make g. start-nyse impure. But there are situations where I'd like to try that. Co-opting the namespace mechanism and IRef is brilliant!

tolitius16:02:36

it's IDeref for now

tolitius16:02:58

IRef (to add watchers) is just an idea I had