#clojure logs

2014-01-24

00:00rovarit's best to not have dysfunctional bros
00:00rovarall drama
00:01rovarhowever, I'm afraid clojure is my bro, I don't share my bros
00:02deadghostdude man
00:02deadghostif you love your bro
00:02deadghostyou gotta set your bro free
00:02deadghostunless you want to marry your bro
00:02deadghostthen you need to ask for rich hickey's permission
00:02akurilinSo, I love how ring will add both url and post data params into the params map, except you have to remember that you can't tell if something is a number or a string in a GET's URL param :(
00:03akurilinDo people end up using the two separate param maps to know when they need to parse for numbers and when they can assume the JSON got parsed correctly to a number?
00:03bbloomakurilin: form and url encodings are EVIL
00:03bbloomi can not tell you how many damn rails apps i've seen that just have params[...] with url, form, and json data all conflated
00:04bbloomthen they scratch their heads for a month when they have a bool a number and a string and can't tell em all apart
00:04guest1234can't some bright clojurean fix this intractable 'form params' problem, once and for all?
00:04bbloomfrankly, it makes a man wish for tcl :_P
00:05deadghostwho is our hero
00:05akurilinbbloom: what kind of options do I have if I need to read the :id in the compojure route and query params? Doesn't sound like I have much of a choice, right?
00:05guest1234Heroes can run. I'm learning to walk.
00:05bbloomakurilin: i dunno, i haven't used compojure
00:05akurilinoutside of redesigning the api to use all posts
00:05akurilinbut then you're pooping on http methods
00:05deadghostwrong guest1234
00:05deadghostheroes can FLY
00:06bbloomhttp deserves pooping on for most things we try to do with http... and it's too damn complicated for the things that SHOULD be done with something like http :-)
00:06deadghostand breathe underwater
00:06deadghostand shoot laser beams
00:06deadghostlike superman and rms
00:06akurilinI get that.
00:07guest1234how much of the damn web is genuinely, just getting damn form data from a to b. that's the entire 'healthcare' problem
00:07guest1234problem / industry.
00:07guest1234but that's another talk
00:09guest1234dead-ghosts can fly. and presumably breathe under water too?
00:09deadghostit's funny how many different frameworks need to be made for CRUD apps
00:09guest1234maybe they're all trying to resolve it the same <wrong> way.
00:09deadghostwill we ever have one unified thing with skinnable syntax
00:10guest1234like with the magic of btc, just have data 'zap' from point A to B.
00:11guest1234magically show up where it needs to, without hassle or conflated, ill-formed nonsense
00:11deadghostI want to hug the internet
00:11deadghostwait no scratch that
00:11deadghostthat sounds awful
00:11guest1234nope. it's logged.
00:12deadghostso what are you guys working on
00:13deadghostI'm herpaderpin a website to keep track of my lists
00:13deadghostcompojure + enlive
00:14guest1234does anyone have the source for D. Nolen's Om ToDo. the source link, https://github.com/tastejs/todomvc/tree/gh-pages/labs/architecture-examples/om has some funky lookin' git jedi
00:15guest1234off this page: http://swannodette.github.io/todomvc/labs/architecture-examples/om/
00:15deadghostI have a friend that likes forking everything he uses
00:15deadghostin case stuff disappears one day
00:16guest1234that's a little creepy, and incredibyl helpful.
00:16deadghostI wouldn't say helpful
00:16deadghostbecause he doesn't have your package
00:17guest1234did he fork todo?
00:17deadghostread above^
00:17deadghostmeaning no
00:17guest1234I guess there's plenty else to read through
00:18guest1234sorry. misread as fork anything that shows up on his page.
00:19guest1234as if stalking daily for any updates to grab.
00:20guest1234anyway, back to the hero that's going to fix FORMS and data integrity across the wire.
00:20deadghostgodspeed
00:20guest1234if you could have that by tomorrow, TTThhhat be great. thanks.
00:27akurilinbbloom: actually I just realized why Parse.com uses POST for fetching and SO uses GET. The former has somewhat complex queries you can define, and so it requires nested datastructures, which you can't really do that well in the URI. SO on the other hand doesn't support complex queries, so it can get away with no nesting.
00:27akurilinSo if I want nesting, I'm kind of screwed and need to POST it.
00:28akurilinI guess you can serialize a JSON object into the URI, but I don't know if that's just a recipe for sadness.
00:30akurilinActually it looks like people do this.
00:30akurilinI don't know if it should make me sad or not.
00:32dsrxdeadghost: websocket repl transport for clojurescript
00:33deadghostI'm only vaguely aware of websockets
00:33deadghostyou lost me at "repl transport"
00:37dsrxdeadghost: right now, browser-connected repls for clojurescript work with the usual iframe cross-page communication hackery which works... except you can't do it unless the page you'd like to run the repl on is served over something besides http (like a spotify application or chrome extension)
00:38dsrxer you can't do it *if* the page isn't served over http
00:39deadghostsounds neato
00:39deadghostI haven't had a chance to try clojurescript
00:39deadghostcan that voodoo work with normal js
00:40deadghostor is it some clojurescript specific magic
00:40eggheaddeadghost: cljs is to js what clojure is to java
00:40deadghostthat sounds stupidly amazing
00:42deadghostI'm pretty happy with just clojure in my life
00:42deadghostbut a clojure for JS rocks my socks
00:42deadghostI'm not a huge fan of js you see
00:42akurilin Nvm, Parse actually does use GET, they URL-encode a json blob.
00:42akurilinUgh guess I'm doing that
00:43dsrxdeadghost: to be honest i'm not totally sure if it will work, i've implemented the CLJS and still have to do the CLJ side that gets piggiebacked to nrepl and be sure it "acts like" the standard repl enough that it will even work
00:45dsrxhrm i guess i should verify that i can actually use websockets in spotify >:D
00:46deadghostit's k, you can be our hero
00:46deadghostdo a write up when you're done
01:02andyf_Wow, someone has been having fun maintaining the channel topic message
01:06coventryAnything obviously funky about this clojurescript code? I'm getting an assertion failure, "alts! used not in (go ...) block". Also, I get "can't recur here", if I use (go-loop) instead of (go (loop)). https://www.refheap.com/26844
01:10dsrxcoventry: are you requiring the core.async macros?
01:10dsrxhave to do it separately in cljs
01:11coventrydsrx: That was the problem. Thanks.
01:27akurilinSanity check: I should be able to specify environ variables in project.clj's :profiles :uberjar :env, right?
01:33andyf_when one is using Leiningen and has intra-file dependencies using :require and :use, is there ever a valid reason for a file foo/bar.clj to have any namespace in it other than foo.bar?
01:34andyf_And as an edit to that question, I would guess that Leiningen has nothing to do with the answer to the question.
01:34tomjackno
01:35nooniani don't think you can do that because of how java expects your file paths to correspond to namespace (package) names
01:35tomjackthere are examples in clojure of violations that involve using load instead of require
01:35tomjackclojure/core_*.clj
01:36tomjacketc
01:36andyf_tomjack: Yeah, I know Clojure implementation itself sometimes uses load, but I'd consider that the exception rather than the rule, from what I have seen
01:37andyf_But I am pretty sure that the implementation of require, use, and ns always look for a namespace foo.bar.blat in foo/bar/blat.clj, in some directory on your classpath.
01:37tomjackright
01:37tomjackso, no
01:38tomjackis there a sane way to add namespaces to edn?
01:38andyf_I am testing the Eastwood lint tool on some projects, and finding some placeholder files in the test directory with a namespace declared by ns that does not match the file path, and wondering whether I should make simple-to-understand error message for that.
01:40eggheadpretty sure Cannot call method 'call' of undefined is the npe of cljs
01:41andyf_tomjack: You mean, enable edn to read namespace-qualified symbols?
01:42andyf_tomjack: At least the tools.reader implementation of an edn reader can read namespace-qualified symbols, so not sure if I understand the question.
01:43dsrxegghead: heh
01:44tomjackandyf_: yes. and keywords
01:44tomjackwhere "namespace" no longer means clojure.lang.Namespace
01:44tomjack..and data readers?
01:44tomjacknah
01:44tomjackwell, yeah. the tag can be data-namespaced, but the var its bound to by *data-readers* will be clj-namespaced
01:44dsrxweird, i considered changing my nick to 'tomjak' on freenode today
01:45andyf_tomjack: I am not familiar enough with data readers to give any advice there
02:16logic_progwhat browser does lighttable use for rendering?
02:17logic_progI know lighttable users node.js
02:17logic_progbut it needs to use a browser for rendering -- what browser does it use?
02:19xuserlogic_prog: chromium
02:20logic_proghttps://github.com/rogerwang/node-webkit/wiki/How-node.js-is-integrated-with-chromium ?
02:20logic_progor should I be reading something else?
02:21xuseryeah, node-webkit uses chromium, node-webkit is wat LT uses
02:22xusers/wat/what/
02:30fredyrhave you guys seen anybody doing cljs and node on the server side for web stuff?
02:31logic_progxuser: nice, thanks!
02:31logic_progfredyr: I have been wanting to, as a poor man's version of erlang
02:32fredyrerlang? in what way
02:41jonathanjare there any good reads about what core.async isn't?
02:42jonathanjcoming from mainly a Deferred/Promise-based workflow, it's kind of surprising to me that core.async channels aren't a more common return value from libraries (i was looking at irclj)
02:43tomjack`does irclj use core.async now?
02:43tomjack`ah
02:45tomjack`go blocks seem reminiscent of promises
02:45tomjack`from the outside..
02:45tomjack`well, no
02:46tomjack`ok, "reminiscent". but promises "complect control flow and communication"
02:46tomjack`this quote is from the blog post about core.async, which I assume you've already read?
02:46eggheadhmm, in om why might i get "Uncaught Error: No protocol method ITransact.-transact! defined for type cljs.core/Atom: [object Object]"
02:47eggheadI thought atoms were perfectly fine things to be 'application state' and that you could use (transact! ...) outside of the react lifecycle to change it's state
02:47tutysaraddellacosta: I had tried fixing the issues with error response from provider, update the issue with comments, see if it is ok
02:49tutysaraddellacosta: , and for multiple provider thing changed the implementation to use a :provider-uri config instead of redirecting /login to the form to choose provider, updated that issue with comments :)
02:53eggheador... why might I be getting errors saying that part of my app state isn't a cursor?
02:53dsrxegghead: i think transact! accepts a cursor into the state, not the state itself
02:53eggheadya, I realized I could just use 'swap!' isntead of transact! outside of the react lifecycle, but now it's saying that things like (:thing state) isn't a cursor
02:55eggheadi'm probably just misunderstanding something
02:56eggheadI'm just trying to do (apply dom/ul nil (om/build-all! my-lis (:get-list-from state)))
02:56eggheadbut it's saying that the value in (:get-list-from state) isn't a valid cursor
02:56jonathanjtomjack`: no, i don't think it does; it talks about callback functions
02:56jonathanjtomjack`: i don't see a lot of libraries that have an async nature with an outward facing core.async interface (some don't even use core.async) and i'm wondering if i've missed what core.async isn't
02:58ddellacostatutysara: okay, responded--thanks!
02:58dwwoelfelIs it common knowledge that the :or destructuring form is eagerly evaluated?
02:59dwwoelfeluser> (let [{:keys [a] :or {a (println "hi")}} {:a 1}]
02:59dwwoelfel a)
02:59dwwoelfel"hi"
02:59dwwoelfel1
03:00logic_progdid the word complect exist before rich hickey?
03:00logic_progdid rich hickey just come up with a word complect
03:00ddellacostalogic_prog: yes, he explains that in one of his early talks in fact, if I recall
03:00logic_progand the rest of the wold go: okay, we accept this world you've defined
03:00dwwoelfelSeems like a bug in core/destructuring, where it uses a get
03:00dsrxcom·plect [kuhm-plekt] Show IPA verb (used with object) Obsolete . to interweave; intertwine. Origin: 1515–25; < Latin complectī to embrace, enfold, equivalent to com- com- + plect ( ere ) to plait, braid + -ī passive infinitive ending; cf. complex
03:00ddellacostalogic_prog: http://wordnetweb.princeton.edu/perl/webwn?s=complect
03:01ddellacostaah, dsrx beat me to it
03:01jonathanjtomjack`: which core.async blog post are you refering to?
03:01tomjack`the one you almost certainly read
03:01tomjack`clojure.org I think
03:01tomjack`I think a Promise interface is pretty similar to event callbacks as far as the comment in the blog goes
03:02tomjack`but I have thought about that comment for some time and still am not sure I understand it :)
03:02jonathanjyes, it is
03:02jonathanjpromises are just a callback abstraction
03:02jonathanjin the promise/deferred world though, whenever you do something async you return a deferred/promise
03:02jonathanjand as such, promises/deferreds permeate almost every aspect of your software
03:03tomjack`..so core.async isn't that, because it doesn't, uh, complect communication and flow of control
03:03jonathanjtomjack`: definitely, and i understand that part
03:03tomjack`I think I understand the question now
03:03jonathanjtomjack`: but why does irclj (to pick an example) not give me channels out?
03:03tomjack`does it even use core.async?
03:04jonathanjwhy do i have to put callbacks in?
03:04jonathanjtomjack`: not as far as i can tell
03:04jonathanjtomjack`: why would one not want to use core.async?
03:04jonathanjtomjack`: i feel like i've missed some crucial part of what core.async most definitely is not
03:04tomjack`I'd guess the explanation is probably more about the author than core.async
03:05ddellacostajonathanj: are you wondering why more libraries don't use core.async, is that part of your question?
03:05jonathanjddellacosta: yes
03:05tomjack`but if we assume that the author was familiar with core.async (and that all the new functions existed when irclj was written ?), it's an interesting question
03:06ddellacostajonathanj: one simple answer is that it's relatively new, and a lot of libs haven't had time to adapt it to their needs--pedestal, for one, I recall being a perfect use-case--but they only started to integrate it this fall (I believe).
03:06tomjack`oh interesting
03:06jonathanjddellacosta: hrm, weird
03:06tomjack`I can't wait to see what pedestal + core.async looks like
03:06jonathanjddellacosta: i've been reading about it for quite a while (before i decided to find out what it was about)
03:06ddellacostaactually, I think that v.2 already integrates it
03:06jonathanjddellacosta: but maybe my perception of time is a little... off.
03:07ddellacostajonathanj: well, it's been proposed and in alpha for a while. But it was only in the latter half of last year that it was officially out, I believe.
03:07dsrxegghead: got context for all that?
03:07ddellacostahere's what I was looking for: https://groups.google.com/forum/#!topic/pedestal-dev/e8MzUH4K-T0
03:07jonathanjso would a library that uses core.async (and exposes a core.async interface for users) return channels from functions that produce results asynchronously?
03:07eggheadsure dsrx
03:08ddellacostajonathanj: ^ you'll note that that post is from July, and it mentions that "Rich Hickey announced core.async a few weeks ago."
03:08jonathanjddellacosta: okay, that makes sense; thanks
03:08dsrxafaik om/build and build-all will only accept a cursor, which is created by om/root and passed subsequently to your rendering functions
03:08ddellacostajonathanj: np, hopefully that puts some of it in context.
03:09eggheaddsrx: https://www.refheap.com/26863
03:10tomjack`"Messages which tell other things to change"
03:10tomjack`https://github.com/pedestal/pedestal/blob/9f7879a6a6fdd5805cb22155d5589a36ae775152/app/examples/walkthrough.clj
03:10tomjack`so I can't tell how core.async affects a typical pedestal user's application code
03:11tomjack`didn't find any core.async requires in files that looked like demo code
03:11tomjack`oh, the app-template is where to look I guess
03:11ddellacostatomjack`: yeah, I'm not knowledgeable about how it works to say, I think that it's pretty heavily integrated into the codebase at this point though (last I looked at it)--so I think it's more that it provides the wiring for the underlying parts. I think that a Pedestal application developer wouldn't necessarily have much need to touch it, as Pedestal provides a pretty thorough FRP pattern itself on top of it.
03:12tutysaraddellacosta: thanks :) will work no the pull requests and for putting the workflow together I have to see how I can do it
03:12ddellacostatomjack`: I could be wrong about that...that statement is based on the last time I played with Pedestal, a few months back.
03:12eggheaddsrx: I don't see how it could *not* be a cursor, since it was passed to the om component
03:12ddellacostatutysara: great, thanks for all of your contributions!
03:12eggheadapp is the thing passed to om/root
03:13ddellacostatutysara: btw, I'm not positive that it makes sense to have one workflow for all providers vs. one per provider...I'll have to think about it. In some ways it makes sense to consider a single provider a single workflow, but I'm just not sure about it yet. So if you think one makes more sense than the other, let me know why--thanks!
03:13tomjack`ddellacosta: sounds reasonable
03:13dsrxegghead: oh hrm
03:13tomjack`I haven't looked at pedestal in a long time either
03:14tomjack`but it seems you're right that core.async is used quite a bit in pedestal itself
03:14tomjack`not sure why it's used in the walkthrough but not user code
03:14tomjack`maybe the walkthrough is for developers?
03:14ddellacostatomjack`: yeah, I've gotta check it out again myself...along with hoplon and a few other things...always more to check out!
03:15ddellacostatomjack`: huh, dunno--I wonder if that walkthrough is v.3 vs. v.2?
03:16tomjack`dunno, will wait and see. won't be using cljs for a long time :(
03:18ddellacostaegghead: I'm still figuring out how this all works, but I've had the same problem, and solved it by passing the whole data structure to the component and deconstructing it within the component code (rather than before I pass it in). I believe it has to do with the structures that can be validly used as a cursor (https://github.com/swannodette/om/blob/master/src/om/core.cljs#L243 for example).
03:19ddellacostaer, not sure if that code example is helpful
03:20eggheadddellacosta: what I don't understand is that it looks exactly like what dnolen is doing in his tutorial example
03:20ddellacostaegghead: which one? the to-do thing?
03:20dsrxmost of the om examples and such pull out the state to be used with build-all before calling it
03:20dsrxegghead: yeah thats why i'm confused too
03:21eggheadmaybe because it is a nested structure or something?
03:21eggheadI mean it's a map of keys to sometimes strings sometimes lists of other maps etc
03:21eggheadddellacosta: nah https://github.com/swannodette/om/wiki/Tutorial#wiki-your-first-om-component this one
03:22ddellacostaegghead, dsrx: as I said I'm still figuring it out, but I believe it has to do with how to-cursor works, which is what happens when you create a component: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L387
03:22dsrxright, it doesn't seem like to-cursor is recursive (heh)
03:23fredyregghead: are you updating your atom outside of the om lifecycles?
03:23dsrxegghead: what version are you on?
03:24fredyregghead: bc then you replace the cursor with a plain atom
03:24eggheaddsrx: latest
03:24eggheadand ya fredyr
03:24eggheadI think basically I have a larger structure {:foo [:a :b :c]} and that is a cursor but apparently [:a :b :c] is not?
03:24eggheadit makes no sense
03:25fredyra cursor is a cursor
03:25fredyr:)
03:25dsrxi don't think om/root ever actually swaps in a cursor to replace your state atom
03:26eggheadfredyr: do you know what is wrong with my code? https://www.refheap.com/26863
03:26eggheadi mean it'll work if everyone has full access to all the state i just want to know why it doesn't work
03:26ddellacostadsrx: it explicitly does in root: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L442
03:26eggheadlike if instead of (:supervisors state) I just say state like ddellacosta suggested
03:26eggheadbut that feels lame
03:29dsrxddellacosta: i see it creating a cursor from the dereferenced state of the atom provided to it (which is then passed onto the render fns), but i don't ever see it updating the atom itself unless i'm missing something
03:30fredyregghead: can you show the om/root code for creation, as well as the atom updates
03:30fredyregghead: bc i don't think the code you posted contains the problem
03:30dsrxthis is the first time i've really dug deep into om so i very well might have no idea what i'm talking about :D
03:30dsrxthe first time i read om source code i didn't know what an atom was
03:31eggheadsure thing fredyr
03:31ddellacostadsrx: that's because you would be doing the updating yourself, using transact! or update!
03:32eggheadfredyr: om root creation: https://github.com/eggsby/warden/blob/master/src/cljs/warden/core.cljs#L17
03:32fredyregghead: also, i don't think you should update the atom outside of om, but use transact! or update!
03:32eggheadswap updating https://github.com/eggsby/warden/blob/master/src/cljs/warden/net.cljs#L19
03:32eggheadfredyr: the whole point of my use case is that I want to keep the ui state in sync with an external resource
03:33eggheadso I kind of have to do it outside of the react component
03:33fredyregghead: sure, but if you look at dnolen's examples, that's usuall done by setting up a channel inside of the will-mount of a component
03:33fredyregghead: where you have access to the cursor
03:34eggheadhmm
03:34fredyregghead: https://github.com/swannodette/om/blob/master/examples/counters/src/core.cljs#L43
03:34fredyregghead: something like that
03:36eggheadi'll try kicking off the polling stuff inside of the will mount and using set-state! or update! instead of swap!
03:36eggheadthanks fredyr
03:36fredyrnp, let us know it you get anywhere
03:40quizdrwhy do I need to writing something like #(vector %2 %) rather than #([%2 %])? I know #() cannot be nested, but this is not a nested #(), or there another reason?
03:40dsrxquizdr: #(vector %2 %) desugars into (fn [x y] (vector y x))
03:40fredyrquizdr: its bc of how #() gets expanded
03:40clgvquizdr: because of the definition of the reader macro #()
03:41dsrx,(fn [x y] ([x y]))
03:41quizdrso my erroneous would just get expanded as (fn [x y] [y x]) ?
03:41clojurebot#<sandbox$eval25$fn__26 sandbox$eval25$fn__26@1d290d1>
03:41fredyr#(%) -> (fn [x] (x)), not (fn [x] x)
03:41clgvquizdr: it expands to a function call and ([]) does only make sense with integers as in ##([4 5 6] 1)
03:41lazybot⇒ 5
03:41clgvquizdr: no. (fn [x y] ([y x]))
03:42fredyr,(macroexpand-1 '#([%2 % 1]))
03:42clojurebot(fn* [p1__52# p2__51#] ([p2__51# p1__52# 1]))
03:43quizdri see
03:43fredyr,(macroexpand-1 '#([%2 %1]))
03:43clojurebot(fn* [p1__78# p2__77#] ([p2__77# p1__78#]))
03:43fredyrquizdr: there's an extra parenthesis
03:43clgv,(read-string "#([%2 % 1])")
03:43clojurebot(fn* [p1__106# p2__105#] ([p2__105# p1__106# 1]))
03:44clgvfredyr: it is not an actual macro ;)
03:44fredyrhah
03:44quizdrclgv macroexpand is quite useful for seeing inside syntax in general even for non macros
03:45clgvquizdr: not more useful then read-string, since that is where the non-macro is happening ;)
03:45clgv*non-macro magic
03:46quizdr,(read-string "(#(%) 5)")
03:46clojurebot((fn* [p1__131#] (p1__131#)) 5)
03:47quizdr(inc clgv)
03:47lazybot⇒ 11
03:47quizdr(+ clgv 10)
03:47lvhHello! How can I get the number of days in between two local-dates in clj-time?
03:47clgvquizdr: but macroexpand-1 is *the* tool when writing macros
03:48quizdr(* clgv clgv)
03:48clgv:P
03:48fredyr~clgv
03:48clojurebotExcuse me?
03:49clgvfredyr: what did you expect as return?
03:49CookedGryphonlvh: Something like (in-days (interval date1 date2))
03:50fredyrclgv: some witty comment?
03:50lvhCookedGryphon: But interval doesn't work on two dates; because it considers them themselves intervals, not times
03:50clgv:P
03:50lvhCookedGryphon: so I also need a way to tack "noon" onto a date
03:50CookedGryphonlvh: how are you making the dates?
03:51lvhCookedGryphon: clj-time appears to do midnight, but even with my limited understanding of calendaring I'm pretty sure that's fragile unless you only use tz-agnostic types everywhere
03:51lvhright now, (local-date); but they will be read from a CSV file after
03:51CookedGryphonand it does, behind the scenes
03:52CookedGryphonif you put the tz data in, it'll use it. If you don't, I'm not sure what you want it to do?
03:54lvhCookedGryphon: When I use date-time, I appear to be getting Intervals in UTC (ISO timestamps ending in Z)
03:55lvhCookedGryphon: How do I tack on "noon" to something? I mean I guess I could do something like (apply local-time ((juxt year month day) my-date))
03:56lvhehh except of course with the times added :)
03:56CookedGryphonlvh: I might be wrong, but I don't think it will make any difference
03:57CookedGryphonif both the dates are in the same timezone (utc) it'll surely just do the arithmetic on the date field and all will be well, I don't see the need to shift it to noon
03:57CookedGryphonand if you did, what good it would do
03:58TheDude_Hi, I'm new to clojure and trying to rename an uploaded file with a long timestamp, but for some reason the code is not working
03:58CookedGryphonthe interval noon to noon is the same as the interval midnight to midnight
03:58CookedGryphonunless there's something fundamentally broken
03:59CookedGryphonespecially as doing it at 00:00:00 is used all through the examples for jodatime/clj-time
03:59lvhCookedGryphon: It's probably a nitpick. If you have half an hour, I highly recommend http://pyvideo.org/video/1765/blame-it-on-caesar-what-you-need-to-know-about-d
04:00TheDude_Thanks, am checking it out
04:00TheDude_What would you recommend as a unique identifier for renaming an uploaded file?
04:00CookedGryphonlvh: yeah, but I trust jodatime/clj-time people have thought about this a lot more than I have, so trying to trick it by moving things to midday sounds like a bad idea...
04:01lvhCookedGryphon: In that talk, the author makes a cogent argument about exactly why it shouldn't ever be midnight.
04:01lvhCookedGryphon: (The answer is that not every midnight time instance exists.)
04:01CookedGryphonlvh: does this come up in your dataset?
04:02CookedGryphonhave you tried putting them into jodatime
04:02lvhCookedGryphon: I have no idea, it's still being constructed. It does come up in real datasets, though.
04:02CookedGryphoni would be very surprised if it didn't work it out, or at least make a reasonable compromise
04:02TheDude_Hi, does anyone know of a lib to handle file uploads and renaming the uploaded file?
04:03lvhCookedGryphon: (There's people that can't check into certain Alitalia flights because they were born on the wrong day; that particular problem is related to Europe/Rome and someone being under the mistaken impression that doing everything in the same timezone would make it sort of work out.)
04:03fredyrclojurebot: clgv |is| (read-string "((.)$(.))")
04:03clojurebotYou don't have to tell me twice.
04:04fredyr~clgv
04:04clojurebotclgv is (read-string "((.)$(.))")
04:04CookedGryphonlvh: lol, yeah, it is a bit of a minefield!
04:04clgv,(read-string "((.)$(.))")
04:04clojurebot((.) $ (.))
04:04clgv:P
04:04lvhCookedGryphon: Anyway, times and calendars are incredibly complicated, and unfortunately not even Zulu time is as easy as we like to think it is (still has leap seconds)
04:05clgvclojurebot: forget clgv |is| (read-string "((.)$(.))")
04:05lvhalso leap days
04:05clojurebotI forgot that clgv is (read-string "((.)$(.))")
04:05fredyrpoint free owl
04:05clgv~clgv
04:05clojurebotIt's greek to me.
04:05fredyr:(
04:05lvhAnyway, what I want is for something to tell me the number of days between 2014 01 01 and 2014 01 15.
04:05clgvclojurebot: clgv |is| usually very busy
04:05clojurebotYou don't have to tell me twice.
04:05clgv;)
04:06TheDude_Does anyone know of a good tutorial on file uploads? Am new to clojure and this one issue is throwing me sideways. Rest ref routing, crud, sessions easy peasy.
04:08srrubyHow do I create a global atom? Thanks.
04:10noonian(def my-atom (atom {})) ?
04:10srrubynoonian: Thanks!
04:10nooniannp
04:11TheDude_Hi, is anyone here avaliable to answer a question?
04:12lvhTheDude_: Lots of people. Probably not me.
04:13noonianjust ask and if anyone knows the answer they will likely answer it
04:14TheDude_Thanks. Have made good progress with clojure but stuck on 1 issue, uploading a file via ring and renaming it either with a long timestamp or maybe userid + sessionid
04:14TheDude_Been trying to crack this nut for 2 days :)
04:17noonianwhere are you having trouble?
04:17clgvTheDude_: isnt a file upload just a HTTP POST request?
04:18clgvTheDude_: I am not sure about the browser side, but if it is just an HTTP POST request on your server you can just access the input stream of the request to get the contents of the file
04:19TheDude_Yes, I can get a file and save it to a folder, however where I'm having trouble is renaming the file with a unique identifier such as long timestamp or session userid
04:19clgvwhen you save it to a folder you specify the filename and thus can use an arbitrary one
04:20quizdrok, i'm looking at a decurrying excercise. i think i must be brain dead. how is it possible to peer inside a curried function to see what arguments it is using internally?
04:21TheDude_I found some code, am trying it now by generating a random number via java
04:21quizdror even to query the number of arguments a fn expects
04:21TheDude_Does anyone have an idea how I would append or prepend that unique random number to the uploaded file name?
04:22clgvTheDude_: can you upload a minimal gist of your file upload code so that we have some context to help you?
04:23clgvappending to strings is easily done via ##(let [existing-string "my-file.txt"] (str "prefix." existing-string ".postfix"))
04:23lazybot⇒ "prefix.my-file.txt.postfix"
04:24clgvif you want to append before the ending you can just split the string at the dot
04:24clgvthe clojure.string namespace is what you want then
04:25TheDude_Thanks guys, I will try that right now. My first time to IRC, how do I post the gist here?
04:26ddellacostaTheDude_: just paste it into refheap.com or gist.github.com (or whatever), and paste the link to that gist/refheap into the IRC window.
04:27quizdrah, of course, use the curried function as a recursive function
04:29TheDude_Thanks, here's the sample code point where I'm at now https://www.refheap.com/26875
04:29d11wtqHi guys. Looking for some input on DSL style choices in Clojure.
04:29d11wtqhttps://gist.github.com/d11wtq/8594436
04:30d11wtqI'm writing (for learning only) a cron style scheduler, that distributes work across a number of nodes. It has a schedule file that is written in Clojure, as in that Gist.
04:30d11wtqDoes that DSL look like you'd expect, or would you abstract further/less with macros?
04:30TheDude_The first definition is handle-upload, not handle-upload-original
04:31d11wtqAnd would you put parentheses around each schedule entry, so it's more logically grouped?
04:31d11wtq(Sorry, I don't really know a better place to ask for peer review... stackoverflow not good for that)
04:31CookedGryphond11wtq: definitely less with macros
04:32CookedGryphond11wtq: I would make it data
04:32quizdrd11wtq programmers.stackexchange often boasts itself as a peer review site
04:32CookedGryphond11wtq: for an amusing explanation of why, see this talk by stuart halloway http://vimeo.com/77199361
04:32quizdractually there is this new beta site at stackexchange, fyi: http://codereview.stackexchange.com/
04:33d11wtqCookedGryphon: Yeah, so the angle was I going for there was, for example, avoiding Keywords and doing somethng like (every 5 minutes (println "Boo"))
04:33d11wtqBut I don't like that.
04:33d11wtqThanks for your suggestions on the other stackexchange sites!
04:33d11wtqI always forget about them :)
04:33alandipertd11wtq: looks cool to me, but yeah macros (if they get big) can be hairy. the only part i might change is to feed it functions instead of exprs for :every and :at; these functions could take the schedule as an arg perhaps
04:34CookedGryphonyeah, you should avoid macros if at all possible
04:34clgv~gist
04:34clojurebothttp://gist.github.com/
04:34clgvthe bot knows ^^
04:34clgvbut refheap as good as well
04:36alandipertd11wtq: also if you feed it functions isntead of exprs, defschedule doesn't need to be a macro anymore
04:36d11wtqYeah, the macro will (obviously) ultimately construct a function that calls other functions. I think some level of macro usage makes writing something like a schedule cleaner though, so you don't need to wrap everything with lambda.
04:36alandipert(not that macros are bad, i personally think they rule and i write them all the time)
04:37d11wtqIt's funny hearing people say to avoid macros. It wasn't that long ago (before I started in Clojure) that I read Let Over Lambda. That puts things in perspective. A little defschedule macro is nothing :P
04:37CookedGryphond11wtq: DSLs are very rarely a good idea. You make it so people can't compose what you're doing easily, and obscure it so that if people want to do anything out of the ordinary, they will probably need to know something about what your macros are generating
04:37CookedGryphonand heaven forbid there's ever a case you didn't think of ahead of time
04:37alandipertd11wtq: imo clojure is a tighter/better designed system than CL, and macros are scarcer because they aren't needed to stitch together the language as much
04:38tomjack`a project for which a CL'er I know thought essential, in clojure, ended up needing virtually no macros
04:39tomjack`er, "for which a CL'er I know thought _macros_ essential"
04:40d11wtqThanks guys. I'll do this with functions alone and finish off by providing a convenience macro. I think that's the way to go (and the way I'd naturally TDD this).
04:42CookedGryphond11wtq: I really recommend that talk I linked to, which would suggest storing your schedule as data where possible. That way other tools can read your data, say you wanted to make a separate app to show you upcoming events rather than scheduling them, or allow you to reconfigure them graphically
04:42CookedGryphonthat would be easy with data
04:42CookedGryphonhard with functions, and extremely difficult with a dsl
04:42CookedGryphonhttp://vimeo.com/77199361
04:42CookedGryphonthere you go again
04:42TheDude_Would it be possible to get some feedback on this code https://www.refheap.com/26879
04:43d11wtqhttp://vimeo.com/77199361 thanks
04:43TheDude_Am trying to rename an uploaded file
04:44steckerhalterhow do I convert long to a byte array? I have found this where the question outlines how to do it with Java, but I'm not sure how to translate that in to Clojure: http://stackoverflow.com/questions/19791255/how-to-convert-byte-array-to-long-without-using-java-nio
04:45CookedGryphonsteckerhalter: I would recommend a ByteBuffer instead of an outputstream if you know the length of your data vaguely
04:45CookedGryphonand don't need to stream
04:46steckerhalterCookedGryphon: ok, any examples how to use it for this purpose?
04:46CookedGryphonthen you just do (doto (java.nio.ByteBuffer/allocate 8) (.putLong 123) (.putLong 321)) etc
04:47CookedGryphonand then .rewind to go back to the start of the bytebuffer if you want to overwrite, or read out one thing at a time
04:48CookedGryphonand look at the docs for how to get a byte array out of that
04:48steckerhalterthanks
04:48CookedGryphon.array i think
04:48noncomanyone using twitter-api, can show an example of a restful statuses-update call? what will be the :params?
04:49CookedGryphonsteckerhalter: np, hope that's enough info to get you started
04:50ddellacostaTheDude_: you need to take a look at ring's multipart-params namespace: https://github.com/ring-clojure/ring/wiki/File-Uploads
04:51ddellacostaTheDude_: http://ring-clojure.github.io/ring/ring.middleware.multipart-params.html
04:53TheDude_Thanks ddellacosta, am checking that right now
04:53ddellacostaTheDude_: try reading through some of the examples that exist first, because your code doesn't really seem to reflect how ring/compojure works. Google "file upload with ring/compojure" and you should find some good examples.
04:56ddellacostaTheDude_: or at least, I'm not sure what's happen with all the functions that you are including from the pgapp.util namespace; could be they are doing the heavy lifting.
04:58TheDude_I got it working with file name as is and to a dynamically created directory for user
04:58TheDude_But I prefer to save em all in one folder with a unique identifier in the file name and store that in the db
04:59TheDude_I'll try a search with ring compojure, since I'm new to clojure not so familiar with all the plumbing in the various libraries
04:59TheDude_SQL Crud, views, sessions, all easy peasy, file upload and manpilating how file is name, where saved, etc, bit challenging :)
05:00ddellacostaTheDude_: ah, I see. I think the problem with your example is just that it's hard to see what stuff like upload-file and gallery-path are doing.
05:00TheDude_The functions in the utils namespace just supply the folder name where to save the file
05:00TheDude_gallery-path is just a reference to the actual folder to store
05:00ddellacostaTheDude_: it would probably be useful to put that in the refheap next time so people can see what they are returning and how they work.
05:01TheDude_upload file I myself am confused :) I don't see it in my utls file
05:02ddellacostaTheDude_: if you are just getting familiar w/Ring and Compojure definitely scan through the examples of argument de-structuring and read up on how the request map works--and you may get some of a sense of how it is by simply dumping out the request itself in your code, to start. That can be useful if it's not clear what is getting passed where.
05:02TheDude_Oh I got it, upload-file is a reference in the [noir.io :refer [upload-file resource-path]]
05:03ddellacostaTheDude_: ah, sorry--I see that referenced in the require form now, I missed it.
05:03TheDude_How long do you think it typically takes a newbie adpoting clojure from standard 00 langs like ruby or coldfusion?
05:03TheDude_lisp is def a diff paradigm, enjoying the journey so far
05:03AeroNotixso my co-worker is trying to set up cider, when opening a cider-jack-in repl and then loading code into it, it complains it cannot find classes. Printing out the class path suggests that it's not picking up the project at all.
05:04ddellacostaTheDude_: in that case, take a look at the noir docs: http://yogthos.github.io/lib-noir/noir.io.html#var-upload-file. I would suggest maybe leaving noir off at first and doing it via ring...just so you get how ring works at first.
05:05TheDude_Is lib-noir created by yogothos?
05:05ddellacostaTheDude_: re: how long it takes? If you've done ruby or python and are familiar with wsgi or rack, then you should get a sense of how ring works pretty quickly.
05:06TheDude_Yes it seems to work same way as middleware
05:06ddellacostaTheDude_: lib-noir is maintained by yogthos, but grew out of code from the-framework-formerly-known-as-noir by Chris Granger
05:06ddellacostaTheDude_: er, not just yogthos I guess
05:06TheDude_yogothos is the man, he's been v helpful
05:08TheDude_I think the key here is reading up the docs and getting more familiar with the plumbing
05:08TheDude_I'm just a week into it so far, looks v promising
05:08ddellacostaTheDude_: yep, definitely agree--I think you'll feel a lot more comfortable with it once you've gotten through Ring/Compojure docs, especially (if you want to do server-side web stuff).
05:09TheDude_I'm mostly doing server side stuff, about 99%
05:09ddellacostaTheDude_: and I definitely recommend looking at the codebase for those two projects as well, they are clean and well written, and the ring architecture itself is simple and logical.
05:10TheDude_Are you doing web dev stuff or you have a diff use case?
05:11ddellacostaTheDude_: I do web dev with Clojure, yep.
05:12ddellacostaTheDude_: but there are a lot of folks using Clojure in a lot of different domains.
05:12TheDude_Using any framework or you write your own
05:13ddellacostaTheDude_: mostly just Compojure, with various libs here and there. I haven't yet found a framework that is as useful as simply composing libraries together.
05:13TheDude_Yeah, I like the simplicity of just putting together some libraries
05:13fredyrspeaking of server side web in clojure, whats the way to setup user account logins and such, with email verification?
05:14TheDude_Thanks for your help, calling it a night for now. Goodnight and again thanks.
05:15ddellacostaTheDude_: cheers, good luck! :-)
05:15ddellacostafredyr: I've built two systems which do that, and they both have required a fair bit of code slinging, unfortunately. :-(
05:15fredyrddellacosta: too bad
05:15ddellacostafredyr: but, the one I built with Friend was a bit simpler. For that project, I used mailchimp + friend.
05:16ddellacostafredyr: I mean, it was a lot of code compared to how I used to set up Rails w/Devise back in my RoR days. But, then again, I had to use Rails. ;-)
05:16fredyrhaha right
05:16fredyryeah, i guess i'm comparing to how i would've done it with django
05:17ddellacostafredyr: the other way I did it was an even more customized version which uses safeguard (my company's lib: https://github.com/diligenceengine/safeguard)
05:17AeroNotixso my co-worker is trying to set up cider, when opening a cider-jack-in repl and then loading code into it, it complains it cannot find classes. Printing out the class path suggests that it's not picking up the project at all.
05:17ddellacostafredyr: yeah, I think that friend is the closest thing we've got to anything rails or django could give us (not knowing what is possible with django, but I assume it is easier)
05:18ddellacostaAeroNotix: is he starting it up in the project directory? I've only started up cider by starting a repl in a separate project dir, then connecting to that, which always works nicely for me.
05:19ddellacostagod, that safeguard read me is f*cking terrible
05:19ddellacostaforgive me for saying so boss. ;-)
05:21ddellacostafredyr: I've actually been meaning to write some sort of "get-going-quickly" thing for friend which wraps up some of the functionality that you get with something like devise in Rails.
05:22ddellacostafredyr: I should add, there is also going the Java route--there are wrappers for stuff like apache shiro I think
05:22ddellacostafredyr: https://github.com/inventiLT/Pocheshiro
05:22ddellacostafredyr: it's just...very Java-y
05:46muhooi love that there's an oath-clj and a clj-oauth library, which are different but seem to do the same thing
05:47steerioat least there's a different word in both (if that's really oath there)
05:47steerioin both = in each
05:47steerioi can't english
05:52katoxis there a simple way in sider to run (macroexpand-1 'form) instead of default (macroexpand-1 form)?
05:57katoxwhat do I do now is to expand all macros from the top level form to get to the proper level - or - just copying the stuff into the repl, adding pprint macroexpand-1 and quote, that seems silly
06:05tim__what is the difference between '(use 'a.b)' and '(:use a.b)'?
06:10katoxtim__: the second is the form used in ns macro, the first is the actual call
06:11tim__Thanks
06:11katoxtim__: np, that said, use is somewhat obsolete now that require has :refer option
06:13tim__thats a lot of help, i'm very new to clojure.
06:18Morgawr,(int 1.999999999)
06:18clojurebot1
06:18Morgawr,(int 1.999999999999999999999999)
06:18clojurebot2
06:18Morgawrwelp
06:19Morgawrhttps://gist.github.com/tshauck/8591809 <-
06:22hyPiRionMorgawr: well
06:22hyPiRion,1.999999999999999999999999
06:22clojurebot2.0
06:23Morgawr,1.999999
06:23clojurebot1.999999
06:23MorgawrI see
06:23Morgawr still fun
06:23arcataneven clojure knows that 1.999... = 2
06:25locksnothing is true, everything is permitted
06:25Morgawrbut then how come (apply + (range)) doesn't return -1/12? :D
06:27hyPiRionbecause range isn't infinite
06:29hyPiRion,(doall (range (- Long/MAX_VALUE 1000) Double/POSITIVE_INFINITY))
06:29clojurebot#<ArithmeticException java.lang.ArithmeticException: integer overflow>
06:32AeroNotixorg.apache.commons.io.IOUtils where does this package/class live? Do I need to download it?
06:33alewI find it very curious that (take 2.5 x) returns 3 elements instead o f2
06:34alew,(take 2.5 (range 5))
06:34clojurebot(0 1 2)
06:34hyPiRionAeroNotix: add [commons-io/commons-io "2.4"] to your dep vectory
06:35AeroNotixhyPiRion: cheers
06:37TEttinger),(take 2.4 (range 5))
06:37TEttinger,(take 2.4 (range 5))
06:37clojurebot(0 1 2)
06:37TEttingerseems to round up
06:37alewIf you look at the implementation
06:38alewit's actually just dec'ing each iteration
06:38alewand checking if positive
06:38alewso you get down to 0.4
06:38alewStill seems like odd behaviour
06:39TEttingerrand-int can take a fraction or float param too. it's even weirder
06:40TEttinger,(frequencies (repeatedly 1000 #(rand-int 2.5)))
06:40clojurebot{2 201, 1 368, 0 431}
06:41TEttingernote how 2 shows up about half as frequently as the others
06:41alewwhat the fuck..
06:47TEttingeralew, that probably has to do with just dividing (rand) by the arg to rand-int
06:48TEttingeror multiplying?
06:49CookedGryphonor it could be that int is truncating, doing a floor
06:49CookedGryphonso 0 and 1 buckets are both twice as big as the 2.5 bucket
06:49hyPiRionCookedGryphon: yeah, rand-int is essentially just (int (* n (Math/random)))
07:18lvhHi
07:19lvhis there a way to tell group-by what to put items into
07:19lvhI want them also *sorted* by (f elem), not just grouped by.
07:22CookedGryphon(into (sorted-map) (group-by f coll))?
07:23CookedGryphonor sorted-map-by
07:23CookedGryphonas your keys are already the values you want to sort by
07:25hyPiRionI think lvh means that the lists inside the maps are sorted
07:25lvhnope, CookedGryphon had it right
07:25lvhthe keys of the map have to be sorted
07:26lvhis there some kind of convention for a memoized function and its unmemoized variant?
07:26lvhSorry, I mean for the *names* of them.
07:26CookedGryphonlvh, i usually call the unmemoized variant blah*
07:26lvhAnd then (def blah (memoize blah*))?
07:29CookedGryphonlvh: yeah
07:30CookedGryphonI think I've seen it in a few other libraries too
07:30CookedGryphononly issue with that
07:30CookedGryphonis that the def there isn't going to pick up the docstring from blah*
07:30CookedGryphonand the arglist
07:31CookedGryphonnot sure what to do about that other than manually attach the metadata
07:35hyPiRionlvh: we do alter-var-root'ing in Leiningen. Consider doing that if you never use the unmemoized version
07:46john2xcan I 'unload' a namespace I use/refer/required in the repl?
07:57noidi,(doc remove-ns)
07:57clojurebot"([sym]); Removes the namespace named by the symbol. Use with caution. Cannot be used to remove the clojure namespace."
08:02locks,(doc doc)
08:02clojurebot"([name]); Prints documentation for a var or special form given its name"
08:12lvhHi
08:12lvhis there a more efficient "intersection?"? Maybe just intersection is already doing what I want
08:12lvhBasically I have a 2-set and an N-set; if either element is in the N-set, give up
08:13lvhI think the way to spell that is (if (seq (intersection s1 s2)))
08:13llasramlvh: You can do way better than that
08:13llasramIf you know s1 is smaller than s2,
08:13llasram(if (some s2 s1) ...)
08:13lvhllasram: Nope. The N-set starts out empty.
08:14lvhllasram: Maybe I should explain what I'm trying to do
08:14lvhI'm trying to solve a hotel-pairing optimization problem
08:14llasramMaybe :-)
08:14lvhI've figured out how to produce candidate pairs in terms of decreasing preference
08:14alandipertcheck each element w/ contains?
08:14lvhif either of the people in the candidate pair is aready assigned, obviously I can't assign them again
08:14lvhso, I'm keeping a set of already assigned people.
08:15lvhDoes that make sense?
08:15lvh(That's the big N-set. It obviously starts empty.)
08:15lvhmaybe that still means some, though.
08:16llasramTotally. And my suggestion still holds -- I just made it overly-strong. And you can always generalize. The important part is that you only care that there is an intersection vs the content of the intersection
08:16lvhbecause it doesn't actually matter if the set is bigger
08:16lvhright?
08:16lvhright
08:16lvhllasram: Thanks!
08:16llasramnp!
08:16hyPiRionlvh: as far as I understand, you can just do (not-any? #(contains? s2 %) s1)
08:17hyPiRionwell heck, llasram's solution is way better. I'll go away now.
08:17llasramhah
08:17llasramActually *I'll* go away now!
08:17llasramThat'll show ya
08:17lvhactually, rethinking my algorithm, it may be necessary to actually have the intersection anyway
08:18hyPiRionI guess I am terrified of nil and write code to defend against them at any momemt.
08:18lvhhmmm, maybe not, because I have every combination
08:18lvhI need a whiteboard
08:18alandipertsome is o(n) worst case though, vs. just using 2 contains? checks
08:19hyPiRionalandipert: not if you know that s1 contains 2 elements only
08:19lvhyeah, I can guarantee they're only pairs.
08:19lvhbecause they come from (combinations all-users 2)
08:20alandiperthyPiRion: oh, right! i had my s1 and s2 backwards
08:24lvhare nested loop/recurs okay?
08:25hyPiRionlvh: I would recommend to split the function up into more functions if that happens
08:25hyPiRionBut it's doable, sure, just a bit convoluted :)
08:25lvhI'm having a hard time making function names sane
08:25lvh(defn pair-least-unmatched-days-within-subgroup)
08:26lvhis there a refactoring thing for emacs that understands clj projects
08:26lvhthat can rename function names?
08:26CookedGryphonlvh clj-refactor
08:26CookedGryphonis probably the closest thing
08:26lvhoooh!
08:26CookedGryphonyou can do nice things like rename file which will update all the references to your namespace too
08:27CookedGryphonand unwind/wind threaded expressions
08:27lvhawesome
08:27CookedGryphonbut mainly I use it for shifting namespaces around
08:27lvhthere's a few things I'm writing that I'm pretty sure can be rewritten with reducers
08:27CookedGryphonif you open a new .clj file, it'll fill out your ns declaration for you too which is nice
08:31alewCookedGryphon: thanks for the tip
08:32lvhyep
08:32lvhmind blown.
08:32CookedGryphonif you think that's good, wait till I get round to updating latest-clojure-libraries
08:33CookedGryphonmy first foray into elisp, which unfortunately doesn't work at the moment thanks to the nrepl->cider thing
08:33CookedGryphonfor looking up and inserting teh latest version of a thing into your project.clj, then uses pomegranate to load it into your running repl with no restart if you want
08:42katoxanother dozen or so hours lost on a dynamic binding
08:43katoxreminds me dependency injection - it feels good at first ;)
08:55lvhhey
08:56lvh... wait, I just figured it out.
08:56lvhSorry :D
09:16steckerhalterit seems that using a ByteBuffer and then doing .putInt in a map does not operate on the original ByteBuffer? the ByteBuffer stays empty at least
09:18andyf_map is lazy. Try doseq around things that you want for side effects
09:19steckerhalterandyf_: ok, will do
09:20andyf_katox: binding and dorun/doall - 2 things that often go well together
09:22katoxandyf_: true enough, this time nil crept in sometimes though
09:45mikerodempty? is a fn; not-empty? is not a fn; not-empty is a fn ;= fn naming fail
09:45afhammadwhat am I missing: I am requiring [monger.core :as mg] within a namespace, however get this: java.io.FileNotFoundException: Could not locate monger/core__init.class or monger/core.clj on classpath
09:45afhammadI have this in my project dependencies: [com.novemberain/monger "1.7.0"]
09:46AeroNotixany httpcs to recommend?
09:46AeroNotixhttp-kit/aleph?
09:47mikerodmaybe `not-empty` was named like that, to make people hate it and just use `seq` instead
09:50gfredericksmikerod: not-empty? would suggest it's a predicate which returns a boolean, which would not be true
09:50gfredericks,(not-empty {:a 2})
09:50clojurebot{:a 2}
09:51gfrederickssimilarly we have some instead of any?
09:51gfredericks,(some #(when (pos? %) (inc %)) [-2 -1 0 1 2])
09:51clojurebot2
09:52mikerodgfredericks: that's fair enough, but it *should* be a predicate that is analogous to `empty?`
09:52gfrederickspresumably rhickey disagrees
09:52mikerodsome, is useful to not be a predicate; it can serve as a "get first" fn
09:52CookedGryphonugh, midje
09:52CookedGryphonsorry, that was meant to be qualified with a complaint :P
09:53quizdrsome can return more than just true or false, therefore it is not a predicate
09:53CookedGryphonmidje isn't reloading when i change my source, just when i change the test file
09:53CookedGryphonany ideas?
09:53mikerodI'm just coming from the standpoint of helping some people write some clj code. They don't quickly accept `seq` as a "not empty" check. They understand "empty?" of course, but then they always get confused when it comes to "not-empty" - no ? mark.
09:53mikerodI meant, new people to clj.
09:53mikerodanyways, just a little nit pick really.
09:54gfredericksclojure is a constant pile of confusion and surprises to new people
09:54mikerod:P
09:54mikerodfair enough
09:54afhammadgfrederick: yes it is
09:55gfredericksdocstrings are often helpful
09:55gfredericksit's nice that they're so integrated
09:55gfredericksrather than having to google to find them
09:56gfredericksI think I had the idea of curating a list of clojure gotchas before
09:58gfredericks,(doc not-empty)
09:58clojurebot"([coll]); If coll is empty, returns nil, else coll"
09:58jcromartiesomebody help me decipher net.cgrand.reload
09:58gfredericksdoes anybody have a solution for cleaning up resources associated with a ring response after the inputstream has closed?
09:58jcromartiewhere do the ::deps metadata come from? do I have to add that to the ns myself?
09:59jcromartiethe documentation in the README here is clearly insufficient https://github.com/cgrand/enlive
09:59jcromartieit just says call (net.cgrand.reload/auto-reload *ns*)
09:59llasramgfredericks: I just got a PR merged into ring which allow using the CollReduce protocol instead of a seq of strings
09:59llasramYou can reify that protocol with your own setup/cleanup surrounding the actual reduce behavior
09:59gfredericksllasram: I'm using cheshire; is there a way to combine those?
10:00gfredericksI guess if I serialized the top-level array myself...
10:00llasramgfredericks: I may have misunderstood. Do you have public code, or more details?
10:01llasramOoops -- gotta scrum. bbiaf
10:01gfredericksk
10:06gfredericksllasram: it's not public; I'm currently using piped-input-stream to start another thread that uses cheshire.core/generate-stream
10:07gfredericksI'm having trouble figuring out how CollReduce is useful at all, much less for my particular use case
10:07gfredericksI must be missing something
10:08clgvwhere is piped-input-stream from?
10:08gfredericksring.util.io
10:10gfredericksI had the impression that pjstadig's scoped library could help with this but then I read through it this morning and I don't think that's true
10:11mmitchel_stuartsierra: I'm looking at using your component lib for a new web app. Would you consider it to be stable enough for a prod app? Also, do you know who might be using it?
10:11clgvanyone used graphstream from clojure, yet? is it easy to use for visualization?
10:11mmitchel_stuartsierra: oh well, i see the README - alpha, beta etc :)
10:11stuartsierrammitchel_: It's quite simple, so yes I consider it stable. I am currently using it on a large client project.
10:11mmitchel_nice
10:12stuartsierraWhere "stable" means "doesn't have any obvious bugs."
10:12mmitchel_It does look quite simple +1
10:12stuartsierraBut I still reserve the ability to change the public API between 0.x versions.
10:17shep-homeIs there a way of telling if putting onto a core.async channel will block?
10:17tbaldridgeshep-home: no, but you can make sure it never blocks
10:18tbaldridgeshep-home: and you can use alt! with :default (or timeout) to do something else if it tries to block
10:18shep-hometbaldridge: thanks. I was thinking of something like a webservice that gets a request and puts it into a channel
10:19shep-homeit could be preferable to return an HTTP busy code right away, and not do the work
10:19shep-homeI think this is called backpressure, but I'm still learning my way around :-)
10:20tbaldridgeshep-home: yeah, use a channel with a larg-ish buffer and then do (alts!! [[c val]] :default :busy)
10:20tbaldridgethat'll instantly return :busy if the channel is full
10:20shep-homeYeah, that makes sense. I was looking at put, but couldnt see how that would help
10:20shep-homethanks!
10:20AeroNotixany httpcs to recommend?
10:22llasramgfredericks: Yeah, you'd need to change your code so that it somehow produces a "collection" of strings instead of writing to an input stream
10:30andyf_stuartsierra: I didn't look thoroughly, but does tools.namespace or any other lib you know implement a check that source file names and namespace symbols in ns forms are consistent with each other?
10:31andyf_stuartsierra: And if not, would such a thing be a useful addition to tools.namespace?
10:31stuartsierraandyf_: I'm not sure I understand the question. If ns forms don't match their files, Clojure won't even load them.
10:31andyf_stuartsierra: But someone can create them and get no errors
10:32CookedGryphonandyf_: in emacs clojure mode you can do (clojure-update-ns) which will replace it with the appropriate namespace
10:32andyf_stuartsierra: I am testing Eastwood on many projects, and sometimes I run across oddball things like this. They can be hard to debug the exceptions that get thrown
10:32CookedGryphonand clj-refactor automatically fills in the right one when you open a file
10:32gfredericksllasram: what's the advantage over a lazy seq?
10:33stuartsierraandyf_: Sounds like something for a linter like Eastwood to check, then.
10:33andyf_I am planning on adding an easy-to-understand message: Hey, this file contains a namespace foo.bar, but it should be bar.baz based on its name.
10:33andyf_stuartsierra: Oh, it will. I'm just asking if tools.namespace is a reasonable home for a function that finds such things or not.
10:34stuartsierraandyf_: Not sure. I'll think about it.
10:34hipsterslapfightexpress : node :: xxx : clojure ... is there an xxx?
10:35andyf_I have read an article about someone in academia who took a C lint tool commercial, and the crazy things they found out in the wild in real C code. I am starting to get a tiny idea of 1% of the stuff that they must have come across :-)
10:35tim__are there any tools like checkstyle / findbugs / pmd etc available for clojure?
10:36andyf_tim__: I do not know exactly what those tools do, but you may want to look at kibit and Eastwood, both on github
10:38llasramgfredericks: You can have set-up / tear-down code :-)
10:46tim__@andy_f thanks, they are exactly what i'm after.
10:47gfredericksllasram: where does the teardown code go? the edge-case is when the socket is closed so the whole thing doesn't get sent
10:53ambrosebsdnolen: do I have to maintain my own cljs.env atom when analyzing CLJS forms? And should I always initialise it by loading core.cljs with my env as cljs.env/*compiler* ?
10:53llasramgfredericks: The client socket? So like, your service is streaming a chunked response, and the client just closes the socket as some point?
10:53jitaIs IntelliJ good IDE for clojure programming ?
10:55saolsenjita: with the cursive plugin it's pretty great
10:55saolsenhttp://cursiveclojure.com/
10:55jitasaolsen: there is la clojure too how does it compare to that ?
10:55saolsenI use it a lot, especially if I have to do anything with java interop.
10:55blrmsaolsen: i haven't seen that, looks nice. i just knew of la clojure
10:56saolsenThis one is newer and I think they built it because of some frustrations they had with la clojure
10:56saolsenI haven't used la clojure though.
10:56locksfor some reason I was under the impression that cursive and la clojure were by the same people
10:57locksor at least people in common?
10:57saolsenthey might be
10:57saolsenI don't really know who's behind it
10:57locksthey changed the name to break backwards compat and etc
10:57jitasaolsen: cool, and when you are not working for java interop what do you use? emacs ;)
10:57locksthis is mostly guessing tho
10:57saolsenbut they're really good, super responsive on twitter and github issues and seem to ship a new version every week or so
10:58saolsenI bounce back and forth between emacs and cursive.
11:00llasramsaolsen: Have you tried eclim?
11:01saolsenllasram: nope, never heard of it
11:01llasramsaolsen: https://github.com/senny/emacs-eclim
11:01llasramEssentially runs Eclipse as a background service, then lets Emacs talk to it
11:04saolseninteresting
11:04saolsenis there clojure integration?
11:04jitasaolsen: do you use cursive plugin or IDE?
11:04saolsenthe ide isn't out yet
11:04saolsenjust the plugin
11:04saolsenand it's still in alpha so you have to add their repository
11:05jitasaolsen: does it work with intelliJ 13ce?
11:05saolsenthe site covers how to get set up
11:05saolsenjita: yep
11:05jitasaolsen: thanks
11:06llasramsaolsen: Oh, no. I misunderstood. It's definitely for writing Java from Emacs, which is for some reason is what I'd taken you to be talking about
11:10lvhmy tests appear to have hit an infinite loop.
11:10lvhhow do I stop them? I'm using run-tests in the repl
11:10arrdemmash C-g?
11:11lvhDoesn't appear to be working.
11:11clgvCtrl+C in lein repl
11:11kzarC-c?
11:11kzaroo too slow
11:11lvhnREPL connection closed: connection broken by remote peer
11:11lvhI think that means java gave up
11:11lvhmaybe?
11:12clgvlvh: killall -9 java ;)
11:13carkor more mashing on the box itself
11:14lvhhehe :)
11:14lvhif anyone has a second to give me some style advice, I think https://github.com/lvh/pairing/blob/master/src/pairing/core.clj#L81 can use plenty
11:14lvhpair-days is what I'm calling and what's doing what appears to be an infinite loop
11:14lvhmaybe it's actually just really really slow
11:15Anderkentwell, I don't see pair-days ever going out of the loop
11:15Anderkentit always recurs
11:16lvhah, yes, that would be bad.
11:16Anderkentpair-subgroup-days seems ok, one thing I'd do is put pairs and paired on separate lines in 0 and 1 cases, so that it looks exactly like the 2 case
11:16Anderkentbut it's a very minor issue
11:17Anderkentin pair-days you just want to check if you have any subgroups left, I guess?
11:17lvhyeah; I added the (if (seq
11:18jstewIf I have a collection [[1 2] [3 4]], what's a nice way to split them by column so that they're [[1 3][2 4]]? My solution is ugly, and I know there's an elegant way.
11:18lvhit appears that I always get [[] []] back from it though
11:19Anderkentthis is another super minor thing, but I prefer to have the terminating case first, since it's so short. saves scanning down to see what the other case is
11:19Anderkentcompare https://www.refheap.com/26994
11:19AeroNotixhttps://gist.github.com/AeroNotix/eecf8d63aa307381bfff anything more idiomatic than this?
11:19Anderkentlvh: do you know if pair-subgroup-days works? :P
11:20lvhAnderkent: Nope, writing tests
11:20clgvAeroNotix: there was a lib for byte array and such mentioned on the ML some time ago
11:20AeroNotixclgv: I was looking for something like this, decided to just start it myself.
11:21AnderkentAeroNotix: what's it trying to do, split a byte array into two around the first occurence of c?
11:22AeroNotixAnderkent: like string/split for byte-arrays
11:22Clomeis there a way to work with java primitives? A java fun returns an int, but in clojure I get an Integer object. Is there a way to tell clojure that I want a normal int.
11:23Anderkentwhy use BAIS instead of areduce?
11:23clgvAnderkent: +1
11:24AnderkentClome: you can tag the arg sometimes. But in general I'd accept boxed stuff most of the time
11:24Anderkentif you really need performance, look into https://github.com/ztellman/primitive-math ?
11:26ClomeAnderkent: A method in java returns an int, and then I use this int in a (case ) form which returns always the default, since integer is an object and it test the memory reference?
11:27AnderkentClome: that doesn't sound right, it should automatically unbox it if your case is int-based
11:28Anderkent,(case (Integer. 0) 0 :yes :no)
11:28clojurebot:yes
11:28AnderkentClome: ^
11:29ClomeAnderkent: it is not int based, since in the casess I use static java int fileds, but they too get boxed in Integers. Any easy solution?
11:30AnderkentClome: I don't follow. If your cases are ints (literal numbers) then it should be int based. can you post your code?
11:31clgvClome: no. the problem is that case needs compile time constants
11:32Anderkent('case' has three modes of operations - either ints, where it uses numerical dispatch, or keywords (where it's objects identity), or other stuff (object hashes)
11:32ClomeKeyboard/KEY_W here is an case example, which is a normal int but in clojure gets boxed in Integer
11:32clgvClome: the symbol which resolves to the static integer is no compile time integer constant
11:32AnderkentAh. That won't work, you need constants. Use condp
11:33clgvClome: there was a question on the ML recently. where someone solved it via writing a macro on top of case such that static constants are resolved
11:34Anderkentclgv: does marking a def as ^:const make it work with case?
11:34clgvAnderkent: never tried
11:34ClomeCan`t I for example say something like this (def ^:const ^int key-w Keyboard/KEY_W), so that clojure dos not box this int?
11:34lvhso, there's a thing I don't get
11:34lvhmap is lazy right? but when I put it in a repl expr, I see the full result
11:34lvhis it lazy, but being instantiated for the repl?
11:35Anderkentlvh: the map gets realized when the repl prints it
11:35Anderkentif you do (def result (map ...)) it won't be realized
11:35AnderkentClome: alas, I don't think you can
11:36clgvClome: well, easy enough to try and see
11:36AnderkentI think case won't even try to resolve symbols
11:36Anderkenti.e. if you say (case x foo :yes) it's checking if x == 'foo
11:36clgvmacroexpand-1 on the case-form might be handy
11:36Anderkent,(cse 'foo foo :yes :def)
11:36clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: cse in this context, compiling:(NO_SOURCE_PATH:0:0)>
11:36Anderkent,(case 'foo foo :yes :def)
11:36clojurebot:yes
11:36clgvah right^^
11:37Anderkentso you can't use symbols to refer to their values
11:37Clomeok, thanks
11:37clgvyou cant use lists either if I remember correctly. but vectors work since they are in the same equality partition
11:38clgv,(case '(1 2) (1 2) :yes :no)
11:38clojurebot:no
11:38clgv,(case 1 (1 2) :yes :no)
11:38clojurebot:yes
11:38AnderkentClome: in general. Don't use case unless you really need the performance of javas switch
11:38clgv,(case 2 (1 2) :yes :no)
11:38clojurebot:yes
11:38clgv^^
11:39AnderkentI suppose writing a macro that evaluates case args then produces (case) with literals shouldnt be that hard?
11:39clgvAnderkent: humm I think that statement is not true. case is compiled to jvm code using hashing
11:39Anderkentclgv: not for int or identity matching afaik
11:39Clomewhy did (case 2 (1 2) :yes :no) returned :no?
11:39clgvI'd think switch is a primitive jvm byte code op, is it?
11:39borkdudewhat is the fastest/easiest (not necessarily best) way of building a crud web app with datomic as storage nowadays?
11:39clgvClome: it did not ^^
11:39AnderkentI'm like 80% sure that (case x 1 :yes :no) compiles to switch
11:39clgv,(case 2 (1 2) :yes :no)
11:40clojurebot:yes
11:40Clomesorry, I meant :yes
11:40Clomewhy is that
11:40clgvAnderkent: switch with hashing I think
11:41Clomeshould not (1 2) return an error, since 1 is not a function
11:41Clomewhat am I missing here
11:42AnderkentClome: case is a macro, it gives special syntax. In there, a list means 'one of these elements'
11:42clgvClome: no. in `case` that's a notation fur alternative values that are matched
11:43Clomeoh right, sorry
11:44borkdudeI have used case exactly once
11:44borkdudeuntil now
11:45borkdude(* amount (case time :month 1 :quarted 3 :year 12)) something like that
11:45Anderkentclgv: so it's either TableSwitch or LookupSwitch depending on whether your keys are sparse or not
11:46AnderkentI can't excactly find where it's emited in the compielr though. ..
11:47clgvAnderkent: just compile a function with `case` and use a decompiler to look it up
11:49borkdudeAh, the amount of users has grown with about 250 since I last paid attention to it
11:49borkdudehere
11:51Anderkentclgv: https://www.refheap.com/27009 yep, tableswitch
11:54eyepatchI'm looking at (take-while #(<= % 4000000) (fib))) I understand the whole bit except for # and % I'm not familiar with those characters. Where could I look them up in docs?
11:55eyepatchObviously you could tell me what they mean in a few seconds. I'm guessing % is a replacement for some unknown value in a predicate that doesn't know what i'll work on and # will return the value of % when the predicate is true.
11:56eyepatchBut I'd be surprised if this was the last time that I ran into unfamiliar characters.
11:56borkdudeeyepatch it is the notation for anonymous functions
11:56borkdude,(#(+ % 10) 1)
11:56clojurebot11
11:56borkdudeeyepatch it's just fancy notation for ((fn [x] (+ x 10)) 1)
11:56llasram,`#(expando! %)
11:57clojurebot(fn* [p1__52__53__auto__] (sandbox/expando! p1__52__53__auto__))
11:57llasramA "reader macro", in the parlance
11:57Anderkenteyepatch: but yes, googling for special symbols is really hard
11:58Anderkenteyepatch: I recommend spelling out symbol names, so try for example "clojure hash symbol" or "clojure pound symbol" (depending on wehre you're from :P)
11:58gfredericksllasram: yes the client closes the socket in the middle; also some other server-side error could happen to interrupt
11:59eyepatchOut of curiosity where is do people say pound and where do they say hash?
12:00eyepatchSo it it similar to a lambda.
12:00llasramgfredericks: Ok. So with the CollReduce-based version, any error like that will cause an exception to be thrown within the dynamic scope of code you control
12:00llasramSo as the stack unwinds, you can perform clean-up
12:00eyepatchoh silly me, it was in the "clojure in 15 minutes" thing.
12:00eyepatchWhich is handy as a reference.
12:01eyepatchok. Everything makes sense now.
12:01Anderkenteyepatch: I think europe says hash, usa says pound?
12:01eyepatchoh, ok.
12:01Anderkentfor me pound is £ :P
12:01llasrameyepatch: What about senseless things? Do those now make sense?
12:01eyepatchI have the tendency to say British slang as an American.
12:01eyepatchllasram, senseless?
12:02llasramAnderkent: I say "hash" and am American
12:02Anderkenteyepatch: beause everything
12:02eyepatchOh. right. I didn't qualify everything.
12:02eyepatchHah, hah.
12:02Anderkentllasram: that's because you're a decent person!
12:02llasramheh
12:02Anderkenteyepatch: llasram: related: the only reason I use 7zip for everything is that it tells me 'Everything is OK' on each run
12:02Anderkentuplifting!
12:03eyepatchlol
12:04AnderkentAeroNotix: did you figure out how to do your split thing with areduce?
12:06AeroNotixAnderkent: sorry, no. I was updating my gpg key
12:06llasramgfredericks: The existing options for using a piped input stream or a seq are both fubar'd. With the input stream, nothing closes it, so your threat just fills the output stream buffer then blocks forever
12:06llasramgfredericks: With the seq option, you not only don't have any way of doing clean-up code, but
12:07llasramgfredericks: It turns out PrintWriter (which is what the servlet API uses) has this *insane* detail that it promises never to throw an exception after construction
12:07llasramgfredericks: So if the client connection closes, the ring-servlet loop just keeps pumping your seq into the void
12:11TimMceyepatch: Hash, pound, sharp, number, octothorpe.
12:11TimMceyepatch: Some of those are actually different characters, but they are all sometimes written as "#".
12:13lockslittle-jailcell-window-bar-thingie
12:15llasramI just know that it has to be called "hash" so that Common Lisp's "#|" syntax is "hash-pipe"
12:16lockspound pipe is… yeah.
12:18tbaldridge"hash-pipe" wow, I need to find a reason to use that phrase
12:19llasramtbaldridge: Write more Common Lisp?
12:19technomancythat's asking a lot
12:19tbaldridgeand seeing how the winds have changed in Colorado lately, I'm now much less likely to be arrested for using the phrase.
12:20llasramOh, yeah -- I guess smoking more marijuana would also increase your number of opportunities for that phrase
12:20locks"no no, I meant an ASH pipe. they vintage son"
12:21tbaldridgeI plan on using the phrase, not using the device the phrase suggests.
12:21llasramJust exploring the linguistic possibilities!
12:24lvhHi
12:24lvhhow can I do destructuring binding in my repl?
12:24gfredericks,(let [[a b] (range 10)] [b a])
12:24clojurebot[1 0]
12:24lvhI want (let [[x y] (f)]), except with keeping the names around
12:24lvhlike def
12:25gfredericks(defmacro defs [form expr] (let [syms (->> form flatten (filter symbol?))] `(let [~form ~expr] ~@(for [sym syms] `(def ~sym ~sym))))
12:25Anderkent(let [[a b] (f)] (def x a) (def y b)) :P
12:26gfredericksI think I left out a paren at the end there
12:26gfredericksbut that lets you (defs [a b] (range 10))
12:26Anderkent#clojurelastwords
12:26rasmustogfredericks: whoa, I've always assumed it wasn't safe to do defs like that, am I wrong?
12:26gfredericksrasmusto: in what respect?
12:26rasmustonot sure, for code reloading or something?
12:27gfredericksit just expands to what Anderkent suggested
12:27rasmustooh, maybe I was trying to "def" something in a function as a means of having a mutable variable
12:27Anderkentnon-top-level defs are discouraged, but as long as you don't do unsane things it's okay
12:27gfredericksoh yeah that's terrible
12:27Anderkentyeah exactly don't put that ina function
12:27Anderkentjust top level
12:27rasmusto(I remember asking about it before I knew a damn thing about clojure)
12:27rasmustos/clojure/fp
12:28gfrederickslooks like that defs doesn't cover map destructuring
12:29gfredericksdue to ##(flatten {:a [1 2 3]})
12:29lazybot⇒ ()
12:29rasmusto,(seq {:a [1 2 3]})
12:29clojurebot([:a [1 2 3]])
12:30lvhhm
12:30rasmusto,(flatten (seq {:a [1 2 3]}))
12:30clojurebot(:a 1 2 3)
12:30lvhhow can do I step by step debugging? there seem to be a bunch of articles on google with few currently usableconclusions
12:32rasmusto,(let [a [1 2 3], _ (prn a) b (map inc a), _ (prn b)] 'foo)
12:32clojurebot[1 2 3]\n(2 3 4)\nfoo
12:32rasmustois how I debug step-by-step
12:32rasmustolvh: probably not the answer you are looking for
12:33`cbpsuddenly I go back to python and I'm at a total loss on how to do recursive traversal algorithms without persistent data structures
12:34Anderkentlvh: debugging is pretty flaky still. Eclipse with counterclockwise can somewhat do it
12:34clgvlvh: you can do that in counterclockwise
12:34AnderkentI usually just deftrace
12:34rasmusto`cbp: use += on mutable lists (and then quit in disgust)
12:34Anderkentand write tests :D
12:35`cbpsys.setsetrecursionlimit(10000) # yeahhhhh
12:35TimMcI tried writing a Python program recently.
12:36mmitchel_what happened?
12:36rasmustohere's how I write python nowadays: ^I^I(range) # syntax error
12:36TimMcIt was going well until I had to figure out how to work with "unicode strings", and I was all http://replygif.net/i/310.gif
12:37mmitchel_lol
12:37mmitchel_that's the best
12:37rasmustoTimMc: use bytearray
12:37rasmustoer wait, no that's even more confusing
12:37Anderkent.. I've caught myself doing (. delegate callMethodStuff) while writing java ..
12:37`cbpunicode strings, the GIL
12:37`cbpthe spanish inquisition was in the habit of burning python books
12:38TimMcAll I wanted to do was to convert some strings to NFD, but nooOOOOoo
12:38lvhCool, I fixed it by using more REPL.
12:39rasmustolvh: how do you use the REPL, which environment?
12:39lvhrasmusto: cider
12:39rasmustolvh: cool, I liked what I used of nrepl.el, but I'm a vim guy personally :D
12:40lvhif anyone feels like giving a newbie code review, https://github.com/lvh/pairing/blob/master/src/pairing/core.clj#L81 could use some
12:40lvhparticularly the function on that line I think
12:40AnderkentI'm pretty happy with foreplay for vim
12:40Anderkentwait, it's called something else now isnt it
12:40Anderkentfireplace
12:40rasmustoAnderkent: fireplace, the public isn't ready for a plugin named foreplay
12:41`cbplvh: would you paste an example input/output please?
12:41rasmustowell, not until we've had a good dose of cider
12:41winkis there a better way to get a mimetype of an image than this? (nio.file.Paths/Files) http://www.rgagnon.com/javadetails/java-0487.html
12:45rasmustooh, I can't do :if-let in a for/doseq, right? should I nest another form?
12:46rasmustoor just a :let [blah (if ...)]] (if blah ...))
12:46`cbpyou can have a :let and you can have a :when that filters
12:48rasmusto`cbp: hmm, I have a var thats bound to either each thing in a seq of things, or just once to nil, I'm not sure if :when helps
12:51lvh`cbp: Did you see the test file?
12:52rasmustooh, I didn't know you could do ##(let [[a b] nil] [a b])
12:52lazybot⇒ [nil nil]
12:52`cbplvh: no I just saw your fn
12:52rasmusto##(let [[a b] '()] [a b])
12:52lazybot⇒ [nil nil]
12:53rasmustois this a lisp-1/2 thing about nil being an empty list of sorts?
12:55fredyr,(int 1.999999999999999)
12:55clojurebot1
12:56llasramrasmusto: "nil punning"; orthogonal to lisp-1 vs -2
12:56fredyr,(int 1.999999999999999)
12:56clojurebot1
12:56fredyr,(int 1.999999999999999999)
12:56clojurebot2
12:56noncomfredyr: magic
12:56fredyr^^ did you guys see this rounding thing on twitter?
12:56fredyri guess its a java thing
12:56fredyrbut im not really sure why
12:57aperiodicit's not a java thing, it's a fixed-point thing
12:57`cbp^
12:57Wild_Catwhat rounding thing?
12:57`cbpdoes the same thing in most languages
12:57llasramrasmusto: In CL, `nil` *is* (`identical?` to) the empty list. In Clojure, the seq API is to *treat* `nil` as an empty sequence
12:57Anderkent,1.999999999999999999)
12:57clojurebot2.0
12:57fredyroh right
12:58Anderkentit worked with that paren, wat
12:58`cbp,(
12:58clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
12:58fredyron twitter it was
12:58metellus,213354908fdjk
12:58clojurebot#<NumberFormatException java.lang.NumberFormatException: Invalid number: 213354908fdjk>
12:58fredyr,(nth [1 2 3 4] 1.9999999999999)
12:58clojurebot2
12:58fredyr,(nth [1 2 3 4] 1.999999999999999999)
12:59clojurebot3
12:59rasmustoah yeah, saw that
12:59fredyrwhich threw me off a bit
12:59rasmusto,1.999999999999999999
12:59clojurebot2.0
12:59rasmustoah ok, it's just a cast-to-int thing
12:59Wild_Catmore like IEEE floating point oddity.
12:59fredyryeah
13:00rasmusto,(nth [0 1 2 3] 1.999999999999999999)
13:00clojurebot2
13:00Wild_Catand not JVM-specific, for that matter.
13:00rasmustoillustrates it a bit more clearly
13:00fredyryeah ofc its for any ieee floating points
13:01fredyr(dec fredyr)
13:01lazybotYou can't adjust your own karma.
13:01fredyr:s
13:01Wild_Catfunny how even when aware of the IEEE floating point imprecision thing, I always tended to assume that they were always erring downwards
13:02Wild_Cat(that is, that the number you get is always <= to the literal you typed)
13:02Wild_Catwhen there's no such guarantee, as we just saw.
13:02Wild_Catand I should have known better.
13:02strijkijzerSo ehh
13:02strijkijzerPeople here don't hate a lisp-like syntax but like it more I assume?
13:03fredyrlol
13:03BullSherdWow, Google is making really strange things http://goo.gl/YEkaMA
13:03BullSherdfunny haha xD
13:04`cbp~guards
13:04clojurebotSEIZE HIM!
13:04strijkijzerfredyr, are you laughing at me?
13:04Wild_Catstrijkijzer: kinda hard to like Clojure and hate the Lisp syntax at the same time
13:04Wild_Cat...although as far as I'm concerned, I like *Clojure*'s syntax -- that is, I find all the additions it made to the Lisp syntax great.
13:05`cbpI like it the most because of stuff like paredit
13:05Wild_Catsimple stuff like vector, map and set literals make it so much more readable.
13:05`cbpand paredit + multiple cursors = yes plz
13:05fredyrstrijkijzer: sorry, but yes it is a reasonable thing to assume, that lispers don't hate lisp
13:05strijkijzerfredyr, maybe they see it as a lesser evil.
13:05strijkijzerSyntax is typically the last concern for me to judge if I like a language, I can get around bad syntax if the semantics are sound.
13:05strijkijzerLike, I hate Haskell syntax but apart from that the langauge is fine.
13:06Wild_Catstrijkijzer: bad syntax is hard to get around.
13:06strijkijzerSo I was wondering if maybe people see the lisp like syntax as a lesser evil or something?
13:06`cbpbad syntax is I have to google for how to write the stupid thing but oh guess what the whole thing is ungoogleable
13:06strijkijzerWell, it's one of the least important parts of programming language design insofar that most languages just re-use the same syntax that was used before and slightly modifiy.
13:06Wild_CatI liken it to typing on an uncomfortable keyboard -- sure, you can do it, but it always gets in the way.
13:06strijkijzerTHere are basically 3 big syntax families in use. C-style, Lisp-style and ML-style.
13:07strijkijzerBut apparently people don't see it as a lesser evil
13:07technomancyyou can tell when someone's new to lisp; it's the people who aren't totally keen on homoiconicity
13:07strijkijzerI hear a lot from people that they don't like it though which confuses me.
13:07strijkijzerIt's not as much the homo-iconicity that I like as much as the consistency and simplicity and explicitness.
13:08Wild_Catstrijkijzer: I can see how "bare" Lisp syntax can be a pain. I mean, like I just said, I don't like it when a language goes too far in the minimalism direction.
13:08strijkijzerIf you see something like x %% y *# z in Haskell you're just going to guess what the praecedence is.
13:08strijkijzerHmm, I don't like "special rules" too much.
13:08Wild_Catvector/map/set literals make Clojure far more readable than most Lisps I've been exposed to.
13:09strijkijzerLike ehh, in Haskell, a year back I was trying to define a (..) operator for double function composition (.) is single function composition, turns out I can't do this because it has [n..k] syntax which is basically (range n k)
13:09Wild_Cat...for that matter they make any language that has them more readable.
13:09strijkijzerI really wonder why on earth [n..k] is necessary, surely range n k suffices?
13:09Wild_Cat(yes Java, I'm glaring at you)
13:10Wild_Cat(and I'm also glaring harder at C++ which doesn't even have *string* literals)
13:12strijkijzerWild_Cat, well, the point is it is arbitrary in languages which allow you to define arbitrarily complex new algebraic datatypes.
13:12`cbpstrijkijzer: for the same reason you need to put a comma between every item in a data structure
13:12strijkijzerYou can't define new datatypes in clojure can you?
13:12strijkijzer`cbp, what is that a reply to?
13:12Anderkentstrijkijzer: define datatype. defrecord might be what you want?
13:12Wild_Catstrijkijzer: new datatypes as in new literals, or as in new data structures?
13:12`cbpsyntax that seems to be designed for people that write with pen and paper
13:13Wild_Catbecause if it's the latter, you absolutely can.
13:13`cbpstrijkijzer: the [n..k] thing
13:14strijkijzerWild_Cat, well is it possible in clojure to create a myList whose interface in every way is identical to the current list
13:14jitaWhich is better ide eclipse or intellij idea ?
13:14strijkijzeror a my-vector.
13:14Wild_Catstrijkijzer: sure.
13:15strijkijzerWild_Cat, ah I wasn't aware of that.
13:15strijkijzerAnd this runs with the same performance internally?
13:15Wild_Catstrijkijzer: it's even necessary to be able to do that, due to the fact that Clojure interops with Java
13:15`cbpstrijkijzer: it's usually best to write high performance data structures with java
13:15`cbpthen write a clojure wrapper
13:16strijkijzerWell, I'm asking about the possibility.
13:16Wild_Catstrijkijzer: I'm guessing the performance will be inferior because Clojure's vector is implemented in Java at a lower-level.
13:16strijkijzerAt least, my point with loads and loads of special syntax for data structures is that it's arbitrary.
13:16strijkijzerI think (vector a b c d) suffices for [a b c d] really.
13:16Wild_Catstrijkijzer: of course it is. But that's not a good enough justification to not add in literals for the most commonly-used data structures.
13:17tbaldridgeWild_Cat: the funny thing is, the java version of vectors is almost exactly like what Clojure would spit out if you used deftype, protocols and type hinting.
13:17Wild_Catthe square brackets jump out at me, making it easier to identify the vector.
13:17Wild_Cat(likewise {} for maps)
13:17tbaldridgeWild_Cat: so there may not be a performance difference at all.
13:17strijkijzerWell, at one point this does some pretty convoluted things wityh the language syntax, OCAml definitely has this problem that the language syntax deifnition becomes too overloaded because of all rthis and typos often result in it not becoming bad syntax but something you didn indend.
13:17Wild_Catespecially when you take into account the fact that Clojure uses vectors and maps *a lot*.
13:18technomancyocaml's precedence rules =(
13:18llasramRaynes: ping
13:18RaynesHello, this is Raynes.
13:18llasramRaynes: https://github.com/Raynes/bultitude/commit/68491b281a5de760fc44e087fffdca2e03b2ef6b
13:18Wild_Catstrijkijzer: language design, at that point, becomes a matter of taste and restraint: how many special cases do you add?
13:18llasramTHe `(second form)` -> `form` commit changes the public interface
13:18llasramIs this known?
13:19Wild_Cat(that's an open question that every language designer will answer differently. I think Clojure hits a sweet spot, or pretty close to one)
13:19Wild_Cat(I also think Python hits another one)
13:19Raynesllasram: The commit specifically states that it shouldn't break existing functionality. If it does, then I will promptly release a new major version and beat Grayson up.
13:20RaynesAnd by 'promptly' I mean at like 10PM tonight PST.
13:20Raynes:P
13:20llasramI'm confused why no one has noticed until now, because it breaks the Leiningen test, but yeah -- `ns-form-for-file` used to return just the ns symbol, but now returns the full form
13:20strijkijzerWild_Cat, well yeah, obviously it's super subjective.
13:21strijkijzerIf I designed a syntax, I would probably make numbers default to hexdecimal and read from lefty to right.
13:21teslanickAre there any guides for building an om/clojurescript app side-by-side with a clojure app?
13:21strijkijzerNote that we currently read numbers from right to left ina script that coes from left to right
13:22llasrams,the Leiningen test,a Leiningen test,
13:27fredyrteslanick: do you mean with a clojure backend or something?
13:28teslanickfredyr: Yeah. With the possibility of logic-sharing across the two stacks.
13:29fredyrteslanick: ah right, i haven't seen anything with om/cljs to that end
13:30fredyrteslanick: but there has been alot of buzz about cljx for code sharing between cljs and clj lately
13:32teslanickInteresting, thanks!
13:36llasramRaynes: To clarify, you are planning on bumping the version vs restoring the old interface, yes?
13:36llasramWell, I guess bumping w/o restoring vs bumping + restoring
13:40AnderkentFWIW, the change makes sense to me, and something like 'ns-symbol-for-file' could be added for the old functionality
13:41llasramAnderkent: Yeah, I don't honestly care. I just want to fix Leiningen in a way that won't need to be changed again right away :-)
13:41Anderkent:D
13:41Anderkent(let [ns-sym (if (symbol? ns-form) ns-form (second ns-form))]) ex!
13:41Anderkent*ez!
13:41Anderkent:P
13:42gfredericks(cond-> ns-form (symbol? ns-form) (second))
13:42gfredericksor the other way
13:43llasramBetter, but I'm looking for a social solution :-)
13:49Raynesllasram: Bumping the version number.
13:49RaynesThe change was necessary for a Leiningen feature
13:49llasramRaynes: Awesome
14:03DomKMIf you were going to read SICP, On Lisp, Lisp in Small Pieces, and Let Over Lambda, in what order would you read them?
14:03DomKMThat's the order I'm reading them but I'm interested in what someone who has already read them thinks
14:04jcromartieI'd read half of SICP first, then give up, and then do the same with the rest in any order you'd like.
14:04jcromartie:P
14:04jcromartiethat's just what I've done
14:04DomKMlol
14:04deadghostI have a terrible tendency
14:04deadghostto stop reading books half way through
14:04deadghosthalfway is enough for me to be dangerous
14:04deadghostthen I go be dangerous
14:05deadghostand say I'll go back to finish eventually
14:05deadghost(hasn't happened yet)
14:07DomKMyeah that's a distinct possibility
14:09jcromartieyou usually get your dopamine hit (for me, when SICP demonstrated how you can build any data structure with closures) about halfway through these books
14:12fredyri've never found let over lambda particularly engaging, so never gotten far
14:13tbaldridgeDomKM: to be honest, in the older lisp books, the lisp being used is so primitive, I wonder if it's worth reading those before the Clojure books.
14:13tbaldridgeI went back and read some Scheme code the other day, and my reaction was "why on earth would you code this way...oh yeah, you don't have types, or literal hash maps, or immutable vectors or....."
14:14bbloomtbaldridge: i'm trying to write some C right now... my brain hurts
14:14bbloomtbaldridge: but it's not the memory management or the low level anything...it's just like... wait... why the fuck are structs in different namespaces from other types?
14:14DomKMtbaldridge: I've already read most of the clojure books, I consider these readings to be more foundational than instructional
14:14bbloomand how come i can't add a new namespace without prefixing symbols?
14:15tbaldridgebbloom: what are you writing?
14:16bbloomtbaldridge: all kinds of fun/terrible stuff :-P
14:19deadghostis there a list of cool stuff written in clojure I can peruse?
14:20Anderkentdeadghost: https://github.com/trending?l=clojure ? :D
14:21deadghostthat works
14:22deadghostthough I'm looking more for a whole project than libraries
14:22Anderkentright, don't know about that, projects by nature don't get as much visibility
14:24AnderkentI mean I guess it depends on what you'd call a project. Maybe just read through sources of tools that you can use? lein, lein plugins (cloverage! except code be ugly) etc.
14:24Anderkentbut in general reading sources of real projects is not actually that constructive
14:25deadghostAnderkent, I was more looking for the purpose of hyping myself up
14:25deadghostlike FUCK YES CLOJURE
14:25Anderkentoh
14:25llasramCode in a non-library project is just code you don't expect to be able to reuse :-)
14:25deadghostCLOJURE!!!1!!11!
14:25Anderkentright, and because you don't expect to reuse it and just want to get shit done it tends to not be as pretty :P
14:25Anderkentdeadghost: I dunno, lighttable?
14:25Anderkentis pretty cool
14:26algernondeadghost: core.logic, kibit are two things that are jawdropping (and are reasonably understandable)
14:26Anderkentcore.async is pretty cool too
14:26algernonalso, overtone. never forget overtone and what Sam Aaron does with it.
14:26deadghostoh right
14:26deadghostI've been meaning to play with overtone
14:37lvhHi :) if anyone is willing to scan some newbie code and give feedback, I'd be much obliged: https://github.com/lvh/pairing/blob/master/src/pairing/core.clj#L81
14:44carklvh: a cursomary glance, and it looks quite neat
14:44lvhcark: Cool! Thanks :)
14:45carklvh : tho i personally prefer being a bit more explicit about the data
14:45stompyjJust want to canvas the community here, for those running clojure web apps, whats your deployment vehicle? immutant? jetty + apache, jetty + nginx? beanstalk/
14:45lvhcark: How do I do that?
14:45Anderkentlvh: the one thing I've mentioned before - I'd swap around the order in if statements, so that you don't have to scan through 15 lines to find the else clause
14:45carklvh : I like having constructor functions for my data
14:45llasramstompyj: jetty in an uberjar fronted by apache right now. Want to move toward immutant though
14:46stompyjllasram: any reason why apache over nginx? I only ask because I haven't used apache in so long, I'm curious if there's something I'm missing there
14:46lvhcark: Ah. I have not done that yet because the data will be coming from gnlary csv data so I will need to write an explicit munging layer :)
14:46carklvh : and let it be known that i disagree with Anderkent =)
14:46llasramstompyj: And these are all internal Web service -- nothing public facing
14:46lvhAnderkent: Sorry I missed that before
14:46llasramstompyj: Because we have tiny team who all knows how to make Apache dance :-)
14:46lvhAnderkent: So (if (not (seq x ...?
14:46stompyjllasram: haha, fair enough
14:47Anderkentlvh: (if-not
14:47lvhoh, I didn't know about if-not
14:47stompyjllasram: how do you deploy?
14:47carkdon't do that ><
14:47carkit's harder to understand
14:47Anderkentstompyj: the one clojure webapp I've used was on aleph, which I believe is powered by netty. Then just pushed as an uberjar to heroku
14:48Anderkentcark: how come it's harder to understand?
14:48llasramstompyj: jenkins builds .deb packages and pushes them to an APT repo, from where puppet then deploys them
14:48stompyjllasram: wow
14:48carkAnderkent: negation is harder on the brain, at least I think it is
14:48Anderkenthuuuh
14:49AnderkentI'm so confused right now but I'll accept that you don't like negation
14:49llasramstompyj: What sort of "wow" was that? :-)
14:49Anderkentfor me (if-not (seq)) is completely idiomatic and automatically parses as 'empty seq'
14:50Anderkentand having the short branch first makes it much easier to scan the code
14:50Anderkentindentation's not reliable over 20-lines
14:50carkahwell that's a fine point anyway
14:50AnderkentI suppose the other solution is to just pull out the long body into a helper fn
14:50bhaumanconfused about how to determine if an instance implements a Protocol in cljs
14:50carkcan't do that with the recur
14:50stompyjllasram: it was a "another deployment strategy I've not heard of yet" wow
14:51stompyjllasram: I've been working in ruby since 2004, and .NET/Java before that... so while I 100% love clojure, I'm still trying to find the right level when it comes to deployment
14:51llasramstompyj: It was inspired by this: https://hynek.me/articles/python-app-deployment-with-native-packages/
14:51Anderkentbhauman: satisfies? protocol object) I think?
14:52stompyjthe ruby in me tells me just to deploy via beanstalk / heroku. But the old enterprise programmer in me wants to invest time in immutant or jetty and do a ansible deploy, etc
14:52bhaumanAnderkent: thanks will try that :)
14:52Anderkentllasram: I did something similar in python but only because we had a 2gb dependency (xelatex)
14:53carklvh : The one thing I don't like is that the shape of your data is not directly apparent. But on the other hand the code is neat. So if it works with you it's all good
14:53llasramstompyj: Yeah, it depends on your use-case. If I were starting from scratch for a public service on cloud infrastructure, would probably do it entirely differently
14:54llasramAnderkent: I did it because we have stuff in Python, Ruby, and Clojure, and our previous system was a mess.
14:54bhaumanAnderkent: thanks, that bit of basic knowledge goes a long way. And now I see it there on the protocols page.
14:54Anderkentyeah, got it
14:54Anderkentbhauman: no worries, pretty used to googling stuff for people ;>
14:55llasramAnderkent: Following the same model for everything got deployment entirely automated, and with atomic packages using the language-appropriate tools
14:55bhaumanAnderkent: I google the crap out of that and it just wasn't surfacing for me
14:55NotteHi, is it possible to have a function with two vector parameters that destructures the second one into head (which i don't care) and tail?
14:56jcrossley3llasram: when the time comes, we'd like to help get debian init scripts hardened for immutant, too.
14:56cark(defn vecs [vec1 [h & tail]] ...)
14:56bhaumanNotte: ^
14:56rasmusto,(let [a [_ & tail] [[1 2 3] ['foo 4 5]] [a tail])
14:56clojurebot#<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>
14:57Nottecark: thanks. I was writing it wrong.
14:57llasramjcrossley3: I have to confess that I personally just use runit :-)
14:57rasmustowhoops, missed something
14:57rasmusto,(let [a [_ & tail] [[1 2 3] ['foo 4 5]]] [a tail])
14:57clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: let requires an even number of forms in binding vector in sandbox:>
14:57jcrossley3llasram: cheater ;)
14:58lvhcark: Would a defrecord fix that
14:58carklvh : don't sweat it. Your code is idiomatic enough. What matters most is to get the product done !
14:59Anderkentbhauman: my query was 'clojure implements protocol' FTR, which brings up clojure.org/protocols, which mentions extends? and satisfies?
14:59bhaumangenius!
15:00esanchollasram: do you use something like Rundeck to orchestrate deployments with puppet?
15:01llasramesancho: Not yet, but we just finally got an ops person who knows this stuff, and he's got plans
15:01Anderkentqueue evil sysop laugh
15:01llasramesancho: For now we just have our internal packages set to be 'latest' and do an `apt-get update` (against internal repos only) on each run
15:02danneuWhat's a good way to create a config.edn file that lets you change things on the fly in production? slurp + a ttl cache?
15:04lvhis there a refactoring lib that can rename a function across a project
15:04lvhclj-refactor.el
15:04lvhI have that; but it only has file renames.
15:06esanchollasram: gotcha, the tricky part is when you need to orchestrate deployments across multiple servers... I'm working on something similar right now and it was funny to read about it in #clojure
15:07llasramesancho: Ah, yeah. That's rare enough for us that it's still manual. Perfect, enemy of the good, etc :-)
15:09stompyjllasram: back, catchingup
15:10stompyjllasram: I might wimp out and go with clojure to start. the thing is that I want to use fluentd or something like that to capture pretty detailed logging events, etc
15:10stompyjllasram: and if I decide to do apache / jetty, then I need to build a chef script that deploys all that stuff (chef is what we currently use), but what I really want to do is use ansible,
15:10stompyjIm being wishy washy atm :)
15:11llasramYou can only find better ways by trying new ways, but you can only get stuff done by doing things which work. Always a dilemma!
15:13stompyjyeah, its further complicated by the fact we are 85% done with this project, and we have about 3 months before it has to launch
15:13stompyjso lots of naval gazing time
15:13stompyjif I don't keep myself on track
15:13stompyjheh
15:17gfredericksI'm seeing some spooky dependency resolution involving lein plugins
15:17llasramSpooooooooky
15:20stompyjllasram: another question, do you guys write tests? and if so, which lib are you using
15:21llasramstompyj: For deployment?
15:21stompyjoh no, TDD type testing
15:21Anderkentmidje for functional tests, junit for integration
15:21stompyji'm using midje right now
15:21stompyjas well
15:21dima_any quick ideas on how to get lein work with some java code using "lombok"? lein pom; mvn compile works, lein compile and lein javac fail with ClassNotFound for "com/sun/tools/javac/processing/JavacProcessingEnvironment"
15:21gfredericksproject has dep [A 2] and plugin [C 1] -> [B 1] -> [A 1]
15:22stompyjI'm finding that unit tests aren't as important due to the functional nature of clojure + the repl
15:22llasramstompyj: Oh, we use clojure.test for all our Clojure testing.
15:22llasramWe used midje for some Cascalog projects, because of midje-cascalog, but the level of magic got too intense for me
15:22llasramPlus my experience is that the way midje wants to run tests when compiling a namespace cramps the typical Clojure workflow
15:23stompyjllasram: Anderkent: thanks
15:23Anderkentllasram: yeah thats why our facts are deftest wrapped ;p
15:23Anderkentmy pain with midje is mostly that factoring stuff out is really hard
15:23Anderkentbecause fact is a macro, you cant just call a function that makes some assertions
15:23llasramAnderkent: I remember trying that and running into some sort of issue -- don't recall exactly what
15:23stompyjdo you guys have any experience with mocking out third party services in midje? This is the one thing I can't wrap my head around re: tests
15:24Anderkentstompyj: if you have a clojure api for them, just (provided (third-party/request :arg1 "foo") => {:response :body})
15:24gfredericksoh I think this is speclj's fault somehow
15:25stompyjAnderkent: that makes sense. then where do you stick all the gnarly responses? inside the test suite itself? or do you load them from a file? currently I have a bunch of (def something <INSERT GNARLY JSON HERE>)
15:25stompyjI will say, I've only ever done TDD in ruby (and a smidge in C#) so outside of the ruby world, I have a ton of "where does this go" questions
15:26eggheaddnolen: am I correct in my observation that om doesn't support lists (only vectors) ?
15:26ddimanobody? :/
15:27Anderkentstompyj: so you probably want to separate this into two layers. One that transforms the gnarly responses into nice data structures. In there you can just put the model responses in test-resources and load from file
15:27Anderkentthen on the business layer you just mock your interaction layer and return maps with whatever you expect
15:27stompyjinteresting. makes sense
15:28stompyjtest/resources is an idiomatic clojure directory structure for such things? (I've never heard of it)
15:29AnderkentI believe it's test-resources in lein
15:31Notte,(do (defn t [coll1 [_ & coll2]] (cond (and coll1 coll2) 0 (and coll1 (not coll2)) 1 :else 2)) (t [] []))
15:31clojurebot1
15:32NotteWould anyone explain me why is it happening, please?
15:33Notte,(true? (and [] (not [])))
15:33clojurebotfalse
15:33edbond,(not [])
15:33clojurebotfalse
15:34edbond,(and true false)
15:34clojurebotfalse
15:34edbond,(true? [])
15:34clojurebotfalse
15:34RickInAtlanta,(if [] true false)
15:34clojurebottrue
15:34edbondNotte, ^^^
15:34Notteow
15:35eggheadNotte: because coll2 doesn't exist?
15:35logic_progis there a way in clojure code to say: "fire off a nrepl at this point" ?
15:35logic_progi.e. a nrepl which has (1) the local environments, (2) I can evaluate forms, and (3) pick a value to return?
15:35eggheadNotte: why do you expect coll2 to exist?
15:36egghead,(and [] (not nil))
15:36clojurebottrue
15:36Notteegghead: i don't know. Sorry.
15:36eggheadNotte: it's the way destructuring works, if it can't find a match it binds 'nil'
15:37Notteok
15:37Nottethank you, edbond and egghead
15:37eggheadif you have [] as your data and [_ & x] as your match, then it will try to break [] into first and rest, binding x to rest
15:37eggheadif you try to get (rest []) you get nil
15:38eggheadhope this helps Notte
15:39Nottei'll remember it
15:40gfrederickswhen a lein plugin has :dependencies, those should never get on the app's classpath, correct?
15:41eggheadhopefully gfredericks are you seeing otherwise?
15:42hiredmansome plugins will inject things in to the projects deps
15:44gfrederickshiredman: this one doesn't obviously
15:44gfrederickshttps://github.com/slagyr/speclj/blob/2.9.0/src/leiningen/spec.clj#L23
15:44gfredericksI am seeing otherwise
15:44gfredericksabout to post a minimal reproducing project
15:46gfrederickshere it is: https://github.com/fredericksgary/bad-deps
15:46gfredericksactually this is quite weird because it's one plugin causing another unrelated plugin's dep to be used
15:47gfredericks`lein deps :tree` does not pick up on this
15:48danielglausergfredericks: did you try `lein shadowdeps :tree`?
15:48danielglauser:)
15:48gfredericks:P
15:49gfredericksmigratus-lein is a plugin that depends on migratus which depends on an old java.jdbc
15:49gfredericksspeclj is a plugin that runs tests
15:50Anderkentgfredericks: when I try running that project I can't even `lein with-profile speclj repl`
15:50gfredericksAnderkent: what's it do?
15:50Anderkentcrash saying nrepl is not on classpath
15:50gfredericksme too; I wonder why
15:51gfrederickssomething about how with-profile works maybe
15:51gfredericksall that profile does is change the :test-paths
15:52Anderkentcrazy. that's even if I remove the plugins
15:52gfredericksyou should be able to avoid with-profile by setting test-paths at the top level and using `lein spec`; but then `lein test` won't work for normal reasons
15:52gfredericksI think you're describing a different [non-]problem
15:52sdegutisQuick design question. I have a macro that basically does (if ~condition (do ~@body) (handle-error)) and I want to replace it with non-macro code. But I'm finding that `body` is often multiple things, so I need to wrap it in (do), which can look a little ugly inside an (if) but can't be replaced with a (when) on account of the else-clause. What would you do in this case?
15:53llasramsdegutis: Just use the macro
15:54gfredericksso where is the classpath actually constructed?
15:57gfredericksleiningen.core.classpath probably
15:58Anderkentgfredericks: yeah, you get both jdbcs on your classpath with that profile
15:59gfredericksAnderkent: how did you figure that out?
15:59Anderkentprinted out the classpath from main
15:59Anderkent:D
15:59sdegutisllasram: hmm, that's one idea, but I can't help feeling like it's non-idiomatic to have (with-some-effect some-arg ...) in my code.
15:59Anderkent(println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))
16:00gfredericksgood to know
16:01sdegutisThis macro mainly exists to hide a (do) and the else-clause, and I'm not sure that's a good enough reason for it to be a macro.
16:01gfredericksAnderkent: wait are you doing that without running the spec task?
16:01gfredericksAnderkent: I get the normal deps using `lein with-profile speclj run`
16:02gfredericksat least it prints the normal version
16:02Anderkentno, I mean with the spec task
16:02Anderkentso I assume it's the speclj plugin messing things up
16:02gfredericksright
16:03gfredericksI can't figure out how though because it seems like the task gets to eval-in-project pretty quick without touching anything weird
16:03Glenjaminthe speclj plugin does something really odd
16:03Glenjamini ran into this the other week, 1 min
16:03sdegutisgfredericks: why did you choose speclj?
16:03gfrederickssdegutis: I didn't
16:03gfredericksam debugging for a coworker
16:04Glenjamini chose it because i like the RSpec test spec style
16:04Anderkentgfredericks: but the speclj plugin adds spelcj to your classpath somehow right?
16:04AnderkentI don't see where it happens but it must
16:04Glenjaminin a recent version of speclj they stopped using a second jvm process
16:04Glenjaminand ran tests in the lein process itself
16:04gfrederickswaat
16:05Anderkentthat'd do it
16:05Glenjaminyou can fix by adding ":speclj-eval-in :subprocess" to your project.clj
16:05Glenjaminhttps://github.com/slagyr/speclj/pull/67
16:05hiredmanhttps://github.com/slagyr/speclj/blob/2.9.0/src/leiningen/spec.clj#L33
16:05Glenjaminthats the one.
16:05Glenjamintook me a good hour or so to track down
16:06sdegutisWow.
16:06sdegutis(re: the pull request)
16:06gfrederickshuh
16:06Anderkentgfredericks: so you basically want a dependency on speclj instead of :plugins speclj
16:06rasmustoi had nil pudding for lunch
16:06Glenjaminyou need both if you want to do "lein spec"
16:07sdegutis(inc rasmusto)
16:07lazybot⇒ 3
16:07gfredericksAnderkent: or both? how does `lein spec` work if it's not a plugin?
16:07Glenjamin"just run it in the same JVM to save 3 seconds" seems like a reasonable idea, apart from the part where it isn't
16:08Anderkentyou're right it's both
16:08Glenjamingfredericks: you need both so you can do lein spec, but adding ":speclj-eval-in :subprocess" should fix classpath weirdness
16:08AnderkentGlenjamin: actually it kind of is, but you want to fire off a new classloader
16:08hiredmanit is a plugin that runs code in the projects process, so it injects a speclj dep into the project
16:09GlenjaminAnderkent: i don't know enough about java/jvm to deal with classloaders, but i would love to be able to run stuff with siloed dependencies
16:09Glenjamindefeat callback hell and all that
16:09Glenjaminsorry, dependency hell
16:09gfredericksI'm having trouble getting this to work after adding :subprocess
16:09Glenjamingfredericks: when i ran into the issue, it was because speclj and lein itself clashed on some dependency
16:10pcnAre there libraries that make file handling easier? I'd like something that implicitly manages a file using with-open, and provides an split. And that buffers reads and writes.
16:10Anderkentlein trampoline was a thing wasnt it
16:10Glenjaminlein trampoline is a funky hack
16:10Glenjaminthe lein shell wrapper reads a file that the lein jvm left behind and execs it
16:11Glenjaminbut shouldn't make a difference vs subprocess
16:11gfredericksGlenjamin: thanks for figuring this out :)
16:11Glenjamingot it working?
16:11Anderkentah. I thought trampoline was reusing the same process, just doing classpath magic
16:11Anderkentbut I guess it's not
16:12hlshipCuriousity: when extending a protocol onto Clojure maps, it seems like you could extend APersistentMap, IPersistentMap, or even Associative. What is the best choice, or what do you need to consider to make a choice.
16:14gfredericksGlenjamin: no but I'm not surprised it doesn't work anymore :)
16:14Glenjaminhttp://www.flyingmachinestudios.com/programming/lein-trampoline/ : "How Clojure Babies are Made: Leiningen's Trampoline"
16:14Glenjamingfredericks: downgrading to speclj 2.8 is probably not unreasonable
16:14AnderkentGlenjamin: yeah I found it now
16:14Anderkentgfredericks: I got it to run tests, it just crashed on checking the exit code ;p
16:14AnderkentI'd raise a bug with speclj
16:15Anderkentmake them worry about it
16:15Glenjaminyeah, i might see if they'll change the default back - it doesn't seem like a good idea
16:15gfredericksyeah I saw the exit code thing too
16:15Glenjaminthe solution to slow jvm startup with speclj is to use --auto
16:15gfredericksso leiningen has a feature where if you say :eval-in :leiningen it... how the hell does it get your normal dependencies in that case?
16:15Anderkentas to classpath isolation, yeah, I'd like a nice thing for it too
16:16Anderkentright now I'm also sharing the classpath with environment project in my plugin (cloverage)
16:16llasramgfredericks: That's intended for plugins and the like, for the plugin code itself. The speclj plugin doing this is totes counter-purpose
16:17Anderkentthe current idea to fix it is to switch to subprocess evaluation, but that means I have to make intrumentation produce files rather thane val things, and bleh in general
16:17technomancygfredericks: :eval-in :leiningen turns :dependencies into :plugins
16:17Anderkent*than eval
16:17technomancyeffectively
16:17gfrederickstechnomancy: how does it do that after the process has already started up?
16:17Anderkenttechnomancy: does it attempt resolution or just takes project classpath and appends it to current one?
16:18technomancygfredericks: pomegranate classloader tricks
16:18technomancyAnderkent: it does a new resolution
16:18Anderkentthen a duplicate classpath entry is probably a bug there
16:19Anderkentoh unless it did a new resolution, got a differnt version... Can you remove things from classpath?
16:19OscarZi have a vector x of maps and i want to return the same vector but without a specific map that i can find with (apply min-key :value x).. whats the best way to do this? probably something simple that im missing again :)
16:19Glenjamingimme 2 mins i can tell you what i conflicted on...
16:20AimHereOscarZ, filter sifts a collection by a predicate
16:21technomancywow wait... speclj runs project code in leiningen by default?
16:21OscarZoh i thought i tried filter.. so predicate like #(not= y %) should work ?
16:21technomancy._.
16:21Anderkenttechnomancy: yep, because it saves 3 seconds!
16:22AimHereOscarZ, well that's one example of a predicate
16:22technomancyhttp://p.hagelb.org/10no.gif
16:22AimHereYou'll have to craft the appropriate one for your problem!
16:22Anderkenttechnomancy: https://github.com/slagyr/speclj/pull/67 go and post that there :
16:23Glenjaminright, yeah
16:24Glenjaminthe problem I had was speclj wanting a newer version of clj-stacktrace than the one that leiningen had already loaded
16:24Glenjaminwhich was resolved by telling it not to do :eval-in :leiningen
16:25AnderkentI mean okay, what they did before was also insane
16:26Anderkentthey spawned off their own jvm
16:26Anderkentrather than using eval-in-project
16:26technomancypretty weird
16:26Anderkentyeah I don't even
16:26technomancyhttp://p.hagelb.org/comfort.jpg
16:27AnderkentHow many pics do you even have there. Damn you for not having an index
16:27sturnerAnyone familiar with http://www.prismtech.com/opensplice and worked with DDS in general from Clojure?
16:27technomancymwahaha
16:28gfredericksI bet he has an emacs function that searches his images directory to make sure he gets the url right
16:29gfrederickshe can send a gif url in an avg of 4 keystrokes
16:29technomancyI've stopped trying to save keystrokes since getting a mechanical keyboard
16:29Anderkenthe just has a mapping from emoticones to gifs on outgoing text
16:29technomancysince each keystroke is so crisp and satisfying
16:29technomancyI no longer want to minimize that feeling
16:30seangrovetechnomancy: Is there a way to specify host on the command line when starting a repl?
16:30bbloomtechnomancy: aw yeah, mmm mechanical. love it
16:31technomancyseangrove: LEIN_REPL_HOST I think
16:31technomancybbloom: cherry MX blues; I heart them so much
16:31jkjsteampunkical keyboard
16:31teslanickkeyboard nerds are the worst. ;)
16:31pcntechnomancy: you must have your own office. I had to take away the keyboard from an intern when he got one a couple of years ago.
16:31Glenjaminwow, this speclj task stuff is really weird now
16:31Anderkentpcn: there are silent mechanical switches
16:31pcnOooooh.
16:31seangrovepcn: My coworker made me give up the kinesis for the same reason
16:31bbloomtechnomancy: kenesis man myself
16:31Glenjamini'm gonna have to dig in and see if i can make this sensible again
16:31technomancypcn: https://secure.flickr.com/photos/technomancy/tags/laboratory yeap
16:31Anderkentoh sorry didnt see cherry mx
16:31seangrovetechnomancy: That did it, thank you
16:32technomancyit's not an office; it's a laboratory =)
16:32Glenjaminthere's one guy in our office with a mechanical
16:32pcnThat's nice.
16:32Glenjaminlucky for us he's a manager now, so doesn't type much
16:32technomancyseangrove: psh; the kinesis is silent compared to this
16:33pcnWhere'd you get the desk from?
16:33alsois it normal for leiningen to give the error "Checksum validation failed, no checksums available from the repository" only the *first time* the dependency is fetched?
16:33technomancypcn: ikea jerker, I think
16:33seangrovetechnomancy: You could just wire your keyboard to play machine-gun fire sound effects whenever you're typing if you're going for a visceral, loud effect
16:34teslanickWhat's the idiomatic way to loop over something with an incrementing index? loop/recur?
16:34AimHereYou want to *feel* the machine gun effects too
16:34gfredericksGlenjamin: coworker pointed out that `run -m speclj.main` works
16:34Glenjaminheh
16:34Anderkentteslanic map-indexed ?
16:34technomancyseangrove: supposedly having audio feedback in the switch itself can help train you to reduce force to the exact amount required for activation rather than bottoming out every time
16:34Glenjamingfredericks: it's possible to use in a repl too, but a bit fiddly
16:34pcnAh, they don't make taht any more
16:34technomancynot really something you can do in software
16:35technomancypcn: I think they just renamed it
16:35teslanickAnderkent: thanks. don't know how I didn't see that.
16:35Anderkentthat's okay
16:38pcntechnomancy: I think it's dead and gone. The replacements aren't reputed to be as good.
16:39logic_proghas ritz been ported to cider, or is it still nrepl only?
16:39technomancypcn: ah, shame
16:39technomancybig fan of standing desks
16:41Raynestechnomancy: Can you tell that Python tooling frustrates me? https://www.refheap.com/27051
16:41technomancyRaynes: my deepest condolances
16:42bbloomvirtualenv is a massive pain
16:43technomancy"at least it's not rvm"
16:43seubertvirtualenvwrapper is fine..
16:43bbloomugh.
16:43RaynesWell, my problem is that virtualenv.el expects me to just have a single directory for all my envs.
16:43RaynesI'm fine with virtualenv.
16:43bbloomdoesn't python have PYTHON_PATH or something?
16:43RaynesIt's also not gonna matter because Python has replaced it in core.
16:43Raynespyvenv yo
16:44Anderkenttechnomancy: +1
16:44Anderkentunless you were being sarcastic
16:44RaynesPresumably at some point people will grow nads and switch to Python 3 across the board...
16:44bbloommeanwhile, plan9 got this right however long ago: union directory mounts > various virtualenv nonsense and PATH variables
16:44Glenjamindoes it handle multiple pythons, or does it still just do different package loading dirs per app?
16:44sdegutisI think Take Me Out should be the official Clojure song, it epitomizes everything Clojure's about, from FP to abstracting sequences: https://www.youtube.com/watch?v=Ijk4j-r7qPA
16:46pcnRaynes: python 2 won't dissappear until all of numpy and scipy work
16:48Anderkentpcn: it won't dissapear from enterprise even then
16:48Anderkenthttp://www.robg3d.com/?p=1175 etc.
16:49gozaladnolen: tbaldridge do you have little bit of time I have some questions in regards to core.async
16:50pcnSure, but by the same token once you only have it in enterprises, it's dead.
16:50tbaldridgegozala: sure
16:50rasmusto:<
16:50rasmustothat's not true of humans, is it?
16:51pcnMy recollection of being in big enterprises is that all learning stopped when I walked in the door
16:51logic_progtbaldridge: if I want uber clojure debugging tools, do I want ritz or cider?
16:52logic_proghttp://www.youtube.com/watch?v=sA5zOLCa3Xw <-- anyone know a link for this talk, where, starting at 11:25, the slides aren't suffering from parallax ?
16:53tbaldridgelogic_prog: there really isn't a good debugger for clojure. You can use JVM debuggers if you want. Most people just get comfortable with smaller functions and the repl
16:53tbaldridgenot to mention that the Clojure compiler does some stuff that makes debugging with a debugger really hard. For example it clears locals after its done (so the data in the locals can be GC'd)
16:54gozalatbaldridge: I’m trying to wrap node IO libs for cljs
16:54logic_progtbaldridge: so the notion of "when an exception happens, fire me up a repl (1) with access to local vars (2) lets me evaluate forms and (3) pick what value to return" is not part of stadard clojure workflow ?
16:54gozalaand expose channel based APIs
16:54logic_progtbaldridge: the compiler argument makes sense
16:54tbaldridgelogic_prog: no, and I'm not even sure such a tool exists for clojure
16:54gozalatbaldridge: one thing that I çant figure out is what’s idiomatic way to report and handle errors
16:55technomancygetting access to locals is not that tricky if you set the point beforehand
16:55technomancyhttps://github.com/technomancy/limit-break
16:55gozalatbaldridge: two options I considered were
16:55tbaldridgegozala: what I recommend is having a dedicated "error" channel. Report exceptions to that channel and have that channel log them or something.
16:55technomancylogic_prog: the difficult part is a stepping debugger
16:55gozala1. Make apis that return records with output channel and error channel
16:56sdegutistechnomancy: ffvii!!
16:56gozala2. Make Error protocol an put them on the same result channel
16:56sdegutis<3
16:56logic_progtbaldridge , technomancy: this makes sense, I can see how this is easy in "interpreted scheme" but hard in "clj compiled to java"
16:56technomancysdegutis: necessarily
16:56sdegutisoh?
16:56technomancylogic_prog: the other thing is you have to be in pretty deep in the guts of some nasty stateful code to actually need a stepping debugger in clojure
16:57technomancydue to referential transparency everywhere
16:57logic_progtechnomancy: I can't belive limit-break is just 32 lines of code: https://github.com/technomancy/limit-break/blob/master/src/limit/break.clj
16:57technomancylogic_prog: it's pretty, errr... limited
16:57Anderkentbadumtsss
16:57danneuI'm just faking it til I make it with my VPS. If I start a datomic-pro SQL transactor on a remote server, then my local peer connects to the jdbc connection with <remote-ip>:4334 (default port), right?
16:57gozalatbaldridge: ok the only inconvenience is that then I end up with ton of APIs that return two channels and on each read one needs to alt! between error and data
16:58gozalatbaldridge: I felt like it would be nice to have something built-in
16:58technomancylogic_prog: however, its simplicity makes it good for understanding what's really at the core of locals-inspection and possibly building something better from that, should anyone be so inclined
16:58technomancyhint hint
16:58logic_progtechnomancy: yeah, exactly why I'm reading it beacuse it's more instructional than production quality
16:59gozalatbaldridge: another question was on how would one communicate back
16:59logic_progtechnomancy: is there a good nrepl tutorial somewhere where I can play with integrating limit-breka into repl-y, instead of only with stdin repl>
16:59technomancysdegutis: dang now you got me listening to http://ff7.ocremix.org
16:59Anderkentlogic_prog: reply can do standalone, i think?
16:59technomancylogic_prog: unfortunately afaik the details are scattered
17:00technomancybeyond just the nrepl readme I mean
17:00gozalatbaldridge: what I mean is let’s say (fs/read path) returns a {:output (chan) :error (chan)}
17:00gozalatbaldridge: what if consumers want’s sot stop reading from output at some point
17:00gozalatbaldridge: Ideally file descriptor should be closed
17:01gozalatbaldridge: but how should one communicate intent that it’s done consuming channel
17:01gozalatbaldridge: I guess what I’m asking for is something like (take-while p c)
17:01tbaldridgegozala: the problem is that the person reading from the channel is very rarely able to do something about the error.
17:02tbaldridgegozala: have you read Joe Armstrong's papers on this sort of thing
17:02logic_progtbaldridge , technomancy : I am considering spening today + weekend studying ritz. Is there anything I should know before hand? (Or is this even a good investment of time -- are there known flaws with ritz?)
17:02gozalatbaldridge: I have not (do you have a link by a chance)
17:03sdegutistechnomancy: dang now you got me listening to https://www.youtube.com/watch?v=LfB3aEOWAlk
17:03gozalatbaldridge: sure reared will rarely handle errors
17:03gozalatbaldridge: but in my frp lib for example I had an error type
17:03technomancylogic_prog: the main complaint is that it's difficult to set up and get working, and it's incompatible with cider. I haven't tried it myself.
17:04tbaldridgegozala: the first part of this paper is good: http://www.erlang.org/download/armstrong_thesis_2003.pdf
17:04gozalaso values put on signal if they of error type would thread through high order functions
17:04tbaldridgeit follows the actor model, but many of the ideas work well in core.async
17:04gozalaand there were functions like catch that could be used to handle those casess
17:05sdegutistechnomancy: True story, this is the playlist that runs 8+ hours a day for me: https://www.dropbox.com/s/zyf3814c2tey0oh/bahamut.png
17:05gozalatbaldridge: I’ll take a look at the paper
17:05technomancysdegutis: there is no shame
17:06sdegutisAlso I designed that app. I think like 3 people know it exists.
17:06gozalatbaldridge: I think it would be good to have some examples with suggestions on how to handle this kind of stuff though
17:07RaynesI swear by pebble for wrist notifications, but I've gotta say, the notification load of this new job and bitemyapp's tweets is going to cause my arm to be perpetually vibrating.
17:09gozalatbaldridge: also how about the other question of letting reader communicate with writer that it’s done
17:10tbaldridgegozala: when its done it normally will just close the channel.
17:10gozalatbaldridge: so you mean reader should (close! input) ?
17:10gozalatbaldridge: is that observable for the writer ?
17:11gozalatbaldridge: so that it could close error channel and free up resources ?
17:11teslanicksdegutis: That's a handsome music player
17:11sdegutisteslanick: thx. src: https://github.com/sdegutis/bahamut
17:12tbaldridgegozala: yeah, if you're looking for resource type stuff, then yes, there probably needs to be a 2nd channel involved that the writer alts over. When the "shutdown" channel is closed it frees the resources and exits.
17:12tbaldridgebut it's hard to say without seeing a usecase
17:12NotteWould you help me with this function? http://hastebin.com/minuxibira.lisp It should return a lazy-seq of tuples
17:13NotteI don't get why i can't realize it even with doall or similar
17:13gozalatbaldridge: how would you implement (fs/read path) ?
17:13gozalatbaldridge: assuming that content maybe large and there for you would wanna stream it
17:14gozalatbaldridge: that’s basically what I’m trying
17:14jstewIf I have a collection [[1 2] [3 4]], what's a nice way to split them by column so that they're [[1 3][2 4]]? My solution is ugly, and I know there's an elegant way.
17:14alandipertNotte: you can use the fact that map takes n colls and do something similar with (map vector colls...), eg
17:14hyPiRionjstew: (apply map list ...)
17:14hyPiRion,(apply map list [[1 2] [3 4]])
17:14clojurebot((1 3) (2 4))
17:14jstewwow... very nice!
17:14gozalatbaldridge: I can put my current code somewhere if you want to take a look
17:14hyPiRioneventually (apply mapv vector ...) if you want them on vector form
17:15jstewclojure is so elegant. My solutions thus far haven't been as sexy as they can be. Thanks :)
17:16Nottealandipert: i thought about it, but i don't want pair like (a a), (b b)
17:16Nottealso i really want to understand what i'm doing wrong
17:16alandipertNotte: what's an example desired in/out?
17:16hyPiRionjstew: It comes with experience, it's hard at first if you've used imperative languages earlier :)
17:17Nottealandipert: (tuples [1 2 3]) ; -> [[1 2] [1 3] [2 3]]
17:17jstewIt's starting to click. I can write clojure, just not "good" clojure yet.
17:17Glenjamingozala: the node streams api is pretty well formed and offers approaches for most of the problems you just mentioned
17:18Nottejstew: what docs are you using?
17:18Glenjamini'm not sure channels alone are rich enough to be streams in the node sense
17:19jstewhyPiRion: Could you be so kind as to explain how that works? map list makes a list out of hte vector, but apply will do what in that context? I thought apply just sort of flattens a list so that it can be used as args?
17:19Glenjaminjstew: yup, it's like * in ruby or ptthon
17:20jstewNotte: docs for what?
17:20Nottejstew: to learn clojure
17:20Anderkentjstew: apply turns it into (map list [1 2] [3 4]). Map then takes the first element from each list, applies list to it (giving (1 3)), then does it again
17:20Nottei can't find much online, compared to other languages
17:20jstewNotte, 4clojure.org, clojure for the brave and true, and google code jam
17:20hyPiRionjstew: (apply map list [[1 2] [3 4]]) is just like (map list [1 2] [3 4]). Since map allow a variadic amount of lists, it works
17:21jstewGot it! Thank you both, Anderkent and hyPiRion. you;ve been helpful
17:21GlenjaminNotte / jstew http://aphyr.com/tags/Clojure-from-the-ground-up is good also
17:21technomancy(inc aphyr)
17:21lazybot⇒ 1
17:21technomancy...!
17:22technomancyI guess he's not on IRC much, but styll
17:22technomancystill
17:22Glenjamini suspect lazybot needs some spit/slurp
17:22hyPiRion(inc aphyr)
17:22lazybot⇒ 2
17:22hyPiRion$seen aphyr
17:22lazybotaphyr was last seen talking on #riemann 2 hours and 25 minutes ago.
17:22jstewtechnomancy: your nick looks familiar for some reason. Were you a rubyist in the past?
17:23technomancyjstew: hush not so loud
17:23jstewhah, knew it. :)
17:23insamniacIt looked familiar to me when I got here, but then I realized it was because of github.
17:23NotteGlenjamin: thanks
17:24rasmustotechnomancy += 1
17:24Glenjaminmutable state!
17:24technomancyhttp://thisotplife.tumblr.com/post/63360807823/mutable-data-structures
17:27AnderkentOTP?
17:27AnderkentOpen Telecom Platform? Seems weirdly specific
17:28ro_stdnolen: howdy
17:28technomancythe reference implementation of erlang is often called OTP
17:28Anderkentright. Didn't realize it's all about erlang
17:29AnderkentI guess that'll join security reactions and plt life in my rss reader..
17:30ro_stwhat does the t in PLT stand for?
17:31Anderkentyou know I thought it was theory, but now I figure itmight be a reference to racket?
17:33gozalaGlenjamin: node streams are like set of channels
17:33gozalaand they are far from ideal
17:33gozalanot to mention there’s no syntax support
17:33hyPiRionro_st: theory, theorists
17:33gozalathat’s why I’m trying to wrap them in core.async flavoured API
17:34ro_staha
17:34Glenjamingozala: i think it's worth exploring, but you'll need quite a few channels
17:34Glenjaminstreams form a pipeline, to handle backpressure correctly - they're actually more similar to Seqs than core.async i would say
17:35gozalaGlenjamin: Not necessarily there are two approaches
17:35gozalaone is more haskelly where you deal with different messages types with actual types
17:35gozalaor you use multiple channels
17:36gozalaI’ve done implementation of both approaches in js in a past
17:36gozalaand kind of prefer former
17:36ro_sthttp://this-plt-life.tumblr.com/post/36425247242/when-i-hear-of-a-lisp-success-in-industry this one
17:36Glenjaminin node nowadays it tends to be more common to define things as streams, and use pipe()
17:36gozalabut I’m not sure how well it maps to core.async
17:36Glenjamini'm unsure which of those categories it fits into
17:37gozalaGlenjamin: none, they basically have one channel in form of event emitter
17:37gozalaand event types serve as a channel / message type
17:37Glenjaminthe client-side examples i've seen from rich have been to attach a single channel to one event listener
17:37Glenjaminbut i can see how one channel would be simpler
17:38gozalaGlenjamin: I also think core.async has a lot more saner approach to IO coordination than node’s hard coded backpressuer
17:38Glenjamindo channels do backpressure?
17:38gozalachannel is sync point
17:39gozalayou can’t write until other end reads
17:39gozalaand you can make buffered channels
17:39Glenjaminright, yes
17:39gozalathat would allow to buffer
17:39Glenjaminso you probably want to work with the .on('readable') api
17:39Glenjamincan a channel be closed?
17:39gozalaGlenjamin: yes
17:40Glenjaminthen that fits a single channel pretty well, and you just have to deal with errors - i think i've caught up with where you started?
17:40Glenjamincan you make a channel throw?
17:40gozalatbaldridge so here is a code I’ve being working on https://github.com/Gozala/clojurescript.node/blob/master/src/node/fs.cljs#L149
17:40mmitchel_technomancy: For :repositories setting in project.clj -- Is there a way to provide a password for each :repository from the environment?
17:41gozalaGlenjamin: you don’t throw, but you can make (Errro. message)
17:41technomancymmitchel_: yeah, check out `lein help deploying` under "credentials in the environment"
17:42gozalaand reader can (if (error? message) (handle error) (do-something message))
17:42mmitchel_technomancy: excellent thanks!
17:42gozalatbaldridge: in this implementation I box errors in error type
17:43gozalarather than implying second channel for errors
17:43gozalaInitially I tried using two channels instead but felt a lot more hassle
17:44gozalatbaldridge: so net module actually uses two channel approach
17:45gozalabut as you can see from example on readme https://github.com/Gozala/clojurescript.node#examples
17:45gozalaAPI tends to become a lot more complex that way
17:46gozalathat’s why I’m leaning towards elm like approach of using types to distinguish data & errors
17:47gozalabut then map, filter and all high orders functions would ideally pass through errors otherwise user will need to do it manually
17:48gozalatbaldridge: another thing is that consumer is forced to handle errors since it’s on the same channel
17:49gozalawhile with two channel approach it felt like it’s easy to forget you to even handle error channel
17:49gozalatbaldridge: does any of my reasoning makes sense to you ?
17:53tbaldridgegozala: so this is a rare example where I'm going to recommend something I don't normally recommend.
17:54tbaldridge1) box errors and then write a macro that I prefer to call <?, this will create a take and if the value is a boxed error, then re-throw it.
17:55gozalatbaldridge: but don’t you think there should be something alike in core.async itself ?
17:55gozalaI feel like it’s not very exotic use case
17:56gozalamost of node APIs will have a same concerns
17:56gozalatbaldridge: what you suggest actually is very similar to what Task.js does
17:56gozalatbaldridge: http://taskjs.org/
17:57tbaldridge2) if you use the latest version of core.async >! now returns falsey if the put happens on a closed channel.
17:57tbaldridgeSo with that you can easily write a with-open macro that calls close! when control escapes the current block.
17:58tbaldridgeThat will allow the file reader to detect that the channel is closed and free up resources.
17:58gozalatbaldridge: but that means producer will have to waste one read until it knows no writes are possible
17:58gozalaideally it would happen prior to that
17:59gozalatbaldridge: also ideally producer will still confirm close
17:59gozalasince there still maybe an error on attempt to free resources
17:59tbaldridge gozala: why do you need to confirm freeing of resources?
18:00tbaldridgewhat are you going to do if freeing fails?
18:00Anderkentthat seems excessive. IF there might be an error, the producer should handle it
18:00Anderkentotherwise it's something you cant handle, so why tell the consumer
18:00tbaldridge(inc Anderkent)
18:00lazybot⇒ 5
18:01gozalatbaldridge: Anderkent I see your point, but freeing up resources may take a time
18:01gozalaso I feel like it’s awkward to pretend that it’s already closed
18:02gozalathat being said I don’t think it’s a big deal in my case so I can ignore it until I have a better use case
18:03gozalatbaldridge: Anderkent don’t you think suggested <? should just be a !<
18:04gozalaalthough to be honest I prefer handling cases via cond rather than catch
18:04tbaldridgegozala: that's an entire other argument, lol
18:05tbaldridgesee arguments over Go's error handling (or lack of it)
18:05gozalaspecially since error propagation is not that useful with async code
18:05AnderkentI do like cond over catch, but also prefer silent error propagation. I.e. monads!
18:05tbaldridgegozala: true, so it's not a bad idea to just box everything into a hashmap and then do cond on it.
18:05Glenjaminthe node core has a "if you subscribe to error you can have it, if you don't then i'll throw" - is there a parallel to be drawn here?
18:06gozalaAnderkent: tbaldridge that’s what I’m suggesting though
18:06tbaldridge{:op :more-data :value "4444"}
18:06gozalaif high order functions would just propagate errors
18:07gozalaGlenjamin: node has domains, and please don’t get me started on them
18:07tbaldridgegozala: well there's another argument to be made here. Let's say I have a chain of (-> read-file map filter map output-data)
18:07Glenjamindomains are awful
18:07tbaldridgeeach of those being a go block doing some processing
18:07Glenjamineven the core devs agree
18:08tbaldridgegozala: some would say that an error in any of those should cause read-file to close it's channel, map filter, etc then all close, propagating the close. Then report the error to a single reporting channel.
18:09gozalatbaldridge: I think it’s more reasonable to have another control structure to handle that
18:09tbaldridgeSo output-data alts on the error channel and the response. If the response channel closes without sending a response the error channel is read and that generates a 500, or something like that
18:09gozala(-> read catch map filter map …)
18:09gozalaor (-> read map filter map catch)
18:10gozalathat way user can decided where to handle errors and how
18:10tbaldridgegozala: this follows the erlang pattern of "let it die". When things error out you crash the entire request/response chain and report the error to a central channel.
18:10gozalathat how most reactive libs deal with that
18:11gozalatbaldridge: now that I think about it’s fine
18:11gozalait’s actually the same
18:11gozalaas long as you have something like catch control structure to deal with recovery
18:12gozalatbaldridge: so only diff is weather channel should be closed on errors or not
18:13gozalaI’d be fine with either option
18:14Glenjamini don't think you should be taking data off a stream that has errored, so i would vote for closed
18:15gozalatbaldridge: Anderkent so are there any chances to incorporate something like this into core.async ?
18:16tbaldridgelike what?
18:18gozalatbaldridge: like incorporate some error support
18:18gozalacatch style control structure
18:18gozalaand special handling of errors
18:18gozalawhich can abort tasks and report errors as you suggested
18:19gozalams rx has such catch like control structure
18:20tbaldridgethe problem is, this use case doesn't really fit well with how core.async is normally used. The idea behind core.async is to turn deep call stacks into linear data flows. This sort of error propagation doesn't really fit with that model.
18:20tbaldridgethe adaption of node.js to core.async is a very interesting use case, but I'm not convinced what we've come up with here is the best solution.
18:21tbaldridgeThe better route is something were we can add monitoring of go blocks. Erlang does this via supervisor trees, where you can say "if this block dies, kill me" or "if this block dies, let me know".
18:21gozalatbaldridge: to me core.async is lower layer to reactive programming like ms rx
18:22tbaldridgeThat allows you to turn your entire HTTP request/response chain into a single dataflow that will crash/cleanup if a single error occurs, which is exactly what you want most of the time.
18:23gozalatbaldridge: that’s fine too
18:23gozalabut some way to communicate errors is necessary, is kind of my point
18:23gozalatbaldridge: at the moment if producer has an error there’s nothing in core.async to support that
18:24tbaldridgegozala: sure there is, the producer sends an error to a channel. build whatever you want on top of that.
18:25tbaldridgeIt's a design decision for the library to not go any further than that. We don't want to dictate how errors should be handled.
18:25gozalatbaldridge: ok
18:26gozalatbaldridge: only issue with that is built in control structures won’t do anything on errors
18:27gozalaso libraries will have to build their own control structures to support errors
18:27gozalawhich may be ok too
18:28gozalatbaldridge: for example generators in JS sort of solve the same problems as core.async
18:28gozalabuth they allow user to throw in exceptions
18:29gozalaI kind feel this is what missing
18:29tbaldridgeIf I were building a node.js interface, I would probably sit and think for about a month on how I might want to handle exceptions. Should they be handled, by whom? Why do we need to handle exceptions, etc. When code starts to get ugly, I like to go back and re-think my assumptions. If the code doesn't "feel right" perhaps I'm wrapping the API in the wrong way.
18:30Glenjamini always thought that core.async was to solve the problem of decoupling bits of your application, and the callback soup was a handy side benefit
18:30Glenjaminthe problem with reading from a stream is that you are actually somewhat coupled to the stream's state
18:30gozalatbaldridge: I have being thinking about it for 2 years now :P
18:31tbaldridgeGlenjamin: agreed
18:31gozalastarted with https://github.com/Gozala/streamer
18:31gozalathen moved to https://github.com/Gozala/streduce
18:31Glenjaminthis is why Node.js has "evolved" a whole new set of libraries and abstractions around streams, separate from callbacks - it's still young and experimental
18:31gozalaand then to https://github.com/Gozala/elmjs
18:31Glenjaminbut there's people playing with lots of approaches
18:32gozalaplus explored all the other reactive things that came up like ms rx, elm
18:32dnolengozala: generators are even more low level than core.async, and you can throw exceptions in core.async too.
18:32gozaladnolen: how can producer of channel communicate error with a consumer ?
18:33dnolengozala: many ways exactly the same as generators
18:33gozaladnolen: I agree generators are more low level
18:33dnolengozala: generators don't dictate anything
18:33gozaladnolen: generators have g.next and g.throw
18:33gozalalater throws in exception into routine
18:34gozalahow one can throw in exception into go routine ?
18:34dnolengozala: yes really low level, you gotta do something different if you want to use promises + generators, or channels + generators
18:34Glenjamingozala: are you familar with caolan as in caolan/async?
18:35gozaladnolen: I really just want a channels, but with some error reporting support from the data producer side
18:35dnolengozala: as people have already said, dictating something is pretty unwise given differing needs for different applications
18:35gozalathere are some adhok ways
18:36dnolengozala: I've done error channels stuff and supervisor stuff, both are appropriate sometimes
18:36gozaladnolen: maybe seeing those examples would help
18:36dnolengozala: or try it yourself :)
18:37gozaladnolen: also adding some error reporting support does not prevents supervisor stuff I think
18:37gozaladnolen: I did that, that’s why I’m trying to get more input from people like you :P
18:39gozalaok I guess I’ll try to finish version with boxed errors on a channel & we’ll see from there
18:39gozalaGlenjamin: yeas I’m aware of async not a fan
18:39tbaldrid_gozala: also remember that core.async channels are multi writer, unlike rx which is (for the most part) single writer
18:40gozalatbaldridge: although you can mix multiple channels in rx so it’s really just defaults
18:40tbaldridgeImagine your surprise if you have two producers writing to a single map channel. One producer errors, and sends an error to map. Map then passes the error on and exits.
18:41tbaldridgeNow the 2nd producer tries to write but the other end is dead.
18:41Glenjamingozala: well caolan has been working on trying to implement decent map/filter/reduce type functions for node streams lately, and strugging with these same issues
18:41bbloomtbaldridge: the Rx source is available & i looked at it closely. i was like "holy crap. so much error propagation logic!"
18:41Glenjamini wasn't suggesting async.js was helpful for this problem :)
18:41gozalatbaldridge: tbaldridge other end maybe dead either way though no ?
18:42gozalaif consumer closed it’s end it’s kind of dead
18:42bbloomtbaldridge: Rx existed prior to async was in C# too, so there's tons of manual state machines. it's pretty horrific in hindsight
18:42eggheaddnolen: ping
18:42dnolenegghead: saw your question earlier, only associative data structures in the app state for Om
18:42gozalaGlenjamin: https://github.com/Gozala/reducers are monadic
18:42gozalaand they do work with node streams
18:43gozalaif you import https://github.com/Gozala/streduce
18:43eggheaddnolen: ya I didn't know that '() wasn't associative but [] was, I figured because you could *nth* on both of them
18:43tbaldridgegozala: actually, the core.async code in master is written to shutdown when the channel the writer is producing to is closed. So closing channels the the "idiomatic" way to terminate processes in core.async.
18:43gozalaGlenjamin: all of the back pressure etc is preserved
18:43eggheadom is awesome but I was so frustrated last night trying to figure out why om was saying my data wasn't a valid cursor :p
18:44dnolenegghead: i've documented this restriction in several places
18:44eggheadmy fault then
18:44gozalatbaldridge: sorry I did not quite got the last comment
18:44gozalayou mean idiomatic way to close channel is from producer side you mean ?
18:46eggheaddnolen: I see it now here: https://github.com/swannodette/om/wiki/Documentation#wiki-root -- I was just unaware that for example the result of 'map' isnt something that is associative
18:46eggheador the result of a for comprehension or something similar
18:46dnolenegghead: Clojure documentation says they return lazy seqs
18:47tbaldridgegozala: in the code in master, it's idiomatic to do it from either side. Both sides should be watching for the channel to close, and shutdown when it happens.
18:47dnolenegghead: other people have encountered this before, but there's not much I can do about it. I wan't to enforce associative data structures for future perf reasons.
18:49dsrx,(doc bean)
18:49clojurebot"([x]); Takes a Java object and returns a read-only implementation of the map abstraction based upon its JavaBean properties."
18:49eggheaddnolen: I'm not against the restriction, maybe the docs could be more explicit and say 'For practical purposes this means you can only use vectors and maps, but not lists or lazy seqs'
18:49dnolenegghead: sure can do that.
18:49gozalatbaldridge: is core.reactive is a thing ? maybe core.async is too low level for what I’m trying to do
18:50gozalatbaldridge: Asking because I noticed your repo
18:51tbaldridgegozala: oh, that repo is super old.
18:51tbaldridgeit predates core.async by a few years.
18:52tbaldridgegozala: as to my point, onto-chan is a producer that shuts down when the channel closes: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L615
18:52dsrx,(instance? clojure.lang.Associative (map identity [1]))
18:52clojurebotfalse
18:53eggheaddsrx: obvious when you know it :p
18:54rasmustodsrx: ##(associative? (map identity [1]))
18:54lazybot⇒ false
18:57Glenjaminis there a better way to get it back into a vector than just calling (vec) on the Seq?
18:57rasmusto##(associative? (mapv identity [1]))
18:57lazybot⇒ true
18:58Glenjaminaha
18:59rasmustoGlenjamin: assuming you're doing a map
18:59Glenjaminmm
18:59Glenjaminfound the related variants
19:00rasmustois there one for hash-maps?
19:00Glenjamin(mapv identity {:a :b})
19:00Glenjamin,(mapv identity {:a :b})
19:00clojurebot[[:a :b]]
19:02rasmusto,(let [a {:a :b}] (into (empty a) (map identity a)))
19:02clojurebot{:a :b}
19:02Glenjamin(into {} (map identity {:a :b :c :d}))
19:02Glenjamin,(into {} (map identity {:a :b :c :d}))
19:02clojurebot{:a :b, :c :d}
19:02rasmustoGlenjamin: hi5
19:02Glenjamino/
19:04Glenjaminwhich is basically what mapv does \o/ https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/clj/clojure/core.clj#L6232
19:05rasmustomine gives you back the same coll type that you started with, which might be useful? Maybe mapv is moreso because you know what you're getting out
19:05Glenjaminmapmap would be a rubbish name, i guess
19:05rasmustomashmap
19:06technomancymapmap would be a great name
19:06rasmustoyeah, map vs hash-map is a hard thing to explain
19:06Glenjaminadd it to core! that's easy to do, right?
19:06rasmustomapmap is a good name, assuming you're OK with map as a coll name
19:06technomancyin mapmap it's at least clear you mean both meanings =)
19:06rasmustotrue
19:06rasmustobut in which order?
19:07dsrxoh i know, call it collectmap[
19:07dsrx:p
19:07rasmustomapm, alternatively maph
19:08rasmustomaph.numeric-tower
19:08Glenjamini guess it's too late to rename Map to Dict :p
19:09bbloomGlenjamin: heh, i've had that thought too, but for some reason "dict" implies to me that the keys are strings
19:09bbloom*shrug* dunno why
19:09Glenjaminah, i can see that
19:09technomancy"Dictionary" is too many syllables
19:10bbloomtechnomancy: that's why python people just call them "dicts"
19:10technomancy"Dict" invites too many jr. high jokes
19:10GlenjaminMapping perhaps?
19:10bbloomfactor calls a map an "assoc"
19:11bbloombut i've found that awkward to say, since my brain reads "assoc" as a verb
19:11rasmusto(assoc (dict :a 1))
19:11bbloomassociation vs associate
19:11btcNeverSleepsHey all... I've got a question regarding the kinda "long" stacktrace, and this question and its answer: http://stackoverflow.com/questions/14297079/ ("Why are Clojure stacktraces so long?")
19:12Glenjamini blame the map function
19:12Glenjamini suppose they both do the same thing, so that's the main issue
19:12btcNeverSleepsIsn't the way the Clojure code (and Clojure Java code) decided not to use many checked exception a major reason for the long stacktraces?
19:13btcNeverSleeps(btw this isn't a criticism of runtime exceptions: I'm just asking if "doing without checked exception" is, or not, a big reason for long stacktraces)
19:13bbloombtcNeverSleeps: whether or not exceptions are checked has nothing (theoretically) to do with the length of a stack trace
19:13AnderkentbtcNeverSleeps: not really. it's just that because of its dynamicity (ww?) the stacks are necessarily deep
19:14bbloomhowever, in practice, checked exceptions tend to cause a lot of re-throwing and exception swallowing, both of which will shorten visible stack traces, but are generally a bad idea
19:14Anderkentand recursion doesnt help either
19:14Anderkentbbloom: eh, they just separate the stack trace into X (20 lines) caused by Y (40 lines) cause dby ...
19:14Anderkentunless you eat the cause in which case you're evil
19:14bbloomAnderkent: indeed
19:15btcNeverSleeps(semi-related): when you code in Clojure (on the JVM), are there any checked exceptions that can happen and that you'd then be forced to catch?
19:16bbloombtcNeverSleeps: no. checked exceptions are an illusion of the java compiler. they are not a JVM byte code feature
19:16btcNeverSleepsand what happens in Clojure if I do Java interop and use a Java method that, in a .java, would refuse to compile if I didn't catch the exception?
19:17bbloombtcNeverSleeps: only the java compiler checks exceptions. neither the JVM nor the clojure compiler checks exceptions.
19:18btcNeverSleepsso if the checked exception is thrown, I end up with a checked exception manifesting itself as a runtime exception?
19:19bbloombtcNeverSleeps: if by "manifest" you mean "be raised at runtime" then yes. if you mean "magically becoming a subclass of the RuntimeException class" then no
19:21socksynot exactly a clojure question, but does anyone know how to speed up infoq videos? Rich Hickey can talk quite slowly
19:21bbloomsocksy: use the extra time between words to reflect on what he's saying :-)
19:22bbloomrich isn't some awful professor whose class you skip and watch later at 2X speed just to make sure you know what's going to be on the test
19:23bbloomevery one of his talks are worth the time to watch and then some
19:23socksyI have the attention span of a gnat, and inevitably my mind starts to wonder and I end up having to rewind and watch the same sentence again and again. I don't get that when the video is sped up :)
19:24socksy*wander
19:24bbloomheh.... ok
19:24technomancysocksy: you can download infoq videos if you change your browser user-agent
19:24bbloomdoes it wonder to things related to what he's talking about?
19:25bbloomif your wandering mind is at least somewhat on topic, that's probably fine to rewind a bunch :-)
19:25socksyI'm not sure...
19:25socksytechnomancy: useful info, thanks
19:26btcNeverSleeps,(.getBytes "a" "non-existing-encoding")
19:26clojurebot#<SecurityException java.lang.SecurityException: denied>
19:29ivansocksy: there are three infoq downloaders, but none can put the slides next to the video
19:29ivanone can replace the video with the slides
19:29ivanhttps://github.com/cykl/infoqscraper https://github.com/mtayseer/infoq-downloader https://github.com/rg3/youtube-dl
19:37steckerhalterany idea why reading a file with (slurp "file.txt" :encoding "UTF-8") that contains one 4-byte utf-8 character prints a string with 4 characters?
19:40alxlitivan: infoqscraper can, get it from master
19:41ivansteckerhalter: maybe you've got a double-encoded UTF-8 file?
19:42alxlitivan: infoqscraper presentation download --type h246_overlay or something like that
19:43steckerhalterivan: not sure what double encoded means, but I created the file myself containg just that utf-8 character in 4 bytes
19:44ivansteckerhalter: does ls -l confirm that it's 4 (or 5) bytes?
19:44steckerhalterivan: yes, 4
19:44ivanalxlit: thanks. will try after I figure out the python 2/3 mess within
19:45steckerhalterxxd -b file >>> 0000000: 11110101 10100111 10111101 10110101 ....
19:46steckerhaltermaybe it just can't deal with 4 bytes or something?
19:49steckerhalterok, hmm... emacs displays one character, gedit says it's invald
19:49steckerhalterõ§½µ
19:50ivanPython says
19:50ivanUnicodeDecodeError: 'utf8' codec can't decode byte 0xf5 in position 0: invalid start byte
19:54steckerhalterwell, that is 0xf5 should be valid looking at https://en.wikipedia.org/wiki/UTF-8
19:55steckerhalters/that is//
19:58ivansteckerhalter: that table refers to some obsolete original design
19:58steckerhalterivan: yeah, it could be the restriction kicking in
19:59AeroNotixwhat can I do if I want to run a test suite with profiling enable?
19:59AeroNotixenabled*
19:59AeroNotixis there a plugin with lein test?
19:59AnderkentAeroNotix: what kind of profiling?
19:59Anderkenttimbre?
20:00AeroNotixAnderkent: memory, cpu, call tracing
20:00AeroNotixAnderkent: never used timbre
20:00Anderkentoh, some jvm agent?
20:00AeroNotixjvm agent?
20:01Anderkentwell, what are you going to use to profile it
20:01Anderkentthere's jvm profilers like yourkit etc
20:01AeroNotixok
20:01Anderkentthese work by attaching an agent ot the jvm, they will tell you what options to add to a process
20:01Anderkentthen you just pass these to :jvm-opts in lein
20:01AeroNotixgotcha, ok
20:01Anderkentor alternatively oyu can use a native clojure profiling lib like timbre
20:02AeroNotixThanks for the info
20:02Anderkentthat works by wrapping your code
20:02Anderkentno worries :)
20:02AeroNotixtimbre looks like it can do individual form profiling, which is cool
20:02steckerhalterivan: ok, got it, it's out of bounds after RFC 3629. thanks
20:04Anderkentsteckerhalter: yeah it says 'octet values c0 c1 f5 to ff never appear'. I wonder what purpose that has
20:06steckerhalterAnderkent: the limitation?
20:33akurilinIs it generally a poor idea to cache data on (def) calls because of the potentially varying order in which this can happen?
20:34akuriline.g. I have a very static table in the db which I want to cache into a var on my app's boot. Doing it in a def seems potentially risky.
20:35akurilinOr I guess not necessarily. Should I consider exporting this to some kind of "init function"?
20:44Morgawrhow would I test if a vector contains an element?
20:45MorgawrI could write my own function with empty? and filter but there probably is a function that does that...?
20:46arrdemwhat SQL layer(s) are people using?
20:46arrdemall I'm really finding is korman and java.jdbc..
20:48akurilinI'm using both. Korma for the boring crud or any time I need to translate something procedurally to a query, and cjj for complex queries.
20:55dee5What's the normal way of running a leiningen task in the background?
20:58hiredmandon't?
20:58dee5:(
20:59hiredmanif you want to run some lein uberjar up an uberjar and run that
20:59hiredmansomething
20:59dee5Alright thanks
21:16x^2im reading through the O'Reilly clojure book
21:16x^2and i understand a lot of the syntax of this now
21:16x^2but im just tryingg to better understand
21:16x^2does Clojure completely abandon the idea of anything object/struct like, and instead carry on through functions passing data to other functions?
21:16x^2or can anyone give me some insight on this
21:16x^2i am kind of reading through, and i understand how to do basic things
21:17x^2but i dont feel like i "get" the big picture on this yet
21:17x^2maybe someone here can shed some light on that
21:19dnolenx^2: there are object/struct like things in the language - but it's common to encourage people to not reach for them unless they really need it.
21:20hiredmandnolen: maps are used all the time
21:20hiredmanx^2: it depends what you mean by object/struct
21:21x^2i mean like
21:21hiredmangenerally clojure code tends to pass around values (immutable data) and call functions on them
21:21hiredmaner
21:21x^2enclosure of data basically
21:21hiredmancall functions with them as the arguments
21:21x^2i know about vectors and stuff
21:21x^2like
21:22x^2i feel i can write some very basic things right now
21:22x^2but i want to make them in the clojure way
21:22hiredmanyeah, so vectors and maps and seqs and functions
21:22hiredmanthat is how you do it
21:22x^2i dont want to be writing java or C++ using clojure if you know what i mean.
21:22x^2okay
21:22x^2this seems like a really wonderful language
21:22x^2i get bored reading about ones that are so similar
21:22x^2but all of these new ideas have me really excited
21:23x^2i am just trying to think of something now i could write to put the ideas of clojure to good use
21:23Morgawrtry writing a LightTable plugin :P
21:23Morgawrit's fun
21:23Morgawrand not that hard
21:23x^2im not sure what that is, and ive only written a couple very basic programs before. so i might want to start at something above a 'hello world'
21:23x^2but not much above
21:23x^2lol
21:23Morgawrhttps://github.com/mdhaney/lt-plugin-template <-- a template for LT plugins
21:24MorgawrLightTable is an editor written in Clojure (for clojure and other languages)
21:24Morgawrbut yeah, just get familiarized with the language, I guess a plugin might be too complex
21:24x^2ooo
21:24x^2yeah for now i think
21:24dnolenMorgawr: well ClojureScript :)
21:24Morgawrit's a pretty neat editor, really extensible, I'm loving it
21:24x^2i am developing using lein- do you think this is a good idea?
21:24teslanickI spent a few weeks banging around in LightTable just to get acquainted with the language.
21:24Morgawrdnolen: well, still Clojure :P
21:24teslanickLein is definitely the thing for development in clojure.
21:25x^2alright well im off to a start then lol
21:26x^2also - i have one question of logistics, i guess
21:26x^2in my lein project directory
21:26x^2or rather
21:27x^2let me start over: i have a directory called "hello" for a basic hello world project
21:27x^2and in the /src folder, i have:
21:27x^2i have a "hello" folder, with core.clj
21:27x^2that reads:
21:28x^2(ns hello.core (:gen-class))
21:28x^2(defn greet[who] (println (str "Hello " who "!")))
21:28x^2(defn -main[who] (greet who))
21:28x^2so obviously in this core.clj, i have one regular function and my main functio
21:28x^2n
21:28x^2how do people usually lay these things out in lein?
21:28x^2like would someone put a bunch of other functions and main in the core.clj?
21:28x^2or would they usually split it up into different files
21:29teslanickA file contains one (or sometimes more) namespaces. But a file contains the same namespace as the file name.
21:29s4muelLike that. Look at project.clj you'll see a :main entry. Usually you split up files by namespace, like example if you have a client server app you'd have (ns foo.client) and (ns foo.server) in src/client.clj and src/server.clj
21:29teslanickSo really you'd be dividing functions up across namespaces related to what they do.
21:30teslanickBy way of example, Clojure has clojure.core, clojure.string, clojure.zip, clojure.pprint, etc.
21:31teslanickWhere core has most of the common functionality, and each of the others have functions specialized to a particular task (strings, tree structures, and pretty-printing respectively)
21:32s4muelIndeedy. There's nothing preventing you from throwing it all in one giant file, either, per se. It is just a matter of style and organization. Take a look at some of the more popular libs to see how they are organized (or as teslanick points out, clojure itself)
21:32x^2YEhmmm, okay
21:32x^2i was going to do that, look at some of what is out there
21:33teslanickA lot of the popular libs are relatively easy to read; as you may have noticed, Clojure is very terse.
21:33s4muelOf course, file paths do come into play when you start adding test frameworks and working more with leiningen in terms of advanced build/compilation stuff. Depends, again, on what you're using.
21:34x^2yeah, that is all very confusing to me right now
21:34x^2now i would like to ask
21:34x^2for a beginning 'first' project, would it be okay to put everything (inluding main) in that core.clj and just work off of that?
21:35x^2for a relatively small project, of course
21:35x^2with just a few functions most likely
21:35teslanickYeah. You can break it up into namespaces later if it grows.
21:35x^2okay, cool
21:35teslanickI've been writing stuff in little clj files scattered across my desktop and copy them into my project when I think they're done.
21:36x^2so you just write them in separate clj files, put them in the same directory, and build?
21:36x^2(simplifying, of course)
21:39teslanickWell, I write a bunch of related functions and test them together, then copy the file into the project and give it a namespace.
21:39teslanickBecause LightTable doesn't care about projects, you can just live-eval stuff as you're working to build things incrementally. The amount of boilerplate necessary is basically nil
21:40x^2hmm, okay.
21:40x^2i do really like the REPL environment, too
21:40x^2it seems very cool.
21:45teslanickI should say that I'm very much a Clojure neophyte myself
21:46teslanickThe REPL is pretty neat, though the thing that gets me is connecting to a running application and manipulating its state as its operating.
21:48x^2i've heard you can do that
21:48x^2i have no idea how yet
21:48x^2but i have seen that as a feature of clojure
21:48x^2which amazes me
21:48x^2it must tie back to the 'code as data' idea, right?
21:49x^2in that you can just feed some 'data' (being code) into an application, and it is evaluated like anything else.
21:49teslanickAlso that mutable state is called out very explicitly.
21:49x^2oo
21:50teslanickAnd altering stateless components is relatively safe.
21:50arrdemif I wanted a doseq with a carry-forwards state that's for, right?
21:50arrdemsorry. loop/recur
22:02gfredericksarrdem: I have no idea what that means
22:03arrdemgfredericks: I was refactoring a doseq and realized that I really wanted an eager reduce, which is just for with some destructuring.
22:03arrdemgfredericks: that was as much me muttering to myself as anything :/
22:03mklappstuhlcurious how the parsing of namespaced function calls like (string/split ...) works in clojure
22:04hiredman parsing?
22:04mklappstuhlis the parse looking for a slash and than splitting the string?
22:04arrdemmklappstuhl: fully qualified symbols are written ns.sub-ns.sub-sub-ns/symbol
22:04hiredmanoh, how symbols are read?
22:04mklappstuhlhiredman: sorry — reading is probably more appropriate
22:05mklappstuhlah
22:05quizdrthis just blew my mind: #(reduce deliver f %&)
22:06mklappstuhlso basically if you use :require [clojure.string :as str] it basically maps str to clojure.str
22:06hiredmanthat has nothing to do with reading though
22:07hiredmanat read time foo/bar is just a symbol with namespace slot foo and a name slot bar
22:07gfredericksquizdr: what on earth is that useful for
22:07hiredmansame with str/foo
22:07hiredman,(read-string "str/foo")
22:07clojurebotstr/foo
22:07gfredericks,(read-string "doesn't/exist")
22:07clojurebotdoesn't/exist
22:07quizdrgfredericks it was amalloy's answer to a problem on 4clojure; I think pretty crafty. more elegant.
22:08x^2,(read-string "testfunc")
22:08clojurebottestfunc
22:08teslanickquizdr: What was the problem?
22:08gfredericksquizdr: ooh he must be taking advantage of the impl
22:08mklappstuhlhiredman: I guess my terminology was wrong
22:08quizdrimpl? what do you mean?
22:08gfredericksdeliver is supposed to be for promises but functions as a generic call function
22:08gfredericks,(deliver inc 42)
22:08clojurebot43
22:09gfredericks^ not what deliver is for
22:09quizdroh i see.
22:09gfredericksthere'd be no reason to even suspect it would do that without reading the source
22:09gfrederickswhich is what I meant by "impl"
22:09quizdrthe doc mentions it as "alpha" anyway and "subject to change" so probably not a good idea to depend on it as habit
22:09quizdr"impl" = "implementation" ?
22:09gfredericksno not for use in production 4clojure
22:09gfredericksyes
22:10quizdrit's amazing to see the paradigm shift among programmers on that site when reviewing others' answers. so many still use loop/recur with a single line alternative does the trick with 25% as much code. fascinating.
22:10quizdr*when a single line alternative...
22:11quizdrmy main take away from those execersizes is that the vast majority of the time, when I approach a problem with a loop in mind, strong liklihood there is a more elegant way instead.
22:11gfredericksyep
22:14bbloomquizdr: i frequently write loops then look at them and say "now what does that actually do?" before refactoring it
22:14bbloomsometimes, i know the algorithm & don't need laziness, but don't know what it is called until i *see* it
22:15mklappstuhlI'd love to see a blog that features small overly complex code snippets and then simplifies them reading that, quizdr
22:15teslanickSpeaking of which, is there any clojure-oriented code review groups out there? The clojure tag on codereview.stackexchange is pretty dead.
22:16teslanickI see the clojure a coworker can write, and I feel like Phillip Fry with a Holophonor
22:17insamniaclol
22:17insamniacyou're not alone
22:19ivanI can confirm that infoqscraper finally does the right thing, if you download a recent ffmpeg build and run PYTHONPATH=. python bin/infoqscraper presentation download --ffmpeg ./ffmpeg --type h264_overlay core-async-clojure
22:20ivanthe aspect ratio on the video recording is slightly off but that is ignorable or fixable
22:25quizdr mklappstuhl just perusing the solutions at 4clojure will give you all you need to know and more, it's a fantastic learning resource
22:25quizdrof course, you can't see the solutions until you've come up with one of your own!
22:27mklappstuhlquizdr: yeah probably thats better for learning, coming up w/ sth on your own first
22:28quizdrbeing able to mix map, apply, reduce all in a single line of code is really extraordinary, all these tools available for genuine creativity. if you ask a c++ person to write a particular function, most of them will do it more or less the same way, because there aren't as many options. but these lisps bring ideas to the surface and really open up the process in ways i've never seen before. i really had no idea what computer programming
22:28quizdrcould be until i discovered this stuff
22:30quizdri know i'm preaching to the choir, but not having to think about low-level details and also getting to increase the thinking/typing ratio when coding has really spoiled me quickly.
22:31insamniacYeah I follow a bunch of people on 4clojure, and it's crazy to see the variety of ways one can approach a problem.
22:32insamniacTo be honest, I'm still uncomfortable with the freedom.
22:33quizdr insamniac i think that will change as you master the various functions. for me i simply don't know what a lot of those functions are, so I resort to basically implementing them on my own to solve a problem, hence why loop/recur ends up getting more air time than it deserves. then I see code on there that uses cool little built-in tools and i realize I should be memorizing the clojure.core API!
22:33gfredericksrandom function you don't know about yet: fnil
22:34quizdr,(doc fnil)
22:34insamniactrue story
22:34clojurebot"([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched."
22:34quizdrwow
22:34insamniaci remember when i first saw juxt and got all giggly.
22:34gfredericks,(update-in {:foo 12} [:bar :baz] (fnil conj #{}) 42)
22:34clojurebot{:bar {:baz #{42}}, :foo 12}
22:37quizdrthat's an eye-full
22:38gfredericksI've mostly only used it to add things to collections that might be nil
22:39dsrx,(doc fnil)
22:39clojurebot"([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched."
22:42teslanickOne thing I've noticed -- and maybe this is because I write clojure after work but before bed -- is that I have really weird dreams about homoiconicity
22:44quizdrtelansick actually i kid you not so have i. when i first discovered common lisp, i was dreaming about it at night for several days.
22:44quizdralmost like discovering a drug, to be honest.
22:44technomancyquizdr: I had a fever like that once
22:45quizdrtechnomancy ha i got the clojure fever every day, son!
22:45technomancyI dreamed I was implementing https://en.wikipedia.org/wiki/Puyo_Puyo_(series) in emacs lisp as a derived mode of M-x tetris
22:45quizdrreally, you too? that's quite a coincidence
22:45technomancyit was a really high fever
22:46quizdr...they always are
22:47teslanickI think my brain made the linguistic connection between homo-iconic and homo-sapiens, so I was dreaming of humans implemented as self-modifying s-expressions. I also haven't been sleeping well, so maybe there's a connection.
22:50quizdri went to a lecture last night, the guy runs a company where they treat the brain as a computer that runs software programmed by nature over large stretches of natural selection, proposing that modern day problems already have solutions in the software. they use Haskell.
22:51quizdrto uncover what the software actually is, they look at statistical analysis of historical problems and how they resolved, using that as evidence of what the inner implementations might be. almost seems like decurrying to me.
22:51teslanickThat's a little arrogant, but then… haskell. ;)
22:51technomancythat sounds like one of the talks I heard at strangeloop
22:53quizdrcheck it out http://www.appliedcognitivescience.com/
22:53quizdrwell, looks like there isn't much there on the site
22:54quizdrhe used topology to showcase the ivention of functors
22:56quizdrin which I discovered that the word "functor" in haskell has a completely different meaning than the same word in c++ :)
23:01KeithPMGood day all. I am trying to figure out why I am not receiving any input from the following function. (compute-winnings-for-a-trial n ) works on its own https://gist.github.com/kpmaynard/8611605
23:02TEttingerKeithPM, conj doesn't change acc
23:02TEttingerso you return the original acc, []
23:02TEttingeryou need to just take out the acc after that compute-winnings call
23:02quizdrKeithPM yes remember all data is immutable. you should just pass the conj statemet to recur
23:03quizdror whatever is appropriate
23:03KeithPMTEttinger: Yes, yes… Bad error :)
23:03TEttingererr I think I read it wrong btw
23:05KeithPMTEttinger: I think I should perform the conj within the recur...
23:06quizdrKeithPM yes that would be a good way
23:06quizdralternately you could use a let form up top if you need the conj result more than once
23:07KeithPMquizdr: OK let within the loop right?
23:08quizdronly if you need the conj result more than once, you could put a let in there yes
23:08TEttingeroh and when I ran it the loop never terminated?
23:08TEttingernot sure what condition it should end on, but I'm guessing m <= 0
23:08akurilinDoes anybody know of a guide for how to set up running unit test from the repl, including reloading the project if it needs to be.
23:09KeithPMTEttinger: Really? But I'm decrementing m each time… Hmmmm
23:09KeithPMTEttinger: Thanks, I will look in to that problem
23:10quizdryou are decrementing m each time, but where is the exit? the recur is outside of your if test
23:10quizdrKeithPM ^
23:12quizdrKeithPM you don't need a let because looks like you are only conj when you recur, so put your conj in the recur only.
23:12quizdryou could replace your current conj form with the recur form to move recur inside the if test, and put the conj inside the recur.
23:13TEttingertry https://gist.github.com/tommyettinger/8611744 , KeithPM
23:13KeithPMquizdr: I agree, The idea is that I would loop to the loop point, with m decremented. If m becomes 0 the else-part should be executed, I think
23:14quizdrif you are going to recur, you a test inside the loop where the result is not a recur, or else you have an infinite loop.
23:14KeithPMquizdr: Yes, I am trying that, recurring in the then-part and returning acc in the else-part
23:14quizdrcurrently, recur is always getting called no matter what
23:15KeithPMquizdr: OK, let me take a look at it. Wow, amazing how easily one can blow one's foot off LOL… 5 lines of code!!!!
23:15TEttingerinfinite loops are easy, fixing them not so much
23:15KeithPMTEttinger: Thanks, looking at it now
23:15quizdrfor example you could have a line like this: (recur (dec m) n (conj acc (compute-winnings-for-a-trial n)))
23:15KeithPMTEttinger: :)
23:15TEttingerdon't need the n actually, since it doesn't change
23:16quizdrput that as one of the if branches and you at least have a non-recurring branch to exit the loop
23:16KeithPMTEttinger: Rightm, right… The n is available already…
23:17KeithPMTEttinger: That's exactly what it should look like, thanks
23:18joshuafcoleHey folks, where do leiningen plugins get stored at?
23:18joshuafcoleI'm trying to patch cljsbuild but can't seem to find it.
23:18quizdrha ha i just saw TEttinger gist, don't know why i was repeating it
23:18quizdrcould have saved some typing
23:18quizdr:)
23:19KeithPMquizdr: Thanks anyway, I appreciate it
23:19TEttingerKeithPM, there's an easier way too
23:19TEttinger,(defn multiple-trials [m n] (repeatedly m #(compute-winnings-for-a-trial n)))
23:19clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: compute-winnings-for-a-trial in this context, compiling:(NO_SOURCE_PATH:0:0)>
23:19TEttingeroh right
23:19TEttingerwell it does almost the same thing, just as a seq not a vector
23:19KeithPMTEttinger: I tried that but repeatedly needs a no-arg function
23:20TEttingerit is, n is outside the closure
23:20KeithPMOh OK, you used the anonymous function… I did not try THAT… That's neat
23:21TEttingerassuming your compute just returned a random number... ##(let [m 6 n 8] (repeatedly m #(compute-winnings-for-a-trial n)))
23:21lazybotjava.lang.RuntimeException: Unable to resolve symbol: compute-winnings-for-a-trial in this context
23:21TEttingerdammit!
23:21KeithPMFor any beginners out there, I am actually following an article which tries to introduce developing an entire clojure program which runs a heads and tails  (coin flipping) game. http://archive.eddology.com/post/14592579289/busy-persons-clojure?goback=.gde_1058217_member_5831664140367724547#!
23:21TEttingerassuming your compute just returned a random number FOR REAL... ##(let [m 6 n 8] (repeatedly m #(rand-int n)))
23:21lazybot⇒ (7 2 7 6 1 1)
23:22KeithPMTEttinger: I will try again with the anonymous function
23:23TEttingerrepeat and repeatedly have some interesting subtle differences... the anonymous fn syntax creates a no-arg fn if no % args are used in the body
23:24KeithPMTEttinger: Yes, I think you already bound the n so anonymous function is in fact no-arg
23:24TEttinger(that's a fun catch, you would expect it to at least have a % single arg, right? but it is smart about it)
23:30KeithPMTEttinger: repeatedly works wonderfully well :) … Fewer keystrokes extends programmers' lives :)
23:38akurilinHey folks. Is there a way to (require) all the namespaced under a certain folder?
23:38akurilinI'd love to be able to require all my test nses at once so that I can do (clojure.test/run-all-tests) on them.
23:40Anderkentakurilin: bultitude can tell you what is on the classpath
23:45technomancyakurilin: the fact that `lein test` can't be invoked from within your project itself is a big failing of the design there
23:47technomancyhopefully we can fix it in 3.0
23:54akurilintechnomancy: I was reading your guide for lein test and you say in there that we should use clojure.test/run-all-tests to test from the REPL. What's your recommendation for getting those namespaces loaded int he first place?
23:55akurilinShould I use bultitude and require all of the test ones?
23:55technomancyakurilin: bultitude is about the only way, yeah
23:56akurilinOk, will give that a try then.
23:56akurilinAny guides for how to UT from one's REPL you might be aware of ?
23:56akurilinI couldn't find anything in the "blogosphere"
23:57akurilinWhich is surprising because this is pretty basic.
23:58technomancyakurilin: I don't ever do a full test from the repl
23:58technomancyI just est the specific nses that I'm working on
23:59technomancyand then before merging or pushing or whatever run a fresh `lein test` from the CLI so I know that the JVM state hasn't been corrupted
23:59technomancypersonally anyway