mount

2016-01-21T07:21:16.000412Z

@tolitius: Boot App Version: 2.0.0 Boot Lib Version: 2.1.2 Clojure Version: 1.6.0 But it's okay, I've been using mount on my own project successfully so far :simple_smile:

tolitius 2016-01-21T14:20:07.000413Z

@bbss: great, thanks for the feedback. This is probably minor then, but whenever you have a chance, could you try to upgrade boot (`2.0.0` is a bit old):

$ boot -u
Retrieving boot-2.5.5.jar from <https://clojars.org/repo/>
#<http://boot-clj.com>
#Thu Jan 21 09:18:36 EST 2016
BOOT_CLOJURE_NAME=org.clojure/clojure
BOOT_VERSION=2.5.5
BOOT_CLOJURE_VERSION=1.7.0
and do boot cljs-example?

jrychter 2016-01-21T20:02:12.000415Z

I'm transitioning to mount and slowly getting the hang of it. But I'd like to ask for some guidance. I have a namespace app.config where normally I used to keep a config atom. This gets initialized with config data read from a file. Problem is, the filename is normally supplied from the command line, in my app.main namespace's main function. What is a reasonable way of passing that filename to app.config defstate functions?

tolitius 2016-01-21T20:04:57.000416Z

@jrychter: welcome! :simple_smile: would something like this work for you: https://github.com/tolitius/mount/blob/master/doc/runtime-arguments.md#passing-runtime-arguments ?

jrychter 2016-01-21T20:05:16.000418Z

Also, is the :refer [config] magical in some way, or will mount work just as well with (:require [my.namespace]) and calling my.namespace/accessor?

jrychter 2016-01-21T20:05:56.000419Z

@tolitius: I don't know how I missed that when reading the docs…

tolitius 2016-01-21T20:06:13.000420Z

:refer [config] is same as Clojure: i.e. my.namespace/accessor would also work

tolitius 2016-01-21T20:06:40.000421Z

@jrychter: it's the last thing.. I might need to reorganize the docs a bit

jrychter 2016-01-21T20:07:15.000422Z

Ok, the mount/start-with-args approach could work. I don't yet see how to make this elegant (e.g. only pass a limited number of well-behaved arguments to mount), but I just need to think about it.

jrychter 2016-01-21T20:08:26.000423Z

Yes, in general I think the docs could be improved. I found them difficult to follow and understand and I think this is preventing people from using mount. Please take this as an observation, rather than critisism, I don't want to sound rude or ungrateful.

tolitius 2016-01-21T20:08:48.000424Z

are all the config values in the external config file, or you are looking to overwrite some of the values in config with something like -D?

tolitius 2016-01-21T20:09:28.000425Z

@jrychter: not at all, great feedback. what (re)organization would you feel help the most?

jrychter 2016-01-21T20:09:32.000426Z

No, the idea is that I just pass the filename. The config ns deals with everything else, such as creating the file if it doesn't exist, or reading configuration from an existing file. So it's just one string-or-nil value.

jrychter 2016-01-21T20:10:22.000427Z

As for docs, when I was reading them, I thought: that's a strange way to begin. For example, they begin by outlining differences from component, which I don't really care about unless I'm comparing the two. But to compare, I have to learn how mount works anyway, so…

jrychter 2016-01-21T20:10:46.000428Z

I think I expected a short outline of the mount approach and then a meaningful reasonably complete example.

jrychter 2016-01-21T20:11:25.000429Z

I write a lot of documentation, so perhaps if I learn to use mount, I could contribute a gentle introduction.

jrychter 2016-01-21T20:12:37.000430Z

Also the 'Value of values' section seems superfluous — I found the behavior obvious. Am I missing something? This is exactly what I expected, so I couldn't understand why there was a section on it.

tolitius 2016-01-21T20:15:36.000431Z

:simple_smile: great. I agree with "a short outline and reasonably complete example", feels more effective. I did include component there because a lot of the people use component, and would be questioning why they need mount. I think it is logical to remove it a bit later, when mount is as familiar (which is slowly happening) "value of values" this was not possible in earlier versions of mount ( https://github.com/tolitius/mount/issues/20 ), and a couple of people asked this would be documented

jrychter 2016-01-21T20:16:20.000433Z

I think in general the documentation is complete, it's just the structure and ordering which can be confusing to newbies like me.

tolitius 2016-01-21T20:16:43.000434Z

the example is there: https://github.com/tolitius/mount/tree/0.1.9-SNAPSHOT#mount-and-develop a ""a short effective outline" would definitely help

jrychter 2016-01-21T20:16:49.000436Z

So, do I understand correctly that mount/start-with-args can take any value, such as a map with options that I want to pass to my components?

jrychter 2016-01-21T20:17:08.000437Z

Yes, the example is actually how I figured out how to use mount.

tolitius 2016-01-21T20:17:58.000438Z

there is also a cljs one, in case you need it in the future: https://github.com/tolitius/mount/blob/0.1.9-SNAPSHOT/doc/clojurescript.md#mounting-that-clojurescript

tolitius 2016-01-21T20:18:10.000440Z

yes, mount/start-with-args can take any value.

jrychter 2016-01-21T20:18:26.000441Z

Though I think it could immediately be enhanced by adding my use case to this https://github.com/tolitius/mount/blob/0.1.9-SNAPSHOT/dev/clj/app/conf.clj (passing the config file name through mount/start-with-args

jrychter 2016-01-21T20:19:06.000443Z

I actually need the ClojureScript one immediately :simple_smile: All my apps are Clojure + ClojureScript. And the one I'm migrating is fairly large on both sides — it's https://partsbox.io/

jrychter 2016-01-21T20:19:43.000445Z

I began on the Clojure side, because it's slightly easier and there are better debugging tools.

tolitius 2016-01-21T20:20:52.000446Z

right, so this file name (i.e. "dev/resources/config.edn") maybe the only thing you pass via -D, and then something like:

(defstate config 
  :start (load-config (:config-path (mount/args))))
would work

tolitius 2016-01-21T20:21:47.000448Z

where it would be pass as (for example) -Dconfig-path=xyz/resources/config.edn

jrychter 2016-01-21T20:22:43.000449Z

I'm reworking my configuration and trying things out as we speak.

tolitius 2016-01-21T20:23:11.000450Z

<http://partsbox.io|partsbox.io> looks cool :simple_smile:

jrychter 2016-01-21T20:23:21.000451Z

thanks

jrychter 2016-01-21T20:23:43.000452Z

BTW, I clicked on the ClojureScript docs immediately, read about derefing, then jumped into Clojure and was surprised that derefing doesn't work :simple_smile:

tolitius 2016-01-21T20:24:01.000453Z

yea, if you need to use mount in both Clojure and ClojureScript I would recommend reading: https://github.com/tolitius/mount/blob/master/doc/clojurescript.md#managing-state-in-clojurescript

jrychter 2016-01-21T20:24:28.000455Z

This is exactly what I started with.

jrychter 2016-01-21T20:25:21.000456Z

Oh, a practical observation: it was (and still is) unclear to me where the (mount/in-cljc-mode) form needs to be placed.

tolitius 2016-01-21T20:25:28.000457Z

oh.. ok. yes, (mount/in-cljc-mode) will switch mount into a mode of derefing. All APIs are going to work consistently between clj and cljs.

tolitius 2016-01-21T20:26:01.000458Z

anywhere before (mount/start)

jrychter 2016-01-21T20:26:04.000459Z

So where does it go? In both Clojure and ClojureScript code (my code isn't cljc)

tolitius 2016-01-21T20:26:36.000460Z

sure, cljc is just a name to indicate that it supports both.. I guess it might be too geeky of me :simple_smile:

jrychter 2016-01-21T20:26:37.000461Z

…and (I think this is what the docs say) does this mean that I will be using @ to access Clojure state as well?

jrychter 2016-01-21T20:27:22.000462Z

So I should call (mount/in-cljc-mode) both in my server-side app and in ClojureScript code, anywhere before (mount/start) to get the same API in both worlds.

tolitius 2016-01-21T20:28:32.000463Z

yes, in case you need to work in both modes, I would recommend to call (mount/in-cljc-mode) at the app entry point, and use @ to access your states (there is a cljs app example). (!) you don't have to do that at all, and work without @ in both clj and cljs, but you might have problems with cljs :advanced optimization mode. this was the sole driver for this mode

jrychter 2016-01-21T20:29:06.000464Z

Actually, I really prefer that mode. Even for aesthetic reasons, I find @ logical to use in case of state.

jrychter 2016-01-21T20:29:20.000465Z

And I do need :advanced very much :simple_smile:

tolitius 2016-01-21T20:29:50.000466Z

right.. this is from docs (with one of the points you agree with already): While initially it may sound strange, this approach has very nice properties: * Mentally something that you deref (@) is associated with a state behind it * The whole system may start lazily without an explicit call (mount/start) * States may have watchers which is just an idea at this point, but it could be quite useful

jrychter 2016-01-21T20:30:24.000467Z

I fully agree and I don't think this sounds strange at all. I always had state encapsulated in atoms, and always used @ to access it.

jrychter 2016-01-21T20:31:18.000468Z

Sigh. I regularly break things completely by making an error in the :stop function, which means I can't stop the system, which means I can't reload the namespace :simple_smile:

tolitius 2016-01-21T20:32:18.000469Z

in the REPL, you could get a reference to the sate var, and stop it manually

tolitius 2016-01-21T20:32:30.000470Z

for example, say you have a web server as a state:

tolitius 2016-01-21T20:32:53.000471Z

(defstate web-server :start (...) :stop (.. with error ...))

tolitius 2016-01-21T20:33:23.000472Z

when you call (mount/stop), the :stop of the web server would error out / or won't stop the server

tolitius 2016-01-21T20:33:32.000473Z

from the REPL you can do:

tolitius 2016-01-21T20:33:47.000474Z

(require '[myns :refer [web-server]])

tolitius 2016-01-21T20:34:02.000476Z

(.shutdown web-server)

tolitius 2016-01-21T20:34:13.000477Z

i.e. if .shutdown is a correct way, of course

tolitius 2016-01-21T20:35:58.000478Z

answering your previous question: on the cljs side you don't need to call (mount/in-cljc-mode)

jrychter 2016-01-21T20:37:24.000479Z

Oh, ok. See, this is what is missing in the docs :simple_smile: I think they should simply say: in Clojure code, call (mount/in-cljc-mode) before (mount/start), which will change the API so that you will need to deref (`@`) state.

jrychter 2016-01-21T20:37:58.000480Z

Thank you for all your help, and thank you for writing mount, which I really like so far. Once I get comfortable using it, I will try to contribute to the documentation.

tolitius 2016-01-21T20:38:49.000481Z

sure, that'd be great, thank you :simple_smile: