#clojure logs

2017-01-08

06:34lxsameeris it ok to have a atom containing a hashmap which each value is an atom itself ?
06:35dysfunsure it's okay. but what are you trying to achieve?
06:37lxsameerdysfun: I'm polling some data from a remote service, I want to keep track of data changes, the data is a huge map, and i want to update the changed values only
06:38dysfuni don't understand the problem with using one atom
06:39dysfunis it a concurrency problem?
06:39lxsameerdysfun: i wanted to create an atom for each key and set a validation and a watcher so validation only allows new values to be set, and watchers trigger the behavior which i needed
06:40lxsameerdysfun: using one big hashmap in an atom, i can't find out what key changed
06:40lxsameerdysfun: how would you design such thing, I need it to be scalable
06:40dysfunsorry, what sort of data will these be?
06:41dysfunare you doing HFT or something?
06:41lxsameerdysfun: the data is a huge json containing stock market information
06:42dysfunokay. so then you process that and update your atom of atoms according to the new values?
06:42lxsameerdysfun: i had this in mind, but I'm open to new ideas
06:43lxsameerspecially my atom of atoms seems not scalable
06:43dysfunokay. so each piece of data is like {:symbol 'FOO" :price 1.23 ...} ?
06:43dysfunthat sort of thing?
06:44lxsameerdysfun: yeah right
06:45lxsameerdysfun: i was thinking about creating a queue using kafka or something
06:45dysfunnow you have two problems ;)
06:45lxsameerand put the values in the queue and have them process by nodes using core.async
06:45lxsameerdysfun: why ?
06:45dysfunwell, message queuing theory says exactly once delivery is hard
06:46dysfunso now we've got to check timestamps and such
06:46lxsameerdysfun: aha
06:46lxsameerdysfun: so what's you solution about this ?
06:47dysfunpick a database designed for storing exactly this sort of data. like riak
06:47dysfunyou can blissfully configure it in last-write-wins mode because that's exactly what you want
06:47dysfunor, if you don't actually need storage, shove it in a megaref
06:48lxsameerdysfun: megaref ? is it a clojure thing ?
06:48dysfunit's a library
06:48dysfunhttps://github.com/cgrand/megaref
06:48lxsameerdysfun: thanks man, i have to read about it, also the riak solution is cool too
06:49dysfuncool, have fun
07:03osfameronlxsameer: dysfun: kafka is pretty good as a queue
07:04lxsameerosfameron: i see
07:04dysfunsure, it is
07:04dysfunbut you have to know how it fails too
07:05osfameronah - we haven't come across particular failure modes - do tell more
07:05dysfunat-least-once != exactly-once will be the first one you'll hit
07:06osfameronah yes. we're making sure all of our consumers are idempotent, which must be as mitigation of that
07:06osfameronI've not followed all the details
07:06dysfunsomeone gets it
07:07osfameronbut yeah, that's easy enouhg for us to do with our particular use of it as a message bus, but might not work for other situations
07:08dysfunyeah. each situation needs it factoring in differently
08:58hiro`Anyone here read Web Development in Clojure? I've seen from the beta-version (which is floating around online) and the author's blog that he was using Yesql, but Luminus no longer uses it. Did the book get updated to use the Luminus stack (inc HugSQL, Yesql's replacement), does anyone know
08:58hiro`?
08:58dysfunthat's a fairly niche question, suspect you'd be better asking in the work week
08:58dysfunmaybe you could check the book's errata online?
08:59hiro`Had a quick scan through that already, couldn't find any reference to it.
09:01dysfuni guess probably not then
09:01dysfunshouldn't be too difficult to get up to date with hugsql though
09:01avicennaweb development with clojure version 2 uses hugsql as seen in the pragprog website
09:01dysfunah, there we go
09:01hiro`ah, that's what I was wondering.
09:01hiro`thanks avicenna
10:36machinewarany convention for naming clojure tests with deftest. deftest fn-name-test? perhaps
10:36dysfunthat's common
10:37dysfuntest-fn-name also
10:37dysfunjust pick a sane one and roll with it
12:04moncreyhey room, looking for a little insight into a missing namespace in a project.... the code runs fine but i cant for the life of me figure out where this library is coming from....
12:04moncreyline 9 of this file https://github.com/overtone/overtone/blob/master/src/overtone/sc/machinery/server/native.clj
12:05moncreypoints to a library that does not exist within that repository, or anywhere else within the organization's repositories.
12:06moncreynot assuming anyone will have the answer but ANY insight would help. so confused.
12:06moncreyif the library did not exist, the project would not run, correct?
12:07moncreyor at least, if it hit that required method, woudnt it throw errors??
12:36justin_smithmoncrey: require looks for a specific artifact inside a package, there'
12:36justin_smiths no rule saying that the name of the artifact require finds has any relationship to the artifact name
12:37scriptorI think they left
12:38justin_smithhmm
12:38rhg135So it can load runtime ns given it exists before hand?
12:41justin_smithwell the ns won't compile unless it can be found - but the point I was making was that there is no relationship required between the name of the ns that require looks for, and the name of any artifact you use
12:44rhg135I see, so a file foo/bar.clj can have ns bar.baz and you require it as foo.bar?
12:44justin_smithrhg135: more like a dependency org.foo/bar can have a file src/baz/quux.clj and you can require it via baz.quux
12:45justin_smithbut the code referencing baz.quux doesn't help you find foo/bar
12:45justin_smithit does appear something is funky here though? https://github.com/search?q=org%3Aovertone+nativescsynth&type=Code
12:46scriptormy guess is that it's from this dependency https://github.com/overtone/overtone/blob/master/project.clj#L62
12:46scriptorcan't find a github of that anywhere
12:47justin_smithbased on the name, I would assume it is the piece of code that tells you which engine is actually present
12:47justin_smithsince overtone uses a big c++ program for all the synthesis, and it needs a different version for every OS configuration
12:49justin_smithit would actually make sense for that data to be provided by the dependency itself (which wouldn't be part of the overtone github, it's a compiled binary)
12:53justin_smithFOUND IT [overtone/scsynth "3.5.7.0"] https://clojars.org/overtone/scsynth/versions/3.5.7.0
12:53justin_smithit's the only clj file in a big blob of native code blobs
12:56justin_smiththat ns in one line: (ns overtone.nativescsynth.availability) (def native-scsynth-lib-availability {:windows {64 false 32 true} :linux {64 true 32 false} :mac {64 true 32 true}})
13:28machinewargoing to post this function I'm working on in case anyone feels like helping refactor and make it more idiomatic clojure. https://gist.github.com/AlexWheeler/7d6a97978e51a036367de42936da8fae#file-clj-clj-L7. comments appreciated
13:31osfameronmachinewar: body of copy-nil-vals could just be: {k (or v k)}
13:32osfameronhmm, that's slightly different semantics, would also overwrite false
13:32osfameron{k (if (nil? v) k v)} I suppose
13:33osfameronwhy do you need to (apply merge) twice?
13:34ridcullymachinewar: could you please also through in some small data example? e.g. going from [{:value 42 :mapped_value 666}] -> {42 666} ?
13:34machinewaryep
13:36ridcullymy gutfeeling is, that you take a lot of "reshaping" steps in between, where something like (into {} (map (juxt :value :mappeD_value)) columns) brings you already close
13:37ridcullythrow in your nil handling around that juxt
13:37machinewaryep that's what I'm thinking. this was my intuitive way of doing it step by step, but figure there's a better way. Cool I'll play a bit with that thanks a lot
13:38osfameronoh, the juxt/into thing is nice ridcully!
13:39osfameronI'd have approached it with a dumb (fn [{keys [:value :mapped_value]} ...)
13:39ridcullywell you have to deal with that nil check there still. so destructuring instead of the juxt is fine
17:18osfameronoh dear, I got lost in http://prog21.dadgum.com/ again
19:48VincentdmHi, I'm new and trying to understand multimethods. I would like to define (defmulti) in one file (namespace), and then use separate files for implementations (defmethod). However, this seems to require a circular dependency.
19:49VincentdmI thought the whole point of such dispatching was that code could require only the namespace that contains (defmulti), and it would call the right implementation automatically.
19:53justin_smithVincentdm: why would that require a circular dependency?
19:53justin_smiththe file that defines a multimethod doesn't need to know about the implementations
19:54justin_smithand no, only requiring the file with the defmulti is not the point, at all
19:54justin_smithyou only need to require the implementations in one place, and every other location can just use the defmulti though
19:59VincentdmHi Justin, seems you are right. My code was faulty (I copt-pasted a ::keyword when moving the defmethod), which caused the dispatching to stop working. This lead me to believe it didn't "find" the defmethod implementation
20:01VincentdmSo when calling a multimethod, Clojure will basically consider defmethods in whatever file, as long as it is included in the project dependencies?
20:01justin_smithVincentdm: no
20:01justin_smithVincentdm: the namespace with the defmethod needs to get loaded (usually via require)
20:01justin_smithit can be loaded anywhere, but it needs to be explicitly loaded, there is no implicit loading of code
20:02Vincentdmok, good to know that
20:02VincentdmSo that means that I cannot add a new implementation of a multimethod, without explicitly referring to it from a more "general" place (which is actually not supposed to know this specific implementation exists)
20:02Vincentdm?
20:06justin_smithVincentdm: define "supposed"
20:06justin_smithVincentdm: the general pattern is you have a bunch of code that refers to the multimethod, and then one place that loads all the defmultis
20:06justin_smithusually a top level namespace that loads your config and starts everything up will also load up all those implementations
20:08justin_smitherr, make that "all the defmethods"
20:08VincentdmWell, I need to work with API's of different vendors, and I was hoping that I could add implementations of new APIs just by adding a new file containing defmethods. But based on your answer I understand that I will also need some central place loading all the implementations
20:08justin_smithsure, you need a top level namespace that controls that stuff, clojure avoids magic
20:08justin_smithbut I misspoke above - you refer to the defmulti everywhere, and only load the files with defmethods in one place (usually your top level ns that also sets up your config)
20:10VincentdmOk, that's clear. As I understand it now multimethods are more about providing a clean syntax (so you don't need to do if/else/.... to dispatch incoming data to the appropriate functions), but it is not really a solution for reducing dependencies.
20:10VincentdmSince I see no real difference between referring to my implementations from within the NS that does the defmulti compared to some other central namespace.
20:10justin_smithVincentdm: yeah, we don't do implicit DI
20:10justin_smithit's just not a thing clojure does
20:11VincentdmAlright. Thanks for clarifying that!
20:11justin_smithbut all that requires is a single require
20:12justin_smithVincentdm: for clarity, I usually find it useful to special case my top level namespace
20:12VincentdmWhat do you mean with "special case"?
20:12justin_smiththat is to say, that namespace breaks some rules the rest of my namespaces follow, because it has to configure everything else and decide how startup happens and what resources we use etc.
20:13Vincentdmok, right
20:13justin_smithit doesn't do "just one thing" - it puts together all the pieces to make everything run (but ideally it does this without also implementing program logic)
20:14justin_smithso that would be the namespace that injects clojure dependencies (since unlike classes they are not injected by just having them on the classpath and referring to something they define)
20:15VincentdmOk, I see. Reminds me of the whole Stuart Sierra Component stuff. With an entrypoint that's responsible of setting everything up
20:15justin_smithexactly - I do that too
21:50tjmayneshello
22:56TimMcpuredanger: I really appreciate the clojure.org HTTPS redirect!
22:57puredangernp
22:57TimMcIs that TLS from Cloudfront back to the origin too?
22:59TimMcI've been going around today poking people about HTTPS and it has been surprisingly productive. :-D
22:59puredangerthe origin is S3 in this case
23:00TimMcAh, got it. So that's good.
23:00TimMcInteresting that you can't attach HSTS for CF. I understand it for S3, though.
23:00puredangerI found some places where people were complaining about it
23:01puredangersounds like it might be something they will add
23:01puredangerif they do, I'll add it
23:02TimMcOh, I remember this now, someone at work was dealing with this -- you can't add *any* custom headers to a CF distribution.
23:05puredangeryeah