#clojure logs

2014-07-03

02:05[Neurotic]Hi, I've used extend-type, but no matter what I do, I can't seem to get it t compile. It keeps giving me 'unable to resolve symbol'. I'm not sure what I'm doing wrong here? https://www.refheap.com/87821
02:06[Neurotic]I've done something stupid, but I can't see what it is
02:35ddellacosta[Neurotic]: what is get-value?
02:36[Neurotic]ddellacosta: what do you mean? it's defined on line 21
02:36ddellacosta[Neurotic]: oh, I see, sorry
02:36[Neurotic]Ah cool. Wasn't sure if I was crazy :)
02:36ddellacosta[Neurotic]: try requiring storm.trident.testing in the same ns declaration
02:37ddellacosta[Neurotic]: damnit, sorry, you are. I must be sleepy today
02:37[Neurotic]nope, no win :(
02:37[Neurotic]unfortunately :/
02:37ddellacosta[Neurotic]: well, wait, where is the type declared?
02:38[Neurotic]it's a Java type.
02:38ddellacostaoh
02:38[Neurotic]it's imported on line 15
02:38ddellacosta[Neurotic]: right, thought it was a type though
02:40ddellacosta[Neurotic]: have you tried importing the get-value fn from marceline.storm.trident where the Protocol is defined?
02:40ddellacosta[Neurotic]: I think that's actually what you want to be doing vs. :refer :all from marceline.storm.testing
02:41Viesti_hum
02:41Viestidoh, I had a tail!
02:42[Neurotic][marceline.storm.testing :refer [get-value]] << like so? says it doesn't exist
02:42ddellacosta[Neurotic]: also, it may be the case that you have to define multiple-arity get-value separately: https://groups.google.com/d/msg/clojure/XeY7MGrcxLQ/6fMfdoWzjWMJ
02:43[Neurotic]ddellacosta: ooh, lemme try that
02:43Viestiwhy do <,>,=,<=,>= return true in the single argument case?
02:43ddellacosta[Neurotic]: also, not [marceline.storm.testing :refer [get-value]] but rather [marceline.storm.trident :refer [get-value]]
02:44Viestiwe had a discussion on another channel where a guy had a bug in his code where he passed only one argument to =
02:44ViestiI understand and quite like of the generality in say <
02:44Viestibut maybe the one arg case is a bit confusing
02:45Viestithis haskell guy was of the opinion that such generality should live elsewhere, but thought about having a good argument on why to keep it in those functions. The generality is at least close in the source code :)
02:48ddellacostaViesti: I think you'd probably get a good answer on the mailing list, but I don't have much other than a guess, which is to maintain consistency with other Clojure functions. But that's just a guess.
02:50ddellacosta[Neurotic]: did it work?
02:50[Neurotic]ddellacosta: nope, but I think I have another idea... need to try it
02:51ddellacosta[Neurotic]: multiple declarations per arity + that require didn't work? Hmm
02:52[Neurotic]I don't *think* so, I've kinda scrapped it, and trying it again, see if I did something stupid
02:53ddellacosta[Neurotic]: well, I don't have any great ideas past that; I hope you figure it out! Good luck
02:54ddellacosta[Neurotic]: oh, one more stupid freaking thing actually--I've had trouble when I had the import at the top of the ns statement vs. bottom, believe it or not
02:54[Neurotic]ddellacosta: looks like the refer worked for a friend of mine... I may try out his code
02:55ddellacosta[Neurotic]: okay, hope that works for you
02:57[Neurotic]ddellacosta: yep, working looks like. Actually needed a [marceline.storm.trident :refer [get-value]]
02:57[Neurotic]which brought in the get-value function from the protocol, so it knew what was going on
02:57ddellacosta[Neurotic]: ah okay, great
02:58ddellacosta[Neurotic]: thought it may be related
03:10Viestiddellacosta: common lips has same single arity case for =,< etc.
03:11Viestiof course should have looked there :)
03:12[Neurotic]ddellacosta: yep, all passing now :) Thanks for your help!
03:12ddellacostaViesti: what's the reason there?
03:12ddellacosta[Neurotic]: great! Glad you got it working.
03:40Viestiddellacosta: didn't find out yet
04:06petrustHow to combine secretary with Om? Should one manipulate the app state atom and then conditionally render in the main Om fn?
04:06petrustOr is there a different om call that I can call from my defroute fns?
04:08borkdudepetrust I have an example of this
04:09petrustthx, borkdude :)
04:09borkdudepetrust this might give you an idea:
04:09borkdudehttps://www.refheap.com/87825
04:10borkdudepetrust call define-routes from will-mount
04:10borkdudeit needs the access to the data argument provided to the Om component
04:10borkdudethat's why I used this construction
04:11borkdudepetrust some more code: https://www.refheap.com/87826
04:12borkdudehope this answers your question a bit
04:12petrustthanks, borkdude!
04:38petrustI’m having a weird issue with dependencies, specifically related to dependencies.
04:38petrust*related to secretary
04:38petrustI’ve added [secretary "1.2.1-SNAPSHOT"] to project.clj deps
04:38petrustI ran> lein clein
04:38petrustand lein cljsbuild clean
04:38petrustif I run lein deps, I get no output, so presumably all deps are satisfied
04:38petrustbut if I now try to run lein cljsbuild auto, I get the following error:
04:39petrustCaused by: java.io.FileNotFoundException: Could not locate secretary/core__init.class or secretary/core.clj on classpath:
04:42noidilein classpath | grep secretary
04:42noidiis the JAR on the classpath?
04:43petrustyes
04:43petrustit’s there
04:44petrust- /Users/petrus/.m2/repository/secretary/secretary/1.2.1-SNAPSHOT/secretary-1.2.1-SNAPSHOT.jar:
04:46noidiunfortunately I don't know enough about cljsbuild to help you :/
04:46petrustdowngraded dep to 1.2.0, same error.
04:48ddellacostapetrust: did you include secretary in any source files, or did you merely add it to the project.clj dependencies?
04:48petrustaddid it to project.clj and :require it in my main.cljs
04:48petrusti.e. :require … [secretary.core :as s :include-macros true :refer [defroute]])
04:48ddellacostapetrust: what happens if you get rid of :include-macros true, does it compile okay?
04:49ddellacostapetrust: and defroute, since that is a macro
04:49ddellacostapetrust: that is, only this: [secretary.core :as s]
04:49petrustseems to be working…
04:51ddellacostapetrust: huh, okay. What about if you then add the macro stuff back in via (:require-macros [secretary.core :refer [defroute]]) at the top of your ns form?
04:52petrustadded back, compiling…works!
04:52petrusthmm
04:52ddellacostapetrust: weird. I'm not sure what is going on since I just created a brand new project and compiled it just fine w/secretary exactly as you described in your first example.
04:53ddellacostaI'll try cleaning as you did, see if that makes any difference
04:54ddellacostanope, works fine...curious
04:55ddellacostapetrust: I'm wondering if there's some other wackiness happening in your project.clj, but I'm really not sure what would be causing this. However, if you can get it to work with :require-macros I suppose you're set...
04:56joelkuiperDoes anyone have any experience with using core.async with the HTTP-kit server? Basically I have some (long running) process ops that return a channel (with the computer value on it when done). I'd like to use the HTTP-kit long-polling trick for sending the responses
04:57joelkuiperbut I'm usure how to proceed; this is what I have right now https://gist.github.com/joelkuiper/d6c03488432f3146d72b
04:59petrustddellacosta: ran lein cljsbuild clean, then lein cljsbuild auto again (with :include-macros), and it seems to work now.
04:59petrustmust be some weird state or env var somewhere
05:00ddellacostapetrust: huh, okay, that's good. Sometimes an extra clean will do the trick, no idea why sadly...
05:01petrusttried a whole bunch of cleans - can’t replicate the error :/
05:07borkdudepetrust I had the same kind of error yesterday when I tried to write a macro in clojurescript
05:07borkdudecleaning, restarting, retrying.. at some point it worked
05:14joelkuiperhttps://stackoverflow.com/questions/24549565/using-http-kit-long-polling-with-core-async-channels
06:12JaniczekIs there any kind of polymorphism operating on two arguments? I'm creating a game and want to do things like (use-on :egg :pan), (use-on :bucket :cow) - but don't know how to NOT have a huge bloated definition of use-on. I'd like to be able to extend it from elsewhere
06:13JaniczekWould multimethods and (use-on [object subject]) instead of (use-on object subject) work?
06:13Glenjaminmultimethods can dispatch on all arguments
06:15JaniczekGlenjamin: care to elaborate?
06:15Glenjaminyep, just typing a repl example :)
06:16JaniczekGlenjamin: great, thx :)
06:16Glenjamin,(do (defmulti f vector) (defmethod f [:a :b] :a-and-b) (defmethod f [:c :d] :c-and-d))
06:16clojurebot#<CompilerException java.lang.IllegalArgumentException: Parameter declaration :a-and-b should be a vector, compiling:(NO_SOURCE_PATH:0:0)>
06:16Glenjaminoh right
06:17Glenjamin,(do (defmulti f vector) (defmethod f [:a :b] [&_] :a-and-b) (defmethod f [:c :d] [&_] :c-and-d))
06:17clojurebot#<MultiFn clojure.lang.MultiFn@28500a>
06:17Glenjamin,(f :a :b)
06:17clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/eval56/fn--57>
06:17Glenjaminhrm, i guess i need to be more explicit
06:17Glenjamin,(do (defmulti f (fn [a b] [a b]) (defmethod f [:a :b] [&_] :a-and-b) (defmethod f [:c :d] [&_] :c-and-d))
06:17clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
06:17Glenjamin,(do (defmulti f (fn [a b] [a b])) (defmethod f [:a :b] [&_] :a-and-b) (defmethod f [:c :d] [&_] :c-and-d))
06:17clojurebot#<MultiFn clojure.lang.MultiFn@28500a>
06:18Glenjamin,(f :a :b)
06:18clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: sandbox/eval138/fn--139>
06:19Janiczek,(do (defmulti f identity) (defmethod f [:a :b] :a-and-b) (defmethod f [:c :d] :c-and-d) (f [:c :d]))
06:19clojurebot#<CompilerException java.lang.IllegalArgumentException: Parameter declaration :a-and-b should be a vector, compiling:(NO_SOURCE_PATH:0:0)>
06:20Glenjamini could have sworn this worked :s
06:21Glenjaminoh right, it doesn't like my variadic thing
06:21Glenjamin(do (defmulti f (fn [a b] [a b])) (defmethod f [:a :b] [a b] :a-and-b) (defmethod f [:c :d] [a b] :c-and-d))
06:21Glenjamin,(do (defmulti f (fn [a b] [a b])) (defmethod f [:a :b] [a b] :a-and-b) (defmethod f [:c :d] [a b] :c-and-d))
06:21clojurebot#<MultiFn clojure.lang.MultiFn@28500a>
06:21Glenjamin(f :a :b)
06:21Glenjamin,(f :a :b)
06:21clojurebot:a-and-b
06:21Glenjamin,(f :c :d)
06:21clojurebot:c-and-d
06:21Glenjamin,(f :c :a)
06:21clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No method in multimethod 'f' for dispatch value: [:c :a]>
06:21Janiczeknice :)
06:21Janiczekthanks a lot!
07:02silasdavisI think I've found a bug in: https://github.com/clojure/data.priority-map
07:03silasdavis(-> (priority-map-by (fn [[_ x1] [_ x2]] (compare x1 x2))) (assoc :a [:foo 2]) (assoc :b [:bar 2]) (assoc :c [:baz 1]))
07:03silasdavisreturns {:c [:baz 1], :b [:foo 2], :a [:foo 2]}
07:03silasdavisthat is, when you use a custom comparator it looks like if two values are equal under comparison they are considered to be the same
07:04silasdavisrather than just being sorted as equal
07:05silasdavisI was using a priority map for [path-to-node distance] and I was getting path-to-node overwritten in all key-value pairs with the same distance
07:05silasdaviswhere can I report this?
07:06silasdavisissues are disabled on that repo
07:06Bronsasilasdavis: https://github.com/clojure/data.priority-map/blob/master/CONTRIBUTING.md
07:08silasdavisah thanks
07:09Bronsasilasdavis: I'm reading the readme, have you read http://sprunge.us/VXXT this?
07:09silasdavisah
07:09silasdaviswell done
07:10silasdavisand thanks
07:10Bronsanp
07:10silasdavisthat's excactly what I'm doing wrong
07:53perplexahai. is there a way to get the namespace of a function from within the function?
07:54perplexalike (ns mynamespace ...) (defn x[] (resolve mynamespace here))
07:54TEttinger,*ns*
07:54clojurebot#<Namespace sandbox>
07:54perplexathat doesn't work
07:55perplexa*ns* is the current namespace, not the absolute namespace of a function ;/
07:55Bronsayou have to close over the *ns*
07:55Bronsa(let [ns *ns*] (defn x [] ns))
07:55perplexai was using *ns* before and it ended up interning functions to the wrong namespace ;p
08:57Janiczekhmm uberjar seems not to pack swing with my seesaw project ... is it normal? (when I run it with `java -jar the.jar`, it's OK and sees Swing, but when I bundle it with Ant AppBundler to an .app, it throws NoClassDefFound for java.awt.Window$Type)
08:57Janiczek(no expert on Java ecosystem)
09:34Janiczekah, it's probably me (in shell) running java 1.7+ and the system (in the bundled .app) running 1.6 or something. java.awt.Window$Type is from 1.7+ up
09:47fowlslegs,(.rotateRight (long 8) (int 1))
09:47clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: rotateRight for class java.lang.Long>
09:47fowlslegshttp://docs.oracle.com/javase/8/docs/api/java/lang/Long.html#rotateRight-long-int-
10:00Bronsafowlslegs: it's a static method
10:00Bronsa,(Long/rotateRight 8 1)
10:00clojurebot4
10:12gfredericksthose sorts of things get made static so they can use primitives amirite?
10:13Bronsagfredericks: probably, yeah
10:30cbparrdem: should the `add examples' page default to 1.4?
10:31cbpI think it would be more practical to default to the latest no?
10:49zeebrahdae know where this moved (out of contrib) http://richhickey.github.io/clojure-contrib/miglayout-api.html ?
10:51fowlslegs,(map #(.bitCount (biginteger (- % 30))) (range 30))
10:51clojurebot(4 3 4 3 3 ...)
10:51fowlslegs,(apply list (map #(.bitCount (biginteger (- % 30))) (range 30)))
10:51clojurebot(4 3 4 3 3 ...)
10:51puredangerzeebrah: afaik it did not go anywhere
10:51puredangerhttp://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go
10:51cbpzeebrah: maybe you can use this https://github.com/scgilardi/artem
10:52fowlslegs,(.bitCount (biginteger 7))
10:52clojurebot3
10:52fowlslegs,(.bitCount (biginteger -7))
10:52clojurebot2
10:52zeebrahpuredanger: yeah i saw that page just before
10:52fowlslegsCan someone explain what's going on with the java.lang.BigInteger class here?
10:52zeebrahcbp: is that maintained? it seems not
10:53cbpmore recently maintained than clojure.contrib.ma
10:53fowlslegsI understand what it means to be in two's complement notation, but it does not specify how many bits it uses as a base.
10:53cbpclojure.contrib.miglayout :-p
10:54fowlslegsThis page http://docs.oracle.com/javase/8/docs/api/java/math/BigInteger.html doesn't, that is.
10:54zeebrahcbp: it's not the actual miglayout library though, just a coupla useful macros/functions
11:00fowlslegsAhh, it must represent it in two's complement notation in byte multiples. I can finally write my hamming distance function for comparing two BigInts.
12:02PigDudewhen you are sharing core.async code between cljs and clj, does your namespace declaration look like this? https://www.refheap.com/87837
12:02PigDudeit seems really ugly
12:03PigDude#+cljs/#+clj everywhere, and the hassle of maintaining two sets of requirements
12:03PigDude*the same set in two places
12:17Willis1Hi, I'm investigating the use of The Grinder's support for Clojure:
12:17Willis1http://grinder.sourceforge.net/g3/clojure.html
12:18Willis1But from what I can tell, there's no way to use lein to pull in additional dependencies
12:18Willis1because the Grinder invokes the clojure scripts directly
12:18Willis1Has anybody made any effort to use lein and grinder together?
12:46synkteWhat is the best way to test a function that creates a new row entry into a sql database?
12:46synkteIs there a lib that could help with that?
12:48mdeboardsynkte: http://clojure.github.io/java.jdbc/#clojure.java.jdbc/insert!
12:49synktemdeboard: So use the ":transaction?" param?
12:50mdeboardsynkte: Depends on your particular application
12:50mdeboardbut if you're asking, the answer is yes
12:51mdeboardsynkte: Well, the default is true, so no :P
12:52synktemdeboard: So, what would be the best way to test a function that does an insert to a sql database?
12:56mdeboardsynkte: Insert, then do a select for that value, then delete it if it iexists
12:56mdeboardsynkte: Do you mean like a unit test i.e. application testing or to only insert if there isn't already a record?
12:57synktemdeboard: unit test
12:57mdeboardsynkte: Yeah then the way I said there
12:57synktemdeboard: Thank you :)
12:58mdeboardno prob
12:58mdeboardI bet amalloy_ has some kind of context manager (`(with-row)`)or something that takes care of that cleanup for you
13:01synktemdeboard: That would be awesome
13:03mdeboarduntil then though yeah you'd just have to clean it up yourseff
13:04mdeboardsynkte: There is this http://clojure.github.io/java.jdbc/#clojure.java.jdbc/with-db-transaction that you could then roll back once done but you'd have to do some additional setup to ensure constraints were not deferred
13:06mdeboard13:01 <mdeboard> until then though yeah you'd just have to clean it up yourseff
13:06mdeboard13:02 <mdeboard> synkte: There is this http://clojure.github.io/java.jdbc/#clojure.java.jdbc/with-db-transaction that you could then roll back once done but you'd have to do some additional setup to ensure constraints were not deferred
13:06mdeboardotherwise you're not actually testing the insert
13:06mdeboardjust something kinda like it
13:11dbaschmdeboard: if I had a unit test for a db I would create a dummy table, insert, and then delete the table
13:11Janiczekare immutable bags (multisets) available in clojurescript, or do I have to somehow include mori-bag? (I'm in browser env, not node)
13:15dbaschJaniczek: clojure.core doesn't have multisets but there are some libraries around, it shouldn't be hard to adapt one of those for cljs
13:15Janiczekyeah, I've found https://github.com/achim/multiset which seams reasonably easy to port
13:16Janiczekonly protocols and clojure.algo (which I'm not so sure about but maybe it can be bypassed)
13:17dbaschJaniczek: as an alternative, you could have a map of keys to counts
13:17dbaschit would be a bit clunkier but at least you wouldn't need an external lib
13:18dbaschof course it might be very inefficient if most of your items appear once
13:18dave-7hey, when using om/root to render a site, you pass it a component, an atom and a map. Should the component be re-rendered if I swap! the atom at some point? The basic tutorial seems to indicate so, but I'm not having any luck. Does the atom count as "attached" to a root if you call (om/root some-comp some-atom {:target dom-node})?
13:47KlaufirHow can I process output from tagsoup ? I have something like this:
13:47Klaufir[:html {} [:head {} [:title {} "asd"]] [:body {} [:div {:class "dc"} "text"]]]
13:48danielszmulewiczI've been using 'length instead of 'count on sequences, and I could swear it was working all the same. Now I get a runtime error. What gives?
13:48amalloymdeboard: nope, i don't. it also seems a little wonky: don't you want to use the db's transaction mechanism if you're inserting stuff you never want to appear there?
13:48tolitiusis there a way to require/use from within a function: e.g. in a local scope? https://www.refheap.com/87842
13:49amalloydanielszmulewicz: length has never in a million years worked
13:49danielszmulewiczamalloy: I'm hallucinating then.
13:49amalloytolitius: no
13:49dbaschKlaufir: what do you mean by process? What do you want to get out of that?
13:49ToxicFrogdanielszmulewicz: .length might have worked, if you were using it on Java objects?
13:49mdeboardamalloy: You do, like I said though it requires a little more insight into how constraints are handled inside a transaction, i.e. initially immediate/deferred, not deferred, etc.
13:50amalloyToxicFrog: only on arrays or strings. collections have .size
13:50mdeboardthat just seemed like a bridge too far to cover w/ that guy's question
13:50danielszmulewiczToxicFrog: No. Just 'length on clojure sequences. I'm utterly confused.
13:50amalloydanielszmulewicz: maybe you were using clojure 1.9? the rest of us are still on 1.6, but who knows what future versions will bring
13:51Klaufirdbasch: I am looking for the language features to process nestes structures like this. Say I want to get the content for :html/:head/:title
13:51dbaschKlaufir: look into things like get-in, or clojure.walk
13:51danielszmulewiczamalloy: Hehe, that must be it. I'm with a future version of Clojure.
13:51danielszmulewicz(inc amalloy)
13:51lazybot⇒ 136
13:51Klaufirdbasch: thanks
13:52tolitiusamalloy: thx. I have to aot a file, but only need some ns at runtime (e.g. in -main), otherwise they have macros that expand into a "never ending ..", so it would not aot compile unless it is in main. is there a known way to load/see/make visible from within a function instead?
13:54amalloywhaaaaa? you've written a macro that doesn't compile, so you want it at runtime? i think you must be confused about something; do you have more specific code that doesn't work?
13:54amalloymore likely, i think, is that you have some def at the top level of a namespace that performs side effects, such as connecting to a database; the solution is to not have side effects at compile-time, but instead to def a delay or a function that is called at runtime
13:58tolitiusamalloy: yes, you are right, but it is not a def, it is a macro, that, when expands (which happens during compilation), starts a scheduler, hence will work on demand, but not if aot'ed. I am looking for a way to isolate this macro expansion in -main. (yes, I know that macro should be rewritten, but that is a bit more difficult at the moment [different project, different existing dependencies, etc.])
14:00hiredmantolitius: if the macro performs side effects at macro expansion time there is no way to isolate that, code is macro expanded before it is compiled and then run
14:00hiredmanaot compilation saves the byte code after compiling so you can run it later, but the macro expand has already happened
14:03tolitiushiredman: I understand that, what I am looking for is a way to only ever "require"/"use"/"load" the namespace where this macro lives on demand. e.g. compile the file that in main has "… and 'import' this namespace as you're running (e.g. runtime)"
14:04tolitiushiredman: avoiding compiling the namespace with this macro ahead of time
14:05TimMctolitius: It sounds like your desire to do this with a macro is distorting your entire program.
14:05danielszmulewiczamalloy: Mystery solved. I was using incanter which advertises a :use namespace usage. This should be outlawed.
14:06technomancy~guards
14:06clojurebotSEIZE HIM!
14:06amalloytolitius: i don't know what this macro is, but it sounds like a scourge on this planet
14:07tolitiusTimMc: it is more of a curiosity now, since I see why it would be useful to do, and now I just want to get to the bottom of whether it is possible (I agree that macro needs to be changed)
14:08tolitiusTimMc: (to have a better control of what gets aot'ed)
14:09tolitiusTimMc: similar to http://dev.clojure.org/jira/browse/CLJ-322
14:12Demosthenes_(doc +)
14:12clojurebot"([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'"
14:13Demosthenes_(doc apply)
14:13clojurebot"([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."
14:19stuartsierraAll, CLJ-322, old friend. It's been a while. We were so young back then. Where did all the time go?
14:46danielszmulewiczI assumed that any library that has 'core in it (like core.matrix) ships with Clojure. Wrong again.
14:47amalloydanielszmulewicz: most don't
14:47amalloycore.* is more like "libraries that might one day be part of clojure"
14:47amalloy"...and which also live at github.com/clojure/*"
14:48danielszmulewiczamalloy: They're halfway there :-)
14:48danielszmulewicz(+ amalloy)
14:48TimMcHuh, the phrase "ships with Clojure" is ambiguous -- at first I read it as "includes Clojure as a dependency", not "is included in the Clojure jar".
14:48danielszmulewicz(inc amalloy)
14:48lazybot⇒ 137
14:48TimMc$karma TimMc
14:48lazybotTimMc has karma 60.
14:48TimMcMan, I've got some catching up to do.
14:49danielszmulewiczTimMc: Don't seat it. amalloy is a bot and everybody knows that.
14:49danielszmulewicz*sweat*
14:50arrdemno mere human could contribute so much to the channel :P
14:50KlaufirWhats the point of 'compare-and-set!' ?
14:51amalloy(inc TimMc) ; to get you started
14:51lazybot⇒ 61
14:51{blake}Aw, a pity inc!
14:51Janiczek:
14:51Janiczek:D
14:51amalloyKlaufir: mostly to implement swap! with. i think i saw one case where it made sense to use compare-and-set! over swap!, but mostly you can ignore it
14:51TimMc(dec TimMc) ;; I don't need your pity!
14:51lazybotYou can't adjust your own karma.
14:51TimMcha
14:51amalloyTimMc: largesse, not pity
14:51Klaufiramalloy: i see, thanks
14:52Bronsaamalloy: swap! is not implemented in terms of compare-and-swap! though
14:52Bronsacompare-and-set!*
14:52amalloywell, it could have been
14:52amalloyinstead, it's implemented in java with an equivalent thingy, compareAndSet
14:53Bronsaamalloy: I don't think swap can be implemetned in terms of compare-and-set
14:53amalloyreally?
14:53TimMcOther way around, right?
14:53hiredmanthere are CAS based algorithms where you want better control over the retries
14:53puredangerpretty much everything can be implemented in terms of CAS
14:54hiredmanBronsa: what makes you say that?
14:54amalloy(defn swap!' [a f] (let [old @a, new (f old)] (if (compare-and-set! a old new) new, (recur a f))))
14:54TimMcOr... thyey can be implemented in terms of each other.
14:54hiredmanno
14:54Bronsaamalloy: hiredman uhm I'm definitely wrong
14:54hiredmanswap! retries until the CAS succeeds
14:55amalloyTimMc: cas is more primitive. you can't really use swap to implementi t
14:55hiredmancomare-and-swap! tries once and returns a boolean
14:55TimMcI mean at the CLJ layer, if you had one of swap! or compare-and-set! you could write the other without interop.
14:56amalloyi don't think that's true
14:56hiredmanif you look at the literature for high performance queues, you often want to do a cas, and if the cas fails do some exponential back off, or switch to some some other strategy, which swap! doesn't let you do
14:57TimMcamalloy: It might require a second atom. :-P
14:57amalloyyes, then you could do it, but that's cheating
14:57TimMcWell...
14:58amalloyactually it's not entirely clear to me how you could do it with a second atom either. coordinating it is non-obvious, and atoms are terrible at coordination
14:59amalloyif you want a solution that works under concurrency
15:02TimMcamalloy: It's stupid, but I think it works: https://www.refheap.com/87845
15:03amalloyyeah, i was just in the middle of writing that myself. i was thinking it doesn't work because of retries, but of course you're resetting it each time you try
15:03amalloyso it's theoretically okay. but on the other hand it's not guaranteed to ever return, which is a problem that compare-and-set! is not supposed to have
15:04TimMcYeah, that's the tricky bit. :-P
15:06TimMcHa, interesting -- you can edit a refheap paste to be private, but not back again.
15:06TimMcwhich is to say it is now at https://www.refheap.com/b08ad02d8bd667abcf364ac65
15:07tbaldrid_amalloy: to the original question, I've used compare-and-set! when I want to return the old value, not the new one.
15:07tbaldrid_amalloy: acutally, every time I've wanted a return value from swap! it's always been the old one, and then I have to write swap-old!
15:07TimMctbaldrid_: Might I suggest https://github.com/timmc/handy/blob/master/src/org/timmc/handy.clj#L129
15:08amalloytbaldridge: really, every time? i find the old one useful about as often as the new one
15:08TimMc(split-atom! a identity f)
15:09puredangerfeel free to vote on http://dev.clojure.org/jira/browse/CLJ-1454 re swap-old!
15:09tbaldridgepuredanger: I think I did ;-)
15:09puredangerI know *you* did :)
15:09tbaldridgerofl
15:09amalloyeg, to reimplement memoize: (defn memoize [f] (let [a (atom {}] (fn [& args] (-> a (swap! update-in [args] (fn [old] (or old (delay (apply f args))))) (deref)))))
15:10amalloytbaldridge: your comment may be the only time anyone has ever used nfirst
15:12TimMcI mostly use my fn for (split-atom! a first next)
15:12seangroveclojurescript: "extend is not currently implemented"
15:12seangrove>.<
15:14tbaldridgeseangrove: seems like that would be a bit "fun" to implement in a AOT compiled language like ClojureScript
15:15tbaldridgeseeing as it just takes a hashmap of function names to functions.
15:34seangroveUhg, clojure.walk doesn't support records.
15:35stuartsierraseangrove: In 1.6 it does
15:36seangrovestuartsierra: Hrm, any idea how that translates to cljs?
15:36stuartsierraseangrove: no idea
15:36stuartsierraDoes cljs even have clojure.walk?
15:36seangrovehttps://github.com/clojure/clojurescript/blob/master/src/cljs/clojure/walk.cljs
15:36tbaldridgeseangrove: if you're using the latest CLJS that means port it yourself and send a patch to dnolen_ ;-)
15:37seangroveI suppose I could take a look at it
15:37stuartsierraIt's easy
15:37stuartsierrahttps://github.com/clojure/clojure/commit/2224dbad5534ff23d3653b07d9dc0a60ba076dd7
15:38seangrovestuartsierra tbaldridge: Yeah, haven't contributed anything to cljs recently, would be good to bring cljs' clojure.walk up to date
15:45dnolen_seangrove: seems pretty straightforward to me, we have the IRecord marker protocol
15:45seangrovednolen_: Yeah, hacking on it locally
15:45seangrovednolen_: Should I use (satisfies? IRecord form) rather than (instance? IRecord form) ?
15:46bbloomseangrove: yes
15:48dnolen_seangrove: you should not consider instance? a thing :)
15:48dnolen_it's there internally for perf reasons
15:48stuartsierradnolen_: Are you referring specifically to `instance?` in ClojureScript?
15:48bbloomit's also anti-modular to depend on concrete types in general
15:49dnolen_stuartsierra: yes
15:49dnolen_oh oops sorry
15:49dnolen_not enough coffee today
15:49dnolen_instance? is fine
15:50dnolen_was thinking about implements?
15:50dnolen_seangrove: instance? IRecord won't work :)
15:52seangrovednolen_: Ok, satisfies? with stuartsierra's change looks like it works. Will check it out a bit more and submit a patch if so
15:54dbasch btw
15:54dbasch,(satisfies? 1 1)
15:54clojurebot#<NullPointerException java.lang.NullPointerException>
15:54dbasch^ could be better
15:54stuartsierradbasch: patches welcome
15:55dbaschstuartsierra: will look into it
15:58stuartsierradbasch: Ah yes, looks like http://dev.clojure.org/jira/browse/CLJ-1107 again.
15:58dbasch,(instance? nil nil) ;; stuartsierra is there a reason this behavior is desirable?
15:58clojurebot#<NullPointerException java.lang.NullPointerException>
15:58dbaschah, ok
16:00puredangerdbasch: no, but it's a "breaking" change
16:01puredanger(although the broken things are already broken, imo)
16:01dbaschpuredanger: oh well
16:02stuartsierra(instance? nil nil) throwing NPE does make sense: that's a bytecode op on the JVM.
16:03stuartsierranull has no type, therefore it is an error to ask for the type of null.
16:04dbaschstuartsierra: it does make sense, but does it make more sense than returning false-y?
16:05stuartsierramaybe
16:05sveriHi, I am trying to use sente and I can establish a ws connection from client to server, however, when I look at the connected uids atom I only see this: {:ws #{nil}, :ajax #{}, :any #{nil}} and it looks like the connection is ok, but the uid is "nil" which is weird I guess, this is my server and client side code: http://pastebin.com/aahbRDQx
16:05dbaschthe reason I brought it up is because it's why (statisfies? 1 1) throws the NPE according to the (old) sources I'm looking at
16:07dbaschah, it's not that
16:08dbaschI think it's this line https://github.com/clojure/clojure/blob/ef2e762e21a817305314ed10bc33505bed6874a5/src/clj/clojure/core_deftype.clj#L497
16:23tbaldridgedbasch: yeah, the first argument is supposed to be a protocol. You're handing it a integer, thus by the laws of Clojure anything can happen
16:24dbaschtbaldridge: do you think it would be worth checking to return a more meaningful error instead of an NPE?
16:24arrdem{:pre [(protocol? ...)]}
16:24tbaldridgedbasch: welcome to clojure.....
16:25dbasch(inc arrdem)
16:25lazybot⇒ 32
16:25tbaldridgedbasch: that requires a check at the invocation of every call to satisfies. Good luck getting that patch approved.
16:26stuartsierraI think it's doable as a fall-through case without adding an additional check at the beginning.
16:28amalloystuartsierra: maybe just catch the exception that is actually produced and wrap it in something nicer? iirc a try/catch costs basically nothing if no exception happens, right?
16:29stuartsierraamalloy: probably not needed
16:30arrdemamalloy: couldn't that obscure other errors?
16:30amalloyarrdem: in satisfies? what other error could there be?
16:31amalloytrue, false, what-the-hell-is-this-i-wanted-a-protocol are the only three reasonable outcomes
16:31arrdemheh
16:31arrdemyeah looking at this I don't see another way to make it explode right off
16:31dbaschI just hate NPEs
16:32arrdemtbaldridge: I did ultimately manage to rebind ns... had to write my own alter-var-root based with-macro-redefs because with-redefs kills the macro metadata and breaks everything
16:32amalloygoogled around a bit, and it looks like try/catch is free if nothing is thrown, except that it adds bytecode, and can prevent some optimizations that assume linear control flow
16:32{blake}Is there are more succinct way of saying "if (nil? %1) (list %2) (cons %2 %1))"?
16:33tbaldridgearrdem: lol yeah, I forgot there's a macro flag on vars
16:33amalloy{blake}: #(cons %2 %1)
16:33amalloythe if is pointless
16:33arrdemtbaldridge: the fun bit is that using with-redefs on a macro flagged var permanently kills the macro flag, which makes code reloading totally horked :D
16:34tbaldridgearrdem: I bet you could do some reflection black magic....
16:34{blake}amalloy, Thanks. Thought I tried that but I must've gotten it wrong.
16:34{blake}(inc amalloy)
16:34lazybot⇒ 138
16:34tbaldridgearrdem: http://stackoverflow.com/questions/1555658/is-it-possible-in-java-to-access-private-fields-via-reflection
16:34{blake}Sorry, TimMc
16:35arrdemtbaldridge: sure, but why bother. this works a treat. https://www.refheap.com/87848
16:35dbaschOTOH if someone is using protocols (which is not a beginner feature) perhaps an NPE is not that horrible
16:40TimMcamalloy: I recently learned that using a finally clause causes code to be duplicated for each catch clause. It's interesting that they chose that instead of using more complicated gotos.
16:41TimMcI'm now imagining some absolutely horrifying situation where a cosmic ray alters the in-memory code for one copy but not another and is even more impossible to debug. :-P
16:41puredangerthere have been a couple strategies used for try/catch/finally bytecode over the years
16:41puredangerI think it was jdk 6 where it last changed significantly
16:42tbaldridgeI know try is mostly free in Java, but is it in clojure? Try bodies are anonymous functions last I checked
16:43Jaoodis there a way to clear/clean the user ns in the repl without restarting it?
16:44amalloyi don't think that's true, tbaldridge
16:44puredangertbaldridge: handwave handwave JIT JIT handwave
16:44amalloythe body of a try is parsed as a BodyExpr, which emits as just a bunch of statements
16:44Bronsahttps://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L2161-L2162
16:45dbaschJaood: you mean something like this? http://stackoverflow.com/questions/3636364/can-i-clean-the-repl
16:45amalloydangit! snuck that in there, apparently. good eyes, Bronsa
16:46tbaldridgepuredanger: it'd be a interesting thing to try sometime, my repl experiments say no, but yes, jit stuff
16:47amalloycan someone explain to me what the various contexts in the compiler mean? i've never really been able to work that one out. like i've seen EXPRESSION and EVAL before, but don't remember seeing RETURN; and anyway i don't know what the others really mean
16:47Bronsaamalloy: return means the expression is in return position
16:47Bronsaas opposed to statement
16:47Bronsa(do 1 2 3)
16:48Bronsa1 2 statement, 3 return
16:48Jaooddbasch: yeah, thanks
16:48Bronsaamalloy: expression is non return, non statement
16:48Bronsaamalloy: meaning the expression value is used but it's not in return position. if it's a statement the return value can be discarded
16:49Bronsaamalloy: eval is this weird context that's somewhat like expression but used when the code is loaded via eval (usually in the repl)
16:50amalloyBronsa: when is an expression's value used but not in return position?
16:50Bronsaamalloy: in a binding for example
16:50Bronsa(let [a 1] 2)
16:50Bronsa1 is an expr
16:50Bronsa2 is return
16:52amalloybecause it's...returning from the let expr? but that's not necessarily returning from the whole function, right? like, in (let [x (let [a 1] 2)] 3), 1 and 2 are both used but not returned
16:52amalloybut 2 is still in RETURN position because it's being returned from the letexpr, whereas there's no expr that 1 is returned from
16:52amalloy(aside from the ConstExpr that emits it?)
16:54Bronsaamalloy: so, wherever you can put a recur, that's a return, if the expression is in do and is not the last expression in that do (do [this]* x), it's a statement, otherwise it's either expression or eval
16:55Bronsain your example 2 has a return ctx, yes
16:56Bronsaamalloy: no actually it's an expr. it has to be in a return position of a fn or a loop to be a return
16:57amalloyi see. so return is like "this would be in tail position if this were the top-level expr of a loop". so the 2 could be in return context, except that it's being parsed as part of a try that's in eval context?
16:57amalloyer, part of a let-binding
16:57brackiHow do I turn a java.io.Outputstream into a ring {:body stream} response?
16:58Bronsaamalloy: that should be correct, yes
16:59technomancybracki: you can copy it to a ByteArray and then make a ByteArrayInputStream
16:59Bronsaamalloy: the last expression in a "block" (let/letfn/..) takes the context of the "block"
17:00Bronsaso if the let is in return position (tail-call of a fn/loop/method body) then the expression in tail position in the let body will have return ctx
17:02Bronsaamalloy: I suck at explaining it but it's really easy to understand if you play a bit with it, analyze some expressions with t.a.j and look at their (-> ast :env :context) and it'll be clear
17:03amalloyyeah, i think i get it, Bronsa
17:04amalloytechnomancy: gross
17:04amalloyuse a pipe; there's one helpfully included in compojure
17:05amalloyor maybe ring. i'm never quite sure
17:05technomancysure, provided you have control over that
17:05brackitechnomancy: Like here http://data-sorcery.org/2009/11/29/incanter-webapp/?
17:06atyzHey all... what would happen if you spawned a lot of futures (blocking calls lasting ~1 second each) then enver defererenced them
17:06atyz*never
17:06amalloytechnomancy: huh? control over what?
17:06turbofailatyz: a future runs whether you dereference it or not
17:07brackiThere's this https://groups.google.com/forum/#!topic/clojure/BZxYCQQJtV8 and this https://github.com/ring-clojure/ring/blob/bc4ddda43e68cc2117f73306d936555ac870239b/ring-core/src/ring/util/io.clj#L11
17:07turbofailatyz: there's a limited thread pool for running them
17:07brackiI don't understand the signature of piped-input-stram
17:07amalloybracki: https://github.com/ring-clojure/ring/blob/bc4ddda43e68cc2117f73306d936555ac870239b/ring-core/src/ring/util/io.clj#L11
17:07puredangerturbofail: it's not limited
17:08amalloyyou can't really convert an output stream to an input stream, bracki. it doesn't make sense, because neither of those actually stores data
17:08atyzturbofail: I think futures are pulling from an unbound pool
17:08amalloyif you have an output stream, and you want writes to it to be sent out over ring, that's what piped-input-stream is for
17:09atyzBasically after a while my cpu usage hits 100% and never comes down. I think this could be due to me abusing futures, is this at all possible?
17:09brackiBut how?
17:09dbaschbracki: what is your output stream? where does it come from?
17:09amalloybut you still have to actually do those writes, so the idea is (let [response (piped-input-stream (fn [out] (.write out "hello!")))] {:status 200 :body response})
17:10brackiI want to use http://people.apache.org/~thejas/thrift-0.9/javadoc/org/apache/thrift/transport/TIOStreamTransport.html
17:10brackiSo I'm not in control of the writing to the outputstream...
17:10turbofailoh hm. wonder why i thought it was bounded
17:10puredangeratyz: do a thread dump - who's doing the work?
17:11puredangerturbofail: the agent send pool is bounded
17:11brackiSo I guess what technomancy said applies. Hard to wrap that thing in a function...
17:12puredangerturbofail: the send-off and future pool (same pool) is a cached thread pool
17:12atyzpuredanger: I did a thread dump (https://www.refheap.com/87785) but it looks similar to a new fresh healthy machine and the thread counts weren't all that different
17:12turbofailpuredanger: ah, the send-pool must have been what i was thinking of
17:13puredangeratyz: none of your threads are doing anything. I don't believe your cpu usage is coming from this process :)
17:13atyzpuredanger: that is really sad news. could you think of anything else that could cause this?
17:13dbaschbracki: it's pretty easy to wrap that in a function, but what do you mean you're not in control of the writing to the output stream?
17:13puredangerwhy do you think it's this process?
17:14atyzeven once the machine is pulled from the LB it continues to stay at 100% utilization
17:14dbaschbracki: I mean, you're writing thrift to an outputstream that you gave that class
17:14atyzpuredanger: my thinking is that there were a bunch of theads getting backed up (they are blocking calls) and for some reason not being killed off
17:14TimMcatyz: Good question -- you *have* confirmed that it's the JVM that's eating the CPU?
17:15puredangeratyz: there are a few threads reading/waiting on sockets - it's possible one of those is reading vast quantities of stuff in a tight loop, but I'd still guess that's IO bound, not CPU bound
17:15puredangeratyz: blocking threads won't show up as cpu utilization
17:15atyzTimMc: I have confirmed that it is the JVM eating the cpu
17:15TimMcOK. :-)
17:16brackidbasch: I'm not doing the write but some Java class using this https://github.com/apache/thrift/blob/38b453be5a015b7aaefcd91b4e261e53e0e211c2/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java#L140
17:16dbaschbracki: ok, but where is it writing to?
17:16brackiBasically I have no control over when (.write stream) is being called
17:16brackiin .write
17:17atyzpuredanger: if that were the case I would expect the cpu utilization to come down after some time?
17:17puredangeratyz: you could connect with jvisualvm or something like that - it can show you what threads are doing
17:17atyzGenerally the amount of data would be a couple kb at most
17:17dbaschbracki: I got that, but what is the output stream?
17:17atyz(thats even a stretch)
17:18amalloyatyz: i'm with puredanger, your jvm isn't doing anything at all. the only way it could be burning through cpu would be like garbage collection
17:18brackidbasch: Something I'm passing in here https://github.com/apache/thrift/blob/56a648d0ffc370123c4f1047b72d0d80080a1d9b/lib/java/src/org/apache/thrift/TBaseProcessor.java#L26
17:19atyzamalloy: if it were garbage collection, how would I confirm that?
17:19puredangeratyz: generally I find if my system is violating my assumptions then one of my assumptions is probably wrong :)
17:19atyzAnd why would it max my cpu indefinitely
17:19atyzpuredanger: I'm sure that I'm wrong in many ways here. Just confused and grasping at straws
17:19puredangeratyz: you would see the GC threads in the thread dump. jvisualvm / jconsole can also show you gc activity
17:20amalloypuredanger: really? i don't recall seeing a gc thread in that list before, like ever
17:21puredangeramalloy: maybe I'm having flashbacks to an earlier time :)
17:21dbaschbracki: I guess my question is: you're writing to some place. What is that place? The network? A file? A Byte array?
17:21amalloypuredanger: i could be wrong. i use yourkit much more than jstack, and while its thread dumps look just like these it's possible it's filtering out some threads i guess
17:22atyzOK so just to dispell my theory completely, having many calls spawned by futures would not exhibit the behavior i'm seeing here?
17:22brackidbasch: I guess a bytearray
17:22puredangeratyz: I don't see anything in this stack that makes me think it's related to futures.
17:23puredangeratyz: I don't even see anything using cpu
17:23atyzpuredanger: is it possible thats because I didn't run it for more than a second or two?
17:23danielsz`I want to split a sequence of variable length in three parts, with the last part having the possible remainder. Think columns in a table. What would be the idiomatic way to achieve this?
17:23amalloythree equal parts, with leftovers appearing in the third?
17:24danielsz`amalloy: yes
17:24dbaschbracki: then do exactly what technomancy said: (.toByteArray os) and then create a ByteArrayInputStream from that
17:25amalloyhttps://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj#L54 does roughly that, except it looks like the excess goes into the first few rather than the last one
17:25puredangeratyz: I don't think I understand what you're doing enough to answer that.
17:27dbaschdanielsz`: you can use partition-all and then concatenate the last two things
17:27danielsz`amalloy: Here's my overkill solution: I partition my sequence, put it in matrix, and take the columns. I figured there must be a simpler way (with built-in fns). But it's not that straightforward as I had thought. At least I can't figure it out,
17:28danielsz`alas.
17:28dbaschdanielsz`: e.g. if you have 20 columns you'll end up with 6-6-6-2
17:28atyzpuredanger: thats fair, I'll take a look into the garbage collection
17:28dbaschdanielsz`: concatenate the last two and you'll have 6-6-8
17:28puredangerjust turn on -verbose:gc
17:29atyzCan you think of anything in particular I shoudl look out for?
17:29danielsz`dbasch: interesting...
17:29hiredmanthe threads are all blocked in that dump, and if you take another dump they will likelly show as blocked again, so the question is, are they actually blocked, or are they flipping back and forth between blocked (waiting on some thing from a queue) and running, the high cpu usage would seem to indicate the switching back and forth, what kind of logging do you have?
17:30atyzhiredman: mostly just request/response logging
17:30atyzNothing actually looking at the jvm or its processes
17:31hiredmanare all the threads doing stuff with datomic?
17:31puredangerdatomic itself has a lot of logging you can turn on, no idea if that would help here
17:32atyzhiredman: I don't think they would be
17:32atyzI'm sshing into a heatlthy machine to see what the thread dump looks like
17:32amalloythat's a cute way to do it, dbasch
17:33hiredmanif datomic reads data in some kind of single threaded fashion, so all your threads are communicating with the datomic io thread via queues you might see something like this, but that is a stretch
17:35atyzhttps://www.refheap.com/87850
17:36atyzhiredman: on an inactive machine, they are blocked as well
17:37puredangeratyz: when you say you just run it for a second or two, do you mean you start the jvm, see 100% cpu, then kill it? if so, what happens if you let it run?
17:38atyzpuredanger: Sorry, i meant to say I killed the thread-dump prematurely
17:38puredangerwell don't do that :)
17:38arohnerwhat is the preferred logging lib to use w/ tools.logging?
17:38puredangerarohner: prob log4j or slf4j over log4j
17:38arohnerthanks
17:39atyzBefore I killed the threaddump. I started teh machine, it was put into the LB. It was used for 2 hours, I pulled it out of the LB (when it was at 100% utilization) and it stayed at 100% utilization for the next 6 hours. At which point it I killed it
17:39atyzI currently don't have any machines at 100% utilization because we just did a deploy and there is very little usage
17:40puredangerso you need a full thread dump when it's at 100% utilization. otherwise, you can't know what's actually using cpu at that time
17:41atyzBut on monday I am very certain that there will be a few at 100%
17:43atyzpuredanger: is there something I should be looking at in the thread-dump that woudl indicate that its the thread that would be using my cpu?
17:43puredangeratyz: it will be RUNNING or RUNNABLE (can't remember which)
17:44atyzSo if the thread-dump doesn't say either ofthose - the cpu usage is not from any of those threads
17:44atyzAnd it would be the GC, possibly?
17:46puredangerwell, it's not the BLOCKED threads. you had a few in IN_NATIVE which could theoretically be doing something but are usually IO waiting. could be GC. using gc logging should make that obvious or just connect with one of the jvm tools and see where the pools are.
17:48atyzOk, I'll give it a look when I have another machine thats stuck at 100% utilization. thank you puredanger amalloy and hiredman
17:49puredangerhappy hunting! :)
17:50atyzhaha, I wouldn't say happy. I hate it when computers make me feel dumb :P
17:50TimMcatyz: Is it throughly enough wedged that you can't attach a liverepl?
17:50cbp/
17:51atyzTimMc: I haven't tried that. they are deployed as jars
17:52atyzAnd don't have access to the box in that way.
17:52atyzThat said, despite being at 100% it still seems fairly responsive
17:53rasmusto_is there something special I have to do to get leiningen to extract/use native dependencies?
17:54technomancyrasmusto_: if the native deps have been packaged for use with lein, there's nothing to do
17:55rasmusto_technomancy: not sure if they have. Trying to use lwjgl-platform-2.8.4-natives-windows.jar
17:55technomancyunlikely then
17:55technomancyunfortunately the docs for that are pretty much crap
17:55technomancyhttps://github.com/technomancy/leiningen/issues/1385
17:56TimMcatyz: liverepl attaches to a running JVM whether it has Clojure in it or not. (Unfortunately, it leaks a classloader each time, so you don't want to do it a lot.)
17:57technomancyprotip: don't think of it as crap documentation, think of it as a pull request opportunity
17:58rasmusto_technomancy: if I add an explicit dep for [org.lwjgl.lwjgl/lwjgl-platform "2.8.4" :classifier "natives-windows"] it'll pull the jar down, I guess I can see about extracting it somehow
17:59aperiodiclast time I made an artifact to be consumed as a native dependency I remember writing a bash script that did manual jar surgery
17:59rasmusto_powershell, here I come
17:59technomancyrasmusto_: if the files that need extracting are under a consistent prefix, :native-prefix "natives/" in the dep vector might do it?
18:01rasmusto_technomancy: the dlls are just in the root of the *-platform.jar
18:01technomancyrasmusto_: maybe just :native-prefix "" then?
18:02rasmusto_kk, will try
18:02rasmusto_technomancy: !! the exception changed. I think that worked
18:02danielsz`If there is a consensus that wholesale imports with :use in the namespace declaration is *evil*, how come the most respected libraries instruct users to do exaclty that? I've seen it three times in a row today. Incanter, core.matrix and ring or ring related. Where is our leadership?
18:03atyzTimMc: https://github.com/djpowell/liverepl <--- That?
18:03technomancydanielsz`: I'm fairly suspicious of incanter in general
18:04technomancyhave run into a number of poor API decisions there, primarily around using macros for no reason
18:04amalloyincanter is like a suuuuuuuper old project
18:05technomancydanielsz`: also there's a big difference between calling the use function directly and putting a :use clause in your ns form
18:05amalloythe author almost has to have been new to clojure when he started, since clojure was new. so probably he's made some poor decisions, in addition to following things that were community standards at the time but have since changed
18:07TimMcatyz: That's the one. We usually kill any host we use it on shortly afterwards as a best practice because of the classloader leakage, but it's hella useful for diagnosis or even hotpatching.
18:07TimMcUnfortunately it doesn't have line editing, IIRC.
18:07danielsz`amalloy: core.matrix is halfway in the standard library! They should know better.
18:07technomancydanielsz`: being a contrib project is entirely a political thing; it doesn't say anything about the code itself
18:08atyzTimMc: The machine is basically dead anyway so I'll give it a try! Thank you :)
18:08atyzI'm going to go home now, enjoy your night!
18:08technomancydanielsz`: if anything it means the docs are less likely to be accurate, because they can't take pull requests
18:08TimMcsame here, you too
18:08technomancyfor quick fixes like this
18:09danielsz`technomancy: What is a use case of a direct use of the use function (except in the README to make a point)?
18:09technomancydanielsz`: repl exploration
18:10danielsz`technomancy: oh yes, of course.
18:10technomancyit's faster to type =)
18:10danielsz`James Reeves definitely knows better. I'll tell him when I get the chance.
18:13ishancIs it possible to gen-class clojure code and use it from java code when both the java and clojure code reside in the same maven project
18:13ishancI am using the clojure-maven-plugin and calling java from clojure works fine, but not the other way around
18:18brackiWhat does this mean? https://github.com/xsc/thrift-clj/blob/master/src/thrift_clj/client.clj#L29
18:18brackiWhat is the signature?
18:19cbpbracki: what signature? {:keys [protocol]} ?
18:19brackii'm talking abot the & :keys stuff
18:19cbpit means you can call that function like (connect! client-class transport :protocol whatever)
18:19rasmusto_,(let [{:keys [a b c]} {:a 1 :b 2 :c nil}] [a b c])
18:19clojurebot[1 2 nil]
18:19cbpbracki: its map destructuring
18:20cbpbracki: the & means it groups every arg after it and then the {:keys } stuff means it destructures it as a map
18:21brackiand the [protocol] part?
18:22gfredericks,(let [[a b & {:keys [c d]}] [1 2 :e :e :d :d :c :c]] [a b c d])
18:22clojurebot[1 2 :c :d]
18:22gfredericksbracki: that means the only key it recognizes is :protocol
18:23danielsz`(inc amalloy)
18:23lazybot⇒ 139
18:23danielsz`That's for the slice function.
18:23gfredericksbracki: i.e., you could call this function like (connect! my-client-class my-transport :protocol my-protocol)
18:23gfredericksor (connect! my-client-class my-transport)
18:24brackitried that but doesn't work...
18:24cbpbracki: it means it's assigning the key :protocol (hence the :keys part) to the name 'protocol'
18:24radixI wonder why they didn't just have two different signatures, with with a protocol argument and one without
18:24cbpthe value of the key i mean
18:24radixs/with with/one with/
18:24gfredericksbracki: in what way did it not work?
18:25gfredericksradix: easier to add more options later?
18:25radixyeah, maybe that.
18:25cbpradix: i guess they thought it would be more explicit to force the user to use the keyword
18:25cbp:-P
18:25rplacaradix: also folks find that keywords are better at documenting how variable args are used, if they really are optional
18:26rplacawhich is basically what cbp said :)
18:27whodidthismaybe would be easier to have a map for the opts
18:27brackigfredericks: it always falls throught to https://github.com/xsc/thrift-clj/blob/master/src/thrift_clj/client.clj#L23
18:29gfredericksbracki: so what's the first arg you're passing to connect!?
18:29brackiOh noes, overwritten import.
18:29brackiEverything is fine.
18:29brackiBut thanks for the destructuring bit
18:35gfredericksI am having some issue with clojure.test and records/protocols
18:35gfrederickssomething to do with the loading-everything-twice tactic I bet
18:35cbpwhat's up with cider now starting at some 'clojure.test.mode' namespace?
18:35gfredericksspecifically a record claimed to not satisfy the protocol when it certainly should
18:36cbpwhich, much to my dismay, does not have clojure.repl use'd
18:37hiredmancider hates the living
18:39gfrederickscbp: I've given up on using things; switched to (ns .)
18:39hiredmangfredericks: throw in some aot'ing and you are totally screwed
18:39gfrederickshiredman: I'm pretty sure I can avoid that thankfully
18:40hiredmanin theory if you are just loading everything twice you should be fine, but if you are doing anything at all between the reloads everything will likely break
18:41hiredmanif you miss a reload, things will break, if you reload in the wrong order, things will break
18:42gfredericksI'm certainly not doing anything other than using normal requires
18:43gfredericksmaybe it's time to bisect my code until I can isolate it
18:45hiredmanah, but do you have :reload in your requires?
18:45gfredericksnope
18:45gfredericksthat would be weird
18:45hiredmanlein used to stick :reloads in the requires for test namespaces
18:45gfredericksO_O
18:45hiredmanfor reasons
18:45abphelp, i'm bleeding clojure for hours now
18:46rasmusto_whatas wrong
18:46cbphe's bleeding clojure
18:46hiredmanwhen I slip shaving parens get everywhere
18:46abpit feels so exciting
18:47rasmusto_hiredman: like ~@?
18:49abpcut down maintenance?
18:50gfredericksno, figure out why clojure no work
18:51abpduh
18:53amalloyi like to imagine maintenance is the name of a really old tree in abp's yard
18:57TimMcnoooo, don't cut it down!
18:58arohnerhas anyone seen 'java.lang.NoClassDefFoundError: clojure/tools/reader/reader_types/Reader' when AOT'ing?
18:59Janiczekany thoughts on the coding style / where it's not idiomatic etc. of https://github.com/Janiczek/cook ? (maybe play with the demo first: http://janiczek.github.io/cook/ - it's short but with a bit of reading)
19:00cbpI have in cljs (:require [goog.date.DateRange :as DateRange]) and (:import [goog.date DateRange]) and other such things. I'm not sure im doing this right
19:03danielsz`(inc hiredman)
19:03lazybot⇒ 49
19:03danielsz`That's for the comment on Cider.
19:03danielsz`It really does hate the living.
19:03amalloycbp: if you have both of this things and others beside it's pretty likely you're not doing it right
19:04amalloyprobably you want only one such thing
19:04cbpand.. it's probably wrong since my repl doesn't like it even though the browser does
19:05gfredericksokay so here's my setup
19:05cbpi guess the answer is to remove the one in the require and switch to DateRange.foo instead of DateRange/foo
19:05gfredericksI have three namespaces: protocol, record, and test
19:05gfredericksprotocol defines a protocol
19:05gfredericksrecord defines a record that implements the protocol
19:06gfredericks(and requires the protocol namespace of course)
19:06gfredericksthe test namespace requires both, and the test creates an instance of the record and calls the protocol fn with it
19:06gfredericksand I get an implementation error
19:06gfredericksbut only with `lein test`
19:06gfredericksif I run `lein test :only the-test-ns` then it passes
19:08cbpactually nevermind that was due to my namespace declaration in the repl not reloading or something
19:08amalloycbp: Foo.bar is kinda like an escape hatch into plain old js; you shouldn't need to use it
19:09abpamalloy: test-maintenance can be a problem. for example testing every single query of an application while also testing the whole api via declarative specs
19:10amalloygfredericks: try putting a (println "compiling x") in each of your namespaces, to see it get double-compiled?
19:10gfredericksamalloy: why haven't I done that yet
19:10cbpamalloy: but then I need to do (DateRange. x y) (DateRange/foo) and DateRange/some-value, and neither import nor require alone allow me to do all of those
19:11gfredericksamalloy: the compile order in the bad case is protocol->record->protocol->test
19:11gfredericksin the good case, protocol->record->test
19:11gfredericksSO THIS IS GREAT
19:13cbper actually import might
19:13cbple sighs
19:17amalloyinteresting, gfredericks. are you sure your tests aren't doing anything weird?
19:17amalloyor your ns forms?
19:17amalloyi say this, as if it were at all useful as a suggestion
19:18gfredericksamalloy: the weirdest thing is that the protocol and records are in test namespaces rather than src namespaces
19:18gfredericksamalloy: my guess is that I didn't reproduce due to nondeterministic namespace ordering?
19:18technomancygfredericks: maybe try putting them in :source-paths in the :dev profile
19:18technomancyinstead of in test/
19:19gfrederickstechnomancy: you're suggesting that test helpers should be separate from the for-realsies-tests?
19:20cbpin which i deref an atom and get a core.async exception
19:20cbpwat
19:20technomancygfredericks: not sure whether that's a general-purpose suggestion or a "this might help in this particular case" suggestion, but yeah
19:21gfrederickstechnomancy: please stay on the line while I try this and a customer service representative will be with you as soon as possible
19:21technomancygfredericks: only if there's decent hold music
19:22noncomis there any existing library to get images from google image search ?
19:22danielsz`technomancy: I meant to ask you: after writing OCaml code on Grenchman, did you have a moment when you said to yourself, this is it, I'm not going back to Clojure?
19:22amalloycbp: i don't think you can get an exception from derefing an atom, in clojure or clojurescript. you *could* get one from attempting to print the result, or really do anything at all with it
19:23gfrederickstechnomancy: the hold music will be good but it will be interrupted every 47 seconds for a message about how super excited we are to have you as a customer
19:23noncomi suppose it is possible with clj-http + some stuff, but probably there is a ready solution
19:23cbpamalloy: yes from printing
19:23amalloygfredericks: i hate you now
19:23gfredericksamalloy: because of how much I appreciate you as a customer?
19:24gfrederickstechnomancy: it worked
19:24gfrederickswhy do we even need the :reload?
19:24technomancygfredericks: for folks with resident project JVMs
19:25gfredericksO_O_O
19:25amalloygfredericks: technomancy runs his tests through swank or cider or whatever, not lein test
19:25technomancylike if you keep your process up in between task runs
19:25technomancy:eval-in :nrepl, ccw, grenchman, etc
19:26gfredericksamalloy: how do I install swank or cider or whatever on my jenkins
19:26amalloyprolly apt-get. the answer to everything
19:26gfrederickswhere is gtrak
19:26technomancydanielsz`: haha, not really. OCaml and Clojure are very complementary.
19:26cbpbrushing up on his coffeescript
19:27technomancydanielsz`: it definitely made me 10x more frustrated at clojure's sloppy nil handling though
19:27technomancy"embrace the platform" is a two-edged sword, as we all know
19:28amalloytechnomancy: but nils are awesome! 10x zero frustration is still zero!
19:28technomancyhttp://p.hagelb.org/get-out.gif
19:28gfrederickslin is an object that signifies the presence of a value; it is always truthy
19:29gfredericksthe SQL equivalent is called LLUN, and it has the property that LUNN = x is always true
19:29gfrederickss/LUNN/LLUN/
19:29aperiodiceven if x is NULL?
19:29danielsz`technomancy: Interesting. I thought there was solace in a native environment vs the hosted one of Clojure (with so many levels of indirectness). And I thought maybe type-oriented development would be addictive. And also more principled design instead of the hackinesss of meta-programming, but maybe all of those are also seductive in their own right.
19:30gfredericksaperiodic: don't do that
19:30technomancydanielsz`: it also made me realize how little I care about homoiconicity
19:30gfrederickstechnomancy: but but paredit!
19:30amalloyaperiodic: testing NULL==LLUN is defined to uninstall your database server
19:30hiredmangfredericks: I jave a jenkins plugin that launches an nrepl repl inside the jenkins jvm
19:30technomancydanielsz`: the main pain point with ocaml syntax is its precedence rules, not the lack of macros
19:31rasmusto_hmm, I have to do a lein clean && lein deps to get my target/native stuff to show up
19:31hiredmanit was super painful
19:31hiredmanthe insides of jenkins are terrible
19:31amalloyrasmusto_: everytime you run *one* of those commands god kills a kitten
19:31gfredericksthe insides of _______ are pretty bad too
19:32technomancydanielsz`: avoiding the large runtime just means you can apply it to a different class of problems. better at small utilities but worse at long-running servers, etc.
19:32hiredmanhttps://github.com/hiredman/jenkins-clojure-injector/blob/master/src/leiningen/jpi.clj
19:32amalloytechnomancy: i had to run `lein clean && lein deps` a few weeks ago, but this was on lein 1.6 and so i didn't think you'd appreciate the bug report
19:32technomancyamalloy: I forgive you.
19:33rasmusto_part of my confusion is trying to deal with a project that has a lot of native stuff and non-specific dependencies
19:33rasmusto_the leiningen stuff is very usable so far, thanks for the support technomancy
19:33technomancyrasmusto_: cool
19:33technomancynative code is definitely a weak point right now since no one understands how it works
19:35danielsz`technomancy: Maybe if you had written Grenchman in Haskell where precedence rules are configurable we would have lost you for good :-)
19:35technomancydanielsz`: lost me to raving lunacy, probably
19:36arrdemtechnomancy: what, you aren't raving already? you built a build tool ffs
19:36technomancydebatable
19:36turbofailhm. when i have to switch between ruby and clojure i find homoiconicity to be a huge deal
19:37turbofailbut perhaps ocaml is different
19:37technomancyturbofail: homoiconicity or clarity?
19:37turbofailboth
19:37technomancyclojure achieves clarity/consistency through homoiconicity I would say
19:37turbofaili really miss being able to use paredit commands for shuffling my code around
19:37technomancyruby fairs to achieve clarity most of the time, and ocaml achieves it through other means
19:38technomancyalso, you can do C-M-k (kill expression at point) without paredit, which goes a long way
19:38technomancyso actually bitemyapp threatened to port grenchman to haskell
19:38turbofailha
19:38technomancyhaha "Derelict repo, abandoned because I have no interest in making tools for the Clojure community."
19:39technomancycute
19:39arrdemyeah... pls flounce more
19:39technomancyhttps://github.com/bitemyapp/grom
19:39danielsz`is it only me or this place feels less threatening since bitemyapp left?
19:40aperiodicit's not just you
19:40arrdemnot just you... it's been an improvement since blocking him on twitter as well..
19:41arrdemlast time we met in person he had some one-liner about how he's keeping a scorecard for how many blocks he can accumulate from clojure users...
19:41danielsz`amazing how 1 person can set a general mood.
19:41technomancyhow is this an improvement? https://github.com/bitemyapp/grom/blob/master/src/Main.hs#L29 over https://github.com/technomancy/grenchman/blob/master/grench.ml#L35
19:42turbofailhm. how does C-M-k work in ocaml? isn't the entire notion of "next sexp" kind of fuzzy?
19:42technomancyturbofail: not at all; it's quite clear
19:43ttasteriscoso what's the story behind bitemyapp? met him once last year at a clj meetup, he sounded peaceful. fast forward a few months and he moved to haskell and all I saw was some rages at clojure?
19:43danielsz`turbofail: Emacs adjusts the meaning of "expression at point" based on context.
19:43technomancyat least, emacs is smart enough to figure it out consistently
19:44amalloyttasterisco: from what i understand he's a pretty mellow guy in person. in #clojure, he was abrasive
19:44arrdemamalloy: meh... he's way more abrasive online, but he's not exactly mellow in person either
19:44technomancyhe's out to prove how right slash smart he is
19:45danielsz`ttasterisco: He's just an assertive and opinionated person. He discovered Haskell and preaches it now. If you don't mind his style, use it to your benefit. Everybody wins at learning Haskell.
19:45technomancyone of my favourite things about OCaml is how it doesn't attract that kind of person
19:46amalloyhaskell is pretty cool. it's just, knowing that doesn't have to correlate with being a jerk. i don't think haskell was really that important in his decision to leave
19:46gfrederickscamel-like personalities
19:46amalloytechnomancy: what is List.tl? clojure.core/rest?
19:46danielsz`Haskell are known to be a peaceful bunch too. Bitemyapp is not representative of Haskell any more than he was of Clojure.
19:47technomancyamalloy: yeah
19:47turbofailtechnomancy: so when you have something like "|List.fold_left (+) 0 xs", what's the "next sexp"?
19:47turbofailin clojure, depending on where i put the point, the next sexp could be `fold-left', or it could be the whole `(fold-left ...) thing
19:48turbofailbut it doesn't seem like i have those options here
19:48technomancyturbofail: probably the whole thing. it's been almost a year since I was using it though.
19:48turbofailhm
19:50amalloyi would have guessed List.fold_left is the next sexp, because in that world you can get the whole thing if you want, via M-4 C-M-k
19:50technomancykinda want to get back into it, but hard to justify when the only clojure I write is lein itself
19:51technomancyI really miss option types and pattern matching
19:52danielsz`technomancy: Exactly.
19:53danielsz`technomancy: I saw this earlier today. I haven't read it seriously though: http://brehaut.net/blog/2011/error_monads
19:53technomancydanielsz`: option types without pattern matching isn't really worth the trouble though
19:54danielsz`technomancy: Good point.
19:54technomancythere's a big difference between "using this technique in our own codebase" and "this technique is pervasively used in the language"
19:55danielsz`technomancy: Very true. Would you say the same for CSP and core.async?
19:55technomancyI don't really know enough about csp to comment
19:56technomancyI suspect it's different just because async communication is a much less common need than representing potential failures
19:57technomancy(witness the fact that I have basically never needed the former personally, whereas any nontrivial program needs the latter)
19:58danielsz`technomancy: I mean that Lisp languages can adopt paradigms and really sway the constituency, like core.async.
19:59danielsz`Lots of people use core.async like it was part of Clojure. While no Option types implementation has convinced. We have the parts. We have core.match and error monads. But it didn't take on.
20:00technomancycore.match was horribly broken for years
20:00danielsz`Maybe that's the reason. Is it better now?
20:00technomancyyeah, but it still never had nearly as much work poured into it as core.async
20:00technomancywhich is really infuriating imo
20:00technomancybecause it's so much more useful
20:01danielsz`I've used it in cljs projects. Very useful, I love it.
20:01arrdemtbaldridge: so given that I'm gonna have to eat the price of compiling clojure/core.clj with the reference compiler whenever I finally hook into RT, do you think it's worth the effort to hack the way require behaves so that core.clj is loaded, analyzed and reduced by Oxcart? I'd like to be able to use the tightest core that Oxcart can build but given that RT is gonna build the "normal" core anyway I'm not sure it buys me anything without starting to write m
20:01technomancyoh yeah, I speak only for server-side stuff
20:01turbofailcore.match looks kind of awkward compared to racket's pattern matcher
20:01turbofailsyntactically anyway
20:02brehauttechnomancy: the error monad thing is useful but yes, problematic. i used polymorphism and it works but it makes me sad
20:02brehauttechnomancy: i'd rewrite that with core.match in a second if i could
20:02technomancybrehaut: erlang just uses pattern matching against lists. works great and is a fairly pervasive pattern
20:02technomancybut core.match is too fast-moving for me to include in lein
20:03technomancysince it would preclude plugins from using newer versions =(
20:03technomancyI've only used core.match in a brief seajure hack night
20:03brehautright
20:04brehauti think core.match has settled a bit recently? mostly due to some hard problems that dnolen is still working out?
20:04technomancyI've been burned by too-old deps several times in the past
20:05technomancybrehaut: it's not just that new versions must be backwards-compatible, it's that new versions literally cannot be loaded by plugins =\
20:05brehautyouch yeah
20:06technomancyhttps://github.com/technomancy/leiningen/issues/1563 =(
20:06gfrederickstechnomancy: just renamespace the libs you want :P
20:07technomancy._.
20:07gfrederickshey man, do it for leiningen.
20:07gfredericks(ns leiningen.clojure.core.match ...)
20:07brehauttechnomancy: :S
20:08technomancyhttp://p.hagelb.org/10no.gif
20:09brehauthaha
20:11danielsz`What makes or breaks compatibility with leiningen? Is it only version clashes with leiningen's own dependencies?
20:12technomancydanielsz`: plugins can only introduce new dependencies, not new versions of existing ones.
20:13technomancywhich I guess is what you said
20:14danielsz`I think so. And those existing dependencies are those listed in leinignen's project.clj: https://github.com/technomancy/leiningen/blob/master/project.clj
20:14danielsz`Very few dependencies.
20:15danielsz`Ah, yes, core.cache gave some trouble
20:16technomancyhttp://p.hagelb.org/lein-deps-tree.html 66 deps in the full tree
20:17danielsz`Oh, I see.
20:17technomancydata.xml and apache http-client are another source of troubles
20:18danielsz`Ah, yes, http-client, talking about fast-moving...
20:19ShayanjmIf I wanted to run a function, wait for some time, then recur indefinitely - how might I do this without committing code suicide?
20:20danielsz`Shayanjm: Would this help? https://github.com/joegallo/robert-bruce
20:21Shayanjmwhy yes, yes it would danielsz`
20:21Shayanjmthanks :)
20:21rurumateis there any source on how to convert the result of (go 42) to a java.concurrent.Future or something similar
20:22rurumatein java preferably
20:22_99hats_danielsz: nice find! I've been looking for something like that too
20:22brehaut,(class (future 1))
20:22clojurebot#<SecurityException java.lang.SecurityException: no threads please>
20:23brehaut&(class (future 1))
20:23lazybotjava.lang.SecurityException: You tripped the alarm! future-call is bad!
20:23danielsz`Shayanjm: That's a library solution. Many ways to achieve this with built-in fns too. Look at delay, future, etc.
20:23brehautle sigh
20:23brehaut,(source future-call)
20:23clojurebotSource not found\n
20:23Shayanjmmuch appreciate danielsz` :)
20:23Shayanjmappreciated**
20:23danielsz`Welcome.
20:31tuft_is there a way to make certain functions available in all namespaces for repl sessions?
20:31tuft_keep needing to "cd" back to user for doc, refresh, etc.
20:32technomancytuft: not really; the best way to do stuff like that is to expose it from the editor
20:32technomancycider for instance has doc, source, etc, but it makes adding new commands difficult
20:33tuftah hrm, ok
20:33tuftthought there might be a way to "patch" clojure.core or something
20:34tuftmy workflow is to run files in the repl, which changes the ns
20:34arrdemtuft: not really, you'd have to hack either the namespace macro or in-ns, neither of which is an awesome idea.
20:34tuft(i'm using cursive)
20:34tuftok, thanks
20:35technomancygfredericks: did you notice how I helped with your defrecord problem without ever once chastising you for using records?
20:36rurumatenot sure if this works: https://www.refheap.com/87852
20:36rurumatecan just call macros using RT.var() ??
20:36lazybotrurumate: Uh, no. Why would you even ask?
20:36technomancytuft: a better solution would be https://github.com/technomancy/nrepl-discover
20:36technomancyexcept it's kinda half-baked
20:37rurumatelet's be nice lazybot mkay
20:39amalloyrurumate: well, he was right
20:39amalloyand robots can afford to be rude
20:40rurumateRT.var("clojure.core","->").invoke(5)
20:40rurumatedon't know how to write that in a repl so not even trying lol
20:41amalloyrurumate: calling macros from java is basically impossible; you can do it, but all they produce is clojure code, which does you no good
20:41noonian,#'->
20:41clojurebot#'clojure.core/->
20:41rurumateso what call RT.var("clojure.core","eval").invoke("(-> 5)") maybe?
20:41amalloythe core.async macros like <! are even worse, because they don't actually exist as real macros: they're just placeholders that go looks for
20:43rurumateis <! a macro?
20:43arrdemyep
20:43amalloyno, it's magic
20:43arrdem(assert (magic? macros))
20:43rurumatewell it could be a function for instance, or just data
20:43rurumatea symbol?
20:43amalloyit's none of those things. it doesn't exist
20:44amalloycore.async/go looks for it in your code
20:44rurumatesince we're in a go block it doesn't matter what it is right
20:44rplacawell, it *is* a symbol
20:44rurumateso just a symbol? but I had to require it
20:45rplacabut the go block macro expansion recognizes it and transforms around it
20:45rurumateanyway how to convert the return value of a go-block to a Future<Object>, there surely is something yet?
20:46rurumatejust for interop goodness
20:47noonianyou could write it in clojure and just call that var
20:47rurumateuuh, that fn you mean?
20:47noonianyes
20:47rurumatethatt would work, provided we have already written it in clojure :D
20:47nooniango-blocks return channels that return the last form of the body of the go-block
20:48rurumateyes, but there is no java interface "channel" and it can be treated like a Future in manyn cases, to from java perspective, it is a Future right?
20:49rurumatesorry keyboard is falling apart
20:49technomancyamalloy: I wonder if it qualifies as a special form
20:50technomancyiirc thrown? in clojure.test is the same way
20:50amalloytechnomancy: well, compare to catch and finally in a try
20:51rurumate_I mean we should probable also write a converter channel -> Queue and a new interface Channel maybe but for now I'm trying to convert the ch to a Future
20:51technomancyamalloy: yup
20:51amalloytry is a special form, and it dictates how to handle catch/finally, neither of which are themselves special
20:51technomancyif you consider the macro the "compiler" I think it fits the definition
20:52rurumate_how to evaluate whole clojure expression given as string, from java?
20:53rurumate_RT.var("clojure.core",:eval read-string can do
20:54rurumate_sigh, RT.var("clojure.core","eval").invoke("clojure.core","read-string").invoke("(-> 5)")
20:57amalloyrurumate_: in clojure 1.6, clojure.java.api.Clojure makes that slightly more convenient, but you've got the basic idea
20:57rurumate_still wrong tho
20:57amalloyoh? did you forget to require clojure.core?
20:59rurumate_why is this so hard?
20:59technomancybecause it's java
21:00amalloyi don't know what he's complaining about. the thing he pasted works
21:00amalloy,(-> (RT/var "clojure.core" "eval") (.invoke (-> (RT/var "clojure.core" "read-string") (.invoke "(-> 5)"))))
21:00clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: RT, compiling:(NO_SOURCE_PATH:0:0)>
21:01amalloy,(-> (clojure.lang.RT/var "clojure.core" "eval") (.invoke (-> (clojure.lang.RT/var "clojure.core" "read-string") (.invoke "(-> 5)"))))
21:01clojurebot5
21:01technomancywell, I wouldn't know how to do that in java
21:01amalloyit's what he pasted
21:01amalloyoh, except he needs to cast to IFn
21:02amalloyno, i guess he doesn't. dunno what was wrong for him
21:08gfrederickstechnomancy: no I did not notice that. thank you for helping me with my defrecord porblem
21:08gfredericks(inc technomancy)
21:08lazybot⇒ 116
21:08technomancyI was holding back
21:10gfrederickstechnomancy: I'm curious how you would model the problem; can't splain it right now though
21:13gfrederickstechnomancy: I guess it's just an unqualified "multimethods" eh?
21:13arrdemhappy 4th people
21:13arrdemmurica
21:29technomancygfredericks: if it's a legitimate polymorphism need, sure
21:29technomancy*legitimate non-bottleneck polymorphism
21:31gfrederickstechnomancy: I use component and I like how protocols formalize the relationship between different parts of the application
21:32gfredericksand make it easy to mock stuff in tests
21:32Shayanjmnot sure if this function does what I want it to do...
21:32Shayanjmhttps://gist.github.com/shayanjm/383b5847738c35f748a6
21:33ShayanjmBasically, when I pass a function into infinite-loop-on-realization, I would like it to execute the function, wait for it to return, and then repeat without blocking the execution of anything else
21:34hiredmanuh
21:35hiredmanrealized? is always true for a promise you have delivered to
21:35ShayanjmEven if the promise hasn't fully resolved yet hiredman?
21:35Shayanjmi.e: if 'func' takes like a minute to fully execute
21:35Shayanjmis current-promise realized before func finishes executing?
21:36hiredmanShayanjm: you are calling func as an argument to deliver, so by the time deliver runs, func as already finished
21:36hiredman(while true (func)) is equivilant to what you have written there
21:37ShayanjmOh I see
21:37ShayanjmSo I actually don't even need the when
21:37ShayanjmI just loop after deliver?
21:38hiredmanno, the promise and the deliver are doing nothing there
21:38hiredman(while true (func)) will run exactly the same
21:38Shayanjmoic
21:38ShayanjmOkay let me ask this a different way
21:38Shayanjmgiven a function which I would like to execute continuously without blocking, and loop on return, what's the easiest way to do that?
21:39Shayanjmsince I'm assuming (while true (func)) will block
21:39hiredmanShayanjm: rigth, and so will your code
21:39ShayanjmOkay let me try refactoring this really quickly
21:46Shayanjmhiredman: https://gist.github.com/shayanjm/d37b5b34b08281fa0aa7
21:46Shayanjmthrew the function into a future
21:47Shayanjmwaiting until the function finishes executing, then recurs
21:54ShayanjmYeah I don't think this is doing what I want it to do...
22:06hellofunki'm trying to find the best way to architect a series of source files that communicate via async channels; but they must all know the same channel object to do so. to avoid circular dependencies, i'm giving each one an atom, then a controller source file creates the channel and each file gets a copy of it. but seems like potential for state mess
22:08ddellacostahellofunk: why can't you put the shared channel in one namespace, and then include that in all the other namespaces that need it?
22:09hellofunkddellacosta: but just including a namespace isn't the same as including the data in an atom stored in that namespace, right? wouldn't all the includes lead to different default values for the atom?
22:09ddellacostahellofunk: or is that what you're doing and I'm not understanding your question?
22:10ddellacostahellofunk: it doesn't have to do with namespaces, it has to do with threads and the type of construct you choose to use
22:10ddellacostahellofunk: I like Arthur Ulfeldt's answer here: http://stackoverflow.com/questions/9132346/clojure-differences-between-ref-var-agent-atom-with-examples
22:11hellofunkddellacosta for example, i have a (def a (atom 0)) in a namespace. now I include this namespace in a bunch of others. But if the atom is swapped by one file, that wouldn't mean that the other files that include the atom file will see that new atom's state
22:11ddellacostahellofunk: yes. So you have to know that that's the model you want to use.
22:12hellofunkddellacosta: you mean "yes" as in, I am correct, the swapped atom would not in that case be seen by other files.
22:13ddellacostahellofunk: no, it would. You are updating that atom and that update would be visible to all namespaces using it.
22:13ddellacostahellofunk: sorry if I responding confusingly, I meant, "yes it would update"
22:14hellofunkddellacosta: oh that's interesting. I thought that when a file does a require, it basically reads the source file as if it was brand new and hadn't been loaded before and any (def a (atom...)) creates a new atom; therefore every require in the whole project would be creating new atoms
22:15nathan7hellofunk: namespaces are like, actual objects
22:15nathan7hellofunk: held in a global table of all namespaces
22:15nathan7hellofunk: they're loaded once
22:16nathan7hellofunk: if you're AOT compiling, they're just classfiles
22:16hellofunknathan7, ddellacosta: ah! so no matter how many times you load (require) a namespace, it really only exists once, including any defs (atoms) it has? wow this is definitely not what I thought was happening.
22:16ddellacostawell, think about defonce
22:16nathan7hellofunk: yep
22:16nathan7hellofunk: see (all-ns)
22:16nathan7,(all-ns)
22:16clojurebot(#<Namespace clojure.uuid> #<Namespace user> #<Namespace clojure.core> #<Namespace sandbox> #<Namespace clojure.repl> ...)
22:17hellofunknathan7 well this certainly makes things easier. i was forging into spaghetti and now i see that was unnecessary
22:17nathan7,(->> (all-ns) (map #(vector (.name %) %)) (into {}))
22:17clojurebot{user #<Namespace user>, clojure.core.protocols #<Namespace clojure.core.protocols>, clojure.core #<Namespace clojure.core>, sandbox #<Namespace sandbox>, clojure.uuid #<Namespace clojure.uuid>, ...}
22:18nathan7that map exists somewhere, the global namespace table
22:18hellofunknathan7 so the first namespace to require another namespace "instantiates" it, while any other requires just "point" to it
22:18nathan7hellofunk: yep
22:19nathan7hellofunk: you could consider all the namespaces as 'already there', but just lazily loaded
22:19hellofunknathan7 i was so wrapped up in the functional nature of how clojure works, it did not occur to me that this object-oriented type of state could be happening
22:19ddellacostahellofunk: yes, I was going to say, think about defonce--its existence tells you a lot about how namespaces work in Clojure
22:19ddellacosta(doc defonce)
22:19clojureboteval service is offline
22:20ddellacosta$&!#&!
22:20ddellacosta&(doc defonce)
22:20lazybot⇒ "Macro ([name expr]); defs name to have the root value of the expr iff the named var has no root value, else expr is unevaluated"
22:21hellofunkddellacosta but if require points to existing namespace objects already, i would think that just plain ol' def would not get recreated if what nathan7 says is correct, that def would not re-def everytime the file is loaded
22:21nathan7hellofunk: it would re-def every time the file is loaded
22:21nathan7hellofunk: however, the file is loaded only once
22:21nathan7hellofunk: unless you require it with :reload
22:22hellofunknathan7 ah, so if i have a (def (atom ...)) then indeed every time that namespace is required, the def will indeed be reset. thus, defonce would prevent this and ensure that only one piece of state existed unchanged no matter how many requires
22:22nathan7hellofunk: no
22:22ddellacostahellofunk: not required, reloaded
22:23hiredmanrequire loads the namespace if it is not already loaded
22:23nathan7hellofunk: require looks like (if (contains? namespaces) (get namespaces ns) (load ns))
22:23hellofunkwell, i mean the :require in the (ns at the top of the file.
22:23nathan7hellofunk: yes
22:23nathan7hellofunk: it'll load it if it isn't loaded yet
22:24hellofunkso, going back to ddellacosta original suggestion, i could put all my shared atoms in a single namespace, but they should be defonce for all of them
22:24hiredmanugh
22:24hiredmanterrible
22:24hiredmanhow about you just pass arguments to functions
22:24hellofunkhiredman, well this gets back to my original question
22:25hellofunkhiredman, the problem is circular dependencies.
22:25nathan7hellofunk: even just def would be fine
22:25hiredmanhellofunk: it isn't
22:25nathan7,@#'clojure.core/*loaded-libs*
22:25clojurebot#<Ref@7643fa: #{clojure.core.protocols clojure.instant clojure.java.io clojure.repl clojure.string ...}>
22:25hellofunknathan7 you say that because everything is loaded at once, therefore all the multiple defs just happen at the same time
22:25hiredmancreate a namespace foo, it requires the other namespaces and calls functions from them
22:26nathan7hellofunk: http://sprunge.us/YOTZ?clojure
22:26nathan7hellofunk: src/clj/clojure/core.clj around line 5475
22:26hiredman(require '[foo.bar :as foo] '[a.b :as a]) (let [c (chan] (foo/bar c) (a/bar c)) etc
22:27nathan7hellofunk: if you haven't passed :reload, and it's already loaded, it'll just grab it from *loaded-libs*
22:27hiredmanglobal atoms in a namespace? what are you guys even thinking?
22:27nathan7q=
22:28hellofunkhiredman so you are suggesting to just pass the channel as arguments instead of sharing it in a piece of state
22:28ddellacostahiredman: I've had cases where global atoms are the right solution--for example if I need initialization of a resource to happen at a specific time, and I know it won't change.
22:28hiredmanhellofunk: yes
22:29nathan7my main clojure app has an agent like this for similar reasons
22:29hellofunkhiredman well I can't really argue with that. but part of this model is stemming from the fact that I'm using Om, which uses a single global atom for state. and i'm trying to interact with it from various source files
22:29nathan7it's the state everything operates on
22:29hiredmannathan7: ugh
22:29nathan7hiredman: it's a server, it has one global piece of state I need to interact with everywhere
22:29hiredmannathan7: ugh
22:29nathan7hiredman: if there is >1 instance of it everything is fucked
22:30nathan7hiredman: and I need access to it from nREPLs etc
22:30nathan7hiredman: I'm considering moving it into the file with my -main and passing it to everywhere from there
22:30nathan7hiredman: but that's still kind of painful
22:30nathan7hiredman: like, I am totally with you on this
22:31nathan7hiredman: but this is just like, say, the global table of namespaces
22:31nathan7hiredman: because it's basically this app's namespaces of domain data
22:32nathan7I still have to think a bunch about how the state works for this thing though
22:32hellofunkhiredman or i guess one could just pass the atom itself around in the arguments
22:33hellofunkhiredman it just seemed easier to reduce lots of extra args on every function
22:33ddellacostahellofunk: I think an atom is a perfectly reasonable place to put a channel that you know won't change for the lifecycle of the app
22:33ddellacostahellofunk: but opinions may differ
22:33nathan7ddellacosta phrased what I was trying to say perfectly
22:34nathan7like, passing this around everywhere would lead to state being strewn all over the place
22:34nathan7and I'm writing Clojure because I wish to avoid that
22:34hellofunkddellacosta regarding defonce vs just def seems this is useful only if you might actually call def on something more than once
22:35nathan7I use defonce for this because I'd rather not have all my state reappear when I re-evaluate the file it's in
22:35hellofunknathan7 be "reappear" you mean get reset to the default state noted in the source file
22:36nathan7hellofunk: which is 'empty'
22:36nathan7hellofunk: (defonce world (agent (WorldState.))
22:37hellofunknathan7 so i think you mean "disappear" upon re-eval rather than "appear" ?
22:37ddellacostanathan7: yes, passing stuff around exclusively can lead to equally hard-to-reason-about code
22:37nathan7err, disappear, yes
22:37gfixlerIs there a version of drop-while that returns the result of the predicate test, instead of the shorter collection?
22:37nathan7Clojure namespaces are a really pleasant mechanism for this stuff
22:38hellofunkwell all this has been quite enlightening. all this time i thought :require statements were giving each source file its own copy of everything in the :require'd namespace. fantastic to hear that's not the case.
22:38ddellacosta_hiredman: can you please allow my handle (ddellacosta) access to clojurebot?
22:38nathan7namespaces just… magically reify a concept I already use in any module system
22:38nathan7and it's grand
22:39nathan7like, my code is data, and it's state
22:39hellofunkthat namespaces are basically an object-oriented structure inside any clojure project is pretty cool, actually.
22:40ddellacosta_hellofunk: not object-oriented. ;-)
22:40nathan7object-oriented in the sense that they are objects that can be manipulated, perhaps
22:41hellofunknathan7 object-oriented in that they are single copies of everything they contain, where all the defs are like stored state made available to any other namespace that uses it
22:43nathan7hellofunk: I suppose they're actually quite OO
22:43nathan7hellofunk: they're state and behaviour
22:43gfixlerNevermind, found it: (some #(when (pred? %) %) coll) ; Clojure is cool
22:43nathan7gfixler: hm, there should be a better way
22:43ddellacosta_nathan7: but not encapsulated; there's no data hiding, no?
22:43nathan7ddellacosta_: ^:private
22:44ddellacosta_nathan7: hmm, fair point, although there's a good amount of debate over use of ^:private
22:44gfixlernathan7: how about (winner pred? coll)? :)
22:45danielsz` gfixler: that reads like 'filter to me
22:45gfixlerdanelsz: you're right - so maybe (first (filter pred? coll))
22:46nathan7okay now I feel very stupid for not thinking of that
22:46gfixlerIt's worse for me; I've been looking at this for about 20 minutes :(
22:46nathan7this is the thing about functional programming languages
22:47danielsz`give it some time. it sinks in and becomes second nature
22:47nathan7like, once I start doing complex objects I can just worry about how my shit fits into this complicated structure
22:47nathan7and I can avoid solving actual, well, math, technically
22:48gfixlerEven though I'm a newb to FP, it's happening. It's becoming more normal each day.
22:48nathan7I'm a functional JS programmer, people pay me money to write JavaScript
22:48nathan7and I love it
22:49gfixlerNice. I'm in games - mostly Python for tools/pipeline stuff in Autodesk Maya.
22:49nathan7because they're convinced that I'm writing JS, and I'm just writing functional code, that happens to be encoded as JavaScript
22:50nathan7and JS lends itself perfectly to this
22:50clojurebotIt's greek to me.
22:50gfixlerHehe. I'm also doing somewhat functional things in Python, and no one is the wiser.
22:50nathan7something I've been doing for a few projects is just prototyping the concepts in Clojure
22:50nathan7and then transliterating it
22:50gfixlerAre you on Linux?
22:50nathan7Yep
22:50gfixlernice
22:50nathan7like, I have a bunch of little helper libs
22:50gfixlersame here - I can hop in and out of languages instantly
22:51gfixler"How would I do this in Clojure?" - seconds later hammering away in a repl
22:51gfixlerthen I go back to Python and sigh, because it's much harder there
22:51nathan7I wrote a helper lib that's just all the hashmap functions from Clojure
22:51nathan7like, assoc/assoc-in/dissoc/keys/vals/etc
22:51gfixlercool - FP is giving JS a second life
22:52nathan7and each of the mutation functions has a matching one postfixed with M
22:52nathan7which actually mutates objects in place instead of copying them completely for every operation
22:53nathan7I write my stuff using the pure functions
22:53gfixlerYou didn't reimplement Clojure's shared structure stuff, did you?
22:53nathan7I did not
22:53gfixlerphwew
22:53nathan7it's a naive copy
22:53gfixlerthat would be crazy
22:53nathan7there's a lib, mori, that just re-exports all ClojureScript's stuff to JSland
22:54nathan7but I want to work with just raw JS objects because mori is giant
22:54nathan7once I'm done writing my logic
22:54nathan7I go through my code and look at where state enters and leaves
22:54gfixlerAh, swannodette, I should've known
22:54gfixlerthat guy is brilliant
22:54nathan7and append an M to function calls
22:55nathan7like, same thing you'd do in Clojure with transients
22:55gfixlerI haven't heard of transients yet
22:55gfixlerWell, I guess that's now technically untrue
22:56nathan7so, Clojure data structures are like all structure-sharing and stuff, so creating new ones instead of mutating in-place is fast
22:56nathan7but if you're doing, say, group-by, and just modifying the same hashmap a hundred times, you're creating a hundred objects and letting them be GC'd again
22:57nathan7so instead, you do (transient {}), and use assoc! instead of assoc
22:57nathan7and get an object that actually mutates in-place
22:57gfixlergot it
22:57nathan7they implement IEditableCollection
22:58nathan7so, assoc! returns a new transient, and marks the old one as being unusable (every operation on it throws, I think), and you pass them around inside your function the same way you'd do otherwise
22:58gfixlerinteresting
22:58nathan7and when you're done with it, you call persistent! and it turns it into a regular hashmap
22:59gfixlersweet - I just found this possibly related thing tonight: http://z.caudate.me/you-took-3-months-to-write-a-mutable-array/
22:59nathan7like, check (source group-by) in your REPL
23:00nathan7gfixler: like, mutable state creates huge trouble for applications
23:00nathan7gfixler: but functions mutating something internally, not externally visible -> "if a tree falls in a forest, and nobody is around to hear it"
23:01nathan7-> if a function mutates a structure internally, and nobody's around to see it
23:01gfixlerRight, as with loop invariants
23:01gfixlerthings are free to change inside the loop, but must be stable at the start and end of each iteration
23:01nathan7Yep.
23:07dbaschnathan7: I don't think that's correct (assoc! may return the same object, although there are no guarantees)
23:25nathan7dbasch: oh?
23:25nathan7dbasch: hmm, yes
23:26dbasche.g.
23:26dbasch,(let [a (transient {})] (= a (assoc! a :b :c)))
23:26clojurebottrue
23:28nathan7dbasch: identical? would be more clear, but yeah
23:28nathan7(I'm aware transients don't do actual deep equality)
23:29dbasch,(let [a (transient {})] (identical? a (assoc! a :b :c)))
23:29clojurebottrue
23:32dbaschnathan7: other than that, I like your explanation
23:33nathan7dbasch: I basically pull the same tricks in JS
23:34nathan7dbasch: like, perform escape analysis in your head, add some M's in places
23:37nathan7dbasch: I'm a compiler nerd (though a fairly half-assed one), so I spend a lot of time thinking about this kind of thing
23:38nathan7dbasch: I have a pile of notes on a fully-refcounted language, where every heap object has an atomic refcounter
23:38nathan7dbasch: and then using that to mutate objects in place opportunistically
23:39nathan7dbasch: and avoiding a lot of allocation using this
23:39nathan7dbasch: and smart ahead-of-time escape analysis style trickery to do even more magic like this
23:40dbaschsounds cool, but at the same time a lot of work
23:41nathan7like, every time I have to think about this, I go scribble in my notes for a bit on how the compiler could do it for me
23:41nathan7a lot of abstractions can be zero-cost
23:43nathan7and all of these things are incremental — you have a little more information on how the program works, the compiler can do a bunch more
23:43nathan7like, a system I admire very much is ZFS, which has this magical property too
23:43nathan7you throw more hardware at it, and it magically becomes faster, in ways that are actually really intelligent, but a lot of it is emergent behaviour
23:44nathan7I haven't found a word or a good way to describe this concept
23:45nathan7lisps are helping me a lot in this, because in a hundred lines of code I can build another lisp
23:45nathan7and in like, maybe two hundred lines I can do it in any nice language
23:46nathan7so I can build entire languages around single concepts very quickly
23:46nathan7and each time I understand more, and my understanding becomes more abstract
23:47dbaschreminds me of this: http://www.buildyourownlisp.com/
23:47nathan7yeah, I saw that
23:47nathan7I still want to build one in Rust so I can do stuff like the refcounting lang
23:48nathan7but I have several implementations of my f-expr lisp which are all cool in their own way
23:48nathan7the one issue I have with writing lisps in lisps is that the lines are blurred easily
23:48nathan7I have an implementation of my fexpr lisp, Plan, in Clojure
23:49nathan7and I'm very confused about how it actually works now because I have a hard time telling what is my stuff, and how it works with Clojure stuff
23:50nathan7because I'm doing a lot of voodoo that unites the worlds of Clojure and Plan
23:50nathan7and I don't actually have debugging tools at all
23:50nathan7so I have a null pointer exception somewhere that I can't really debug
23:51nathan7and my mental model of it all is very murky
23:56nathan7dbasch: maybe I should actually follow the buildyourownlisp sometime, but in Rust
23:56dbaschI guess it shouldn't be that hard to do it in Go either
23:57nathan7Yeah, I have a very strong dislike of Go
23:58nathan7bnoordhuis (possibly drunkenly) perfectly described it as the language that "missed the last 20 years of computer science"
23:58dbaschto me it's just another language, neither here nor there
23:58nathan7it's neither here nor there indeed
23:58serjeemit makes me sad that in TYOOL 2014 they're still putting out non-polymorphic typed languages
23:59nathan7elaborate
23:59nathan7oh, nvm, makes sense now