#clojure log - Mar 24 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:44 optout: i wonder if these automated bots would follow such a redirect

1:07 justin_smith: well, if it was well behaved enough I could just keep it away with a robots.txt

1:08 but in all seriousness, I wonder if they use clients that would follow redirects, good question

1:13 vas: Hi! I'm trying to do a simple word-to-numbers mapping function so if the String passed in is "doubleplus" it returns 99, if it's "plus" it returns 74

1:13 but I'm stumped. it seems like none of my if statements work in the function

1:13 justin_smith: vas: care to share a paste?

1:13 vas: Shore.

1:15 https://www.refheap.com/98813

1:15 justin_smith: vas: you don't have the ifs nested

1:16 ,(do (if true 42) :other)

1:16 clojurebot: :other

1:16 justin_smith: if doesn't make the function return

1:16 the function returns the last result in the body

1:16 vas: Aha. hrm. so (= string "val") is a totally legit way to test string equality?

1:17 tolstoy: vas: try 'cond'.

1:17 vas: Oh hey, it works now. :D

1:17 justin_smith: vas: if you move the paren after 99, and the one after 30, and put them both after 74, it will work

1:17 OK

1:17 and yeah, cond will be clearer

1:17 vas: thanks friends.

1:17 justin_smith: or case

1:17 vas: I shall investigate Cond.

1:18 tolstoy: Or a hash map, but one thing at a time, eh?

1:18 justin_smith: ,(case "doubleplus" "doubleplus" 99 "needswork" 30 74)

1:18 clojurebot: 99

1:18 vas: Well, i'm going to be summing over many ratings, so I wanted something that could get me there incrementally

1:18 tolstoy: ,(get {"plus" 74, "doubleplus" 99} "plus")

1:18 clojurebot: 74

1:19 vas: Oh cool.

1:19 i'm just marveling at how awesome (map ...) is

1:19 justin_smith: even better ##({"plus" 74 "doubleplus" 99} "default" 74)

1:19 lazybot: ⇒ 74

1:20 vas: what's a ## do? o.o

1:20 justin_smith: &({"plus" 30 "doubleplus" 99} "plus" 74)

1:20 lazybot: ⇒ 30

1:20 justin_smith: vas: it's for using lazybot ##"mid message"

1:21 but sometimes it doesn't work without delimiters :P

1:21 vas: and yeah, map, and it's friends mapcat and for and reduce, all very powerful

1:21 TEttinger: justin_smith: ##(str "two hashes need a paren after them")

1:21 lazybot: ⇒ "two hashes need a paren after them"

1:21 justin_smith: TEttinger: sometimes ##{:a 0}

1:21 lazybot: ⇒ {:a 0}

1:22 TEttinger: ah

1:22 I wonder how it decides

1:22 justin_smith: I just forget all the special cases

1:22 TEttinger: ##[1 2 3]

1:22 lazybot: ⇒ [1 2 3]

1:22 TEttinger: ###{1 2 3}

1:22 lazybot: ⇒ #{1 3 2}

1:22 TEttinger: oh wow

1:22 justin_smith: heh

1:22 TEttinger: ###(+ % %2)

1:22 lazybot: ⇒ #<sandbox6330$eval45507$fn__45508 sandbox6330$eval45507$fn__45508@7ec76e93>

1:22 vas: thanks a lot for your help guys! :D

1:22 justin_smith: I'll try ##::a

1:22 TEttinger: heh

1:23 justin_smith: yeah, I think it comes down to "delimiters", of any sort

1:23 ,(def a 42)

1:23 clojurebot: #'sandbox/a

1:23 justin_smith: oops

1:23 ##'+

1:23 lazybot: ⇒ +

1:24 TEttinger: so I'm thinking of using ClojureCLR to handle the most complex part of my C# game. it looks like a statically typed collection of collections is going to be really brittle here and need lots of special cases

1:24 justin_smith: because the reader expands it to have parens

1:24 Seylerius: What's the clojure-y way to go about making a function take either a reference to a thing, or a set of constraints defining what potential things would be appropriate?

1:24 Something based on multi-arity?

1:24 justin_smith: Seylerius: what do you mean by reference?

1:24 Seylerius: it could be a protocol and thus dispatch on type

1:25 Seylerius: it could be a multimethod and dispatch on an arbitrary function called on the args deciding the method

1:25 TEttinger: Seylerius: what potential things are appropriate to return?

1:25 or are appropriate to receive as an argument to a returned fn?

1:26 those seem like different functions tbh

1:27 Seylerius: justin_smith, TEttinger: This is the knowledge mapping thing I've talked about previously. So I'm looking to have the association matrix of potential-facts be able to treat factoids, and sets of constraints that specify factoids, equally.

1:27 The goal being a step closer to logical omniscience.

1:27 justin_smith: Sounds like a multimethod or protocol to me

1:27 Seylerius: Talk protocols at me...

1:27 justin_smith: would this be decidable based on the type of the first arg?

1:27 Seylerius: I don't know much about them.

1:27 justin_smith: likely.

1:27 justin_smith: a protocol is the clojure flavor of java's interfaces

1:28 Seylerius: If the first arg is a factoid, then it's a factoid, if not, then it's constraints.

1:28 justin_smith: it's like a superclass, but you don't inherit any functionality from it, you just conform to its signiture

1:28 Seylerius: Nice.

1:28 TEttinger: ah, that sounds like a multimethod

1:28 justin_smith: Seylerius: http://conj.io/store/v0/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/defprotocol/

1:30 protocols are good for if you will have multiple functions describing how to use some piece of data (eg. think of collections in clojure, multiple types implement it, but with all of them you can do conj, make it a seq, etc. for each of them)

1:30 Seylerius: Hmm... Protocols might be the thing.

1:31 vas: You guys are awesome.

1:31 Seylerius: Have a predicate protocol, implemented by both factoid, and some sort of potential-factoid.

1:31 justin_smith: yeah, that makes sense to me at least

1:32 Seylerius: Then factoids and simple predicates can get treated the same, respond to confidence queries, etc.

1:33 justin_smith: yeah, once you have an assortment of functions that should all work on the same variety of types, protocols are a huge win

1:33 Seylerius: The difference being that factoids are bound to source material, whereas simple predicates aren't.

1:33 justin_smith: and like I said, clojure itself is full of this (well, it's a mixture of protocols and interfaces but the basic concept stands)

1:34 Seylerius: Simple predicates are only defined by their relationships to other predicate-ish objects, whereas factoids are predicates that also have bound source material.

1:34 I think.

1:34 (This is still all very conceptual—I'm essentially trying to move humanity a tick closer to logical omniscience, which is widely considered a pipe dream)

1:37 TEttinger: Seylerius, or a very bad idea

1:37 it could be a good idea!

1:38 Seylerius: No, I'm pretty sure it's a very good idea.

1:39 TEttinger: I think Stephen Hawking is in the "if we already have flying drones with missiles fighting wars for us, then making an artificial intelligence that could effortlessly assume control of flying drones with missiles is a bad idea" camp

1:40 Seylerius: And here's why: being able to chase implications of what we know as quickly as we can define what we know and the potential implications allows us to get knowledge out of all the hacks, leaks, and sudden declassifications of interesting data massively quicker than currently possible.

1:40 This isn't AI. This is completely incapable of making decisions or taking actions. Only of chasing truth.

1:41 Now, this type of thing is extremely important as one component of strong AI, but it isn't an AI on its own.

1:41 TEttinger: ah, so something that can extrapolate information from seemingly unrelated large amounts of data?

1:41 Seylerius: Essentially.

1:42 As we define the first-order meanings of the data, it starts assisting in the defining of second-order meanings, and using those to assist in defining third-order meanings.

1:42 TEttinger: wasn't that a big part of what caused the market crash of 2007-2008?

1:42 Seylerius: The predicate protocol would hinge heavily on computing confidence relationships between other predicates.

1:42 TEttinger: a bad formula used to assign value to junk loans

1:43 Seylerius: There were good formulae; but folks stopped using them and changed them to allow them to get away with more, because they wanted to take more liberties, and got deregulation from Clinton.

1:43 Normally the Democrats are supposed to be pro-business-regulation, but Clinton did something dumb.

1:44 Basically, there were risk caps in the good formulae, and inherently riskier formulae, and they used the good formulae with looser caps, and the risker formulae with whatever caps they felt like.

1:45 (Gross oversimplification)

1:46 TEttinger: https://en.wikipedia.org/wiki/Glass%E2%80%93Steagall_Legislation

1:46 that regulation mainly?

1:46 Seylerius: Yeah, that was the big thing he nerfed.

1:47 justin_smith: Oh man, if only we used the vocabulary of WoW etc. to describe politics.

1:47 "so our guild was camping this Senator instance, and we almost had regulatory capture in the bag"

1:47 TEttinger: https://en.wikipedia.org/wiki/Financial_crisis_of_2007%E2%80%9308#Incorrect_pricing_of_risk this is getting interesting

1:48 Seylerius: Anyway, yes, extrapolation is the goal. Confidences will all be expressed in terms of decimals, confidence relationships in terms of deciBayes (or whatever the current quirky name for using decibel-type-numbers to play with probabilities is), and Bayes Law will feature quite heavily.

1:48 vas: house senate committee stole my cloudsong

1:49 XD

1:49 justin_smith: haha

1:49 Seylerius: And it'll be somewhat crowd-sourced and live entirely decentralized (for unkillability), and source-backed confidences will be considered more heavily than simple predicates.

1:49 justin_smith: instead of Democrats / Republicans we would of course have Horde / the other Horde

1:49 Seylerius: Heh.

1:50 Yeah, the WoW jargon might help frame the politicians as the enemies of the people they act like.

1:50 TEttinger: heh

1:50 vas: Haha horde and other horde. That is true.

1:51 Seylerius: Red Horde, Blue Horde, and the Confederated Popular Alliances?

1:51 TEttinger: this was an excellent article about the perils of trusting sources http://www.slate.com/articles/technology/bitwise/2015/02/wikipedia_gamergate_scandal_how_a_bad_source_made_wikipedia_wrong_about.html

1:51 vas: i believe the newbies are our future... teach them well and let them lead the raid...

1:51 Seylerius: vas: Hah.

1:52 TEttinger: The rule of Wikipedia is that authority trumps accuracy. Editors are not allowed to contradict what established “reliable” sources like the New York Times, the Washington Post, and the Guardian say...

1:56 Seylerius: TEttinger: Source-degree rankings? First-hand sources trump second-hand sources, etc.; news articles can only be second-hand sources at best; and so on?

1:56 J_Arcane: TEttinger: they actually did finalize all of the actions, though, and in the end have since been exceedingly generous in interpreting the sanctions of same.

1:56 justin_smith: Seylerius: they ban original research, which means content can be deleted unless secondary sources can be found

1:57 Seylerius: Ah. Yeah, that's where this tool is different. It's meant to be a platform for original research.

1:57 Analyzing things like the Stratfor leaks.

1:57 TEttinger: oh nice

1:57 massive data then

1:57 Seylerius: Or _everything_ Cryptome ever released.

1:59 Basically I'm trying to give the "We don't fully trust the gov't not to lie to us" camp the kind of logical omniscience that we have to assume the Three-Letter-Agencies already have.

1:59 Or approximation thereof.

1:59 Painfully massive data.

1:59 Completely decentralized through massive DHTs and Tahoe-LAFS over I2P.

2:00 (Don't want to make this thing easy to kill, now do we?)

2:00 Make some kind of sense?

2:04 TEttinger: yep

2:05 you also need some way of verifying nodes that do calculations to ensure they aren't compromised

2:06 stuxnet did an amazing job at making sure things appeared normal to a user even though it was instructing hardware to spin itself to ruin in the room next door

2:08 Seylerius: TEttinger: Yeah, I'm going to do some sort of consensus verification and repeated re-checking.

2:08 Maybe something blockchain-shaped.

2:10 TEttinger: you could also encrypt the actual content of the data you're processing and have one computer hold unencrypted data but only have a responsibility to assign hashcodes or some equivalent to the data, and another computer holds encrypted data and can use the hashcode-like information gathered from multiple sources to make decisions blind

2:15 vas: TEttinger: you bring up some very good points about authority's weight in wiki-verse.

4:01 Seylerius: TEttinger: That's a hell of an idea.

4:02 Might take some work to make it workable and allow users to actually play with the data without compromising the separation from the processing layer.

4:02 TEttinger: it might make more sense to just partition a job into extremely small chunks

4:02 Seylerius: Yeah.

4:03 Tiny.

4:03 TEttinger: as in, so small that interference by malicious parties couldn't tell what they're altering

4:03 Seylerius: Right.

4:07 TEttinger: that might be interesting

4:07 you could intentionally throw bogus information into the system to try to catch nodes that are disregarding the information they get

4:11 Seylerius: Yeah.

4:11 The trick is balancing the obfuscation with the ability of users to get the info back out.

4:12 TEttinger: I'd send a message to undo the previous n messages after you get the info you need

4:13 you'd probably only want to send intentional bad data if an analysis showed that something wasn't making sense with what you expected vs. what you got

4:14 also, you'd need a way to avoid malicious users spamming "undo 9999"

4:15 If there are any ClojureCLR users here, can you tell me how I could run a clojure function on a clojure var (possibly all declared in the same .clj file), and get back some data that I can use from C#?

4:23 Seylerius: TEttinger: That's the real catch. Preventing the protection mechanisms from both interfering with the use of the system, and from being misused by malicious actors.

5:56 sveri: Hi, when I add a self defined tag in selmer, is there a way to use it in an if tag? like so {% if self-defined-tag arg1 arg2 %}.... {%endif%}

5:56 when I try that I get a NumberFormatException on arg2

6:26 pkug: What would be the short "return a sequence of first elements of sequences in X" ? so '((1 1 1) (2 2) (3)) would yield '(1 2 3)

6:27 scottj: (map first coll)

6:27 Ricardo-Arges: map first

6:27 :-P

6:27 pkug: omg

6:28 thanks

6:29 Ricardo-Arges: Anyone using neocons? Any better options? Borneo seems to be rather dead.

6:29 kungi: ikitommi: when using compojure-api how can I add a file upload to a route.

6:30 Ricardo-Arges: I'm using neocons and don't have any major issue with it, but just ran into a dependency issue that got me wondering. It's early on that if there are better options, now's the time to jump.

6:31 TEttinger: ,(map first '((1 1 1) (2 2) (3) ()))

6:31 clojurebot: (1 2 3 nil)

6:31 TEttinger: nice, it handles empty seqs too

6:31 (inc scottj)

6:31 lazybot: ⇒ 3

6:38 pkug: is that an upvote?

6:39 Bronsa: #clojure internet points

6:39 oddcully: ,(def upvote inc)

6:39 clojurebot: #'sandbox/upvote

6:39 pkug: one needs to be defined first right

6:40 * Ricardo-Arges pets clojurebot

6:40 Bronsa: TEttinger you can use `keep` in place of `map` if you don't want the nil

6:40 ,(keep first '((1 1 1) (2 2) (3) ()))

6:40 clojurebot: (1 2 3)

6:40 TEttinger: oooh

6:41 (inc Bronsa)

6:41 lazybot: ⇒ 97

6:41 Bronsa: keep is the lovechild between map and filter

6:41 TEttinger: getting close to to big 1 double 0

6:49 Deraen: kungi: Wrap the routes handling file upload in (middlewares [(ring.middleware.multipart-params/wrap-multipart-params)] ...), or similar middleware, and use s/Any for file field

6:50 kungi: Deraen: Thank you. I will try that.

6:51 ikitommi_: kungi: no helpers, so just like you would do it with Compojure.

6:52 kungi: ikitommi_: Deraen will this work with swagger-ui out of the box or do I have to add some metadata to the swagger-docs function?

6:54 Deraen: kungi: No. And I'm not even sure if Swagger-ui has file upload support. If it has, please open a issue at ring-swagger so we can check if we can add support for that.

6:55 kungi: Deraen: Ok

6:59 ikitommi_: kungi, Darean: swagger-ui has support for it.

7:00 http://petstore.swagger.io/#!/pet/uploadFile

7:00 we'll add that.

7:05 kungi: ikitommi_: great

7:05 (inc ikitommi_ Deraen)

7:05 lazybot: ⇒ 1

7:22 TEttinger: ,(inc 1 2 3)

7:22 clojurebot: #error{:cause "Wrong number of args (3) passed to: core/inc--inliner--4209", :via [{:type clojure.lang.Compiler$CompilerException, :message "clojure.lang.ArityException: Wrong number of args (3) passed to: core/inc--inliner--4209, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6732]} {:type clojure.lang.ArityException, :message "Wrong number of args (3) pass...

7:22 TEttinger: inc is a single-arg function!

7:22 (inc ikitommi_)

7:22 lazybot: ⇒ 2

7:22 TEttinger: (inc Deraen)

7:22 lazybot: ⇒ 1

7:48 m1dnight_: Guys, im trying to figure out how I can write code like this more idiomatic: https://www.refheap.com/98821

7:48 I had a look at multimethods but I'm not sure if that's better

7:48 something along the lines of (defn foo ([x] (identity x)) ([x & xs] (conj (foo x) (doall (map foo xs)))))

7:49 Empperi: m1dnight_: not sure what you want for it to be more idiomatic, but I'd use doseq

7:49 since your setup-server is obviously a function with side effects

7:49 otherwise you wouldn't need doall

7:49 m1dnight_: heh, exactly :)

7:49 Empperi: so (doseq [info serverinfos] (create-bot info))

7:50 the downside of that is that you won't get back the return values of setup-server

7:50 if you need it

7:50 m1dnight_: hrm, I do

7:50 but then ill leave it at this I guess

7:50 I was hoping I could merge both methods together

7:50 Empperi: in that case map + doall is fine

7:50 m1dnight_: functions*

7:50 Empperi: well you can but why would you want it?

7:51 (doall (map #(setup-server %) serverinfos))

7:51 and you don't need the create-bot function anymore

7:51 or even better

7:51 no need for the anonymous function

7:51 just (doall (map setup-server serverinfos))

7:51 does the exact same thing

7:52 and makes more sense than create-bot too if you're passing stuff named serverinfo

8:21 m1dnight_: another quick question, is there something like cycle but not infinite?

8:22 e.g., (cycle [1 2 3]) --> [2 3 1]

8:22 i cant think of a name to google it :p

8:22 oddcully: you want to permutate the entries?

8:23 m1dnight_: not really permute. Think of a list [a b c] where the leftmost element is the most important

8:23 and if a certain predicate does not suceed for that, shift the list once to the left

8:23 if you get what I'm saying :p

8:23 the shift is because I dont want to keep an index of where I'm at at that current position in the list.

8:24 (cycle (cycle [1 2 3])) ---> [3 1 2] for example

8:25 Hrm, I guess I could just use cycle and do something like (defn shift [xs] (drop 1 (cycle xs)))

8:38 dysfun: (inc clojure.core/reduced)

8:38 lazybot: ⇒ 1

8:48 noncom: m1idnight_ i think this is called "circle buffer"

8:48 or circling buffer

8:48 i had this question for scala once: http://stackoverflow.com/questions/8876769/best-practice-for-shifting-a-sequence-in-a-circular-manner

8:49 justin_smith: noncom: any relation to ringbuffer?

8:49 noncom: rrriiight!

8:49 "ring", not "circle" :)

8:49 justin_smith: ringbuffers are an optimization for super fast append / pop off the end

8:49 also, if they have a primitive type, they are amazing in their cache perf

8:50 err, it can be either prepend with a pop off the end, or append with pop off the front, depending which direction you are going

8:52 noncom: also, ringbuffers are the secret sauce behind the "disruptor" lib

8:52 they are also used extensively in DSP

8:54 noncom: hmmm

8:55 yeah, one of those things that gets you to the speed edge with hardware..

8:57 imagine, i have a task, made of like 20 subtasks. each task is a fn, called inside the ubertask fn. so i want to be able to arbitrary turn on and off various subtasks.. is there any library for that?

8:57 i can do this in many different ways, but probably there is something already there

8:58 jonathanj: does anyone use any of the dunaj tools?

8:58 anyone here, rather

8:58 noncom: jonathanj: nope. i have just stumbled upon it a couple of days ago for the first time. after reading the intro, still, i do not really get the point..

8:59 jonathanj: oh, it's a fork of clojure

8:59 for some reason i was under the impression that it was a bunch of utility libraries

8:59 noncom: yeah, that i have read there.. they also separate things in namespaces.. so that you have to import all the stuff separately instead of just having core in there

8:59 at least that's the impression i got

9:00 s/import/require

9:00 probably there is some meaning in it, that i did not yet discover..

9:00 jonathanj: what you can say about it?

9:01 Ricardo_: jonathanj: Seemed to be all over /r/clojure for a few days

9:01 noncom: umm, just reviewed the intro again. it turns out, dunaj is 10 different projects, and separating core in namespaces is just one of them

9:03 dysfun: ah, and that answers whether recur works across different arg counts

9:03 (no)

9:04 Ricardo_: One of those comments called Dunaj a "reference library for proposed changes", which while interesting as a description, seemed to have little use for me right now, so I didn't look further into it.

9:07 justin_smith: noncom: that sounds a lot like fnk from prismatic/plumbing

9:09 noncom: https://github.com/Prismatic/plumbing#graph-the-functional-swiss-army-knife

9:10 noncom: graph can be compiled lazily, such that only results you use are calculated, or parallelized, so that if possible things are done in separate threads, etc.

9:24 jonathanj: i would have liked to make use of Dunaj in small pieces for projects to test it out, but it doesn't really seem well suited to that

9:25 justin_smith: yeah, the project seems specifically to be there for testing things that are too big to just do as a lib within Clojure.

9:50 jonathanj: plumbing is pretty damn cool

9:51 although giant "cool utilities" libraries can be unwieldy

9:52 justin_smith: I bet plumbing is lighter weight than nrepl though

9:53 jonathanj: haha

9:54 that's probably true

9:55 justin_smith: we've got these hogs we just take for granted...

9:58 mpenet: bah, it's not like a few Kb here and there matter much

9:58 tbaldridge: noncom: yeah, there are some aspects of Dunaj that are interesting, and perhaps would have a chance of getting into Clojure in the next 5 years, but it just touches too much, imo.

9:59 Like the whole protocols-at-the-bottom is a refactor I would not be surprised to see in the next 5 years, although there are currently no plans to do so (that I know of).

9:59 jonathanj: mpenet: it's mostly just mentally annoying, things like: where was for-map from again? oh yes, the graph library that has nothing to do with map utilities it's just sort of a "and if you call now you'll also receive this shiny for-map function!" scenario

10:00 justin_smith: mpenet: it's not just a few kb, it's the size of everything once its compiled, and the time it takes to load the whole thing up (compare clojure startup time with / without nrepl)

10:01 jonathanj: what are my choices for code documentation that don't involve literate programming styles?

10:01 dysfun: codox

10:01 * dysfun switched to codox after a conversation in here the other day

10:01 dysfun: (from marginalia)

10:02 justin_smith: prismatic/schema is a kind of documentation :)

10:02 (as is core.typed)

10:03 jonathanj: i don't know if it's a bad habit but i like the way Sphinx lets me combine prose documentation with API documentation for Python projects

10:03 justin_smith: jonathanj: or did you mean specifically generating html browsable docs

10:03 dysfun: isn't that basically what literate programming does?

10:03 jonathanj: dysfun: i'm not sure i follow

10:04 dysfun: you like mixing api docs and prose

10:04 jonathanj: dysfun: literate programming is words interspersed with code

10:04 dysfun: marginalia isn't

10:05 jonathanj: i mean the final output

10:05 dysfun: right. marginalia has one column for words, one for code

10:05 that's your mixing of prose right there

10:05 jonathanj: yeah, but it's mixing code and prose

10:05 dysfun: you define comments with a double-colon and you get your prose

10:05 jonathanj: not prose documentation with API documentation

10:05 dysfun: oh i see what you mean

10:05 jonathanj: so for no apparent reason all my source code is in my documentation

10:05 dysfun: i haven't found a tool for doing that yet

10:06 the nearest thing is gorilla repl notebooks

10:10 borkdude: how do I log a query with clojure.java.jdbc?

10:10 mpenet: justin_smith: if you don't use it loading time isn't impacted, I am not saying it's never important, but most of the time the rants about library size for dependencies where just a few functions are used are a bit pointless.

10:11 ex flatland/useful

10:11 dysfun: borkdude: log in what sense? make a record that the query was issued? automatically when queries are issued?

10:11 borkdude: dysfun I get an error message about invalid sql when using clojure.java.jdbc. I want to see the query

10:12 dysfun: the function that issues the query, wrap it in a try/catch with the sql in scope and dump it to stdout?

10:13 tcrayford____: borkdude: lol at the all the layers of fuckups that mean it isn't in the exception message

10:13 (that's really fucked up, and fuck whichever layer(s) is doing that)

10:13 dysfun: tcrayford____: design by (enterprise) committee

10:13 tcrayford____: "design"

10:14 dysfun: i realised something today actually. for all we mock java, they're just brave warriors making it painful to use hashmaps so as to force you to build types

10:14 borkdude: tcrayford____ I'm not using any other layer than clojure.java.jdbc :)

10:14 dysfun: i mean, you're in danger of your code working sometime soon if you aren't defining lots of types

10:14 tcrayford____: borkdude: right, but it might be the driver, or java.jdbc, or some internal jdbc layer

10:15 borkdude: there are prolly like 20k+ lines of java code before you actually call sql

10:22 borkdude: I found the error though

10:22 (jdbc/update! conn :col-name nil ...) fails

10:34 sdegutis: What's the general consensus on Boot.sh?

10:43 profil: is there an easy way to conj to a list inside a map? I got an atom that looks like this (def state (atom {:list []})), and I want to add items to the list

10:43 sdegutis: profil: try update-in

10:43 profil: sdegutis: ahh, I knew that I had used it before, thanks

10:44 s/used/done/

10:44 sdegutis: profil: if it's a one-level map and you're using Clojure 1.7, use update

10:44 (doc update)

10:44 clojurebot: "([m k f] [m k f x] [m k f x y] [m k f x y ...] [m k f x y ...]); 'Updates' a value in an associative structure, where k is a key and f is a function that will take the old value and any supplied args and return the new value, and returns a new structure. If the key does not exist, nil is passed as the old value."

10:44 justin_smith: otherwise of course, update-in

10:44 profil: whats the difference?

10:45 justin_smith: ,(update {:list []} :list conj :a)

10:45 clojurebot: {:list [:a]}

10:45 sdegutis: profil: update is just a specialized version of update-in that's only available in newer Clojure

10:45 justin_smith: ,(update-in {:list []} [:list] conj :a)

10:45 clojurebot: {:list [:a]}

10:45 profil: sdegutis: alright, seems that I am not using Clojure 1.7 cause doc says nil

10:45 justin_smith: update-in needs a sequential arg, update just the key

10:46 profil: *clojure-version* helps here :)

10:46 sdegutis: To be fair though, Clojure 1.7 doesn't even exist yet.

10:46 justin_smith: not that it stops us all from using it

10:47 profil: lol :D

10:47 dysfun: 1.7.0-SNAPSHOT exists

10:47 sdegutis: I'm still on 1.5.1 because when I try upgrading to 1.6, a lot of my tests break and I don't quite know why.

10:47 profil: {:major 1, :minor 6, :incremental 0, :qualifier nil} :D

10:59 sdegutis: Anyone know of a good blog post on translating project.clj to build.boot?

11:02 acron^: I understand that predicates are idiomatically suffixed with '?'

11:02 but what does the '!' suffix imply?

11:02 sdegutis: acron^: same as in Ruby

11:03 acron^: not a Rubyist :)

11:03 sdegutis: acron^: i.e., it has side effects

11:03 justin_smith: acron^: generally, that something is not safe in a transaction context

11:03 acron^: Aha

11:03 dysfun: acron^: depends where. in the core library it means 'unsafe for transactions', but a lot of libraries have other meanings

11:03 justin_smith: we have lots of things without ! that have side effects

11:03 sdegutis: justin_smith: so true

11:03 pr-str

11:03 justin_smith: alter-var-root

11:03 sdegutis: pr-str's my favorite one

11:03 acron^: I'm using timbre for logging, and it has 'set-config!'

11:03 justin_smith: ,(doc alter-var-root)

11:04 clojurebot: "([v f & args]); Atomically alters the root binding of var v by applying f to its current value plus any args"

11:04 dysfun: acron^: in that case, he's using it to indicate the side effects

11:04 acron^: internally using "swap!"

11:04 justin_smith: sdegutis: wait, how does pr-str have side effects?

11:04 dysfun: (it changes global state)

11:04 sdegutis: justin_smith: it prints to *out*

11:04 justin_smith: no it doesn't print

11:04 acron^: Is there a 'safe' way to change state?

11:04 sdegutis: Oh what am I thinking of?

11:04 justin_smith: ,(type (pr-str :a))

11:04 clojurebot: java.lang.String

11:04 sdegutis: Oh.

11:05 acron^: I understand clojure has forms for this, but I don't know them

11:05 dysfun: acron^: don't use mutation. atoms are 'safe' in a sense, and entirely not in another

11:05 justin_smith: you may just be thinking of print, or pr

11:05 sdegutis: See this is why I stopped talking for so many months, cuz I'm usually wrong :)

11:05 justin_smith: haha

11:05 anyway, alter-var-root is one of the must mutatingly evil things in clojure, and no "!" in it

11:07 sdegutis: It seems every 10 minutes something reminds me of why I slightly wish our app was written in Haskell instead of Clojure.

11:08 But I don't know Haskell yet so I'm sure it's got its own share of unsolved difficulties :)

11:09 justin_smith: sdegutis: given how often you like to revisit your decisions and start things over and second guess your designs, I could see you wasting a lot of time using haskell, and loving every unproductive minute of it

11:10 sdegutis: justin_smith: Heh so true, that's probably why I'm not in charge of making technical decisions ;)

11:10 justin_smith: At least I started keeping track of these things though! http://mutable.info

11:10 This way it's slightly easier for me to remember why I hold some decision.

11:11 patrickgombert: sdegutis: is anti-lisp still hosted somewhere?

11:12 sdegutis: patrickgombert: hi!!!

11:12 patrickgombert: :)

11:12 sdegutis: patrickgombert: Unfortunately I think it's gone forever :(

11:12 patrickgombert: but that's okay, because it was so incredibly awful in every way

11:12 It was more of a way for me to learn how to do things the hard way in C :)

11:13 patrickgombert: still working at 8L?

11:13 patrickgombert: sdegutis: yup

11:13 sdegutis: Still have open Friday afternoons?

11:14 bcm: have any of you guys looked at re-frame?

11:14 patrickgombert: yeah, I’ve been working on https://github.com/mylesmegyesi/clojure.core/ in my free time

11:14 sdegutis: patrickgombert: oh yeah I saw that, very nice

11:14 J_Arcane: patrickgombert: That's cool!

11:14 sdegutis: patrickgombert: if I come visit one of these Friday can I help with that?

11:15 patrickgombert: sdegutis: absolutely!

11:15 the amount of work going into it comes and goes in waves

11:16 J_Arcane: being a hosted language seems like a bit of a double edged sword for any language. Moving towards independence seems the safer way to go.

11:17 patrickgombert: yeah, performance is a big issue

11:17 sdegutis: Well, lots of people consider it a downside that Haskell "is its own platform", because that means it can't benefit from the libs on an existing platform (i.e. JVM).

11:18 But I think that's an insane objection, because Ruby is also its own platform, and it's doing fine. (And both have decent C FFI.)

11:18 patrickgombert: the independent version has a harder time adapting to things on its host platform

11:18 J_Arcane: I found myself wondering today if ES6 having TCO as part of the standard means ClojureScript will get full TCO before core does ...

11:19 sdegutis: By that logic, C is it's own platform, and no one complains about that ... ;)

11:19 Well, I do, but I'm nuts.

11:19 Glenjamin: patrickgombert: have you been following the dunaj stuff?

11:20 patrickgombert: I haven’t, I saw people talking about it earlier

11:20 I was going ot check it out over lunch

11:20 Glenjamin: it's worth a read, there's some stuff about re-doing core to use protocols first - which i'd imagine is similar to your host-agnostic stuff

11:21 sdegutis: Glenjamin: link?

11:21 Glenjamin: http://www.dunaj.org/guide.html

11:23 Bronsa: sdegutis: I was reading through the backlog -- saw your comment about tests breaking when updating to 1.6

11:23 sdegutis: 1.6 changed the way colls are hashed and thus how elements in unordered collections are "ordered". it's possible that some of your tests were relying on the order of unordered collecitons like maps or sets

11:24 sdegutis: Bronsa: hmm, that sounds like a huge part of it, yeah

11:24 Bronsa: the other part seems to have been that some map-like things (in Datomic) were "expanded" unexpectedly in one half of the = but not the other

11:24 Bronsa: sdegutis: a bunch of contrib libraries had the same buggy tests exposed while upgrading to 1.6

11:27 sdegutis: So far I really like the idea of Dunaj, but I wonder if it's still actively developed and how much community enthusiasm it's gained.

11:31 justin_smith: sdegutis: the guy is very active, too soon to see what the real engagement will be I'd say

11:34 Glenjamin: i'd like to see the Dunaj stuff presented at a clojure conf, and to see some productive movement on the back of that

11:47 BinaryResult: FYI in case you missed it yesterday, Disco Melee is hiring clojure devs http://www.reddit.com/r/Clojure/comments/301coc/disco_melee_is_hiring_clojure_developers/

11:59 J_Arcane: Is there somewhere I can read up more on when and where it's allowed to use (recur ...)?

12:00 justin_smith: J_Arcane: from the tail position, which means the value that would be returned from your function

12:02 J_Arcane: this one from racket is decent, though the syntax for racket is not identical to clojure of course http://docs.racket-lang.org/guide/Lists__Iteration__and_Recursion.html#%28part._tail-recursion%29

12:04 J_Arcane: Racket's my main language of experience. I'm specifically confused with Clojure here, and the (recur ...) form. Frex: https://www.refheap.com/98829

12:04 justin_smith: J_Arcane: recur is legal in places where racket would do TCO

12:05 in the second instance, can you see how the recur is not the form the function would return?

12:05 in that there is a * waiting to be called after it

12:05 which means it is not the tail, * is

12:08 the classic trick to making a function tco friendly is to add an argument representing a partial computation / accumulated state. So you would have two args to the recursive function, coll and total, and pass the new total to each recursion

12:08 J_Arcane: I suppose? But doesn't that also apply to (and) in the former case?

12:08 justin_smith: no, because and doesn't need to know what recur returns

12:08 whether it is truthy or not, it is guaranteed to be the return value

12:08 J_Arcane: Hmm.

12:09 justin_smith: ,(macro-expand '(and x y))

12:09 clojurebot: #error{:cause "Unable to resolve symbol: macro-expand in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: macro-expand in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: macro-expand in th...

12:09 justin_smith: ergh

12:09 ,(macroexpand '(and x y))

12:09 clojurebot: (let* [and__4187__auto__ x] (if and__4187__auto__ (clojure.core/and y) and__4187__auto__))

12:10 Morgawr: ,(and 3 4)

12:10 clojurebot: 4

12:10 justin_smith: ,(and 3 nil)

12:10 clojurebot: nil

12:10 justin_smith: ,(and 3 false)

12:10 clojurebot: false

12:10 justin_smith: with two args, if the first is truthy, the second is simply returned

12:10 in all cases

12:10 (unless the second throws an exception I guess and thus doesn't return...)

12:10 J_Arcane: Ahh, right, because and short circuits it doesn't need the old parts anymore, where as * still would have to use both first and rest in the final step of the expansion. IIUC.

12:11 justin_smith: right

12:11 it has work left to do

12:11 so it can't erase the call stack

12:11 Morgawr: ,(macroexpand-all '(and x y))

12:11 clojurebot: #error{:cause "Unable to resolve symbol: macroexpand-all in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: macroexpand-all in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: macroexpand-...

12:11 justin_smith: or, with recur, I guess we can say more accurately, can't erase the locals

12:11 Morgawr: ,(clojure.walk/macroexpand-all '(and x y))

12:11 clojurebot: #error{:cause "clojure.walk", :via [{:type java.lang.ClassNotFoundException, :message "clojure.walk", :at [java.net.URLClassLoader$1 run "URLClassLoader.java" 366]}], :trace [[java.net.URLClassLoader$1 run "URLClassLoader.java" 366] [java.net.URLClassLoader$1 run "URLClassLoader.java" 355] [java.security.AccessController doPrivileged "AccessController.java" -2] [java.net.URLClassLoader findClass "...

12:11 Morgawr: wait.. where's macroexpand-all from?

12:11 justin_smith: Morgawr: you need to require clojure.walk

12:11 Morgawr: I can do that in the bot?

12:12 justin_smith: yes

12:12 ,(require 'clojure.walk)

12:12 clojurebot: nil

12:12 Morgawr: ,(macroexpand-all '(and x y))

12:12 clojurebot: #error{:cause "Unable to resolve symbol: macroexpand-all in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: macroexpand-all in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: macroexpand-...

12:12 Morgawr: ,(clojure.walk/macroexpand-all '(and x y))

12:12 clojurebot: (let* [and__4187__auto__ x] (if and__4187__auto__ y and__4187__auto__))

12:12 Morgawr: there we go

12:12 ,(macroexpand '(and x))

12:12 clojurebot: x

12:12 Morgawr: alright, that's cool, enough botspamming :D

12:12 J_Arcane: This is one of the trickiest parts of Clojure for me compared to other Lisps or FP langs. XD It's been good practice for forcing more composition use, but now the course section I'm on is all about recursion.

12:13 Bronsa: recursion isn't used in clojure as much as in other lisps (mostly scheme)

12:13 Morgawr: I don't honestly use recursion as much, it's all nicely packed into proper already-existing functions that do most of what I need already.

12:13 justin_smith: J_Arcane: I think it's useful, because in another lang that does implicit TCO, you would think "it's safe to call this with a large arg, since it's a tail call", and not know you are wrong until it hits a large enough arg.

12:13 Morgawr: And the few causes I don't have such functions, I can use recur pretty transparently

12:13 justin_smith: in clojure it's much more explicit about the optimization

12:13 Morgawr: cases*

12:15 J_Arcane: justin_smith: Yeah, in Racket or Haskell, it's well optimized for all kinds of recursion, so I wouldn't give it a second thought, and in F# I'd just need to remember to write let rec instead of let. Clojure however is less forgiving re: falling back to a recursive solution, so it forces me to think more compositionally.

12:15 justin_smith: J_Arcane: "well optimized" - the Haskell version of product as written there would blow the stack for a large enough list

12:16 unless it somehow turns a non-tail call into a tail call?

12:16 agarman: J_Arcane: let rec is similar to clojur's recur in that both signal to the compiler to check that the function can be TCO

12:16 J_Arcane: justin_smith: Fair enough (my Haskell is pretty basic, you are very probably right).

12:17 And also in fairness, Racket is not necessarily the fastest of Lisp dialects at times.

12:17 Probably because sometimes it's so easy to write an unoptimal solution that's nonetheless 'fast enough'.

12:19 agarman: justin_smith: my understanding of haskell is that it's calling may or may not produce a new stack frame

12:19 which is same as scheme/racket

12:20 justin_smith: agarman: right, that's what I thought. but I wouldn't put it past those brilliant folks to find a magical conversion that turns naive recursion into tail recursion programatically.

12:20 probably some operation named after a greek letter

12:20 agarman: it just passes the stack's return point along...

12:21 J_Arcane: justin_smith: sufficiently advanced Haskell is indistinguishable from magic ... ;)

12:21 justin_smith: agarman: yes, that's how tco works, but tco isn't possible if you don't recur from the tail position

12:21 agarman: justin_smith: I've done some pretty impossibly non-Tail eliminatible things in haskell and Scheme and never seen a stack overflow

12:22 justin_smith: agarman: for inputs of what size?

12:22 agarman: https://wiki.haskell.org/Tail_recursion

12:22 djames_: instead of (or (pred-1 v) (pred-2 v) ...) I'd like to use (or-fn pred-1 pred-2 ...). Instead of rolling my own, is there a library with this sort of thing already? I looked at Medley -- not there

12:22 justin_smith: agarman: I mean if it can't be a tail call and you call recursively anyway, yeah you can do that in clojure too

12:23 sdegutis: justin_smith, J_Arcane: which product definition are we talking about?

12:23 justin_smith: and I know for a fact scheme doesn't have any rewriting magic to make it work (unless you count stalin)

12:23 sdegutis: https://www.refheap.com/98829

12:24 agarman: justin_smith: haskell & scheme have different semantics for 'call' that do not care if your tail can be eliminated or not. And you can write truly functional programs because your function composition doesn't build stack

12:24 bja: anyone know how I might declare using prismatic/schema that a fn has the input schema Foo that I happen to already have around

12:24 sdegutis: justin_smith: oooh I see, the * makes it not tail positino

12:25 justin_smith: agarman: it will build stack unless it can be eliminated, and yes, function composition can be eliminated, because the calls are all in the tail position

12:27 sdegutis: Optimizing your own functional code has to be one of the most boring tasks.

12:29 djames_: to reply to my own question: `any` from amalloy/useful is eponymous https://github.com/amalloy/useful/blob/develop/src/flatland/useful/fn.clj#L82

12:30 justin_smith: djames_: I wonder if that is different from some-fn ?

12:30 (doc some-fn)

12:30 clojurebot: "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns the first logical true value returned by one of its composing predicates against any of its arguments, else it returns logical false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical true result against the original predicates."

12:31 djames_: justin_smith: spot on, many thanks, as always

12:33 agarman: justin_smith: just re-read info on Racket, you're correct that it does TCO, but its stack is only bound by available memory (which can be an issue).

12:34 {blake}: cfleming: Cursive no work with IntelliJ 141.177?

12:34 agarman: justin_smith: haskell however does not do TCO at all.

12:34 justin_smith: agarman: OK, but laziness gives it effectively the same result

12:35 agarman: yep

12:35 gfredericks: anybody ever run into CLJ-1237?

12:35 agarman: that's what I was getting at before...is that call-by-need obviates TCO

12:35 justin_smith: agarman: ahh, now I get it

12:36 agarman: justin_smith: yay!

12:38 justin_smith: and I'm pretty sure my confusion with racket was caused by #lang lazy

12:38 justin_smith: aha

12:38 sdegutis: Anyone here using Boot?

12:39 I'm having hecka time trying to port project.clj to build.boot

12:40 J_Arcane: Kinda weird actually that this course I'm talking doesn't yet really address stack-safe recursion in Clojure yet in this section ... All the code is basically classic scheme style, which I guess is fine for toy examples.

12:41 agarman: J_Arcane: material probable taken from the numerous Scheme teaching resources

12:41 J_Arcane: http://iloveponies.github.io/120-hour-epic-sax-marathon/recursion.html

12:42 justin_smith: that's a great URL

12:43 agarman: J_Arcane: next page is about recursion that's safe

12:43 J_Arcane: :D Yeah. From the University of Helsinki MOOC.

12:43 agarman: Good to know. I figured they'd get to it, maybe I should just follow directions now and get to writing proper (recur) calls later ...

12:44 justin_smith: if you're lucky they'll cover trampoline too

12:44 agarman: yeah, (recur) shouldn't be common in your code though

12:44 there's usually better built-in constructs that recur for you

12:44 J_Arcane: Yeah.

12:45 That's been my general impression, and I've tried to stick to that in the stuff I've written too.

12:45 agarman: justin_smith: I didn't see trampoline in the three pages I skimmed through

12:45 J_Arcane: My (my-every? ...) above got rewritten as a map-reduce frex.

13:17 kovasb: cemerick whats up man

13:22 black13: how do i call or wrap a dll from clojure?

13:26 dah: black13: jni?

13:26 black13: i was affraid of that.

13:26 dah: never used it on windows, but i expect you can load dlls

13:26 justin_smith: black13: I think the best bet is clojure-jna https://github.com/Chouser/clojure-jna

13:27 dah: woah cool

13:27 justin_smith: dah: looks pretty good from the examples

13:28 dah: indeed

13:28 sdegutis: I think I finally may have build.boot working!

13:29 justin_smith: dah: likely the process would be figuring out the right system call on your platform for loading a dynamic lib, then calling that... then binding its functions of course

13:29 on a posix/*nix type system you would use ldload from libc

13:30 err, I mean dlopen

13:30 mikerod: Has anyone seen Clojure's Compiler get into a very long compilation "cycle" where it follows a path like : IfExpr#hasJavaClass -> LocalBindingExpr#hasJavaClass -> LocalBinding#hasJavaClass : repeating a lot

13:30 I do not have an example to recreate it yet.... trying

13:31 I do know I've seen it coming from a FnExpr body

13:31 sdegutis: ,(cons 1 (cons 2 (cons 3 (cons 4 ())))) ;; cool

13:31 clojurebot: (1 2 3 4)

13:31 justin_smith: ,(conj () 4 3 2 1)

13:31 clojurebot: (1 2 3 4)

13:32 mikerod: I was just curious if someone has some insight into this sort of issue - known defect or something. We thought it was an infinite looping situation, but it actually compiled successfully after about 1,000 seconds.

13:32 dah: justin_smith: i was going to do a raspberry pi project in python to avoid jni -- maybe i'll try clojure instead

13:32 justin_smith: dah: see also pixie

13:33 Bronsa: mikerod: are there recurs?

13:34 sdegutis: justin_smith: whoa

13:35 mikerod: Bronsa: No

13:35 Bronsa: mikerod: in case of auto-boxing loop args, the compiler might repeat analysis, if you have a lot of *nested* loops where loop args boxing is required that might explode

13:35 mikerod: then I have no idea and would be curious to see an example :)

13:35 mikerod: Bronsa: I do not think I'm in that sort of situation.

13:35 Ugh I want an example to demonstrate, the one I had was too proprietary and also too convoluted

13:36 sdegutis: Anyone here have thoughts on Boot.sh?

13:36 It's an alternative to Leiningen for most projects.

13:36 dah: justin_smith: looks newat

13:36 sdegutis: It's closer to Gulp than Grunt afaict.

13:36 dah: er neat

13:36 mikerod: I'll continue to try to get a case that is the same situation

13:37 We do have a type hint for Java involved, but nothing fancy l ike recur or boxing

13:37 Bronsa: mikerod: fyi "IfExpr#hasJavaClass -> LocalBindingExpr#hasJavaClass -> LocalBinding#hasJavaClass" is not unusual at all, that just means you have a local used in one of the return branches of an if expr

13:39 SagiCZ: whats the trick to doseq over a collection and have the index as well?

13:39 (doseq [[i item] ... coll..] ..)

13:40 schmir: SagiCZ: map-indexed

13:40 SagiCZ: no it was different

13:40 ambrosebs: (doseq [[i item] (map-indexed vector coll)] ) something like that?

13:40 SagiCZ: i dont need map-indexed.. i have the indexes via (range ..)

13:41 (doseq [[i item] (range (count coll)) coll] ..)

13:41 ambrosebs: (map vector rgns coll)

13:41 mikerod: Bronsa: yes, we sure do :)

13:41 justin_smith: sdegutis: that doesn't work though

13:41 mikerod: Bronsa: when I'm trying to make a minimal case, it just compiles fast and fine

13:41 SagiCZ: ambrosebs: i think thats it thanks

13:41 justin_smith: err I mean to say that to SagiCZ

13:41 sdegutis: justin_smith: what?

13:41 oh

13:42 mikerod: Bronsa: it looked somewhat like this https://www.refheap.com/98831

13:42 but this compiles no problem

13:45 Bronsa: mikerod: I see nothing weird there, probably impossible to tell without an actual repro case

13:46 mikerod: yep :(

13:46 doing some VisualVM certainly shows that loop we discussed above happening a lot of times

13:46 dah: justin_smith: don't see anything about concurrency yet, which is a deal breaker for my project. looks super promising though

13:47 mikerod: hopefully I can get an actual reproduction of it. it was a stab in the dark to see if anyone knew of something related that is already posted somewhere. :P

13:47 hard to Google search these things.

13:47 justin_smith: dah: yeah, it uses rpython, which doesn't support real threads yet. It's possible to do concurrency via fork and anonymous pipes (I've done it), but it isn't as simple as clojure concurrency

13:48 dah: but really, it will not do anything less than python would concurrency wise

13:48 (for the same reason, it's generated via rpython)

13:50 dah: justin_smith: sure, although i'd probably end up using cpython for library compatibilty and end up with the GIL

13:51 justin_smith: dah: also, ocaml has similar GIL issues, but does interop with native libs quite easily, and has better perf than any other option mentioned so far

13:53 dah: justin_smith: my app is continuously reading a stream from a serial port and occasionally writing a circular h264 buffer to disk. i bet green threads would be fast enough but i might start losing serial data if i block on the pi's slow IO

13:53 probably should just try and see

13:54 freddd: looking for a little update-in help if anyone's around. in a command like (update-in lists [(keyword list)] conj item), if the (keyword list) doesn't exist, is there a way to enforce that it should be created as a set?

13:55 Bronsa: freddd: replace conj with (fnil conj #{})

13:55 ,(update-in {} [:foo] (fnil conj #{}) 1)

13:55 clojurebot: {:foo #{1}}

13:56 freddd: Bronsa: wow, thanks.

13:57 SagiCZ: how would i construct a map that keeps the order i used in its literal when calling seq on it?

13:57 Bronsa: SagiCZ: you can't using regular clojure maps and map literals

13:57 SagiCZ: ,(seq {:a 0 :b 4})

13:57 clojurebot: ([:a 0] [:b 4])

13:58 SagiCZ: what can i do?

13:58 Bronsa: use something like flatland/ordered

13:59 SagiCZ: ok i just want to sort it by its values

13:59 which are strings

13:59 Bronsa: then just use a sorted-map with the appropriate comparator

13:59 justin_smith: sorted is fine, sorted-map

13:59 yeah

13:59 freddd: Bronsa: looked up fnil and it looks like it could come in handy pretty often. thanks again!

13:59 Bronsa: freddd: fnil in combination with update-in really rocks

14:00 or assoc-in

14:00 no nevermind, just update-in :P

14:16 Shayanjm: Does anyone know of a good library that would allow me to do some 3D calculations & modeling? I'm trying to model a sphere and some entities drawn on it but incanter doesn't seem to support it :\

14:21 sdegutis: Would an intense disdain for .jars and the JVM tooling be justified?

14:22 arrdem: why would you even ask that question in a JVM oriented channel?

14:22 what response do you think that could possibly elicit?

14:22 sdegutis: arrdem: I figure there are probably level-headed and objective people in here who recognize and admit to downsides of the tools they use and prefer.

14:23 Shayanjm: sdegutis: the jvm adds enough niceness that we overlook some of the flaws ;)

14:23 ntaylor: also, "level-headed" doesn't usually mesh with "intense disdain"

14:23 sdegutis: Are such flaws even legitimate flaws, or are they usually just based on a misunderstanding of the pros and cons?

14:25 Bronsa: sdegutis: you didn't describe any of the flaws you're talking about

14:25 sdegutis: I'm just watching the output of compiling Boot (which turns out to be a JAR embedded inside a shell script), and it's just making me wonder why all the hassle it's going through is necessary compiled to more traditional compilation techniques.

14:25 (Also it's taking forever to compile.)

14:26 Bronsa: that has probably nothing to do with "jars and jvm tooling" as it has to do with clojure compilation times?

14:26 ntaylor: well, not to pile on, but Boot isn't "the JVM tooling", for one thing

14:26 sdegutis: Bronsa: well I don't fully understand how it works.. I just know that it takes a lot longer than in other compiled languages, and it has very strange file requirements (POM, XML, etc) and file hierarchies.

14:27 ntaylor: imho there isn't such a thing as a build system that isn't strange, just build systems you might not know the idioms for

14:27 sdegutis: good point :)

14:30 ntaylor: a lot of the complexity of building on the JVM stems from the multi-platform nature of it - it's a lot easier for a project compiled with, say, autoconf, since it reasonably knows where to find dependent libraries and whatnot

14:31 if you can't reason about your underlying system, complexity that might be abstracted away gets pushed back up

14:32 which, to be sure, is a major bummer and all, but as Shayanjm says, it's not like you're trading something for nothing

14:32 justin_smith: ntaylor: in my experience there is nothing simple or easy about autoconf

14:32 probably some of the ugliest open source code in wide usage

14:33 ntaylor: justin_smith: what's not to love about M4 :)

14:33 freddd: another question if anyone's around: if i have an atom that contains a set, i know I can add with conj, but is there a way to remove without reset?

14:33 justin_smith: ntaylor: I've seen nice m4 code, but not in autoconf

14:33 timvisher: ,,(inc Long/MAX_VALUE)

14:33 justin_smith: freddd: disj

14:33 clojurebot: #error{:cause "integer overflow", :via [{:type java.lang.ArithmeticException, :message "integer overflow", :at [clojure.lang.Numbers throwIntOverflow "Numbers.java" 1501]}], :trace [[clojure.lang.Numbers throwIntOverflow "Numbers.java" 1501] [clojure.lang.Numbers inc "Numbers.java" 1839] [sandbox$eval25 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler eval "Compiler.java" 6784] [clojure.lang.Com...

14:34 timvisher: i thought it autoboxed up into BigInteger

14:34 justin_smith: ,(inc' Long/MAX_VALUE)

14:34 clojurebot: 9223372036854775808N

14:34 ntaylor: (but, I mean, that was part of what I was trying to get at. It's easy to say "this is so much worse than the build process for compiled language" until...)

14:35 freddd: justin_smith: perfect. thanks!

14:37 ntaylor: imho part of the problem is that it's easy to write a makefile for a small to medium C project that's totally understandable, whereas the equivalent project managed by maven or sbt or whatever has a lot more going on, so folks naturally towards complaining about "jvm complexity"

14:37 (similar to the "why is HelloWorld.java thirty lines long" complaint)

14:41 the-kenny: That's because java is way too verbose :)

14:42 ntaylor: just like maven :)

14:43 justin_smith: has anyone looked at maven's new multi-syntax support? we could likely get maven supporting project.clj files

14:43 ntaylor: oooh

14:44 justin_smith: it's very new iirc

14:45 ntaylor: yeah, it's new to me at least

14:45 that'd be awesome

14:45 justin_smith: one minute, trying to find my source again...

14:46 "maven escapes from xml" http://www.infoq.com/news/2015/03/maven-polyglot?utm_source=reddit&utm_medium=link&utm_campaign=maven%20polyglot

14:46 they show a yaml example

14:47 if it can do yaml, I bet we can make it do edn

14:48 https://github.com/takari/polyglot-maven-examples

15:00 amalloy: justin_smith: https://github.com/takari/maven-polyglot/tree/master/polyglot-clojure/src/main/clojure ?

15:01 H4ns: is cider broken for anyone else or is it just me? i get complaints about missing nrepl ops and unbound variables.

15:01 gfredericks: I can't recall anybody ever claiming that cider was not broken

15:01 amalloy: it's linked to from polyglot-maven-examples, but i can't really tell if it's the thing you want or what

15:02 justin_smith: amalloy: cool, I didn't find that before

15:02 it may be

15:02 H4ns: make sure your nrepl dep in profiles.clj is under the dev profile

15:03 H4ns: justin_smith: thanks, but it is there with the correct version.

15:04 hm, but it is listed as dependency, not as a plugin.

15:04 justin_smith: cider is a plugin, nrepl is a dep

15:04 H4ns: cool, moving cider/cider-nrepl from :dependencies to :plugins fixed the issue.

15:04 justin_smith: *bow* thank you!

15:04 justin_smith: oh wait, to be clear I am talking about cider-nrepl the plugin, and tools.nrepl the dep, both need to be on the right version

15:05 cool

15:05 H4ns: I find it amusing how often I can help people get cider working, while I never have the patience to keep it working myself

15:06 H4ns: justin_smith: it is a drag, but somehow i am under the belief that i can't live without it.

15:06 justin_smith: what's the alternative if i want M-. and tab completion for symbols?

15:06 justin_smith: H4ns: not sure really, I just don't use those features.

15:08 timvisher: H4ns: fwiw, .lein/profiles.clj can have this in the :user profile and it should work accross all your projects

15:09 you really only need it in your project.clj if you want to include an nrepl server in prod i think

15:09 H4ns: timvisher: i actually need to have it attached to our main project so that we can run the development environment on all boxes easily.

15:09 justin_smith: timvisher: with new versions, tools.nrepl needs to be under :dev in profiles.clj

15:10 timvisher: as far as alternatives, last i heard cursive isn't using nrepl at all (^_^)b

15:10 justin_smith: oh, there is that!

15:10 timvisher: justin_smith: that's probably true. i'm talking about the cider-nrepl plugin :)

15:10 justin_smith: which breaks with the wrong tools.nrepl version

15:10 timvisher: H4ns: sure

15:10 justin_smith: which means an explicit dep needed

15:11 thanks to a leiningen interaction

15:11 timvisher: hah

15:11 clojure tooling

15:11 it's not the worst…

15:15 H4ns: that is a comforting thought

15:24 ntaylor: timvisher: for my part, coming to Clojure from Scala, I was astonished at how good the tooling is

15:25 (it's not that sbt et al. are that terrible, but they're disliked enough in the community that everybody rolls their own half-baked and not-terribly-good reimplementations, so nothing is consistent and nothing else has the critical mass to gain traction)

15:30 Bronsa: mikerod: did you figure anything out?

15:46 hamid: guys would anyone help me to overcome this http://clojurescriptkoans.com/#destructuring/7?

15:46 i dont get this one. :/

15:47 amalloy: man, i gotta say making you call str on some keywords doesn't feel like a great koan plan to me

15:49 hamid: http://clojurescriptkoans.com/#destructuring/7

15:50 mikerod: Bronsa: no, can't recreate. removed the issue by removing a `cond->` though...

15:50 which we replaced with pretty much our own rollled cond->

15:50 very weird, but I can't get it to be a minimum case

15:58 Bronsa: it looked more like this https://www.refheap.com/98831

16:01 bja: is it crazy to think that clojure.lang.Keyword/intern should be overloaded to accept a (Namespace, Str) argument in addition to (Str, Str)?

16:01 mikerod: In its use of `cond->`. we just removed the `cond->` by replacing it with our own, I put that on the refheap too

16:01 but note that neither example revealed the issue. but it is very close. I just can't get it to be slow with the rest of the projects contexts involved and there is a lot of stuff there

16:02 bja: was exploring and noticed that (= ::foo (keyword *ns* "foo")) which seemed weird (you have to convert *ns* with str first)

16:02 err, (not (= ...))

16:02 amalloy: bja: i'd certainly appreciate a similar change to clojure.core/symbol: ##(symbol 'foo 'x), for example

16:02 lazybot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String

16:03 szatz: can anyone help with an import question? most imports i've used allow me to import several classes in a single go, like [java.net ServerSocket Socket]. however, [javax.mail Session] doesn't work, while [javax.mail.Session] does. any insights?

16:03 gfredericks: szatz: that second one might be a NOOP

16:04 om: szatz: have no problem with [javax.mail Session Folder Flags Flags$Flag] in a piece of code right now! what version do you use?

16:04 amalloy: yeah, that second one doesn't do anything

16:05 er, the last one, which i guess is the third

16:05 gfredericks: yeah "third" is what I meant by "second"

16:07 szatz: gfredericks, amalloy: hm, you're right.

16:07 om: java 8/clojure 1.6

16:08 amalloy: szatz: you probably don't have javax.mail classes on your classpath? i don't think it comes with the runtime

16:08 om: szatz: and javax.mail "1.5.2"?

16:08 (inc amalloy)

16:08 lazybot: ⇒ 241

16:10 szatz: amalloy: ok, i'll give that a go.

16:11 om: couldn't say. i thought it was just sort of "there."

16:11 om: szatz: use [com.sun.mail/javax.mail "1.5.2"] in your boot / lein / maven config

16:12 irctc_: An argument expansion question, using clojure.java.jdbc. How would you expand an arg list inside a vector. Explicit values in the vector: (jdbc/query db [prepared-statement val1 val2 .. valN]) I have (def bind-values '(val1 val2 valN)) How does one expand bind-values in the vector after the prepared-statement?

16:14 schmir: irctc_: (apply vector prepared-statement bind-values)

16:15 szatz: om: yes, that works perfectly. thanks.

16:16 om: szatz: you're welcome

16:20 irctc_: schmir: thank you! perfect!

16:29 ortuna: How can I resolve a string into a var? `(def a "test")` want refer to "a" as the var.

16:29 Bronsa: ,(def a "test")

16:29 clojurebot: #'sandbox/a

16:29 Bronsa: ,(resolve (symbol "a"))

16:29 clojurebot: #'sandbox/a

16:34 ortuna: Bronsa: Thanks! That worked. Would it also be possible to refactor for a let binding? refer to `a` inside a `(let [a "test"])`

16:34 amalloy: ortuna: no

16:34 Bronsa: ortuna: no, that'll require plugging into the compiler internals

16:35 not impossible, but I wouldn't do that.

16:36 ortuna: gotcha, thanks for your help!

16:37 EnglishGent: hoping someone can help me with an oddity (I am new) - because this is baffling me

16:37 sveri: Hi, I have a list of maps with nested maps and lists and another list with a path. Now I want to traverse the first list down to the paths endpoint. It's a bit hard to explain, but here is an example: http://pastebin.com/t7akxr9k maybe some of you has an approach to that? reduce only takes on sequence to iterate on

16:37 EnglishGent: I have Leinengen & Clojure working fine from the command line

16:37 I have Cider apparently successfully installed on emacs

16:37 but when I do 'cider-jack-in' - I get a message in the mini-buffer area - I do not get the window split to see a repl

16:38 and when I switch to the 'repl buffer' - it does not contain the connection message, does not show a prompt

16:38 and does not appear to respond in any way to what is typed into it

16:39 if I do 'lein repl' I get an error about a socket

16:39 martin@olympian:~/clojure-noob$ lein repl

16:39 nREPL server started on port 49248 on host - nrepl://

16:39 ERROR: Unhandled REPL handler exception processing message {:id ce4c00fe-7ce8-4815-b2fd-fea2d4cb5ded, :op ack, :port 49248}

16:39 java.net.SocketException: Socket closed

16:39 though the repl then seems to work just fine

16:40 any help appreciated! :)

16:40 bacon1989: that's weird

16:41 you're going to have to work out the socket issue, since cider communicates to your repl server through TCP sockets

16:41 try checking to see if you have any other running java instances running a repl

16:41 it might be conflicting with another process using that port

16:41 EnglishGent: ok - let me have a lok

16:41 look*

16:43 okay *now* there are no other java processes running

16:43 let me try from scratch

16:45 nope - same problem :/

16:46 okay... I'm going to do an dist upgrade first - see if that helps

16:46 I'm pretty sure I shouldn't be seeing socket errors when running lein repl from a terminal

16:46 I've never seen that before

16:46 I suspect that must be where the issue lies :|

16:54 I'm not sure this has improved things... now the "starting nRepl server" message doesn't get replaced with a connection string

16:54 *and* the window doesn't split

16:55 *but* - if I try firing up a shell & doing 'lein repl' in that - I no longer get any errors about sockets

16:55 * EnglishGent wonders wtf is going on

16:55 EnglishGent: :|

16:58 gfredericks: EnglishGent: does it say what version of nrepl is running?

17:00 EnglishGent: If I start if from the shell "nREPL server started on port 49362 on host - nrepl://

17:00 REPL-y 0.3.5, nREPL 0.2.6

17:00 Clojure 1.6.0

17:00 "

17:00 This time no errors about sockets

17:01 Is there a way to tell cider to connect to a known repl on a known port? that might be worth trying

17:01 sdegutis: Anyone else feel like we have either too many or too few programming languages?

17:01 I alternate between those every day.

17:03 EnglishGent: sdegutis - I just always wind up wanting to use a feature from a language that is *not* the one I am writing the code in :)

17:03 sdegutis: lol

17:03 Bronsa: i feel like all I read from you is random complaints that have most of the time little to do with clojure

17:03 sdegutis: tower of babel all over again

17:03 Bronsa: good point, my apologies

17:04 kludgecode: ,(def r {:p 1 :d 2})

17:04 clojurebot: #'sandbox/r

17:04 kludgecode: ,(:p r)

17:04 clojurebot: 1

17:04 kludgecode: ,(r :p)

17:04 clojurebot: 1

17:04 gfredericks: EnglishGent: yeah M-x cider lets you specify a port; nrepl 0.2.6 has a nondeterministic bug that might be related

17:04 kludgecode: Who needs Perl?

17:05 xemdetia: kludgecode, I need perl :(

17:05 please don't take my perl away

17:06 kludgecode: How bout if we give it a new number?

17:06 And make it backward breaking?

17:06 EnglishGent: thanks gfredericks :)

17:06 gfredericks: thef

17:06 np

17:08 ortuna: does `with-redefs` work with a namespace that has `(require [something :as new-something])` if I do (with-redefs [something/my-fn.... doesn't work?

17:08 gfredericks: it should work

17:09 how does it not work?

17:09 ortuna: hmm so something I'm doing

17:09 it's calling the original which is inside a function I'm testing

17:10 gfredericks: is there laziness involved that would cause the code to not run until after the with-redefs completes?

17:10 Bronsa: either lazyness or inlining can break with-redefs

17:10 gfredericks: where inlining only happens for low-level arithmetic & such in clojure.core

17:10 Bronsa: yeah

17:11 EnglishGent: no - that still doesn't help :/

17:12 gfredericks: what doesn't?

17:12 EnglishGent: where would you get the cider from marmalade or melpa

17:12 trying to connect it to an existing server

17:12 again - I get no errors, but when asking it to show me the repl

17:12 I get a buffer with no content which just ignores what ever is typed into it

17:13 gfredericks: that happens to me sometimes and if I just kill the buffer and try again once or twice it works

17:13 #ciderlife

17:15 how do you inferior lisp folks get docstrings? do you have to walk al the way to your repl and type things into it?

17:15 like a caveman?

17:20 ortuna: Bronsa gfredericks thanks, it was lazyness :/

17:21 gfredericks: somebody should do a talk on conciously segmenting your code into dirty imperative stuff and clean functional stuff

17:21 xemdetia: gfredericks, they should. that would probably be a fantastic starting point to say 'why functional'

17:22 gfredericks: laziness interacts with that idea a lot in clojure

17:22 patrickgombert: gfredericks: Gary Bernhardt did a “functional core, imperative shell” talk

17:23 gfredericks: oh cool

17:24 patrickgombert: I think that this is a variation of that talk: https://www.destroyallsoftware.com/talks/boundaries

17:24 EnglishGent: that approach only works if you don't call *any* higher-order functions in the pure core with not-so-pure functions as arguments

17:25 gfredericks: why would the pure code be using not-so-pure functions as arguments?

17:26 EnglishGent: it's an easy mistake to make when writing the shell code to think that as I am calling a pure function there cannot be any side effects - regardless of what arguments I give it

17:26 gfredericks: oh hey the talk is about the value of values :)

17:26 EnglishGent: this is wrong - 'map' is a pure function... but pass it an impure one as it's first argument & now it has side effects

17:27 gfredericks: I like doseq better than map for side effects

17:27 mostly because it looks a lot more like the imperative shell

17:27 EnglishGent: so do I - but it was the quickest example that spranf to mind :)

17:27 sprang*

17:28 * EnglishGent admits to liking Haskell as well

17:29 EnglishGent: so I have smacked my head against the impure / pure distinction a few times :)

17:29 ortuna: so, I have a more broad question. I feel like I'm testing too much, is there a good project to read their tests that you think are a good example? (I'm coming from ruby)

17:30 gfredericks: yeah haskell is a big fan of that

17:30 "Separate your code or we'll make you use this monad."

17:30 ortuna: do high-level tests with test.check

17:34 Lewix: im going thourhg clojure programming book - it's quite dense

17:34 what do you guys think of it?

17:34 ortuna: gfredericks: Thanks, watching the talks now

17:35 Lewix: ortuna: don't test private methods

17:35 gfredericks: unless you want to

17:35 cfleming: timvisher: Cursive has exclusively supported nREPL pretty much forever - I'm actually just adding support for non-nREPL REPLs right now.

17:38 Lewix: ortuna: I'm also coming from ruby - How far did you get in the clojure ecosystem

17:42 ortuna: Lewix: I'm not really sure :) I read http://www.amazon.com/gp/product/B007Q4T040 , I did learn elixir some time ago, and a lot of the concepts are 1 to 1 with clojure (and I'm guessing with functional programming)

17:45 I've not written any macros yet, but I understand the concept from Elixir. They always said it was an "exceptional" thing to write a macro so far in clojure it seems like a true statement as well

17:48 actually now that I think of it, I had a very specific task I needed to do: generate a pdf for my Ruby site: http://commits.io , PrawnPDF was taking 30 secs to generate a PDF. I used clojure w/ clj-pdf and created a microservice for the PDF and was able to generate a huge PDF in 3 secs as opposed to 30 secs.

17:48 Lewix: ortuna: omg thats the one I'm reading - how far did you read it

17:49 ortuna: cover to cover :D

17:49 Lewix: ortuna: amazing

17:49 ortuna: Its a good book, I feel its complete

17:50 Lewix: ortuna: i love it

17:50 ortuna: your website

17:51 shameless plug though

17:51 ortuna: heh, yeah. Probably the only time I'm able to talk about it in a conversation :D

17:52 Lewix: ortuna: the book seems endless though (so big) aha

17:52 dah: my take on macros is that you only use them when you want to create something akin to a language feature

17:52 Lewix: ortuna: are macros kind of like ruby dsl stuff

17:53 dah: i think another way to say it is "when you want to stray from the default evaluation semantics"

17:53 gfredericks: Lewix: ruby uses DSLs too often

17:54 Lewix: gfredericks: ya i guess

17:55 ticking: Lewix: they are way more

17:55 they are like a compiler step that you can define

17:56 enfocus for example uses this to precompile minimal html templates into cljs code

17:57 Lewix: ticking: i see. anyways ill talk to you later. i need to do some more reading

17:57 have a good one

17:59 ortuna: Anyone know of a Clojure project that needs help and is beginner friendly?

18:00 justin_smith: Nothing on our side of things establishes the job's folder.

18:08 OOPS

18:09 amalloy: too late, justin_smith. now we know your job involves folders

18:09 corporate espionage via idling in irc

18:09 turbofail: we're pretty much guaranteed to beat them to market now

18:09 justin_smith: haha

18:13 EnglishGent: well I'm making progress - I've established it's *something* in my emacs config ... becuase if I use a completely fresh one with just cider - it works fine

18:13 oddcully: ,(symbol (name :foo))

18:13 clojurebot: foo

18:14 oddcully: is there a shortcut for this?

18:14 Bronsa: ,(.sym :foo)

18:14 clojurebot: foo

18:14 amalloy: Bronsa: :(

18:14 Bronsa: oddcully: implementation detail though

18:15 amalloy: yeah, i know..

18:15 oddcully: means? we mortals should not use it?

18:15 Bronsa: oddcully: exactly

18:16 oddcully: each time you do that a puppy dies etc

18:16 oddcully: ok, i stick with the "complicated" one

18:16 thanks anyway

18:16 (inc Bronsa)

18:16 lazybot: ⇒ 98

18:16 fryguy: guys, can I ask a huge troll-y question? sorry in advance :( I'm a long-time vim user. Is cider worth trying to switch to emacs, or is fireplace "good enough"

18:16 amalloy: honestly anytime you are cnoverting a keyword to a symbol yourself, by any means, you are usually doing something wrong

18:16 justin_smith: fryguy: I'd guess fireplace might be better, at least if you care about stability.

18:16 amalloy: fryguy: fireplace is fine

18:17 stick with vim

18:17 justin_smith: fryguy: cider is notorious for its instability.

18:17 fryguy: there's some pretty reasonably packaged emacs+evil kits out now (spacemacs looks especially promising), but just trying it out things still felt very foreign to me. Wasn't sure if I was missing out on anything super noteworthy

18:17 ambrosebs: fryguy: I use fireplace. Only downside in practice to me is vim is single threaded

18:18 justin_smith: emacs is single threaded too

18:18 ortuna: fryguy: https://github.com/krisajenkins/EvilBegins , been trying it off and on

18:18 justin_smith: it will totally lock up if you start like printing super long lines in a cider repl buffer

18:18 I use the evil mode in emacs, because I don't hate my hands.

18:18 fryguy: ortuna: I just saw that and tried it. The out of the box experience for spacemacs seemed better.

18:19 ambrosebs: ok didn't know that

18:19 oddcully: amalloy: right now i am playing around with instaparse and look up a form in transform

18:19 justin_smith: but I wouldn't switch to emacs for the clojure tooling. If you need like org mode or whatever, sure try it out.

18:19 ambrosebs: but also check out Cursive

18:19 fryguy: but yah, I don't want to derail this too far, I realize this is a super troll topic, the fact that several people here are actually using fireplace and you aren't all emacs users is enough for me to at least stick with it for now.

18:19 justin_smith: yeah, cursive is probably the best tooling for clojure out there right now, and some people use it just for the debugging support even if they don't use it as a regular editor.

18:20 Lewix: hey

18:20 gfredericks: emacs: come for the org-mode, stay for the org-mode.

18:20 justin_smith: fryguy: I can't recall ever seeing a real editor flamewar here

18:20 (inc gfredericks)

18:20 lazybot: ⇒ 128

18:20 gfredericks: ,(* 2 2 2 2 2 2 2)

18:20 clojurebot: 128

18:20 ambrosebs: also proof-general. best thing ever.

18:21 justin_smith: ambrosebs: fascinating, I'll have to check that out

18:21 amalloy: fryguy: i think most of the people who told you to stick with vim are emacs users. it's just that there's more useful things to do than pointless flamewars

18:22 Lewix: i don't understand this piece of code https://gist.github.com/6ewis/366d4aec2228e86d0ad2

18:22 amalloy: Lewix: well for starters it doesn't work, because there's a space in `log-> file`

18:23 justin_smith: Lewix: I think there is an extraneous space on line 8

18:23 yeah, what it intends to do is take a file name and return a function that would log to that file

18:23 Lewix: amalloy: ok , beside that I don't understand line 5, and i also dont get line 8 to 9 (what's the -> operator for)

18:23 justin_smith: Lewix: are you familiar with #() syntax?

18:24 Lewix: justin_smith: anonymous functions

18:24 justin_smith: Lewix: -> is not an operator

18:24 amalloy: Lewix: -> is just part of the function name

18:24 justin_smith: it's just part of names

18:24 amalloy: "log->file" is supposed to mean "log to file" but imo it's a pretty dumb name

18:24 justin_smith: which is why log->file is not the same as log-> file

18:24 Lewix: it seems to me that with-open has three arguments

18:25 justin_smith: Lewix: what makes you think that?

18:25 it takes a binding vector and a body

18:25 Lewix: justin_smith: i see. so it's part of the name. ok I get part 2 , what about part 1/

18:26 justin_smith: right isn't the body the third arg?

18:26 justin_smith: it is args 2 through N

18:26 Lewix: (( print-logger f) %))

18:26 justin_smith: that's one argument

18:27 Lewix: 1. why so many parenthesis?

18:27 justin_smith: it's the function returned by (print-logger f) called with the first arg to the function as its argument

18:27 Lewix: 2. what does it do with this second arg (if you count your args 0-based)

18:27 justin_smith: print-logger takes a stream to write to (I'm inferring) and returns a function that writes to it

18:28 Lewix: I don't see where you call anything a third argument

18:28 and no, it is not 0 based

18:28 first argument is [...]

18:28 Lewix: justin_smith: ah sorry second*

18:28 justin_smith: second is (...) after it

18:28 two arguments

18:28 not zero based

18:28 (print-logger f) returns a function, I assume it returns a function that writes to f

18:29 Lewix: why the extra parenthesis?

18:29 justin_smith: that function is called with % as an arg

18:29 that's why the extra parens

18:29 you are calling the result of a function call

18:29 ,(#(+ % %) 4 5)

18:29 clojurebot: #error{:cause "Wrong number of args (2) passed to: sandbox/eval26/fn--27", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (2) passed to: sandbox/eval26/fn--27", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 36] [sandbox$eval26 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler e...

18:29 justin_smith: ,(#(+ % %1) 4 5)

18:29 clojurebot: #error{:cause "Wrong number of args (2) passed to: sandbox/eval53/fn--54", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (2) passed to: sandbox/eval53/fn--54", :at [clojure.lang.AFn throwArity "AFn.java" 429]}], :trace [[clojure.lang.AFn throwArity "AFn.java" 429] [clojure.lang.AFn invoke "AFn.java" 36] [sandbox$eval53 invoke "NO_SOURCE_FILE" -1] [clojure.lang.Compiler e...

18:29 Lewix: justin_smith: thank you for your continous help. I appreciate it

18:30 justin_smith: ,(#(+ % %2) 4 5)

18:30 clojurebot: 9

18:30 justin_smith: finally

18:30 Lewix: I get it now

18:30 justin_smith: anyway, same reason there are extra parens there

18:31 well, "extra"

18:31 Lewix: ,(= (#(+ %1 %2) 4 5) (#(+ % %2) 4 5))

18:31 clojurebot: true

18:32 amalloy: Lewix: justin_smith is also known for his discrete help, but he doesn't advertise it

18:32 justin_smith: haha

18:32 ambrosebs: but it's always differentiable

18:32 oops, bad tab expansion

18:32 amalloy: ambrosebs: time to change nicks. there can be only one

18:32 ambrosebs: xD

18:33 Lewix: amalloy: I have a lot of respect for what you guys do helping people - you're passionate about it and I really appreciate it, really

18:33 justin_smith: I'll keep that in mind - discrete help. lol

18:34 justin_smith: hope you don't charge people discretely...^^

18:37 idnar: so I have some code like (byte-streams/to-byte-buffer (repeat 0x10000 [0])) but that's pretty slow; what would be a better way to do that?

18:39 Lewix: what's the difference between functional and declarative

18:41 brehaut: Lewix: given nobody can agree on the definition for either, thats going to be hard. a fair number of people would say that functional is a kind of declarative

18:41 dmitrig01: Midje question! I have the following two files: https://gist.github.com/dmitrig01/b7eac75c3a2b0d98ce78 - file 1 has (defprotocol A (a [_])), 2 has (:require [file1 :refer [A]]) (defrecord-openly B [] A (a [_] (prn "something")))

18:41 midje autoexpands that to (midje.data.prerequisite-state/implements-a-fake? a), but a is not defined in file 2

18:41 what’s the best practice here?

18:42 amalloy: "functional" is a word you have arguments about on HN, and "declarative" is a word you use to describe languages you like

18:43 brehaut: (inc amalloy)

18:43 lazybot: ⇒ 242

18:43 Lewix: (class amalloy)

18:43 ,(class amalloy)

18:43 clojurebot: #error{:cause "Unable to resolve symbol: amalloy in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: amalloy in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: amalloy in this context", :a...

18:44 justin_smith: Lewix: regarding declarative vs. functional, functional programming is one category of declarative, sql is also declarative in certain aspects, or even xml

18:44 Lewix: justin_smith: or even html

18:44 justin_smith: declarative doesn't neccessarily even imply turing-complete

18:44 right

18:46 Lewix: justin_smith: what does turing-complete have to do with it

18:46 justin_smith: even Java style classes / inheritance can be called declarative, in comparison to prototype inheritance

18:46 Lewix: functional is a programming language family, so it makes more sense to compare it to other things that are turing complete usually

18:47 amalloy: declarative means "say what to do, not how to do it". but applying that is very subjective

18:47 justin_smith: declarative is a style of establishing things (as contrasted to procedural / imperative)

18:47 Lewix: justin_smith: I don't see the relationship

18:47 with turing complete*

18:47 EnglishGent: something can be declarative without being turing complete - but then I'd call it a declarative DSL

18:47 'programming language' normally implies turing completeness

18:48 indeed it also normally implies the ability to drive the machine somehow (capture keyboard input, output text, play audio, etc)

18:49 gfredericks: usually something declarative has something else processing it

18:49 EnglishGent: otherwise I'd have to consider a game-board for Conway's life as a 'programming language'

18:49 justin_smith: Lewix: usually when we talk about declarative in relation to functional, we are talking about programming languages, things that are turing complete, but I think it helps to remember that declarative isn't just a property of languages

18:49 Lewix: I see

18:49 justin_smith: it can also be a property of document formats (contrasting to procedural document formats where the tags tell the renderer what to do)

19:14 freddd: if anyone's got a minute, i've got a vector, and I want to use its contents as the arguments to a function that takes [& args]. is there a 'nice' way to do that?

19:14 justin_smith: freddd: apply

19:14 ,(apply + (range 10))

19:15 clojurebot: 45

19:16 gfredericks: ,(apply + (range 1000000)) ;; make the bot earn its keep

19:16 clojurebot: 499999500000

19:18 freddd: justin_smith: thanks, again. i appreciate it!

21:48 Shayanjm: Is there any easy way to center a parametric plot at a certain point in incanter?

21:48 I've got a plot where I need to draw a bunch of circles, but the plot scale is making it difficult to see what's happening and I can't find a straight forward way of addressing that

21:51 nevermind i think I can just use set-axis

22:40 spinningarrow: does anyone know how I can ignore clojure files in editorconfig?

23:49 Shayanjm: Made some great progress on my side project today

23:50 What's interesting is that I discovered (organically) that the trivially optimal configuration for circle-in-circle packing might resemble something close to the golden ratio

Logging service provided by n01se.net