mount

bill 2017-02-02T00:00:33.000643Z

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.

bill 2017-02-02T00:02:20.000645Z

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)

bill 2017-02-02T00:03:59.000646Z

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.

tolitius 2017-02-02T01:41:31.000654Z

back

tolitius 2017-02-02T01:44:01.000655Z

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

tolitius 2017-02-02T01:45:15.000656Z

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

tolitius 2017-02-02T01:48:04.000657Z

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}}}

tolitius 2017-02-02T01:48:53.000659Z

so I am not sure how you would make:

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

tolitius 2017-02-02T01:50:05.000660Z

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.

tolitius 2017-02-02T01:51:37.000661Z

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

bill 2017-02-02T14:32:34.000664Z

@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.

bill 2017-02-02T14:37:55.000665Z

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.

tolitius 2017-02-02T16:19:52.000666Z

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) 🙂

bill 2017-02-02T16:43:47.000667Z

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!

tolitius 2017-02-02T16:49:27.000669Z

🙂

tolitius 2017-02-02T16:49:36.000670Z

it's IDeref for now

tolitius 2017-02-02T16:49:58.000671Z

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

bill 2017-02-02T17:13:43.000672Z

I see.