#clojure logs

2015-09-15

02:10neoncontrails,(doc list*)
02:10clojurebot"([args] [a args] [a b args] [a b c args] [a b c d & ...]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."
02:10neoncontrailsWhen is this preferable to list?
02:15jeayeneoncontrails: When you're consing multiple items onto a list.
02:15jeaye,(list 1 2 (list 3 4))
02:15clojurebot(1 2 (3 4))
02:15jeaye,(list* 1 2 (list 3 4))
02:15clojurebot(1 2 3 4)
02:21neoncontrailsjeaye: That makes sense. Thanks!
02:23jeayeSure.
03:26instilledthe documentation of defrecord states that metadata is supported. Unfortunately I fail to access the metadata on a defrecord. How is this done?
03:53mavbozoinstilled, (-> (Point. 3 4) (with-meta {:foo :bar}) meta)
03:53mavbozoinstilled, ;= {:foo :bar}
05:05iwohey, this is a really stupid question but... is there any better way to write: (do (side-effect-fn) nil)
05:06iwokind of like dorun (returns nil) but not for seqs
05:07mavbozoiwo, rather than (do (println "foo") nil), you can just write (println "foo")
05:08mavbozoprintln is side-effecting function
05:08iwoI have a function that does something like: (if (...) (something) (do (increment-failure-metric) nil))
05:09iwomavbozo: in this case, increment-failure-metric returns something :(
05:09mavbozoiwo, and you don't want the return value from increment-failure-metric?
05:09iwoso I end up having to explicitly add nil as the return value. I know it's probably stupid to try to find a function to do that, it just feels like there should be one :)
05:10lumawhy do you need to specifically return nil?
05:10iwoone option I was trying to find: a function that takes any arguments and always returns nil
05:11iwoluma: because the return value of my fn is obviously something completely different, and has nothing to do with metrics
05:11taliosmmm mutation - something smells there
05:11iwoI guess the answer here is that I should move the metrics out of this function
05:11iwobasically I want: do-nil :)
05:15TMAnow you have it: (defn do-nil [& _] nil)
05:15talios:)
05:15luma(def do-nil (constantly nil))
05:16TMA,((constantly nil) 1 2 3)
05:16clojurebotnil
05:16taliosTMA - mmm, doesn't iwo want it to RUN what he passes in, THEN return nil. that just returns will only
05:17mavbozo,((constantly nil) (do (println "foo") :done))
05:17clojurebotfoo\n
05:17mavbozo#((constantly nil) (do (println "foo") :done))
05:17TMA,((constantly nil) (println "foo"))
05:17clojurebotfoo\n
05:17noncomyou should not be concerned with the return value if you disregard it in any case
05:18TMA,((fn [& _] nil) (println "foo"))
05:18clojurebotfoo\n
05:18taliosI guess the bigger question is what does (something) return
05:18noncomfor example, (swap!) is a very common operation and it always returns a value (most often not nil). it is used in so many places that treating it as a special case is unfeasible
05:18TMAtalios: clojure does not seem to be lazy
05:19taliosTMA - whats laziness got to do with it?
05:20TMAtalios: arguments are evaluated even if they are unused; therefore any side effects are performed
05:20TEttingerTMA: ,((fn [& _] nil) (println "foo")) is calling that fn with nil
05:20TEttingerprintln returns nil
05:22taliosTMA - him, I thought (if) was a special form, assumed it handled that case. easy enough to macro up a lazy (if~ ) or something tho
05:22mungojellyyeah clojure has laziness as a prominent strategy but not a basis is my impression
05:23taliosit's probably one of the main things I dislike about clojure ( over tooling, and lack of types ) is the inconsistency in strictness
05:24TMATEttinger: the whole invocation returns nil (regardless of the return value of any provided parameter forms); it first evaluates the arguments to (fn [& _] nil); during the evaluation any side effects are performed (in other words the argument forms are RUN); the values are then passed onto (fn [& _] nil) which ignores them and returns nil
05:26mungojellythe feeling seems to be, here we are on the jvm, we're going to play with all these messy toys here, so we're also going to have a functional laziness and keep it in a box and negotiate in various ways between that and the mess
05:26mjgmessy toys?
05:27mungojellythings that are practically useful but hugely effectual or stateful or otherwise not ideal
05:27TEttingerTMA: I'm curious what the alternative here is. would you want to do a compile-time analysis of the whole program path to see where values produced by side-effecting functions are used, and not run the side effects if the values aren't used?
05:28TMAHowever, if clojure were lazy (in the Haskell style), the arguments would not be evaluated, because they were not used (you'd need to resort to some monad trickery to force them to be evaluated; but then Haskell is pure, there are no monadfree sideeffects)
05:29mungojellyyeah that sounds like real laziness, if it's never used it just doesn't happen in the first place, the eventual use is always what triggers everything behind it
05:30iwoI think what I'm after is: (defmacro do-nil [& body] `(do ~@body nil)) :)
05:30TEttingeralso I suspect it would make the already slow clojure AOT compile process even slower
05:31TEttingeriwo, yep
05:31taliosTEttinger - frege seems quite snappy to compile :)
05:31taliosI've not done anything large in it yet tho
05:31TEttingerdon't know it
05:31TEttingerlazybot takes about 2 minutes to uberjar the relatively large program
05:31talioshaskell for the jvm :)
05:32TEttingerthat sounds kinda awful... isn't one of the biggest advantages of haskell the guarantees they have by their own type system and ecosystem in general?
05:33taliosand that type system carries across. the FFI to java is rather controlled, and lifts nulls into Maybe's, and wrapps impure things into ST
05:34taliosTEttinger - https://www.youtube.com/watch?v=9V7w-RSC_1A - from this weekends FregeDay mini conf
05:34mjgCould one, as an experiment, write a macro which wrapped every form in (delay...) to simulate haskellesque laziness?
05:37TEttingermjg: it would also need to deref the values before they're used, but it seems possible
05:42mjgThat's a pretty steep overhead, right? But if it were implemented as a new reference type which was automatically forced on-demand, then it seems pretty similar to what haskell is doing.
05:42mjgjust as an alternative to compile-time analysis, not suggesting you actually do this.
06:01cydorktalios: frege is coming along nicely..
06:03talioscydork - yep, seems to getting more and more interest. esp. now theres the maven plugin, the lein plugin, the gradle plugin, and some experimental stuff I'm toying with with hazel. Now we just need libraries to build an ecosystem
06:04cydorktalios: yep. just saw some article about the benchmarks.. which were on par with ghc
06:05talioscydork - oh? got a link, I wonder if that in relation to the performance talk given at FregeDay
06:06talios( also next to that video I posted above )
06:06cydorktalios: https://gist.github.com/vsts/57565f5b7d11df39541c
06:06talioscould be interesting running some things thru JMH
06:06cydorktalios: https://www.reddit.com/r/haskell/comments/3igird/frege_faster_than_haskell_ghc/
06:06taliosah yes that post.
06:31seyeHi. Am I correcting in thinking that it isn't possible to deref or ensure multiple refs at the exact same 'snapshot time'?
06:32tomshachamplease could i have a nice example of a macro? something beyond "infix" that just allows (1 + 1)
06:33sobelseye: sounds like you might want to use a transaction
06:35seyethis is within a transaction
06:36gilliardtomshacham: there's a lot of macros in clojure itself - look in core.clj
06:37sobelseye: you should be good. refs are connsistent inside transactions.
06:37sobelseye: are you familiar with the MVCC model?
06:37seyeyes
06:38sobelthat is the STM model for transactions
06:38seyei know :)
06:38seyehowever
06:39seyeif i deref two refs within a transaction, it is possible for another transaction to commit between the two derefs, so the second ref may have a value different to the one that it had when i derefed the first one.
06:40tomshachamgilliard: thanks
06:40sobelyour transaction shouldn't see that
06:42sobelare you concerned that the ref could be altered before your transaction ensures it?
06:50seyeYou are correct sobel, i'm relieved to say! I ran a test that made it look like it was failing, but it was actually retrying the transaction to keep if consistent and the output confused my slow brain!
06:51sobelwhew!
06:54seyehttp://pastebin.com/6s5TuPNN
07:05aneI edited the Clojure wikipedia page a bit, can anyone check if the edits make sense? https://en.wikipedia.org/w/index.php?title=Clojure&type=revision&diff=681133095&oldid=680279119
08:43chouserane: It's great to have all those citations. The word "force" might be a bit too strong since uncoordinated mutation is still available.
08:43chouserane: perhaps "encourage" instead of "enforcing" and "forces"?
08:47aneyes!
08:48anei need to find citations for the second paragraph of the history section, but can't
08:48anei know he mentioned it in some video but i don't remember which one it was
09:03dumbintelCan someone explain atom's to me? Living Clojure's explanation is a bit abstract. Are they like pointers and refs like references?
09:04chouseratoms and refs and agents are all like pointers, but with semantics to control how they're updated
09:04snowellI found this answer to be helpful: http://stackoverflow.com/questions/9132346/clojure-differences-between-ref-var-agent-atom-with-examples
09:04chouserThe semantics differ, which is why there are three different types.
09:05chousersnowell: Nice.
09:05chouserI would also recomment "The Joy of Clojure" ;-)
09:05dumbintelI think I get wrapped around state as a new idea. I'll start with that article.
09:07mavbozochouser, will the 3rd edition contains core.async and transducers? :)
09:09chousermavbozo: I suppose it should, shouldn't it.
09:09noncomdumbintel: atoms just store mutable state that is guaranteed to cause no concurrency issues on change, no order is guaranteed, they block thread until state change is successful. refs contain state and allow to change several refs in a particular order, providing all safety of atoms, they block too. agents are same as atoms but do not block, use for spin-off or long-term calculations
09:10noncomvars are used for programmatic entities, like functions, variables, not for data
09:11noncomdumbintel: i think it is safe to say that in over 90% of cases it is almost certain all your data can be handled with atoms.
09:14noncommavbozo: heh, transducers.. let alone transducers, i'm still waiting for an example of a real world complexity UI built with core async.
09:16dumbintelAlso, would you guys recommend a web front end or a swing front end for a game with chess-like elements meant to study A.I.
09:18dumbintelThe interface would be static for the most part where dynamic elements are pieces, but even those are just simple images coming in and out of view.
09:40noncomwheres lazybot?
09:49tmarbleI'm getting compilation errors (ClassAdapter.java) when building clojure from master... anyone seen this?
10:17justin_smithnoncom: atoms do not block, they retry
10:17justin_smithnoncom: they are a non-locking optimistic concurrency mechanism
10:17justin_smithnoncom: refs also retry
10:17justin_smithnoncom: agents lock rather than retry
10:18noncomjustin_smith: hmmmmm, well, in my practice, if i swap an atom, the thread stops until the swapping is successful
10:18justin_smithnoncom: this is important, because side effects inside swap!, or a mutable object inside an atom, can cause serious bugs because of retries
10:18toluhi
10:18justin_smithnoncom: that's because it blocks your thread until a retry succeeds
10:18justin_smithnoncom: that is not the same as locking the atom
10:19justin_smithnoncom: it blocks the caller, it does not lock the data
10:19noncomhmmmm... this is interesting, apparently there are subtleties for the terms
10:19noncomah yes, blocks the caller, sure, but data is available. well, it blocks the calling thread.. that's what i meant..
10:19noncomtolu: hi
10:19noncomtmarble: maybe you're using an unstable branch?
10:20noncomtmarble: ah, master, quite probable
10:20toluplease I would like to add a value into a particular column of a vector without replacing the previous value. I did this (assoc [1 2 3 4] 1 8) ;;=> [1 8 3 4] but I want [1 8 2 3 4]
10:20justin_smithnoncom: right, the important thing is to remember that it doesn't lock the data, it will retry, and that is why side effects inside a swap! call, or mutable objects inside an atom, will cause bugs
10:20tmarblenoncom: I've even tried JDK 6 and the args used in the latest Hudson build http://build.clojure.org/job/clojure/lastBuild/console
10:21tmarblethe only difference is that I'm using maven 3 (could be a showstopper?)
10:21toluI did this (assoc [1 2 3 4] 1 8 ) ;;=> [1 8 3 4] but I want [1 8 2 3 4]
10:21justin_smithtolu: vectors don't support that directly, you'll likely need to coerce to a sequence, do sequence ops, then create a vector again
10:21justin_smithor you can use something like a finger-tree that can do that directly
10:21noncomyeah, this i know. probably had to mention also, but the reply was getting big already. however, what i said, does not contradict what you're saying. what you're saying is an expansion of my saying, so i think, that will not break the space-time continuum this time :D and when he learns more, he'll also accomodate the wisdom you're mentioning! :)
10:22noncomtolu: simplest solution in one line would be something like (concat (take N col) [8] (drop N+1 col))
10:22noncomtolu: or fingertrees, yeah, they're cool
10:23tolunoncom: and justin_smith: thanks
10:23justin_smith,(let [v [1 2 3 4]] (apply conj (subvec v 0 1) 8 (subvec v 1))) ; another way
10:23noncomah, it should be (drop N col) i guess
10:23clojurebot[1 8 2 3 4]
10:23noncomsubvec is faster on vectors, right?
10:23justin_smithI forgot about subvec!
10:23justin_smithyeah
10:23justin_smith*almost forgot
10:24tolucool
10:24mungojellywhatever topic you ask about on freenode you get an answer that's too specific and too detailed and too picky and too particular, it's a great place to learn things :)
10:24justin_smithheh
10:25justin_smithmungojelly: it's because someone can come back and say "you said atoms locked and thanks to retries I bought 100 porsche's from amazon.com when I was only supposed to buy 1"
10:26justin_smithmungojelly: you have to answer with not only the current situation in mind, but others your answer will likely be extended to
10:26noncomtmarble: well, sometimes master branch of a repo can contain something that does not compile... although i did not look into clojure repo and can't say more
10:26mungojellythose are the beneficent reasons, and then there's that it gets boring explaining the same thing over and over so you look for more interesting perspectives on them :D
10:27noncomyeah :D
10:27noncomsounds like we can make a library for that
10:28mungojellyisn't there a doubly linked list around here you should ask for if you want cheap inserts. i don't know how to ask for it i just remember rich hickey or someone saying doubly-linked lists are something we get.
10:29justin_smith,(defn vinsert [e index v] (apply conj (subvec v 0 index) e (subvec v index)))
10:29clojurebot#'sandbox/vinsert
10:29justin_smith,(vinsert 8 1 [1 2 3 4])
10:29clojurebot[1 8 2 3 4]
10:29justin_smithsweet!
10:30justin_smithmungojelly: sounds like finger trees
10:30mungojellyok fine i will google finger trees
10:30justin_smiththat vinsert works, but is O(n) with the size of (count v) - index
10:31justin_smithwhere fingertrees are log or something
10:34noncomjustin_smith: please remind me, you were saying it is possible to lay effects on sampled instruments in overtone... is that by re-routing the synth output through a fx and into the output
10:34noncom?
10:34justin_smithyes
10:34mungojellyok i think i sorta understand what a finger tree is now, but i'm not entirely grokking how that lets you make a persistent double-list
10:35mungojellythis overtone thing sounds fun maybe i should move that up my list of things to look at
10:35noncomcool, sounds as straight as any DAW, not sure why I was thinking too much about it
10:36noncommungojelly: sure, it's pretty awesome actually
10:36sobelovertone is somewhat powerful but there are some areas you're totally on your own
10:37justin_smithnoncom: in my experience it takes a while for all the routing and stuff to be intuitive, especially when you don't have a pretty antialiased rendered picture of the "wires" and "processing units" as if they were physical objects in a studio
10:37justin_smithnoncom: and then there's a log of people who still have problems even with the logic of routing the physical objects...
10:37justin_smithbut it's basically just plumbing
10:37justin_smiths/log/lot
10:38justin_smithnoncom: true story - functional program first appealed to me because it follows the same cause and effect rules that audio processing gear does
10:39justin_smithnoncom: that is, good code is only effected by its input, and you should be able to reason about what any subgraph does independently of the chain
10:39noncomyes, this is so true. actually, sound making in this way is functional programming in disguise!
10:40mungojellyi think we talk a lot about these things as pure ideal concepts but really they're more aesthetic
10:40justin_smithexcept for reverb - you have to cheat a little bit for things like reverb :P
10:41mungojellylike around here there's lots of talk about being functional, oh we should be functional, what do the functions do, they advance the state of The Thing, oh what's in the thing, a bunch of states sending messages to one another, objects. but at least you can rewind them when they fall over the same as usual. ;)
10:41justin_smithmungojelly: it's not just aesthetic - it's a set of rules for abstractions that compose well for the pragmatic reason that you want your code to be easy to think about
10:41noncomwell, delay then too needs some cheating, but i think this can well be tied with functional programming
10:41justin_smithand it turns out that there is an aesthetics to things that follow that logic, sure
10:42justin_smithnoncom: yeah, I mean really even filters have a phase (time) shift, but yeah, big picture it's functional or something very close to it
10:42mungojellybut what i mean is that things can so easily be put inside of one another in these systems, that you can only know the style of something by looking at the style of all of its details
10:43noncomyeah
10:43justin_smithmungojelly: ideally you shouldn't put state inside something funcitonal - it's OO where you hide the details on the inside
10:43xtrntrhi, trying to copy this code and make it work
10:43xtrntrhttp://programming-enchiladas.destructuring-bind.org/rm-hull/6857333
10:43justin_smithhaha, funcitonal
10:44xtrntri'm not sure how does the web server render the canvas
10:44xtrntrdocument-ready?
10:44justin_smithxtrntr: the server does not render anything
10:44justin_smiththe browser renders the canvas
10:44mungojellythere's that old saying about how every system that's not lisp ends up having a poorly implemented poorly documented lisp in it, but also i think it goes the other way around, the pure functional programs all write imperativeness into themselves somewhere in order to do that.
10:44xtrntrjustin_smith: ah
10:44justin_smithmungojelly: as long as it's real imperative and not OO, you're fine
10:45xtrntrxtrntr: sorry, i'm not very familiar with web programming, which function is the link between clojurescript and the browser?
10:45noncomxtrntr: clojurescript is translated into javascript and executed as a plain web page script
10:45justin_smithmungojelly: and it's more nuanced than that. Ideally functional code should not contain state, and stateful objects should be at the top level, connected to each other by functional plumbing
10:46xtrntrit must be document-ready right? i found it in the jquery docs
10:46justin_smithmungojelly: of course in order to compute anything at all, state is going on in registers and such, but the idea is that you can have an effectively stateless interface despite that
10:46noncomi find that in the real world, when you go through the levels of the system, it oscillates between OO and FP, morphing
10:46xtrntrnow i have to link the js or cljs file in my index.html file?
10:46noncomxtrntr: iirc document-ready means that all page data was received by your broewser and it is ready to be rendered
10:47justin_smithxtrntr: the generated js should be linked, yes
10:47justin_smithxtrntr: the cljs compiler will arrange for your -main to be called when the page loads iirc
10:47justin_smithxtrntr: you might be able to get more detailed answers from #clojurescript
10:48noncomxtrntr: still, why did not you try luminus? :) it would already be clear to you if you've simply examined the code generated by the template
10:48xtrntrah, sorry to bother you guys
10:48xtrntri actually copied the code into luminus, but as a newbie everything seems very strange and unfamiliar
10:48noncoma game drawn on a canvas is little more than a simple page script
10:48xtrntri'm ok with lisp syntax, but never did web programming
10:48xtrntrinto a limunus created project*
10:48noncomweb creeps me out a little too :)
10:49noncomso, then you could simply copy the scripts into the project and let them draw on a canvas that you create
10:50xtrntrah
10:50xtrntri'm not very sure what that means
10:50xtrntrso the scripts are located in my src directory, but how do they get loaded into the browser?
10:50justin_smithoh man I have so many layers right now - cljs in the browser, interacting with 3.js in the same browser (and sometimes those interactions are a bit odd) then clojure on the server, talking via kafka to another set of clojure servers running onyx to balance tasks, then other clojure servers doing REST style http queries...
10:50xtrntri'm trying to understand how the pieces fit together
10:51justin_smithxtrntr: the clojurescript compiler takes your clojure code and turns it into js file(s)
10:51noncomjustin_smith: wow
10:51justin_smithxtrntr: then that js file is loaded into an html page which is served to the client, and the client runs the js
10:51noncomxtrntr: also, if you're following luminus template, your source should be under src-cljs
10:51justin_smithnoncom: yeah, it's kind of wacky
10:52noncomjustin_smith: i wish i had a job like that...
10:52justin_smithnoncom it's fun until the deadlines loom...
10:52noncomoh deadlines...
10:53justin_smithand also, when things break in a system that distributed, figuring out how it broke is like a game of clue
10:53justin_smith"It was a reagent component, in the browser, with the websocket!"
10:53justin_smith"no, it was the onyx task, in the amazon cloud, with the core.async channel!"
10:54noncomactually, that's pretty fascinating
10:54noncomthen you start thinking if some greater structure can be imposed on things...
10:54justin_smithnoncom: bugs that I would sort out in a minute or two locally can turn into a thirty minute sleuth job of resuscitating and replaying events from the kafka log...
10:55noncomsure, they get lost in the sea of changes
10:55justin_smithand of course I as the backend / infrastructure guy am trying to prove the frontend cljs code is broken, and the frontend folks are trying to prove my infrastructure fucked up...
10:55xtrntrjustin_smith: should i include the document-ready in the same script where the -main function is called?
10:56justin_smithnoncom: well, the cool thing is that with kafka all messages are stored for a while (and are fully readable as edn data in our usage) so we really can replay and recreate bugs
10:56justin_smithxtrntr: why do you need document-ready?
10:56noncominteresting
10:56xtrntrto draw the maze and stuff
10:56justin_smithnoncom: kafka is like a hybrid of a logging system and a message queue
10:56noncomxtrntr: yeah, document-ready is used if you're programming very bare javascript...
10:57noncomxtrntr: if you look at core.cljs, provided to you by luminus, you will see, that it is far simpler
10:57tmarblenoncom: had crufty *.java files in the tree! Now builds with JDK 6 + mvn2 and JDK 8 + mvn3
10:58justin_smithwell, that maze example is using document-ready so maybe it has something to do with that design...
10:58dm3is there a way to edit and eval source of project's dependencies in Emacs with CIDER? I found how to navigate to a read-only buffer with cider-find-ns...
10:58xtrntrdo you mean core.clj?
10:58xtrntrsorry, i'm trying to learn by copying and pasting
10:59xtrntri'll work backwards from a working example
10:59noncomxtrntr: if you're so unfamiliar with web, why don't start small? there's really tonns of web-specific stull to know when coming from non-web world...
10:59justin_smithxtrntr: for starters, make sure you have a project that is set up to run the clojurescript compiler
10:59xtrntri thought copying and pasting is the lowest rung there is?
10:59justin_smithxtrntr: as dnolen mentioned in #clojurescript, you should probably start with some of the basic clojurescript docs
11:00noncomxtrntr: maybe you should try first creating a simple web page and get it rendered, then add some cljs to breathe some life into it. there are innumerable example out there, under 100 loc
11:00justin_smithxtrntr: copying and pasting won't help if you aren't even running the right compiler
11:01xtrntryou mean the options in my project.clj when you say compiler?
11:01xtrntralright i'll read some stuff before i get back here
11:01dnolenxtrntr: working backwards is a huge waste of time IMO. Just read the Quick Start and get the fundamentals down first.
11:01justin_smith(inc dnolen)
11:09xtrntri get this error when i try to compile
11:09xtrntrCaused by: java.io.FileNotFoundException: Could not locate monet/canvas__init.class or monet/canvas.clj on classpath.
11:09xtrntrbut i've included the monet dependency in project.clj
11:10xtrntrand the example on the github page uses it no problem
11:10xtrntrhttps://github.com/rm-hull/monet
11:20oddcullyxtrntr: monet is cljs - the error looks like one from clj?
11:21xtrntrahhh
11:21xtrntrsorry that was it
11:21xtrntri was using cljs code in a clj file ...
11:21xtrntr._.
11:21xtrntri hope i'm not the first one to make such a mistake
11:22justin_smithxtrntr: I think if you slow down and look at some of the basic cljs docs this stuff will be much easier
11:22xtrntrokay :)
11:31mungojellyyes everything stateful is all bunched up nicely on to a top coordination layer and everything's beautiful-- which is just what makes that stateful layer so effective as a library for the next thing to build on and we're off to the races again :/
11:57joefromctif i def a variable in a repl session in a function, can i delete it and try again?
11:57justin_smithjoefromct: you can just use def again
11:57joefromctbasically i have a function that tests if a varibale is nil, and if not it def's it
11:57joefromcti'm sure there is a more functional way to do this
11:57sobeldefonce
11:58sobelslightly different but may be what you intend
11:58lodin_joefromct: Why do you want to do that?
11:58joefromctsobel: ah, thanks. I'll look into it.
11:58joefromctwell, i can't define a spark context into sc twice
11:58justin_smithyeah, use defonce for that
11:58joefromcta spark context is i guess the session on a cluster, and i'm testing my program "bootstrapping" i guess
11:59joefromctok thank you
11:59justin_smithjoefromct: well, either defonce, or don't put it in a def at all, and use a proper system building lib like stuartsierra/component
12:00joefromctjustin_smith: yeah, baby steps, but i'll put that on the research/to-do list.
12:00joefromctnot sure i totally understand what a system building lib is at the moment.
12:00sobelit's so easy to try out libs with clojure. i don't even hesitate if i get a good recommendation here.
12:01justin_smithjoefromct: the idea is that if you have stateful resources, instead of defining them at compilation time as defs, you can initialize them in a system startup procedure, then pass them to the code that needs to use them via the same startup
12:01joefromctjustin_smith: simple enough, and makes perfect sense. thanks i'll look into it.
12:01joefromctjustin_smith: sounds like something a scheme person would love.
12:02joefromctor i guess any lisper
12:02justin_smithjoefromct: among other advantages, you would avoid the problem where if you try to make an uberjar, your top level spark connection will run while compiling the code (which might not be something you want)
12:02justin_smithjoefromct: pretty much :)
12:03joefromctso, i just yanked the text from this irc chat into org-capture and put component as an org-task based on justin_smith's recommendation.
12:04joefromctemacs is amazing. i don't need a computer anymore just an emacs machine.
12:04joefromctand cider.
12:04justin_smithheh
12:24mungojellyi just learned defonce yesterday, i'd seen it a few times in the days before that, and i misread it as de-fonce, i was wondering what foncing was and how it removed it, i noticed it was coded defensively so i thought maybe it was a pun on defence
12:25anelol
12:27joefromctdoes anyone have any experience with flambo vs sparkling? What the trade offs are between them?
12:29sdegutisIs it common to get the initialized fields of a defrecord all map-like using their keyworded names?
12:30sdegutisLike, (:bar (Foo. "this is the bar field"))
12:39mavbozosdegutis, it's common in my usage
12:39sdegutisThanks. Anyone else can add to this?
12:45eLobatohi there channel. I was wondering if there are any best practices on how to use clojure.test to test read/write to a file? I'm trying to find some expectations/mock framework but I didn't find anything conclusive, help?
12:54lodin_sdegutis: Yes, it is common. But if you use a record you probably have a reason, and you might consider providing a functional API for it via protocols, including stuff that happens to be stored directly in the record. That makes you free to adjust the implementation accordingly, and extend other data that is equivalent in content but not in structure to the protocol.
12:55sdegutislodin_: in this case I'm using defrecord to switch between a live implementation and an in-memory implementation for when running tests
12:56sdegutislodin_: they both conform to an abstract defprotocol which my code uses as if it were the thing itself
12:57lodin_sdegutis: Then for "private" code that knows it is working on a particular record, then I think it's perfectly fine.
12:57sdegutisOkay that makes sense.
12:57sdegutisSince not every record will have that same key.
12:58lodin_Right.
12:58sdegutisIf I want to make it public, I should make a getter for it.. like (uri [this] uri)
12:58sdegutisAs ugly as it is, that's the right way.
12:58lodin_sdegutis: I believe so. Others might disagree.
12:59lodin_sdegutis: In practice I often only access record fields in protocols implementations, and then I don't need to use keyword access. To update the record I of course use keywords with assoc etc.
13:00lodin_Inside the protocol implementations, that is.
13:00sdegutisThanks.
13:01lodin_sdegutis: It great that Clojure lets you start with a map and then transition to a record. That way you don't have to model everything up front, as long as you realize that your old code only works with your "first" record that you then created a protocol for.
13:05sdegutis:)
13:10mavbozospeaking of defrecord, I just read defrecord docstring again and stumbled on few paragraphs. But currently I am interested in this paragraph: "Two constructors will be defined, one taking the designated fields followed by a metadata map (nil for none) and an extension field map (nil for none), and one taking only the fields (using nil for meta and extension fields). Note that the field names __meta and __extmap are currently reserved and should not be us
13:10mavbozoed when defining your own records."
13:11mavbozowhat is the example of 1 constructor that is "taking the designated fields followed by a metadata map" ?
13:14justin_smithmavbozo: (->Foo 1 2)
13:14mavbozowhat confuses me again is the next paragraph that describe the factory functions ->TypeName and map->TypeName
13:14justin_smithmavbozo: that's what that is describing
13:15justin_smith->TypeName is the one that takes the designated fields
13:15mavbozojustin_smith, so the "constructor" and "factory function" terms refer to the same thing?
13:16justin_smithafaik yes
13:16justin_smithwell, the constructor is the one that refers to it as a class directly, I thought
13:17lodin_justin_smith: What about the metadata map?
13:17justin_smith(TypeName. x y)
13:17justin_smithlodin_: not sure about that part, is it an optional arg?
13:18mavbozo trying (Foo. 1 2 ^{:name :foo}) in the repl throws Unmatched delimiter RuntimeException
13:19justin_smithwhat about without ^
13:19mavbozono matching ctor found for class user.Foo
13:19mavbozoIllegalArgumentException
13:22rhg135,(do (defrecord Foo []) (Foo. {} nil))
13:22clojurebot#sandbox.Foo{}
13:23rhg135,(do (defrecord Foo []) (meta (Foo. {:i-has-meta true} nil)))
13:23clojurebot{:i-has-meta true}
13:26rhg135also takes an extmap, which can be nil
13:27lodin_What's in the extmap?
13:28Bronsathe extra fields you assoc to a record that weren't declared
13:28Bronsa,(defrecord x [a])
13:28clojurebotsandbox.x
13:28Bronsa,(.__extmap (map->x {:a 1 :b 2 :c 3}))
13:28clojurebot{:b 2, :c 3}
13:29rhg135yup, they are usually hidden
13:30lodin_Ah. So map->x looks up what's a field and what's not and effectively splits the map?
13:31rhg135theoretically
13:31rhg135idk the implementation
13:32Bronsayes
13:32Bronsait actually dissocs the known fields from the map
13:33mavbozoah, so i misunderstood the paragraph. my first try should be (Foo. 1 2 {:name :foo} nil) ;; remove the caret ^ and add nil
13:34rhg135yup
13:34mavbozorhg135, Bronsa thank you
13:34Bronsayeah you basically get Record(declared-args*) and Record(declared-args*, meta, extmap)
13:36phaseNiHello, how do I access member classes from a java class?
13:36rhg135Parent$Child
13:37phaseNiI must be doing something super wrong, because that isn't working
13:37phaseNi(new Parent$Child) should work, correct?
13:37lodin_I guess this is here just for the implementation, and that assoc etc make use of it? In user code you can just do (-> (->Foo ...) (with-meta metamap) (into extmap)), right?
13:38Bronsalodin_: yes
13:38BronsaphaseNi: is Parent a fully qualified classname?
13:39rhg135java.util.Map$Entry
13:39rhg135,java.util.Map$Entry
13:39clojurebotjava.util.Map$Entry
13:39phaseNiBronsa: BAM! Thanks :)
13:40BronsaphaseNi: importing foo.Bar doesn't import foo.Bar$Baz
13:40Bronsaif you want to write Bar$Baz instead of foo.Bar$Baz you'll have to import it
13:41rhg135they're essentally different classes alltogether
13:42phaseNiYeah I figured
13:42rhg135for naming
13:42phaseNiIt was $ that I was really missing all this time
13:43phaseNithank you rhg135 and Bronsa
13:43rhg135is there better docs for this now
13:44rhg135I recall tripping on this
13:44phaseNiActually I found nothing of help
13:45rhg135what a bummer
13:45phaseNiThe interop doc doesn't even mention import
13:45rhg135I know
13:46rhg135I gess you could read the code
13:46phaseNi:P
13:46phaseNinow to figure out proxy...
13:47rhg135it's not bad
13:47BronsaphaseNi: if you don't need to extend a concrete class you'd rather be using reify than proxy
13:47rhg135^!!!
13:48phaseNiohhh
13:48clojurebotTitim gan éirí ort.
13:48phaseNinifty
13:48phaseNithanks
13:48mavbozorhg135, clojure-doc.org mentioned it http://clojure-doc.org/articles/language/interop.html#imports
13:48Bronsait has better syntax and better performances
13:49mavbozokudos to clojure-doc.org contributors
13:49phaseNiYeah, I was reading http://clojure.org/java_interop
13:49phaseNiit is indeed in the other doc
13:49rhg135,(reify Object (toString [_] "a"))
13:49clojurebot#object[sandbox$eval25$reify__26 0x116ce57d "a"]
13:51rhg135won't anyone think of the performance
13:53rhg135I've seen proxy too often in the wild
13:53Bronsareally?
13:54rhg135ppl new to clojure
13:56mungojelly*earmuffs* means you might change the value of something?
13:56rhg135yes, usually dynamic
14:01justin_smithmungojelly: specifically that a var can be dynamic in scope
14:03rhg135it's just a convention though, right
14:03mungojellyyes what i'm reading is a style guide, it wouldn't have to tell you you had to if you had to
14:04mungojellyshould i really say io! around i/o
14:04justin_smithmungojelly: if it would be erroneous to send the same io repeatedly
14:04justin_smithor to read more than once for one input
14:04mungojellythat makes sense and yet i don't think i've read "io!" in any code yet? maybe i wasn't looking for it yet
14:05rhg135but if you don't ppl will be very dissapointed in you to say the least
14:06rhg135not use *stuff*
14:07mungojellyi'm glad clojure uses earmuffs for something they're pretty
14:09rhg135clojure is aesthetically pleasing
14:10fantazoclojure is a lisp. so it must be aesthetically not pleasing. this is the unwritten rule of bullshittery, it must be true!
14:10justin_smithfantazo: also, parenthesis cause cancer
14:11fantazojustin_smith, and small penises too.
14:11rhg135along with c++ is da best
14:12mungojellyclojure takes away all those ugly parentheses and instead you get some pretty -> and ->> and way too much knowledge of which things take arguments in which places
14:13mungojellyi've heard a lot of "but sequence arguments should go at the end! then it's great!" which is clearly just blaming the victim :p
14:13rhg135wrap it all in maps!
14:13justin_smithmungojelly: the arg placement order is predictable for sequential and associative args (sadly it is not consistent with string/regex)
14:15rhg135knowing the api is nice
14:16rhg135makes you more productive in any language
14:20noogaah, that's why I wanted flip-args function
14:20mungojellyok so i was trying to decide between {:grid {[0 0] :a} :tiles {:a {:quality "value"}}} or just {[0 0] {:name :a :quality "value"}} that is whether to put a level of indirection, i guess i'm leaning towards the latter, maybe "make this tile a copy of this other one" would be a better efficiency hack anyway if it needs that
14:21mungojellyi think -<><:p seems useful! it seems to be like a joke, but i think that's because you don't realize all the stuff you're used to is just as weird :p
14:25rhg135premature optimization
14:36mungojellywell i also thought it might be a premature optimization to bother to reduce the datatype to a finished model like that, maybe it should just be a sinkhole of tile insertions
14:37mungojellythen i wouldn't have to check anything when you insert tiles or add grids or anything, just i'd have to sort through the updates for the latest news
14:41rhg135indirection usually adds power, but lowers performance
14:41mungojellyis there a better way to say (filter #(= (first %) [0 0]) coll)?
14:54mungojellyso which data structure do i want if i just want to toss a bunch of things shaped like {:xy-grid-pos [0 0] :tile-name "happy tile" :hex-color-string "#00FF00" :time-inserted 987298472938749} into it and then later i want to ask for all the ones where :xy-grid-pos is [0 0]
14:56rhg135I'd use a pair of a stack and a lookup table
14:57rhg135But I'm not that experienced
14:57mungojellyis a stack something we get here that works differently than a vector?
14:58rhg135you can use a vector
14:58rhg135,(pop [1])
14:58clojurebot[]
15:00rhg135,( [] (conj 1) (pop) (conj 2 3) (peek))
15:00clojurebot#error {\n :cause "Wrong number of args (0) passed to: core/pop"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (0) passed to: core/pop"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.AFn invoke "AFn.java" 28]\n [sandbox$eval49 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval49 invo...
15:00rhg135,(-> [] (conj 1) (pop) (conj 2 3) (peek))
15:00clojurebot3
15:00mungojellyok yay now i know (peek)
15:01mungojellyhow many words do you think you need to learn to speak clojure
15:01rhg135alor works with lists
15:01mungojellyi'm guessing a few thousand
15:01rhg135~100ish maybe
15:01clojurebotHuh?
15:02rhg135imo
15:02mungojellythere's something reasonable like that in the core, but then you have to know some libraries to understand the idiom around here, you need to know java even to understand lots of things
15:03mungojellybut we live in a world where java is mandatory, so i do know enough of that bull to get by
15:06rhg135do you mean words as in english?
15:06mungojellyi just mean as in like the human capacity for language
15:06rhg135ah
15:06rhg135a lot
15:07mungojellysometimes if there's multiple arities of something it only counts as one word because you can understand the pattern and it's not an extra burden, but sometimes it's two ideas and you learn them separately
15:08rhg135ideas, more than you should
15:15sobeli would not be too hasty in comparing programming languages to spoken languages
15:16mungojellywell i have a unique perspective on it as one of the only fluent speakers of lojban, which is the only language in a vast otherwise empty space between
15:16sobelno you don't
15:17sobeli know several long-time lojban speakers and one of theme is a PhD-EE and we've kinda gone there about languages
15:17mungojellyprogramming languages aren't really computer lanugages they're human languages for talking about computation, so like in terms of number of symbols for instance they're closer to our preferences than a computers
15:17sobeli'm open to new ideas but fairly skeptical that there are any in this topic
15:18sobeli disagree strongly with your characterization that they are not really computer languages
15:18mungojellythere's a general shortage of new ideas on every topic, for a few more years, i'm sure we'll feel very nostalgic about it
15:18sobelthey do not talk about computation, they represent computation in somewhat human-readable symbols, but the orientation is computing not human communication. that's a fundamental divergence.
15:19mungojellyfor instance if you say the same thing in clojure we can write various compilers to express that idea in various concrete forms to various virtual machines
15:20sobelgotta go
15:20mungojellybut the essential thing is its meaning to us, the computation we think it represents, if it turns out it doesn't do what we think it should in an edge case we'll "fix" what the computer understands from it whenever that's practical
15:24mungojellyoh ok i was confused, i don't have to choose which data structure i'm talking about, i can write to the sequence interface or the collection interface or whatever and it works with a variety of data structures from clients
16:00lodin_justin_smith: Regarding your question about using lenses in Clojure. I just wrote a piece of code where a lens would've been sweet.
16:06rhg135what's the recommended way to store state in clojure? (atom huge-structure), {:part-a (ref substructure)}, or else?
16:07rhg135the first is convenient but it limits concurrency, the second is I'm not sure
16:32mungojelly,(defn latest-tile [grid x y] (->> grid (filter #(and (= (:x %) x) (= (:y %) y))) (sort-by :time) (last)))
16:32clojurebot#'sandbox/latest-tile
16:32mungojellyi feel like i'm saying it wrong when i say "#(and (=" is that wrong?
16:33lodin_mungojelly: What would be wrong with it?
16:34mungojellylodin_: i feel like there should be one word that means "filter for where these keys are that"
16:38lodin_mungojelly: Write your own contains-map?. :-)
16:38lodin_,(defn contains-map [a b] (= (select-keys a (keys b)) b))
16:38clojurebot#'sandbox/contains-map
16:39lodin_,(defn contains-map? [a b] (= (select-keys a (keys b)) b))
16:39clojurebot#'sandbox/contains-map?
16:39lodin_Now, #(contains-map? % {:x x :y y}).
16:40mungojellylodin_: i'm just trying to be idiomatic, it's polite and also there are many sensible pretty idioms around here :)
16:41mungojellythanks for the example of select-keys that's just what i've been playing with now
16:43lodin_Could use clojure.set/superset? as well.
16:43lodin_*thinks, *were
16:44dbaschmungojelly: it sounds like you have the wrong data structure for what you’re trying to do, if you have to do a linear scan and then a sort to find the latest tile
16:45mungojellydbasch: sure well "wrong" as in imperfect, what would you use?
16:45dbaschmungojelly: if you’re doing lookups based on coordinates, a map of maps
16:48dbaschmungojelly: the point being, if you’re doing this all the time for a large number of things why not have constant-time access to your items
16:51mungojellydbasch: map of maps like {0 {0 {:color "#00ff00"} 1 {:color "#009900"}} 1 {0 {:color "#009933"} 1 {:color "#00ff33"}}}?
16:52dbaschmungojelly: yes, where you have constant-time access to color (x, y) instead of having to search
16:53mungojellybut then i want it to be like {0 {0 #{{:color "#00ff00" :time 9837487} {:color "#009900" :time 873874}}}} hmm
16:53lodin_I have a bunch of delays that can take quite some time to realize. I want to print all realized delays and for that I can use realized? but I also want to wait for those that have been triggered. How would I do that best? (I do not want to trigger any delays unnecessarily.)
16:55mungojellythe question is whether the constant time access is worth breaking it up so it's unreadable. but i guess with a tiling system the number of tiles the user wants is, more tiles, mooooooooooooore. so i shouldn't be intentionally slow.
16:59mungojellyi don't know the answer to your question but thanks for teaching me "realized?" that's awesome
17:01rhg135,(into {} (map (comp (juxt :name :doc) meta)) (ns-publics (the-ns 'clojure.core)))
17:01clojurebot{nil nil}
17:01rhg135meh!
17:01dbaschmungojelly: you may want the set to be a sequence ordered by time, unless you’re going to be mostly checking for contains?
17:02rhg135,(into {} (map (comp (juxt :name :doc) meta)) (vals (ns-publics (the-ns 'clojure.core))))
17:02clojurebot{primitives-classnames nil, +' "Returns the sum of nums. (+) returns 0. Supports arbitrary precision.\n See also: +", decimal? "Returns true if n is a BigDecimal", restart-agent "When an agent is failed, changes the agent state to new-state and\n then un-fails the agent so that sends are allowed again. If\n a :clear-actions true option is given, any actions queued on the\n agent that were bei...
17:03mungojellydbasch: i'm not trying to tune it to be performant in any way, it's mostly supposed to be easy to handle, the use case i'm targeting is the beginner who's about to write (* cell-size x) for the zillionth time, my toy gives you the tiles so you can play on top of the tiles
17:03rhg135it helped to read it thouroughly for me
17:12lodin_I guess I want future-done? except delay-done?.
17:12hiredmandelays don't do that
17:13hiredmana delay only runs when it is forced, and forcing a delay blocks until it is done
17:13lodin_hiredman: Hence the problem. :-)
17:13hiredmana future and future-done? is exactly what you want
17:13lodin_hiredman: future runs it, even if no one wants it.
17:13hiredmanso you should be using futures and not delays
17:14lodin_Nope. I don't want to run anything until requested.
17:14hiredman05:13 < lodin_> hiredman: future runs it, even if no one wants it.
17:14hiredmanoh, I misread that
17:15lodin_So the point of delay is precisely to only run what is requested, and cache the result.
17:15ZimaBluefuture inside a function? "start working in another thread but only when someone asks you to". If multiple derefs possible, make the future memoize?
17:15hiredmanlodin_: my take on this is, your situation is extremely unlikely to be unique, so if the functionality doesn't seem to match up with what you are doing, everyone else is solving it a different a way
17:16lodin_ZimaBlue: I don't follow.
17:17hiredmanZimaBlue: you could put a future in a delay
17:17lodin_But how would I query the future inside the delay ...?
17:17hiredmanderef the delay
17:17ZimaBluedisclaimer I'm new to clojure and haven't been here for the whole conversation, but it sounds like you want to have the behaviour of "run in another thread and don't block, but only when someone specifically asks you to"
17:17ZimaBlueand I thought a future inside a function would do that
17:18ZimaBluemaybe it's inside a delay =/
17:18lodin_hiredman: Oh, you mean that I do two derefs.
17:18hiredmanwell you do a single deref to get the future, and then you can check to see if the future is done
17:18lodin_The delay creates the future and returns it. Then I deref again. If I want to query I deref the delay, and query the future.
17:18lodin_That works.
17:52phorseDoes anyone have experience converting large sql tables into excel docs? I'm using docjure and on a table with ~150,000 rows it hits the GC threshold and chokes.
17:58noncom|2phorse: maybe you can first dump it into csv with korma?
17:59noncom|2justin_smith: hi, are you here?
17:59noncom|2phorse: if even korma will choke, then maybe do it in chunks, like, by the id or sorts
18:02phorseI'm using yesql at the moment - does korma have csv conversion built in?
18:04justin_smithnoncom|2: hello
18:04noncom|2phorse: i doubt it has csv built-in, but wo knows
18:05phorseOk, so csv is basically a long string, as opposed to writing a long xml file.
18:05noncom|2justin_smith: hi! have you worked with secretary + reagent.session ?
18:05phorseTheoretically then, I don't need to hold the whole thing in memory at once, right?
18:05noncom|2phorse: yes
18:06justin_smithnoncom|2: I used secretary but ended up replacing it with a home-brewed router
18:06justin_smithnoncom|2: I don't think I have used reagent.session
18:06phorseThanks, I'll play with that for a bit and see what I can see.
18:06justin_smitheven xml can be streamed, if you try hard and believe in yourself, it's just trickier
18:07noncom|2justin_smith: alright, then another little question, do you have an idea, in a single-page app, if i have a subpage to view an entity and i want to let user view several entities, i suppose i should let him open several pages or will it go against single-page?
18:07noncom|2if, of course, this question makes any sense to you :)
18:08justin_smithnoncom|2: I would make that "page" just be a component that can be sucked into a [:div] for reagent in a for loop
18:08justin_smithor are you thinking multiple tabs
18:08noncom|2well, the for loop will make a list and multiple tabs just require to render them to tab components, right?
18:09justin_smithright, generate a tab in each iteration of the for comprehension
18:09noncom|2very cool
18:11noncom|2thank you :)
18:19lodin_hiredman: I just found out that realized? block on delays if realization has begun, which makes sense I guess. I don't actually want that behavior, so the future in delay solution works well.
18:24lodin_justin_smith: Did you see my lens comment above? I rewrote it to use megakorre/glasses (even though glasses is a snapshot release), and it was indeed pretty.
18:25justin_smithlodin_: no, I missed that
18:26lodin_justin_smith: You asked me the other day if I thought lenses were useful in Clojure, and just a moment ago I wrote some code that would benefit from a lens.
18:28noncom|2lenses are cool when you can put them into use
18:50pseudonymousIs there a way to disable leiningen's auto-update mania ? I would've thought that once all plugins were stored in ~/.m2 it wouldn't try to re-download everything
18:50justin_smithpseudonymous: are you using snapshots?
18:51justin_smithnothing that isn't a snapshot should be changing versions on you without your help
18:52pseudonymousNope. I'm not. I've tried to package the entire program up into a docker container where 'lein deps' was run prior - so the deps do reside inside the container itself.
18:53justin_smithcould it be a profile difference looked for different deps?
18:56pseudonymousjustin_smith: shouldn't think so, until recently I only had a single profile (:dev) -- I'm in the *very* early stages of packaging this thing up
18:57justin_smithare you using a plugin like lein-ring that adds dependencies?
19:00pseudonymousjustin_smith: Yup, I am, 3 plugins of which lein-ring is one of them. But lein-ring etc are fetched when I build the docker container (at which point I run 'lein deps' inside it)
19:03pseudonymousInterestingly it does add a few additional things, but nowhere the number which it tells me it's fetching (of which quite a few were libraries I've seen it download during the container build process)
19:19pseudonymousjustin_smith: do you perchance have a lein project.clj which has a production and a dev profile which you use ? I think I must be mkaing a mistake somewhere (launching with 'lein with-profile prod ring server' - yet dev-only dependencies are fetched)
19:22justin_smithpseudonymous: the reaosn I ask is that lein-ring has different deps duiring jar creation
19:26pseudonymousjustin_smith: I'm admittedly a bit lost there - I was naively hoping that by using lein I could be blissfully unaware of anything related to jars (very much why I'm not attempting the überjar method)
19:32justin_smithpseudonymous: lein-ring introduces deps, so if you do a different task with lein-ring it might just pull in different deps (other plugins do this too)
19:33justin_smithpseudonymous: the reason to do uberjar is that way you don't have to worry about whether lein goes and looks for more deps at runtime - because at runtime there is no lein, just the jvm and your uberjar, the deps are already there
19:34pseudonymousjustin_smith: just another point of variation I would've loved to avoid. 2x because I've been in jar-hell many a times in years back when dealing with Java. Jars to me are like RPM dependency hell of the mid-nineties ^^
19:35justin_smithpseudonymous: you are using the jvm, there will be jars. Uberjar creation is more predictable than using lein in production is.
19:35pseudonymousBut OK, I guess I'll need to take a deep breath, and figure out how in the world I can accomplish an überjar. I'm definitely too sleepy for that right now.
19:35justin_smithpseudonymous: "lein uberjar"
19:35justin_smiththat's it
19:36justin_smiththen java -jar your.uber.jar
19:36pseudonymousWell.. there must be a reason for the lein-ring plugin, right ? In the absence of that, I'll need to setup an entrypoint of some sort
19:36justin_smithlein ring uberjar
19:36amalloylein ring fabricates an entry point for you
19:37justin_smithor lein ring uberwar if you want to run in a container
19:37pseudonymousOh god, more JVM lingo. The beast rears its head
19:38pseudonymousI'll give it a whirl tomorrow :) I'm thankful for the suggestions (and patience!)
19:38amalloy~justin_smith is an agent of the beast
19:38clojurebotYou don't have to tell me twice.
19:38sobeloh noes, jvm lingo
19:39sobeli gotta say, kudos to whomever decided it wise to overload the basic zip file for the jar spec
19:39sobeland basically knock off the tar cli
19:40sobelfor all the gripes people have had creating and managing jars, they have no clue what hell they've been saved from by jars
19:42justin_smith~justin_smith
19:42clojurebotjustin_smith is sitting on a throne of flies.
19:42justin_smithhaha
19:43pseudonymoussobel: you might say that, but 80% of my time programming servlet, JSP and whatever else we were dragged through during university was actually spent feeding the beast various jar files and seeing version differences among our group crash whatever example app of the week we were toiling away at. It's by far the least pleasurable environment I've ever come across (npm, pip, gem etc comes to mind)
19:53justin_smithpseudonymous: yeah, putting multiple people's projects into one runtime and expecting deps to be a sane thing is probably futile. But if it's a single project with lein managing things, in my experience that can work out pretty well.
19:54pseudonymousjustin_smith: Seems do-able. The Luminus project's extensive documentation make it seem pretty easy (They really nailed it documentation-wise, superb job!)
20:06creeseHas anyone got instrumentation working with New Relic?
20:51kavkazWhat's up everyone
20:54justin_smithfixin some distributed systems
20:57kavkazJust going to continue on my project now. Trying to find the right music for me to listen to... I've been kind of down and it's hard to find the music that's gonna fit me right
20:59kavkazI may have found it (: