#clojure log - Oct 30 2014

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

0:00 justin_smith: chenglou: kind of figures - and then each of those items would know how to compare to one another

0:01 starting with "if they are they same object yes, if they have different hash-codes no" and working forward from there I guess

0:01 bbloom: oooo i did install the legacy java package on my mac b/c it apparently uninstalled the old sdk

0:02 chenglou: yeah. Someone ping me if they discover a magical, collision-free hash that can be modified in constant time =)

0:02 bbloom: when i launched intellij for the first time after yosemite

0:02 justin_smith: chenglou: lol

0:02 bbloom: could that have something to do with it?

0:03 justin_smith: different default heap sizes would be the first difference I would think of

0:06 bbloom: $ lein pprint

0:06 Error occurred during initialization of VM

0:06 Too small initial heap

0:06 hmmm

0:08 technomancy: 32-bit jdk?

0:10 bbloom: technomancy: java -version reports 64-bit server 1.7.0_09

0:11 i'm not sure how to set the system default heap size for jvm

0:12 computers hate me

0:13 JAVA_OPTS='-Xmx768M' lein repl <- seems to do the trick

0:13 i guess i can just put that in my shell rc

0:14 technomancy: or is that a terrible idea that will break my computer in some unexplained way 6 months from now?

0:22 justin_smith: Raynes: amalloy: one of you have a template for what the mongodb config for .lazybot/config.clj would look like? I will add it to the default if so, otherwise I will do my best to reverse engineer the config that should be there.

0:25 amalloy: justin_smith: does it need any? the lazybot instance in here has no mongodb config. i think it just assumes a mongodb server on localhost:default-port, and that it's allowed to write to the lazybot db

0:25 justin_smith: amalloy: oh, sounds magic!

0:25 I'll make sure my db is on the default port then

0:25 and that I am whitelisted to use the db etc.

0:26 amalloy: shows how much I know about mongodb (jack shit)

0:27 amalloy: justin_smith: the default mongodb config is to just assume the firewall takes care of everything, so that if you can connect to localhost you have permission to do whatever

0:27 it looks pretty clear from lazybot/core.clj that there's nothing configurable at all

0:27 justin_smith: amalloy: OK

0:27 amalloy: except you can use a db name other than lazybot if you want

0:28 dbasch: justin_smith: mongodb is webscale, almost as fast as /dev/null. That’s pretty much all you need to know.

0:28 oh, and it has shards as its magic secret scalability sauce

0:31 justin_smith: amalloy: weird, when I run > show dbs I see a lazybot db with contents, but @help gives me a connection error? very weird

0:32 ahh, never mind - it's an access control exception

0:32 I need to do that security settings thing

0:58 raspasov: hey guys does anyone have any idea about function calls within [let] blocks - long time ago I overheard from someone that they are not the most efficient way of executing fn calls in Clojure - is there any truth to that or it does not matter?

1:00 justin_smith: raspasov: why would a function call inside a let block be less efficient? function call dispatch can be marginally cheaper if you bind the function within a let block so that you never deref the var at runtime, but even then the speedup should be minor

1:01 raspasov: I see, ok, I was just wondering if there was any truth in that statement

1:05 tolstoy_: Andfam.12

1:21 andyf: Leiningen question: I have a directory in my project containing Clojure source files that I want to be in the classpath while I run ?lein test?, but I don?t want them in :source-paths, and I don?t want them in :test-paths. Why? Because they are not source files for the project, and they are only indirectly files for testing, by being require?d from my regular test files. Any recommendations?

1:26 zRecursive: ,(doc ->>)

1:26 clojurebot: "([x & forms]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

1:26 justin_smith: andyf: isn't test-resources a thing?

1:27 andyf: justin_smith: Checking Leiningen docs for such a thing...

1:28 justin_smith: andyf: it's not in the example proejct.clj, so it likely is not a thing

1:28 but you could set a :resource-path under the :test profile I guess?

1:28 :resource-paths that is

1:28 andyf: justin_smith: I have tried putting it into the :resources path in the :dev profile, and that seems to be doing reasonable things, but your suggestion sounds even better.

1:29 justin_smith: Sorry, I meant to say in the :resource-paths in the :dev profile

1:30 Do :resource-paths in a profile like :dev or :test, and a "global" :resource-paths, concatenate?

1:30 justin_smith: andyf: there is a merge that is done of the active profiles

1:30 I think testing pulls in :dev, :user, :test

1:32 andyf: Duh, the very first example given in output of "lein help profiles" is adding a directory to classpath in :test profile.

1:32 justin_smith: oh, nice!

1:32 https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md this has some good info for showing your effective profile etc. too

1:34 andyf: Yep, lists and vectors are concatenated when merging profiles. Cool. Bob's my uncle.

1:34 (inc justin_smith)

1:34 lazybot: ⇒ 111

3:30 dopamean_: i am having a nightmare of a time trying to send a simple http request

3:30 i know all the information im sending is accurate because when i do it in the terminal with curl i get the expected response

3:30 but when using clj-http i get a 400 error every time

3:31 sveri: dopamean_: did you set the :content-type and :accept key values?

3:34 dopamean_: at first no

3:34 because i didnt think i needed to for a post request

3:34 but then i did add it and its still not working. though its a little unclear to me from the api exactly how it wants the information

3:35 this is the offending code: (client/post spotify-access-token-url {:form_params data})

3:35 data is a map with all the necessary stuff in it

3:36 sveri: dopamean_: Hm, it's been almost a year since I used this and I remember having had problems too, I don't remember what exactly the problem was, but this solved my problem: :as :json in the options map

3:37 dopamean_: 400

3:52 sveri: dopamean_: I had some success debugging rest services using the postman app from the google chrome store, I know you tried already with curl, but if you dont get closer to the problem I guess it's worth to try it

3:56 dopamean_: i started with postman

3:56 sveri: it does work with postman?

3:56 dopamean_: no

3:56 which means im not setting something correctly

3:56 something that curl is doing automatically

3:56 sveri: yep

3:57 dopamean_: all i specified for curl was a bunch of -d tags

3:57 sveri: I guess you just have to figure this out by trial and error

3:57 dopamean_: and then the url

3:57 ive been at it for 3 hours

3:57 https://developer.spotify.com/web-api/authorization-guide/#authorization_code_flow

3:57 im on step 4 of that

3:57 requesting the new access token

3:58 can you read that and tell me if there is something glaringly obvious that im missing?

3:58 it says send a post request and then it says request body parameters...

3:58 is that not form-params?

3:59 sveri: it should be

3:59 However, this is hard to debug remotely, all I can ask is if you set all the params from step 4 correctly

3:59 which you did, I guess

4:00 dopamean_: yup

4:01 if i left all the params off, just to see what happened, do you tihnk a 400 response would make sense?

4:01 sveri: I am sorry then, I guess I am of not much value here

4:01 dopamean_: or should it be something else?

4:01 its all good

4:02 sveri: Yea, that would make sense

4:04 dopamean_: hmm

4:04 i just sort of got it to work

4:04 in postman

4:04 changed from "form-data" to "x-www-form-urlencoded"

4:05 sveri: nice, maybe curl does some kind of auto negotiation

4:05 dopamean_: perhaps

4:05 now if i can just get clj-http to do the same thing

4:07 shem: dopamean_: did you check if it does a OPTIONS query first? cljs-ajax/POST does that and had me baffled for a while

4:07 dysfun: i was going to recommend http-kit which has a quite nice promise-driven API. i'm a bit mystified to find it's not on clojure-toolbox

4:08 oh, it's under servers

4:08 dopamean_: what do you mean by options query/

4:09 shem: if i call POST with json content-type, it first does OPTIONS to the same uri

4:10 and your server endpoint might be confused with that

4:10 dopamean_: maybe thats whats happening

4:10 i have no idea

4:16 well

4:16 i feel dumb for wasting so much time on this

4:16 it works fine with http-kit

4:18 sveri: dopamean_: Hehe, I wasted time on much easier things, that's part of programming

5:11 jzinedine: hey guys, anyone knows about a seed project wiring pedestal service and reagent together?

5:12 I'm looking for a sample app to start with, and follow the patterns to build my app.

5:49 borkdude: https://gist.github.com/anonymous/53423c327ffda7faf852

6:15 celwell: I'm using lein-beanstalk, how can I define the application name to be something other than the name I have for my lein project (defproject ...)?

6:18 Hmmm, looking at the source, this seems promising, will try: https://github.com/weavejester/lein-beanstalk/blob/master/src/leiningen/beanstalk/aws.clj#L50

6:24 Glenjamin: is anyone around familiar with figwheel? I'm trying to figure out a way to have the :on-jsload callback fire once on initial page load

6:24 on a related note, thanks to everyone who recommended reagent to me the other day - it's excellent

6:38 OliverJAsh: i'm learning clojure and have a JS background. i'm familiar with functional-reactive programming. i've used RxJS. can anybody tell me if clojure’s sequence data structures (seq?) are the same concept as what Rx calls "observables"?

6:39 TEttinger: sequences are a very common type in clojure. they can be lazy seqs or finite seqs.

6:40 lazy seqs you can generate with something like

6:40 ,(repeat "infinite")

6:40 clojurebot: ("infinite" "infinite" "infinite" "infinite" "infinite" ...)

6:40 TEttinger: and here, clojurebot limits how many items it will print

6:41 you could get just two items out of an infinite lazy seq with "take"

6:41 ,(take 2 (repeat "infinite"))

6:41 clojurebot: ("infinite" "infinite")

6:41 TEttinger: seqs are printed with single parentheses, like lists

6:41 I'm not sure what observables are, but I hope that clears up a bit

6:42 OliverJAsh: does a sequence represent data over time? i.e. can you add new values to the sequence through time, and the data will be "pulled through", like in functional reactive programming?

6:44 i think i'm confusing seq and FRP when they are totally different things :)

6:45 TEttinger: you might be thinking of core.async (a popular clojure lib)'s concept of channels

6:45 mavbozo: in core.async, (thread) and (go) return channel

6:45 TEttinger: I can't explain channels

6:45 mavbozo: what can I do with those channel, any easy example?

6:47 (thread (+ 1 2))

6:48 never mind, found it myself

6:49 (def c (thread (+ 1 2)))

6:49 (<!! c)

6:52 shriphani: hi, anyone here used core.matrix ? I want to compute a row-sum and I was wondering if a reduce is the right way to go ?

7:06 ustunozgur: hi all, in cider, what's the easiest way to send C-M-x output to repl?

7:07 that's, I want to see the output in the repl, not in the mini buffer.

7:10 mavbozo: ustunozgur: so far, the solution is to create a elisp function and bind that function to keystroke

7:11 ustunozgur: i found the function in the README of clojure core async tutorial here https://github.com/halgari/clojure-conj-2013-core.async-examples

7:13 ustunozgur: mavbozo: thanks ,look promising, although cider-find-or-create-repl-buffer seems to be gone. maybe renamed

7:13 mavbozo: ustunozgur: here's my elisp snippet https://github.com/mavbozo/mavbozo-dotemacs/blob/0ca56487242f5b222fc3ac7a7c8c7243b4a1a0a6/mavbozo-custom.el#L149-L164

7:14 ustunozgur: yeah, I still use cider 0.70

7:15 ustunozgur: thanks a lot.

7:16 I slightly modified it to execute the top level form instead.

7:17 mavbozo: ustunozgur: I am still a emacs newb, I would like to see your code, thanks

7:20 ustunozgur: mavbozo: here you go

7:20 https://gist.github.com/ustun/0f1a86142b95a391773c

7:20 I bound to Alt-Enter

7:20 so anywhere within the form will execute the outermost form in repl

7:21 mavbozo: ustunozgur: fantastic! thanks a lot

7:22 ustunozgur: this is actually slightly different from how cider sends it to the repl but good enough for my demo purposes.

7:22 giving a talk today to a java user group

7:22 the difference between this and cider's C-M-x is that

7:22 if you are in a different namespace in cider it will send that to that namespace

7:22 whereas this will send the code to the current namespace the repl is in.

7:24 mavbozo: ustunozgur: have a great talk!

7:24 ustunozgur: thank you!

7:28 edbond: I use lein new with template and it seems old version of template is used.

7:29 pandeiro: edbond: did you `lein install` the template from a local repo with the same version?

7:29 edbond: https://github.com/magomimmo/om-start-template

7:30 pandeiro, no, used lein new om-start as in Readme

7:30 pandeiro: edbond: or maybe the clojars version is behind the github

7:30 edbond: maybe I had an old version

7:30 pandeiro: edbond: no i think lein new always checks

7:30 edbond: pandeiro, thanks, I'll check clojars

7:31 pandeiro: edbond: so you could do `git clone git://github.com/magomimmo/om-start-template && cd om-start-template && lein install`

7:31 edbond: pandeiro, thanks. Clojars have more recent version that github :)

7:32 https://clojars.org/om-start/lein-template 0.0.7

7:32 https://github.com/magomimmo/om-start-template/blob/master/project.clj here is 0.0.6

7:32 pandeiro: wow that's a first

7:32 i think `lein new ...` should always by default get the latest version from clojars

7:34 edbond: I have 0.0.7 jar here /home/eduard/.m2/repository/om-start

7:36 yes, clojars is a bit behind. Thanks, pandeiro

7:36 (inc pandeiro)

7:36 lazybot: ⇒ 2

7:38 fairuz: hey guys, if let say I open 2 terminals, with one runing lein repl. Then I modify one of my function, and compile using lein compile. Do I need to reload the repl?

7:41 clgv: fairuz: why dont you just reload the namespace of the function?

7:41 fairuz: sounds like what you describe will fail

7:42 fairuz: development gets much easier if you have editor and repl integrated since you can use commands like "evaluate that function definition in repl"

7:46 TimMc: fairuz: None of Leingingen, the default REPL, or Clojure itself will automatically reload code.

7:46 fairuz: clgv: TimMc: Ok. I'm still learning on how to develop/debugging efficiently using repl.

7:47 so how to reload a namespace?

7:47 redo a (use xxx)?

7:47 clgv: fairuz: use one of the editor+repl combinations or IDEs

7:47 fairuz: with :reload or :reload-all yes

7:49 fairuz: clgv: Ok cool. Does not want to start an IDE war, but what are recommended IDEs? LightTable is more than enough I suppose?

7:49 clgv: fairuz: options for dev envs are Emacs+Cider, Vim+Fireplace, Eclipse+Counterclockwise,IntelliJ+Cursive, Nightcode ... maybe others I currently forgot

7:49 ah right LightTable ^^

7:50 TimMc: fairuz: My usual pattern is this: lein repl; edit files; (require 'foo.bar.baz :reload); repeat

7:51 I don't use lein compile because I'm not using AOT.

7:51 clgv: TimMc: you dont use any integrated editor + repl combo?

7:51 TimMc: Nope.

7:51 clgv: wow O_o

7:52 fairuz: TimMc: I just want to ask about that :) we actually don't need to compile each time we modify the files right?

7:52 TimMc: clgv: One f these days I will try setting up cider again, but the last time I tried it all fell apart.

7:52 clgv: TimMc: I am only using lein repl on remote machines and sometimes if it gets more complicated I connect with my dev env to the remote nrepl

7:52 TimMc: fairuz: Right, reloading will compile on the fly (not to disk, just in memory.)

7:53 clgv: TimMc: haha yeah, seems that cider thing breaks often surprisingly

7:53 fairuz: TimMc: got it

7:53 TimMc: clgv: I version my .emacs.d so it shouldn't be too bad once I get it working, but I need to get a stable version in there.

7:54 clgv: TimMc: last posts on the ML suggest that even the stable version might break spontaneously - no idea if thats true

7:54 TimMc: fairuz: Or usually (require '[foo.bar.baz :as f] :reload) since I'll be calling it a lot.

7:54 clgv: This does not surprise me.

7:55 It also doesn't really fit with my windowing preferences. I like having my REPL in a totally separate window.

7:56 clgv: TimMc: yeah thats the setup I use with counterclockwise as well

7:57 TimMc: Bronsa suggested using emacsclient in order to accomplish that, but... eh, another thing to set up the next time I want to work.

7:59 clgv: TimMc: hehe. I think I'll never leverage the power of emacs since I am not good at remembering many complicated shortcut combinations...

7:59 shem: emacs can sprout several proper windows of course

8:00 clgv: TimMc: I used it 2 months for the SBCL course exercise I was organizing

8:05 TimMc: fairuz: Oh, just a tip -- you'll eventually find yourself in a situation where you have fn B that calls A, you rewrite and reload both repeatedly, but you fail to do it in the right order, and it works in your REPL because an old version of A is in memory but B doesn't work with the A on disk.

8:06 You should be aware that this can happen so that you'll recognize it when it does. (This gets worse with defrecords and deftypes and multimethods -- different symptoms, same essential problem.)

8:07 `lein test` or restarting your REPL will give you a more honest view of the world.

8:14 whodidthis: how does a human being test a ring middleware that depends on another middleware

8:17 foofoobar: Hi. (first „hello“). Why is this \h instead of h ?

8:18 clgv: foofoobar: notation for character literals

8:18 ,(str (first "hello"))

8:18 clojurebot: "h"

8:18 clgv: above it is a string instead of a character ^^

8:18 foofoobar: ,(str \h)

8:18 clojurebot: "h"

8:18 foofoobar: ah, okay. thanks

8:18 elfenlaid: well, strings aren't sequential by default, but can transform to sequence; and sequence from string is a list of chars

8:19 clgv: elfenlaid: that's a complicate explanation. strings are arrays of chars on the jvm would suffice ;)

8:19 at least internally ;)

8:20 elfenlaid: ow, ok :)

8:22 clgv: ,(mapv #(nth "hello" %) (range (count "hello")))

8:22 clojurebot: [\h \e \l \l \o]

8:29 mavbozo: whodidthis: by mocking the required middleware

8:35 fairuz: TimMc: thanks for the tip. Really appreciate any advice now since I'm just started :)

8:36 whodidthis: i liked the ((wrap-whatever identity) {:body "my-request"}) approach, whats a cool way of testing something that depends on another, should i just ((mw/wrap-something identity) ((mw/wrap-else identity) {:body "my-request"}))

8:37 just request parsing middleware

8:41 mavbozo: whodidthis:(-> {:body "my-request"} (mw/wrap-else identity) (mw/wrap-something identity))

8:42 whodidthis: threading macro -> is better

8:42 whodidthis: cool, always room for some magic

8:43 mavbozo: whodidthis: better to use threading macro -> in your case

8:43 perplexa: thread-first macro*

8:43 :P

8:47 whodidthis: although if i want to use a threading macro thingie i guess i would have to (as-> {:body ""} _ ((mw/wrap-else identity) _) ((mw/wrap-something identity) _))

8:53 clgv: fairuz: better make your first steps with LightTable since you have already installed it ;

8:59 mavbozo: whodidthis: or, (def test-app (constantly {:body ""}))

9:00 whodidthis: (-> test-app mw/wrap-else mw/wrap-something )

9:16 si14: how would you translate CLJS app? I've come up with a simple macro, but it's still not obvious how to compile two different artifacts for different languages.

9:17 of course I can use environ or somethings like this and do TRANLSATION=en lein cljsbuild once production, but this seems a bit messy to me

9:24 perplexa: si14: you can use #+clj and #+cljs macros, if i understand you correctly

9:24 oh wait, you're actually talking about languages and not clj and cljs ;p

9:24 si14: perplexa: no, sorry, I meant human languages :) like compiling two different artifacts for English and Esperanto languages

9:25 perplexa: haha yeah just realised :D

9:25 sorry

9:25 si14: :)

9:25 thanks for an advice, anyways :)

9:26 perplexa: si14: i don't understand your use case.

9:27 si14: perplexa: webapp with i18n

9:27 perplexa: languages are something chosen by the client, so shouldn't you include all resources and then decide inside of your application which one to use?

9:27 not at compile time

9:27 that would diminish the purpose of i18n

9:30 si14: perplexa: I can compile two different artifacts and give a choice on a landing page, I think

9:30 basically, two different webapps

9:31 perplexa: shouldn't be a different app at all, the logic stays the same, just the strings are different

9:31 maybe use something like https://github.com/ptaoussanis/tower

9:32 and decide which language to use based on browser accept headers

9:34 si14: perplexa: I also need quite a lot of language-specific resources, so it be unwieldy to include them in app if they will not be needed

9:35 ustunozgur: anyone encountering erros with swing gui (frames) not appearing with cider?

9:36 it returns visible=true but the gui is no where in sight

10:01 perplexa: do people actually use type hints?

10:09 Glenjamin: generally only to remove reflection on iterop

10:09 personally

10:22 justin_smith: perplexa: they can make a massive difference in performance when you need them

10:24 perplexa: justin_smith: so it's preferable to just add them :)

10:25 Glenjamin: i'd say add this https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L255 to your project.clj

10:25 then do whatever it tells you

10:28 perplexa: Glenjamin: i'll give it a shot

10:34 si14: oh wow. pretty epic

10:34 there are no externs for Web Audio API in Closure Compiler that is used by CLJS

10:35 * si14 this: (.log js/console (or js/window.AudioContext js/window.webkitAudioContext)) turns to this: console.log(function(){var a=window.wd;return x(a)?a:window.he}());

10:36 si14: (erroneous /me, sorry)

10:36 Glenjamin: https://code.google.com/p/closure-compiler/issues/detail?id=710 looks relevant

10:38 zot1: question on idiom: i'm trying to do something like update-in, but where the "rhs" also needs the same keyed structure. my raw version is above, and my first attempt at making it generic below. suggestions on how to improve? https://gist.github.com/anonymous/90213a0f47091e287bfc

10:41 justin_smith: zot: I think there is a misplaced paren in that reduce

10:42 zot: justin_smith: could be, it was 'scratchpad' idea, although it at least parsed in the repl, i think

10:42 si14: Glenjamin: yeah, but it doesn't work now

10:42 justin_smith: ,(reduce +)

10:42 Glenjamin: you can just pull in additional externs in the build config

10:42 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core/reduce>

10:42 justin_smith: zot: you should have seen that error

10:43 zot: i just pasted it again w/ no problem, although there is definitely a paren off. strange.

10:43 justin_smith: zot: anyway, unless I am mistaken, the paren to the right of ks should be before m1 in that reduce call

10:44 zot: yep i've fixed it here, and will repaste if useful :)

10:45 is there a cleaner way to pull it off? the anon func for reduce is … awkward, but i haven't (so far) imagined a better way, other than maybe as a walk that update-in's the peer structure. important to note is that both trees can be sparse, so update-in, or sth else that will create missing structure, is preferred.

10:47 justin_smith: zot: I like the reduce version (the version of it with correctly balanced parens at least)

10:48 zot: justin_smith: ok, good to hear from somebody else… trying to learn with the notion of using func composition instead of tricky anon fns… and this one befuddles ;)

10:49 justin_smith: zot: I don't see a straightforward way to do this with function composition though

10:50 zot: justin_smith: ok — i'm still finding my way in clojure, so sometimes there's a super awesome way that i've just never seen, forgotten, or can't find via google :)

10:51 justin_smith: tnx for taking a look!

10:53 EvanR: is there a type which is just a date, and not a java Date which is taking liberties with midnights and time zone assumptions

10:55 zot: EvanR: familiar with clj-time?

10:55 EvanR: no

10:55 zot: google it. it can probably do what you want, and way way more.

10:55 irctc: hi

10:55 :)

10:56 EvanR: ok

10:56 irctc: is this a place where a newbie can ask questions?

10:56 EvanR: also i just discovered java GregorianCalendar

10:57 andyf_: irctc: yes

10:57 ohpauleez: irctc: Most certainly!

10:57 hyPiRion: EvanR: prefer clj-time and joda-time whenever you can

10:58 EvanR: im reading the doc, it might work

10:59 irctc: i'm looking at https://github.com/aphyr/riemann/blob/master/src/riemann/email.clj at the function (defn email-event i'm trying to understand it

10:59 so [smtp-opts msg-opts events] are arguments ok so far :)

11:00 then "(let [events (flatten [events])" what does it means exactly it flattens events and places it in events?

11:00 i don't get it

11:01 Glenjamin: irctc: it takes any single item or nested sequence of sequences, and gives you a single sequence of events

11:01 irctc: why is it flattening events at all?

11:01 ok

11:01 so it suspecteed it would be nested i understand

11:01 Glenjamin: [1 [ 2 ] [3 [4] ] ] => [ 1 2 3 4]; but also 1 => [1] and [1 2] => [1 2]

11:01 irctc: and i'm allowed to override like this the same variable name?

11:01 events it flattened and named as events again...

11:01 Glenjamin: yes, a let binding runs in order and can re-bind locals

11:02 irctc: ok

11:02 then this "subject ((get msg-opts :subject subject) events)" what is the first "subject" is it a function i lost it at that point

11:03 EvanR: clj-time youre my only hope

11:03 at least one industrial time lib may actually make sense

11:04 andyf_: irctc: I don't know exactly what the args to this function are, but (get msg-opts :subject subject) is an expression that either returns a function, or a value like a map or vector that can be used as a function

11:04 irctc: Whatever that is, it is then called with the argument events, and the return value of that is bound to subject

11:05 irctc: If it makes it clearer, it could be written in two lines instead like so:

11:05 irctc: some-fn (get msg-opts :subject subject)

11:05 irctc: subject (some-fn events)

11:06 irctc: I should have started with your question, though: subject there is just another name that is being bound to a value in the let

11:07 irctc: ok got it about the first subject

11:07 yes its an array i missed that so we are bidning 3 items events subject and body

11:08 andyf_: irctc: yes, the let is binding 3 values to those names

11:08 irctc: so about the inner "(get msg-opts :subject subject) " its get from map named "msg-opts" the field :subject and the default would be the last "subject" if not found?

11:08 andyf_: irctc: yes

11:08 EvanR: sweet

11:08 irctc: but can i be sure there is a default "subject"? what if was not bound yet?

11:09 justin_smith: irctc: if subest was not bound yet, that would not even compile

11:09 ,(get {} :foo foo)

11:09 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)>

11:10 andyf_: It looks like the original value for subject is coming from the :use on line 5

11:10 irctc: ok

11:11 is it aggregating somehow the subjects from all the events into a single one? or the body from multiple events into a single one? i don't get how it achieves this..

11:11 andyf_: irctc: That would be much less obvious if subject were def'd in namespace postal.core, which has (:use postal.core) up near the top, since that will bring in every public def in postal.core into this namespace. That is one reason why many Clojure programmer recommend against an "unlimited" use like that.

11:12 irctc: hmmm

11:12 i see this

11:12 in riemann.common

11:12 subject is also a function named "defn subject"

11:13 so wow with a field named subject, a default value, and a function all named subject !! :)

11:13 andyf_: irctc: Again, I'm not familiar with the exact context here, but I would guess subject is a function. It can take whatever events is (probably a sequence of events), and calculate a subject line, probably a string, to use in an email message.

11:14 irctc: riemann.common/subject is the default function to use for calculating the subject, but it can be overridden by putting a key named :subject into the map msg-opts, whose value is a different function to use instead

11:14 irctc: so in this"subject ((get msg-opts :subject subject) events)" the first subject is a "string" and third subject is a function!?

11:15 andyf_: irctc: that would be my guess

11:15 irctc: oh sorry default

11:15 in anyway the main thing that mixed me up is that subjet was a function defined something else i just looked for the concatenation somehwere..

11:15 andyf_: irctc: I am not claiming that those are the best names to use for clarity of purpose :)

11:15 irctc: :)

11:16 ok i think i got some of the subject :)

11:17 justin_smith: irctc: yeah, the naming here is kind of odd, here is a hopefully less clever and more clear version that does exactly the same thing https://www.refheap.com/92484

11:20 irctc: https://www.refheap.com/92484 --> *much more clearer!!*

11:20 https://www.refheap.com/92484 --> *much clearer!!*

11:21 andyf_: irctc: My inner grammar Nazi thanks you

11:22 perplexa: i there a better way than (* (int (/ x y)) y) to make x a multiple of y?

11:22 without casting to an int in the middle ;p

11:22 clgv: justin_smith: tsktsk to much :use there ;)

11:22 irctc: :)))

11:22 justin_smith: clgv: I did not touch the ns form at all

11:22 andyf_: perplexa: Not much different, but you could use (quot x y) instead of (int (/ x y)) ?

11:22 perplexa: like, i have x=11, y=2, expected result is 10

11:22 justin_smith: clgv: it is just there to provide context in the function I reworkd below it

11:23 clgv: ,(- x (mod x y))

11:23 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(NO_SOURCE_PATH:0:0)>

11:23 clgv: oh comma :P

11:23 perplexa: ah yeah, andyf_! that looks a bit better :) gracias

11:23 andyf_: clgv: I'm curious -- I understand that 'unlimited' :use's like that are frowned upon in most uses, but do you use them in test code, e.g. (:use clojure.test) ?

11:24 perplexa: clgv: that also, yes ;p

11:25 but i remember from back when i cam across some C algos that subtraction is usually more expensive than multiplication/division

11:25 * perplexa shrugs

11:25 perplexa: no idea how jvm handles that, it's probably bad either way :D

11:26 andyf_: perplexa: I would think that it is usually the opposite, i.e. + and - are fastest integer ops, and multiply and divide are slower. This is likely getting more historical now, as * quot and mod are probably all just as fast as + and - on integer ops on most modern processors.

11:26 justin_smith: perplexa: with out immutible data structures and laziness and runtime polymorphism, we have much bigger optimization targets than the cost difference of subtract vs. multiply

11:27 *with our

11:28 andyf_: clgv: I ask because right now Eastwood warns on all 'unlimited' use's, but I've been wondering whether I should disable that warning for source files in :test-paths

11:28 perplexa: mmh :)

11:29 cbryan: andyf_: or just do :require [... :refer :all]

11:29 eastwood is fine with that

11:29 mgaare: andyf_: replacing them with (require '[whatever :refer :all]) should shut up eastwood too

11:29 doh

11:29 cbryan: ;)

11:29 Glenjamin: heh, i'm not clear why :refer :all is considered nicer than :use

11:30 andyf_: Sure. My main curiosity is, for people who frown on unlimited :use, do you use them in test code? I do, and it seems relatively common.

11:30 justin_smith: andyf_: to me :use makes sense if there is a clear "referent" namespace, where your code only makes sense if read in parallel with that namespace (whether you are wrapping it, or testing it, or extending it...)

11:30 andyf_: but even then, more than one :use is a problem

11:31 Glenjamin: i'd rather just list out the 5 or 6 functions i need

11:31 andyf_: justin_smith: because? Sorry, not obvious to me why.

11:31 Glenjamin: it's not that often to have a namespace with more than that many you need to use

11:31 andyf_: Glenjamin: Even in a test namespace?

11:32 Glenjamin: do you mean for clojure.test, or for the system-under-test?

11:32 justin_smith: andyf_: if the namespace is about wrapping / extending / testing one other ns, then it only makes sense in context of that ns and one would be looking at both together, with more than one ns used, that introduces the ambiguity and refactoring difficulty that to me are the real pain points in :use

11:32 andyf_: Glenjamin: either, but if you have reasons for doing it differently for each, I'm curious.

11:32 mgaare: andyf_: the more places you have to look to answer the question, "now where did this symbol come from?", the unhappier I get :D

11:32 Glenjamin: andyf_: well clojure.test, only is, testing and deftest are really used that often i'd have though

11:32 system-under-test i usually :as to a single letter

11:34 andyf_: So perhaps if Eastwood never warned about (:use clojure.test), but kept its current warning for such a use of any other namespace, not many people would mind that behavior?

11:35 Bronsa: andyf_: I :use clojure.test in all my tests

11:35 andyf_: I look at Eastwood warnings on quite a few projects on a regular basis, so certain warnings I can get tired of seeing, and I imagine others woudld, too.

11:35 Glenjamin: Bronsa: how many different vars from clojure.test do you think you use often?

11:35 andyf_: Bronsa: You and nearly everyone else :)

11:35 Bronsa: Glenjamin: just is and deftest probably, but it's just too much of a hassle to :refer them

11:35 Glenjamin: i'm interested in whether :use clojure.test is habit, or because it's annoying not to

11:36 Bronsa: andyf_: which version of t.a.jvm is eastwood using atm?

11:36 andyf_: Glenjamin: Can't speak for others, but for me it is annoying to pick exactly what I want, even though it is a copy-and-paste if I wanted to go to that trouble.

11:37 Glenjamin: i don't use clojure.test very often, but i'd have expected something like [clojure.test :as test :refer (is testing)] would cover most usage

11:37 andyf_: Bronsa: Latest Eastwood release 0.1.4 is getting creaky old: t.a(.j) version 0.2.2 :-(

11:37 Bronsa: andyf_: no I mean SNAPSHOT :P

11:37 andyf_: Bronsa: Getting real close now to another release. Testing the latest masters of t.a(.j) as we type

11:37 justin_smith: Glenjamin: most would refer deftest too I think

11:38 Glenjamin: mm

11:38 andyf_: I think I just committed that about an hour ago

11:38 Glenjamin: but still, not many, out of the, what?, 20 or so vars in there

11:38 Bronsa: andyf_: ah cool, asking because 0.6.3 should be more than twice as fast than 0.2/0.3

11:38 Glenjamin: i count 29 vars

11:39 Bronsa: ,(require 'clojure.test)

11:39 clojurebot: nil

11:39 Bronsa: ,(count (ns-interns 'clojure.test))

11:39 clojurebot: 40

11:39 justin_smith: ,(count (ns-publics 'clojure.test))

11:39 clojurebot: 37

11:39 andyf_: Glenjamin: I think everyone who uses clojure.test uses deftest and is. A fraction use testing, and an even smaller fraction use are

11:39 justin_smith: use would only give us the publics, right?

11:40 Bronsa: justin_smith: ah yeah

11:40 andyf_: Glenjamin: Past that, I haven't even looked at what else is in clojure.test

11:40 justin_smith: Bronsa: though for compilation tooling you usually care about the interns, I am sure :)

11:40 Glenjamin: mostly stuff to run tests

11:41 justin_smith: and fixtures!

11:41 I guess those count as running stuff actually

11:41 Glenjamin: fixtures would probably be ok using test/use-fixtures ?

11:42 justin_smith: Glenjamin: sure, I usually use test/testing too, and in many namespaces I even do test/is

11:49 andyf_: justin_smith: You've stunned the room into silence with that one. We are all mentally reeling :)

11:50 justin_smith: haha

11:58 donbonifacio: can I deconstruct a variadic function to a hash? (defn hey [*hash-obj*] ...) and call (hey :name "Lucy" :age 1)

12:02 gfredericks: (defn hey [& {...}] ...)

12:04 cbryan: is there a preferred pastebin for this channel?

12:04 benzap: if I understand correctly, gfredericks is saying that optional arguments when passed to a function are presented as a list after the set of arguments through a defined var (defn [x & args] ...) where 'args' is a list of arguments succeeding the the variable 'x'

12:05 noonian: cbryan: refheap

12:05 justin_smith: ,((fn [& {a :a b :b}] [a b]) :b 2 :a 1)

12:05 clojurebot: [1 2]

12:06 justin_smith: benzap: he meant that ^

12:06 benzap: justin_smith: thank you for clarifying

12:07 donbonifacio: thanks justin_smith gfredericks

12:07 justin_smith: donbonifacio: another thing is that using rest args map destructuring is controversial

12:07 benzap: i didn't supply a name for defn, so my example is probably confusing

12:07 justin_smith: donbonifacio: it is often easier to just use a hash as an argument

12:07 cbryan: is there a more idiomatic way to write this? the (some? (some ...)) feels wrong https://www.refheap.com/92486

12:07 donbonifacio: I see

12:08 whodidthis: if a human being, using yesql, has (defqueries "file.sql") in a file, can the queries be referred to from another file

12:08 justin_smith: donbonifacio: for example if you want to provide that set of keys / values to some function, and you have them in a map already

12:08 benzap: this actually brings up something that bothers me regarding defprotocol, where you are limited to providing nothing but arguments, with no & rest statements

12:08 but i'm guessing this a limitation when trying to communicate with a java interface

12:08 justin_smith: whodidthis: by requiring that namespace and accessing them from said namespace, right?

12:10 whodidthis: right

12:12 justin_smith: whodidthis: yeah, yesql just creates a call to def https://github.com/krisajenkins/yesql/blob/master/src/yesql/types.clj#L51

12:12 so you can access it as you would any other def from another ns

12:14 whodidthis: sweet

12:24 SagiCZ1: the other i read something about meta data.. and i wanted to ask, would it be possible to save some kind of benchmark data to some functions in my program, and look for bottlenecks this way? i was thinking, that each time the function gets called, it updates its own metadata, thats possible right? and can i extract this metadata later? i would like to implement this with minimal impact to my existing program

12:24 justin_smith: SagiCZ1: profilers do a much better version of this

12:24 jvisualvm comes with the jdk, yourkit is popular (and you can get it free for open source work)

12:25 SagiCZ1: justin_smith: i've tried a profiler but showed some low level clojure core functions as hot spots.. useless for me

12:26 noonian: cbryan: i think you can leave off the some? calls since everything in clojure except nil and false is truthy in conditionals

12:26 Glenjamin: maybe that means your app isn't slow?

12:27 SagiCZ1: Glenjamin: there is one of my functions which could be improved from linear to constant time, and the profiler wasnt able to identify this.

12:27 cbryan: noonian: ah cool! thanks

12:27 justin_smith: Glenjamin: more likely just a forst / trees issue, with noise from the lower level stuff that the functions are constructed from

12:27 Glenjamin: SagiCZ1: if it wasn't a hotspot, then it suggests that n is small enough that the constant factor / overhead dwarfs the time complexity

12:28 SagiCZ1: Glenjamin: i think it suggest, that jvisualvm is maybe good for java but not so much for clojure

12:28 Glenjamin: i've managed to use it very well on clojure, and speed up clojure functions which were bottlenecks

12:29 are you running the profile on your app generally, or while running a specific bit of code?

12:29 SagiCZ1: Glenjamin: it is running some heavy computation that takes minutes to finish

12:29 in the list of functions that the profiler identifies there is non of my own functions..

12:29 Glenjamin: and you start profiler, run computation, stop profiler?

12:30 SagiCZ1: yes

12:30 Glenjamin: are you using the top-down view?

12:30 or just looking at self times?

12:31 SagiCZ1: Glenjamin: i was sorting them by time

12:33 Glenjamin: try using the top-down view, it'll let you drill down by times that include the timing of the functions that call

12:36 SagiCZ1: Glenjamin: is there a difference between 'sampler' and 'profiler'? in jvisualvm?

12:36 Glenjamin: the only difference i've seen is that i've never got the profiler to work, but i have got the sampler to work :)

12:36 SagiCZ1: Glenjamin: same here

12:38 Glenjamin: where would i find the top down view?

12:38 justin_smith: I've seen the profiler work for heap profiling

12:41 SagiCZ1: Glenjamin: also, is it wrong, that i am profiling the repl running the task?

12:46 EvanR: is there a function to take a value, return it unless nil, in which case throw an exception

12:46 SagiCZ1: i have found some info by using the "snapshot" option ... not sure what it all means

12:46 justin_smith: (assert v)

12:46 err, no

12:47 ,(and (assert v) v)

12:47 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: v in this context, compiling:(NO_SOURCE_PATH:0:0)>

12:47 EvanR: fantastic

12:47 ,(assert 3)

12:47 clojurebot: nil

12:47 justin_smith: oh wait...

12:47 not and

12:47 ,(do (assert 3) 3)

12:47 clojurebot: 3

12:47 justin_smith: ,(do (assert nil) nil)

12:47 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: nil>

12:47 EvanR: ,(assert false)

12:47 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: false>

12:48 EvanR: looks like a function is in order

12:48 justin_smith: there is that too - perhaps you want something using nil?

12:48 ,(do (assert (not (nil? false))) false)

12:48 clojurebot: false

12:50 EvanR: can i customize the error message

12:51 justin_smith: ,(assert nil "that should not have been nil")

12:51 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: that should not have been nil\nnil>

12:51 EvanR: ,(assert false "foo")

12:51 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: foo\nfalse>

12:52 EvanR: ,(assert false nil)

12:52 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: \nfalse>

12:56 justin_smith: EvanR: you can also use :pre in functions

12:56 EvanR: in this case im making sure the result is not nil before returning it

12:56 justin_smith: ,(map (fn [x] {:pre [(not (nil? x))]} x) [0 1 2 nil 3])

12:56 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: (not (nil? x))>

12:57 justin_smith: ,(map (fn [x] {:post [(not (nil? %))]} x) [0 1 2 nil 3])

12:57 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: (not (nil? %))>

12:57 EvanR: checking the input is not nil as a post action?

12:57 justin_smith: that's not input

12:57 % stands for the potential return value

12:57 EvanR: x?

12:57 oh

12:58 could be good

12:59 justin_smith: ,(map (fn [x] {:post [(not (nil? %))]} [x]) [0 1 2 nil 3])

12:59 clojurebot: ([0] [1] [2] [nil] [3])

12:59 justin_smith: does not trigger, because not nil any more

13:03 EvanR: another factor here is that you can decide at runtime whether asserts are checked (and this includes :pre and :post condition asserts)

13:03 so the consequences there are twofold: you can be more ambitious about assertion and not worry too much about the effect on performance, and if you want real exception handling don't use assertions

13:03 EvanR: production mode seems like the last place i want to omit debug support

13:05 yeah this is not exception handling

13:06 justin_smith: if you are writing a lib, you should consider the fact that users of the lib are allowed to turn assertions off

13:06 so assertions should be used as a dev-time verification of correctness of code, rather than a debugging-of-runtime-condition thing (maybe logging is a better fit for that?)

13:07 technomancy: contracts!

13:07 or something

13:07 EvanR: if they turn assertions off, it shouldnt matter, because they shouldnt be happening

13:07 the errors

13:07 justin_smith: technomancy: schema!

13:08 * EvanR mumbles something about types

13:08 technomancy: racket!

13:09 justin_smith: EvanR: well we do have core.typed for typechecking code, and schema for runtime data validation

13:09 EvanR: i looked at core.typed, i did not understand the filters part

13:09 and schema refers to prismatic?

13:10 justin_smith: yeah, prismatic/schema provides tools for verifying certain properties of clojure data

13:10 EvanR: it sounds good

13:10 justin_smith: things like "this has to be a map with the :a key having a number value"

13:11 EvanR: in this particular case, its asserting that what im looking for in a dictionary is actually there

13:11 rather than a structural assertion

13:11 justin_smith: EvanR: right, so you could describe the dictionary with a schema as always having a value at a particular key

13:11 that is a structural assertion

13:11 EvanR: the keys are dynamic

13:12 justin_smith: EvanR: schema doesn't fully describe the data

13:12 noonian: EvanR: you can do that too i believe

13:12 justin_smith: it just says "it at least needs this kind of value in this place"

13:12 EvanR: which place?

13:12 justin_smith: the one you specify!

13:13 as I said above, for example you could specify "this is a map, it has a key :a, the value at that key is a number"

13:13 that is a schema

13:13 EvanR: this is another mismatch on usage of a map

13:13 its not a record, its a lookup table

13:14 justin_smith: EvanR: then use deftype

13:14 EvanR: all i can say about it is its a map with String keys and the values are vectors

13:14 noonian: maps are often used as records in clojure

13:14 EvanR: i know this.

13:14 i am not using it as one here

13:14 noonian: you can describe what you just said you the schema library is all justin_smith is saying

13:14 justin_smith: EvanR: and exactly what you said is expressable as a schema

13:15 EvanR: justin_smith: runtime checking this fact how often?

13:15 on inserts?

13:15 justin_smith: EvanR: checking it when you invoke the check, that's up to you, they just provide the checker. I think there is a shortcut for doing it on the arg on each invocation of a function. But you can invoke the checking wherever.

13:16 EvanR: it's not a typing system, it is a validation tool

13:16 noonian: yeah, you can either annotate the fns metadata so it is always run with validation or you can only validate it when you want to

13:16 EvanR: yeah so all i was saying is that a check that the particular key i need is there isnt a schema thing

13:16 justin_smith: how not?

13:17 noonian: we're talking about the library called schema, not the abstract concept of what a schema is

13:17 EvanR: its a map from strings to maps, not even known to be non empty

13:18 thats about all i can think of using schema for in this case

13:18 noonian: which is a perfectly valid use case for schema

13:18 if you care to ensure that the data you get conforms to the specification you just said

13:18 EvanR: a runtime lookup that a key is there, that i am already looking up anyway, i dont see a library here

13:18 noonian: sure, thats up to you

13:19 justin_smith: EvanR: I can understand if you don't like this abstraction, but this abstraction does address your data validation issue

13:19 EvanR: so... it equips a map with some extra stuff to never return nil?

13:19 all lookups return something?

13:19 justin_smith: no

13:19 EvanR: ok because that would seem like a weird role for something called schem

13:19 mgaare: you use it to instrument your functions, iirc

13:20 EvanR: it makes total sense to describe record structures

13:20 noonian: it doesn't modify a map, it describes what a map at a certain part of your program is expected to look like

13:20 justin_smith: EvanR: it is an abstract description of a data structure, and a function that tells you whether the input data matches that description

13:20 noonian: you annotate the function, not the data

13:20 EvanR: the exact structure of my dynamic lookup table at runtime might be describable with dependent types or something

13:21 i would need a program to run to describe exactly which keys are in there

13:21 and really it doesnt matter, as long as im not ending up with an invalid key

13:21 justin_smith: EvanR: schema doesn't fully describe the keys, but validates that set of properties you ask it to validate

13:22 noonian: (def my-schema {s/Keyword s/Any}) describes a map of keyword keys to anything

13:22 you could ensure that the values are maps of course

13:22 or that the keys are a subset of a specific set of keywords

13:23 justin_smith: noonian: or that at least key foo is present, with a value of type F

13:23 EvanR: yes that makes sense

13:23 that though would not

13:23 neither would, for my case

13:24 noonian: 'its a map from strings to maps, not even known to be non empty'

13:24 you can describe that easily

13:24 EvanR: id like an environment that separates the concept of records from A -> B maps to avoid confusion on the topic

13:24 noonian: {s/Str {s/any s/any}}

13:24 EvanR: noonian: not even known to be non empty, is a non-constraint

13:24 justin_smith: EvanR: in clojure records (as defined by defrecord) are maps

13:25 EvanR: the situation is very simple

13:25 justin_smith: i understand its all the same here

13:25 justin_smith: not if you use deftype

13:25 EvanR: so they are the same but not

13:25 justin_smith: which I brought up before, if you want a type, use deftype

13:26 EvanR: that would make sense, today i have not brought up any usecase for a record / type

13:26 yesterday though i was talking about records, and people thought i was wanting to know about lookup tables, uniform keys values

13:26 very frustrating

13:27 justin_smith: EvanR: does clojure even have any concept of uniform keys in a lookup table? other than numeric index I guess

13:27 EvanR: uniform key type

13:27 string, keyword, number

13:27 the values is the more interesting thing to be uniform

13:28 justin_smith: but we have no abstraction (other than arrays / vectors) that has uniform key type as a property

13:28 not to mention values!

13:28 EvanR: not unexpected

13:29 does prismatic schema allow recursive schemas

13:30 justin_smith: EvanR: https://github.com/Prismatic/schema/issues/35 addressed here

13:30 technomancy: amalloy_: I remember you saw a use of flatten in lein that was somewhat justified? was it in lein clean?

13:31 EvanR: yurg, cyclic data structure is not what i was expecting

13:32 justin_smith: EvanR: a schema is a data structure, a recursive schema would need to be a cyclic data structure

13:32 EvanR: seems like a limitation of the schema rep

13:32 justin_smith: OK

13:33 EvanR: the set of concerns / interests you have here makes me wonder if you wouldn't prefer using scala over clojure. Not saying "get out of here if you feel that way", just I think scala dev is more aligned with those concerns.

13:33 noonian: schema supports recursive schemas now: https://github.com/Prismatic/schema/wiki/Recursive-Schemas

13:33 justin_smith: (inc noonian)

13:33 lazybot: ⇒ 9

13:33 noonian: i think they just don't guarantee them to be fast when validating

13:33 justin_smith: noonian: I guess I found some out of date info

13:33 EvanR: good enough

13:34 noonian: justin_smith: yeah, that issue was closed at the bottom by an accepted PR :P

13:34 justin_smith: noonian: haha, reading ftw

13:35 EvanR: since i have all this java stuff set up i guess it wouldnt be out of realm of possibilities to install and try scala

13:35 but seems scary as hell

13:35 justin_smith: EvanR: agreed

13:36 EvanR: for example, this type signature freaks me out https://twitter.com/extempore2/status/430341743779659776

13:37 EvanR: wtf

13:37 robstory: there are scarier things, like clobbering immutable namespace with a single import: https://gist.github.com/wrobstory/60750cec022650bf27b1

13:37 justin_smith: EvanR: but clojure has its wtfs too, as we both know

13:39 robstory: does that prevent the original immutible version from being avaialable, or change which version library code would end up using?

13:40 {blake}: I'm trying to get a form going with hiccup and keep getting a "Key must be integer" exception.

13:40 amalloy: {blake}: you have too many parens probably

13:40 {blake}: Minimal example: (defn test-form []

13:40 (f/form-to [:post "/posts/new"]))

13:40 amalloy: ,([:x] [:y])

13:40 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer>

13:40 {blake}: amalloy, Too many parens? Unpossible!

13:40 EvanR: you can never have too many parens

13:41 {blake}: Well, that's what I thought. I'm copying and pasting examples from git and elsewhere, and the common thread is that error.

13:42 robstory: justin_smith: for the former, you can still call scala.collection.mutable.Set, and have to do so explicitly. For the latter, I do not believe it would trickle down into lib code. Should stay contained in that particular scope.

13:42 {blake}: amalloy, Oh...so...okay, that's an error you get when you've executed a function you didn't want and made something a parameter you didn't mean.

13:43 amalloy: well, when you try to call a vector with something that's not an integer

13:43 {blake}: I need that macro thing. macroexpand!

13:46 Well, that didn't help.

13:46 noonian: ,(get [1 2 3] :foo)

13:46 clojurebot: nil

13:46 noonian: hmm

13:46 ,([1 2 3] :foo)_

13:46 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer>

13:47 amalloy: {blake}: i think you need a less minimal example, because that one looks fine

13:48 noonian: get is more forgiving; it works on anything, and never throws an exception

13:48 noonian: interesting

13:49 amalloy: well, "never". you could create a type that responds to get by throwing an exception, but you'd have to do it on purpose

13:51 dbasch: ,(get get get get)

13:51 clojurebot: #<core$get clojure.core$get@48b1ca>

13:51 dbasch: ^ four get

13:51 justin_smith: dbasch: I only just now realized it was a rebus

13:52 ,((get get get get) (get get get get) (get get get get) (get get get get))

13:52 clojurebot: #<core$get clojure.core$get@48b1ca>

13:56 turbofail: we need to go deeper

13:58 noonian: sounds like a job for ben affleck and bruce willis

13:58 amalloy: ,((fn [n] (nth (iterate (fn [get] (get get get get)) get) n)) 10) ;; arbitrarily deep, with example tenth-order usage

13:58 clojurebot: #<core$get clojure.core$get@48b1ca>

13:59 amalloy: plus, i got to write *six* gets in a row

14:00 justin_smith: (inc amalloy)

14:00 lazybot: ⇒ 182

14:22 technomancy: amalloy: hey, I remember you saw a use of flatten in lein that was somewhat justified? was it in lein clean?

14:23 amalloy: technomancy: that's the only use of flatten in leiningen at all, now that i've removed the others

14:23 technomancy: amalloy: I just got a PR for lein clean that uses it and I almost flipped out

14:23 amalloy: i'm not really convinced it's justified, but taking it out could break back-compat in ways i'm not competent to diagnose

14:23 technomancy: but then I took a closer look, and it seems necessary to support both singular and plural paths

14:23 :classes-path vs :source-paths

14:24 amalloy: you still don't need a whole flatten for that, just (mapcat (fn [x] (if (coll? x) x [x])) whatever)

14:25 technomancy: true, but that's super noisy in comparison

14:25 amalloy: sure. but you can define that somewhere, and then use it in a non-noisy way. call it squish-a-little

14:26 justin_smith: sounds like we need a version of concat that takes both collections and single items (and would look a lot like amalloy 's anonymous fn above)

14:26 hiredman: venial-flatten

14:26 justin_smith: haha

14:27 amalloy: (inc hiredman)

14:27 lazybot: ⇒ 60

14:29 technomancy: trying to keep my LOC numbers down here amalloy, geez

14:29 amalloy: dem bytes ain't cheap

14:30 technomancy: if we get within an order of magnitude of the lines of sbt we won't be allowed to make fun of them as effectively

14:32 TimMc: technomancy: Longer lines.

14:33 turbofail: you can still make fun of them for taking a ridiculously long time to do anything

14:33 technomancy: turbofail: let he who is without sin cast the first stone

14:35 turbofail: lein seems to do most operations significantly faster

14:35 even with the clojure startup time

14:35 EvanR: how would venial flatten know if you really wanted to flatten something or treat it as a "single item"

14:36 justin_smith: EvanR: it only flattens the args, not any of their contents

14:36 TimMc: EvanR: coll?

14:37 EvanR: i guess i should have specified, how would it know if you wanted to flatten a coll

14:37 a subcoll

14:37 justin_smith: EvanR: if you wanted that, you are calling the wrong function

14:37 amalloy: EvanR: easy: you don't, or you wouldn't have called venial-flatten

14:38 justin_smith: ,(defn venail-flatten [& args] (apply concat (map #(if (coll? %) % [%]) args)))

14:38 clojurebot: #'sandbox/venail-flatten

14:38 amalloy: it's like, how does + know you don't want to multiply one of the items instead?

14:38 turbofail: asking the important questions

14:38 justin_smith: ,(venial-flatten "a" ["b" "c" ["d"]] ["e" "f"])

14:38 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: venial-flatten in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:38 EvanR: i misunderstood the purpose here, its concats args

14:38 amalloy: justin_smith: s/apply-concat+map/mapcat/

14:38 EvanR: rather than flattening something

14:38 justin_smith: ahh, yeah

14:38 ,(defn venial-flatten [& args] (mapcat #(if (coll? %) % [%]) args))

14:38 clojurebot: #'sandbox/venial-flatten

14:39 justin_smith: ,(venial-flatten "a" ["b" "c" ["d"]] ["e" "f"])

14:39 clojurebot: ("a" "b" "c" ["d"] "e" ...)

14:39 justin_smith: EvanR: right, but it replaces a use case where otherwise flatten got called

14:39 EvanR: another thing i was thinking of was, your structure might not have enough info in it to tell an operation what to do with it, would be another style if it did

14:39 amalloy: i think the version of it that would be useful for lein doesn't take &args, but sure, a general one might

14:40 {blake}: amalloy, You're right; because the error is in the calling code, which is trying to call the result of the routine.

14:40 justin_smith: EvanR: yeah, this is reading a config file (project.clj)

14:40 EvanR: as such it has "conveniences" for the writer

14:40 amalloy: {blake}: speaking of which: stacktraces!!! so important. it would be pretty easy to have told you that, if you'd gisted a stacktrace along with the error message

14:41 {blake}: amalloy, OK, I have another opportunity, since it's back. =P

14:41 EvanR: ,(concat [1] [2] [3] [4])

14:41 clojurebot: (1 2 3 4)

14:41 turbofail: we need a "fatten" function. though i'm not exactly sure what it will do

14:41 EvanR: ,(concat [1] [2] 3 [4])

14:41 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

14:42 EvanR: ,(concat [1] [2] #{3} [4])

14:42 clojurebot: (1 2 3 4)

14:42 amalloy: turbofail: ##((fn fatten [x] (nth (iterate list x) 10)) 5)

14:42 lazybot: ⇒ ((((((((((5))))))))))

14:42 turbofail: this will suffice

14:42 EvanR: ,(concat [1] [2] {3 5} [4])

14:42 clojurebot: (1 2 [3 5] 4)

14:42 EvanR: yurg

14:43 justin_smith: ,(seq {4 5 6 7})

14:43 clojurebot: ([4 5] [6 7])

14:43 EvanR: ,{1 2 3}

14:43 clojurebot: #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>

14:43 justin_smith: ,(flatten {4 5 6 7})

14:43 clojurebot: ()

14:43 EvanR: im glad that case is taken care of

14:44 amalloy: justin_smith: a classic

14:45 {blake}: justin_smith, Wow, that's really flat.

14:45 justin_smith: {blake}: inorite

14:45 EvanR: very zen

14:46 {blake}: So, here's my new "key must be integer" (now! with stack trace!) https://www.refheap.com/92490

14:46 justin_smith: (dec flatten)

14:46 lazybot: ⇒ -4

14:46 {blake}: lol

14:46 EvanR: (dec flatten)

14:46 lazybot: ⇒ -5

14:47 {blake}: Hiccup seems easy enough to use, but not being able to figure out how to glue it into my ring app is why I started rolling a few simple routines to do my own HTML.

14:51 justin_smith: {blake}: I think the issue could have to do with the ambiguity of providing a function to be called on the request, vs creating the response inline. I haven't used compojure in ages, but you are clearly directly specifying a response with one route, while naming a function to be called in another

14:52 {blake}: justin_smith, Hmmmm.

14:54 justin_smith: what happens if you change the first route to do (test-form spreadsheet)

14:54 {blake}: justin_smith, OK, thanks. Let me see if I can't find out how those are supposed to work together.

14:55 csd_: Is it necessary to escape user passwords when developing a web app?

14:56 mgaare: csd_: are you not hashing user passwords?

14:56 csd_: i am--good point

14:57 EvanR: users should be allowed to put any text they want for a password

14:57 csd_: how do you guys guard against sql injection

14:57 in general

14:58 amalloy: csd_: always use parameterized queries, of course

14:58 never ever ever ever write (str "insert into x (password) " user-password)

14:59 EvanR: ideally the library doesnt even let you use a string

14:59 amalloy: meh

14:59 csd_: amalloy: korma/jdbc are fine though right?

14:59 amalloy: csd_: sure, as long as you never build query strings yourself

15:00 EvanR: i think it'll be a few more generations before we see a no-strnigs sql library that actually lets you do the things you want to do and is as approachable/flexible as sql

15:00 EvanR: in clojure?

15:00 dbasch: passwords should be hashed as soon as possible on the server, and the plaintext forgotten forever

15:01 EvanR: if you use a query type which is almost like strings but doesnt support strcat that would do it

15:02 where ? and ?? are replaced with args or lists of args

15:02 mgaare: then you've lost composability

15:02 amalloy: mgaare: well, you don't really have that with sql anyway. it's not much of a loss

15:03 mgaare: I felt like this had some good ideas, just didn't quite get there: https://github.com/LauJensen/clojureql

15:04 amalloy: mgaare: right, it's the lisp curse: 20 different people each solving 80% of the same problem

15:05 mgaare: I've got some ideas for yet another crack at the problem

15:05 EvanR: just drop sql the language

15:05 dbasch: that happens in every language, someone solves the interesting 80% of something and never gets to the tedious 20% that would take forever

15:06 csd_: coughlighttablecough

15:06 mgaare: one insight for me is that combining query generation with query executiotn is a mistake

15:07 {blake}: csd_ lol

15:08 EvanR: in what sense are they combined?

15:08 amalloy: dbasch: you've read the lisp curse, i presume?

15:09 dbasch: yes

15:09 mgaare: EvanR: in the sense that many libraries are built around doing both together

15:10 EvanR: im sure youre right but which one are you thinking of

15:10 mgaare: korma, clojureql, hyperion are a few off the top of my head

15:11 EvanR: looking at korma, wow jeez

15:12 i guess this is for quick and dirty

15:12 clojurebot: Ok.

15:13 EvanR: you can wrap these in lambdas, but good luck mixing and matching where clauses

15:13 mgaare: Chris Granger later on said he regretted the way he designed korma, that it was the result of being new to the language and applying too much thinking from elsewhere

15:14 EvanR: now im even more curious, elsewhere where?

15:14 csd_: as someone who just recently used korma id love to know a better alternative

15:14 turbofail: honeysql is an example of a library that doesn't combine the two

15:14 mgaare: other languages

15:14 there's a lot of ActiveRecord influence in there

15:14 EvanR: right that one

15:15 justin_smith: mgaare: ahh, so he was a rubyist?

15:15 mgaare: yeah, HoneySQL is pretty good

15:15 justin_smith: I'm not sure of his full background. I know that he used to work at Microsoft on VS

15:16 justin_smith: mgaare: ahh, you are referring to the general active record concept, not the specific ruby lib called ActiveRecord?

15:16 turbofail: honeysql has some issues of its own, don't remember exactly what they were

15:16 {blake}: "The Lisp Curse" is brilliant. And reminds me of my desire to implement Clojure in Smalltalk.

15:17 dbasch: aka ORM

15:17 years ago I had an employee who implemented his own ORM in Java because he didn’t like Hibernate

15:17 mgaare: justin_smith: yeah, I just think of ruby's ActiveRecord being so dominant in mindshare that I sometimes use the terms interchangeably

15:17 rubber_duck: why do people bother wrapping up SQL :\

15:18 YeSQL takes care of the nasty string embedding issues

15:18 one of the primary reasons I use clojure is because it works with data so nicely it's super easy to consume results of raw SQL queries

15:18 justin_smith: mgaare: from some googling I discover there is also a lib called ActiveRecord for php

15:18 dbasch: rubber_duck: because at some point people thought that you could abstract away the fact that there was a sql database under your persistent object store

15:19 turbofail: rubber_duck: sometimes i want to generate queries, not merely paramterize them on data

15:19 justin_smith: dbasch: because the differences in semantics between your object system and the database are just useless noise, of course :) you can just ignore them

15:19 mgaare: rubber_duck: ah, yesql looks pretty cool. Hadn't seen this before

15:20 rubber_duck: turbofail, aside from trying to implement a custom DSL -> SQL compiler I think I'd still rather work with strings

15:20 dbasch: justin_smith: there’s even a wikipedia page for the concept http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch

15:21 turbofail: rubber_duck: suit yourself. i happen to think working with strings is a disaster

15:21 EvanR: "oop vs relational war"

15:21 circa 1991

15:21 mgaare: it reminds me of how things worked with html libraries somewhat... I used enlive for a while, super complex and powerful, eventually said "f it" and went all the way over to selmer

15:22 yesql seems like an overreaction in the same way

15:22 rubber_duck: EvanR, that's the beautiful part of clojure - there's no OOP - SQL is just another data returning function - you don't care about "keeping your objects synchronized" because you're working with values by default

15:23 justin_smith: rubber_duck: to be fair there is some OOP, but we can usually avoid it, and it's on the layer of "how to tell jdbc what to do" not on the layer of representing the queries and results

15:24 EvanR: yeah i tried reading about that stuff in the history books, and it made no sense

15:24 so many assumptions about how you have to do stuff, it was all a figment of their imaginations

15:24 amalloy: EvanR: a string type that doesn't support concatenation is certainly interesting. you could do even better in haskell, with a newtype wrapper around String such that you can concat query bits with each other but not with user-input strings

15:25 bbloom: mgaare: yesql is only an overreaction if you have a genuine need to abstract over sql dialects or compose queries from fragments

15:25 EvanR: amalloy: the haskell lib mysql-simple and postgres-simple is what i was thinking of, it overload string literals for this

15:25 amalloy: right

15:25 bbloom: if you don't need to abstract over sql dialects, you can use database-specific abstraction and composition mechanisms

15:25 amalloy: i haven't actually used those, but overloaded strings did seem like the natural thing when you suggested it

15:26 EvanR: but the point about it not being as flexible is true, in which case you really want your field names, joins, where clauses, group bys, orders, limits, and unions to be their own types which you just nest

15:26 thats the simple way

15:26 or you could make this sql compiler thing

15:26 mgaare: bbloom: The pile-of-strings approach is not very resilient to change either

15:26 bbloom: mgaare: the question is: what changes?

15:27 mgaare: in my experience it's easier to change sql queries than it is to change ORM invocations

15:27 you're more likely to get analysis errors trying to execute fixed queries than you are trying to generate queries reflectively from schema

15:28 mgaare: I think we can agree that ORM is not the way

15:28 amalloy: it's no coincidence that ORM shares two letters with MURDER

15:28 bbloom: sure, so ORM is clearly out, but the question is whether or not you want a metalanguage for queries

15:28 EvanR: "how do i do X" "dont do X" mapper

15:28 bbloom: korma etc are decidedly ORM-like

15:28 rubber_duck: as much as I love clojure reading it's source to reverse engineer protocols/specs makes me want to bang my head against the wall, I wish core.typed was at the point it could be baked in to the language :)

15:28 EvanR: sql is already a meta language for queries

15:28 bbloom: but there's stuff like ClojureQL etc that are arguably more composable

15:28 EvanR: a sucky one

15:29 hiredman: really, you just want something that makes generating sql strings better

15:29 EvanR: and you always want a better language for doing X rather than beating your keyboard like a caveman

15:29 Bronsa: ,(meta (seq (with-meta (lazy-seq []) {:foo 1})))

15:29 bbloom: right, but there's always costs

15:29 clojurebot: nil

15:29 hiredman: relational algebra is fine and good, the result sets you get back from java.jdbc are fine

15:29 bbloom: coding directly to a SQL AST may be preferable in some cases

15:29 hiredman: bbloom: right

15:29 bbloom: but SQL wasn't designed to be coded to at the AST level like a lisp was

15:30 so there's naturally some abstract vs concrete syntax mismatch

15:30 so the developer has to bear the weight of that cost

15:30 if you're not metaprogramming queries (or not doing it often) it may not be worth it to pay that cost for all other concrete queries

15:30 EvanR: until some developer makes a better language that other developers recognize as good

15:30 hiredman: speaking of everyone having an 80% solution https://github.com/hiredman/graph/blob/master/src/com/manigfeald/graph/rel.clj is what I wrote last time I had to write a lot of sql joins

15:30 mgaare: SQL was designed for businesspeople to use, and it was at least more successful at that than the previous efforts at that objective like Cobol

15:30 bbloom: btw, i'm a big fan of C#'s Linq to SQL

15:31 it's exceptionally well done

15:31 EvanR: yeah thats a good example

15:31 bbloom: it has both solid concrete sytnax and is very robust both in terms of reliability and completeness

15:31 rubber_duck: F# typeproviders look even sexier

15:31 hiredman: bbloom: indeed

15:32 EvanR: foo to sql compiler

15:32 design pattern

15:33 justin_smith: bbloom: would Linq be usable from clojure-clr?

15:33 bbloom: justin_smith: the compiler might be, yeah

15:33 justin_smith: you'd still need a mapping from a clojure data structure to an Expression data type to invoke the compiler

15:34 rubber_duck: In F# type providers basically both the compiler and the IDE can read your DB schema trough a plugin and generate type info and provide code completion off live DB - that's just :O

15:34 justin_smith: bbloom: that seems more tractable than string based stuff at a glance

15:34 bbloom: justin_smith: you'd get a good SQL compiler, but you basically now need a clojure to C# compiler

15:34 which is, of course, different than clojure to msil

15:34 linq operates on an expression tree datatype

15:35 seems like that may be as hard, if not harder, than just compiling to SQL

15:35 EvanR: expression trees without further context sounds way easier to deal with than sql text

15:36 but its c#

15:36 bbloom: basically, the C# compiler uses the type of an argument to overload the call site to automatically quote the passed expression

15:36 it's basically C#'s macro mechanism

15:36 turbofail: hm. interesting

15:37 bbloom: http://msdn.microsoft.com/en-us/library/bb397951.aspx

15:37 it's similar to scala's call by name, but scala does not let you inspect a call by name argument

15:37 to do that, you must write a scala compiler plugin

15:41 turbofail: this doesn't seem to allow for compile time shenannigans. though on the plus side, it doesn't seem to allow for compile time shenannigans

15:43 though it also appears you can compile at run time, as in clojure. so the distinction is kind of fuzzy

15:51 andyf: Bronsa: Would you prefer I test latest tools.reader over the revert change you suggested?

15:54 Bronsa: andyf: yeah

15:56 EvanR: apt-get installing scala, im feeling bored with life

15:57 perplexa: does anybody use clojure to build GUI apps?

15:58 and if yes, what libs do people use? i just saw seasaw but it seems unmaintained

15:58 sveri: Hi, name one beginner friendly .emacs.d repo, at best with an overview of the shortcuts, pleas

15:59 andyf: A few have created some: Nightcode clooj clj-ns-browser. Seesaw is a good swing lib wrapper

15:59 perplexa: thx andyf!

15:59 andyf: Why did it seem unmaintained ?

16:00 perplexa: commits are from 4-1 year ago

16:01 andyf: There is an email list where some q & a still occurs. Not sure if it is still being enhanced.

16:01 noonian: you could also go the cljs + node webkit route

16:02 perplexa: btw andyf, i didn't mean IDEs ;p

16:02 amalloy: perplexa: sometimes things are just done. seesaw works fine, as far as i know. there's no need to constantly add new bells and whistles to it

16:03 perplexa: i'll give it a try then

16:03 andyf: Seesaw is not specific to IDEs. They are just examples I knew without looking up more

16:05 ustunozgur: try this: google for java rationale

16:06 amalloy: perplexa: also, it looks like he's been merging pull requests regularly. Last one merged a month or two ago

16:08 {blake}: Crap. Hiccup doesn't have a date control?

16:08 Bronsa: http://sprunge.us/LZTB

16:10 EvanR: you know very well source code degrades over time naturally and must be constantly updated to maintain a constant level of workingness

16:10 amalloy: that's interesting, Bronsa. does the compiler just choose arbitrarily among equally-good overloads?

16:10 AimHere: EvanR, binary code degrades faster, of course

16:11 EvanR: lol

16:11 Bronsa: amalloy: that's what it looks like

16:11 seangrove: {blake}: I assume you must mean something like hiccup (in clojure) throws an error if you do [:date ...]?

16:11 perplexa: amalloy: fixing typos in comments ;/

16:11 amalloy: perplexa: so, it works so well that the only pull requests people are sending him are comment typos, and he's even merging those? where is the bad news?

16:12 justin_smith: {blake}: seangrove: yeah that confused me too, all hiccup does is output tagged elements, why would it care if it was a date or not?

16:12 {blake}: seangrove, I'm looking for a "date-field".

16:13 Bronsa: amalloy: the funnt thing is that it doesn't do that at compile time, those compile into a reflective call

16:13 amalloy: right

16:13 perplexa: i thought there would be the need to update it, but seems swing is consistent in its api, but i really have no idea :)

16:13 seangrove: {blake}: Post some code and error output

16:13 AeroNotix: dakrone: hey when are you going to release clj-http 1.0.2?

16:14 {blake}: seangrove, Nothing to post. There's no "date-input". Maybe I'm supposed to use "input-field"--but that's a "defn-".

16:14 AeroNotix: not trying to rush you but a weird bug between elastisch and clj-http seems resolved when using 1.0.2-SNAPSHOT

16:15 seangrove: {blake}: Surely it's just [:input {:type "date"}] ?

16:15 {blake}: seangrove, Like maybe it's supposed to be called (inputfield "date" "mydate")

16:15 amalloy: Bronsa: what order do the methods come out in when you use reflection to look up the methods named foo and bar?

16:16 seangrove: Weird, I had never even seen this https://github.com/weavejester/hiccup/blob/1.0.5/src/hiccup/form.clj#L89

16:16 I've never used the helper functinos I guess

16:16 justin_smith: {blake}: I think what you may be missing is that hiccup is really about constructing a fairly straightforward edn that can be translated to html, and you don't need a specific function to create that edn, you can put it in literally or write your own function that outputs edn

16:16 seangrove: justin: Did you know about those helper elems?

16:16 {blake}: justin_smith, Yeah. Sounds plausible.

16:16 justin_smith: seangrove: I have looked at them, but never really needed them

16:17 Bronsa: amalloy: yeah they come out in reverse order

16:17 amalloy: it looks to me like the issue is that (clojure.lang.Compiler/subsumes (into-array [Long]) (into-array [Integer/TYPE])) and (clojure.lang.Compiler/subsumes (into-array [Integer]) (into-array [Long/TYPE])) are both true

16:17 {blake}: justin_smith, seangrove Leave it to the noob to find the obscure stuff...

16:17 justin_smith: hehe

16:17 amalloy: so the compiler considers those both perfect matches, and doesn't bother looking to see if there's another equally-good match

16:18 justin_smith: {blake}: another approach would be to use the same macros that are being used in the code seangrove linked to

16:18 Bronsa: amalloy: I gave up months ago trying to understand how all that actually can work, I just accept it does most of the time

16:18 amalloy: a solid plan

16:19 {blake}: justin_smith, I am using those; that's why I was looking for a "date-field".

16:20 justin_smith: {blake}: I mean the macros that generate those definitions

16:20 (it's macros all the way down)

16:21 {blake}: justin_smith, Till you get to the turtles, anyway. I was thinking about the "input-field" function. Was there a macro I could use instead?

16:22 andyf: Bronsa: Maybe I am getting overly worried by your example, but does that mean that Math/abs could truncate longs to ints with no way to predict?

16:22 noonian: as long as the last one never gets expanded then you

16:22 you're good right?

16:22 {blake}: OK, here's a more general-purpose question: I'm used to having a substring function that handles out-of-bounds conditions...gracefully...like (subs "" 0 4) returning "", rather than "HOW DARE YOU!?!" Is there such a thing in Clojure?

16:22 justin_smith: {blake}: in seangrove's link they use "defelem"

16:23 great simile about system design: "like putting a pig heart in an alligator because mammals are clearly better than reptils"

16:23 {blake}: justin_smith, So I could make a "defelem date-field", IOW. Yeah... OK, feasible.

16:23 EvanR: sounds tastey

16:24 {blake}: It's bacon that eats you!

16:24 justin_smith: EvanR: there's a cajun place nearby, open real late, you can get a killer mac+cheese+alligator sausage

16:26 amalloy: andyf: looks possible to me, yes

16:26 noonian: justin_smith: where at?

16:27 justin_smith: noonian: portland, OR

16:27 noonian: justin_smith: i know, i mean where in pdx?

16:27 is the cajun place you're talking about

16:28 justin_smith: montage, se industrial

16:28 noonian: i've never had alligator

16:28 ah right, one of my friends seears by montage

16:29 justin_smith: it's an intense place, definitely not a laid back atmosphere

16:29 Bronsa: andyf: yeah it would look like so

16:29 andyf: OTOH (fn [a] (Math/abs a)) would emit a reflection warning

16:29 amalloy: andyf: if you decompile (fn [x] (Math/abs x)), it boils down to a reflective call that hinges on clojure.lang.Reflector/paramArgTypeMatch

16:30 and it says that a Long arg matches an int param

16:32 and the way it unboxes is via Long.intValue(), which silently overflows

16:32 andyf: Uncool

16:37 Bronsa: I suppose it makes sense that the combination of how tools.reader adds more file loc metadata than the Clojure reader, and how syntax quote works, that some code could throw method too large with tools.reader when eval'd but not with standard reader ?

16:37 Bronsa: andyf: yeah probably

16:37 andyf: it might choke on the <clinit> method

16:37 amalloy: andyf: i'm a little surprised. at least in the reflective case, your code is really slow already anyway; Reflector could do an overflow check when unboxing, and throw an exception

16:38 andyf: I have only seen that occasionally so far. Will let you know if it gets worrisome.

16:38 Bronsa: andyf: I remember seeing that for midje a while ago

16:39 amalloy: Bronsa: just in general, not for tools.reader, right?

16:39 andyf: I suppose best workaround would be to disable some of that extra metadata in tools.reader ?

16:40 Bronsa: amalloy: some midje macros output a *huge* amount of code for even relatively small inputs, tools.reader adds >2x the amount of metadata that LispReader does and that's enough to trigger a methodwhatever exception

16:41 andyf: ATM there's no way to control what metadata is attached where in tools.reader

16:42 andyf: I know how to use grep for end-column :-)

16:42 Bronsa: heh

16:42 andyf: it's not only end-column/end-line though

16:42 andyf: tools.reader adds line info on vector/set/map literals too

16:43 and maybe on symbols or something like that, I don't remember

16:43 andyf: cljs needs this to emit accurate source-maps

16:43 andyf: Ok. Good to know, but not urgent.

16:44 hiredman: on that basis I continue to blame midje for everything

16:46 amalloy: Bronsa: i remember long ago that midje was regularly emitting enough code to break the compiler even using the ordinary reader, so i can't really blame tools.reader for this

16:49 TimMc: I feel like this is probably a usecase for generative testing. :-)

16:50 Oh nvm, you're talking about the sheer quantity of code.

16:50 We've run into that at work a couple times, but it's slightly our fault.

16:50 Bronsa: amalloy_lunch: the real issue IMHO is that the compiler doesn't split methods when they start getting big enough they could hit the limit & doesn't compress the data when building the constant table in <clinit>

16:51 those are both things I'd like to address in tools.emitter.jvm but I have an awful long list of things to do before I can start playing again with t.e.jvm

16:54 andyf: (zinc Bronsa)

16:54 (inc Bronsa)

16:54 lazybot: ⇒ 65

16:54 andyf: I hope you are not now, or ever, covered in zinc

16:55 TimMc: unless it's sunscreen

16:55 Bronsa: Is there a Jira ticket for that? I'd like to vote for it.

16:55 andyf: I like to think there are 2.5 people working on Eastwood, and Bronsa is 2 of them :-)

17:00 TimMc: Hah! Who is .5?

17:00 andyf: Me

17:06 Bronsa: TimMc: no ticket that I'm aware of

17:06 technomancy: ~theology

17:06 clojurebot: It's greek to me.

17:07 tim___: ooh, that's a good one

17:07 Bronsa: andyf: that's totally untrue and you know it. both eastwood and t.a would be nowhere near what they are now if it wasn't for your hard work

17:08 andyf: It's a humbler- than-I-actually-am joke

17:08 technomancy: tim___: not actually the response I was expecting, but that works surprisingly well.

17:09 ~geometry

17:09 clojurebot: Titim gan éirí ort.

17:09 technomancy: ~theology is <reply>Clojure needs some theology and geometry; some taste and decency. I suspect we are teetering on the edge of an abyss.

17:09 clojurebot: 'Sea, mhuise.

17:09 technomancy: ^ what I think of when I hear that midje is emitting enough code to break the compiler

17:12 justin_smith: technomancy: among the many things we have in a lisp that scale to great ends thanks to our compible tools, is space usage

17:13 tbaldridge: and it's not just Midge, try using core.match with core.async's go macro...

17:14 or writing any large function in something like core.match or core.async

17:16 technomancy: one of the many reasons it bums me out that pattern matching isn't part of the language

17:27 EvanR: im using core.match, should i be worried?

17:29 andyf: Probably not, unless you mix with core.async and/or large functions

17:30 technomancy: I can't use it because it would lock all lein plugins into a specific version =\

17:30 but if you don't have a big plugin ecosystem that shouldn't be a problem for you

17:30 it used to have a bunch of AOT bugs, but it sounds like those have been taken care of

17:30 andyf: technomancy: Not if you renamed the namespace of the one you use :-)

17:31 Bronsa: andyf: hah, I was waiting for this comment

17:31 justin_smith: andyf: and the jar dep too?

17:31 andyf: I don't recommend that. I am a masichist in some ways.

17:32 technomancy: don't give me any crazy ideas

17:32 I have plenty of my own, and it gets confusing when I have to tell them apart from other peoples' crazy ideas.

17:32 =)

17:32 andyf: justin_smith: No jar dep. copy the source & rename the namespaces

17:33 Assuming licenses are compatible

17:33 technomancy: like what clojure does with asm, I guess

17:33 justin_smith: oh, of course

17:39 amalloy: i would support a jar rename of core.match by technomancy. it would have to be called technomatchy or matchnomancy or something

17:39 and it would be sufficiently advanced to be indistinguishable from matchic

17:40 justin_smith: phil.matchelberg

17:40 amalloy: (inc justin_smith)

17:40 lazybot: ⇒ 112

17:41 andyf: Any technology distinguishable from magic is insufficiently advanced.

17:42 jamieenglish: Hi all, I'm looking to build a load testing web app and want to use JMeter as a library, rather than an executable. Is this a bad idea??

17:42 lazybot: jamieenglish: Uh, no. Why would you even ask?

17:43 andyf: Man, lazybot has no empathy

17:43 justin_smith: lazybot, are you silly??

17:43 lazybot: justin_smith: Definitely not.

17:44 arohner: ok, real stupid question. clj-time surely has a date time formatter that will take an #inst, right?

17:44 (with the #inst part stripped)

17:44 dbasch: lazybot is distinguishable from magic

17:44 hiredman: #inst will actually take a lot of things

17:44 arohner: hiredman: my goal is to take a string generated by #inst, and parse into joda (and then later spit joda times into strings that resemble #inst)

17:45 jamieenglish: Well, lazybot, jmeter is cool as a cli, but there doesn't seem to be much info on using it to programatically build and run load tests :(

17:45 arohner: I know I can write the formatter, I'm just amazed it doesn't exist yet

17:45 or I'm unable to find it

17:45 justin_smith: jamieenglish: in case it is not clear, lazybot answers anything ending in ?? with a random yes or no

17:45 amalloy: jamieenglish: lazybot is a bot; he's just guessing that because your question ended with ?? you are asking something to which the answer is probably "no"

17:45 EvanR: ??

17:45 lazybot: EvanR: Uh, no. Why would you even ask?

17:45 clojurebot: CLABANGO!

17:45 amalloy: justin_smith: not so!

17:45 EvanR: ???

17:45 lazybot: EvanR: Yes, 100% for sure.

17:46 amalloy: is there a way to force lazybot to answer with a yes???

17:46 lazybot: amalloy: Yes, 100% for sure.

17:46 justin_smith: amalloy: oh, TIL

17:46 EvanR: ? ?

17:46 jamieenglish: justin_smith: I got that :)

17:46 amalloy: justin_smith: the ?? ending is the only part of it that seemed to me to be actually a good heuristic; i put in the ??? thing so i could use lazybot as a stooge

17:46 EvanR: #"\?\s*?\d*$"

17:47 justin_smith: amalloy: look for a ‽ trigger in my pr for lazybot

17:47 * EvanR throws in more \

17:48 technomancy: we had someone get super mad at that in #leiningen the other day

17:48 but it was about a windows question and he was actually pretty mad to begin with afaict

17:48 amalloy: is it possible that amalloy is secretly pulling all the strings behind lazybot‽

17:48 lazybot: "no, no way that would ever happen"

17:49 amalloy: lol, silly me. put in ""s as if IRC were a clojure repl

17:49 justin_smith: amalloy: I read the quotation marks as sarcasm

17:49 EvanR: hhkklklhkjh

17:49 hiredman: ~amalloy

17:49 amalloy: EvanR: vim is over there

17:49 clojurebot: amalloy only uses locally sourced, free range electrons

17:50 amalloy: technomancy: it's a fun feature, but i probably wouldn't add it today, just because he does occasionally upset people who don't get it

17:51 sometimes those people deserve it, but uninformed newbies don't need any extra confusion in their lives

17:51 justin_smith: jamieenglish: your question piqued my curiosity, and all I find so far is forum threads about whether it would be a good idea (with many people saying it is crazy) and no guides to embedding jmeter, or examples of using it that way.

17:51 dbasch: amalloy: we can all use more confusion http://www.scientificamerican.com/podcast/episode/confusion-helps-us-learn-12-06-25/

17:51 technomancy: amalloy: I'd say it's not bad in high-traffic channels where the bot is unlikely to be the only response

17:51 sdegutis: Hi bbloom. Thanks for the fun conversation about religion on Twitter.

17:52 technomancy: but timezones make it more complicated too

17:52 bbloom: sdegutis: that isn't appropriate to bring up here

17:52 hiredman: I dunno, I mean, I seem to recall hearing that the less informed you are about a topic the more confident you are in your opinions on it

17:52 sdegutis: Oops.

17:52 hiredman: so maybe confusion is called for

17:52 dbasch: not sure, I’m meta-confused

17:52 technomancy: relevant https://twitter.com/geektastic/status/527456651578966017

17:53 justin_smith: hiredman: dunning-kruger? that's kind of a curve

17:53 jamieenglish: justin_smith: thanks for looking. I'll have a quick stab at it and hopefully report back if I get anywhere

17:54 technomancy: "We come here upon what, in a large proportion of cases, forms the source of the grossest errors of mankind. Men on a lower level of understanding, when brought into contact with phenomena of a higher order, instead of making efforts to understand them, to raise themselves up ...

17:54 justin_smith: jamieenglish: I bet ##java would have more actual insight

17:54 technomancy: to the point of view from which they must look at the subject, judge it from their lower standpoint, and the less they understand what they are talking about, the more confidently and unhesitatingly they pass judgment on it."

17:54 ^ tolstoy had a good explanation for why people go "ugh parens"

17:54 amalloy: technomancy: solution to non-problem: tell lazybot to /nick lazyBOT-this-is-a-BOT

17:54 jamieenglish: justin_smith: cheers, I'll try there

17:54 technomancy: amalloy: nope, people would still miss it.

17:55 amalloy: technomancy: a non-solution to a non-problem, then. seems like a good plan

17:57 mmeix: justin_smith hyPiRion P.S. to the problem I had yesterday: found another solution without reduce :-) https://www.refheap.com/92493

17:57 EvanR: /nick NOT-A-BOT

17:58 kenrestivo: well i for one enjoy lazybot and clojurebot's weird quirkd

17:59 hugod: bbloom: re your conversation on stevedore, dsl's, etc, I am generally unhappy with stevedore being more than a syntactic translation. I would really like to be able to try using an equivalent of racket's #lang support to have stevedore look more like plain shell, and just add interpolation of clojure values.

18:00 amalloy: mmeix: (defn runs [coll] (flatland.useful.seq/glue conj [] #(= %2 (inc (peek %1))) coll))

18:00 hoangelos: I'm using the clojure client. Is there a way to get the delete-directory to be recursive?

18:00 justin_smith: hoangelos: "the clojure client"?

18:01 hoangelos: well. it's just a wrapper around the java client...

18:01 oops

18:01 justin_smith: hoangelos: what's the referent here?

18:01 bbloom: hugod: interesting

18:01 hoangelos: hilarious wrong room

18:01 mmeix: amalloy (flatland.useful.seq/glue) is new to me ... looks useful though

18:01 amalloy: mmeix: it's super useful for batching of all sorts

18:01 kenrestivo: well of course it's useful, it's useful.

18:02 amalloy: and this has the upside that it's lazy-ish, or at least as lazy as partition is

18:02 mmeix: amalloy thanks! will try

18:03 justin_smith: mmeix: amalloy: not to be confused with gfredericks/useless

18:03 mmeix: how do you people know about sich a lib? I wouldn't know how to search for something like that ..

18:03 technomancy: same way you solve every problem

18:03 clojurebot: Titim gan éirí ort.

18:03 amalloy: mmeix: i wrote it

18:03 technomancy: ask on IRC!

18:03 justin_smith: mmeix: well, amalloy knows about it because he wrote it

18:03 heh

18:03 mmeix: ah! ok ... so:

18:04 dbasch: mmeix: now you know about it because you asked

18:04 mmeix: (inc amalloy)

18:04 lazybot: ⇒ 183

18:04 amalloy: but useful is broad enough that it has answers to a lot of common problems; it might be worth your while to skim it and take note of anything you might want later

18:04 http://flatland.org/useful/

18:04 dbasch: contagiousness is the essence of virality

18:05 mmeix: thanks - this IRC channel is a constant source of wisdom for a beginner ...

18:07 amalloy: oh nice, i forgot i added flatland.useful.fn/ap

18:08 the number of times i've written something like (-> xs (foo) (bar) (apply update-in [:x] inc)) and then been like "what the heck why doesn't this work"...

18:09 er, except that inc of course doesn't want to be applied; imagine some other function for the example

18:09 when clearly i should be writing (-> xs (foo) (bar) ((ap update-in) [:x] inc))

18:10 mmeix: BTW: does anyone know about a introductory tutorial for derive?

18:11 (maybe I should immerse myself into Joy of Clojure for this ...)

18:12 but for this evening: studying the treasures of flatland :-)

18:13 justin_smith: mmeix: my suggestion around derive was you can use multimethods to describe behaviors on various kinds of input, and then derive to build heirarchies of things with behaviors

18:13 mmeix: aha! ok ...

18:13 justin_smith: mmeix: the embryo of an idea there being that one could model musical domain knowledge about rules that way

18:14 but it's not a totally solidified thing, may be hare-brained

18:15 mmeix: so derive is about multi-methods ...

18:15 worth learning anyway I guess

18:15 justin_smith: mmeix: yeah, it's about describing a kind of inheritance or taxonomy

18:16 mmeix: in terms of methods?

18:16 justin_smith: mmeix: methods use isa? and isa? respects the taxonomies / heirarchies built by derive

18:17 mmeix: ah, it's a more generalized concept

18:17 something to let sink in for some days, I guess

18:17 justin_smith: ,(derive ::cat ::animal)

18:17 clojurebot: nil

18:17 justin_smith: ,(derive ::cat ::heatsink)

18:17 clojurebot: nil

18:17 justin_smith: ,(isa? ::cat ::animal)

18:17 clojurebot: true

18:18 justin_smith: ,(isa? ::cat ::heatsink)

18:18 clojurebot: true

18:19 mmeix: and ::cat would be a method/function ... , or just anything?

18:19 sounds a bit like OO inheritance to my naive understanding

18:19 (I'm really a beginner still...)

18:19 justin_smith: mmeix: a multimethod could have a method for ::animal

18:20 mmeix: a bit

18:20 mmeix: ok

18:20 amalloy: mmeix: it kinda is, yes. but it's a small piece of the object model (namely, polymorphic dispatch) without the rest bundled into it

18:20 justin_smith: right

18:20 mmeix: ah! ::cat would be a dispatch value

18:20 amalloy: yes

18:20 justin_smith: mmeix: when provided with ::cat, it would match ::animal

18:21 mmeix: (light bulb)

18:21 ok, something to ponder on

18:21 justin_smith: in another context, it might match ::heat-sink

18:21 because a ::cat has many purposes, of course

18:21 mmeix: I guess I have to learn about the :: notation and it's meaning beforehand

18:22 justin_smith: mmeix: oh, that's pretty simple

18:22 amalloy: mmeix: you can pretend, for this conversation, that ::x is the same as :x

18:22 justin_smith: ,::foo

18:22 clojurebot: :sandbox/foo

18:22 EvanR: a keyword which has lower probability of colliding with someone elses

18:22 mmeix: sort of privileged keyword?

18:23 EvanR: namespaces

18:23 mmeix: ok, will read into this

18:24 thanks to all! (again & again)

18:25 (reading & REPLing)

18:28 justin_smith: dbasch: that object-relational-mismatch wikipedia article you linked has some hilarious barely-hidden edit war argument going on in it

18:32 EvanR: is there a function to convert an empty array to nil, only if empty

18:32 i love nils

18:32 justin_smith: seq

18:32 amalloy: &(doc not-empty)

18:32 lazybot: ⇒ "([coll]); If coll is empty, returns nil, else coll"

18:33 EvanR: ,(seq ())

18:33 clojurebot: nil

18:33 EvanR: ,(seq (1))

18:33 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

18:33 EvanR: ,(seq '(1))

18:33 clojurebot: (1)

18:33 dbasch: justin_smith: “I am mostly concerned about link to “How Vietnam Can Still Be Won” ... whereas the parent article is genuinely scholarly-like article on issue with OR/M technology, the latter is mostly (self-?)advertising heavily criticized in its comments as valueless.”

18:33 amalloy: could be seq or not-empty, depending on what you actually need

18:34 justin_smith: dbasch: wat

18:34 EvanR: ,(not-empty '(1))

18:34 clojurebot: (1)

18:34 EvanR: ,(not-empty ())

18:34 clojurebot: nil

18:34 dbasch: justin_smith: from http://en.wikipedia.org/wiki/Talk:Object-relational_impedance_mismatch

18:34 amalloy: EvanR: the difference is what they do when called on [1]

18:34 justin_smith: ,(not-empty [1 2])

18:34 clojurebot: [1 2]

18:34 Bronsa: ,[(not-empty [1]) (seq [1])]

18:34 clojurebot: [[1] (1)]

18:34 justin_smith: yeah, not-empty is a better default if you care about the type of the input

18:34 EvanR: ,(not-empty [1])

18:34 clojurebot: [1]

18:35 justin_smith: seq is just the one I use more often / remember more quickly

18:35 amalloy: i picked not-empty because EvanR said "array"

18:35 and "only if empty"

18:35 justin_smith: but there is no such thing as an empty array!

18:35 EvanR: well in my mind its an array, but after going through these other standard functions it probably isnt

18:35 justin_smith: but vector, yeah

18:35 :)

18:35 SagiCZ1: (doc derive)

18:35 clojurebot: "([tag parent] [h tag parent]); Establishes a parent/child relationship between parent and tag. Parent must be a namespace-qualified symbol or keyword and child can be either a namespace-qualified symbol or keyword or a class. h must be a hierarchy obtained from make-hierarchy, if not supplied defaults to, and modifies, the global hierarchy."

18:35 EvanR: but not-empty seems more obvious maybe

18:35 amalloy: EvanR: probably not

18:35 seq is a better default

18:35 EvanR: theres no empty arra?

18:35 amalloy: only use not-empty if you have some concrete reason to do so

18:35 justin_smith: EvanR: empty vectors sure

18:36 but arrays are fixed size

18:36 EvanR: what would you do with an empty collection, with no facility for adding new elements?

18:36 SagiCZ1: if i am frequently acessing last item of some sequence, should i use reverse-chronological list (this accessing its head) or should a vector suffice?

18:36 amalloy: either sounds fine, SagiCZ1

18:37 justin_smith: SagiCZ1: imho vectors are great for that, since you also get the intuitive behavior for first, nth, etc.

18:37 EvanR: justin_smith: pass it to something that doesnt have a special case for empty

18:37 map filter etc work on empty things just fine

18:37 SagiCZ1: alright thanks

18:37 justin_smith: EvanR: ? what would that thing do with it? you can't change dimensions of an array

18:38 EvanR: i dont remember the last time i wanted to change the dimensions of an array

18:38 justin_smith: EvanR: so what would you do with a 0 length array?

18:38 I change dimensions of collections all the time

18:38 ,(conj [] 1)

18:38 clojurebot: [1]

18:38 dbasch: justin_smith: here’s the original article they referred to https://web.archive.org/web/20120329012639/http://www.thefreelibrary.com/Object+Relational+Mapping%3B+How+Vietnam+Can+Still+Be+Won-a01073854068

18:38 EvanR: thats mutating?

18:39 justin_smith: EvanR: that's making a new collection, with the other as a basis, arrays can't do that

18:39 vectors can

18:40 amalloy: i think EvanR's usage is not defined nearly well enough to be giving opinions about what the right way to do things is

18:40 EvanR: this is a very interesting way to distinguish between various basically the same thing

18:40 an abstract vector of things which supports "concat" (not mutating, not implying any implementation or optimizations or performance) should really have an identity element

18:41 justin_smith: OK, just saying that in terms of impl, if there is a way to make a zero length array, I don't know of it

18:41 amalloy: justin_smith: ???

18:41 lazybot: amalloy: Yes, 100% for sure.

18:41 amalloy: &(object-array)

18:41 lazybot: clojure.lang.ArityException: Wrong number of args (0) passed to: core$object-array

18:41 EvanR: the notion in my mind sort of sounds like why does javascript have empty string

18:41 amalloy: &(object-array 0)

18:41 lazybot: ⇒ #<Object[] [Ljava.lang.Object;@22b0ded4>

18:41 justin_smith: amalloy: d'oh!

18:41 thanks

18:41 EvanR: but i did not know java cant make zero length arrays

18:42 that is interesting

18:42 justin_smith: EvanR: it can

18:42 amalloy: EvanR: it does, of course

18:42 EvanR: alright

18:42 amalloy: zero-element arrays are not very useful as things to write to, of course

18:42 EvanR: right... you can write to arrays ;)

18:43 its all coming back to me

18:43 i never even thought about writing to an empty array

18:44 dbasch: zero-length arrays are useful mostly for api compatibility

18:44 e.g. you get an array of search results from a java api, but there are no matches

18:45 justin_smith: dbasch: good point, I guess I would have expected Null for that, but that isn't handled so well in java

18:46 amalloy: of course java methods that work with arrays have not been very hip since like java 1.1. collections are a lot more workable

18:46 dbasch: null would be bad design, because really you’re getting empty results and you’d have to special-case a null check

18:46 amalloy: I’m talking specifically about Lucene

18:47 justin_smith: dbasch: my brain is too lispy, sometimes this is a problem

18:47 EvanR: in lisp, empty list is the same as null?

18:47 amalloy: EvanR: varies by language

18:48 EvanR: interesting choice if it is

18:48 justin_smith: EvanR: historically (common lisp) it is, and it is reflected in clojure in places

18:48 ,(cons 1 nil)

18:48 clojurebot: (1)

18:48 amalloy: EvanR: your background is haskell, right? in common lisp, for example, a list is defined basically like: data List a = Cons a d | Nil

18:49 so the only way you could have an empty list is nil

18:49 (and yes, i got the data declaration wrong, but i think you get the idea)

18:49 dbasch: although the Lucene api has changed, and it looks like the examples are out of date

18:49 e.g. “ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;”

18:50 bbloom: <3 this clojure 1.7 :warn-on-boxed setting. got some nice wins on some otherwise reasonably well tuned code

18:50 EvanR: Nil being a special symbol for Nil, nevermind, i vaguely remember reading about flamewars over this

18:51 dbasch: but Lucene is one of the highest quality java libraries I know of

18:53 andyf: bbloom: give puredanger mad incs

18:53 bbloom: (mad-inc puredanger)

18:53 (inc puredanger) ; plus a regular one

18:53 lazybot: ⇒ 20

18:57 justin_smith: dbasch: other gems of that talk page include the argument that relational databases will inevitably be replaced by systems that tie data to code

18:58 dbasch: that would be web scale

18:58 dopamean_: does anyone know of a good resource for adding things to the session map that ring provides?

18:58 justin_smith: dopamean_: assoc / assoc-in

18:58 dopamean_: right

18:58 justin_smith: dopamean_: it's just a map

18:58 dopamean_: however i thought i could only add i when a response was being sent or something

18:59 justin_smith: ? you can add it whenever you like, just make sure to supply your modified version to the next stage

18:59 dopamean_: right thats the part that im confused about

19:00 the function that responds to the request calls another function that renders some stuff with enlive

19:00 justin_smith: you add new data to the request map under the :session key, and then you pass that along

19:00 amalloy: dopamean_: you want a middleware like: (defn with-magic [handler] (fn [req] (handler (assoc-in req [:session :magic] :activated))))

19:00 (or anyway you might want such a thing)

19:01 justin_smith: dopamean_: {:body (enlive/whatever input) :session (update-session (:session request)) :status 200}

19:01 dopamean_: damn

19:02 that seems kind of obvious

19:02 justin_smith: dopamean_: well, it's using standard clojure data structures, but some of the consequences can be interesting and subtle if you are used to doing things another way

19:03 amalloy: (inc justin_smith)

19:03 lazybot: ⇒ 113

19:03 bbloom: https://github.com/clojure/clojure/blob/b01adb859c66322c5cff1ca9dc1ad98585f2cdc1/src/jvm/clojure/lang/Compiler.java#L7552-L7553

19:03 dopamean_: thanks a ton

19:03 this helps a lot.

19:03 amalloy: hey, that is my second inc of you today. i must be in a generous mood

19:03 bbloom: ^^ seems like that'll break w/ more than HASHTABLE_THRESHOLD fields (16)

19:05 hiredman: bbloom: the bare array map constructor doesn't do any checks

19:05 bbloom: hiredman: ah yes, it doesn't call assoc

19:05 cool thanks

19:06 always seemed a tad sketch to me that array map knows about hash map

19:06 but such is the price of avoiding an extra level of indirection, i suspect

19:06 andyf: bbloom: Not sure why it would break, but Clojure definitely can create array maps larger than the threshold

19:07 bbloom: andyf: https://github.com/clojure/clojure/blob/b01adb859c66322c5cff1ca9dc1ad98585f2cdc1/src/jvm/clojure/lang/PersistentArrayMap.java#L200-L201

19:07 EvanR: what is "array map"

19:08 justin_smith: EvanR: one of the concrete implementations underlying clojure's hash-map

19:08 andyf: Not by that line of code, though :-)

19:08 justin_smith: ,(class {:a 0})

19:08 clojurebot: clojure.lang.PersistentArrayMap

19:08 justin_smith: ,(class (apply hash-map (range 100)))

19:08 clojurebot: clojure.lang.PersistentHashMap

19:08 EvanR: and "hash-map" is referring to just the map { }

19:08 dbasch: EvanR: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentArrayMap.java

19:09 bbloom: andyf: yeah it's just jamming an array in there directly

19:09 EvanR: whats persistent about it, beyond the usual?

19:09 justin_smith: EvanR: hash-map always creates a PersistentHashMap iirc, but literals can create ArrayMaps

19:09 andyf: I didn't track down how it happens, but saw some when adding some debug prints when fixing something else

19:10 justin_smith: EvanR: nothing, the naming differentiates from java stuff that is mutable

19:10 EvanR: well, nothing beyond the usual "persistent collection" meaning

19:10 amalloy: it's funny because array-map is one of the things in clojure that isn't really very persistent

19:10 danielszmulewicz: so many sql abstraction libraries... what's your favorite?

19:11 andyf: justin_smith: EvanR: Wikipedia has article with reasonable dean of persistent data struct. It means something.

19:11 justin_smith: andyf: yes, sorry, I meant persistent in this case just means that, not that persistent was not a meaningful thing

19:11 amalloy: andyf: heh. "dean of persistent data structures" is a position i'd take

19:12 justin_smith: andyf: maybe I misunderstood his "beyond the usual" qualifier

19:12 andyf: Durn auto correct: dean -> defn

19:12 EvanR: so it means immutable

19:13 amalloy: EvanR: persistent actually means something stronger than that, but it's often used loosely to include anything immutable

19:13 EvanR: this arraymap implementation is nice and simple, i can see how a small map can get some performance out of this

19:13 amalloy: it's kinda questionable to call PersistentArrayMap "persistent", but not totally wrong either

19:13 EvanR: i dont know what it means but im guessing it doesnt mean its still there after your jvm shutsdown

19:14 and your computer reboots

19:14 justin_smith: EvanR: immutible, and also capable of sharing data as needed (though I am not sure if that is neccessary for the definition)

19:14 EvanR: yep that would be a free benefit of immutable

19:14 dbasch: EvanR: for that matter, databases are not too persistent in the face of potent magnets

19:14 amalloy: EvanR: have you read the wikipedia article andyf suggested?

19:15 justin_smith: EvanR: not quite free - you need the right kind of tree structure to make it really work

19:15 dbasch: but persistent has a very specific meaning when it comes to data structures

19:15 that has little to do with durability

19:15 amalloy: you guys are talking at cross purposes, justin_smith/EvanR

19:15 justin_smith: OK

19:15 EvanR: which article

19:15 amalloy: http://en.wikipedia.org/wiki/Persistent_data_structure

19:16 EvanR: interesting

19:16 the context is an api which "modifies" an object

19:16 amalloy: justin_smith was trying to talk about efficient structural sharing, where to EvanR it just sounded like pointer sharing

19:16 EvanR: im still not fully understanding what that means in clojure

19:17 justin_smith: amalloy: yeah, because that, to me, is what differentiates persistent data structures for other immutible data structures

19:17 dbasch: EvanR: there’s a good talk by bbloom about persistent trees

19:17 let me find it

19:18 EvanR: https://www.youtube.com/watch?v=j649Tr25RyA

19:18 slides http://www.slideshare.net/g33ktalk/software-dendrology-by-brandon-bloom

19:18 justin_smith: EvanR: maybe not so much about "modifying" an object, as making a variation without needing to copy the entire object in the process, while still not effectively altering the original

19:18 amalloy: that was a good talk. does he talk about the definition of persistence? i don't remember that part. i guess even so it's a good introduction to the data structures clojure uses to get well-performing persistent values

19:18 bbloom: dbasch: i'm glad you enjoyed my talk! but i think zach allaun gives the best intro to how the structures work: http://www.infoq.com/presentations/julia-vectors-maps-sets

19:19 i didn't really set out to cover that

19:19 justin_smith: bbloom: that was like a reverse kanye

19:19 bbloom: justin_smith: i'm not going to let you finish, since somebody else did the best thing OF ALL TIME

19:20 TEttinger: that thing being https://www.youtube.com/watch?v=bP2FpVKlp1s

19:21 my brother made that, I just added two frames of video and uploaded it

19:21 EvanR: ok, yeah, it makes sense to have a name for this when immutable is not the default

19:21 bbloom: it's more than immutable

19:21 EvanR: even though the apis in clojure ive seen so far dont have much to do with updating in place

19:22 bbloom: it's about structural sharing

19:22 you can achieve immutable w/ full clone on all writes

19:22 justin_smith: EvanR: it's not about mutation

19:22 EvanR: yeah, the java code to support this stuff has the option to copy or not, or update in place or not

19:22 justin_smith: EvanR: it's an implementation detail for immutability

19:24 EvanR: is there anything that does copy on write?

19:24 hmm, i guess thats the default

19:24 amalloy: EvanR: well, array-map

19:24 which is why i said it's a bit awkward to call it PersistentArrayMap

19:24 EvanR: i meant to ask, is there anything that mutates if it knows nobody will be affected

19:24 in place

19:24 amalloy: EvanR: transients

19:25 EvanR: ok

19:25 amalloy: for one example, see the definition of mapv

19:25 justin_smith: for values of "it knows nobody will be affected" that include "it's your own fault if you thought you wouldn't be affected"

19:25 amalloy: which modifies a transient vector in place until it's ready to return it, then converts it to a persistent

19:26 EvanR: map doesnt just do that?

19:26 justin_smith: meaning not that transients are sneaky, but there are ways to misuse them if you are not careful

19:26 EvanR: oh map produces a seq

19:26 amalloy: EvanR: it can't, because of laziness

19:26 EvanR: nevermind

19:27 in ruby / javascript you get used to only have one "array"

19:27 justin_smith: yeah we have list / lazy-seq / queue / vector / array

19:27 all very distinct

19:27 EvanR: and map

19:27 didnt know about queue

19:27 justin_smith: yeah, that's not even sequential

19:28 EvanR: i didnt think it was, but its supporting all these sequential interfaces

19:28 amalloy: EvanR: speaking of ruby, mutability, and being used to having just one array: https://docs.google.com/presentation/d/1mGihUBBIKMQn5Uz-5DvQ1Vu24qSuk3o4yUoPoBZW3tI/edit#slide=id.g432ac727f_023

19:28 justin_smith: ,(into [] (-> clojure.lang.PersistentQueue/EMPTY (conj :a) (conj :b) pop))

19:28 clojurebot: [:b]

19:29 justin_smith: ^ queue

19:29 SagiCZ1: can if-let check if all the bindings are not nil? i know it works for one..

19:29 amalloy: justin_smith: queue isn't sequential?

19:29 justin_smith: amalloy: I listed it with the sequential ones

19:29 I was saying map was not

19:29 amalloy: oh, i see

19:29 EvanR: never use basically anything in ruby's array library

19:30 amalloy: EvanR: clojure's seq interface is a bit like Foldable. it's not just for things which are sequential, but for things which you can get a sequential view of

19:30 EvanR: no ! doesnt mean no shenanigans

19:30 amalloy: man i forget if you are the guy with a haskell background or not

19:30 if not this was a silly comparison

19:30 EvanR: "haskell background" lol

19:30 SagiCZ1: ,(if-let [a 5 b 6] (println a b))

19:30 clojurebot: #<CompilerException java.lang.IllegalArgumentException: clojure.core/if-let requires exactly 2 forms in binding vector in sandbox:, compiling:(NO_SOURCE_FILE:0:0)>

19:30 EvanR: does that exist yet

19:30 amalloy: it's like ruby's enumerable, kinda

19:30 SagiCZ1: okay

19:30 amalloy: EvanR: huh? haskell's been around for over a decade

19:31 probably over two, but i'm not sure

19:31 dbasch: ruby bang is pretty random as an indicator of mutability

19:31 justin_smith: amalloy: ~2, for sure, I remember hearing about it in the late '90s and it wasn't brand new

19:32 dbasch: it’s more like “I bet you didn’t expect this to mutate stuff, did you?”

19:32 there are plenty of bang-less methods that mutate things

19:32 EvanR: the similarly named ruby functions keep_if is the opposite of delete_if but doesnt mutate

19:32 for some reason

19:33 technomancy: I read ruby bang as a "there's another version of this that's non-destructive; that's probably the one you want" marker

19:33 amalloy: justin_smith: 1990 for 1.0, apparently

19:33 dbasch: technomancy: to me it’s more like “read the docs for this because it may do unexpected shit”

19:33 justin_smith: cool, gonna be on a third decade before we know it

19:34 dbasch: technomancy: e.g. compact and compact! on arrays

19:34 EvanR: read the docs, then give up and read the source code, if you can

19:34 because they write it using instance_eval

19:36 hiredman: /win 5

19:37 justin_smith: dbasch: let's change the names to pmap‽ and flatten‽

19:37 EvanR: amalloy: seq's interface seems to be, "get the next thing" and "unget a thing" https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java

19:38 rather than foldable

19:38 dbasch: with the bonus that the interrobang makes them harder to type and you have to wait for autocompletion

19:38 amalloy: well, there's get the current thing and get the rest of the things, which is isomorphic to foldable

19:38 noonian: its get the next thing, and get everything else

19:38 amalloy: cons is not exactly related to that

19:39 EvanR: foldable is about reducing all the things with an accumulator

19:39 the cons thing is curious

19:40 amalloy: yes, and? that's the same as head/tail, in that you can implement one in terms of the other

19:41 EvanR: i dont think you can implement a head/tail with foldable

19:42 might be wrong

19:49 amalloy: EvanR: maybe not. it's easy to get head, but getting a tail that preserves the type is harder than i thought. they serve similar purposes, but i guess may not be isomorphic

19:51 hyPiRion: a tail that preserves type with foldr assumes the underlying structure has a tail in the first place. That's not necessary with foldable

19:52 amalloy: hyPiRion: i was imagining you could return a new foldable thing which delegates to the first one and ignores the first value of it, or fold over it with a function that knows how to ignore exactly one value

19:52 the first is impossible; the second actually is probably doable now that i think about it

19:52 hyPiRion: amalloy: oh right, that you can do

19:52 amalloy: but both of those are really hard if you want to return something of exactly the same type as your input

19:52 when all you know is that the input is foldable

19:52 hyPiRion: That's like, drop for foldables

19:53 amalloy: hyPiRion: right, which is easy in clojure, but not at all obvious for a more strictly typed thing. like, writing `rest :: Foldable t => t a -> t a` is harder than i thought

19:55 SagiCZ1: i decided to work with vectors but most clojure functions return seq.. should i always make sure to convert them into a vector?

19:55 hyPiRion: amalloy: it's possible to return a foldable though (t a -> Foldable a). Don't think you can be isomorphic

19:55 amalloy: hyPiRion: for sure that's possible, yes

19:55 because you can just write `rest = tail . toList`

19:56 hyPiRion: right

19:57 amalloy: SagiCZ1: usually you should work with vectors only when you need some property of theirs that seq doesn't have; at other times, use a seq

19:58 SagiCZ1: amall

19:58 amalloy: i see, thanks

20:00 take-last sometimes returns something called Clojure.lang.Cons, why?

20:00 justin_smith: ,(type (cons 1 nil))

20:00 clojurebot: clojure.lang.PersistentList

20:01 SagiCZ1: i did (take-last n vector-coll) and then (vector-coll index) and that throws clojure.lang.Cons cant be cast to clojure.lang.IFn

20:01 hyPiRion: justin_smith: you have it the other way around: Cons returns list, list* returns cons

20:01 ,(type (list* 1 2 3 ()))

20:01 clojurebot: clojure.lang.Cons

20:02 justin_smith: hyPiRion: d'oh, of course, how could I not remember something so simple!

20:02 SagiCZ1: i dont know if i should care about it or stick to vectors or what :(

20:02 justin_smith: SagiCZ1: the return value of take-last is not callable, even if its input was

20:03 technomancy: just don't pay attention to the class

20:03 pay attention to the interfaces

20:03 amalloy: SagiCZ1: take-last is not a thing that vectors can do efficiently. maybe it's time to step back and think about what you need to be able to do to your collections

20:05 SagiCZ1: i really just need to just add a new value to it sometimes, read last n values from it.. and sometimes i need to trim some old values to keep it from growing too big

20:05 justin_smith: SagiCZ1: trim from which end?

20:05 amalloy: that sounds mostly like a queue

20:05 justin_smith: amalloy: I was wondering, yeah

20:06 ,(into [] (-> clojure.lang.PersistentQueue/EMPTY (conj :a) (conj :b) pop))

20:06 clojurebot: [:b]

20:06 justin_smith: reusing an example I shared before

20:06 SagiCZ1: from the beginning

20:06 queue...

20:06 justin_smith: the into is just being used for display purposes - it doesn't print nicely

20:06 technomancy: clojurebot: queuefish?

20:06 clojurebot: I don't understand.

20:06 technomancy: clojurebot: the hell you don't

20:06 clojurebot: Excuse me?

20:06 SagiCZ1: wait it totally is queue

20:07 technomancy: bots these days

20:07 lazy slackers

20:07 SagiCZ1: :)

20:07 justin_smith: ~quefish

20:07 clojurebot: I don't understand.

20:07 hyPiRion: lazybot: you heard him

20:08 SagiCZ1: the weird thing about queue is that you usually add new item to the head right? .. but that should be considered the "last" or "newest" item.. which usually has the highest index which is associated with tail in my head

20:09 noonian: thats an implementation detail of a queue imo

20:09 justin_smith: SagiCZ1: you can try out variations of what I put in above to see how it works - conj adds to the end, pop takes off the left (peek gets the item you would have popped)

20:10 SagiCZ1: and is that the only way to create this queue in clojure? there is nothing similar to 'vec', 'vector' or something?

20:10 amalloy: SagiCZ1: curiously enough, no, there is no better way built in

20:11 justin_smith: SagiCZ1: because you always start with an empty one, right?

20:12 SagiCZ1: justin_smith: i guess so

20:12 justin_smith: though many of us would like a prettier syntax for the empty one built in

20:12 that's what technomancy was talking about with queuefish

20:12 SagiCZ1: ,(clojure.lang.PersistentQueue)

20:12 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn>

20:12 technomancy: justin_smith: no, this is clearly the deranged utterings of a madman

20:12 SagiCZ1: ,(clojure.lang.PersistentQueue/EMPTY)

20:12 clojurebot: #<PersistentQueue clojure.lang.PersistentQueue@1>

20:12 technomancy: don't try to read sense into it

20:13 justin_smith: SagiCZ1: it's an empty coll, not a function that generates an empty coll

20:13 oh wait, it also returns itself when you call it? funny

20:13 never thought to try that

20:13 oh wait

20:13 ,(Math/PI)

20:13 clojurebot: 3.141592653589793

20:13 justin_smith: it's that thingy

20:13 interop can be weird

20:13 technomancy: bot quirk?

20:13 SagiCZ1: wait what, thats odd

20:14 works in my repl too

20:14 justin_smith: technomancy: nope, it's a legacy thing I guess?

20:14 technomancy: huh

20:14 justin_smith: it's always worked

20:14 SagiCZ1: it was actually a newb mistake, i didnt want to use the parens

20:14 justin_smith: it's weird

20:14 amalloy: technomancy, justin_smith: (Foo/bar) worked before Foo/bar was introduced

20:14 justin_smith: SagiCZ1: right, then I tried to figure out why it worked :)

20:14 amalloy: right, legacy

20:14 technomancy: no kidding

20:14 deep magic from the dawn of time

20:15 SagiCZ1: i guess i could just make some tiny wrappers for the queue to make it more readible in my code.. what's stopping me right

20:15 amalloy: SagiCZ1: folks usually do

20:15 justin_smith: ,queue-fish

20:15 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: queue-fish in this context, compiling:(NO_SOURCE_PATH:0:0)>

20:15 justin_smith: ~queue-fish

20:15 clojurebot: Pardon?

20:15 SagiCZ1: ~tired?

20:15 clojurebot: Gabh mo leithscéal?

20:16 justin_smith: anyway queue-fish is https://groups.google.com/forum/#!topic/clojure-dev/GQqus5Wycno

20:16 SagiCZ1: thanks

20:19 justin_smith: I think a readable print is a bigger deal with queues - unlike anything else that is sequential and persistent, they don't have a nice printed representation that shows the contents.

20:20 SagiCZ1: justin_smith: how come? isnt queue also a sequence of some sort?

20:21 justin_smith: it is, but it prints ugly

20:21 ,(conj clojure.lang.PersistentQueue/EMPTY 1)

20:21 clojurebot: #<PersistentQueue clojure.lang.PersistentQueue@20>

20:21 justin_smith: no hint of the contents

20:21 ,(seq (conj clojure.lang.PersistentQueue/EMPTY 1))

20:21 clojurebot: (1)

20:22 SagiCZ1: oh i see

20:26 justin_smith: but anyway, if you want to add on one end, and drop from the other, you do definitely want a queue, probably that one

20:26 even if it doesn't print nicely

20:27 technomancy: clojurebot: queuefish is print-method magic to get (conj (conj clojure.lang.PersistentQueue/EMPTY 12) 9) ; -> <-(12 9)-<

20:27 clojurebot: 'Sea, mhuise.

20:27 technomancy: clojurebot: queue-fish is queuefish

20:27 clojurebot: c'est bon!

20:28 hiredman: ~queuefish

20:28 clojurebot: queuefish is print-method magic to get (conj (conj clojure.lang.PersistentQueue/EMPTY 12) 9) ; -> <-(12 9)-<

20:28 hiredman: ~queuefish

20:28 clojurebot: queuefish is print-method magic to get (conj (conj clojure.lang.PersistentQueue/EMPTY 12) 9) ; -> <-(12 9)-<

20:28 hiredman: blegh

20:28 some day

20:29 amalloy: hiredman: hm?

20:29 justin_smith: ,(seq (conj clojure.lang.PersistentQueue/EMPTY 12 9)) ; bike shedding a factoid

20:29 clojurebot: (12 9)

20:30 technomancy: http://p.hagelb.org/mrfp.gif

20:30 hiredman: amalloy: clojurebot assumes 'is' means equivalence so it is free to permute and infer

20:30 amalloy: right...which i thought technomancy was using on purpose to create two copies of that factoid

20:31 hiredman: but you also get queuefish is queue-fish out of that too

20:31 technomancy: I was hoping for a redirect but ... who can fathom the mysteries of clojurebot

20:31 dang

20:31 justin_smith: ~queue-fish

20:31 clojurebot: queue-fish is queuefish

20:31 hiredman: hence my "some day"

20:38 Bronsa: bbloom: the compiler silently ignores type hints in so many places it's not even funny

20:39 amalloy: *sigh* i just wrote a lexicographic sort for vectors of 1-2 elements out by hand. why didn't i just use some standard sort thingy?

20:40 justin_smith: amalloy: I am sure your version is unrolled and super-duper optimized

20:40 tuft: amalloy: at least you haven't typed it in yet

20:42 gfredericks: ,(sort [[1 3] [5 4] [3 3]])

20:42 clojurebot: ([1 3] [3 3] [5 4])

20:42 amalloy: gfredericks: that's fine for 2 elements

20:42 try 1-2

20:42 andyf: Bronsa: t.a.j used to throw on (extend-type (class (log-window-proxy nil)) ...) but latest does not. That sound intentional to you? I think it was.

20:42 gfredericks: ,(sort [[1 3] [5 4] [3]])

20:42 clojurebot: ([3] [1 3] [5 4])

20:42 gfredericks: ,(sort-by (juxt first second) [[1 3] [5 4] [3]])

20:42 clojurebot: ([1 3] [3] [5 4])

20:43 amalloy: hm, that's a good point

20:43 ,(sort [nil 4])

20:43 clojurebot: (nil 4)

20:43 gfredericks: woah did I just show amalloy how to use juxt to solve a problem

20:43 I think I just beat #clojure

20:43 justin_smith: (inc gfredericks)

20:43 lazybot: ⇒ 101

20:43 andyf: Andyf's mind also blown

20:44 gfredericks: Wait, you can still hear us? You were supposed to go to the next level.

20:44 Bronsa: andyf: t.a.j should still throw on that, it's probably getting caught by the wrong-tag handler though

20:44 andyf: by eastwood's wrong-tag-handler, that is

20:45 (inc gfredericks)

20:45 lazybot: ⇒ 102

20:45 andyf: Bronsa: Got it. I still need to tweak the wrong tag linter better

20:45 gfredericks: andyf: hold on let me take out the cartridge and blow in it

20:46 andyf: gfredericks: No like red/blue pill next level

20:48 Bronsa: andyf: btw have you seen missing line/col info by any chance?

20:49 andyf: Bronsa: Some but not a lot. I try to improve thosr when I can but I may run out of steam on some of them for nect

20:49 Next release , except to create an issue

20:50 Steam, meaning enthusiasm for debigging every last thing

20:50 I am on fire with typos today

20:51 amalloy: debigging. apple autocorrect strikes again?

20:51 i can't imagine that's even in their dictionary though

20:51 andyf: To manager: yeah I just need to debig my code a bit more and we'll be ready to ship.

20:51 gfredericks: s/ship/shup/

20:52 justin_smith: "this is messed up because of a method too large error, time for some debigging"

20:52 andyf: That was just iPhone fat fingers

20:52 gfredericks: andyf: you're halfway to the correct kiwi pronunciation

20:52 Bronsa: andyf: yeah no worries, I was just asking bcos I saw some missing source info earlier and that shouldn't happen

20:52 I think I have a fix though.

20:53 andyf: Nice

20:58 bbloom: Bronsa: yeah, true

20:59 Bronsa: i guess the issue i hit was that the type hints are inconsistent between symbols and class objects

20:59 amalloy: well, in fairness to me it looks like i at least got the case analysis right on my hand-unrolled compare-via-juxt

20:59 dbasch: debigging code embiggens my salary, it’s a perfectly cromulent use of my time

21:00 Bronsa: bbloom: andyf can attest how many open source libs (even big ones) have wrong/useless tags

21:00 bbloom: yeah, i'm ok with useless tags

21:00 i rather over tag than under if they aren't doing harm

21:00 i'm just not ok with silent slowness that i can't find easily

21:00 Bronsa: bbloom: by useless I mean possibly useful tags in position where the compiler will ignore them

21:00 bbloom: and i really do believe slow and working is a better default than ONLY FAST but compiler type checking headache trying to get it there

21:01 andyf: The rules for which ones are useful are not something I keep on my head even yet

21:01 bbloom: yeah

21:01 i have this project that has a bunch of bits that need to be super fast, but those bits are also really tricky to get right and have a ton of duplication that macros can solve for me

21:01 getting fast code generated is proving reasonably tricky

21:02 and it's probably likely i'll convert a bunch of key bits to java to get the maximum perf in some corner cases

21:03 takes some mental energy to resist the urge to optimize/rewrite like crazy, but it's worth the mental energy savings in being able to work in clojure to start with

21:03 dbasch: but sometimes it’s necessary to leave the clojure bike and drive the java minivan

21:04 bbloom: but fixing some unboxed math right now involved some definlines and whatnot... got me a 40% win on one of the most important fast paths

21:04 Bronsa: nice

21:04 bbloom: i haven't dug too deep in to the byte code, but i suspect that i can do even better

21:05 Bronsa: ... according to core definline/:inline should be avoided

21:05 hiredman: core is so weird

21:07 bbloom: given the commitment to back compat, seems unlikely for definline to go away

21:07 hiredman: indeed

21:08 bbloom: and although it's ugly as hell to template-ize syntax-quote whole functions, it considerably speeds up my inner loop

21:08 i've got 3 definline usages, for a total of about 15 lines of code and 7 call sites in a ~5k program that does some pretty funky low level stuff to begin with

21:09 i'm comfortable w/ the tradeoffs, although i wish for a language that scaled to the lowest level more gracefully

21:09 that said, clojure is surprisingly graceful at it compared to pretty much any other dynamic language i've ever used (although i've never done any perf work in CL)

21:11 turbofail: you can do all sorts of grungy low-level things in SBCL, including going down to assembly

21:11 oh hey look that /msg spammer is back

21:11 zoom__: find a new link at least

21:11 TEttinger: solo hoy!

21:11 only now! can you be spammed

21:18 marcuscreo: howd

21:18 howdy

21:21 Bronsa: andyf: source-info should be fixed for good now

21:23 andyf: I'll give it a whirl and see what happens.

21:30 mdeboard: hiredman: Is techsonian.net related to techsonian.com?

21:46 gfredericks: does clojurescript include a format function these days? if not where would I get one?

21:48 justin_smith: gfredericks: clojurescript.net lets me use format

21:49 gfredericks: grepping the cljs repo suggests it's not provided

21:49 I think it was in the past though

21:49 justin_smith: http://clojurescript.net/ works in this repl

21:50 gfredericks: http://dev.clojure.org/jira/browse/CLJS-324

21:50 clojurescript.net is a whole nother impl amirite?

21:51 justin_smith: oh yeah, it is the self hosting version from kanaka

21:51 never mind that then

21:51 gfredericks: I guess I'll try goog.string.format

21:52 actually I think that's probably what this code was using implicitly anyhow

22:11 csd_: Anyone know how to set autoreconnect=true in Korma?

22:21 arrdem: dbasch: ping

22:21 dbasch: pong

22:26 danneu: i didn't know assoc could take more than 1 k/v pair. slightly nicer than using merge when the kvs you're merging weren't already in a map.

22:27 justin_smith: how would merge be better if they were?

22:28 ,(assoc {:a 0} :a 42 :b 1 :c 2)

22:28 clojurebot: {:c 2, :b 1, :a 42}

22:28 danneu: when you're actually merging map data

22:28 justin_smith: mow, merge-with on the other hand

22:28 oh, I misread

22:29 *a map

22:30 gfredericks: ,(merge-with #(list %1 %2 %1 %2) {:a 0 :b 5} {:b 7 :c 8})

22:30 clojurebot: {:c 8, :b (5 7 5 7), :a 0}

22:31 gfredericks: ,(merge-with #(list %1 %2 %1 %2) {:a 0 :b 5} {:b 7 :c 8} {:b 2})

22:31 clojurebot: {:c 8, :b ((5 7 5 7) 2 (5 7 5 7) 2), :a 0}

22:31 gfredericks: wee

22:35 justin_smith: ,(defn combine [a & rest] (letfn [(vectorize [v] (into {} (map (fn [[k v]] [k [v]]) v)))] (reduce (fn [a b] (merge-with into a (vectorize b))) (vectorize a) rest)))

22:35 clojurebot: #'sandbox/combine

22:35 justin_smith: ,(combine {:a 0 :b 1} {:a 42 :b 420} {:a -1 :b 666})

22:35 clojurebot: {:b [1 420 666], :a [0 42 -1]}

22:36 justin_smith: ,(combine {:a 0 :b 1} {:a 42 :b 420} {:a -1 :b 666 :c 3})

22:36 clojurebot: {:c [3], :b [1 420 666], :a [0 42 -1]}

23:30 ddellacosta: folks: https://groups.google.com/forum/#!topic/clojure/AYe1opodrGA

23:31 (hope it's okay I push that here)

23:31 (let me know if not and I'll abstain)

23:39 amalloy: ddellacosta: seems totally fine to link to once. more than once would probably be uncouth

23:39 ddellacosta: amalloy: gotcha, thanks--I'll leave it at that. It's on the list so presumably folks will find it there anyways.

23:52 TimMc: ddellacosta: My only feedback is that I don't know why I'd bother clicking the link, other than that I'm a folk. :-P

23:53 ddellacosta: TimMc: ah, good point. Job posting for Clojure dev/sysadmin devops position. :-)

23:53 TimMc: Best of luck!

23:53 ddellacosta: TimMc: thanks!

23:56 TimMc: Have you tried http://functionaljobs.com/ ?

23:57 ddellacosta: TimMc: not yet, we are still going through our options

23:57 TimMc: If I were looking for a Clojure position, that's probably the first place I'd check, but maybe 'cause I just happen to know about it.

23:59 ddellacosta: TimMc: hmm, good to know!

Logging service provided by n01se.net