#clojure logs

2015-03-12

00:00justin_smithsejje: it's odd that it uses the term "confusing" instead of the more standard "conflict", might be worth making a pr for
00:00sejjearen't you just the fountain of knowledge!
00:01sejje(inc justin_smith)
00:01lazybot⇒ 207
00:02justin_smithsejje: I have never regretted the time I wasted learning to do things by hand with the Linux CLI while my peers were pointing and clicking :)
00:03sejjei'm about a decade into my linux foray, it's my daily. haven't run into that issue, though. and i'll admit my knowledge is still a bit superficial.
00:03sejjei've had to fix about 25 wifi card driver issues, though...
00:03justin_smithheh
00:04sejjejustin_smith: hopefully one last question...what's this syntax? :exclusions [com.cognitect/transit-clj]] -> [org.clojure/data.json "0.2.5"]
00:05amalloyjustin_smith: i think that's because it doesn't tell you aobut every conflict, only those that it thinks might surprise you
00:05justin_smithamalloy: oh, I guess that would be a nuance
00:05justin_smithyeah, it won't list the things you have proper :exclusions for
00:05amalloyeg, if you ask for a recent version, and some library asks for an older one, it assumes you are doing that an purpose and that it won't cause problems (though IMO that is not particularly true)
00:06justin_smithoh, it doesn't list conflicts when you ask for an explicit version at the top level? that's an odd choice, I would have expected an explicit exclusion
00:07razum2umis there any videos from http://euroclojure.com/2014/#programme-jump ?
00:07justin_smithsejje: it's saying [foo/bar :exclusions [com.cognitect/transit-clj]] pulls in a dep for [org.clojure/data.json "0.2.5"]
00:07amalloyi believe that's the case, but try it and see if i'm wrong, of course
00:07justin_smithsejje: replacing foo/bar with whatever was actually in your deps output of course
00:13raspasovhey guys - anyone with Cursive + ClojureScript experience, what's the state of the union on that ? :)
00:19dnolenraspasov: code navigation, completion, etc. works great. REPL bits need a lot work, but cfleming is on it as far as I know.
00:19raspasovdnolen: cool, are you using it from Cursive? can you eval from IntelliJ into the browser?
00:19raspasovor better to just hit refresh? :)
00:20dnolenraspasov: no I'm sick of ClojureScript tooling, it's Clojure scripts fed to the ClojureScript compiler for me
00:21raspasovdnolen: ok cool! thanks :)
00:21dnolenhowever, the goals is to stabilize the fundamentals to the point that downstream tooling can be productive for the people that want it
00:37sejjejustin_smith: that moment when the problem wasn't a dependency issue...sigh. all resolved, ring still won't start. ::throws desk::
00:37nuwanda_raspasov: you can eval from intellij into the browser
00:38raspasovnuwanda_: yea? nice - how do I hook it up?
00:38raspasovdo you Import the project into IntelliJ?
00:38raspasovjust started following https://github.com/omcljs/om/wiki/Basic-Tutorial
00:38raspasovgot Figwheel and the Hello World
00:38raspasovhaven't touched Cljs in months, trying to get up to speed :)
00:40nuwanda_raspasov: yeah, you can import lein projects into intellij
00:40nuwanda_you can follow cursive's guides to starting repls etc
00:41raspasovok got that, how do I hook up the repl? I do it all the time with JVM Clojure
00:41raspasovbut this doesn't seem to work that way
00:41nuwanda_they have instructions on the website on how to get their repl started inside the ide
00:41nuwanda_you can start a browser repl inside that one
00:42nuwanda_and then you normally use whatever is the default keybind for "eval form in repl"
00:51sejjehttp://pastebin.com/DXUqK7ny if anyone has any insight, i'd surely appreciate it!
00:53justin_smithsejje: looks like something that happened when you were loading watt
00:54sejjejustin_smith: it's definitely related to watt, as removing the :require from home.clj leaves things running smoothly. fwiw i've used watt in a non-web (luminus) project with no issues.
00:55sejjesome brief googling made me suspect a dependency issue, based on similar issues (but for other projects)---but alas, that doesn't seem to have helped.
00:55sejjedoesn't help that i find clojure stack traces fairly incomprehensible
00:55justin_smithsejje: do you have a link to watt.core? clojure watt isn't a useful google search from here
00:55justin_smithwatt.core is where the error is being reported
00:56sejjehttps://github.com/nicknovitski/watt/blob/217e3a28ecc01f77282faad265c5a42e47268765/src/watt/core.clj
00:57sejjebtw, an aside: does the stacktrace report line 1 (in watt/core) because it's ignoring whitespace?
00:58justin_smithsejje java.lang.ClassNotFoundException: org.apache.http.conn.ssl.SSLContexts
00:58puredangerclj_http.conn_mgr imports org.apache.http.conn.ssl.SSLContexts
00:58justin_smithand that's the error, right
00:58puredangerwhich is from org.apache.httpcomponents/httpclient
00:58justin_smithsejje: manually add that dep (or change the version you get so you get that class defined)
00:59puredangerthat seems to be in the deps list so not sure why that wouldn't get picked up
01:00justin_smithpuredanger: he was messing with version conflicts though, it could be he settled on a version that did not provide that class?
01:01puredangerit's in the 4.2.1 that's in the deps tree
01:01justin_smiththat's weird
01:01sejjeso guys, adding this ([org.apache.httpcomponents/httpclient "4.3.5"] ) to project dependencies fixed the issue, but i don't understand why--i had to explicitly exclude that when importing watt (and several other libraries) to satisfy lein deps
01:02puredangerwas just going to say it looked like you had excluded it
01:02puredangerwhy?
01:02clojurebotwhy is the ram gone
01:02puredangersometimes I hate clojurebot
01:02sejjebut i only had to exclude it because lein thought it conflicted, right?
01:02justin_smithclojurebot: are you really that bad??
01:02lazybotjustin_smith: What are you, crazy? Of course not!
01:02clojurebotExcuse me?
01:03puredangerit looks to me like leiningen itself is also excluding it so maybe that was causing something weird
01:03sejjepuredanger: it had the issue before i excluded it--i did that because i thought it was a dependency conflict (lein deps :tree recommended it0
01:04justin_smithyou know, if there were a unicode for waldo, we could put one in every stack trace
01:04puredangerjust fyi (not that this would necessarily help you), but in clojure 1.7.0-alpha5 (can't remember which alpha it was changed exactly), imported classes are not loaded.
01:05sejjegiven these stack traces, it'd actually be a task to find him
01:06hiredmansejje: have you looked at `lein deps :tree` ?
01:06sejjehiredman: yessir, thanks. we actually got it sorted, just talking about the aftermath at this point.
01:07sejjehiredman: i had satisfied all of the :tree recommendations for conflicts
01:07hiredmanlikely you have two deps pulling in different versions of httpclient, so lein just picks one, and the one it picks doesn't work
01:08hiredmanso you have to explicitly tell it which transitive dep to pull in, either by excluding one, or declaring a non-transitive dependency on one
01:08sejjeyeah apparently the remaining one wasn't recent enough, or was broken in some way. setting it explicitly in deps fixed it.
01:19domokatois it sufficient to store a cache (map) as an atom, even though there is a gap in time between a cache miss and adding to the cache?
01:21justin_smithdomokato: atoms don't lock, if that's your concern
01:21justin_smiththey retry if there is a conflict
01:22domokatothe worst that would happen is an item would be added to the cache twice but one of them would be lost, which should be fine
01:22domokatoright?
01:22justin_smithdomokato: depending on how you write the function that you pass to swap!, it can refuse to associate data if it is already present
01:23justin_smithbut do be aware that swap! will retry, so don't put side effects in the function
01:24domokatoi'm just using assoc
01:24domokatopassing assoc to swap!*
01:24justin_smithOK, that will just overwrite - I'm more trying to point out that writing a function with the preserving / overriding behavior you like is an option
01:25hiredmanassoc in a delay
01:26hiredman(swap! cache (fn [m] (if (contains? m k) m (assoc m k (delay get value))))) (force (get cache key))
01:26hiredman@cache
01:34domokatohiredman: hm, how does that help?
01:36domokatothe problem is I don't want to perform a swap! if the cache already contains the value, so I can't put the cache lookup in the function passed to swap! Unless...there's no harm in doing a swap! with no changes?
01:38domokatohm, actually the retrying thing might be a problem in the case where I'm trying to create a new Texture; I don't want to leave extra of those laying around
01:39domokatoI guess I'll have to use locking then?
01:39justin_smithdomokato: that's what the delay helps with
01:40domokatooooo, i get it
01:40domokatoneat, thanks!
01:45domokatoi don't get the (delay get value) part, though. The get is basically a noop, right?
01:46justin_smithyeah, I think he meant (delay (produce result))
01:46justin_smithor whatever
05:01doritostainsthere's a dependency in my project for tools.nrepl 0.2.6 but I don't know where it's coming from. I have 0.2.7 in my dependencies list but it's not taking. lein deps :tree doesn't show me any information about a conflict
05:01doritostainshow do I track down where 0.2.6 is being pulled in from or force 0.2.7?
05:05TEttingeris it a dev-dependency?
05:05TEttingernot sure if deps :tree shows those
05:07doritostainsyeah it has a :scope of "test"
05:07doritostains [org.clojure/tools.nrepl "0.2.6" :scope "test" :exclusions [[org.clojure/clojure]]]
05:12cflemingdoritostains: That's injected by Leiningen. I'm not sure why it wouldn't take your explicit dependency though.
05:14doritostainscfleming: yeah I did lein upgrade and it says I'm at the lastest version. I'm confused, I'll try also adding the dependency to the dev profile
05:16hyPiRiondoritostains: https://github.com/technomancy/leiningen/issues/1840
05:17doritostainshyPiRion: excelent, thanks!
05:18doritostainswas going to try that but forgot the exclusion, greatly appreciate it
05:19hyPiRionnp :)
05:22doritostainsworking perfectly now, it's goign to be a good night!
05:52eglihyPiRion: your solution for upgrading the dependency of tools.nrepl only works for dev builds, doesn't it?
05:52egliwhat if I want to include a repl in my production build?
05:54hyPiRionegli: I think it should work fine if you just copypaste that into :dependencies instead
05:54hyPiRionbut if not then there's probably an issue up on lein's tracker
05:54eglihyPiRion: ah, cool thanks
06:44mpenetis there a not awfull way to get to the methodTable keys in a defmulti ?
06:44mpenetappart from (-> x bean :methodTable keys)
06:49mpenet`nevermind
07:42noncomi have some general style question
07:43noncomwhen you write things like (map ... coll) or (filter ... coll), then - how do you usually do it - do you first write (map coll) and then put the cursor in the middle and write the fn or do you first write the fn and then the coll? (and init in case of reduce, if needed)
07:43noncomi find myself always writing like (reduce init coll) and then returning to (reduce | init coll) and writing the actual fn...
07:43noncomseems kinda strange to me...
07:44agarmanit's not unusual
07:44nsjphi usuall wrap it... (map .. coll) then figure out what to do in-between
07:45noncomwhy then don't we have (map coll ...) instead of (map ... coll) ? is it because the map is a verb and we map the fn over coll, and not coll over fn ?
07:45nsjphthat's a great question, but i'm not knowledgeable to answer it
07:46nsjphoh
07:46nsjphwell
07:46nsjphusually with the notation method, you have the arguments last
07:46nsjph(+ 1 1) for instance
07:46clojurebot2
07:46nsjphso (map .. coll) has the arguments last as well
07:47nsjphso with map, but the function and collection are arguments
07:48nsjphgiven that you might re-use that in the future, with varying arguments, i would tend to agree that you leave coll as the final argument
07:48nsjphif the (map f ...) usuall remains unchangeed
07:52stuartsierra*Sequence* functions (map, filter, reduce) take the sequence last. Almost everything else, including non-sequence collection functions, takes the "primary" argument first.
07:54nsjphfor newcomers, it might feel a bit weird, but the consistency helps when you use other sequence funcs
07:56gfredericksI've always thought that a lot of things take a function as the first arg because it's occasionally useful with partial
07:57gfredericks(def compact (partial remove nil?)) ;; e.g.
07:57agarmanyeah, no use of partial application over a collection
08:07tickingany idea what could cause wrong line numbers for IllegalArgumentExceptions?
08:08TimMcagarman: I've sometimes mapped a map or set over something.
08:08TimMcbut that's rare, yes
08:08agarmanyes
08:16agarmanrarer something is, uglier it can be e.g., #(map % set)
08:56eli-sedo dynamic vars work well with core.async? e.g. doing channel operators in a binding block in a go block
08:57ro_stprobably depends on whether you're using threaded or parked
08:57ro_stdouble ! or single !
08:57ro_stdouble ! probably won't work
08:57mpenet`eli-se: I dont think so, no guarantee that your parked op will be taken over by the same thread later on
09:53AtarianIf I split up a program into seperate files that share the same namespace, do I have to :require libraries in both namespace declarations or just the first?
09:57stuartsierraAtarian: just the first, the other files should start with (in-ns 'the-namespace)
09:59AtarianThanks stuartsierra
10:00AtarianI was just putting the seesaw stuff in another file is all
10:01stuartsierraSome development tools/IDEs may have a harder time figuring out where things are when one namespace is split across multiple files, but Clojure itself doesn't care.
10:02AtarianI'm using emacs
10:03AtarianI do find I have to C-c functions in the other file
10:29eric_normandclojurescript is feeling more mature
10:35sveriit is possible to have one namespace spanning several files?
10:36arrdemWith load, yes
10:36sveriarrdem: ah ok
10:36arrdemclojure.pprint does this for instance IIRC.
10:38sdegutisIs there any news on ClojureScript being hosted on node without the JVM?
10:39zerokarmaleftsdegutis: I doubt that's a goal of the project
10:39sdegutisI thought it was coming 2015.
10:40zerokarmaleftperhaps I'm misunderstanding what you mean by "hosted on node"
10:40sdegutisThe compiler.
10:41noncom|2is there a jvm-independant compiler?
10:41zerokarmaleftthe compiler itself is written in clojure, I can't imagine it being rewritten in JS
10:41charlespwdis there a more elegant way of getting multiple keys out of a record than (map (into {} my-rec) [:x :y])
10:42zerokarmaleftthat's a lot of effort for arguably little value
10:42sdegutiszerokarmaleft: but if the compiler is written in Clojure that's fully compatible with ClojureScript, it should be possible to run it via node
10:42arrdemcharlespwd: (map my-rec keyseq) should work.
10:42mpenet`there's shin https://github.com/fasterthanlime/shin
10:42charlespwdit doesn't
10:42sdegutischarlespwd: select-keys
10:42charlespwdUser.Ball cannot be cast to clojure.fn
10:42sdegutis(doc select-keys)
10:42charlespwdwill try that
10:42mpenet`but it trades the jvm bits with ruby/v8
10:43clojurebot"([map keyseq]); Returns a map containing only those entries in map whose key is in keys"
10:43charlespwdthanks, select-keys is exactly what I was looking for
10:44tbaldridgeIMO at this point the hardest part of "porting" CLJS off the JVM would be advanced compilation. I don't think anyone feels like writing a JS tree shaker...
10:44noncom|2is there a one-liner to make the following regexp match return "176006" string?
10:44noncom|2,(re-find #"(rc_)(\d)([\.]*)(\d)([\.]*)(\d+)(_\w+?_\w+)" "rc_1.76006_android_int")
10:44clojurebot["rc_1.76006_android_int" "rc_" "1" "." "7" ...]
10:44zerokarmaleftsdegutis: I suppose that's true...I haven't been following the ML closely recently, so maybe I'm missing something
10:44tbaldridge(I know I don't)
10:45arrdem##(re-find #"(rc_)((\d)([\.]*)(\d)([\.]*)(\d+))(_\w+?_\w+)" "rc_1.76006_android_int")
10:45lazybot⇒ ["rc_1.76006_android_int" "rc_" "1.76006" "1" "." "7" "" "6006" "_android_int"]
10:46arrdemnoncom|2: ^
10:48noncomsorry if i missed a reply, i got dropped out
10:49arrdemnoncom: try #"(rc_)((\d)([\.]*)(\d)([\.]*)(\d+))(_\w+?_\w+)"
10:49sdegutistbaldridge: don't what?
10:49sdegutisoh
10:50sdegutistbaldridge: nvm
10:50noncomarrdem: it returns "1.76006".. it is with the dot.. oh.. well, maybe there is no way..
10:50noncomi will just take items from the []
10:50noncomsince i am sure of their positions
10:51sdegutisDoes clojure.typed have anything like ADTs, maybe using pre-defined keywords?
10:51sdegutisi.e., it verifies that a value can either be :foo or :bar, nothing else, not even another keyword.
10:53mpenet`,(.replaceAll "rc_1.76006_android_int" "[^0-9]" "") ?
10:53clojurebot"176006"
10:53mpenet`hairy but...
10:53noncomwow
10:53arrdemlol
10:53noncomthat does it i think
10:53mpenet`I am sorry
10:53noncomu see, i am so lame about regexps, even the one you saw above, was made by my friend..
10:54arrdem(inc mpenet) ;; for knowing your sins
10:54lazybot⇒ 5
10:54mpenet`I suck so much in RE that I have to resort to that, my bad
10:54noncom:D
10:57arrdemis there some reason you need to strip the '.'s? I'm just looking at your regex and thinking about possible collisions between legitimate strings if '.'s are stripped.
10:58noncomummm yes, i have to receive an int from the string..
10:58arrdemEx. (= (f "1.23") (f "12.3"))
10:59noncomyes, just like that..
11:00sdegutisIs core.typed ready for production use?
11:02mpenet`sdegutis: some are using it with success, ex circle-ci
11:02mpenet`sdegutis: anyway, it's compile time checks, so you're not risking much
11:19noncomi have a [] with strings of 3 types, mixed. like 1) a string, containing #, 2) a string containing "sugar" and 3) a string, containing "best". what is the most idiomatic way to get the 3 []s of strings, in respect to the grouping criteria?
11:19noncomi could surely use 3 (filter ...) things, but that looks clumsy..
11:20gfredericksnoncom: does group-by work for you?
11:20justin_smith(inc gfredericks)
11:20lazybot⇒ 121
11:20justin_smithhe even said the magic "group" word
11:20gfredericks,(* 11 11)
11:21clojurebot121
11:22noncomoh, right :)
11:22noncomthank you very much
12:08bhurlowhi guys, datomic question here:
12:08bhurlowwhat's the SQL LIMIT equivalent for datomic queries. Do I necessarily have to use take/drop?
12:09bhurlowwhat if I am taking from a really big collection? i.e how lazy is datomic?
12:11noncomdo i imitate "curl -F" thing in clj-http with (client/get ... {:form-params ...}) ?
12:11justin_smithbhurlow: probaly a better question for #datomic, but the results will be pulled from the local cache whenever possible, and results you don't access should populate the cache when first received regardless of usage
12:15tbaldridgebhurlow: however, Datomic's query engine is set based, so if you try joining super large datasets you might thrash the cache if you don't have enough RAM
12:16tbaldridgebhurlow: but Datomic also offers several APIs for talking directly to the indexes, so sometimes it's faster to start with a lazy search over a index, and then query off of the first result. But all that really depends on what you are trying to do
12:17eli-sempenet`: I see.
12:17eli-seI like to use dynamic vars for DI and I'm trying to find a solution for this other than passing things around or clobbering everything with reader monad.
12:18gfrederickseli-se: have you looked at component?
12:18justin_smitheli-se: the thing is that if the base implementation is passing things around, then you can do dynamic vars, or magic global atoms, or whatever else on top of that
12:18justin_smiththe others are not as flexible
12:18eli-segfredericks: the technique/library by stuartsierra?
12:18eli-seWatched a video about it but never used it.
12:19justin_smitheli-se: yeah, most attempts to deal with this stuff will be clumsy and / or buggy attempts to do half of what component does
12:19eli-seI see.
12:20bhurlowthanks tbaldridge! I'm gonna move this over to #datomic but many thanks
12:21mpenet`eli-se: actually i prefer fn argument, easier to test, more predictable and actually faster in most cases
12:24justin_smithmpenet`: well, it may be more powerful, more general, faster to execute, more predictable, and very easy to test, but it also means you have to add an argument to a function. Think of the poor typing fingers.
12:25eli-seI have trouble with that in a current project and it's very urging to just create hard dependencies on DB connections and such since it's very cumbersome to add something.
12:25eli-seAlthough I think that problem has more to do with the fact that SRP is violated all over the place.
12:25justin_smitheli-se: component is designed to alleviate that encumberance
12:26eli-seE.g. if we want to add a widget to a page then we tend to acquire the data in the request handler of the page. I've been thinking about a different architecture lately which is less like the URL-corresponds-to-function design.
12:26mpenet`yeah component is good, just a bit complicated to retrofit depending on the app size/way it's coded.
12:27eli-seBut rather doing the UI client-side and fetching all data through separate requests.
12:27eli-seThat'd be much easier to program, though not feasable to add to the current system. I'll apply it in a new thing I'm working on.
12:28justin_smitheli-se: sounds like you are in the uncanny valley between OO and FP
12:29eli-seMwah not really, I prefer procedural/FP over OOP. We use very little OO techniques.
12:29justin_smithSRP is OO. encapsulation is OO
12:30clojerEditing Clojure in Emacs Live! it seems sometimes my updates are not recognised when I C-c c a form following an edit. Any ideas?
12:31justin_smithclojer: what sort of thing are you updating?
12:31eli-sejustin_smith: SRP is only OO if you are in the narrow minded world where responsibilities apply only to classes
12:32eli-seSRP applies to anything be it a module or a function or a program.
12:32clojerjustin_smith: File within a project. I change the (defmethod and it seems to cling to the old error.
12:32kitallisI was hoping extracting out defroutes* and putting explicit middlewares would only apply it to a section of the routes and not to the entire defapi that they are composed in – but that is not the case – anyone have experience with that in compojure-api?
12:32justin_smithclojer: defmethod is defonce
12:32justin_smithclojer: to actually change it, you have to assign it to nil first
12:32justin_smithor undef it
12:33clojerjustin_smith: I'm not assigning to it. Just editing a mistake.
12:33justin_smitheli-se: functions don't have responsibilities, responsibilities imply encapsulation and state, functions have return values that are fully controled by their inputs.
12:33eli-seBasically, I want to have more request handlers that do fewer things. It'd lead to a much nicer design.
12:33justin_smithclojer: like I said, defmethod is defonce
12:33clojerjustin_smith: Same error after correcting and I'm pretty sure it's fixed.
12:33justin_smithyou *have* to assign it to nil, or no change will happen
12:33eli-sejustin_smith: I disagre.
12:34justin_smithclojer: do you understand what defonce is?
12:34justin_smithclojer: if defmethod has been evaluated before, it won't be evaluated again
12:34clojerjustin_smith: How do I "assign it to nil"?
12:34justin_smithclojer: so you need to explicitly assign it to nil or it cannot update
12:34clojurebotCool story bro.
12:34Deraenkitallis: You can use context to limit middleware to only certain routes
12:34justin_smithclojer: (def method-name nil)
12:35kitallisDeraen, aha
12:35clojerjustin_smith: Is this an Emacs thing or a Clojure thing?
12:35justin_smithclojer: clojure thing
12:35Bronsajustin_smith: isn't just defmulti defoncey?
12:35justin_smithBronsa: oh, shit, you're right :)
12:36clojerjustin_smith: I'll have to brush up on (defonce :(
12:36justin_smithclojer: listen to Bronsa - defmulti is defonce, defmethod is not
12:36clojerjustin_smith: Something I need to learn. Doesn't make blind bit of sense right now.
12:37justin_smithclojer: I was just using "defonce" as a shorthand. A way of saying the form is not re-evaluated if the definition has been created already.
12:38justin_smitheli-se: can you show me a pure function that has a "responsibility" ?
12:38Deraenkitallis: Here is a gist as it seems readme is missing this: https://gist.github.com/Deraen/0d37fdcbf98f3d9056e6
12:38clojerjustin_smith: Will take your word for it but the reason I'm peeved is that I read up on defmulti/defmethod in several sources and don't recall a mention of this. Clojure has some weirdness at times.
12:38kitallisDeraen, yup, got it, thx a ton
12:40kaplankitallis, o/
12:40{blake}I just checked out Rich Hickey's "ants" thing from a couple years back. (defstruct!)
12:41justin_smitharrdem: someone should add a mention that defmulti is defonce to this page http://conj.io/store/v0/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/defmulti/
12:41justin_smithmaybe I need to check out that repo finally...
12:41tbaldridgedoes anyone know why it contains defonce?
12:41{blake}On my machine, about every 8 seconds it stops cold for half-a-second.
12:42justin_smithtbaldridge: so that all your defined multis don't break when you reload the file containing the method
12:42tbaldridgeI guess to not have it accidentally blow away all defmethods when a ns is reloaded
12:42arrdemjustin_smith: noted
12:42justin_smithtbaldridge: otherwise reloading the file with the method impl, would always require reloading every file that defines a multi
12:42tbaldridgeseems like someone could defonce part but not the other
12:42justin_smithhmm
12:42{blake}I'd say garbage collection but I can't see why it would need to GC that often. Is it maybe related to all the threads?
12:42tbaldridgeon re-evaluation, reset the dispatch function and all caches, but leave the method list alone
12:43{blake}Also, it takes 1.6GB of RAM. lol
12:43justin_smithtbaldridge: might be a worthwhile contribution
12:43justin_smitharrdem: fuck it, I'm doing it, expect a PR shortly
12:44arrdemjustin_smith: lol you'll want to pr the clojure-grimoire/datastore
12:45arrdem*repo
12:46justin_smitharrdem: is that different from https://github.com/clojure-grimoire/grimoire
12:46justin_smithit is, and I found it, don't mind me
12:47arrdem<3
12:48justin_smithwoah, this is the first fork? inconceivable
12:48arrdemI need to get a real editing workflow built.... people didn't seem to go for the original PR based workflow.
12:48arrdemjustin_smith: yep. andyf and I are entirely to blame for all the notes at present.
12:50justin_smitharrdem: cool - so it looks like functions are grouped by the earliest covered clojure version that implemented them?
12:50arrdemjustin_smith: bingo
12:50arrdemjustin_smith: just throw that comment in 1.4.0. I think that's where it is at present.
12:50justin_smitharrdem: just making sure editing defmulti under 1.4 would show up where expected :)
12:50justin_smithyup
12:51arrdemhttps://github.com/clojure-grimoire/lib-grimoire/blob/master/src/grimoire/api.clj#L95-L102
12:51justin_smithok, what about the wacky file names for the examples?
12:51arrdemthose filenames are literally meaningless.
12:51arrdemjust has to be a file in that dir to show up.
12:51justin_smithso I can just generate something and it suffices that it be unique?
12:52arrdemcorrect.
12:52arrdemmany examples are in files named andy<n>.clj
12:52arrdemothers have numeric names that are legacy from how clojuredocs indexes and names examples.
12:53justin_smithcool, making a "defmulti is stubborn" example now
12:55arrdemjustin_smith: as long as you're monkeying around in there https://github.com/clojure-grimoire/grimoire/issues/176
12:55arrdem<3
12:55justin_smitharrdem: OK, if you're gonna twist my arm about it, sure, why not
12:55SirRobinin cljs ~*file* returns a tmp file /tmp/form-init...clj
12:56arrdem(inc justin_smith)
12:56lazybot⇒ 208
12:56SirRobinis there an easy way around this?
12:58hiredmanSirRobin: you are likely looking at the wrong *file* if cljs has one at all
12:59hiredmandue to generally horriblness, clojure's *file* tends to be bound to that at runtime when using lein (at compile time it is actually bound to file being compiled)
12:59hiredmanI dunno if the clojurescript compiler has its own *file*
12:59Bronsathere should be a cljs.analyzer/*cljs-file* or something like that IIRC
13:00{blake}Are there any hooks for knowing when GC is being called?
13:00hiredman(clojurescript macros being written in clojure when expanded are running at "runtime" for clojure which is why you see that value for *file*)
13:00tbaldridge{blake}: https://blog.codecentric.de/en/2014/01/useful-jvm-flags-part-8-gc-logging/
13:03justin_smitharrdem: another thing missing is the demonstration of defmulti with more than one arg
13:03SirRobinBronsa: awesome, cljs.analyzer/*cljs-file* did the trick
13:03SirRobinthanks
13:03arrdemjustin_smith: I'll open a ticket.
13:04justin_smitharrdem: I'll do an example of that while I'm at tit
13:04justin_smith*it
13:04arrdemthanks
13:06{blake}(inc tbaldridge)
13:06lazybot⇒ 19
13:06{blake}tbaldridge: Groovy.
13:19noncomhow do i avoid the "pending takes exceed 1024" in core.async when trying to take from a channel inside a (go (<! ..)) block inside a method of a proxied Java class that executes on a like 100 FPS basis
13:19noncom?
13:20noncomall in all, what is the general advice on avoiding this pending takes thing? using alts?
13:22agarmanyou need to have something take
13:22agarmanor something put
13:23agarmaneither side you can cause the error if there's too many pending ops
13:33tbaldridgenoncom: that's a problem you get when you aren't properly handling backpressure
13:34tbaldridgeperhaps you're spinning up > 1024 go blocks?
13:35tbaldridgenoncom: a gist might help
13:43justin_smitharrdem: big cleanup and extension sent your way
13:44justin_smithhttps://github.com/clojure-grimoire/datastore/pull/2/files
13:45noncomtbaldridge: https://www.refheap.com/98371
13:45justin_smithincludes showing the super cool feature that a defmulti can be varargs while the defmethods are not
13:46noncomthe printer and dispatcher are simple java threads which just perform the method on each run
13:46justin_smithperhaps s/cool/weird/
13:47tbaldridgenoncom: so two things. (go (<!)) and (go (>!)) are just slower versions of take! and put!
13:48tbaldridgebut that's your problem, you either need to use >!! and <!! or need a way to not continue executing until the callback passed to a take! or put! is called.
13:48tbaldridgeOr just use a dropping/sliding channel
13:49tbaldridgeotherwise, this code would eventually run out of heap space, that's what core.async is complaining about with the 1024 thing
13:50noncomumm... but <!! will block until it receives a message, effectively preventing the reader thread from doing other things?
13:52noncomhmm, messaging with core.async seems a little bit more complex than with googles event bus :)
13:52noncomi wished for just a similar simplicity...
13:53raspasovnoncom: how is google's event bus different in that regard? (I have never used it)
13:54noncomraspasov: it is totally clear of any synching problems afaihui (as far as i have used it)
13:55noncomraspasov: also, it is built on totally different concepts.. more javaish ones
13:55raspasovnoncom: well but does that mean that it is also all just callback-based?
13:55noncomidk how it works internally... it just does not have a similar pressureback problem..
13:56arrdemjustin_smith: great thanks. redeploying now.
13:56tbaldridgewell most likely the google event bus is using unbounded queues, something core.async refuses to let you do
13:56justin_smitharrdem: cool beans, glad I could help
13:57noncomwell, google event bus just calls particular methods, passing them the events. the dispatching and synching mechanism somehow handles that and makes it feel, like messages just get instantly delivered where they should be
13:57noncomand the methods are just called with these events passed to them
13:57justin_smitharrdem: next is to make an example using the :heirarchy key I guess (I've never needed that before...)
13:57noncomhere, in core.async, i have to control the receiving site on my own
13:58raspasovnancom: in core.async you can prevent blocking a thread if you use something like (go (let [msg (<! a-chan)] (println msg))), almost like a callback but much nicer
13:59arrdemah buggery I have datafile changes that expect the development version of Grimoire love
13:59arrdem*live
13:59raspasovnoncom: *
14:00tbaldridgenoncom: so you do have some options here. the reader side could be using a loop inside a single go,
14:00arrdemjustin_smith: yeah sorry your changes aren't gonna show up in the live site until I do the next release. Which should be next week.
14:00noncomraspasov: well, yes, but the problem is that if the reading thread is 100 faster than the writing thread, then the reading thread will generate an excessive amount of "takes"
14:00tbaldridgenoncom: but on the writer side, you could do something a tad ugly and use an agent that calls >!!, but yeah, that's a bit ugly
14:01tbaldridgeBut I'll now quote Rich: "having unbounded queues is just saying 'I know there's a problem, but I don't want to deal with it right now'"
14:01raspasovnoncom: no, it won't; in a (go-loop) it will "park" effectively blocking, but not really blocking a real java thread
14:02justin_smitharrdem: no biggie
14:02noncomyes, probably i have to somehow make all this work, just get the right design of it..
14:02raspasov(go (loop []
14:02raspasov (println (<! a-chan))
14:02raspasov (recur)))
14:03raspasov(>!! a-chan 1)
14:03raspasovnoncom: (def a-chan (chan 1)) first
14:04noncommaybe you can make some comment on my scenario: i have thread A which listens to mouse and posts all the messages it generates (can be like 100 msgs/sec). the messages get posted to a bus (a core.async channel), and later, some other threads, running on slightly different speeds have to take these events and process them
14:04raspasovnoncom: is this ClojureScript or Clojure?
14:04noncomclojure
14:05raspasovnoncom: ok, so
14:05noncomraspasov: i start to see what you mean, i can embed the thing in a go-loop and put all the functionality in there..?
14:05raspasovfirst of all, do you can about **all** events or only latest, since it's mouse events?
14:05raspasovdo you care*
14:06raspasovI have seen browser scenarios where you care about only latest, but not all
14:06noncomi think all events... if i am to use just the latest ones, i do not even have to use any messaging, an atom would suffice..
14:06raspasovsince you can discard old if newer ones are more important - depends on the use case; let me know because that might influence the design sligthly
14:06raspasovehhh not really
14:07raspasovI would use atom if I care for all
14:07raspasovand a core.async sliding-buffer
14:07raspasovif I care only for latest
14:07raspasovbut here's the thing
14:07raspasovyou're saying the consumer might not be fast enough
14:07noncomyes..
14:08raspasovso how could you possibly care for all events? like, you need a policy there
14:08raspasovyou can be like "producer is at a random, potentially infinite speed"
14:08raspasovand my consumer is limited, but I still care for all
14:08raspasovdo you see what I mean ? : )
14:08raspasovcan't*
14:08noncompartly :)
14:09raspasovanother question: I assume this runs on one machine?
14:09raspasovno distributed processing, right?
14:10noncomyes
14:10noncomone machine
14:10noncomone jvm :)
14:11raspasovok cool
14:11raspasovso if the events are only mouse clicks... right?
14:12noncomwell, not actually.. they are also mouse moves
14:12noncomand mouse clicks
14:12noncomthey can also be touches (up to 10)
14:12noncomor even more than 10 touches...
14:12raspasovok - what is the amount of processing that happens per each event?
14:12raspasovis this for Android/mobile?
14:13noncomthis should work on desktop and also android, but also on TUIO-enabled devices like multitouch tables...
14:13noncom(the tuio ones are desktops as for the processing unit)
14:14noncomso three can be many events. the events themselves do not get much processing
14:14noncomhowever, different places in code may react on them differently
14:14noncombasically, this is a gui..
14:15raspasovok yea I get it, is there any IO associated with an event or it's all local to the device, i.e. is there any writing to disk, calling the internet etc?
14:15raspasovor it's all just GUI changes?
14:15eli-sewith Component is it typical to have multiple systems?
14:15eli-selike, subsystems
14:17noncomraspasov: in general, no io is associated with it directly
14:17noncom(aside from 3d and opengl stuff as for output)
14:17raspasovnoncom: ok let me make a quick gist
14:21raspasovnoncom: https://gist.github.com/raspasov/d006968103b6854a4565
14:24noncomlooking at it..
14:27noncomraspasov: wow, well, that looks rather useful! i have to try to apply this in my situation..
14:28raspasovnoncom: ok cool :) I hope it helps; one thing is though, the (go) loop runs on a different thread pool... I am not quite sure if Android restricts updating the UI from the main thread only? you need to look into that
14:28noncomraspasov: well, i have a fully opengl gui, so android should not get in the way :)
14:29raspasovnoncom: ok good :)
14:29noncomthank you! you have been very helpful!
14:29raspasovyou're welcome, any time
14:29noncom(inc raspasov)
14:29lazybot⇒ 1
14:29gfrederickseli-se: no, I usually have one system at a time on a jvm; what you're thinking of as subsystems is probably just a component that depends on other components
14:29eli-seok
14:31raspasovnoncom: have you gotten Clojure to run on Android? I have never tried that
14:32noncomraspasov: yes, clojure runs just fine on android. there is a special initiative http://clojure-android.info/ that has a little tuned clojure.jar to work flawlessly on android
14:32noncomit is somewhat slower, but i managed to get a repl inside my app
14:33noncomalso, there is a repl in google play
14:33raspasovnice, that's good to know :)
14:33noncom(but not very functional, since it is very bare :))
14:39lemonodorraspasov: there are a few example android apps around. i wrote this one to control a drone: https://github.com/wiseman/shrimpdroid
14:40raspasovlemonodor: that's neat
14:46justin_smitharrdem: tbaldridge: in making an example for the optional :hierarchy key to defmulti, I discovered that it throws an error if you provide a hierarchy directly, and tells you it needs a derefable type. Which makes me realize, if you specified the dispatch function as a var, you wouldn't need to worry about defmulti being defonce, because you could just reassign the var
14:47amalloyjustin_smith: you would still need to worry
14:47amalloybecause it would save the old dispatch values
14:47justin_smithahh, caching
14:47justin_smithick
14:47amalloywell, not "caching" really
14:47amalloyit's caching in the same sense that when you (def x 1), clojure saves 1 as the value for x
14:48amalloyit has to do that in order for the def to be functional
14:48justin_smithOK. So you don't mean save the dispatch values as in saving the results of dispatch function for a given input?
14:49amalloyno
14:49amalloyit doesn't do that
14:50amalloyi mean the defmethods are still there, being mapped to by (f x), even though your dispatch function is now g
14:50justin_smithahh, now I see what you mean
14:51gfredericksanybody know if there's anything wrong with a single throwable object getting thrown in multiple situations?
14:51amalloygfredericks: a number of libraries do this already
14:52amalloyi think it's not a big deal
14:52justin_smithalso, it was interesting to use make-hierarchy and the three arg version of derive. It's the immutable version of derive, so you need to chain it, but that also means you can "fork" two hierarchies locally off the same base hierarchy.
14:53gfredericksamalloy: cool thanks
14:55atyzRandom question: What log management tools do you all use?
14:56atyzPreferably hosted solutions
14:57agarmanlog to Kafka where I am no
14:58agarmanlogged to Cassandra at the Weather Channel
14:59justin_smithamalloy: we may have been miscommunicating, what I was talking about works
14:59agarmanused LogStash & Flume
14:59justin_smithamalloy: https://www.refheap.com/98378
14:59atyzagarman: I'm more interested in hosted solutions. Currently looking at moving away from our splunk
15:00atyzHow did you find logstash and flume?
15:00amalloyjustin_smith: yes, but that's something to worry about. what if you had defmethods for "a" and for ["a"] already?
15:01amalloythen the behavior of (rebindable ["a"]) just changed, as a result of you changing the dispatch function. obviously this *could* be what you want, but it's unchecked mutability
15:01amalloyit's not something that's obviously wrong to do, but it's something you have to be very careful with
15:01justin_smithamalloy: yes, fair point, it trades one problem for another. But needing to change your defmethod if the defmulti dispatch changes is predictable, defmulti doing nothing with no error message is tricky and catches many of us.
15:01justin_smith*has caught
15:01justin_smithI won't make the mistake again :)
15:02agarmanatyz: either lib was fine. flume had issues with some of the load we put through it ... sinks overflowed
15:05agarmanatyz: fluentd is another good lib
15:05agarmanand app
15:05atyzagarman: thank oyu
15:09amalloyi don't know which mistake you mean, justin_smith, but i'm pretty sure i will make the mistake of forgetting how redefining a defmulti works again
15:09gfrederickshandling partial failure with component is tricky
15:09amalloygfredericks: (System/exit 300)
15:09gfrederickslike what if I want the rest of the system to keep running, and for the failed thing to keep trying to revive itself
15:12eli-seHmm.
15:13eli-sethis is neat: http://ideone.com/Udb6OL
15:14eli-seI don't like (let […] (do stuff) (let […] (do more stuff))) as it tends to get unreadable quickly.
15:15justin_smitheli-se: one trick is to put _ (do stuff) inside the let block
15:15justin_smith_ conventionally meaning that you won't be using the return value
15:15eli-seyeah right
15:16amalloyeli-se: this isn't going to work if you call it from another macro definition, eg (defmacro foo [x] `(im (let [y# 1]) (+ ~x y#)))
15:16eli-sethough that'd still put the last thing out of the […].
15:16justin_smitheli-se: right, this is just for avoiding nested let blocks
15:17justin_smithanother trick is to make some bindings into (delay ...) forms that are later dereffed, then you can still do short circuiting within one let block
15:17justin_smithbut that is also often a sign that it should be more than one function
15:19anewhat's a good way of avoiding nesting when-lets?
15:20gfredericksane: some-> is sometimes (ha!) applicable
15:20amalloycross to the other side of the street when you see one coming
15:20justin_smithane: the two tricks I use are and or when inside the form generating the value, or using (delay ...) and then dereffing the value later only if the proper conditions are met
15:21justin_smith(let [cond (some calc) a (when cond ...) b (when (and cond a) ...) ...] ...)
15:21justin_smithbut that's less than ideal
15:21justin_smithbetter than nested when-let though
15:21justin_smithactually b could just use (when a ...)
15:23anethat looks... a bit confusing
15:25anei want to bind two variables though, which is why i had them nested initially. should i "tuple" them somehow? make the ultimate cond return (x y) and then bind using that?
15:25anei mean, (list x y)
15:25justin_smithane: that really doesn't work so well with when-let
15:25justin_smith,(when-let [[x y] (list nil nil)] :OK)
15:26clojurebot:OK
15:26justin_smithprobably not what you expect
15:26aneoh, poop
15:26anea cond-let would be great!
15:26justin_smiththere is probably something like that in flatland/useful
15:27justin_smithor and-let
15:27justin_smithor soemthing like that
15:27anehrm, actually, these two when-lets aren't dependent of each other
15:27aneso i could just let [a (...) b (...)] and then when (and a b) (...)
15:28justin_smithyou could avoid unneeded work with the form I suggested (let [a (...) b (when a ...)] (when b ...))
15:28justin_smithbecause you don't even need b if a is falsey
15:30aneoh yeah, that's amazing!
15:30justin_smithhaha, you called it confusing the first time
15:30aneheh
15:30anei just couldn't parse it for all the ellipses
15:31justin_smithane: the thing in flatland/useful I was thinking of was let-later https://github.com/flatland/useful/blob/develop/src/flatland/useful/utils.clj#L224
15:32justin_smith(let-later [a (...) ^:delay b (...)] (when (and a b) ...))
15:34amalloyjustin_smith: egamble/let-else has something more focused on conditionals inside of let clauses. i don't really care for it myself, but if nested when-lets bother you you will probably like it
15:35amalloyand i think he borrowed my :delay notation
15:35raspasovrandom: I just turned on :global-vars {*warn-on-reflection* true *unchecked-math* :warn-on-boxed} ... omg :)
15:35raspasovonly on 1.7 for :warn-on-boxed...
15:36justin_smithraspasov: yeah, that's an awesome feature
15:36justin_smith(inc puredanger)
15:36lazybot⇒ 36
15:36raspasovjust turn that on, run lein repl, and get scared :)
15:36puredangerwat!
15:36justin_smith?
15:36raspasovpuredanger: yea that's awesome
15:36puredangersorry, woke me up
15:37justin_smithit's OK, you can sleep again, it's just that your work is appreciated
15:37raspasovthere's so many reflections/boxed math things in so many popular libs
15:37puredangerwhich actually is totally fine, mostly doesn't matter at all
15:37justin_smithraspasov: and finding them all is the first step in squashing them all
15:37puredangerexcept for when it does
15:37raspasovyea :)
15:37raspasovgreat feature, definitely!
15:38raspasov(inc puredanger)
15:38lazybot⇒ 37
15:38puredangerit's not perfect - won't catch return boxing and a few other cases. hard to fix that one without introducing a lot of false negatives though
15:39puredangerhttp://dev.clojure.org/jira/browse/CLJ-1585
15:39puredangerif anyone wants to make that patch suck less, that'd be cool
15:41puredangerif I could go back in time and use :warn-on-boxed while redoing all the alioth programs, that would free up a lot of my past self's time
15:41raspasovpuredanger: haha, one day!
15:41justin_smithpuredanger: where the issues are "unfixable", is that as in the jvm can't unbox it, or Clojure can't with the current implementation?
15:42pyrhi clojure. I need to reify an interface that expects a void return, is there any way to do it without resorting to a java shim ?
15:42puredangerjustin_smith: I don't remember now, mostly just that it caught a lot of cases where the boxing was a totally reasonable thing and gave more ignorable results than usable
15:43puredangerpyr: you can type hint ^void
15:43amalloypyr: just reify it? there's nothing special to do
15:43amalloyyou don't have to hint it at all
15:43puredangeramalloy: annoyingly, compiler will still prepare the return value though
15:43puredangerand *box* it if it's a primitive oy
15:43justin_smithamalloy: ahh, is this a thing where javac would enforce a certain signature but the vm actually doesn't care?
15:43amalloyand then throw it away? that's pretty funny
15:44puredangeramalloy: yes, bit me in some perf stuff
15:44pyramalloy: yup, that doesn't work :-)
15:44amalloyjustin_smith: no, the compiler knows what the return type is without you telling it
15:44justin_smithoh, that actually makes sense
15:44amalloypyr: then it's nothing to do with the return type, you're doing something else wrong
15:45amalloythat is, you've asked "how do i do X", and the answer is "just do X"; but really X isn't working because you're doing Y instead and we need to know what Y is to fix it
15:45justin_smith~xy
15:45clojurebotxy is http://mywiki.wooledge.org/XyProblem
15:49puredangerpyr: you can't type-hint ^void, I'm dumb - you can use that in definterface, but not when implementing it
15:49amalloyprobably in gen-class too
15:49arohner__ ERROR clojure.tools.nrepl.server - Unhandled REPL handler exception processing message {:op stacktrace, :session 7e32246a-44ba-4abf-b140-1aec3a202e6e, :print-level 50, :id 23}, running tools.nrepl 0.2.7. Anyone here interested?
15:50puredangerprobably, never use it :)
15:53pyrpuredanger: the interface i'm reifying comes from java and defines void as the return
15:53puredangeryeah, that shouldn't matter
15:53pyrmy reification just does (reify Interface (method [this arg] ...))
15:54pyrthe compiler tells me: Mismatched return type: onEvent, expected: void, had: java.lang.Object
15:54puredangerClojure compiler? or javac?
15:55pyrclojure
15:56amalloypyr: does this interface have multiple methods with the same name and argument count?
15:58amalloyif it doesn't, then remove all typehints you've put in the reify method signature and this will fix itself
15:58puredangerpyr: can you post a larger paste of the results or something?
15:59amalloyif it does, then add more typehints
15:59puredangeran example with JDK interface Closeable:
15:59puredanger(def c (reify java.io.Closeable (close [_] (println "hi"))))
16:02pyrthis is the interface: https://github.com/shyiko/mysql-binlog-connector-java/find/master#L730-L733
16:02pyrit is a subclass
16:02creeseFor s3-wagon-private, where do I put pom.xml and settings.xml?
16:03amalloypyr: you linked to a directory, not an interface
16:05pyrsorry, be back in 5
16:05puredangercreese: settings.xml is in ~/.m2
16:06puredangerpom.xml is in your project
16:07creesepuredanger: where in the project? root?
16:07puredangeryes, like project.clj
16:16pyrso that's the one https://github.com/shyiko/mysql-binlog-connector-java/blob/master/src/main/java/com/github/shyiko/mysql/binlog/BinaryLogClient.java#L730-L733
16:16pyrreally straightforward
16:17justin_smithpyr: so you are implementing BinaryLogCLient$EventListener ?
16:17pyrjustin_smith: yes
16:18pyrgot my error, i was giving a hint in the reify method
16:18pyrin the interface implementation i should say
16:18pyrsorry for the noise
16:22amalloywell, it's not "noise" if hearing it helps other people avoid your problem
16:23amalloypyr: to confirm, the solution was what i said earlier, right? "remove all typehints you've put in the reify method signature and this will fix itself"
16:24pyramalloy: i managed to miss that line (got held up on the phone)
16:24pyramalloy: but indeed, it is the right approach
16:32eli-seI wish I were a good programmer.
16:33jjmojojjmojoeli-se: do more clojure, it'll just happen :)
16:35mdrogaliseli-se: No one is born being good at this stuff. :)
16:36justin_smithmdrogalis: speak for yourself, I was refactoring my legos at age 2 /s
16:36eli-seI like to think I was born whilst programming.
16:47justin_smitheli-se: puts "push, push" in a whole different context
16:47eli-seShe was committed to it, though.
16:47arrdempuredanger: to your knowledge, has anyone done translations/internationalization of clojure's docs?
16:47eli-seNot to mention the guy saying that was a total git.
16:48puredangerarrdem: no
16:48arrdemokie doke.
16:49arrdem(inc justin_smith)
16:49lazybot⇒ 209
16:50arrdemjustin_smith: you can put "Fixes clojure-grimoire/grimoire#<issue-num>" in a merge message and it'll auto-close the related issue(s).
16:50justin_smitharrdem: cool, I'll try to remember that
16:51justin_smithalso, locally bound first class heirarchies are interesting...
16:51justin_smith*hierarchies
16:58creesewhen I add repositories, leiningen tries to fetch deps from there too. How can I prevent this?
16:58justin_smithyou want to add repositories but not use them?
16:59creeseI want add one to deploy jars to
16:59amalloycreese: you can put them in deploy-repositories
16:59creeseah, ok
17:14creesewhen I deploy, leiningen complains about missing maven metadata, but it seems to work okay? What is expected?
17:15hiredman(why is lein, a build tool, involved in deploying at all?)
17:15gfrederickslein does what maven does
17:16hiredmanoh deploying to a maven repo, of course
17:17hiredmanI was thinking deployment to servers running stuff
17:43RisikoHello guys!! I need to ``use`` a configuration variable sharing it between files... I did try some trick but I did obtain only compilation error...
17:44RisikoHow do you set config variables for a cli application?
17:45justin_smithRisiko: the best option is probably to pass the config from your -main to the functions it calls
17:47FrozenlockRisiko: https://github.com/clojure/tools.cli
17:48RisikoFrozenlock: mmmh, 500 Internal server error
17:48FrozenlockWhat? Try to refresh...
17:49RisikoAh, ok, github is down!!
17:49justin_smithworks here
17:49justin_smith$ping github.com
17:49lazybotjustin_smith: FAILURE!
17:49Risiko$ping www.github.com
17:50lazybotRisiko: FAILURE!
17:52Risiko@justin_smith Your is a functional solution but I'm actually passing it too many arguments... Other solutions like require_one in php?
17:52creeseOnce I have a jar, how do I install deps? Up to now, I've been using an uberjar.
17:53justin_smithcreese: if you want to use it from other projects, lein install
17:53justin_smithcreese: if you want to share it generally, you can look at lein deploy
17:53justin_smith(lein deploy is for putting it on eg. clojars)
17:53creeseI'm doing "lein deploy" to private S3
17:54justin_smithoh, OK then
17:54creesebut it doesn't put the deps there
17:54justin_smithno, it doesn't need to
17:54justin_smithif another project loads your project, its responsibility is to also load its deps
17:54justin_smithand your project has a pom.xml describing those deps
17:55justin_smith(lein generates one)
17:55justin_smiththat's why you don't have to specify all the deps of the libs you use, and they don't have to package them either
17:57hiredmanuse an uberjar
17:57creeselein deploy doesn't build one
17:57hiredmanlein deploy is for deploying librarys that other things can depend on
17:58hiredmanlibraries generally don't bundle all their deps, they just bundle depdency information
17:58turbofailperhaps they're asking about some sort of transitive deploy mechanism
17:58creeseI haven't found a plugin that can deploy uberjars
17:59hiredmandon't deploy uberjars
17:59hiredman(to maven repos)
17:59creesefor deploy means "send to s3"
17:59hiredmanno
17:59hiredmanlein deploy can write to s3, but it is treating s3 as a maven repo
18:00hiredmanuse s3cmd or whatever to have your ci server upload the built uberjar to some place on s3
18:01hiredmanlein deploy is strictly deployment in the maven sense of the word, which is all about deploying libraries to respositories, not deploying applications with all their dependencies to be run
18:01creeseI see
18:02hiredmanyou can certainly stick an uberjar (or any random file) in to a maven repository, repos are basically just http servers
18:02justin_smithcreese: maybe you are looking for something like "lein beanstalk deploy" offered by the lein beanstalk plugin? that builds and deploys an uberwar, and restarts the app server to use that uberwar
18:02hiredmanlein isn't built around doing that though
18:02creesejustin_smith: no, we use bare aws. I'm using supervisor
18:03justin_smithcreese: OK
18:03creeseWe have multiple environments and we want to build once
18:05vasHi. Eventually my website is going to have javascript for interactivity and animations, and I want to load new data from Datomic on certain changes, what's the preferred way to invoke clojure methods from javascript? or is this where clojurescript comes in?
18:06justin_smithvas: typically my sites will use an AJAX call from the js to hit a backend service that provides a json response
18:06hiredmanat work we have archiva set up acting as a private caching maven repo, so internal libraries for reuse get deployed there, and application code (servers and what have you) is built as some kind of artifact on our ci servers (typically a tarball) and uploaded to some well known location on s3. the app is "deployed" when chef downloads the tarball and sets it up
18:06justin_smithvas: for pushing from the server side instead of pulling from the client, you could look into using websockets, or you could have the client poll
18:07vasjustin_smith: okay, that makes at lot of sense. Thanks :D -- the actions are all client-triggered, but now that you mention it, it could be really cool to have it load via websockets.
18:07justin_smithvas: websockets are more complex to set up though, not really worth it unless you need server side push with quick response on the client side
18:08justin_smithor heavy two way communication I guess
18:08hiredmanyou can get a similar setup just replacing archiva with using s3 as your private maven repo, but having a caching maven repo is really nice
18:09creesecaching maven repo? what's the advatage over something simple like s3?
18:10hiredmanit is sort of like a caching http proxy, instead of directly fetching dependencies from other maven repos, you fetch from your archive setup, and archive is setup to fetch from some other repos if it doesn't already have a dep
18:10hiredmanso archiva keeps a copy of all your depdencies
18:10hiredmanif whatever maven repo goes away, or deletes an artifact, or whatever, no worries
18:10creesecool
18:11creeseyeah, we'll need something like that eventually
18:11hiredmanit can also speed up your builds (by very little) because you tell lein to only grab artifacts from archiva instead of searching N different repos for artifacts
18:11vasjustin_smith: okay, it doesn't have to be incredibly real-time, so perhaps polling will be good (in which case ajax is more-or-less the same "solution"?)
18:12sdegutisAre there times when a variadic function could only be implemented with apply but not with reduce?
18:12justin_smithyeah - the idea is that you have a timeout, and after that timeout you make an xhr from the js, get json back, do something interesting with that json
18:12sdegutisI'm difficult time finding when I _need* apply.
18:13justin_smithsdegutis: get is varargs, you can apply on it, reducing on it would make little sense
18:13justin_smithsdegutis: just a random example, not the specific case where you would likely be using apply
18:13amalloy_you need apply when you want to call a function, but instead of having N arguments individually you have a collection of N items
18:13sdegutisjustin_smith: ah
18:14sdegutisIn every use of apply at work, we could use reduce insead.
18:14justin_smithsdegutis: there are many varags functions that reduce on their args (+, *, assoc), but you can't generalize that to all varargs functions
18:14vas(comment "just reading ambient chat here i learn so much ")
18:14turbofailalso it's not like apply can only be used with vararg functions
18:14sdegutisMaybe some libs we use internally use apply and can't replace it with reduce I guess.
18:15justin_smithturbofail: sure, but that's where the apply/reduce distinction comes up
18:15sdegutisjustin_smith: ah like format
18:15justin_smithindeed
18:15gfredericksany of the update functions
18:15sdegutisvas: so tru
18:15sdegutisgfredericks: good point
18:16sdegutisI hoped to prove to myself the uselessness of apply, but nope.
18:33{blake}OK, so running Rich's "ants" thing and it does turn out to be GC that makes it so slow. It's fine up till it hits 1.6GB (lol) on my system.
18:33{blake}So I'm trying it with -XmX3GB to see what that does.
18:34amalloy{blake}: try running it with -Xmx50m too
18:34{blake}(I'm guessing it'll be fine till it gets to 3GB, though why it would EVER get to 3GB, I don't know.)
18:34amalloyi'd bet there's too much memory, not too little
18:34{blake}amalloy: There's such a thing as "too much memory"?
18:34amalloysure
18:35amalloy{blake}: do you clean up your house/apartment every week or whatever, or do you let it pile up for five years because you have room to hold all the junk?
18:36{blake}amalloy: OK, fair point. This is every 8 seconds but...turns out all specifying 3GB did was...hide the GC messages?
18:36amalloyfrequent small GCs can be a lot more efficient than occasional enormous collections
18:36turbofailwell in theory the overall throughput should be similar for both cases
18:36{blake}(I probably screwed up those switches.)
18:36amalloyturbofail: yes, but nobody notices overall throughput most of the time. they notice long pauses
18:37hiredmanit could also be no one has run ants.clj in 3 years and bit rot
18:38amalloyit's sad to see good bits go bad
18:38{blake}hiredman: I think there must be something like that afoot.
18:38amalloy{blake}: seriously though try it with 50mb
18:38{blake}amalloy: Wait, you don't think my machine's in danger, do you?
18:39amalloylazybot runs with iirc 60mb, which is more than enough
18:40{blake}I'm going to try that, but I want to know why I was getting the slowdown W/O the GC error messages first. 'cause if I just screwed up both switches I learned nothing, except that I'm Java-ignorant.
18:40amalloy{blake}: remember that it's not -Xmx3gb, but -Xmx3g (i dunno if the excess b does anything, but don't do it)
18:42{blake}amalloy: OK.
18:42{blake}Now I've specified 3G and the GC errors are back, well below 3GB.
18:43{blake}(But I haven't hit the slowdown yet.)
18:43ntaylorare they in fact gc errors?
18:43ntaylor(e.g. are you seeing anything like "concurrent mode failure")
18:44{blake}They're "Allocation Failure" messages, which I believe occur when GC is called because...you know, it failed to allocate. =P
18:44ntayloroh, no
18:44ntaylorwhat an allocation failure is is a) badly named ;) b) says that there wasn't enough room in the young-gen to satisfy an allocation, so it forces a generational promotion
18:45ntaylorso you can reduce those by either resizing your heap so that you get more space for the young generation, or let the JVM's "ergonomic" collection do it for you
18:46ntaylorbut, young GCs are expected to be frequent anyway (especially in more functional-style languages like Scala and likely Clojure too, where more short-lived objects are allocated than in Java)
18:47{blake}ntaylor: Interesting.
18:48{blake}I think amalloy has it: With the 50M option it uses a lot less memory and Full GCs being done right-and-left, you don't get the every-eight-second-beat thing.
18:49ntayloryeah
18:49amalloy{blake}: today you learned: there's such a thing as too much memory
18:49{blake}And it uses a crapton less memory. So far just (just...lol) 120M versus 1.6GB previously.
18:49amalloy{blake}: i expect you could run ants with -Xmx20m, really. perhaps less
18:50{blake}amalloy: I did!
18:50amalloymost of the overhead will be the jvm
18:50ntaylorwhich collector are you running, btw?
18:50{blake}It's pouring out those GC messages like berserk.
18:50ntaylor(if this is a standard clojure benchmark apologies)
18:50amalloy{blake}: i'm curious what makes you say it uses 120M. there are a lot of incorrect ways to measure that
18:50{blake}ntaylor: The one that I got without knowing what I was doing.
18:50ntaylorhaha.
18:51amalloy120M doesn't particularly surprise me, but you could easily be getting the wrong number anyway
18:51{blake}amalloy: I'm just using the process manager to watch how much java.exe is consuming. Which, yeah. Caveats apply.
18:52{blake}But I've seen those kinds of hits before, when the OS started allocating virtual memory and pretending it was RAM.
18:53ntaylor{blake}: if it helps, you can also set -Xms to the same thing as -Xmx and have the JVM preallocate its heap
18:53ntaylorrather than having it grow "as needed"
18:53ntaylorwhether that removes a variable for you I donno
18:53{blake}ntaylor: Yeah, that's what I was going for when I set it to 3GB. (But forgot the minimum part.)
18:53ntaylorah, cool
18:54{blake}But if I'm setting the heap to 50m, and the process manager reports 120M...well, I guess there's an...accounting issue.
18:54ntayloroh, well, there's more to your java process than the heap
18:54ntaylora lot of what the process manager tells you will be stuff that isn't your heap (like each thread's stacks, all the classes you've loaded, etc.
18:55ntaylor70mb overhead for all that stuff doesn't seem out of place to me
18:55{blake}Sure...although at 1.6GB...heh
18:55ntaylor:)
18:56{blake}ntaylor: But, yeah, that looks reasonable. I set it to 20MB and now the heap is down to 80+MB. So...
18:57ntaylorcool
18:57{blake}*shakes head* Too much memory. Next, it'll be "your computer is too fast."
18:57ntayloryeah, it's just the cost of getting the benefits of the JVM :)
18:57{blake}(Though come to think of it, I've seen that.)
18:58ntaylorjust hit the turbo button!!
18:58ntaylor(or make your heap larger :) )
18:58{blake}ntaylor: Hey, I'm old enough to remember having to turn the turbo button off...
18:59vasturbo button. let me "lock" this floppy with that physical switch
18:59amalloy{blake}: my first experience with "your computer is too fast" was with an old qbasic program, maybe 15 years ago
19:00amalloyit calibrated its own speed (ie, amount of time it spent sleep()ing between frames) by counting from 0 to 100000 and seeing how many seconds that took, or something like that
19:00{blake}amalloy: A game? Something that checked the speed and found it couldn't slow down enough for your machine?
19:00amalloyon a faster machine, it did that in 0 seconds and divided by 0
19:00{blake}amalloy: Ha!
19:00ntaylorouch.
19:00turbofaillol
19:01amalloyat least it was qbasic, though. easy enough to edit the source to count to 10000000 and adjust correspondingly
19:01{blake}amalloy: Turbo Pascal's CRT unit did a timing check. Somewhere around the time '486s came out, all the TP programs started breaking because the 32-bit counter went kerflooie.
19:01ntayloran annoying variation on that one that I've found is when certain games don't know about your processor's CPU throttling capabilities so it checks the speed but doesn't compensate when speedstep kicks in
19:02{blake}ntaylor: I think FPS is the only way to go.
19:02justin_smithon the other hand, nethack's basic playability hasn't changed since 1985 and it's still awesome
19:03{blake}justin_smith: Right? The most exciting game news this year so far is "New Nethack coming!"
19:03{blake}(Nethack hacking being the only reason I go near C these days.)
19:05ntaylorncurses all the way, I guess!
19:05amalloyncurses is the best physics engine around
19:06{blake}Is there a good Clojure ncurses interface? I went off of Losh's thing, which uses Lanterna.
19:08amalloyi think lanterna is it
19:08ntayloryeah, I donno what ncurses' windows support is like but you'd probably need a layer for calling out to conio on that side of things
19:08ntaylor(is conio still a thing? Haven't touched windows development in years)
19:09{blake}ntaylor: I don't know but as of Windows 7 (and maybe Vista) you can't full screen a console.
19:09ntayloroh wow
19:09{blake}I'm beginning to suspect large heap sizes in the Java switches don't actually do much.
19:10sdegutisHolding Fn key for F1?
19:10justin_smithCtrl-Alt-F7 OK I'm back
19:10{blake}justin_smith: lol. I like to have 5 full-screen Nethack games running at once...
19:11justin_smithsdothum: on linux, control + alt + f<x> switches to virtual console <x>
19:11justin_smitherr
19:12justin_smithanyway, that was for sdegutis, who probably has some amusing new name now but I suppress nick change spam
19:12ntaylorC-a n C-a n C-a n ... :)
19:13justin_smithntaylor: sure, within one console - someone brought up windows console not being able to do full screen, and I was reveling in the fact that I could go into fully console mode
19:13{blake}I guess if you run emacs you can go into a full console Nethack without ever leaving your editor.
19:14justin_smith{blake}: emacs-el is funny, I have a partially-implemented clojure client for it
19:14justin_smith{blake}: it sends all game events as sexprs
19:15ntaylorsure :)
19:15{blake}emacs-el?
19:16justin_smitherr, sorry, nethack-el
19:17justin_smithelisp frontend for nethack, I was re-implementing the client side
19:17justin_smiththe server side presents game events to the client as sexprs
19:17{blake}justin_smith: Ha...how did I know, without even looking...that existed?
19:17justin_smithkind of how you would use json sent to the client from a webserver
19:18amalloyi liked the idea of emacs-el
19:18ntaylorhahahahaha
19:19{blake}What does it get you? I mean, it sounds AMAZING. But so does LSD.
19:19gfredericksis this similar to lein-lein?
19:19justin_smith{blake}: nethack-el? it means you can script the nethack game using elisp
19:19justin_smithemacs-el of course would be the self-hosting engine for emacs
19:20{blake}justin_smith: So...play scripts, presumably?
19:20justin_smith{blake}: macros for combined commands
19:20justin_smith{blake}: maybe an auto-play bot
19:21{blake}justin_smith: Right. Yeah, that's cool. I could write a program that played Nethack better than I did.
19:21justin_smith{blake}: things like pausing the game and warning you if certain dangerous events happen while the game is spammy and the message may have been missed
19:21{blake}justin_smith: Yeah, I hacked boots-of-safety in there once because I was tired of stepping in lava and off bridges.
19:21justin_smitheg. that time I died because I got too hungry. Really, that only happened once, it isn't a recurring issue or anything.
19:22justin_smithoh yeah, a "do you really want to do that" prompt for stepping into water/lava would be another good one
19:22{blake}sure, just like I never choked on the Astral plane eating a giant while satiated and with a 20 strength anyway.
19:22justin_smithhahaha
19:23{blake}justin_smith: Yeah, though in the Nethack mode, just building it in is too easy. It has to cost you a slot.
19:23amalloyjustin_smith: i hate to interrupt the nethack reminiscence, but all this stuff is built into DCSS, with a lua scripting frontend if you need anything fancier
19:24{blake}amalloy: Yeah, I saw that. DCSS is pretty slick.
20:05l1xhey guys
20:07l1xhttps://gist.github.com/l1x/110ae53629b8579143ac
20:07l1xcould somebody explain this please?
20:07l1xi can see a method in an instance
20:07l1xbut i cant invoke it for some weird reason
20:07justin_smithl1x: what args does it take?
20:07l1xstring
20:07justin_smithl1x: maybe it's vararg?
20:08l1xhttps://apache.googlesource.com/kafka/+/0.8.2.1/clients/src/main/java/org/apache/kafka/clients/consumer/Consumer.java
20:08l1xhttps://apache.googlesource.com/kafka/+/0.8.2.1/clients/src/main/java/org/apache/kafka/clients/consumer/KafkaConsumer.java
20:08justin_smithl1x: yup, it's vararg
20:08l1xi see
20:08l1xhow can invoke that?
20:08justin_smith(. a subscript (into-array ["test-shovel-0"]))
20:09justin_smiths/subscript/subscribe, of course
20:09l1xi see
20:09l1xdamn, i am stupid
20:09l1xthanks justin_smith !
20:09l1xhttps://www.irccloud.com/pastebin/EBjmY7zD
20:09l1xthanks!
20:10justin_smithnp, glad it worked
20:10gfredericksjustin_smith: do you think that deserves a helper in clojure.core?
20:10justin_smithgfredericks: that would be super nice
20:10gfredericksif nothing else it would at least call out the fact that those things need special handling
20:10justin_smithmaybe (... a subscribe "test-shovel-0")
20:10justin_smith... is a good way of saying vararg
20:10gfredericksnot a bad idea
20:11justin_smithmaybe it needs an indicator of where the var part starts though
20:11gfredericks(...subscribe a "test-shovel-0")
20:11justin_smith(...subscribe a ... "test-shovel-0")
20:11gfredericksyeah I'm not sure if they'red be ambiguity otherwise
20:11gfredericksthere'd
20:11gfrederickstheired
20:11gfredericksthair'd
20:11justin_smithI'm sure there are methods that would be ambiguous, somewhere
20:12justin_smithbut yeah, that would be a nice reader macro to have
20:12justin_smithsome variation on that
20:12justin_smithmaybe (.subscribe a ... "test-shovel-0")
20:12justin_smithwhere the ... indicates where varargs start
20:12gfredericksbut but
20:12gfredericks... might be bound
20:12justin_smithahh, yeah
20:13justin_smithwe could use the … unicode then
20:13gfredericks,(let [... (fn [& args] (reduce + (map (constantly 3) args)))] (... ... ... ...))
20:13clojurebot#error{:cause "Illegal field name \"...\" in class sandbox$eval25", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.ClassFormatError: Illegal field name \"...\" in class sandbox$eval25, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.ClassFormatError, :message "Illegal field name \"...\" in class sandbox$eval2...
20:13gfredericksjustin_smith: that could also be bound
20:13l1xdamn
20:13gfredericksoh heeeey
20:13l1xthis library drives me crazy
20:13gfredericksmaybe you can't
20:14l1xhttps://www.irccloud.com/pastebin/GUQD0gJy
20:14justin_smithgfredericks: starting with . is special in the calling position
20:14l1xit supposed to wait 100ms
20:14justin_smith,(let [... 42] (list ...))
20:14clojurebot#error{:cause "Illegal field name \"...\" in class sandbox$eval51", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.ClassFormatError: Illegal field name \"...\" in class sandbox$eval51, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type java.lang.ClassFormatError, :message "Illegal field name \"...\" in class sandbox$eval5...
20:14justin_smithoh, wait
20:14justin_smithnever mind!
20:14justin_smithwe can totally use ...
20:14lvhIs there something special about requiring a record?
20:15gfredericksyes
20:15gfredericksbut don't do it
20:15justin_smithlvh: require the namespace that defines the record, then import the record type
20:15gfrederickslvh: use the constructor fns if you can
20:15lvhoh, because they're literally Java types.
20:15lvhgfredericks: I can't. I'm type-annotating.
20:15lvhjustin_smith: That makes sense. Thanks :)
20:15gfredericksaw man
20:15justin_smithso yeah, you need the require / import 1-2 punch
20:16lvhgfredericks: Is the next point "don't type-annotate"?
20:16gfrederickslvh: well I wasn't sure exactly what you meant by that
20:16gfredericksso I was just going to let it go
20:16gfredericksbut now that I've invested this much time typing about it the sunk-cost falacy says I have to press on
20:16lvh(ann some-name SomeRecord) <- that kind, where ann coes from clojure.core.typed :)
20:16lvhthat takes java types, allegedly
20:17gfredericksokay so then
20:17gfredericksum
20:17lvh(I understand that that is not a very useful kind of type checking)
20:17gfredericksare you using protocols?
20:17gfrederickswhy are you using records?
20:17lvhgfredericks: Not my code. test.check has defrecord Generator in it
20:17justin_smithyeah, better to annotate with a protocol or even interface, then implement said protocol or interface with the record, for sure
20:17gfredericksoh snap it's core.typed + test.check
20:17gfredericksthat's hardcore
20:18lvhgfredericks: no kidding
20:18justin_smiththrow some core.match and core.async in there too, see how much the compiler can take
20:18gfredericksman why did we put a defrecord in there
20:19lvhjustin_smith: it has core.logic and core.async, too!
20:19lvhwell, not core.logic
20:19lvhbut just wait until I find a reason
20:19gfredericksI think I had thought about doing a protocol with it
20:19lvhI guess it might not be too late to do it that way since generator is hella internal?
20:19gfredericksthe record is sort of an impl detail but it wasn't designed with core.typed in mind
20:20lvhright
20:20gfredericksman core.typed I'll tell you what.
20:20lvhhey man, I'm not complaining; I'll just move some logic out to some fns
20:20lvhI just had a bug and thought "hey a type system could totally have told me about that one"
20:21lvhI mean, for it to be useful I don't want to say that something is of type Generator
20:21gfredericksbut hey wait
20:21lvhI want to say it's a Generator of maps that look like *this*
20:21gfredericksare you type annotating your test code?
20:21lvhgfredericks: right now I'm not, no
20:22gfredericksthen how did this even come up?
20:22gfredericksyou're using test.check in your not-tests?
20:22lvhgfredericks: Yeah. It's program that tests an external system. Think ab, or something.
20:22gfredericksI wonder if you could make your own protocol and base your types off of that
20:22lvhgfredericks: I use test.check to generate some scenarios
20:23gfredericksthat would even give you the paramaterization you need I think
20:23gfredericksI forget how to do that with core.typed
20:23lvhgfredericks: So I guess the next thing I do is learn what a rose tree is? I guess maybe I don't even really care about a rose tree because IIRC that's only about efficient shrinking, right?
20:23gfredericksyou might even be able to do it w/o a protocol
20:24gfrederickslvh: it's just a lazy tree, and yeah only related to shrinking
20:24lvhgfredericks: well, if my signature is turns-a-random-number-into-a-thing, then...
20:24gfredericksI think rose might refer to it being N-ary
20:24gfredericksI was never sure where that terminology came from
20:24lvhI was doubting if I should capitalize it; I figured maybe the author
20:25lvhgfredericks: wikipedia, the SSOT about the universe, agrees with you
20:25gfredericksphew
20:27gfrederickslvh: so you're using just the generators then?
20:27gfrederickslvh: oh hey a maybe alternative to core.typed is to use prismatic/schema, and then maybe could even make use of schema->gen stuff
20:30cjlaroseHey does anyone know of any good references about hash array-mapped tries, such as those used in Clojure? I've got Phil Bagwell's papers up and the clojure implementation, but I thought maybe there's something more easily consumable around.
20:31justin_smithcjlarose: hyPiRion has a good series of blog posts on the persistent vector implementation
20:31justin_smithI don't know about anything good for hash array mapped tries though
20:31cjlaroseOoo that might be helpful.
20:42cnb_I need to deploy a webservice in immutant but there is no documentation on how to do it
20:43tcrawleycnb_: what do you mean by "webservice"?
20:44cnb_a javax.jws using anotations
20:45tcrawleywhat version of immutant are you using?
20:46cnb_2.0.0.beta2, and I'm trying to deploy to wildfly
20:46tcrawleyare you wanting to include the webservice as part of the immutant war file you are building? or do you want to deploy the webservice in a separate war?
20:47cnb_I'm using lein immutant war -o /srv/wildfly
20:49tcrawleywhere is the webservice? is it in your app's source tree? does it get compiled and included if you do `lein uberjar`?
20:55cnb_this is what I have http://pastebin.com/KJ901Ci3. I'm deploying using lein immutant war -o /wildfly
20:57tcrawleycnb_: hmm, I would think that would get scanned and properly loaded. Would you be willing to create a small app to reproduce the problem and file an issue at https://issues.jboss.org/browse/IMMUTANT?
20:58tcrawleyI need to run now, but can take a closer look tomorrow
20:58cnb_thanks tcrawley
20:59tcrawleymy pleasure!
21:01gfredericks(inc tcrawley)
21:01lazybot⇒ 1
21:02TEttinger(inc \)
21:02lazybot⇒ 1
21:04justin_smith,(eval `(def ~(symbol "") 42)); hey gfredericks did you see this fun trick?
21:04clojurebot#'sandbox/
21:04justin_smith,@(resolve (symbol "sandbox/"))
21:04clojurebot42
21:04gfredericksI did not
21:04gfredericks,sandbox/
21:04clojurebot#<RuntimeException java.lang.RuntimeException: Invalid token: sandbox/>
21:04gfredericksnot so fun if you can't use it :/
21:05TEttinger,
21:05clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
21:05justin_smithgfredericks: it exists, it's just not readable
21:05gfrederickssure
21:05TEttinger,(eval `(def ~(symbol "[") 42))
21:05clojurebot#'sandbox/[
21:05gfredericks,(create-ns (symbol "what about ythis?``"))
21:05TEttinger,[
21:05clojurebot#object[clojure.lang.Namespace "what about ythis?``"]
21:05clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
21:05gfredericksoh hey
21:05TEttinger,[[]]
21:05clojurebot[[]]
21:06gfredericksclojurebot's printing code there helps you distinguish between thrown/returned exceptions
21:06justin_smithoh, that is nice actually
21:06TEttinger,(eval `(def ~(symbol "[]") 42))
21:06clojurebot#'sandbox/[]
21:06TEttinger,[]
21:06clojurebot[]
21:06gfredericks,(ex-info "" {})
21:06clojurebot#error{:cause "", :via [{:type clojure.lang.ExceptionInfo, :message "", :at [clojure.core$ex_info invoke "core.clj" 4579]}], :trace [[clojure.core$ex_info invoke "core.clj" 4579] [sandbox$eval259 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invoke "core.clj" 3078] ...]}
21:06Bronsa,(throw (ex-info "" {}))
21:06clojurebot#error{:cause "", :via [{:type clojure.lang.ExceptionInfo, :message "", :at [clojure.core$ex_info invoke "core.clj" 4579]}], :trace [[clojure.core$ex_info invoke "core.clj" 4579] [sandbox$eval283 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invoke "core.clj" 3078] ...]}
21:06Bronsauh?
21:07gfrederickswelp
21:07gfredericksnobody knows
21:07Bronsa,(RuntimeException. "foo")
21:07clojurebot#error{:cause "foo", :via [{:type java.lang.RuntimeException, :message "foo", :at [sandbox$eval307 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval307 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invoke "core.clj" 3078] [clojure.core$eval285$fn__286$fn__296 invoke "NO_SOURCE_FILE" 0] ...]}
21:07TEttinger,(eval `(def ~(symbol "1") 42))
21:07clojurebot#'sandbox/1
21:07Bronsa,(throw (RuntimeException. "foo"))
21:07TEttinger,1
21:07clojurebot#error{:cause "foo", :via [{:type java.lang.RuntimeException, :message "foo", :at [sandbox$eval355 invoke "NO_SOURCE_FILE" -1]}], :trace [[sandbox$eval355 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Compiler eval "Compiler.java" 6747] [clojure.core$eval invoke "core.clj" 3078] [clojure.core$eval333$fn__334$fn__344 invoke "NO_SOURCE_FILE" 0] ...]}
21:07clojurebot1
21:07Bronsawtf.
21:07Bronsa,]
21:07clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: ]>
21:07gfredericksit's the read-time errors
21:08gfredericks,(let)
21:08clojurebot#error{:cause "Wrong number of args (0) passed to: core/let", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (0) passed to: core/let", :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6628]}], :trace [[clojure.lang.Compiler macroexpand1 "Compiler.java" 6628] [clojure.lang.Compiler macroexpand "Compiler.java" 6694] [clojure.lang.Compiler eval "Compiler.java" 6768] [...
21:08gfredericksyep
21:08Bronsagfredericks: yeah
21:08Bronsai can reproduce that in my repl
21:08gfredericksoh really?
21:08Bronsayeah
21:08gfrederickswait huh
21:08Bronsawell
21:08gfrederickslike with master code?
21:08gfredericksthat can't be right
21:08Bronsano, just kidding
21:08gfredericksphew
21:08TEttinger,(eval `(def ~(symbol "forv") 42))
21:08clojurebot#'sandbox/forv
21:08TEttinger,forv
21:08clojurebot42
21:09TEttinger,(eval `(def ~(symbol "#_") 42))
21:09clojurebot#'sandbox/#_
21:09TEttinger,(+ 1 #_2 3)
21:09clojurebot4
21:10TEttinger,(+ 1 #_ 2 3)
21:10clojurebot4
21:10TEttingerawwww
21:10BronsaTEttinger there's no way that def'ing stuff changes the reader behaviour
21:10TEttingeryeah, I realize that now
21:50weavejesterDoes anyone happen to know of any debug middleware for Leiningen?
21:50gfredericksweavejester: depends on what you're trying to debug exactly probably; `lein pprint` helps for some things
21:50justin_smithweavejester: other than :eval-in pprint nope
21:51weavejesterHm, I haven't tried :eval-in pprint.
21:52weavejesterOne of the problems with Leiningen's config is that it's sometimes extremely difficult to tell if anything's changing it.
21:53weavejesterAs far as I can tell, whenever I add cljsbuild to my prep-tasks, something else runs it as well, before any of the other prep-tasks.
21:53gfredericksoh it has a debug option
21:53gfredericksI forget how to turn it on
21:53gfredericksmay or may not help with that
21:54weavejesterHm, it looks like maybe a :debug true option in the project.clj file
21:54weavejesterBut it doesn't appear to do anything.
21:56dbellstylistic question:
21:57dbelldoes anyone else define private fns with letfn and then define the public fn in the let block?
21:57gfredericksweavejester: not sure how familiar you are with the lein codebase, but a last-ditch option could be getting a user.clj on the classpath and hooking into things that way
21:58gfredericksdbell: traditionally hiredman will scoff at people for doing that
21:58dbellwell i'm all ears for scoffing
21:59weavejestergfredericks: How would I get Leiningen to pull in a user.clj in Lein's classpath?
21:59gfredericksdbell: I believe the reasoning is that vars are a many splendored thing, vars lift us up where we belong, all we need is vars
21:59dbellha
21:59puredangerthey're like the force. they surround us and bind us together.
21:59weavejesterdbell: It seems logical to use private functions to define private functions.
21:59weavejesterThere are also benefits around namespace reloading
22:00weavejesterAnd there's less indentation
22:00gfredericksweavejester: oh also try the DEBUG env variable just in case that's different
22:00gfredericksweavejester: do you know if the java command accepts multiple -cp flags? if so you could add to the classpath with JVM_OPTS
22:01gfrederickshuh LEIN_JVM_OPTS is a separate arg I wonder what the diff is
22:01weavejestergfredericks: Oh, the DEBUG env var pulls up some interesting results...
22:01gfredericksphew
22:01gfredericksweavejester: these vars are listed at the bottom of the sample.project.clj fyi
22:01dbellthe thing i've liked is that it embeds the association in the code; with defn- you have to put it in comments or docs
22:02dbellbut if there's performance penalties...WELL then
22:02gfredericksdbell: I think if anything there should be antipenalties
22:02gfredericksbut probably not noticeably
22:03dbellis fn creation ever expensive?
22:03gfredericksuhm
22:03dbelli got on this tack because it felt dirty defining helper fns in the fns that use them
22:04gfredericksthat's not too dirty
22:04dbelle.g. (defn do-complex-process [args] (let [helper-fn #(asdfasdlfjafs)] (use-helper-fn)))
22:04gfredericksit's certainly not expensive compared to having more defns
22:05gfredericksyou have to be at a pretty low level before you worry about the cost of fns
22:05amalloydbell: creating a function is one object allocation
22:06amalloyif the function doesn't close over any locals, it's just a call to new MyFn(); if it does close over a local named x, it's a call to new MyFn(x)
22:06weavejesterHm, it looks like cljsbuild invokes prep-tasks, so it can't be in prep-tasks itself.
22:08dbellthanks all
22:08weavejesterOh, nope, it was this bug: https://github.com/lynaghk/cljx/issues/60
22:10weavejestergfredericks: Thanks for the DEBUG tip
22:10weavejester(inc gfredericks)
22:10lazybot⇒ 122
22:10gfredericksweavejester: no probs
22:25SeyleriusAnyone got a sec to talk about complex data structures in clojure? I'm thinking that a lisp may be more appropriate for the project I'm planning, but I don't know enough about clojure and other lisps to know what sort of data structure would be appropriate. I do know how I'd do it in an object-oriented way, but I'd like to know how it can be better expressed in a functional design.
22:28gfredericks~anyone
22:28clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
22:29SeyleriusBasically, it's a complex knowledge map, drawing heavily from graph theory, and where the relationships between the nodes are themselves defined by nodes. Premises would be groups of connected nodes, and have confidence values. One of the core features of the final system will be a prototyping ability, wherein a premise's confidence value can be linked to one or more prototypes. A prototype would define properties that a matching premise would have
22:29Seylerius, and if a matching premise were found, it would influence the confidence value of the original premise in a specified way.
22:29clojurebot#error{:cause "Can't take value of a macro: #'clojure.core/and", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Can't take value of a macro: #'clojure.core/and", :at [clo...
22:30SeyleriusWhoops. Did the place my client broke the line break clojurebot?
22:31justin_smithSeylerius: clojurebot is triggered by , at the beginning of the line
22:32Seyleriusjustin_smith: I figured as much. Hopefully the accidental non-command didn't crash it. Meanwhile, got any theories on such a thing, or a good paper to read on graph-theory-like data structures in functional programming and/or clojure?
22:32justin_smithSeylerius: are the relationships in the graph nodes because the relationships themselves can be connected to other nodes in the graph?
22:32justin_smithSeylerius: clojure doesn't
22:32justin_smith"crash" all that often
22:33Seyleriusjustin_smith: Good to hear. As far as the relationships, yes they are. Basically, I'm defining a comprehensive knowledge mapping, including the principles of the knowledge mapping, inside the knowledge mapping.
22:33justin_smithSeylerius: the standard representation for a relatively sparse graph would be an adjacency list
22:33SeyleriusIf this sounds like circular logic, that's because reflective coherency of a logic system looks a _lot_ like circular logic.
22:34justin_smithSeylerius: I studied cybernetics, so I think I have a gist of what you are getting at
22:34SeyleriusAh, good.
22:34SeyleriusYou're probably a good person to talk with, then.
22:36SeyleriusWould you agree with my guess that Lisps and FP in general, and Clojure in particular, are a good idea for this type of task?
22:36justin_smiththere are a few dedicated graph packages for clojure. But you can do a lot just starting with an adjacency list
22:36SeyleriusGood.
22:36justin_smithyeah, clojure is pretty powerful for graph stuff, though for certain algorithms you may want to use something that is more mutation friendly
22:36SeyleriusI've got a lot of graph theory to read up on.
22:37justin_smithit's a big (and fascinating) field
22:37SeyleriusI may want to resist mutation, actually, since tracking variations of premises and their respective likelihoods separately is a _very_good_idea_.
22:38SeyleriusRather than changing premises, track all the different variations, their likelihoods, and the competition between them, y'know?
22:38justin_smithSeylerius: it mostly ends up being a pragmatic concern, but that really depends on the complexity of what you are doing and the size of the data set etc.
22:38justin_smiththough there are ways to use mutable data in clojure, that's not what the language makes easy
22:38TEttingerSeylerius: a friend implemented dijkstra's algorithm for graph pathfinding in a pretty concise way in clojure, I've used it a lot
22:39TEttingerthe version I use is array-based since my data is an array and it makes sense
22:39xapak~.
22:39clojurebotNo entiendo
22:40SeyleriusThe data set is going to end up being huge. And the processing likely very complex. But I really think the lack of mutation won't be a problem, since I'd actually prefer to consider a modification to a premise to be a new premise, rather than mutate (and thus possibly lose) the old one.
22:40SeyleriusTEttinger: That's shiny. Got a link?
22:40TEttingerhttp://ideone.com/pwiTf2
22:40justin_smithSeylerius: this isn't just about the domain data, it's also about the intermediate data as you process things
22:40TEttingerthat's a version with no dependencies that can run in ideone
22:41TEttingerthe version I used in a game had a dependency on hiphip, an array handling library from Prismatic (who make some really good libraries for clojure)
22:43Seyleriusjustin_smith: Mind sharing a few examples?
22:43SeyleriusTEttinger: thanks
22:43TEttingerintermediate data is a really good use case for transient collections in clojure
22:44SeyleriusI kinda figured it would be.
22:44TEttingerwhich are mutable within a single fn, and must be made back into immutable persistent collections outside of it
22:45SeyleriusAlso, clojure will have the advantage of playing very nicely with the java-based I2P, which I intend to use as transport network underneath the DHT this thing will live in.
22:46SeyleriusAnd yet clojure is thankfully still not java.
22:46nsjphuntil you get an exception ;P
22:46TEttingerheh
22:46SeyleriusThere is that.
22:46vasjava is exceptional :D
22:46TEttingernsjph, on the plus side, it takes much less code to actually cause that exception!
22:46nsjphyes
22:47nsjphno more factories
22:47TEttingerpublic static void...
22:47nsjphListFactory MapFactory VecFactory
22:48TEttingerC# has stuff like protected static internal IEnumerable<IKeyValuePair<K,V>> GetKeyValuePairs<K,V>(this IDictionary<K,V> the_horror)
22:50TEttingerwhich actually would let you write quite a bit less code... new Dictionary<string, int>{{"foo", 1}}.GetKeyValuePairs();
23:02TEttinger,(let [na Double/NaN nana (* 0.0 Double/NaN) nanana (Double. Double/NaN) watman (Double. (* 0.0 Double/NaN))] (map #(= % %) [na nana nanana watman]))
23:02clojurebot(true true true true)
23:03TEttinger,(let [na Double/NaN nana (* 0.0 Double/NaN) nanana (Double. Double/NaN) watman (Double. (* 0.0 Double/NaN))] [(= na na) (= nana nana) (= nanana nanana) (= watman watman)])
23:03clojurebot[false false true true]
23:05TEttinger&(let [na Double/NaN nana (* 0.0 Double/NaN) nanana (Double. Double/NaN) watman (Double. (* 0.0 Double/NaN))] (for [ogod [na nana nanana watman] wat [na nana nanana watman]] (= ogod wat)))
23:05lazybot⇒ (false false false false false false false false false false true false false false false true)
23:17namragotta love daniel higginbotham and his style of writing :D
23:37justin_smithnamra: that's nonrecursive right?
23:38namrajustin_smith: sry but i don't understand
23:38namrawhat you mean
23:38justin_smithnamra: I mean he hangs out here and has the nick nonrecursive
23:38justin_smithunless I am mistaken
23:38namraah ok
23:39namrai don't know if that's the case. haven't been here that long as you and are not so active as you. so you might be right ^^
23:39justin_smithnamra: yeah, I checked twitter, that's his handle there, so that's the same guy here too
23:40justin_smithhe's the one behind clojure for the brave and true
23:40namra:)
23:40namrayea i know, read the blog series
23:40namraand just saw the book version on no starch press