#clojure log - Sep 02 2013

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

0:00 johnmn3: yea, cljsbuild is hanging while compiling a fresh project from cljs-kickoff... could lein or cljsbuild be corrupted?

0:03 guess I could try moving to cljsbuild "0.3.3-SNAPSHOT"

0:03 cgag: try just deleted cljsbuild

0:03 from your .m2 folder

0:06 johnmn3: oh, whatayaknow... successfully compiled in 91 seconds... that was after it pulled down 0.3.3-SNAPSHOT

0:06 will try back on the main project now

0:07 cgag: awesome

0:07 how big is your project if you don't mind me asking? 91 seconds seems like a long time

0:07 oh, well, and / or what are you running this on?

0:09 johnmn3: one sec... pulling the deps might have slowed it down.. running again

0:11 futile: Oh my.

0:11 Maybe I'm wrong, but ns-tracker seems to take 100% CPU while watching for changes.

0:13 johnmn3: hmm... 47 seconds... running on an Samsung ARM A15 Chromebook with cruton in chroot

0:16 cgag: and the project isn't that big 3 cljs files, largest of which is ~1k lines

0:42 futile: I love the guard-rails analogy for testing.

0:42 Tests make great guard-rails, but you don't drive by constantly banging into the guard rails back and forth.

0:50 noidi: futile, yeah, it's a good one

0:59 futile: I was brought up in a TDD environment, and I've seen a *lot* of damage done by having a naive purist approach to it.

1:01 bbloom: futile: i don't understand "X driven Y" or "A oriented B"

1:01 futile: why would i ever choose ONE approach to anything?

1:02 futile: bbloom: it's helpful as convenient language to quickly express a concept

1:02 although I'm not sure it's *actually* helpful, since it's usually so sweepingly broad as to be often misunderstood

1:02 Like C++ is Object Oriented in a totally different way than Go and Smalltalk are.

1:03 bbloom: futile: so i used to think the worse thing you could do to any idea was assign a name to it

1:03 once you make it a methodology, it becomes a religion

1:03 futile: And sure, I test-drive my app, but sometimes those tests are manual tests that I do once in the repl, and stick the results into a function and never touch it again.

1:03 bbloom: what i learned from the clojure community & rich in particular was that defining words you thought you knew is a way to accomplish all the good things from naming stuff, but with far less of the bad things

1:04 defining simple & easy turned out to be 100X more useful than "decomplection oriented programming"

1:04 :-P

1:04 futile: ha

1:04 bbloom: that only works when everyone in the conversation agree on what simple and easy mean. And when they don't, that's not immediately obvious, sometimes for a while.

1:06 bbloom: futile: is it immediately obvious what "test driven development" means?

1:06 it's certainly less agreeable than simple & easy...

1:06 futile: heh

1:06 thats what im saying.

1:07 ive come to a conclusion that doesnt fully make sense yet

1:10 something like, if you're good at programming, the designs of your program are much more important than the details that change by the language.

1:10 brehaut: bbloom: TDD means Ron Jeffries fails to write a Sudoku solver

1:10 futile: except thats not fully true, because i would rarely use Java or half its features to solve any problem.

1:10 i may be too tired to make sense.

1:11 bbloom: brehaut: lol oh man that was hilarious

1:13 noidi: I prefer Nat Pryce and Steve Freeman's "development guided by tests"

1:14 futile: time to write a recursive descent parser for Clojure code until i pass out

1:14 bbloom: futile: it's LL(1), pretty easy :-)

1:14 futile: oh i wonder, is Clojure's own parser usable exteranlly?

1:14 bbloom: futile: see tools.reader

1:15 noidi: I think tests can and do have a place in the design process, but they don't drive the design, they inform the designer

1:15 futile: bbloom: erm i cant say i know the difference between parsers, but ill take your word for it

1:15 noidi: nice way of putting it!

1:15 I can't actually go public with these opinions since I work for a guy who is big in the TDD/agile world.

1:15 bbloom: futile: an LL(1) grammar/parser means you can parse it from top to bottom, left to right, with only 1 character/token of look ahead

1:15 callen: "big"

1:16 futile: callen: you've probably heard of him

1:16 bbloom: ah! sweet, just what i was planning :)

1:16 bbloom: futile: unless you're looking for a learning experience, just use/contribute-to https://github.com/clojure/tools.reader

1:17 futile: bbloom: does that 1-char look-ahead take into account the various forms starting with # (not counting tagged literals)?

1:18 bbloom: futile: yeah, when you encounter #, which clojure calls the "dispatch reader", it only needs to look at the next character to decide how to continue parsing. if it's a letter, it's a tagged literal or a record. if it's _ it discards, if it's ( it's a function, etc

1:18 callen: futile: maybe.

1:18 futile: callen: probably

1:18 callen: futile: I know a lot of TDD people, I just can't think of any where you live.

1:18 futile: bbloom: hmm interesting

1:19 bbloom: thanks for this link, i think i will use it

1:19 bbloom: clojure was designed to be LL(1) on purpose

1:19 callen: futile: understanding chomsky hierarchies is critical if you want to do anything with parsing.

1:19 futile: what bbloom just said about being designed as an LL(1) language on purpose is extremely useful.

1:19 futile: bbloom: oh?

1:19 callen: oh?

1:19 callen: contrast with trying to do some kind of machine processing of, say, C++

1:19 bbloom: most practical languages design for a particular subset of CFG to ensure fast/simple/easy parsers

1:20 callen: bbloom: I should write a clojure reader with instaparse :P

1:20 futile: callen: then write up a performance comparison with tools.reader

1:21 callen: futile: http://www.cs.dartmouth.edu/~sergey/langsec/occupy/

1:21 bbloom: callen: if you do, i'd be curious how it performs. i suspect it would be mega slow at first, but could be reasonably tweaked to be just a small bit slower than a real LL(1) parser

1:21 callen: bbloom: that's precisely what I was wondering. It'd be useful since Selmer is performance focused but we'd like a cleaner parser.

1:21 (with better errors)

1:21 futile: although that page has "jokes" in them, it's directly relevant to what we're discussing.

1:22 futile: bbloom: tools.reader/read actually executes code?

1:22 bbloom: futile: um, it shouldn't.....

1:23 callen: it's read, not eval.

1:23 nor print, nor loop ;)

1:23 futile: oh

1:24 bbloom: callen: i'm a big fan of generalized CFG parsing b/c i like the tracer rounds approach to eliminating ambiguity & i think that if you've got a code file over 5000 lines or so, it's too damn long. with that in mind, who cares if your parser is O(n^3)

1:24 futile: I think I got confused because of *read-eval*

1:24 bbloom: futile: clojure has a #=(this gets evaled) form which is mega evil / a bad idea

1:24 futile: Oh wow.

1:25 callen: bbloom: I'm a fan of clean, reliable parsers period because I've seen too many shitty shotgun parsers.

1:25 futile: I think I'll use that in every file from now on.

1:25 bbloom: futile: that's why there is clojure.edn/read

1:25 * callen starts to ponder ifdef-esque uses of #=

1:25 bbloom: callen: terrible plan.

1:25 callen: bbloom: it's just idle thoughts of evil, don't worry.

1:26 bbloom: anyway, i'm off to bed. futile: go forth and learn to parse

1:26 futile: bbloom: learn forth? ok

1:26 bbloom: futile: that too. forth is awesome

1:26 futile: no wait, parse forth?

1:26 oh no

1:26 learn go.

1:26 but i already did

1:27 and i most certainly will not parse go, thank you very much!

1:27 bbloom: futile: i gave a talk about concatenative languages at clj/west. factorcode.org == super cool. learn that too

1:27 futile: factjor

1:27 callen: sigh ANTLR. https://raw.github.com/laurentpetit/ccw/c672824293148e202322c537a52a1edd71c61a16/clojure-antlr-grammar/src/Clojure.g

1:27 bbloom: yeah i wrote that :-P

1:27 futile: :D

1:28 bbloom: callen: i'm annoyed that all these damn readers do syntax quoting

1:28 callen: just b/c rich hacked it that way doesn't mean everybody else should

1:28 but i'm out, cya

1:29 callen: cheers.

1:29 futile: Aw, tools.reader doesn't preserve input locations.

1:30 Or maybe it doesn't but just not obviously.

1:30 Aha! IndexingReader

1:44 Dang, input-location information is only provided for some types. Not numbers, for example.

1:45 bbloom: I think that kills it for my purposes. But thanks.

1:50 noidi: ah, futile left already

1:50 he could have looked at Christophe Grand's Clojure parsers

1:50 Parsley and the newer one

1:51 Sjacket

1:51 ah, apparently Sjacket is built on top of Parsley

1:55 ddellacosta: how do I do "delete from things where id in (1, 2, 3)" in clojure.java.jdbc?

1:56 Raynes: Well you just wrote the sql for it, so I expect the next step would be to execute it.

1:57 ddellacosta: Raynes: one would think.

1:57 callen: ddellacosta: raw parameterized or pseudo DSL?

1:57 juliangindi: I'm trying to figure out how to write a function that returns two values that I can capture in two variables. Any suggestions?

1:57 ddellacosta: let me be more clear--how do I use the built-in DSL capabilities of clojure.java.jdbc to make a parameterized delete?

1:57 …such as they are.

1:58 callen: ddellacosta: (j/delete! sqlite-db :test_table (s/where {:id 9001}))

1:58 ddellacosta: I guess I can just do execute! with my string above, but, blah

1:58 callen: ddellacosta: no, use what I just showed you.

1:58 ddellacosta: callen: that works wonderfully for one id.

1:58 that much I can figure out from the docs.

1:58 Raynes: I hate sql dsls. So much.

1:59 callen: give me 2 seconds to dive into their ghetto ass API

1:59 and then you'll have an answer.

1:59 Raynes: Korma is fine.

1:59 Raynes: So is SQL.

1:59 So why not just write SQL? :(

2:00 ddellacosta: callen: so, sounds like we know about the same amount about it…d'oh.

2:00 Raynes: The thing about these crazy ass DSLs is that they're designed to provide flexibility that nobody actually uses.

2:00 callen: ddellacosta: I just got done writing blackwater, it's PTSD to re-remember what I learned about c.j.j

2:00 ddellacosta: Raynes: the answer is that it is handy to have a DSL to generate SQL for you when you are repetitively doing something specific for your domain model

2:00 callen: I need to down a few shots of scotch and then I'll be okay, just give me a minute.

2:01 ddellacosta: callen: hehe

2:01 Raynes: You don't need a DSL for that, you need mustache.

2:01 callen: Tell me about it.

2:01 callen: I've probably touched c.j.j more than anybody in the last 2 months, including Corfield.

2:01 ddellacosta: Raynes: whatza mustache

2:01 callen: I suspect so.

2:01 callen: ddellacosta: he means the template lang, which is a terrible idea.

2:01 Raynes: ddellacosta: It's a bit of facial hair under the nose.

2:01 callen: Raynes: that's a moustache.

2:01 ddellacosta: ooh, yeah, I don't want to do that

2:01 Raynes: ddellacosta: It's a template language and callen can go screw himself.

2:01 ddellacosta: now now you two

2:01 aaelony: fwiw, I typically leave SQL as a string but have different functions for potential where clauses

2:01 Raynes: It's a perfectly suitable solution to this problem.

2:02 ddellacosta: Raynes: it leaves out a lot of the stuff in between, like, validation

2:02 callen: Raynes: mustache is not an acceptable way to structure or manage SQL queries.

2:02 Raynes: I certainly don't think writing it in a Clojure DSL is a suitable way either.

2:02 aaelony: or separate generating functions for sub queries, etc...

2:03 Raynes: It's certainly no more suitable than using a templating language.

2:03 callen: ddellacosta: yeah you're going to have to use execute!, the .sql API only supports dumb AND'd where clauses.

2:03 ddellacosta: you realize Korma is more flexible and better designed right?

2:04 Raynes: Who'da thunk it.

2:04 ddellacosta: callen: okay, that's about what I thought, but figured I'd ask to see if someone had a more clever idea.

2:04 callen: ddellacosta: I tried. c.j.j is dumber than I'm capable of outsmarting.

2:04 * callen cries bitter tears

2:04 ddellacosta: callen: we were using korma and migrated away from it for various reasons--it is too magical for us, and even with the kind of pain of dealing with c.j.j dumbness it is better than wrestling with magic

2:05 callen: ddellacosta: for the love of god, submit issues to the Github so these things can be fied.

2:05 fixed.

2:05 Korma isn't irreparable, it just needs improved. It's a much more solid base to work with than c.j.j

2:05 ddellacosta: https://github.com/korma/Korma/issues/70

2:05 callen: but if nobody submits the tickets...

2:05 grr. k, I'm fixing this.

2:06 ddellacosta: this was the back-breaker for us I believe. I should add, it wasn't me, it was someone else on my team that was doing the heavy wrestling. But I can't complain too much about c.j.j, honestly.

2:06 https://github.com/korma/Korma/issues/64

2:07 I mean, it may have gotten better already, but we started the porting-over process a while back, so it would be seriously counter-productive to go back again now.

2:07 callen: sigh, I know.

2:07 I just want Korma to get that last 10% sorted so people don't have to use c.j.j

2:07 * ddellacosta nods at callen

2:08 callen: because seriously, incrementally assembling queries in Korma is WAY nicer than c.j.j

2:08 ddellacosta: callen: yah, I know. I mean, honestly I am not sold on either one

2:08 callen: and that's all I ever really needed or wanted from an ORM, and Korma does it in terms of SQL itself, but as part of the language.

2:08 ddellacosta: callen: but korma is definitely easier to do this kind of stuff.

2:10 callen: ddellacosta: I do so much CRUD that I really need a nice querying layer so I can abstract the bullshit away.

2:11 otherwise I spend all time doing manual breakouts of various reporting scenarios and it's a huge waste of human life.

2:11 ddellacosta: callen: I hear ya. I just have a few customized macros that do a lot of the heavy-lifting, and otherwise, I write lower-level stuff. Generally, it's not a problem.

2:21 callen: ddellacosta: just to clarify, is the problem returning results at all or loading the results?

2:21 noidi: callen, is korma under active development?

2:21 zeroem: is there a list of common reasons compiling cljs (targeting node) leaves out certain parts of libraries?

2:22 callen: noidi: yes, very.

2:22 ddellacosta: callen: the problem is constructing a prepared statement for deletion

2:22 zeroem: I'm trying to get a program using core.async and some of the impl objects aren't showing up in the compiled version

2:22 callen: ddellacosta: I'm talking about the Korma issue.

2:22 ddellacosta: callen: I want to do something like (delete-things! ids)

2:22 callen: ddellacosta: I'm working on it.

2:22 ddellacosta: callen: oh, sorry

2:22 callen: ddellacosta: I am not improving c.j.j

2:22 that is never ever going to happen.

2:22 ddellacosta: callen: haha, okay

2:22 callen: not unless they clean house and hang a few guilty parties.

2:23 ddellacosta: the insert returning results issue, which part is problematic?

2:23 returning results at all, or ever having gotten them to begin with?

2:23 noidi: I'm starting a new project that needs to use a SQL database, so I should choose between Korma nd c.j.j right about now

2:23 callen: ie, is it okay if I just nil the bastard about?

2:23 ddellacosta: callen: um, at this point it is momentum more than anything. The issue at the time had to do with the fact that some of our records have a LOT of data in them

2:23 callen: and returning them would mess us up pretty bad.

2:23 callen: ddellacosta: so, getting the records at all. got it. thank you.

2:23 ddellacosta: callen: yep, sorry for the overly long answer...

2:23 noidi: in general I'm not a fan of frameworks and magic, so I've been thinking about going with c.j.j

2:23 callen: that also means I'm prolly fucked.

2:24 binding macro gets defenestrated, now we try again...

2:28 ddellacosta: uh, korma can already do what you wanted.

2:28 ddellacosta: I just need to figure out the user-side entry point and document it.

2:28 ddellacosta: callen: yah, I mean, again it's a year old issue...

2:28 callen: well it needed responded to, documentation, etc

2:28 even if it was a non-issue.

2:28 ddellacosta: callen: not surprised to hear that at all. Yeah, definitely.

2:28 callen: ddellacosta: again, I don't know for sure if there's a user-side entry point

2:28 I just see the necessary code in exec-sql.

2:28 and it seems like a possible branch.

2:29 ddellacosta: gotcha

2:30 on the other side of the SQL DSL divide, I'm about to scream at how hard it is to simply execute a delete with an " IN " condition in c.j.j

2:31 callen: lol.

2:32 ddellacosta: on that subject, go here: http://sqlkorma.com/docs and cmd-f for "[in "

2:32 I'll chill out on smug mountain while I figure out how to pass :with-results nil to the macros.

2:32 ddellacosta: callen: I know, I know, Korma can do it…not helpful now unfortunately.

2:32 callen: ddellacosta: need to bug my ass earlier rather than later.

2:33 ddellacosta: callen: dude, earlier is, like, before I started working for these guys

2:33 callen: oh sure, I know we weren't talking at the time

2:33 just as a for-future type thing

2:33 I like sparing people pain.

2:33 ddellacosta: callen: oh, yeah, most definitely I'll be bugging you about Korma if I start using it again. ;-)

2:33 callen: alex baranosky is going to hate me if that happens.

2:33 ddellacosta: alright, I think now is a good time to eat, before I throw my computer across the room.

2:33 * ddellacosta contemplates going out

2:33 korny: any thoughts on korma upgrading it's c.j.j dependency? We had real pain when we tried adding some code that used jdbc 0.3 stuff and it collided with the korma dependency

2:33 callen: 2013 and we can't do a SQL " IN "

2:34 korny: exclude and replace.

2:34 korny: did exclude and replace break?

2:34 korny: didn't try that - seemed a bit risky

2:34 callen: korny: just...write tests.

2:35 korny: :) lots of tests, just not sure our tests would cover making korma use a newer jdbc version

2:35 (and to be fair, when I say "lots of pain", mostly it was just rewriting the merged code back to jdbc 0.2 stuff)

2:36 noidi: ddellacosta, looking at c.j.j, it looks like writing your own `s/in` wouldn't be too hard https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc/sql.clj#L292

2:36 ddellacosta: noidi: that's basically what I'm doing, because I have no choice.

2:36 korny: working at financial institutes makes us tend to be pretty conservative sometimes, I'll admit

2:36 callen: noidi: it's still silly as hell.

2:38 ddellacosta: what I can't grasp is why I keep getting "Parameter index out of range (1 > number of parameters,

2:38 which is 0)," which is forcing me to actually read through clojure.java.jdbc…not what I had planned on doing today. *sigh*

2:41 callen: ddellacosta: how would you feel about Korma only returning insert/delete counts and not results as a default?

2:42 ddellacosta: callen: I think that would be wise, with some option to return the results if need be

2:43 callen: ddellacosta: working on it.

2:44 I know how to do what I want, but it's stuff at a layer below the epidermis.

2:44 incidentally, the layer where the macros end and the functions begins.

3:00 rhg135: Another ? Abot zip, what is the make-node func for?

3:10 ddellacosta: rhg135: it is for what happens when you add a node while traversing a zipper

3:11 …among other things

3:11 rhg135: What if you want a read-only one?

3:12 ddellacosta: rhg135: …don't modify your tree as you traverse it? zip is not going to all of a sudden mutate anything

3:13 rhg135: I mean just supply nil?

3:13 ddellacosta: rhg135: try it and see. ;-)

3:13 rhg135: K

3:15 callen: ddellacosta: insert-returning, insert-returning*, delete-returning, delete-returning*. insert/delete/insert*/delete* no longer return by default.

3:15 ddellacosta: https://github.com/korma/Korma/pull/178

3:15 ddellacosta: I am harassing the motherfuck out of Alex until it gets merged.

3:15 ddellacosta: callen: cool. Thanks for all your effort. I can't promise this means we'll start using Korma all of a sudden, but it's good to know it's being actually worked on.

3:16 callen: probably in general though, that's a good change.

3:16 callen: ddellacosta: I expect nothing. this is purely about improving Korma.

3:16 ddellacosta: I meant it when I said I just want people to submit issues so things can be fixed.

3:16 ddellacosta: callen: yah, figured.

3:25 rhg135: It works fine

3:29 ddellacosta: rhg135: yeah, not surprised to hear that. The only time make-node is used is when something is changed on the tree. Probably you'd get an exception if you mutated something, but otherwise seems like it should be fine.

3:30 rhg135: So (constantly nil)

3:32 kral: namaste

3:41 hhenkel: Good morning. Quick question regarding the use of "edn" for config files. Is there a way to reference allready described data?

3:42 Like init a list of data and later on pointing to it?

3:43 nightfly: That sounds outside of the scope of EDN

3:44 hhenkel: nightfly: hmm, okay. Just thought it might be possible, as it seems doable with property files.

3:48 nightfly: afaik EDN is just safe read'd clojure structures, which means no evaluation that would be resolve references.

3:49 *needed to resolve

3:52 hhenkel: okay, then it seems unpractical for my purposes. Any other suggestions for a configuration format and parser?

3:52 augustl: I use clojure files for config, and evaulate the values as clojure, so I can have "do" blocks and logic and what not in there if I want to

3:57 hhenkel: augustl: okay, that would also be a possibility. Are you aware of a parser who works with simple substitution?

3:59 schmir: being able to execute code in your config files may be sign that you're too lazy to think about the configuration file format. make sure you really want to do that if you're going to let customers use it

3:59 augustl: hhenkel: I just use the clojure reader

4:00 schmir: I regret having executable config files :) It's just for web happs I host myself, but it's still bad design to have logic in config files

4:02 nightfly: meh

4:03 I thought it was becoming a trend to use stuff like Lua for app configuration because of the value of being able to have execution in configuration files.

4:05 ivan: it's no longer plain data if it executes code, you are in a much more complicated world tied to implementation

4:07 hhenkel: I don't want to execute code, I'm just search for a way to reference allready described data.

4:07 augustl: the specific problem I'm having is that by having my config file return (in my case) a datomic database connection, I have to have really clever stuff in my config file when I need to now use multiple databases.. :)

4:08 hhenkel: one way is to use (read-string) and (eval) the values

4:09 referencing already described data sounds a lot like just executing code to me, I might be wrong though

4:11 hhenkel: augustl: Referencing would be nice, but a simple substitution of values would also work for me.

4:12 Something like "key1 = valueA" and key2 = ${key1}

4:13 I don't care if it key2 points to the same refernce or if it would just be substituted on a string level.

4:13 augustl: not sure if anything exists, but should be a pretty small task to implement your own "let", so to speak

4:14 hhenkel: It seems like it should work with property files: http://stackoverflow.com/questions/872272/how-to-reference-another-property-in-java-util-properties

4:32 noncom|2: kral: namaste

4:33 clgv: noncom|2: if I am not mistaken you were the guy interested in more primitive support for functions, e.g. float, int, right?

4:39 sheldonh: i am looking for some functional katas to use to get into clojure. anything leap to mind?

4:39 opqdonut: are you aware of http://www.4clojure.com/ ?

4:40 sheldonh: opqdonut: yay! i am now. thank you :)

4:42 verrrrry nice

4:46 mheld: hey y'all

5:15 sheldonh: how can i prevent the repl from displaying the result of an expression? sometimes, it's enough for me that the statement completes without error

5:16 maybe just (nil? expr)

5:16 clgv: sheldonh: use (def result (my-expr ...))

5:17 sheldonh: clgv: hmmm. i thought that just made result an alias for my expression, without evaluating it

5:17 clgv: sheldonh: then the result isnt shown unless you look at the var `result`

5:18 sheldonh: no that is wrong. it evaluates your expression. only in the case of lazy sequence functions the sequence wont be realized

5:18 sheldonh: clgv: aha! thanks for clarifying

5:18 clgv: sheldonh: but for such an op you can use `doall` to force evaluatuion (def result (doall (map something some-coll)))

5:31 mheld: pedestal is the cool new hotness with respect to web frameworks in clojure-land?

5:36 mpenet: mheld: depends, it's one option if you need to do server push among other things. http-kit is also worth a look (ring compliant, easy to learn compared to pedestal)

5:48 Apage43: man

5:48 synthread just made my day

6:15 turbopape: /msg Chanserv recover #emo.tn

6:16 Raynes: Strrrrrrike one!

6:20 noidi: ambrosebs, I forgot to reply on the mailing list, but anything that shaves time off core.typed startup is a plus. who cares about 10MB these days :)

8:35 In this blog post Stuart Sierra uses a var to hold the instance of the development system. Do you know if there's a reason why he's not using an atom instead? http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

8:36 using vars like that feels dirty to me

8:37 manutter: He only uses it to start and stop the system right?

8:37 noidi: yes

8:38 I think an atom would better communicate that the value is going to change

8:38 manutter: I think it's just a convenience. The "dirtiness" of global vars comes from bugs that arise when different parts of the system change the global in different ways

8:38 but the system in this case doesn't even know about the var

8:38 It's only ever referenced from the repl, by the developer.

8:39 noidi: yeah, maybe it's ok to think of it as a constant

8:39 manutter: I think of it as a developer tool rather than as code

8:39 noidi: I'll still use an atom in my adapation of his workflow, though :)

8:40 manutter: Sure, that would work just as well

8:45 sheldonh: how can i use something from clojure.contrib in a repl started with lein repl? i tried (require 'clojure.contrib) and got FileNotFoundException from the repl and a big history lesson from google. i'm trying to use (profile ...)

8:46 noncom: sheldonh: clojure contrib is no more since afaik clojure 1.3

8:46 now it is spread among differnt libraries

8:46 sheldonh: this page may be of use to you: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

8:47 sheldonh: noncom: sadly not. it doesn't document where clojure.contrib.profile went

8:48 noncom: or maybe it does. if it has no "Migrated to" and "Status:", maybe that means it was just thrown away?

8:48 noncom: sheldonh: is it a profiling lib?

8:49 sheldonh: noncom: yeah. http://richhickey.github.io/clojure-contrib/profile-api.html

8:49 noncom: sheldonh: i guess that the libraries which are not shown where to find, have gone. my best guess is that currently threre are better altrnatives

8:49 try https://github.com/ptaoussanis/timbre

8:50 this is a profiling lib that many ppl would advice to you today...

8:50 i did not use it yet, though

8:51 sheldonh: noncom: i was hoping for something "built in" because i haven't yet learned how to use third party libraries. but i guess now's the time. thanks!

8:51 noncom: sheldonh: do you use leiningen?

8:52 sheldonh: noncom: yup

8:52 noncom: does it automagically download project.clj deps? :) :) :)

8:52 noncom: sheldonh: so you simply add [com.taoensso/timbre "2.6.1"] to your dependencies

8:52 and run "lein deps"

8:52 sheldonh: yay! npm for clojure :)

8:53 noncom: yes, all will be downloaded automatically.

8:56 * ucb waves

9:08 noncom: is there a way i can get to know arity (arities) of an existing function?

9:10 llasram: noncom: AFAIK, the closest you can get is by looking at the :arglists metadata on a function-holding Var.

9:10 noncom: nice, i will try!

9:13 also, do you maybe know, if i create a proxy, and in one of the implemented methods i need some function. so i have 2 options: 1) define the function right inside the proxy or 2) refer to a function defined elsewhere. My question is: does the function defined in way 1 go into every proxy instance, taking up memory?

9:22 TimMc: noncom: Something just occurred to me about your research project: If you want a different ns form, fork Clojure.

9:37 AWizzArd: Compojure/Ring question: I am using core.typed and want to write a type annotation. defroutes returns a function. My question: what type is the input parameter, and what type is the output parameter?

9:38 Let’s say I have this: (defroutes foo (GET "/" [] "<h1>Hello World</h1>")) — what is the argument to foo, so that it will return me a map with that html in the :body?

9:40 ordnungswidrig: (foo {:request-method :get :uri "http://example.com/&quot;})

9:42 AWizzArd: ordnungswidrig: kthx

9:51 noncom: TimMc: yeah, I thought about that. I could get that functionality, although that would mean that the original Clojrue still lacks it.. but I could make the tests on that forked version.. I also thought that maybe it is not the ns form that has to be tweaked, but maybe I have to write a custom replacement for (require)

9:52 that would allow staying with the mainstream clojure also

10:54 coventry: In emacs, using ritz-nepl, C-c C-b (nrepl-interrupt) interrupts any running process, but does not return me to the REPL prompt. Anyone know a workaround for this?

11:12 noncom: is someone familiar with ñäî-håtp here?

11:12 *clj-http

11:12 callen: noncom: just ask your question man

11:13 I need a Taser-over-TCP/IP protocol so I can zap people that ask to ask.

11:13 noncom: how do i get the list of available content types? (the prefabs which have keyword alias)? and can i use pain strings if i don't find the one i need, like "'application/x-www-form-urlencoded"?

11:13 i looked into sources, but can't find

11:14 (client/post) refers to some (request) func, i cant find the source of..

11:14 silly but..

11:14 oh damn

11:14 looks like i got it

11:15 there is no explicit :use or :require of the namespace that it comes from. instead, it is referred to somewhere in the middle of the code, by its fulyl qualified name

11:16 how strange

11:26 invis: please help me to write function that do this: https://www.refheap.com/18231

11:27 waste about 3 hours and still cant create a good decision for that

11:29 opqdonut: use recursion

11:29 on the second parameter

11:29 (defn combs [xs n] (if (zero? n) [[]] (for [x xs y (combs xs (dec n))] (vec (cons x y)))))

11:30 bbloom: also, consider lazy-seq

11:31 invis: to: <opqdonut> Thanks a lot

11:31 Anderkent: or use clojure.math.combinatorics/cartesian-prudct

11:32 opqdonut: yeah, that would be neater

11:32 Anderkent: (apply clojure.math.combinatorics/cartesian-product (repeat 2 [1 2 3]))

11:32 ((1 1) (1 2) (1 3) (2 1) (2 2) (2 3) (3 1) (3 2) (3 3))

11:33 coventry: I came across a let binding of "_", which isn't used in the body. There's magic to binding "_" in a let-form, right?

11:33 TimMc: No magic.

11:33 coventry: Thanks.

11:33 TimMc: _ is simply convention for "not used"

11:33 Anderkent: coventry: that's just a way of evaluating stuff for side effects in middle of let

11:34 _ is a name as any, but people pick it because it's the convention for unused

11:34 TimMc: In some languages (and in some Clojure macros or DSLs) it *is* special, but the meaning is still "don't care" or "unused".

11:35 coventry: Anderkent: But it is the final binding in the form, so it could go more simply in the body. Maybe there were other bindings after it at one stage. https://github.com/clojure/jvm.tools.analyzer/blob/master/src/main/clojure/clojure/tools/analyzer.clj#L840

11:35 callen: I use _ for things I'm doing for side effects or where I don't care about the returned value in general.

11:35 Anderkent: coventry: I think it's more of a 'this *has* to happen before expr-ast is used'

11:35 callen: especially in let bodies.

11:35 Anderkent: and thus makes sense to put it in the let where expr-ast is defined

11:36 coventry: OK, thanks.

11:49 cjfrisz: Is there an easy way to run the core.typed type checker as part of my cljs build, i.e. by modifying my project.clj?

11:51 bbloom: cjfrisz: i'm trying to convince ambrosebs that more people will use core.typed if `lein check` worked.

11:51 callen: bbloom: or if it was faster.

11:51 cjfrisz: bbloom: That's pretty much exactly what I want

11:52 callen: a continuous type checker ala lein prism would be cool.

11:52 Anderkent: (deftest passes-checks (typed.core/check-ns)) ? :P

11:52 bbloom: cjfrisz: it's part of my master plan to convince more people that types are like unit tests. you can measure type coverage the same way you measure test coverage: in both cases you don't necessarily need 100% coverage

11:53 callen: I'm a little dubious of anything that places burdens on callers though.

11:54 cjfrisz: bbloom: Ambrose mentioned to me that core.typed for cljs integration isn't quite up to par, so is it a fool's errand to try using it right now?

11:54 ambrosebs: cjfrisz: There's nothing at the moment. Also CLJS support is pretty dodgy atm.

11:54 bbloom: Anderkent: that's what ambrosebs told me too :-P but `lein test` should be renamed to `lein unit` and then test should be an alias for `check` and `unit` :-)

11:54 cjfrisz: there's your answer ^^

11:54 ambrosebs: cjfrisz: If you're playing around right now I'll give myself a quick refresher of what I've actually implemented.

11:55 cjfrisz: Oh sweet…it probably would have been a good idea to check if ambrosebs was actually here

11:56 ambrosebs: cjfrisz: Well, tell me what happens if you open up a clojure REPL and run (cljs.core.typed/check-ns 'your.ns)

11:56 Anderkent: FileNotFountException! (.. I'll show myself out)

11:57 ambrosebs: Anderkent: are you talking about core.typed?

11:57 oh right :)

11:57 cjfrisz: ambrosebs: I just started adding types a few minutes ago, so let's see if I'm far enough for that to work :-)

11:57 bbloom: ambrosebs: the joke was that your/ns.cljs was not found :-P

11:57 ambrosebs: LOL

11:58 mheld: what's the de-facto way to get views set up with clojure

11:58 I've got a bunch of models and I want to map them to the RESTey views I've got

11:58 callen: mheld: Ring/Compojure.

11:58 mheld: need to get a little more specific about what you mean by "views" though.

11:58 Are these API endpoints or hooman-facing HTML pages?

11:59 mheld: callen: I come from the rails world

11:59 Anderkent: Actually, it wouldn't be a FNFE, but I was too lazy to check what it actually is. (IllegalArgumentException :P)

11:59 mheld: I'm looking for human-facing pages

11:59 callen: mheld: http://www.luminusweb.net/

11:59 ambrosebs: cjfrisz: make sure you're using macros from cljs.core.typed. I haven't documented anything yet :)

11:59 mheld: callen: gracias

12:00 it looks like the philosophy of clojure is to be sinatra-ey -- are there any monolithic rails-ish frameworks out there?

12:00 Anderkent: mheld: as in web templates? envlive is cool.

12:00 mheld: I looked at pendulum?

12:00 pedestel

12:00 but it didn't conform to ring, and that made me sad

12:01 Anderkent: the whole your-models-can-be-resources-and-talk-to-controllers-that-have-7-methods thing

12:01 cjfrisz: ambrosebs: it may take me a few minutes to get myself un-noobed enough to give you useful info

12:01 bbloom: mheld: not to discourage you from using clojure, b/c clojure is freaking awesome, but the best monolithic framework out there… is rails :-P seriously, no sense reinventing it

12:02 mheld: bbloom: heh, I don't see why there couldn't be a monolithic framework in clojure!

12:02 bbloom: mheld: it's just not in this community's DNA

12:02 mheld: (I'm actually rewriting this rails project in clojure because I'm giving up on trying to get rails+activerecord to work with this propriatary database)

12:03 bbloom: mheld: your best bet is to write your API/backend in clojure and then wrap a rails frontend around it

12:03 Anderkent: mheld: pedestal is probably your best bet if you really need it to be monolithic. But in general ring+compojure+enlive has worked for me

12:03 mheld: bbloom: that's silly!

12:03 Anderkent: but I've never liked the rails magic, so might be skewed

12:04 ambrosebs: cjfrisz: the only documentation for CLJS atm is in the tests. eg. https://github.com/clojure/core.typed/blob/master/src/test/cljs/cljs/core/typed/test/dnolen/utils/dom.cljs

12:04 IIRC that type checks.

12:05 bbloom: mheld: if you're porting a substantial piece of code, the best thing to do is to change as few things at a time as possible

12:06 mheld: bbloom: it's not substantial

12:06 bbloom: and it'll probably be scrapped by the end of the week

12:06 I'm just POCing something

12:06 bbloom: mheld: in that case, the sinatra-ish frameworks in clojure land are the way to do

12:06 they are super simple

12:07 mheld: well, it would be un-substantial if I could just (defresource MODEL [:index :show :new :create]) or something

12:07 and nest resources

12:07 that'd be super choice

12:07 Anderkent: with compojure you can define routes per resource and nest those pretty easily

12:09 mheld: Anderkent: true

12:10 cjfrisz: ambrosebs: It says it can't find the cljs file's namespace in the classpath

12:10 ambrosebs: https://gist.github.com/cjfrisz/14f2d06882fd53a0dd5f

12:10 ambrosebs: feel free to assume I've missed something obvious wrt cljs; still getting the hang of it vs. Clojure

12:11 ambrosebs: cjfrisz: I've got this in my project.clj

12:11 :source-paths ["src/main/clojure"

12:11 "src/main/cljs"

12:11 ]

12:11 cjfrisz: ambrosebs: good call

12:12 ambrosebs: (I'm just as clueless as you right now)

12:12 I just keep dnolen on chat :)

12:12 bbloom: ambrosebs: should start bugging cemerick too, since he's taken over lein-cljsbuild

12:13 i trust in chas to just make my life easier at every turn

12:13 ambrosebs: bbloom: didn't know that. nice.

12:13 bbloom: ambrosebs: https://github.com/emezeske/lein-cljsbuild/commits/master

12:14 ambrosebs: bbloom: dnolen has the added bonus of "sure, I'll add that to cljs.compile"

12:14 bbloom: ambrosebs: true, but it's a lot more work to convince dnolen of anything :-)

12:14 ambrosebs: :D

12:14 nice, cljsbuild is in good hands.

12:17 cjfrisz: ambrosebs: I'm starting out trying to type a function that takes 2 numbers and returns them in a vector

12:17 ambrosebs: It seems that something's unhappy with me trying to use Number in my annotation: https://gist.github.com/cjfrisz/6bf9e1a088e030c7173a

12:17 johnmn3: I'm getting NullPointerException on lein cljsbuild once. Then I run it again and it compiles in around 120 seconds. But when I refresh the page, nothing loads. the console says: Uncaught TypeError: Object #<Object> has no method 'run'

12:17 ambrosebs: cjfrisz: try number.

12:18 johnmn3: and my run method is the method that kicks off from the html into my cljs, obviously

12:18 but the stacktrace is weird: java.lang.NullPointerException: at java.util.regex.Matcher.getTextLength(Matcher.java:1234)

12:19 which continues into clj_stacktrace

12:19 I'll just post up the stack trace

12:20 mheld: I'd also kill for luminus to have a 'lein luminus generate model THING foo:string bar:text'

12:20 that'd be nice

12:21 johnmn3: isn't this a strange stack trace: https://www.refheap.com/18232

12:22 might be a bug in the compiler?

12:22 cjfrisz: ambrosebs: Let's take a step back and acknowledge that this is my first time trying to use core.typed…how would I write the annotation for an arity 2 function that takes two number and returns them in a vector?

12:22 ambrosebs: cjfrisz: [number number -> '[number number]]

12:22 cjfrisz: ambrosebs: Ah, probably misusing Vector*

12:23 johnmn3: cause I've been removing, slowly, some of the recent changes to my cljs and it's not fixing it. there's no indication of error in my file.

12:23 Anderkent: johnmn3: might be. Seems like it's trying to clean up some cause exception and fails

12:23 see lines 19-22 in that stacktrace

12:23 ambrosebs: cjfrisz: IIRC (Vector* number number) is the same as '[number number]

12:23 is that how you're using it?

12:23 cjfrisz: Yes, and it gave me the same error

12:23 AssertionError Assert failed: No check-fn bound for rest type

12:23 check-fn-method1-rest-type clojure.core.typed.check/check-fn-method1 (check.clj:2953)

12:24 R_Macy: How do you introspect a namespace and see all of the available functions?

12:24 ambrosebs: cjfrisz: which core.typed version?

12:24 cjfrisz: ambrosebs: 0.2.1

12:24 R_Macy: bumbling around on the internet and in the manual, I don't see anything obvious

12:24 johnmn3: so frustrating! I've run lein cljsbuild clean. Run lein cljsbuild once ... it fails... run it again, it succeeds in 120 seconds. and again, the js doesn't load in the browser.

12:24 R_Macy: (in a repo, to be more specific)

12:25 repl*

12:25 Anderkent: R_Macy: (keys (ns-map 'ns))

12:25 it will give you more than just the functions, but oh well

12:26 johnmn3: i'm also on java 8 on an ARM processor. Starting think it's not worth the edge cases for development.

12:26 Anderkent: R_Macy: actually, use ns-publics not ns-map

12:26 unless you want the private symbols too

12:26 R_Macy: Ah cool thanks Anderkent

12:26 ambrosebs: cjfrisz: thanks.

12:26 R_Macy: I don't just public symbols, trying to see avail functions for a library I'm planning to use :)

12:27 ambrosebs: cjfrisz: I've actually had my CLJS tests commented out while I was waiting for a new version of CLJS.

12:27 bbloom: R_Macy: (find-doc "ns-")

12:27 ambrosebs: cjfrisz: I shall resurrect them.

12:27 bbloom: cjfrisz: talk about service. you should have ambrosebs just write all your type annotations too!

12:28 Anderkent: bbloom: ha, assuming they have docstrings :D

12:28 bbloom: Anderkent: seems like they do....

12:29 benkay: i've got time for one video this morning: should it be RailsConf 2012 Simplicity Matters or Strange Loop 2011 Simple Made Easy?

12:29 silasdavis: is there a core function to get the values from a map?

12:29 Anderkent: silasdavis: vals

12:29 cjfrisz: bbloom ambrosebs: I know! it's like having the best automatic type recovery pass over my code!

12:29 bbloom: silasdavis: http://clojure.org/cheatsheet

12:29 Anderkent: trying to teach people to fish too :-)

12:29 juliangindi: can anyone give me some guidance regarding returning multiple values from a function and than saving them to local variables within another function

12:30 silasdavis: thanks, did try some fishing, assumed 'values'

12:32 Anderkent: juliangindi: you will have to return a collection then destructure it on the receiving side. For example (defn foo [] {:a 1 :b 2}) and then (let [{:keys [a b]} (foo)] ...)

12:33 juliangindi: Anderkent: Awesome, thanks!

12:35 cjfrisz: juliangindi: here's another example: https://gist.github.com/cjfrisz/6414524

12:36 juliangindi: cjfrisz: how do you get away with passing in too few arguments without using something like 'partial'

12:37 cjfrisz: juliangindi: Because I free-handed that and made a mistake :-)

12:37 I didn't make that mistake when I double-checked it in the repl

12:37 juliangindi: cjfrisz: ohh haha! still a good example, thanks!

12:38 cjfrisz: juliangindi: I updated it with the fix

12:41 Although I suspect that multiple return values via destructuring is less efficient than using values/call-with-values/let-values in Scheme, I appreciate how much simpler it is in Clojure

12:41 That is, assuming a good implementation of multiple return values in Scheme

12:42 ambrosebs: So is that a core.typed bug that I'll need to wait on before continuing?

12:42 Er…I should say cljs.core.typed bug?

12:43 ambrosebs: cjfrisz: probably. I think type checking any function body is broken.

12:44 cjfrisz: ambrosebs: alright, I'll probably leave my typed code in a branch then

12:45 I had been thinking about testing out core.typed with this little game even before I had two 10+ minutes bug track-down sessions yesterday that wouldn't have happened if I had types :-)

12:45 ambrosebs: cjfrisz: FWIW the types could stay there and have no effect.

12:46 cjfrisz: ambrosebs: true, I should have thought of that

12:46 clgv: in datomic how do I add an entity to a "many", "ref" attribute and not replace the previous entity, i.e. I want to build up a list incrementally

12:46 silasdavis: can I do better than: (apply concat (vals {:a [3] :b [6 4 6]}))

12:47 benkay: clgv will you pastebin your schema?

12:47 Anderkent]away: silasdavis: that looks good to me

12:47 silasdavis: is (mapcat last {:a [3] :b [6 4 6]}) better?

12:48 Anderkent]away: make that (mapcat val ...)

12:48 ambrosebs: cjfrisz|away: :)

12:48 coventry: ambrosebs: Since jvm.tools.analyze/macroexpand is piecing the macroexpanded form together from the results of eval'ing the input, there is no way to get back individuating metadata on the inputted symbols, is there? E.g. (def n #(fn [& args] 1)) (-> '(do (n) (^{1 2} n)) macroexpand last first meta) returns {1 2}, but replacing macroexpand with jvm.tools.analyze/macroexpand results in nil instead.

12:48 silasdavis: Anderkent]away, ah nice, thanks once again

12:49 benkay: clgv: [:add ?e :listy-ref ?ref-entid] maybe?

12:50 ambrosebs: coventry: that might be a bug.

12:50 coventry: I imagine the metadata should show up in the AST, so it should be easy to put it back into the form.

12:50 coventry: ambrosebs: Oh, it would be so great if there were a simple fix for that.

12:51 ambrosebs: coventry: I'll have a quick look.

12:51 coventry: Thanks, ambrosebs.

12:51 ambrosebs: coventry: it's actually reconstructing an analyzed form, not an evaluated form.

12:52 clgv: benkay: I used {:db/id experiment-id, :experiment/instance-runs instance-run-id} so I see only the last value

12:53 benkay: clgv: if you pastebin your schema and the query that's not working i'd love to take a look at it

12:53 clgv: (or, you know, subset of schema...)

12:54 clgv: benkay: the schema gets generated by another lib. what is the easiest way to query it?

12:55 benkay: clgv: generate it at the repl?

12:57 clgv: i'm imagining a situation where because your schema isn't available for inspection you're having trouble reasoning about application logic

12:57 clgv: benkay: I tried (d/q '[:find ?i ?t ?c :where [?e :db/ident ?i] [?e :db/valueType ?t] [?e :db/cardinality ?c]] (d/db conn)) but I'll need to resolve the ids

12:58 benkay: well my problem is that I do not know how to build a list incrementally. I just assumed normal add would work that way for :db.cardinality/many

12:59 benkay: has in my experience

12:59 gotta run, apologies for being useless

13:10 clgv: running that same query in my local instance returns stuff, but not I think the useful stuff :(

13:11 clgv: benkay: consider :experiment/instance-run as many ref attribute do I add components to it by adding {:experiment/_instance-run expid, ...}?

13:11 ambrosebs: coventry: I don't know where the metadata goes..

13:12 benkay: clgv: that's what i would do. does that not work for you?

13:12 coventry: ambrosebs: No worries. I think it might be a fairly tricky problem. Thanks for taking a look.

13:13 benkay: clgv: i think you'd have to first acquire the entid for the experiment and then add a ref attribute to the experiment entity pointing to the instance-run entid

13:13 clgv: benkay: seems not. just tried that manually

13:13 ambrosebs: coventry: cool, yea maybe there is some subtle interaction between reading and analysis.

13:14 clgv: benkay: the schema already exists

13:14 benkay: clgv: not talking about the schema.

13:14 ambrosebs: coventry: I just can't find an AST field in clojure.lang.Compiler for local Var metadata.

13:15 clgv: benkay: is there no description available online how to handle :db.cardinality/many attributes?

13:16 ieure: I'm having issues with serving static resources in a war file (generated with `lein ring uberwar') from tomcat.

13:16 coventry: ambrosebs: I think I was only adding metadata to the symbol in the list, in which case the problem might be that the analysis is dropping the symbol in favor of the var it represents.

13:16 ieure: It works fine with `lein ring server' or an embedded Jetty, but throws "java.lang.NullPointerException: Handler returned nil" under Tomcat.

13:17 ambrosebs: coventry: that makes sense.

13:17 ieure: Any idea what might be wrong here? I see the files on the path in the .war

13:17 ambrosebs: coventry: this kind of thing works nicely in CLJS.

13:17 analyzer is much nicer.

13:18 coventry: ambrosebs: Oh, that's interesting. I was thinking to primarily target cljs in the end anyway, but I thought things would be simpler to experiment with in clojure.

13:19 ambrosebs: coventry: No, definitely use CLJS to experiment with analysis.

13:20 benkay: clgv: here's a thing that does cardinality/many refs

13:20 clgv: http://paste.lisp.org/display/138732

13:20 coventry: ambrosebs: OK, thanks. But before I go that route, is hacking the compiler to put the symbol metadata in the AST likely to be as much of a bear as it sounds?

13:20 clgv: benkay: thx. I was googling myself the last 15mins ^^

13:20 but found nothing suitable yet

13:20 benkay: clgv: I strongly recommend working through Day of Datomic.

13:21 silasdavis: I have function with a base return value of true or false if a data structure is in a valid format

13:21 I'd like to pass the invalid entries out as well

13:21 benkay: clgv: that repo managed to bang some insight through this rock i call a skull

13:21 ambrosebs: coventry: I wouldn't recommend it :)

13:21 silasdavis: I'm considering throwing an exception, returning a hash, or implementing an error monad

13:21 clgv: benkay: humm is there some guide how to work through? manually I tried to find the things I need in there but not with much success yet

13:21 coventry: ambrosebs: OK, thanks. :-)

13:21 silasdavis: does anyone have any recommendations?

13:21 ambrosebs: coventry: could be fun/educational though.

13:22 coventry: probably only a few lines.

13:22 you'd need your own version of tools.analyzer too.

13:22 benkay: clgv: open up example in one window, transcribe it by hand into your editor. if you get stuck, go to a different example.

13:22 ambrosebs: or... no actually emit-form is a multimethod, so you'd just need to make 1 new multimethod for :var.

13:22 sick :)

13:23 clgv: benkay: humm right

13:23 benkay: clgv: i've not had much success just looking for specific snippets to solve my problems. far more productive for me (in learning both clojure and datomic) has been to work at developing holistic understanding

13:24 clgv: benkay: well my import managed to import 500 entities but didnt update the many ref attribute and then died with a TimeoutException ... :(

13:25 coventry: ambrosebs: Yeah, I figured I'd have to make a small change to tools.analyzer, too. Do you have any suggestions about which parts of Compiler.java to read, if I want to have a go at this?

13:25 benkay: pretty sure we just went screaming through my personal knowledge horizon :(

13:25 ambrosebs: Find VarExpr, I assume there's a "parse" method on that.

13:25 coventry: Thanks.

13:25 ambrosebs: Add an extra field to VarExpr for local metadata.

13:26 coventry: Great, I'll be in touch if I succeed. :-)

13:27 ambrosebs: coventry: great

13:27 clgv: benkay: oh, did not know `touch` yet...

13:28 benkay: do I need to specify both parts of a relation in a transaction to establish it?

13:28 benkay: clgv: that is indeed a thing.

13:28 clgv: what do you mean by both parts of a relation?

13:29 clgv: benkay: like in the component_attributes.clj example

13:29 benkay: clgv: db.type/ref is inherently bidirectional

13:29 ambrosebs: coventry: looks like clojure.lang.Compiler.AssignableExpr.Parser is what you want to tinker with.

13:29 makkalot: hi, i'm trying core.typed when i (:require [clojure.core.typed :as t]) and then t/All or t/U it says can not find them but i'm able to t/cf , any ideas ?

13:29 clgv: benkay: oh I meant that the target entity is in the transaction as well

13:30 coventry: Thanks, ambrosebs. I'll take a look.

13:30 ambrosebs: makkalot: All and U are special, they are never qualified.

13:31 makkalot: ambrosebs, so how can i use them ?

13:31 ambrosebs: if you have a type called All, use a qualified symbol.

13:31 if you want to use *the* All, just use (All [x]...)

13:32 clgv: clgv: no seems to work without.

13:32 weird...

13:34 benkay: clgv: it seems so?

13:34 clgv: it does in the day-of-datomic case. it did not in my example.

13:35 benkay: clgv: well hang on, can you shoot me a line number or three in component_attributes.clj that demonstrate what you mean by both parts of a relation?

13:35 clgv: benkay: I phrased that badly ;)

13:36 benkay: clgv: gotta step away again for a few

13:38 makkalot: ambrosebs, thanks

13:38 ambrosebs: makkalot: np

13:48 cjfrisz: ambrosebs: how do I define a type shorthand/alias, i.e. (type-alias my-type (Vector* Type Type))?

13:48 ambrosebs: (def-alias MyType "mydoc" Type)

13:49 http://clojure.github.io/core.typed/#clojure.core.typed/def-alias

13:49 mheld: anybody here use haml with their clojure webapps?

13:49 coventry: ambrosebs: Do you know what the distinction between VarExpr vs TheVarExpr is about? TheVarExpr has a Parser class which pulls a Var out of the form, whereas VarExpr doesn't seem to have any kind of parser in its inheritance/composition hierarchy.

13:50 ambrosebs: coventry: semantically it's the difference between a and #'a.

13:50 coventry: Thanks.

13:51 ckirkendall: Has anyone ran into this exception when doing clojurescript? clojure.lang.Namespace cannot be cast to clojure.lang.Named

13:51 ambrosebs: coventry: isn't the parser for VarExpr in AssignableExpr?

13:53 timvisher: hello all

13:53 juliangindi: hello there

13:53 cjfrisz: ambrosebs: didn't notice your reply until just now; thanks!

13:53 otherapricot: when using Enlive, is it possible to select the *parent* of a node matching some criteria?

13:53 ambrosebs: cjfrisz: :)

13:53 dnolen: cjfrisz: btw, so are you working on a fun project that involves CLJS? :)

13:53 timvisher: happy labor day to the 'mericans

13:54 cjfrisz: dnolen: Yes

13:54 sandbags: afternoon

13:54 dnolen: cjfrisz: nice!

13:54 cjfrisz: Had an idea for a game kicking around in my head, and I needed some application development in my life in addition to the platforms stuff I do at work

13:54 coventry: ambrosebs: AssignableExpr appears to be an interface, and it's not clear to me which of its implementations might contain the parser used for VarExpr. I'm relatively inexperienced, though, might have missed something. https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L744

13:55 timvisher: anyone able to tell me what triggers changing a namespace in the browser repl?

13:55 ambrosebs: coventry: whoops I was looking at AssignExpr :)

13:55 coventry: timvisher: in emacs, C-c M-n will eval the namespace form of the current buffer.

13:56 timvisher: i'm used to `C-c C-l`ing a file and having all the functions loaded into the image in the namespace declared at the top

13:56 but in the browser repl, this doesn't seem to happen

13:56 coventry: thanks

13:56 ambrosebs: coventry: I guess search for "new VarExpr" and see what's creating it?

13:57 timvisher: coventry: is there any way to tell what namespace I'm in?

13:57 i.e. evaling *ns* in jvm clojure

13:57 coventry: ambrosebs: Thanks, I was about to go through all instances of VarExpr in the file. "new VarExpr" is more specific. :-)

13:57 ambrosebs: coventry: hehe

13:58 timvisher: also, is there a writeup anywhere of the differences between clojurescript namespaces and clojure namespaces?

13:58 i keep hearing people mention that clojurecript doesn't support true namespaces but never an articulation as to why

13:59 ambrosebs: timvisher: I'll tentatively point out that the current namespace is kept in cljs.analyzer/*cljs-ns*

13:59 if you can get to it from a browser repl (I have no idea)

13:59 coventry: timvisher: Sorry, missed that you're talking about clojurescript. I asked about *ns* etc. in clojurescript (actually pedestal) a couple of weeks ago. There doesn't seem to be a good way of doing it at the moment. (See dnolen's answer a couple of responses down.) http://clojure-log.n01se.net/date/2013-08-11.html#19:26

14:00 timvisher: ambrosebs: yeah, it doesn't look like it's defined in the browser repl :()

14:00 coventry: ambrosebs: (Regarding the compiler) Aha, I think I want analyzeSymbol.

14:00 timvisher: s/:()/:(

14:01 ambrosebs: timvisher: :)(

14:01 coventry: sounds about right.

14:01 bbloom: timvisher: quite simply, clojurescript does not have a data type which represents namespaces

14:01 timvisher: …. at runtime

14:01 timvisher: lol. that's actually a great emoticon

14:02 bbloom: timvisher: there is a divide between the compiler on the JVM and the running code in the JS engine. namespaces only exist at compile time. at runtime, they are just plain old javascript objects

14:02 timvisher: bbloom: ok. so what am i doing when i eval `(in-ns 'some-ns)` in a brepl?

14:02 bbloom: timvisher: you're sending an instruction to the repl implementation

14:03 timvisher: bbloom: so why would that be any different than loading a file with the `(ns …)` declaration at the top?

14:03 bbloom: timvisher: realize that clojure, and indeed most lisps, are two-stage systems. one stage is compilation & the other is evaluation. on the JVM, both of those stages live on the same host & can share objects. in CLJS, the stages are stratefied across a host boundary.

14:04 timvisher: the ns directive is not special in clojure: it gets evaluated to code which creates namespace objects dynamically. in clojurescript, it's a special form that is analyzed at compile time

14:04 timvisher: ok

14:04 bbloom: timvisher: the in-ns function isn't actually defined in cljs. the REPL is analyzing your input and giving a directive to the compiler

14:05 that's a repl feature, not a runtime feature

14:05 unlike clojure, where in-ns is an ordinary function

14:05 make sense?

14:05 timvisher: got it, so in cljs i should be in the habit of using in-ns to change between namespaces as i move around in my buffers or at the repl. there's really no analog at the moment to simply being in the ns at the top of the file?

14:05 bbloom: i think so. :)

14:06 lol, as much as i ever get anything.

14:06 bbloom: timvisher: just pretend that clojure.core was divided in to two namespaces: clojure.compiler and clojure.runtime

14:06 timvisher: clojurescript only has clojure.runtime

14:07 timvisher: namespaces are part of clojure.compiler

14:07 timvisher: however, since that divide doesn't really exist, it's a little less clear what works how on which side of the boundary

14:07 cjfrisz: ambrosebs: seems like def-alias causes a runtime JS exception

14:07 TypeError: 'undefined' is not an object (evaluating 'cljs.core.typed.def_alias_STAR_')

14:07 timvisher: bbloom: and in this case clojure.compiler is in java and clojure.runtime is in javascript and the 2 can't communicate.

14:07 ambrosebs: cjfrisz: oh, forgot you were using CLJS :)

14:07 cjfrisz: ambrosebs: haha

14:08 ambrosebs: cjfrisz: tell me these things xD

14:08 bbloom: timvisher: right

14:08 cjfrisz: So that's a known problem?

14:08 bbloom: timvisher: so there is cljs.repl that approximates a subset of clojure.compiler via talking to the compiler remotely

14:08 ambrosebs: cjfrisz: might just be not yet implemented.

14:08 timvisher: bbloom: got it. that's much clearer. thanks very much.

14:08 cjfrisz: ambrosebs: Should I be filing tickets on these things?

14:09 ambrosebs: cjfrisz: that would be awesome.

14:09 cjfrisz: ambrosebs: Will do :-)

14:09 ambrosebs: cjfrisz: thanks!

14:09 timvisher: so my take away at this point is that the only reliable way to switch `ns`es is to use `(in-ns …)`.

14:09 futile: Who was that person who did a talk and put their slides online that mentioned CounterClockWise and the other plugins, and explained that tools.reader rips out source-location info but you can put it back?

14:10 coventry: futile: Christophe Grand, sjacket.

14:10 futile: Because tools.reader doesn't keep the source-position for each form in every atom type.

14:10 Ah! Thanks coventry.

14:12 coventry: But actually, tools.reader is pretty good about decorating the tree it returns with source location data, so you might be talking about someone else.

14:15 bbloom: coventry: tools.reader only stores that info in metadata afaik, which means it can't work for numbers, keywords, etc

14:16 cjfrisz: dnolen: JIRA says you fixed the infinite loop for circular dependencies in the CLJS compiler, but I set myself up to test it yesterday and got a stack overflow

14:16 coventry: bbloom: Right, thanks.

14:17 futile: bbloom: yeah, that's why I can't use it.

14:17 bbloom: fortunately it shouldn't be that difficult to write an efficient/fast recursive-descent parser for Clojure in Clojure, right?

14:17 bbloom: futile: have you seen https://github.com/cgrand/sjacket

14:18 cjfrisz: And by "set myself up," I mean that I had an object hierarchy that I needed to fix, and decided to see what happened when I introduced a circular dependency

14:18 futile: bbloom: I got scared away by "Sjacket is still in its infancy"

14:18 timvisher: so i just did this. i evaled `(in-ns 'x)`, and then evaled another form with a function defined in x and got a `Cannot call method 'call' of undefined` error because what tried to get executed was `other-ns.f`

14:19 i guess there is a slight delay in the switching of the namespaces?

14:19 bbloom: futile: *shrug* like i said, it's LL(1) so pretty easy to parse. see LispReader.java in the clj source

14:19 timvisher: because i executed it again a second or 2 later and got the right results

14:19 bbloom: ~1kloc

14:19 clojurebot: Excuse me?

14:19 futile: clojurebot: you're excused

14:19 bbloom: futile: and that does lots of extra stuff too, like syntax quote, which you won't need

14:19 clojurebot: Titim gan éirí ort.

14:20 coventry: futile: tools.reader is pretty close already. I was planning to work around this issue by hacking on it. (I already have a version of it which turns off syntax-quote.)

14:20 futile: bbloom: oh good that confirms what I was thinking, as I don't want to pull in something that's overkill

14:21 The only thing that makes writing a parser a little scary for me is that I don't know *all* the syntax things you can do. Like, doesn't Clojure have literal syntax for longs (20L) and imaginary numbers?

14:21 bbloom: futile: it's all in LispReader.java

14:21 futile: bbloom: then I'll check it out, thanks :)

14:22 Wait, https://github.com/clojure/clojure is the official repo?

14:23 coventry: futile: Yes. http://clojure.org/downloads

14:24 futile: Okay thought so. I guess it threw me off because I thought that was just a mirror, but I saw it was mentioned in that downloads page.

14:30 cjfrisz: ambrosebs: Here's the ticket for def-alias http://dev.clojure.org/jira/browse/CTYP-39

14:30 ambrosebs: cjfrisz: thanks!

14:30 cjfrisz: ambrosebs: I forgot the other issue I was having, and my scrollback in IRC isn't going far back enough for me to see it

14:31 ambrosebs: don't worry about it.

14:31 futile: lol, today's log for http://logs.lazybot.org/irc.freenode.net/%23clojure downloads instead of opens in-browser

14:32 coventry: In the clojure source code, running "ant" twice seems to result in a complete rebuild. (2 minutes on my machine) Is there any way to make it more selective about what needs to be recompiled and what tests need to be run?

14:32 mheld: hey guys, can I have one of y'all look over a macro that I'm writing up? here's what I have so far http://pastie.org/private/ntsqnw9g4jtnvdnaqymgfq (macroexpand-1 (defcrud device [:id :first_name])) gives me a not-so-useful error message -> CompilerException java.lang.RuntimeException: Unable to resolve symbol: devices in this context, compiling:(/private/var/folders/c_/2j9hpl0n0fn3v59cy4nvkms80000gn/T/form-init6654342976921486472.clj:1:16)

14:32 am I not unquoting something right?

14:33 coventry: mheld: Can you show the call to the macro which is generating the error?

14:33 mheld: coventry: (macroexpand-1 (defcrud device [:id :first_name]))

14:34 (plural is coming from an inflection library

14:34 )

14:34 cored: hello

14:34 this does return true in the repl, (= (list :a :b :c) '(:a :b :c))

14:35 but I get an error in 4clojure, am I doing something wrong?

14:35 mheld: coventry: could it be because of the way I'm defn-ing?

14:36 coventry: mheld: I don't know why you'd be getting a symbol "devices" out of that input.

14:36 timvisher: cored: link?

14:37 is there any way i can avoid a full recompile in cljs when adding a previously unreferenced goog component?

14:37 mheld: coventry: the plural of device is devices

14:37 coventry: mheld: I would be looking at defentity.

14:38 ambrosebs: cjfrisz: seems i've broken cljs.typed fairly well in the last few weeks :)

14:38 cjfrisz: ambrosebs: Oh, I remember now: function annotations don't seem to work

14:38 mheld: coventry: ha, you're right!

14:38 cjfrisz: ambrosebs: :-)

14:38 cored: timvisher: (= (list __) '(:a :b :c))

14:38 that's the question

14:38 clojurebot: Cool story bro.

14:38 ambrosebs: cjfrisz: yea I'm observing that too.

14:38 cored: I added (= (list :a :b :c) '(:a :b :c)) as I did in the repl

14:38 ambrosebs: I swear they worked.

14:39 cjfrisz: ambrosebs: Like my boss always says, "Bug reports should always make you happy; they're an opportunity to make your software better."

14:39 ambrosebs: love it :)

14:39 Chousuke: cjfrisz: that depends on the bug report :P

14:39 "it crashes" is not going to make people happy

14:39 timvisher: cored: can you give me a link to the problem?

14:40 cored: timvisher: I think I found the issue, the site is just asking what I have to put in the missing spacce not the entire expression

14:40 timvisher: http://4clojure.com first problem

14:40 cjfrisz: Chousuke: (Un)luckily I work with people whose bug reports are pretty well explained and indicate that I implemented something wrong

14:40 timvisher: cored: that's what i was assuming you were doing

14:40 poutsi: Chousuke: you could react to that by making the software lethal... which could be interpreted as a subjective improvement on your own part

14:40 ;P

14:40 timvisher: 4clojure's random in the order it present problems so i couldn't just visit the site

14:41 cored: timvisher: oh, sorry

14:41 timvisher: did not know that

14:42 coventry: cored: Just give the URL in your browser address bar.

14:42 timvisher: cored: no problem. glad you're sorted :)

14:42 cjfrisz: ambrosebs: And here's the other ticket: http://dev.clojure.org/jira/browse/CTYP-40

14:42 ambrosebs: great

14:43 Chousuke: cjfrisz: today at my work we got an order for a new server that "should be like the other one"

14:43 cjfrisz: Chousuke: haha!

14:43 Chousuke: cjfrisz: nowhere did it specify what other one

14:43 mheld: coventry: oh, apparently it's not working because it's not a literal string

14:48 coventry: mheld: sounds like progress.

14:51 mheld: I miss define-syntax

14:51 callen: mheld: really?

14:52 mheld: yes

14:52 cjfrisz: mheld: agreed

14:54 mheld: callen: I also like having a singe namespace for functions and variables

14:54 callen: mheld: Clojure is a Lisp-1...

14:55 mheld: I could've sworn it was a lisp-2

14:55 callen: mheld: ...no.

14:55 cjfrisz: oh thank glob it's not a lisp-2

14:55 mheld: weird that defn and def are two different things

14:55 callen: mheld: defn is just sugar for def and fn.

14:55 cjfrisz: mheld: defn is syntactic sugar

14:56 mheld: oh! I did not know that

14:56 callen: you really don't want to mistake the sugar for a representation of the semantics.

14:56 mheld: that makes me like clojure even more

14:56 callen: mheld: it would seem you haven't noticed much, you need to get a book.

14:56 mheld: callen: I should get a book

14:56 callen: mheld: I recommend the one by Chas Emerick et al.

14:56 mheld: http://www.clojurebook.com/ this one.

14:56 covers things nicely.

14:57 cjfrisz: mheld: I miss pattern-matching macro transformers and the greater amount of parenthetical delimiters

14:57 And yes I just said I wish Clojure had *more* parens

14:57 mheld: me too

14:59 johnmn3_: is there a known combination of cljs release and cljsbuild that work best together?

14:59 having a fun time trying to troubleshoot this build problem

15:00 callen: johnmn3_: you mean an example project? If so, tonnes.

15:01 bbloom: cjfrisz: i seriously can't read infix

15:02 cjfrisz: bbloom: ?

15:02 bbloom: cjfrisz: associativity & precedence is convenient when writing on paper, but fuck me it's so much harder to read w/o extra parens

15:03 cjfrisz: bbloom: Oh, I see what you mean

15:03 wrt Clojure, forms like 'cond' have fewer parens than in Scheme

15:03 johnmn3_: I mean I've tried the latest clojurescript release, I've tried "0.0-1843", cljsbuild 0.3.2 and 0.3.3-SNAPSHOT. I've tried using a fresh project directory. I see no obvious syntax errors anywhere. With CLJS 1843 and cljsbuild 0.3.2, the compile just hangs forever. Using whitespace.

15:03 bbloom: cjfrisz: so there are two factors at play

15:03 cjfrisz: Which makes it harder to read to me

15:04 bbloom: cjfrisz: 1) is the elimination of the overloading of parens and 2) is implicit grouping for even numbers of forms

15:04 cjfrisz: the former i quite like, the later i'm still on the fence about

15:04 cjfrisz: but lean towards the side that clojure is on now

15:04 gfredericks: I'm just digging into core.typed for the first time; I always thought hypothetically that the most promising aspect was type-checking clojure-style "use maps for everything" business code

15:04 cjfrisz: bbloom: I always get cranky when a cond clause gets long

15:04 gfredericks: in particular using HMap to track what keys are present when

15:05 bbloom: cjfrisz: yeah, so cond is the WORST CASE for #2

15:05 cjfrisz: bbloom: and core.match has the same problem

15:05 bbloom: cjfrisz: and so nobody can agree on how to properly indend a cond in clojure

15:05 gfredericks: but now I'm thinking it's prohibitively tedious when type-annotating all vars is required

15:05 noncom|2: how can i create a runnable jar with leiningen, that, upon being launched, gives a clojure repl in one of the namepsaces?\

15:05 bbloom: cjfrisz: yeah, it's not so bad for let b/c the odd forms are always symbols

15:05 R_Macy: what's an idiomatic compjure project structure? any good examples out there?

15:06 gfredericks: noncom|2: check out nrepl and reply

15:06 noncom|2: ok!

15:06 cjfrisz: bbloom: I have code that let-binds cond rhs expressions just so they'll fit on one line and I'm bitter about it to this day

15:06 gfredericks: noncom|2: might be able to just use reply, I forget how it works exactly

15:06 bbloom: cjfrisz: i've just taken to indenting the even forms in a cond

15:07 cjfrisz: my editor & half the community hates it, but it looks much nicer to me

15:07 noncom|2: i just thought there was some like checkbox in leiningen for that, but if no, then i go for what you say, thanks!

15:07 cjfrisz: bbloom: I think I've done that, too. Feels weird, though

15:07 bbloom: But better than leaving them at the same indent level

15:07 bbloom: cjfrisz: in practice, i've found that any time my conds get big and ugly, i just refactor

15:07 timvisher: is there a shortcut way in closure to get the currently selected radio button in a radio button group?

15:08 bbloom: cjfrisz: the only time it's really a problem is when there is a lot of context from the lexical closure. otherwise it's easy to extract out helper functions. make a protocol or multimethod

15:08 cjfrisz: in practice, i kinda like it when some constructs become unwieldy quickly, b/c it forces you to refactor

15:08 timvisher: something like jquery's `:checked` pseudoselector?

15:08 cjfrisz: bbloom: I definitely see the benefit of that, but somewhere along the line I picked up a policy of only factoring things out if they're used more than once

15:09 timvisher: lol

15:09 bbloom: cjfrisz: terrible policy :-)

15:09 timvisher: should've tried that one first

15:09 shaungilchrist: bbloom: that is seriously a great aesthetic feature

15:09 timvisher: :)

15:09 bbloom: cjfrisz: i assign names to basically everything. makes my code a little bit longer vertically (more lines) but far less dense

15:09 cjfrisz: bbloom: I think it's an inherent mistrust for a compiler whose source code is unknown to me

15:10 bbloom: I don't know how good the inliner is ;-)

15:10 bbloom: cjfrisz: the inliner is terrible. the jit is pretty good :-)

15:10 cjfrisz: but clearly you should code for humans first & computers second :-)

15:10 gfredericks: most of the time

15:10 bbloom: cjfrisz: not the least of which is yourself. i can never tell what brandon of 1 week ago was up to, unless he refactored :-)

15:11 cjfrisz: bbloom: I think this is one of those "I agree with your position completely but will be unable to extract myself from mine"

15:12 bbloom: I think I picked it up at work, and if I change my habits, my boss will make fun of me

15:12 bbloom: cjfrisz: your boss will make fun of you for writing clearer code?

15:12 sounds healthy.

15:13 * gfredericks imagines Nelson Muntz as a boss

15:13 cjfrisz: bbloom: Actually he probably won't make fun of me, but he'll end up inlining that himself when he takes a pass over the code

15:13 bbloom: cjfrisz: that just seems insane to me....

15:13 cjfrisz: the JVM *looooves* small methods

15:13 cjfrisz: bbloom: "Oh, this let-bound var is only used once, I'll just put the definition inline"

15:14 bbloom: cjfrisz: that let bound name is valuable documentation! i spent valuable time coming up with a name for that exrpession

15:14 jowag: anyb knows the status of multi-reducible reducers? I was thinking about using core.async to implement them, but it may be slow that way

15:14 gfredericks: bbloom: does the indirection of vars not get in the way of jvm optimization?

15:14 or are we just talking about locals?

15:14 cjfrisz: bbloom: Again, agree with your position, just have bad habits :-)

15:15 bbloom: gfredericks: so that's an interesting point

15:15 gfredericks: for locals, it clearly doesn't matter

15:15 gfredericks: for vars, they have dynamic scope & so every var reference is technically an indirection (ie deref) on lookup

15:16 gfredericks: my understanding is that the deref method is tiny & a itty bitty guard expression is put in there & the result is pretty much immeasurable, but i could be very wrong. i dunno

15:16 cjfrisz: What's the type for a variable length, homogeneous vector in core.typed?

15:16 Just realized that I asked "What's the type for…" in a Lisp IRC channel

15:17 gfredericks: cjfrisz: go to your room

15:17 actually I'm playing with core.typed right now myself

15:17 I don't know the answer though

15:19 * cjfrisz goes to room, contemplates what he's done wrong to get to this point

15:20 kab3wm: I can't seem to figure this out - I have a function that calls 3 other functions (each with side-effects). I do not care about the response. I have wrapped the 3 fn's in a do, but only the last fn is creating a side-effect. I thought that was the purpose of do, is there something else I should be using?

15:20 gfredericks: kab3wm: nope that sounds super weird

15:20 callen: cjfrisz: Vector* is a heterogenous vector.

15:21 it's a vector of "Value"s.

15:21 gfredericks: kab3wm: the first two return lazy seqs that you're not realizing?

15:21 do*

15:21 TimMc: mheld: I could lend you my Clojure book -- it's whichever one Chas Emerick wrote.

15:21 gfredericks: TimMc: Clojgramming Projucre

15:21 is the title

15:21 shaungilchrist: I just have to say, though there is some small amount of potential slowdown w/ cljs - the approach of ditching jquery etc. more than makes up for it.

15:21 kab3wm: gfredericks: nope, if I switch the orders of the fn's each one works as long as it's the last fn in the (do)

15:21 mheld: TimMc: ha thanks :-)

15:21 callen: Get this book -> clojurebook.com

15:22 mheld: TimMc: I'm on the west coast now :-(

15:22 callen: mheld: TimMc is recommending the same book I recommended. Just geti t.

15:22 cjfrisz: callen: I thought I could specify a fixed-length, homogeneous vector, e.g. (Vector* number number)

15:22 gfredericks: kab3wm: that's what made me speculate about lazy seqs

15:22 mheld: callen: I know TimMc IRL :-P

15:22 juliangindi: Im attempting to loop a body and than update the input values at the "recur" section. I am having difficulties and any help would be super appreciated: https://gist.github.com/Julian25/6416129

15:23 callen: cjfrisz: it's fixed length and homogenous because you passed it two numbers.

15:23 cjfrisz: use value.

15:23 I specifically said, of "value"s.

15:23 gfredericks: juliangindi: your recur needs to have two args

15:23 kab3wm: gfredericks: simplified example on pastebin on pastebin- http://pastebin.com/Uu6XjnDf

15:23 gfredericks: the first is the new value of loopCurrent, the second is the new value of loopNext

15:23 callen: cjfrisz: you can also do '[(Value x)]

15:24 kab3wm: ick, what's with the parens at the end man :\

15:24 noncom|2: reply seems a good option, but there are no instructions on how to install and use it to be the frontend of the application...

15:24 juliangindi: gfredericks: parse-raw-input return two values that i am attempting to capture in loopCurrent and loopNext

15:24 gfredericks: kab3wm: that didn't tell me anything new; some example code from one of the functions would be nice

15:24 noncom|2: it is present in lein, ok, but i want it to be the user interface for the app

15:24 juliangindi: gfredericks: such as in this line of code "(let [[currentList nextList] (parse-raw-input (line-seq rdr))]"

15:24 kab3wm: callen: I'm still learning. this helps my eyeballs for now.

15:25 gfredericks: juliangindi: so (let [[a b] (parse-raw...)] (recur a b))

15:25 TimMc: mheld: Ah, right! Oh well.

15:25 juliangindi: gfredericks: ah..I see. I'll give it a shot. Thanks!

15:25 cjfrisz: callen: thanks!

15:26 callen: cjfrisz: just read the docs: https://github.com/clojure/core.typed/wiki/Types

15:27 ckirkendall: dnolen: got time for an odd async and clojurescript exception

15:27 callen: ckirkendall: just ask your question, don't target people like that.

15:27 kab3wm: gfredericks: ok, here's a better paste - http://pastebin.com/ZFJiGgvD

15:28 ckirkendall: I am getting the following exception: java.lang.ClassCastException: clojure.lang.Namespace cannot be cast to clojure.lang.Named


15:28 gfredericks: kab3wm: yeah that looks reasonable; you don't need a do at the top level of a defn, but that shouldn't be your problem

15:28 I have no further ideas

15:29 ckirkendall: I traced it to the fixup-aliases method here -> https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async/impl/ioc_macros.clj#L613

15:29 juliangindi: gfredericks: Getting a strange error: "Can't take value of a macro". Here is the updated gist. https://gist.github.com/Julian25/6416129

15:29 kab3wm: gfredericks: originally I had it all at the end of let and that wasn't working, so I've just been trying whatever I can think of. Thank you for taking the time to look. I'll keep playing with it.

15:29 ckirkendall: Are we able to call (name ns) on a namespace? I didn't think we could do this. Is this an issue with my version of clojure.

15:30 gfredericks: juliangindi: you'd want to remove the square brackets in your recur; I don't think that would give you that error though

15:30 amalloy: ckirkendall: ns-name

15:30 juliangindi: gfredericks: Yeah, I removed the square brackets, to no avail

15:31 gfredericks: juliangindi: oh you lost your parens aroudn let; line 7

15:31 ckirkendall: amalloy: I thought so but this is in the core.async code.

15:32 juliangindi: gfredericks: Yup, that was it! Thanks :)

15:32 amalloy: ckirkendall: in that code, ns isn't a namespace, it's just a symbol

15:32 well, maybe. i guess i don't know

15:32 ckirkendall: its somehow getting a namespace

15:35 if sym is a namespace this code will looks like it will fail

15:35 It has (if-not (namespace sym) sym (... (name sym)))

15:46 arkh: in c2, I'm able to successfully set e.g. the "width" of an SVG dom object with (attr (select "#svg-thing") :width 80)) and I can read the value back to verify the change took place but, visually, nothing ever changes with the SVG object

15:46 whoops - make that (attr (select "#svg-thing") :width 80)

15:47 a browser element inspector still shows the svg as having the old width

15:59 rurumate_: Where is clojure.contribs.combinatorics now?

16:00 cjfrisz: callen: I couldn't get any type using Vector* to type-check for variable-length vectors. I'd checked over the docs both before and after your advice, and finally tested (clojure.lang.IPersistentVector MyType) to specify a variable-length vector that contains only entries of type MyType.

16:00 coventry: rurumate_: People talk here a lot about clojure.math.combinatorics. I haven't used it, though.

16:01 rurumate_: oh yeah, just found it, thanks

16:10 * ucb waves

16:13 callen: ucb: howdy.

16:13 ucb: hey callen

16:13 how's it going?

16:13 callen: ucb: pretty good, tossed a PR at Korma last night, signed on a place in SF this morning. Working on a public holiday. You? :)

16:14 ucb: callen: writing tests for riemann streams and stuff. Finally doing some clojure for a change, so pretty good (despite a haunting migraine)

16:15 callen: ucb: I know the horror of trying to get work done with a migraine beating down the walls. Hope you feel better soon. Glad you're doing Clojure :)

16:15 ucb: yeah, the migraine is easing off as the day progresses (? - it's nearly 9pm here) so I've struggled to get anything done today

16:16 callen: ucb: 1251 and waiting on Chinese food on my end :)

16:16 ucb: nice

16:19 callen: ucb: there's a dude writing a CMS in Clojure and Couch, might want to look into that if you weren't already aware.

16:19 he's been "thought-streaming" the work.

16:19 ucb: oh?

16:20 I'm deciding, slowly but steadily, that webdev is not my thing

16:20 for one, I suck at it

16:20 callen: https://github.com/SnootyMonkey/falkland-cms https://thoughtstreams.io/snootymonkey/falkland-cms/ https://readthedocs.org/projects/falkland-cms-api/

16:20 ucb: I've been full stack for a long time, everything from persistence to JS. Why do you believe you're bad at it?

16:21 ucb: callen: lack of practise most likely. Been a backend dev most of my life. So-called devops (according to younguns these days)

16:21 gfredericks: does anybody know the best way to type-annotate #(assoc % :foo 12) in terms of HMap?

16:21 ucb: callen: been struggling to make any tangible progress on my clojunauts thing I told you about some time ago

16:22 bbloom: is there a good way to track down the source of a rouge stack overflow in a sizable chunk of code?

16:22 callen: ucb: well, there's always the option of tapping into the dark powers of Lord Sauron if you want help.

16:23 ucb: I have notions and suggestions when it comes to coder's block or working through unfamiliar territory as well.

16:23 ucb: callen: I would mind the help/advice really

16:23 ergh


16:23 callen: bbloom: stack overflows that are red?

16:23 ucb: NT

16:23 ok?

16:23 * ucb sighs

16:23 gfredericks: bbloom: clojure is a DSL for creating obscure stack errors

16:24 callen: bbloom: is visualvm or yourkit an option?

16:24 bbloom: you could watch the stack bloom.

16:25 amalloy: bbloom: i'd probably just read the stacktrace. it's usually got a pretty good indication

16:25 bbloom: callen: maybe...

16:25 callen: amalloy: I figured that wasn't an option since he didn't just do that.

16:25 I would've suggested that to most punters but I figured he knew better.

16:25 bbloom: amalloy: unfortunately, the stack trace is very short.

16:25 callen: ^^ that's what I suspected.

16:25 amalloy: uhhhh

16:26 bbloom: it's failing in clojure.lang.AFunction$1.doInvoke

16:26 amalloy: mind if i look at it? you've got me curious now

16:26 bbloom: which i assume means i wrote a bad function :-P

16:26 https://gist.github.com/brandonbloom/6416765

16:26 callen: bbloom: code?

16:27 bbloom: callen: i'm not quite ready to share yet :-P but it's probably too much code to quickly analyze for such a bug anyway.

16:27 amalloy: bbloom: this is coming from nrepl? it does some unpleasant things to stacktraces

16:27 callen: bbloom: I'm suspicious of the apply.

16:27 amalloy: also you misspelled propagate

16:28 callen: bbloom: are you doing a map of reductions?

16:28 bbloom: in a loop/recur?

16:28 bbloom: amalloy: lol thanks

16:28 amalloy: anyway, it looks like handle-base calls itself recursively forevery

16:28 bbloom: callen: no

16:29 amalloy: via propagate's lambda, and some other function at 329

16:29 callen: then it's probably just a straight up recursive function that isn't using loop recur.

16:29 I don't really know what to tell you without code in front of me.

16:29 amalloy's nose seems good.

16:30 bbloom: thanks guys, was just looking for some general advice. is there a way to recover a more complete stack trace?

16:30 amalloy: bbloom: run your app outside of nrepl :P

16:30 callen: bbloom: dump them periodically via st.

16:30 probably to a log file

16:30 put it right before the tail position.

16:30 amalloy: but it won't be an interesting stacktrace. it's just going to be those five lines repeated a few hundred more times

16:30 callen: not using nrepl is good too.

16:31 amalloy: plus like whatever your path from -main is, i guess

16:31 callen: amalloy: more of a just-in-case measure.

16:31 bbloom: callen: there's only one recur that is basically a trampoline through this propagation mechanism

16:32 i'll probably just stare at it for a while longer & the solution will come to me

16:32 thanks again

16:34 mheld: how would I override the statement that korma generates for INSERT?

16:34 callen: mheld: slow your roll son.

16:34 coventry: Am I just wrong to want to add attributes to every class in Compiler.java which implements Expr and modify every instance post-instantiation? I can't add members to the Expr interface, because then they're static final. Is this actually an appropriate place to use inheritance?

16:34 callen: mheld: what exactly is meant by "override"? What do you want to accomplish?

16:35 mheld: korma generates INSERT INTO TABLE(key key) values (value, value) and I need INSERT INTO TABLE values(value, value,,,) -- filling in the holes that are in the column names

16:35 callen: mheld: why do you need the latter?

16:36 mheld: callen: proprietary database

16:36 callen: mheld: if it's not an officially supported database, vendor specific things require using raw queries.

16:36 mheld: I'm ok with that

16:36 callen: decorating the insert macro behavior is possible, but I just got done making some tweaks to that last night and would rather not re-open that front.

16:36 mheld: hah

16:36 ok

16:37 yeah, I'm diggin' clojure a lot

16:37 I totally forgot how much I love lisp

16:37 coventry: Actually, I know I'm wrong, because it's complicating these objects. But I don't know the right way to achieve my goal of passing form-level metadata through the compiler's analyzer.

16:37 callen: it's easier to do semi-custom queries if you use the insert* fn and write an alternative or use a different make-query-then-exec fn.

16:37 mheld: yeah I have ridiculous amounts of fun. 3/4s of the reason I do Clojure OSS stuff.

16:38 coventry: dare I ask what you're doing? :P

16:40 coventry: callen: I want to be able to map as many components of fully macroexpanded forms as possible back to their locations in the source code, for an edebug-like tracing tool.

16:40 callen: first noncom, now you?

16:41 coventry: I think you're thinking of futile, and as far as I know I was working on this before him. :-)

16:41 Is he also trying to make a tracing tool?

16:41 callen: futile works on everything, none of it counts.

16:41 noncom is doing something magical with ns decls, I don't know exactly what.

16:43 coventry: My initial strategy was to use the location metadata you get from an indexing reader, and rely on the fact that macroexpand preserves this metadata. But it turns out that the only reliable tool for full macroexpansion is the compiler itself. It drops the form-level metadata during analysis. I am currently thinking of ways to make it not do that.

16:47 bbloom: amalloy: ah, turns out it was me, not nrepl eating the stack trace :-P

16:48 i had another bit of code that was converting host exceptions in to target language exceptions

16:51 callen: most creative way to fuck onesself I've heard in awhile.

16:52 bbloom: this little project has been a total mind fuck in general

16:53 every time i code something up & it works, i'm pretty damn proud of myself & then immediate in disbelieve and try to falsify my results

16:54 i'm working on abstract interpretation of a language w/ multi-shot continuations, which is hard to implement on the JVM :-/

16:55 coventry: Oh, if I'm going to hack the compiler, I might as well hack macroexpand-1 to keep track of what it's expanded to what. That is a simple change which will maintain my form-level metadata, and I can easily reconstruct the fully expanded form from it.

17:08 callen: coventry: https://github.com/ztellman/riddley

17:10 coventry: callen: Thanks, I hadn't come across that yet. If I can use it to track source code location, it sounds perfect.

17:10 callen: coventry: if you're trying to do something that involves ?!SCIENCE!? then ztellman and aphyr are good github accounts to check first

17:11 ckirkendall: I was able to fix the issue with 'name' being called on a namespace by patching core.async.

17:11 coventry: callen: I'll keep that in mind. :-)

17:11 ztellman: haha, lag between tweeting the repo and its use being suggested: 3 minutes

17:12 callen: ztellman: not my fault your work was relevant.

17:13 or that I habitually check my twitter :\

17:14 ztellman: well, on the subject of open source by Kyle and myself, there will be some interesting stuff appearing on the Factual repo in the next week or so

17:14 keep watching the skies

17:25 coventry: ztellman: that library is so useful to me. Thanks.

17:26 callen: coventry: he's gone, but I'll pass the love on :P

17:26 coventry: Thank you, too. :-)

17:32 noncom|2: can i make "lein repl" to start in a particular namespace?

17:34 callen: noncom: you type in (ns name.space.here) I think.

17:37 chronno: noncom|2: you can use the :repl-options and :init-ns in your project.clj (https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L293)

17:37 noncom|2: chronno: cool! thank you!

17:38 chronno: noncom|2: np, although if you run it with nrepl.el it doesn't work as expected :-( (https://github.com/clojure-emacs/nrepl.el/issues/316)

17:39 noncom|2: eheh :) luckily i have to run it from the OS

17:42 AWizzArd: About Protocols: I have (defprotocol P (f1 [x]) (f2 [y])) and (extend-protocol P String (f1 [x] :string-f1) Object (f2 [x] :object-f2))

17:43 Calling (f1 "hi") works fine of course, but (f2 "hi") doesn’t. Is there a way how I can convince Clojure to find the most specific f2 for Strings that is implemented?

17:43 In our case here it would be the Object f2. Currently it seems that because I specified *something* for class String, Clojure now expects me to implement *all* protocol FNs for this class, and does not allow fallbacks to the next most specific impl.

17:45 dnolen: AWizzArd: partial implementation of a protocol is a broken implementaiton, it's just not how protocols are meant to work.

17:46 AWizzArd: Seems I have to live with this then.

17:47 It’s a bit cumbersome for my JavaFX usecase, but thanks for letting me know that this behaviour is indeed a desired feature.

17:48 coventry: What's desirable about this limitation?

17:49 callen: if it's that loosey-goosey, don't use protocols.

17:50 AWizzArd: coventry: well, an advantage is that this way one can detect possible bugs.

17:50 If you just forgot to implement a protocol fn you will get an exception.

17:51 Although I would prefer to be able to specify ^:partial to let Clojure know that this is what I want.

17:53 juliangindi: I'm working on my first full Clojure project and I was wondering if anyone had tips/tricks/tools for debugging

17:53 callen: AWizzArd: you could contrive a fakey auto-generator exception-throwing shim for the rest.

17:53 juliangindi: REPL, ritz, println, pray.

17:53 juliangindi: visualvm, yourkit, tools.trace

17:53 limit-break/debug-repl

17:54 unit tests

17:54 functional tests

17:54 generative tests

17:54 mocking

17:54 not writing bugs.

17:54 juliangindi: if I could write bug-free code for the rest of my life, I'd get bored =)

17:54 AWizzArd: callen: yes, I could offer a conveniece macro to my users, to allow them adding new JFX components for which I couldn’t implement Container behaviour myself.

17:55 Probably a good idea.

18:00 Another protocol + core.typed question: (defprotocol P (foo [a b] [a b c])). Clojure eats this expression, but is this the correct way to do it? (ann-protocol P foo [[Any Any -> Any] [Any Any Any -> Any]])

18:02 callen: ambrose has you people seriously hooked on types.

18:04 AWizzArd: I wanted them since 2004 in Lisps.

18:04 And 2008 I started basic work on it. It’s fantastic that finally someone took the required time and did it.

18:04 Especially gradual typing is what I wanted.

18:05 nice read about it: https://groups.google.com/forum/#!topic/clojure/ekj0jksZehU

18:06 Meikel mentioned gradual typing back then.

18:12 callen: I'm a fan of optional typing, don't get me wrong, I'm just pleased and amused by how people are going nuts for them since Ambrose started talking about it more.

18:13 AWizzArd: I can’t speak for others, but I wanted this since so many years and had so many discussions about it, since 2004. So for my case it is indeed something very deep.

18:15 The interesting thing is that just a few daysweeks ago this project became usable.

18:15 And I am already looking forward to all those people who argumented *against* static typing, and now they have it.

18:15 “I always said it was a good thing” <-- there will be plenty of those, from all the haters too :D

18:17 brehaut: callen: i think there is a reasonably large subset of clojurists who would _almost_ use haskell or an ML but prefer clojure's – for lack of better word – flavour of functional programming, but do miss the static type checking

18:18 AWizzArd: Just because you can see the merits a dynamic language doesnt mean you dont *also* see the merits of static typing.

18:19 irrelephant: just playing around abit with threading, i want to get some monitoring from the threads but can't get the logger function to update more then 1 item in the agent http://pastebin.com/ymBGxFd5

18:20 as pasted only the last value gets updated, which makes sense to me, but wrapping it in a do will stop the threads working all together

18:20 amalloy: irrelephant: assoc-in doesn't mutate anything

18:20 AWizzArd: CT allows us to even statically type code from authors who totally not want it.

18:20 amalloy: the definition of write-output is clearly wrong, without even reading past it

18:21 irrelephant: amalloy, oh, well it kinda works =)

18:21 technomancy: AWizzArd: I have my doubts as to whether that would be effective

18:21 AWizzArd: technomancy: what you mean?

18:22 technomancy: just that it's easy to write code that a typechecker can't do anything useful with if you don't care

18:22 amalloy: you really just want (update-in output [:thread-summary tid] assoc :current-item msg, :foo (rand-int 1000))

18:22 brehaut: technomancy, AWizzArd: the TypeScript 'DependantlyTyped' repository is a good example of the pros and cons of that approach

18:23 technomancy: AWizzArd: I mean I think you can make it work, it would just be lots of work if you're going against the grain

18:23 AWizzArd: technomancy: my point is the thing we both talked about a few months ago, where you said you would like it if type-hints can go into an extra file, to avoid code clutter.

18:23 brehaut: sorry sorry, DefinatelyTyped https://github.com/borisyankov/DefinitelyTyped

18:23 AWizzArd: brehaut: you have a lin.. ah okay

18:23 technomancy: AWizzArd: oh yeah, that's definitely the way to go in either case

18:24 brehaut: AWizzArd: specifically multiple type definitions for various libraries, with different language version and library version support and assumptions about how to best type said libraries

18:24 AWizzArd: technomancy: this we can do. I could write all type hints for, say, Compojure and Ring today and push this as a tiny lib to Clojars. You can then just depend (via Leiningen) on my lib and get all the benefits, as if the original authors added those type annotations.

18:25 brehaut: AWizzArd: https://github.com/brehaut/ring.typed/ ;)

18:25 ring is _bloody hard_ to type

18:26 AWizzArd: brehaut: yup, I just learned this today :-)

18:26 Aah, there *is* ring.typed? Cool, let me have a look…

18:26 brehaut: AWizzArd: thats my own experimental hack at it

18:26 AWizzArd: its not useful

18:26 AWizzArd: unlike https://github.com/brehaut/re.typed/ ;)

18:27 AWizzArd: To me it is useful, thanks for this source for examples.

18:27 brehaut: AWizzArd: note that its against quite an old version of core.typed atm

18:28 AWizzArd: One thing we definitly need is an emacs plugin that will hide/show all type annotations when pressing Ctrl+F9

18:29 This way even technomancy might accept 1-3 type annotations in his code ;)

18:29 irrelephant: amalloy, ah that does the trick, thanks. any pointers why a do wrap would lock the threads?

18:29 AWizzArd: Or, if the annotations go indeed into their own file, such an emacs plugin could store them there, and only show them in-place on demand.

18:30 amalloy: irrelephant: what you describe makes no sense

18:32 brehaut: AWizzArd: I quite like the annotations in another file approach

18:33 AWizzArd: although for practical reasons its useful to have them inline

18:33 AWizzArd: brehaut: I want them directly there where the def/defn is. But: with a nice IDE plugin a separate file can be totally fine.

18:33 irrelephant: amalloy, sorry, when you look at the paste there are 2 assoc-in that want to change the agent, but as pasted only the last update will actually materialize, from what i understood so far that makes sense and wrapping the 2 statements in a do function should remedy that

18:34 but when i do that the threads seem to lock up

18:34 amalloy: wrapping those in a do would make no difference whatsoever

18:34 AWizzArd: This plugin would have to automatically take care and move the annotations into the correct file, even when I edit them in-place. And I must be able to hide/show them, and when I show they need to appear as if they were in my current source file.

18:49 irrelephant: amalloy, well actually it stops the program from working :p, but back to more reading for me i guess. so if i also want to run let's say inc via update-in i should just make another send call from the worker thread or is there a way to put it all into one function?

18:51 callen: irrelephant: I can't handle your nick.

18:51 amalloy: that hardly seems relephant, callen

18:53 callen: amalloy: I don't have the koalafications to handle this ridiculousness.

18:53 irrelephant: one could even say it's totally irrelephant

18:54 rplevy: Any idea why this would produce nil in Linux JVMs and only produce result on Mac JVMs? https://www.refheap.com/18238

18:55 genEric: just for you callen

18:55 callen: even more maddening.

18:55 bbloom: aw, that makes me beary sad

18:56 amalloy: rplevy: just a coincidence: you're making the reflector guess which overload to call, and apparently it guesses differently in your two environments

18:56 submit takes either a Runnable or a Callable, and Runnables don't have a value

18:57 IFn is both of those things, so if you don't specify which you want it to act like, you get a guess

18:57 rplevy: oh! that makes sense

18:58 callen: amalloy: I'm now convinced you aren't mortal.

18:58 amalloy: callen: it's pretty easy to diagnose the fifth time i see it

18:59 rplevy: I'm gonna go with the not mortal explanation anyway

19:00 callen: amalloy: you've lived the lives of 500 wizards in the last 5 years anyway, so I'm going to say it's isomorphic with being immortal anyway.

19:00 amalloy: haha

19:00 callen: in the next episode of, "Stump amalloy!", the audience loses. Again.

19:04 amalloy: okay, how do you force Runnable vs. Callable with Executors?

19:04 the question nerd-sniped me.

19:05 amalloy: callen: let-bind it with a typehint

19:06 (let [^Callable f (fn ...)] ...)

19:07 callen: amalloy: returns nil, actually.

19:08 hrm, wait

19:08 amalloy: i don't think i believe that. gist a reproducing repl session?

19:09 callen: yeah that doesn't work.

19:09 bbloom: anybody ever see some weird shit with defrecord and instance? not behaving?

19:09 amalloy: bbloom: you probably reloaded the file with defrecord but not the file with instance

19:10 and then tested some old instances

19:10 callen: https://www.refheap.com/18241

19:10 amalloy: ^^

19:10 bbloom: amalloy: yeah, i tried that...

19:10 amalloy: er suspected that, but i can't see how… there's only one file & i restarted the repl

19:10 amalloy: then i thought i may have copy pasted the defrecord line & didn't cut the origina… but no, only one

19:10 callen: amalloy: I guessed the solution you suggested, that's why I asked to make certain I wasn't crazy.

19:11 dissipate_: why do i keep hearing that macros are bad because they don't compose well with functions?

19:12 callen: dissipate_: totally false, it's a conspiracy. They're just trying to keep real ultimate power out of the hands of the oppressed proletariat.

19:12 amalloy: callen: you haven't typehinted tp, so it's still using reflection

19:12 callen: dissipate_: rise up and destroy your masters! Macro all the things!

19:13 dissipate_: callen, Chas Emerick mentions it in his talk: http://www.infoq.com/presentations/What-Sucks-about-Clojure-and-Why-You-ll-Love-It-Anyway

19:13 amalloy: (and you can't typehint the var, because that doesn't mean what you want. you have to hint it at call-time, or in a let-binding)

19:13 dissipate_: the guy who wrote the book 'Clojure Programming'.

19:13 callen: dissipate_: yes, he's one of the Illumi-lispy! the new world order of lisp overlords trying to keep macro power from people like you.

19:13 dissipate_: hehehe

19:13 i bet...

19:14 amalloy: callen is the secret leader of the Resistance

19:14 bbloom: amalloy: http://dev.clojure.org/jira/browse/CLJ-1132

19:14 amalloy: i'm not using tomcat or anything. i'm just using a normal repl, but apparently i'm not totally crazy...

19:15 amalloy: but this explains my bug from earlier! i have (defrecord Raise …) and then (defn raise? [x] (instance? Raise x))

19:15 amalloy: yeah, i can imagine classloaders/AOT causing a problem there

19:15 although of course it shouldn't

19:15 bbloom: amalloy: my recursion termination condition involved raise?

19:15 amalloy: hah

19:16 bbloom: amalloy: i refactored the shit out of my code in a quest to narrow down the bug. i apparently didn't need to do that, but i'm happy with the result :-)

19:16 now i need to figure out why the fuck this predicate is broken

19:16 i'm not using AOT or anything, i don't think

19:16 amalloy: no AOT, no classloader funkiness, no reloading? hard to see how this could go wrong then

19:17 bbloom: amalloy: vim-fireplace doing something funky maybe?

19:17 amalloy: beats me

19:17 bbloom: but (instance? Raise …) genuinely does not work lol

19:17 amalloy: i don't even use nrepl in emacs, so how vim+fireplace over nrepl behaves is entirely foreign to me

19:19 callen: aahhhhh executor service. very good.

19:28 bbloom: amalloy: and now i can't reproduce it

19:28 amalloy: that plus the growling in my stomach means a dinner break is the clear solution to debugging this

19:29 amalloy: bet you a dollar you reloaded but forgot about it

19:29 bbloom: amalloy: i killed the repl & started over several times

19:29 then i moved some code around & it went away

19:29 then i tried to undo back to a point where it was failing, but i couldn't

19:30 brain is clearly failing

19:30 * bbloom goes for food

19:31 eph3meral: anyone know of such a thing as a collection of problems to solve that can or would help illustrate useful examples of macros?

19:32 i.e. where can I learn more about macros - such that I can spot places that might be appropriate to use them

19:32 AimHere: Well if you can translate from Common Lisp, there's Paul Graham's 'On Lisp' which is very macro-centric

19:32 Available as a free pdf or a really expensive out of print rare dead-tree book

19:34 rplevy: eph3meral: the clojure koans project has some macro meditations, though that might not be as many as you might like.

19:34 amalloy: On Lisp isn't really macro-centric; macros are one of several topics that it covers more or less equally

19:35 eph3meral: cool thanks

19:35 AimHere: Beg to differ

19:35 Basically about the entire middle half of the book, from chapters 7-18 out of 25 deal with macros

19:36 And of course subsequent chapters use them to illustrate the advanced stuff later on

19:37 eph3meral: I'm on Ubuntu 13.04 so I'm pretty sure I can find a clisp interpreter somewhere :)

19:38 rplevy: On Lisp is definitely "The Lisp Macro Bible" if there ever was one

19:38 AimHere: Let Over Lambda is the Lisp Macro Book of Mormon

19:38 rplevy: haha

19:39 brehaut: lol

19:40 rplevy: not to offend any actual Mormans here but LoL does raise the insanity levels a bit over its self-ordained prequel, so the analogy is fitting

19:40 LoL meaning let over lambda

19:40 not laughing out loud

19:40 nor Land of Lisp

19:42 microamp: would you recomment 'land of lisp' for a lisp beginner?

19:43 shaungilchrist: I would - or realm of racket :-)

19:44 I think as soon as we come up with a sufficiently clever name for a clojure variant it will appear

19:45 all I've got is "clowder of clojure"

19:45 brehaut: or just clojurebook.com ;)

19:45 we dont need fancy titles or cartoons to have great books about clojure

19:45 microamp: shaungilchrist: thanks, i might get it

19:46 shaungilchrist: converting the exercises/games to clojure is an awesome way to learn once you are familiar with the concepts

19:47 microamp: how about 'learn you a/some x for great good' for clojure?

19:50 rplevy: microamp: I think that was the idea of 'Meet Clojure' which is on hold right?

19:57 benkay: what would the idiomatic way to compute the result of mapping 2 functions on to a set separately?

19:57 would be(

19:57 *

19:58 I want to (map (partial + 1) (partial + 11) #{3 4 5}), but that's not a thing :(

19:59 AimHere: You could just nest the maps, or nest the function call

20:01 ,(map (partial + 1) (map (partial + 1) #{3 4 5}))

20:01 clojurebot: (5 6 7)

20:02 benkay: ,(map (partial +1) (map (partial +11) #{3 4 5}))

20:02 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

20:02 s4muel: ,(->> #{3 4 5} (map (partial + 1)) (map (partial + 11)))

20:02 clojurebot: (15 16 17)

20:02 benkay: ,(map (partial + 1) (map (partial + 11) #{3 4 5}))

20:02 clojurebot: (15 16 17)

20:02 benkay: I want (4 5 6 14 15 16)

20:02 technomancy: "learn you a clojurebook.com for great good"

20:02 AimHere: benkay, map uses the second and subsequent arguments as additional collections to be mapped over

20:02 technomancy: oops; didn't read the backlog

20:03 AimHere: ,(map + [1 2 3] [100 200 300] [1000 2000 3000])

20:03 clojurebot: (1101 2202 3303)

20:03 technomancy: benkay: mapcat juxt maybe

20:03 benkay: technomancy: i think i'll go play with mapcat and juxt for a bit now

20:03 thanks all

20:10 futile: Hello.

20:13 seancorfield: Hi futile

20:13 futile: How goes it seancorfield?

20:14 seancorfield: Just back from a week's vacation and catching up on tickets at work... and writing some Clojure of course :)

20:14 futile: Hoorah.

20:14 You don't have Labor Day off?

20:14 I thought this was a national holiday and you were in US.

20:15 ddellacosta: seancorfield: what logistical stuff do I have to go through to contribute to clojure.java.jdbc?

20:15 futile: Wow, that was a rude thing of me to say, sorry.

20:15 ddellacosta: is that packaged with Clojure?

20:16 ddellacosta: seancorfield: would like to help out with some DSL stuff, if possible.

20:16 futile: nope, but it's managed by the core team I think

20:16 futile: Oh.

20:27 brainproxy: generic term for things being compared?

20:28 comparands doesn't seem to be a word ore really fit the bill

20:28 *or

20:28 futile: i know that a comparator is something used to compare

20:28 brainproxy: "compared objects" is going the right direction, but would prefer a simple term

20:28 futile: comparatee?

20:28 let me see what NSArray calls it

20:29 heh it just calls them "objects"

20:31 brainproxy: :)

20:31 futile: "comparable"

20:32 "comparative" might be a stretch

20:33 brainproxy: "contrastitee"

20:36 Well, I just finished moving all my projects to Dropbox. Switching betwixt two computers is too painful otherwise.

20:36 hyPiRion: I really like git repos for that purpose

20:41 yogthos: xeqi: re: unit tests in the book, I just introduce core.test mostly and mention a couple of ring specific test libs

20:42 futile: hyPiRion: my git repos are inside Dropbox now :)

20:42 hyPiRion: needing to git push and then switch computers and git pull is so tedious otherwise

20:44 Wow, the latest version of magit is kind of weird.

20:44 seancorfield: sorry, got busy with a repl connected to production, doing some data detective work futile and ddellacosta

20:44 ddellacosta: seancorfield: no worries, of course.

20:45 futile: seancorfield: heh I've done that several times already in this short year

20:45 seancorfield: futile: re: Labor Day - my employer has a very flexible PTO schema so i can choose not to take public holidays off and work instead - and then take vacation when i actually _want_ to!

20:45 futile: seancorfield: what an awesome employer. Who are they?

20:45 seancorfield: ddellacosta: to contribute to java.jdbc - sign & submit your Contributor's Agreement, get on clojure-dev, get a JIRA account, get a github account

20:46 basically read http://dev.clojure.org/display/community/Contributing

20:46 ddellacosta: seancorfield: contributor's agreement is: http://clojure.org/file/view/ca.pdf ?

20:46 seancorfield: futile: World Singles... internet dating :)

20:46 futile: seancorfield: is that process meant to raise the bar on contributions or something?

20:46 ddellacosta: seancorfield: ah, okay

20:46 seancorfield: thanks for the links! Will do.

20:47 seancorfield: ddellacosta: background reading http://clojure.org/contributing

20:47 ddellacosta: seancorfield: excellent. Will read up and follow-up. Thanks for all the info.

20:47 benkay: so, blackjack. this function takes in a sequence of cards ([[1 :hearts] [3 :clubs] [:king :diamonds]], for instance) and returns a list of numbers representing the possible scores. except that for some reason it's blowing up on ace cards, and i'm out of ideas as to why.

20:47 http://paste.lisp.org/display/138742

20:48 futile: oh man, ive never written a card came before

20:48 benkay: any suggestions (including those of the idiomatic type) are very welcome

20:48 futile: that sounds like a fun project for FP

20:48 benkay: futile: i'm definitely enjoying it. learning piles while working through the implementation. stuck on this thing though.

20:49 futile: benkay: well with the little details you've given, I can't figure it out. Maybe use refheap.com?

20:49 benkay: futile: http://paste.lisp.org/display/138742

20:50 and since you ask: https://www.refheap.com/18244

20:51 xeqi: yogthos: ring specific like ring-mock?

20:52 yogthos: https://github.com/xeqi/peridot and https://github.com/xeqi/kerodon

20:52 futile: benkay: I would probably split that up into several small obvious functions for starters

20:52 yogthos: xeqi: weavejester mentioned those

20:52 futile: But like I've said, I never did a card game before; maybe this kind of complex function can't be broken down any further. But I doubt it.

20:53 xeqi: yogthos: hehe, awesome

20:53 futile: benkay: one simple thing that would definitely make it more readable is to use destructuring

20:54 benkay: futile: that's a thing i'm not good at yet :)

20:54 dissipate_: seancorfield, does your employer let you use clojure at work?

20:54 futile: benkay: which one?

20:54 benkay: futile: destructuring

20:55 futile: benkay: ah let me take a stab at it

20:55 benkay: Also try to prefer working with lazy sequences instead of using (loop)

20:55 seancorfield: dissipate_: we've had clojure in production for two years

20:56 futile: Aye, us too.

20:56 s4muel: benkay: you've an error in mapcat -- should be (mapcat (juxt (partial + 1) (partial + 11)) scores))

20:57 seancorfield: we have about 14.5kloc of production clojure and just over 3.5kloc of test code

20:57 futile: benkay: can you give me some sample inputs and outputs for this function? That'll help me easier.

20:57 benkay: thanks s4muel!

20:58 futile: [[3 :aces] [4 :diamonds] [:queen :clubs] [:ace :hearts]]

20:58 dissipate_: seancorfield, i see. you are lucky to work at an FP shop. :D

20:59 futile: benkay: those are inputs?

21:00 benkay: futile: that'd be a single input

21:00 futile: benkay: and what would the output for this input be?

21:01 benkay: (score-hand [[3 :aces] [4 :diamonds] [:queen :clubs] [:ace :hearts]]) => ???

21:01 lazybot: futile: Oh, absolutely.

21:01 futile: lazybot: smartass

21:01 benkay: (18 28)

21:01 futile: Okay.

21:01 benkay: futile: (18 28)

21:02 s4muel already found my bug, but I have a different question for you on the topic of destructuring, futile

21:02 given that sequence of vectors, how would you go about constructing a new local containing all of the first items in each entry?

21:02 futile: benkay: logically speaking, how do you get [18 28] from this input?

21:03 benkay: 3 + 4 + 10

21:03 = 17

21:03 then + 1 and + 11

21:03 in blackjack, aces can count as either 1 or 11

21:03 TEttinger3: Raynes or amalloy, if you're around, do you know how on earth lazybot's rss plugin works? I can only seem to find unreadable feeds

21:03 benkay: and face cards count as ten

21:04 futile: benkay: how is [3 :aces] a valid card?

21:04 I've never heard of "3 of aces" before

21:04 benkay: futile: mistake on my part.

21:05 futile: benkay: what should :aces be, :hearts?

21:05 benkay: anything. irrelevant for scoring.

21:05 futile: ok

21:05 seancorfield: dissipate_: our front end is CFML, our back end a mix of CFML and Clojure... just FYI (re: "lucky")

21:05 TEttinger3: cfml is coldfusion?

21:06 futile: benkay: so [[3 :spades] [4 :diamonds] [:queen :clubs] [2 :hearts]] would produce only [19] ?

21:06 seancorfield: cfml is the language, coldfusion is adobe's commercial implementation, but we use railo a free open source engine

21:06 benkay: futile: yup!

21:07 futile: benkay: Ah, tricky, so for every ace you have, you double the numbers of results you could have, kind of like a factorial (I think)

21:07 benkay: futile: precisely.

21:07 futile: benkay: are the suits really completely ignored?

21:07 benkay: i believe so

21:08 futile: benkay: then that's the first thing to do, build a new structure that eliminates them, since they're just noise.

21:08 benkay: i think they're relevant during a push to determine the winner of a tie

21:08 nope, incorrect.

21:12 dissipate_: seancorfield, i thought cold fusion was old stuff from the '90s?

21:13 seancorfield: dissipate_: adobe release version 10 a while back; railo's project is on 4.x; the language has evolved a lot... it's a js-like OO scripting language that compiles on demand to JVM bytecode now

21:13 benkay: futile: incorrect referred to my statement, not your suggestion about a new structure.

21:13 futile: benkay: right

21:13 seancorfield: dissipate_: it even has closures... unlike java :)

21:15 dissipate_: seancorfield, and what is the app?

21:16 seancorfield: an internet dating platform... 50+ sites, a dozen languages (including RTL such as arabic), about 4M users

21:16 Raynes: TEttinger: Apparently it doesn't work. :P

21:17 TEttinger: Raynes, could it be some change in xml or zip libs?

21:17 Raynes: TEttinger: Well, it was never exactly the best feed reader ever to begin with, but sure, that's also plausible.

21:18 amalloy: benkay: that problem is trickier than it looks. i don't love my solution, but https://gist.github.com/amalloy/e3368747b399e83b91d6 will work

21:18 Raynes: amalloy: '((((((((())))))))

21:18 dissipate_: seancorfield, i see, cool. can't say i'm interested in that kind of app. but if it makes money, right on.

21:19 seancorfield: internet dating is an interesting business dissipate_ and we are happily profitable :)

21:19 futile: benkay: well, what I came up with actually didn't use any destructuring

21:19 so that's weird

21:19 seancorfield: (and have been around for well over a decade now)

21:21 benkay: futile: care to share?

21:21 dissipate_: seancorfield, and look at you, you probably have direct access to the databases with all those female profiles. :P

21:21 futile: benkay: https://www.refheap.com/18246

21:23 benkay: that combinations function probably just needs https://github.com/clojure/math.combinatorics

21:23 seancorfield: dissipate_: and happily married for 14 years to someone i met online (on usenet, not a dating site!)

21:23 futile: I'm no math wiz.

21:24 benkay: thanks futile! someday i'll write code like that.

21:24 Raynes: seancorfield: Usenet isn't a dating site?

21:24 You just rocked my existence, Corfield.

21:24 futile: benkay: you can start today, just a matter of memorizing patterns

21:25 benkay: I'm a cheater, all I do is copy other people's code.

21:25 dissipate_: futile, cargo cult programming?

21:26 futile: probably

21:26 "hey ->> works for him, i should use it too"

21:27 benkay: amalloy: that's a groovy approach as well

21:27 seancorfield: Raynes: well, I guess some Usenet groups acted as dating "sites" :) Jay & I met in rec.art.bodyart ... go figure ...

21:28 benkay: amalloy: futile: thanks for the examples!

21:29 TEttinger: Raynes, I don't personally use RSS feeds, but one channel my lazybot is running in could use announcements when new things come in from an RSS feed. could the notifo plugin help?

21:30 oh nope. notifo is dead and gone

21:31 amalloy: notifo sounds like it's related to core.logic negation support

21:32 TEttinger: heh, it's a startup that lasted one whole year

21:36 bja: a year is a long time

21:37 futile: benkay: sure thing

21:46 dissipate_: TEttinger, why did notifo go under?

21:46 Raynes: amalloy: I figured out how to easily do the pebble-notifies-me-of-irc-pings thing.

21:46 TEttinger3: not sure

21:47 Raynes: amalloy: There is an email address you can send an email to that triggers a text message on your phone. I can add a lazybot plugin to send out emails when certain things are mentioned on IRC.

21:47 ?????

21:47 profit!

21:47 Obviously this only works in channels where lazybot is, but most of the channels that I care about are lazybot-enabled.

21:49 futile: so, is it rude to use "brotastic" as an exclamation?

21:49 mtp: bros are rude in general

21:49 so yes

21:49 futile: aww

21:50 that's not very brotastic :(

21:50 holo: hi

21:50 Raynes: futile: As a bro I can confirm that mtp is not a bro. Bro.

21:51 holo: hei, where are seq-utils?

21:52 from contrib

21:54 juliangindi: I have a list of numeric strings like such '("2" "5" "6") and want to convert it into a vector of true integers, ie. [2 5 6]. Any ideas on how I could do this?

21:55 aaelony: (map #(Integer. %) '("2" "5" "6") )

21:55 juliangindi: aaelony: DUH. That would surely do it. Thanks :)

21:56 aaelony: sure, np… also(into [] (map #(Integer. %) '("2" "5" "6") ))

22:02 cjfrisz: dnolen bbloom: Can one of you CLJS compiler hackers explain this one to me? https://gist.github.com/cjfrisz/94ba0f606d11a702a18f

22:03 juliangindi: just figured out the original list did not have three separate numeric strings, but one string containing three numbers, such as "2 5 6"…any ideas on how to take those apart and form a list with three elements as opposed to one

22:03 dnolen: cjfrisz: that's blowing up at the top level? or are you nesting your #()

22:04 bbloom: dnolen: heh, i was literally about to ask that

22:04 cjfrisz: dnolen: top level

22:04 aaelony: ,(doc clojure.string/split)

22:04 clojurebot: "([s re] [s re limit]); Splits string on a regular expression. Optional argument limit is the maximum number of splits. Not lazy. Returns vector of the splits."

22:04 dnolen: cjfrisz: is this browser REPL or compiled file?

22:04 cjfrisz: dnolen bbloom: do you think this is a game?? of course it was top level!

22:04 ;-)

22:04 dnolen: Compiled file

22:05 dnolen: cjfrisz: hrm, I do stuff like that all the time and haven't encountered it, would be helpful to see a minimal project that repros

22:06 bbloom: i'm gonna leave this one to dnolen, b/c i'm trying to end my marathon debugging session

22:07 cjfrisz: dnolen: weird...

22:08 dnolen: if it helps, proto/render! is a call to a function declared in a protocol

22:08 I guess I could put together a trivial project that does that

22:08 dnolen: cjfrisz: can't see how that would matter we don't do anything to special with protocol fns at CLJS source level

22:09 cjfrisz: dnolen: Well then that's weird, because I don't know how that could expand into a #() within that expression

22:10 dnolen: cjfrisz: yes, I can't reproduce this situation at REPL at all. You only get that error if you have multiple nested #()

22:11 TEttinger3: Raynes, I solved it. the API for shorten-url changed in lazybot, just removed the second param, "isgd" which isn't needed, and it workjs

22:13 bbloom: cjfrisz: #() is resolved at read time…. i think

22:14 brehaut: ,(read-string "#(%1)")

22:14 clojurebot: (fn* [p1__31#] (p1__31#))

22:14 dnolen: cjfrisz: what version of CLJS are you pulling in?

22:15 bbloom: cjfrisz: yeah, what brehaut said ^^

22:15 cjfrisz: do you have another # anywhere else in the file? :-P

22:15 cjfrisz: maybe your scheme is showing....

22:15 cjfrisz: dnolen: I'm using [org.clojure/clojurescript "0.0-1859"] in my project.clj

22:15 bbloom: I actually don't use #() that much because it hurts my scheme :-)

22:16 bbloom: I only had one other #() expression in my whole repo, changed it to a fn and the same thing happens

22:16 dnolen: cjfrisz: k, pretty recent

22:16 bbloom: cjfrisz: i didn't say #() i said #, just hash. like any tagged literals or #t typos or anything?

22:17 cjfrisz: bbloom: haha, that is often the case, but not this time

22:17 I have had several compiler errors on #t in my code

22:17 bbloom: cjfrisz: it's hard to switch languages :-P

22:20 maacl: dnolen: Are there any plans to implement everyg in core.logic for ClojureScript?

22:20 cjfrisz: bbloom dnolen: Seem to have stamped it out, but I'm super weirded out

22:20 Hang on…need to pull up the file I changed to fix it

22:21 dnolen: maacl: I'd take a patch, but I'm fairly lukewarm about moving core.logic ClojureScript along until there's better support for sharing more code.

22:21 cjfrisz: you might have hit a tools.reader bug (which is what bbloom was alluding to above)

22:22 cjfrisz: if you can repro that would be super helpful and we can ping Bronsa about it.

22:24 cjfrisz: dnolen bbloom: it cleared up when I changed this to a fn https://github.com/cjfrisz/chaser-cljs/blob/gradual-typing/src/cljs/chaser_cljs/game_env.cljs#L81

22:24 That's in a different file altogether

22:24 bbloom: lol strange

22:25 cjfrisz: Indeed

22:25 The js/setInterval from the gist doesn't even call that code

22:26 dnolen: cjfrisz: sounds like a reader bug to me

22:26 cjfrisz: The code that I changed to fix it gets called at startup and occasionally as a result of keydown event

22:29 dnolen bbloom hold up…maybe I didn't build correctly

22:29 Looks like even if I take out every #() in my code except the one for the js/setInterval call, I still get the nested #() error

22:30 kab3wm: gfredericks: not sure if you are still around, earlier you looked at this paste (http://pastebin.com/ZFJiGgvD) for me and asked if it was returning a lazy seq. I said no. It is, but I didn't understand the issue earlier. Do I need to not make it return a lazy seq somehow, or how do I handle this?

22:30 cjfrisz: Oh…wait I'm an idiot

22:30 dnolen bbloom disregard, it was user error

22:31 bbloom: *sigh* what happened?

22:31 cjfrisz: I found where I snuck another #() in there, and it was totally nested

22:31 It is a game and I have shamed my family and everyone I've ever known

22:31 bbloom: cjfrisz: i'm genuinely curious how you pulled that off

22:32 dnolen: cjfrisz: good to know not a reader bug

22:32 cjfrisz: I wrapped an init expression in a # and didn't notice it

22:32 It slipped my notice until the 3rd or 4th time I checked grep

22:32 bbloom: cjfrisz: sooo grep failure. got it lol

22:32 dnolen: bbiab

22:35 gfredericks: kab3wm: easy answer: wrap it in doall; my preferred answer: don't use e.g. map for side effects; use doseq instead

22:35 in general don't mix laziness and side effects

22:36 kab3wm: gfredericks: got it. thank you!

22:40 cjfrisz: bbloom: current status http://www.hark.com/clips/xmcydyzdrb-survey-says

22:40 bbloom: cjfrisz: eh, we've all done dumber :-)

23:01 maacl: dnolen: Ok, I will look into it, but as you say looks rather involved.

23:02 Ph_D: Does anyone have knowledge on the Friend authentication library? I'm having serious trouble getting the "interactive-form" to function.

23:05 Scratch that— I'm going to investigate further with login-failure functions.

23:08 ddellacosta: Ph_D: I know a bit, if you ask a question I may be able to help.

23:16 xeqi: Ph_D: I've used it

23:17 Ph_D: ddellacosta & xeqi: Well, there are three things so far I've found that are required to make this work: 1) A way to encrypt and compare passwords, 2) Middleware for adding form fields as keywords into the :params part of the request, 3) a properly structured map of users. I seem to meet all of these requirements, but I can't seem to log in whatsoever. It fails consistently.

23:22 Trying to be succinct: I've tested the Bcrypt functions in the REPL (with database calls), my middleware is adding form fields to the :params correctly (so says my (println response) in the form-failure-handler), and I've tried two users maps: '{:username "admin" :password "pass"}' and '{"admin" {:username "admin" :password "pass"}}'.

23:25 xeqi: Ph_D: and your :credentials-fn is something like (partial bcrypt-credential-fn (fn [name] (@users name))) ?

23:30 callen: Ph_D: it's usually not worth the trouble

23:30 Ph_D: Yes, it's: (partial bcrypt-credential-fn (get-user "admin"))

23:30 (get-user "admin") returns from Redis:

23:30 {"admin" {:password "<long bcrypt hash>", :username "admin"}}

23:30 I've also tried it without the nested hash:

23:30 {:password "<long bcrypt hash>", :username "admin"}

23:30 xeql: ^

23:30 callen: Ph_D: please don't paste code to the channel unless it's a one-liner. Use refheap.

23:30 Ph_D: callen: will do

23:30 callen: Ph_D: unless you've got a complicated security/auth situation, Friend isn't typically going to win you more than it costs you.

23:31 Ph_D: callen: that's why I'm learning it. It's an experience.

23:34 xeqi: Ph_D: you'll want it to return the {:username .. :password ..} version

23:35 does `((partial bcrypt-credential-fn (get-user "admin")) {:username "admin" :password "..."})` work on a repl?

23:35 though I doubt the "admin" should be hardcoded in the get-user call

23:37 Ph_D: xeql: It does, yeah. I'm only hardcoding it so far for testing purposes before I switch it out for a proper function.

23:42 xeqi: Ph_D: then it looks like 1+3 are working correctly. For 2, are you using wrap-params and wrap-keyword-params, a form that adds "username" and "password" parameters, and friend's `authenticate` with `:workflows [(interactive-form)]`?

23:43 Ph_D: xeql: I'm using compojure's (handler/site), which adds those and then some. I've seen working examples that do the same.

23:43 xeqi: yep, thats sufficent for the middleware stack

23:43 provided its like (-> routes (friend/authenticate ...) ... (hiccup/site) ..)

23:44 hfaafb: are loops a code smell

23:47 Ph_D: It's all laid out like that (I'm assuming you meant (handler/site)), yeah.

23:49 Oh, wow. Okay, does my use of http-kit as my server make a difference? This could be what's holding me back.

23:49 SegFaultAX: hfaafb: No.

23:51 coventry: "lein pprint" lists [org.clojure/tools.trace "0.7.6"] in the :dependencies, "lein classpath" lists the jar path, but (require 'tools.trace) fails in "lein repl" with "Could not locate on classpath." Any ideas why that would happen?

23:52 xeqi: coventry: (require 'clojure.tools.trace) ?

23:59 benkay: how would I defer the evaluation of <?

23:59 I want to (every? (< n) [x y z]), but no ams success.

Logging service provided by n01se.net