#clojure log - Nov 06 2013

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

0:00 jared314: hfaafb: vec works the same as apply vector, but the source looks very different. What is it doing?

0:03 hfaafb: is there a reason you can't do (vector ...) instead of concat? concat returns a lazy seq

0:03 jared314: i'm not an expert but my first guess is its dropping to java for performance

0:12 devn: logic_prog: (apply vector 1 2 3 '(4 5 6)) won't work.

0:13 logic_prog: ,(apply vector 1 2 3 '(4 5 6))

0:13 clojurebot: [1 2 3 4 5 ...]

0:13 logic_prog: ,(apply vector 1 2 '(3 4))

0:13 clojurebot: [1 2 3 4]

0:13 logic_prog: devn: ^ :-)

0:13 devn: weird

0:13 my repl was out of order for a second. i was having a mini clojure crisis.

0:14 logic_prog: anyway, yes, vec only takes one argument -- a collection

0:18 logic_prog: could you explain what you mean by: "is a list still constructed in between"?

0:19 logic_prog: (apply vector 1 2 3 (concat .... ))

0:20 I think (concat ... )) constructs a _list_, then we make it a vector

0:20 I'd prefer to just create a vector without the intermediate list

0:20 jared314: i thought concat was lazy

0:20 timsg: it is

0:23 devn: You could follow the pattern in mapv, filterv, etc. I think

0:23 abaranosky: hey dudes, anyone got a good setup in their Emacs to nicely M-. (or equivalent) into Java code?

0:24 devn: hola -- i have never really set that up

0:24 i had it once, for like a day

0:24 technomancy: logic_prog: into maybe

0:24 abaranosky: devn: I know, noone does, be it is handicapping me I decided

0:24 I love `into`

0:24 devn: technomancy: yeah that's basically the mapv/filterv abstraction

0:24 well not really, but it's close

0:25 the use of transient and persistent!

0:25 abaranosky: (into [1 2 3] more-stuff)

0:27 devn: curiously -- (vector 1 2 3 '(4 5 6)) looks to be faster than (into)

0:29 (vector 1 2 3 (concat 4 5 6)) looks fine performance-wise, maybe even better

0:29 (class (concat 4 5 6))

0:29 logic_prog: i think what you're doing is fine and nothing to get worked up over

0:30 use the lazy-seq intermediate with confidence

0:31 i guess my personal answer is: if you're asking whether there's something faster -- you could build one or tinker a lot to find the best one for the inputs you're handling, but i think what you're doing is just fine and nothing to get worried about

0:32 mercwithamouth: i'm trying to include monger in a project. i ran lein repl after including the dependency but i'm not sure how you would go about using it? https://www.refheap.com/20510

0:33 :use should be ':require' by the way..sorry

0:33 devn: mercwithamouth: did you run `lein deps`

0:33 mercwithamouth: devn: yup

0:33 it pulled the dependencies but i'm obviously not importing them right =(

0:34 devn: What you're doing looks reasonable to me, but I don't often work from lein repl.

0:34 mercwithamouth: devn: nprel???

0:34 lazybot: mercwithamouth: How could that be wrong?

0:35 devn: mercwithamouth: yeah

0:36 mercwithamouth: switching over from light table...one sec.

0:38 devn: mercwithamouth: oh, found your problem maybe

0:39 mercwithamouth: defproject jackals -- ns jackal.db

0:39 mercwithamouth: is your file in src/jackals/db.clj maybe?

0:40 mercwithamouth: devn: yeah

0:44 devn: were you saying i need to add that namespace to defproject?

0:49 devn: mercwithamouth: if you were in light table im not sure how it all works

0:49 technomancy: your project name doesn't have to match your namespace names

0:49 devn: but it looked weird to me that you're project's name...

0:49 what technomancy said

0:50 technomancy: unrelated, but are you stuck with mongodb?

0:50 mercwithamouth: ahh oops...sorry the projectname is lyingassjackals as the rest of it is. i think i accidentally cut that off when pasting.

0:50 technomancy: not at all....datomic?

0:50 i was just going to play with it since i was somewhat familiar with mongo

0:50 technomancy: mercwithamouth: no, I can't say I'd recommend single-vendor lock-in, but you can do better than mongo

0:51 mercwithamouth: do tell...throw something at me.

0:51 i'm making a very small app that lets you like or dislike images.

0:51 technomancy: postgres is always a reasonable default

0:51 riak if you need HA above all else

0:52 mercwithamouth: i almost chose redis since it's going to be a simply key/value type deal.

0:52 ..and my redis book is sitting here unused, lol

0:52 technomancy: the new json column type in postgres 9.3 lets you do all kinds of schemaless stuff with it

0:52 mercwithamouth: hmm i'll take a look see

0:52 technomancy: well, if you don't need durability at all redis is nice

0:53 mercwithamouth: yeah this is a toy app for friends to mess around

0:53 no serious data

0:53 carmine?

0:57 devn: mercwithamouth: if this is just a hobby app I recommend redis or riak.

0:58 mercwithamouth: the simplest thing is probably redis

0:58 mercwithamouth: devn: redis it is

1:10 weird..can't get emacs to open to save my life even after a reboot. this is a sign...back to light table.

1:11 technomancy: can't get it to even open?

1:11 mercwithamouth: not until i talked trash about it just now =)

1:11 bitemyapp: devn: howdy!

1:12 devn: nice seeing you :)

1:12 technomancy: that's a new one

1:13 mercwithamouth: yeah i used emacs for months...with no problems. like even now...nrepl doesn't seem to want to kick in.

1:13 i'm sure it's something i did personally without thinking.

1:14 devn: bitemyapp: hola

1:17 bitemyapp: devn: cbp finished the RethinkDB driver for Clojure

1:17 devn: released it last weekend! http://github.com/bitemyapp/revise/

1:17 I'm working on open sourcing a migration toolkit for Datomic. Also thinking about a lock-free resource-pool library for Clojure

1:17 devn: how are you?

1:23 devn: well, thanks

1:23 bitemyapp: cool

1:24 bitemyapp: datomic is pretty great

1:30 mercwithamouth: well now it's working with light table.

1:30 you guys still don't like mongodb though do you? =P

1:32 jared314: mercwithamouth: restarted lighttable?

1:33 mercwithamouth: jared314: rebooted. emacs is still acting funny but to be honest my shell is acting crazy in general tonight. i'll go back and pull a previous version later on. i must have broken something earlier

1:34 yeoj___: is there anyway to eval a symbol to it's value? I was thinking unquote would do that.

1:36 jared314: yeoj___: well, eval would do it. :)

1:36 jebberjeb: yeoj___ : eval

1:37 devn: yeoj___: do you have some example code with expected input & output?

1:39 yeoj___: well, i guess this https://www.refheap.com/20512

1:40 jared314: why are you using keywords like that?

1:40 yeoj___: i'm trying to have a sort of configuration file, and i wanted to make it so the user could just type in the base-name, and then i would eval that into other things

1:40 but i'm pretty sure it's not the right way.

1:41 devn: yeoj___: what do you want to come out of this on the other side?

1:42 (my-function-thingy (read-string (slurp "file.clj")))

1:42 => ...

1:42 yeoj___: devn: ok, i'll try that.

1:43 devn: yeoj___: nono, im asking you what you hope to accomplish here

1:43 You want a configuration file that's read as a clojure datastructure, right?

1:43 yeoj___: devn: i want to have a configuration file, and based on "base-name" other things get "defaulted" in the config file. but give the user an option to type in things to override/etc.

1:44 devn: i was thinking a clojure data structure would be good.

1:44 devn: yeoj___: you can do a lot of other things

1:44 yeoj___: try (read-string (slurp config.clj)) -- have the user write a plain clojure map with keywords in it

1:45 yeoj___: i want a param file, that can reference params already in itself... (i.e. base-name)

1:45 devn: so the file looks something like {:foo "bar" :baz "qux"}

1:45 yeoj___: and that got me thinking of string templating, but i'm sure lisp-ish stuff has a better way

1:45 devn: yeoj___: if you want templates there are lots of options

1:45 but frankly, you can just use a map for this kind of thing

1:46 idk, experiment with it and see where you and up

1:46 yeoj___: devn: ok. thanks.

1:48 devn: this is a better example: https://www.refheap.com/20512

1:48 i think i might need templating.

1:49 jared314: leiningen does something like that with project files

1:50 yeoj___: ah right. with a defproject.

1:50 jared314: but i think they do something with macros

1:50 yeoj___: so i think i could do it with a let binding, but i'm not sure if i could do it with a straight map.

1:50 jared314: to make it work

1:55 devn: yeoj___: im still a little confused. You have :db-spec {... :subname (str "//localhost:5432/test") ...}

1:55 why do you call str there?

1:56 it looks like in the other cases you're wanting to use :base-name like it's a passed in value

1:56 to which I say: why don't you just use a function to return the configuration map?

1:56 jared314: devn: in project.clj files you can use ~ to eval code in the project configuration

1:56 devn: he wants that

1:57 devn: jared314: im not sure that's it

1:57 yeoj___: devn: i guess i don't want to have str in there... thats here i was trying to quote/unquote to get :base-name to resolve later on.

1:57 devn: i'm thinking i'm just going to have one let binding in a seperate file called config.clj, and slurp/eval that

1:58 devn: yeoj___: up to you, but I personally recommend just keeping it simple unless you actually need to do this for some reason

1:59 yeoj___: devn: ok. I had convention over configuration stuck in my head.

1:59 i.e. you give me the "base-name" of the program-run and i'll suggest the output file, the log file, the temp file, etc...

1:59 devn: yeoj___: i understand the desire, but frankly, think about a database.yml

1:59 test, production, development

1:59 sometimes a staging

2:00 there's a shorthand for inheriting from a base template

2:00 but that template is just a map under the covers

2:00 so just make a function that does that for a base config map you specify

2:00 and read in the user's map and merge it

2:00 or something like that

2:00 yeoj___: devn: ok, that makes sense i think.

2:01 devn: yeoj___: im just saying i really don't think you need to get into a whole templating dependency to support user config in a nice approachable way

2:01 yeoj___: you could always have a default config file: default.clj: {:default-option-1 "abc" ...}

2:02 and then just merge it with the user's map read from custom.clj: {:default-option-1 "not abc"}

2:02 yeoj___: devn: ahh, ok. I think maybe my idea is it's a bit more than a config... or will be at somepoint.

2:02 devn: i'll try a simple map for now, leave out the merging, and look into templating.

2:03 devn: i guess i'm curious about when templating overlaps with a proper dsl also...

2:03 devn: yeoj___: im not trying to tell you it's a bad idea -- i just am raising an eyebrow because it seems like a lot of trouble for not a lot of value

2:04 yeoj___: the merging seems like a nice way to achieve what it sounded to me like you were looking for

2:05 yeoj___: devn: ok, i'll give that a shot.

2:05 devn: which is the ability to have some defaults which the user can override

2:05 but to not make them override or configure /all/ of it

2:05 to just let them pick and choose what they want to edit

2:05 which could itself be a simple set of defaults

2:06 the user can change them or not

2:06 yeoj___: devn: i guess the merge is straight forward as well...

2:07 myguidingstar: hi all, what's the best practices to see source of a multimethod in REPL

2:12 muhoo: wow i've gotten into a habit of using reduce intead of loop. not sure if that's a good habit tho

2:12 mercwithamouth: hah so fish is what broke everything

2:13 Apage43: muhoo: mayhaps its a stepping stone to clojure.core.reducers/fold

2:13 muhoo: well yeah if i needed that kind of parallelism

2:14 bitemyapp: muhoo: that's proper dude.

2:14 muhoo: learning you don't need loop/recur and can get by with plain old folds is the golden path to FP.

2:14 muhoo: this just looks so ugly https://www.refheap.com/20513

2:15 i mean, yecch

2:15 loop would probably be clearer, since i'm abusing the accumulator there

2:15 bitemyapp: muhoo: haha, no, that's fine.

2:16 muhoo: man...you should see some of the code I wrote recently at work...that's nothing :)

2:16 8-deep nested reductions, multiple-layers-deep accumulators...

2:16 * bitemyapp cackles maniacally

2:16 Apage43: partition might be handy here

2:16 bitemyapp: muhoo: http://i.imgur.com/WwterpW.gif you're fine.

2:17 Apage43: ,(partition 2 1 [1 2 3 4])

2:17 clojurebot: ((1 2) (2 3) (3 4))

2:17 bitemyapp: Apage43: nice!

2:17 muhoo: ^^ :)

2:18 going to have to keep that in mind the next time I encounter overlap.

2:19 muhoo: cool, but i don't like hairy code

2:19 Jarda: hmm

2:19 muhoo: always feels to me like i haven't simplified it enough. when i was young i was proud of incomprehensible bullshit. now it makes me deeply uncomfortable

2:20 bitemyapp: muhoo: well Apage43 just showed you how to simplify it.

2:20 Jarda: anyone aware of a way to make a testing library (cucubmer in this case) output string diffs in assertion output

2:21 muhoo: bitemyapp: Apage43: ah i see, nice. make 'em into pairs. will try that

2:21 mercwithamouth: hmm can anyone explain this error to me? http://d.pr/i/EGEM

2:22 Apage43: ,{:a 1 :b 2}

2:22 clojurebot: {:a 1, :b 2}

2:22 bitemyapp: muhoo: if your data makes your code ugly, then unfuck da data! :)

2:22 Apage43: ,{:a 1 :b 2 :c}

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

2:23 amalloy: mercwithamouth: {<pool>} is rubbish

2:23 er, {<opts>}

2:23 muhoo: Apage43: huge improvement, thanks.

2:23 Apage43: cool :)

2:23 mercwithamouth: amalloy: do tell? i'm toying with the example and admittingly i had no clue what that portion did.

2:23 * mercwithamouth removes it

2:23 amalloy: it's...pseudocode you included in your actual code

2:23 which reasonably enough does not parse

2:24 bitemyapp: mercwithamouth: what...is with the pseudocode...

2:24 mercwithamouth: where's your book?

2:24 mercwithamouth: o_O;

2:25 * mercwithamouth opens redis book

2:25 mercwithamouth: fine fine! =)

2:25 bitemyapp: mercwithamouth: http://www.clojurebook.com/

2:26 Apage43: man

2:26 that thing's readme is telling folks to write macros? :(

2:26 mercwithamouth: Apage43: yes carmines docs are beginning to scare me

2:26 but it's supposedly a great library

2:27 bitemyapp: i have that as well...doesn't cure my redis fogginess

2:27 bitemyapp: Apage43: I stopped recommending pt-too-many-fucking-vowels-nis' libraries.

2:27 I still use timbre but I've got a jaundiced and blood-thirsty eye pointed at it.

2:27 ddellacosta: bitemyapp: why?

2:28 bitemyapp: ddellacosta: global singleton resources for no good reason, crazy fucking macros for no reason, documentation recommends bad practices.

2:28 Don't get me wrong, you can "get things done" with his stuff. His is the best redis library for Clojure

2:28 but my god the code is disconcerting to me at times.

2:29 ddellacosta: bitemyapp: okay, thanks for the feedback. Will review. I've felt like timbre was pretty easy to use, and I like the appenders, but I haven't dug too deeply into the codebase.

2:30 bitemyapp: ddellacosta: yeah...if you take a look at timbre's codebase....

2:30 ddellacosta: I like the appenders too...but the underlying code...

2:30 ddellacosta: it is pretty macro-tastic, scanning it now.

2:30 bitemyapp: macro-tastic is a good word for it.

2:30 ddellacosta: did you see that revise got released?

2:31 ddellacosta: cbp picked it up and wrote 90% of the library, there's a RethinkDB client for Clojure now.

2:31 ddellacosta: bitemyapp: nope, but not really in the market for a RethinkDB client

2:31 bitemyapp: don't get me wrong, that's pretty cool though. :-)

2:31 bitemyapp: ddellacosta: oh I know you're not likely to become a user, but look at the API! github.com/bitemyapp/revise/

2:31 ddellacosta: woah, what is this dealy: https://clojars.org/revise/latest-version.svg

2:32 bitemyapp: ddellacosta: magic that prevents me having to change the READMEs ever again.

2:32 ddellacosta: bitemyapp: pretty neat

2:32 bitemyapp: ddellacosta: my primary contribution was the connection lifecycle. I made it async, lock-free, and more efficient than most database connection implementations.

2:33 ddellacosta: I'm really happy with it. It's also inspired me to think about possibly writing a generic resource pooling library for clojure.

2:33 a lock-free one. possibly based on ring buffers.

2:33 ddellacosta: running a query just returns a promise that you deref.

2:33 ddellacosta: bitemyapp: would be interested to see that. We use pgpool w/postgres so wouldn't have much use for it...but it would be good to separate it out in any case

2:34 bitemyapp: that is neato

2:34 I like the query api

2:34 bitemyapp: and the connection can perform work while waiting on an arbitrary number of query results, it doesn't block the whole connection like most implementations.

2:34 ddellacosta: the brilliant query API is all cbp. :)

2:34 mercwithamouth: ahhh how reading the code you use works wonders o_O

2:34 ddellacosta: bitemyapp: congrats. :-)

2:34 bitemyapp: mercwithamouth: think. read. design. Don't play bumper cars with your code :)

2:34 ddellacosta: thanks :D

2:35 "Uhm backtraces" very confidence building commit message cesar.

2:41 muhoo: what are you talking about? half my commit messages are "doh!"

2:42 alright fine, that's on private branches, and i merge --squash those before anyone sees 'em, but still

2:43 bitemyapp: muhoo: that was pushed straight to master. I'm equally guilty, I just found it amusing :)

2:47 muhoo: huh, that trick for overlapping partition was in my notes, from 4/10/12. had totally forgotten about it.

2:48 year and a half ago :-/

2:48 bitemyapp: muhoo: at least you keep notes. I feel like I just had a pseudo-religious epiphany that I should start doing that.

2:48 ...now.

2:53 glosoli: A bit of a dumb question, but how do I correctly use map in such situation (map #({:phone %}) [444444 11111]) I want to make some function to every value of vector, but I am not sure why does ArityException get thrown

2:53 s/make/map

2:53 Apage43: glosoli: what output do you want, exactly?

2:54 at any rate, you're calling a map as a function with no args here, and maps require one or two

2:54 pepijndevos: &(map #(vector :phone %) [1111 4444])

2:54 lazybot: ⇒ ([:phone 1111] [:phone 4444])

2:55 glosoli: ({:id "f250b7c8-5b2f-4191-98bb-38e267af8821", :phone 37062681701, :mask "***"} {:id "02ba1da9-4689-44ff-a82b-f409ae2645b0", :phone 37061564497, :mask "***"})

2:55 I want something like this as a result

2:55 id will be generated too though, stupid of me of not including it in the example

2:56 Apage43: ,(for [phone [123 456 789]] {:phone phone :id "pretendthisisanid"})

2:56 clojurebot: ({:phone 123, :id "pretendthisisanid"} {:phone 456, :id "pretendthisisanid"} {:phone 789, :id "pretendthisisanid"})

2:56 pepijndevos: glosoli, try using proper fn syntax instead of the lambda reader macro

2:56 jared314: you can use the hash-map function

2:57 (map #(hash-map :id (something) :phone %) [...])

2:57 glosoli: pepijndevos: yeah it works that way, the lambda reader macro is what got me curious, but proper fn syntax might be better suit for such situation I guess

2:58 pepijndevos: the first argument in the lambda macro gets called as a function

2:58 Apage43: #(foo %) is equivalent to (fn [x] (foo x)), often confused for (fn [x] foo x)

2:58 glosoli: ok thanks folks

2:59 pepijndevos: &(#())

2:59 lazybot: ⇒ ()

2:59 pepijndevos: that's just weird...

3:00 Apage43: ,()

3:00 clojurebot: ()

3:00 jared314: ,(#())

3:00 clojurebot: ()

3:00 Apage43: an empty list is just an empty list =P

3:00 following that i said above, that's equivalent to (fn [] ())

3:00 pepijndevos: Apage43, yes but according to your logic that would be equivalent to... oh wait (fn [] ()) so it kinda makes sense.

3:00 Apage43: ,((fn [] ()))

3:00 clojurebot: ()

3:13 Apage43: ,(let [v [5 4 3 2 1 0]] (mapv v v))

3:14 clojurebot: [0 1 2 3 4 ...]

3:16 Apage43: so, for that transform (swapping values with indices), I wonder what is the longest cycle I can get iterating that for a vector of some size

3:16 with 5 I found a 4-cycle

3:16 &(take 5 (let [v [5 0 2 4 1 3]] (iterate #(mapv % %) v)))

3:16 lazybot: ⇒ ([5 0 2 4 1 3] [3 5 2 1 0 4] [1 4 2 5 3 0] [4 3 2 0 5 1] [5 0 2 4 1 3])

3:36 devn: Apage43: come off of it

3:37 err in reply to your thing earlier about a book telling people to write macros ":("

3:37 Apage43: not a book

3:37 devn: that assertion in this community is annoying as hell

3:37 Apage43: a README for a library

3:37 devn: "don't write macros! the sky is falling!"

3:37 Apage43: a database client library

3:37 i'm not against macros

3:37 devn: even still, gigantic shrug

3:37 Apage43: but "how to connect to a database" shouldn't have defmacro in it

3:38 devn: who cares what other people do with their clojure?

3:40 jkj: well. macros are sometimes nice layer on top if you can do everything also without them

3:40 devn: ugh -- there it is again

3:40 jkj: macro-only libs are HARD to drive programmatically and generally useless if you want to do anything other than the designer intended

3:41 devn: yes, yes, everyone knows -- but I wish people would quit playing 5th grade teacher reminding everyone to "be careful with macros!" all the time

3:41 you always hear the people cautioning about the use of macros

3:41 and no one talking about the things they can give you

3:42 jkj: oh. well. people just broadcast their personal opinions

3:43 devn: clojure is a consenting adults language

3:43 jkj: i don't think it is really intended that macros are bad, but there is a common antipattern that people want to warn about

3:43 devn: people need to chill out about THE HORROR OF MACROS

3:43 Apage43: I wasn't concerned about the use of macros so much as

3:44 jkj: so when you know better, you can just stop listening to the warnings :)

3:44 Apage43: the idea of introducing macros while trying to show someone how to connect to their db

3:45 bitemyapp: Apage43: I agree.

3:45 devn: Apage43: I get it. I just wish there wasn't all of this glasses-adjusting, pocket protector wearing, overprotective parenting

3:45 bitemyapp: Apage43: btw, have you read the code to timbre?

3:45 Apage43: i have

3:45 i wrote my own appender once

3:45 devn: <mom voice>don't forget to wear a helmet!</mom voice>

3:46 ^---the clojure community on macros

3:46 bitemyapp: devn: macro-madness and weird galapagos-island micro-lisp DSL macro-fueled what-the-fuck-is-going-on crippled Common Lisp. We're trying to balance empowering the programmer with common sense.

3:46 devn: bitemyapp: you're doing it too?

3:46 bitemyapp: devn: I write Lisp like a fucking madman, I'm just trying to temper my own enthusiasm.

3:47 devn: bitemyapp: yes, but i wish people would quit tempering OTHER PEOPLE'S enthusiasm

3:47 bitemyapp: some of us have been waiting for the "Rise of Lisp" for most of our natural lives. Not wanting to repeat the mistakes of the lsat major Lisp isn't a sentiment that should be disregarded out of hand

3:47 also believing that documentaton could be improved to reflect a better style doesn't seem unreasonable to me.

3:47 also holy god I type so much faster on this thinkpad. Like night and fucking day.

3:48 devn: programming languages ought to be prescriptive up to a point. if people want to warn about macros so much, take them out of the language.

3:48 or better yet, we'll have people sign agreements that they understand how to properly use macros

3:48 Apage43: devn do you have a highlight for "macro" if you do it is okay, I have one for "crypto"

3:48 devn: the whole thing is asinine

3:48 bitemyapp: it's really not

3:49 noobies have a habit of over-using them if not corrected.

3:49 they'll use them where functions would've sufficed and returned errors that made sense.

3:49 devn: let them make mistakes. that is how people fucking learn.

3:49 bitemyapp: the macros *need* to be in there, though.

3:49 devn: well, maybe. I return to what I said about bizarro-world galapagos island Common Lisp libraries.

3:49 some common lispers managed to entirely avoid learning how "map" worked.

3:49 devn: i would like to present a challenge to the community: don't remind everyone about macros the next time they come up

3:49 H4ns: devn: you don't teach people how to drive by showing them the innards of the engine first.

3:50 bitemyapp: I'm...not exaggerating.

3:50 devn: bitemyapp: dude. i get it. history. yes. understood.

3:51 it's just creativity stifling, mob mentality, "wear a helmet!" crap though

3:51 bitemyapp: devn: well I don't know what you want me to say. There are well-substantiated reasons for a "golden path" to learning FP in Clojure before going hog-wild with the Lispy bits.

3:51 devn: why don't people constantly remind people about alter-var-root, using mutable arrays, etc.

3:51 bitemyapp: devn: you're talking to an "ally". Idiomatic Clojure for me means using nutty AOP shit.

3:51 and macros to sugar up said AOP.

3:52 why? because why the fuck not.

3:52 Apage43: if the README for a library asked folks to configure it using alter-var-root i'd be a bit concerned then too.

3:52 bitemyapp: but I wouldn't teach a new person that way, it's not worth the complexity budget when learning.

3:52 the way I teach Clojure to newbies is like an immutable FP Python.

3:52 Apage43: alter-var-root...kekekekekeke

3:53 Apage43: incidentally i'm really enjoying synthread when i have an excuse to use it

3:53 bitemyapp: Apage43: <3

3:53 devn: yes, i just think all of this enthusiasm for what other people ought to do with their clojure code is a bunch of crap. clojure is a consenting adults language.

3:53 Apage43: i get to keep saying "man.. this would have been some *ugly* ass code without that."

3:54 bitemyapp: Apage43: I'm pretty certain Raynes has a standing death warrant for people that use synthread in production code.

3:54 this tickles me to no end, since he was originally a Haskell coder.

3:54 devn: well, you're welcome to nominate yourself the Johnny Appleseed of macros.

3:55 devn: it's not like that

3:55 bitemyapp: devn: I look forward to the "smashing your conses for fun and profit" posts >:)

3:55 (i'm srs, I want to see a tutorial with that title.)

3:55 devn: it's not so much that i think we need a heavy duty advocate for macros

3:55 it's that i wish people would just shut up and let nature take its course

3:56 Apage43: leave macros alone?

3:56 bitemyapp: devn: I'm down with that :)

3:56 I need to start taking extracts of my ugly code and shove it in devn's face, so he can get a whiff of nature taking its course :D

3:56 devn: people who learn clojure are not stupid, y'know?

3:57 these people will figure it out. you can't use them all of the time.

3:57 Apage43: sure

3:57 i just https://github.com/ptaoussanis/carmine#connections

3:57 devn: but you learn how far to take something by doing it to an extreme

3:57 so i think it is actually more harmful to discourage macros

3:57 Apage43: would rather not help someone debug a macro (at least if they've never written one before) when they're trying to connect to redis

3:58 bitemyapp: devn: I think I would be less concerned if clojure had a type system to whack people on the nose.

3:58 devn: because there might be really good places where they fit that people don't commonly use them, and when they hear "oh, be careful! look out! you might poke your eye out!"

3:58 it makes them skip them altogether

3:58 and they're a wonderful intentional feature of the language

3:58 amalloy: Apage43: you may be interested to know that for n=4, the longest cycle is also 4 (4 3 1 0 2); for 6 and 7 it is 5; for 8 it is 6. after that it gets a bit hard to brute-force

3:58 devn: so just quit telling people and let them learn like everyone else did

3:58 bitemyapp: Apage43: dat fuckin' pseudocode.

3:58 Apage43: amalloy: ! nice

3:58 mercwithamouth: hrmm how would i go about fixing my casting issue? https://www.refheap.com/20514

3:58 devn: </rant>

3:59 * devn wipes weat

3:59 devn: sweat*

3:59 Apage43: i'm glad i wasted someone else's time with that =P

3:59 bitemyapp: being back on Linux has put me in a really good mood

3:59 amalloy: it looks kinda like cycle-len might be (floor (/ input-len 2)), Apage43

3:59 bitemyapp: I chuckled when I upgraded Ubuntu and saw the fuckin' couchbase user in the login screen though

4:00 * mercwithamouth gasps @ the convo about ME and redis...ok dont fix my casting issue..i'll play with it =P

4:00 mercwithamouth: playing is fun and fundamental.

4:00 * ucb waves

4:00 amalloy: mercwithamouth: "x cannot be cast to IFn" means "you have too many parens around a value of type x"

4:00 * devn waves

4:00 ucb: bitemyapp: thanks for the link; 'tis gooood

4:00 amalloy: in this case, all the keys in your map

4:01 devn: Speaking of "goooood": http://skillsmatter.com/podcast/scala/the-refined-clojurist

4:01 I missed that one.

4:01 * bitemyapp makes <3 with his hands at ucb

4:01 * devn makes a && with his hANDs

4:02 devn: ill be here all week ladies and gentlemen

4:02 bitemyapp: LOL

4:02 mercwithamouth: amalloy: ahh gotcha! now i know wha to look for =P

4:02 devn: try the veal

4:02 amalloy: inline logical operators are the mark of the devil, devn

4:02 devn: lol

4:02 oh god

4:03 How dare you talk about my logical operators like that! This is outrageous!

4:04 And on that note, I must be off. Bed time.

4:04 bitemyapp: I probably abuse "or" and "and" short-circuiting too much.

4:04 devn: ta

4:04 devn: bitemyapp: are you going to the conj?

4:05 mercwithamouth: thank you =P

4:05 problem solved

4:05 now..to refactor

4:06 bitemyapp: devn: exhaustion and lack of time/funds make it extremely unlikely. :(

4:06 amalloy: bitemyapp: how is it possible to abuse that?

4:06 devn: bitemyapp: bummer

4:06 bitemyapp: amalloy: triply nested forms and the like. Makes me feel like I should be splitting out constituent functions more aggressively. Nothing major.

4:07 amalloy: bitemyapp: https://github.com/flatland/schematic/blob/master/src/flatland/schematic/core.clj#L41

4:08 i remember that having more ors and ands, and less fors, than it actually does, but it still sounds like what you describe :P

4:08 bitemyapp: amalloy: yeah I write code like that, but worse.

4:08 amalloy: <3 and/or

4:08 bitemyapp: amalloy: I'm actually considering making caaar cdar cadr style macros for the and/or stuff I do.

4:08 * ucb sees nothing wrong with that code

4:08 amalloy: haha

4:08 bitemyapp: (aoaoaor ...)

4:09 Apage43: (Rawr)

4:09 amalloy: does that actually make sense, bitemyapp? it doesn't sound that way to me, but my brain may not be working

4:09 bitemyapp: Apage43: ALWP

4:09 amalloy: does what make sense? car/cdr and/or macros?

4:10 amalloy: yeah

4:10 bitemyapp: amalloy: yes, but I don't have the spare sanity to prove my point off-hand.

4:10 amalloy: it works for caadr, but those are unary

4:10 and/or are n-ary

4:11 bitemyapp: specifically what I was thinking of was using nested vectors and sequential application to produce what I had in mind

4:11 maybe use numbers for arity?

4:12 a2o3a4or(rest)

4:12 ...I need sleep.

4:12 amalloy: *chuckle* you might also need medical attention

4:12 bitemyapp: almost certainly.

4:12 amalloy: but who knows, maybe it works out fine

4:13 bitemyapp: well, it could be made to work, it's just a terrible idea.

4:13 amalloy: i support terrible ideas

4:13 bitemyapp: ucb: https://soundcloud.com/maribel/sets/asthetics

4:14 amalloy: my fantasies involve having a greater crop of questionable libraries than ztellman.

4:14 * ucb clicks

4:14 bitemyapp: I might (inc bma-evil-libraries) this week.

4:14 ucb: listen to it loud!

4:15 it's shoegaze, WALL OF SOUND TIME

4:15 ucb: I need to set up my speakers

4:15 this is a great excuse to do so

4:15 amalloy: i think it won't be long before he has a library that accepts as input a library and produces something equally questionable. the ztellman grey-goo scenario

4:15 Apage43: well equally questionable is not so bad

4:16 but if it produces something minutely more questionable than its input, you can feed it to itself

4:16 bitemyapp: (reduce increase-questionableness [] ztellmans-libraries)

4:16 Apage43: and you now have a questionability pump

4:16 bitemyapp: (constantly AFOREMENTIONED) ;; OH GAD

4:19 I wonder if Baranosky always catches up on his tweets at 0115.

4:21 smiler: Is there a document somewhere about idiomatic style for Clojure?

4:24 bitemyapp: smiler: none that are accurate that I'm aware of, but flatland has libraries with decent examples.

4:25 don't look at my code.

4:25 smiler: :P

4:25 mpenet: smiler: there are http://dev.clojure.org/display/community/Library+Coding+Standards and https://github.com/bbatsov/clojure-style-guide , but both are somewhat opinionated.

4:26 smiler: That's almost unavoidable

4:26 bitemyapp: batsov's guide is bad

4:26 please do not link :(

4:27 amalloy: not so unavoidable as you might think - lisp-family languages don't really have the "style holy wars" that c-family languages do; everyone just uses the same style

4:27 glosoli: ,(clojure.string/join (repeat 5 "*") (subs "59as5d465as4d564asd" 1 5))

4:27 clojurebot: "9clojure.lang.LazySeq@4186e49aclojure.lang.LazySeq@4186e49sclojure.lang.LazySeq@4186e495"

4:27 glosoli: Any ideas why does this return lazy seq ?

4:28 amalloy: &((juxt str pr-str) (range 5))

4:28 lazybot: ⇒ ["clojure.lang.LazySeq@1b554e1" "(0 1 2 3 4)"]

4:28 bitemyapp: amalloy: incisive. nice work.

4:29 amalloy: and probably cryptic enough to him that i resemble the oracle at delphi

4:29 mpenet: bitemyapp: it's not that bad, some parts are questionable, but overall it's ok for a newcomer

4:36 amalloy: by the way, Apage43, the code i used to find those numbers is at https://www.refheap.com/de564455dd37659d8418ebedf if you are interested. i'm going to bed, so i'm just throwing it away now that i've pasted it for you

4:36 Apage43: thanks

4:43 noncom: when using core.async pub/sub mechanism, can several subscribers be subscribed for the same topic?

4:44 Uatec: isn't that the definition of a Topic as opposed to a Queue?

4:45 that you get multiple subscribers?

4:51 mpenet: noncom: I think there's a pub fn for that

4:51 noncom: and sub of course, never used them tho

4:52 noncom: best thing to do is just try on the repl

4:52 noncom: guys, just wanted to be sure.. i think i better do a simple repl try

4:52 mpenet you were faster mentioning the repl ))

5:21 zilti: Is there a way to dynamically create a function without using macros?

5:22 magnars: What's dynamic about it?

5:22 jonasen: zilti: like (fn [x] (+ x x))?

5:22 zilti: jonasen: Yes, but... I don't know the argument list yet at code-writing-time

5:23 Neither the function body

5:24 noncom: (eval ('fn your-arg-list your-body)) ?

5:24 zilti: jonasen: The argument list is in (first (val listener)) and I need to get that into that fn form

5:24 noncom: ,((eval ('fn '[x] '(+ 1 x))) 3)

5:24 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

5:25 noncom: ùð êøïðå

5:25 oh right

5:25 zilti: That won't work because the body expression has objects in it, which results in an error when using with eval

5:26 noncom: oh thats too bad, maybe you could proxy them or turn them into a function call, say on an atom?

5:26 btw, the above version with eval wont work, here is a working version: ((eval `(fn [~'x] (+ 1 ~'x))) 3)

5:27 magnars: Sounds like you're looking for an embedded language.

5:27 zilti: Basically I'd want this: (fn (first (val listener#)) (postwalk varwalker (rest (val listener#))))

5:28 noncom: zilti: the simplest approach i can think of is to first put the objects in a atom or a ref and then call your function with accessors to it

5:28 magnars: what you mean by "embedded language" ?

5:28 zilti: noncom: This looks like it would be an ugly, huge pile of code to achieve that

5:29 noncom: zilti: not really a huge pile, just one more atom and atom-calls instead of direct object access. but i hear you.. yes, sometimes it is like that with clojure... at least i can't think of something else right now..

5:30 zilti: noncom: It works like this now (eval `(fn ~(first (val listener#)) (postwalk varwalker (rest (val ~listener#))))) hmm... I'm not sure how robust this is?

5:30 magnars: noncom: Like embedding a lua. If you're executing code that you don't know the form or contents of, it better live in a sandbox.

5:31 noncom: afaik only java class constructor calls in code are treadted specially and can't be passed like normal IFns, i.e. they are not IFns.. but what you say does not seem like a secial java case

5:31 magnars: oh that's right

5:32 zilti: well, cool! you can always ask here later again, when greater gurus of the language come in here

5:33 zilti: noncom: The only problem I still have now is that my varwalker fails? It does (if (var? x) (deref x) x) but it seems in that code configuration that doesn't work

5:34 noncom: what does it say?

5:34 brb

5:36 zilti: noncom: It just doesn't seem to deref the var (or deref'ing doesn't un-var it)

5:38 noncom: Before that line of code, I have code that resolves all symbols in listener# that are resolvable, so they get "replaced" with a var. Then I want to deref them so I get the objects.

5:40 noncom: The weird thing is, that varwalker actually works. Except when it's inside this eval like this: (eval `(fn ~(first (val listener#)) (postwalk ~varwalker ~(rest (val listener#)))))

5:48 jonasen: zilti: this seems overly complicated. Is the problem that you don't know the argument count? Or what exactly are you trying to do?

5:50 zilti: jonasen: Basically turning something like this {:on-action [[x] (blah blah)]} into (set-listener!* obj :on-action (fn [x] (blah blah)))

5:50 jonasen, noncom: But I found the solution, I had to quote the args: (eval `(fn ~(first (val listener#)) (postwalk ~varwalker '~(rest (val listener#))))) Like this, it works.

5:51 ...or, compiles.

5:51 jonasen: zilti: Why not {:on-action (fn [x] (blah blah))}?

5:52 zilti: jonasen: ... no idea.

5:58 noncom: zilti: so you made it work in the end?

5:58 zilti: noncom: Not yet.

5:58 jonasen: zilti: If I understand your use-case correctly you're tring to register a bunch of events from a map? Something like https://www.refheap.com/20520 ?

6:00 zilti: jonasen yes, something like this... But the events are part of a quoted map which is quoted for other reasons, and I can't properly "unquote" that stuff

6:02 jonasen Basically I need a way to reliably turn something like '(fn [a] (do-something a)) into (fn [a] (do-something a)) without going over (#'fn [x] (#'do-something #'a))

6:07 jonasen: zilti: I think you should take a look at why the map have to be quoted. Is it really necessary? Is it out of your control (i.e., it's not your code)?

6:09 other than that, if you have '(fn [a] ...) and want to turn it into a function you'll have to evaluate it

6:09 zilti: jonasen: Well it is my code

6:10 jonasen: but the need to use `eval` is very rare

6:13 zilti: jonasen: Hmm yes I was able to eliminate the need for quoting it

6:13 jonasen: zilti: problem solved! :)

6:31 noncom: zilti: could you post the form of your solution please? i was researching this kind of problems for some time too..

6:32 zilti: noncom: In the end it now looks like this: https://github.com/zilti/clojurefx/blob/master/src/clojurefx/core.clj#L368 (Line 385)

6:35 noncom: wow cool, javafx wrapper!

6:40 zilti: :)

6:42 clgv: zilti: do you plan to integrate features like in seesaw? selection, config, ...

6:43 noncom: is there a way to recognize arity of a passed IFn?

6:44 clgv: noncom: only via reflection

6:44 noncom: for a given variable you can access its metadata

6:45 noncom: i think there'd be no metadata - i want to know arity of a function passed in the options map, the function is declared in-place.. so i think i better restrict the user than to invent something reflection-based here..

6:45 speed matters too

6:47 clgv: noncom: yeah the variable approach does not include anonymous functions..

6:58 noncom: but you could force your user to attach metadata containing the arity information

6:59 noncom: or for better usability expose a custom fn-macro that records the metadata

7:01 noncom|2: clgv: i think that in this case i will simply force user to always write full-arity fn. this will also make the code more transperant..

7:02 clgv: noncom|2: yeah the optimal solution depends heavily on your concrete scenario

7:08 sveri: hi, on my journey through clojure i wanted to try to implement something like reduce in a parallel manner myself, now i read the book Clojure Programming/Programming Clojure and they have examples with futures there, but i wonder, they always define them like this: (def (future ...)) without an argument list, is there an example where i can call a future with an argument? or am i thinking in the wrong direction?

7:10 noncom|2: sveri (future) is a simple java Thread dispatch

7:11 sveri: it takes only the body to execute in the run() method

7:11 sveri: noncom|2: so i could place it anywhere theoretically?

7:11 clojurebot: No entiendo

7:11 noncom|2: sure

7:12 sveri: noncom|2: ok, thank you so far, i'll try this

7:12 noncom|2: it returns something after it finishes, it is called "dereferencing future", so if you (def a (future. ..)) then when the future finishes, @a will return the result. or hang forever :)

7:15 i use (binding) to bind my-var to some value, and later, when I am printing it to the console, it says #<Unbound Unbound: #'my-ns/my-var>, then if I #' it, it says #'my-ns/my-var ... but how do i get to print the value that has been bound to it?

7:17 andrewmcveigh|wo: noncom|2: not 100% sure of what you mean, but the `binding` is only bound for code called from inside (binding ....)

7:18 noncom|2: yes, i ment i try printing it from inside the binding form.. that "later" in my original sentence was obscure..

7:19 andrewmcveigh|wo: paste? sounds like it should work.

7:20 clgv: noncom|2: put a gist up ;)

7:20 noncom|2: ok, i'll try

7:21 clgv: noncom|2: everyone's crystal spheres are currently in repair ;)

7:22 noncom|2: ))) but the code is quite complex here.. it is a function passed to a macro that generates a map of functions and stuff.. . ill see if i can boil it down to a gist

7:23 clgv: noncom|2: maybe that is part of the problem ;)

7:23 noncom|2: i'm almost sure :)

7:23 but it works fine! it's just that i get that wrong thing on printing

7:23 "wrong"

7:24 clgv: "but it works fine" is the argument I hear for spaghetti c++ code all the time ;)

7:41 noncom|2: clgv: i think i figured the reason. despite that the (println) is inside the binding, it is inside a (fn) created inside the binding, and the fn is stored to an atom and executed later, so when it is executed, it is not inside the binding anymore

7:42 and i did not use the bound value inside that fn, only outside so that is why it worked fine

7:47 clgv: noncom|2: if I remember correctly there is something like `bound-fn` which preserves bindings

7:48 noncom|2: checked, it is called `bound-fn

7:48 noncom|2: thanks, i gotta check it out since what if i'll have to use the bound variable inside the fn

7:49 clgv: noncom|2: `future` uses (let [f (binding-conveyor-fn f)] ...) https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L6335

7:51 noncom|2: wow seems like quite a machinery is involved

7:52 clgv: noncom|2: I think. I'd use `binding-conveyor-fn` like `future` does

8:44 glosoli: Is there some way to use let in Enlive clone-for macro ?

9:16 rollin: hi

9:21 hi all

9:26 noncom|2: rollin: hello!

9:41 with core.async, i have (alts!) inside a (go), called from a java cycle, and after some time it comes up with java.lang.AssertionError: Assert failed: No more than 1024 pending takes are allowed on a single channel.

9:42 how do I make it not to make a pending take if there is nothing to take at the moment?

9:44 BobSchack: The go block is called inside a java loop?

9:44 noncom|2: BobSchack: right.

9:45 i guess this is a wrong desing?

9:45 tbaldridge: noncom|2: perhaps use alts!! with :default ?

9:45 noncom|2: although I'd need a gist to get a better idea of what you are trying to do

9:47 noncom|2: tbaldridge: i'm just playing with core.async to learn the things and I'm trying to apply it in a scenario where I put it inside a proxied java class which has this update() method called over and over again from the main app cycle

9:48 tbaldridge: noncom|2: and the update() needs to take from a channel?

9:48 noncom|2: yes, i would like to make decisions inside of update(), based on what is there on the channel, or just skip the block if no message comes

9:48 i guess that the alts!! with :default sounds good here

9:49 tbaldridge: noncom|2: yeah, :default with alts!! (or alt!!) should do the trick. Perhaps even do alts!! a few times per update() that way you can get whole batches of updates for every update(). Otherwise you'll only get one item per update().

9:50 something like "take until the channel is empty"

9:51 noncom|2: tbaldridge: this sounds as if this is what it should be, right! so i just deplete the channel on each update() cycle!

9:51 tbaldridge: noncom|2: right. Although if your producer can outproduce the taker, you may never exit the update(), but that's not hard to fix.

9:52 noncom|2: tbaldridge: yeah.. i'll have to think about that... but i think that in the current scenario there won't be such a problem! thank you for the advice!

9:53 tbaldridge: noncom|2: anytime

10:56 seangrove: Is there a way to get compojure to parse query vars as integers that's cleaner than this? https://www.refheap.com/3ad182b22af25034cb19d4a32

10:57 wink: that's a good question.

10:58 usually not asked by the people who ridicule PHP et al for the type system. surprise, HTTP integers are strings :P

10:59 seangrove: I usually encapsulate it in a function that returns -1 as fallback (depending on use case, ofc)

10:59 clgv: seangrove: isnt there some ring middle ware that just applies clojure.edn/read to the params?

11:00 seangrove: clgv: I was more looking for something like the url route binding, don't necessarily want all params to be edn

11:00 bitemyapp: seangrove: cleanest way I know is to use a schema or validator that attempts coercion based on defined type and returns failure with a sensible error message if any choke.

11:00 seangrove: wink: Ah, thought there might be something inline.

11:02 bitemyapp: I should probably bring in prismatic's schema at this point

11:02 Alright, well, another ecosystem question then - is there a way to find unused dependencies, both in a project and a namespace?

11:02 bitemyapp: seangrove: I use ag (grep) for that.

11:02 bbloom: that seems like killing a fly with a bazooka

11:03 bitemyapp: bbloom: more trying to capture multiple benefits in one go.

11:03 seangrove: bbloom: Just meant I have some simple-ish data dependencies happening, probably better to do it now and think things through than to retroactively try to bolt it on. The latter has been pretty painful for some of our systems.

11:04 bbloom: what about some function like (coerce-map {:weeks coerce-int :limit coerce-int} {:weeks weeks :limit limit})

11:04 you write those 3 helper functions

11:04 then you write a nice macro to give you plesant sytnax for that wrapped up with a let

11:04 then you go back to work :-)

11:05 seangrove: bitemyapp: looking more for something language aware, that can be integrated into an emacs mode or linter

11:05 clgv: seangrove: slamhound?

11:06 bitemyapp: seangrove: slamhound or add to kibit/eastwood.

11:07 seangrove: Slamhound is close, but it doesn't provide any intermediate data (from looking at the readme), it only returns the reconstructed ns

11:07 Let me see if I'm wrong...

11:08 jcromartie_: I like how Pandora still calls themselves "a new kind of radio" even though they're 13 years old

11:14 bbloom: jcromartie_: i (dis)like how their air app still randomly stops playing songs in the middle & sucks down a ton of memory & requires i relaunch it each morning

11:14 other than that, great service :-P

11:15 jcromartie_: I'm still paying them while I patiently await their demise. I just don't know how they are still around.

11:16 bbloom: lol, this just happened: https://www.evernote.com/shard/s57/sh/7623196a-dd69-4997-bc62-b50c091b3644/4f4ca346f5823cdac26250ebf41e64e7

11:16 i forgot to reboot it this morning

11:17 whoops

11:20 seangrove: Too bad the music industry is so bad, it'd be cool if others could easily build players on top of music API's

11:23 Hrm, it looks like clojure.java.jdbc/with-connection is deprecated... https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L775 any insight as to why bitemyapp?

11:25 bbloom: seangrove: anything that uses *db* is deprecated

11:25 seangrove: using a single dynamic var w/ thread local behavior for such configuration is a (common) bad idea

11:25 it means you have to change every damn callsite when you later decide you need to talk to a second database

11:26 rkneufeld: bbloom: Is the alternative to use db-do-commands?

11:26 bbloom: rkneufeld: i haven't used this particular library, so i'm not familiar with it's API

11:26 seangrove: bbloom: Yeah, fair enough.

11:27 bitemyapp: seangrove: yeah don't use *db*

11:27 Pass around your db/conn explicitly.

11:27 bbloom: a lot of people use dynamic variables when what they *really want* is implicit *static* variables

11:27 a dynamic variable is inherently mutable

11:27 bitemyapp: oh not this again.

11:27 bbloom: bitemyapp: that was the end of my rant :-P

11:28 bitemyapp: bbloom: I think what people would really like is the implicit parameters from Scala and Haskell.

11:28 walk the call stack to find the first instance of the matching type, bring it into local scope of the executing function.

11:29 bbloom: bitemyapp: interestingly, that's NOT how haskell's implicit params work

11:29 scala uses type, but haskell matches names (and errors if types don't match)

11:29 the name approach is *far superior* in my opinion... for the same reasons i dislike return type polymorphism :-)

11:29 bitemyapp: bbloom: I prefer the name-based approach too.

11:29 bbloom: which haskell has, and scala doesn't :-P go figure

11:29 bitemyapp: you get the type enforcement anyway.

11:30 sigh, my kingdom for a type system ;_;

11:30 bbloom: iirc the reason they went w/ the name approach was b/c it was like some grad student who imlemented it and it was too complex to wire it in to the type system

11:30 happy accident

11:30 bitemyapp: yeah that was nice anyway.

11:31 I don't really like guessing what Scala will do.

11:31 bbloom: this is where i mention ambroseb_ since i like him to hear my rantings about how it's obviously a better idea to have your type systems not influence semantics :-)

11:32 bitemyapp: bbloom: I once eliminated a thread-local global variable in Python by replacing access to it with a "getter" that walked the entire VM call stack to find an instance of the expected name and type.

11:32 at runtime, in case that wasn't obvious.

11:32 bbloom: bitemyapp: that's interesting... let me think about how i feel about that :-P

11:32 tbaldridge: bitemyapp: also known as "screw you JIT"

11:32 bbloom: tbaldridge: lol

11:33 tbaldridge: at least for PyPy not sure how the JVM handles call frames

11:33 bbloom: bitemyapp: my issue w/ that is that i think that implicit parameters should only ever get passed ONE call frame at a time

11:33 it's implicit passing, not implicit usage

11:33 if a stack frame doesn't mention the parameter, it shouldn't get passed to children

11:33 otherwise, it's really dynamic scope

11:33 even if the variable isn't itself dynamic

11:33 bitemyapp: bbloom: well, the global variable was breaking shit, my stack-walker fixed the bugs.

11:34 so my "Give-a-fuck-o-meter" wasn't very sensitive to the demerits of my approach.

11:34 tbaldridge: doesn't C++ do implicit parameters that way? Inlines the value into call site? I forget what language does that.

11:34 seangrove: bitemyapp: But the poor bastard who comes after you...

11:34 bitemyapp: seangrove: I made the author of the original global variable version aware of what I'd done.

11:34 seangrove: bitemyapp: Fair enough, as long as it's communicated an understood. Cool trick either way.

11:35 bitemyapp: I actually pasted the stack-walking code to the developer mailing list out of immense pride.

11:35 bbloom: tbaldridge: C++ has implicit parameters!?

11:35 bitemyapp: bbloom: he's talking about static value inlining though

11:35 tbaldridge: to be honest, that's what I love about Python everything can be queried at runtime, even the stack

11:35 bitemyapp: ^^ yep lol.

11:36 bbloom: i can't do C++. my brain hurts. makes me wish for C + embedded useful language

11:36 bitemyapp: tbaldridge: still prefer Clojure, but Python gives me the right knives, guns, and clubs when I need them.

11:36 tbaldridge: I'm thinking of C++ default parameters, which I guess are static values. I assume Scala has something different?

11:36 bitemyapp: what we need is Clojure on the Python VM ;-)

11:37 bbloom: tbaldridge: i like maximally reflective environments, but python (and ruby, etc) there are no limits on those APIs. if you only provided those APIs as effect handlers that must be installed in to the stack, then your JIT could prove lack of access to them & optimize away the reflective scaffolding

11:37 tbaldridge: but i'm only in favor of that idea if you also provide deoptimization for debugging :-)

11:38 tbaldridge: bbloom: PyPy does that just fine. It optimizes away all that stuff, but if you try to access the callstack it bombs out of the jitted code and generates a callstack on the fly via black magic.

11:38 bbloom: tbaldridge: yup. that's the future

11:38 challenge is that python doesn't make that easy :-P

11:39 tbaldridge: the code that does this has the most awesome name in compiler tech ever: http://morepypy.blogspot.com/2010/06/blackhole-interpreter.html

11:39 bbloom: the approach in javascript engines (and pypy, etc) is to assume nobody does fancy crazy reflective things & then add a trap

11:39 llasram: tbaldridge: What did happen with clojure-py? Did you lose interest, or other?

11:40 bbloom: i'm saying you can actually *prove* the lack of that stuff trivially if you must have the effect in the callstack. then deoptimization doesn't happen when somebody breaks the rules, instead you get an exception. so deoptimization comes from the *outside* when you attach a debugger, not from the *inside* when you do something slow

11:40 tbaldridge: llasram: I hit some bugs with code generation. And yeah, also lack of interest.

11:40 bbloom: obviously requires a new language design tho

11:41 tbaldridge: llasram: but it's been almost a year since I worked on it, and I'm starting to get the itch to work on it again.

11:42 llasram: there's even some interest outside of the Clojure community. The Blender devs contacted me awhile back and asked for a Python 3 version so they could write Blender plugins in clojure.

11:42 stuartsierra: Anything that depends on the call stack, whether it's dynamically-scoped Vars or some clever trick, totally breaks when you start doing async stuff.

11:43 llasram: tbaldridge: Oh, cool. I never had a chance to dig into, but was interested. Clojure access to numpy would be pretty nice

11:43 tbaldridge: llasram: yeah, and some of the new stuff in Python is just amazing: http://numba.pydata.org/

11:44 llasram: Ooh. Fancy.

11:50 justin_smith: we were playing with CDT (the ritz predecessor) the other day, we were able to get access to, and walk through, the stack trace, and look at locals, and move up and down the stack etc - from a totally separate codebase, not even having the other project being debugged in the class path

11:51 we are going to bundle it up into a webapp, so you pick a dt-socket to open and if you have a clojure target it gives a point and click debugger into that process

11:51 (regarding that talk of debuggers and stacks above)

11:55 some coworkers have fond memories of http://werkzeug.pocoo.org/docs/debug/ werkzeug, so they are trying to make a clone in clojure

11:55 (in and for)

11:59 TimMc: bitemyapp: Oh, are we doing confessions again?

12:13 muhoo: speaking of debugging, has this shown up in anyone's utility library yet? http://www.learningclojure.com/2010/09/astonishing-macro-of-narayan-singhal.html

12:14 i've found it pretty useful for debugging in the repl. functions with big nasty let statements can be kind of opaque

12:15 justin_smith: muhoo: with cdt you can print out local bindings if you break inside the let

12:16 I assume ritz can do similar

12:16 and you don't need to change the code, there is just a command that prints out or returns local bindings

12:17 mdrogalis: Also a no-edit debugger https://github.com/MichaelDrogalis/night-vision

12:18 justin_smith: mdrogalis: cool

12:19 muhoo: alts!! makes me laugh. still waiting for someone to (defn first!!1!!1! [] ...)

12:20 justin_smith: yeah, but ritz.

12:20 i have had zero success trying to get ritz to run. figured i'd keep it simple and stick with my plain old nrepl and clojure.tools.trace when needed

12:20 justin_smith: that is why we switched to cdt

12:20 noncom|2: if i want to pass a function created with #() in plsace where a function, requiring two arguments is assed, but my function does not need these arguments, what is the idiomatic way to ignore them with respect to #(%) syntax? if I just omit any %, it errors about arity. if I write (fn) fully, then i can simply ignore the passed args in the body. but what is the #() way of this?

12:20 justin_smith: much less complex

12:21 once we get a decent UI on top, it can be standalone

12:21 muhoo: ~cdt

12:21 justin_smith: (is our plan)

12:21 clojurebot: No entiendo

12:22 justin_smith: noncom|2: a (do %2 %) will eval to % but use both

12:22 but it would be ugly

12:22 really the only clean way is to use fn

12:22 muhoo: ~cdt is http://georgejahad.com/clojure/cdt.html

12:22 clojurebot: Ack. Ack.

12:22 technomancy: is needing mid-function locals inspection anything other than a pointer to the fact that your functions aren't small enough?

12:23 justin_smith: technomancy: it is a pointer to the fact that my webapp just shit the bed and I want to see all the values right now rather than trying to recreat the error a second time

12:23 technomancy: I mean it's one thing to be able to do something with a stateful object that depends on dynamic scope if you're dealing with certain kinds of libs

12:23 justin_smith: this way I don't need to put tooling in beforehand, it allows me to inspect in context from the outside

12:23 technomancy: but I don't see the point of inspecting locals

12:24 mdrogalis: night-vision.goggles <- thank you for not calling it night.vision.core =D

12:24 justin_smith: if I can store the values in scope, I can test my fixed version of the function

12:25 technomancy: justin_smith: yeah, but you can do that much more simply with args than you can with locals

12:25 you can alter-var-root something without going in and adding a break line to its source

12:25 I prefer the non-invasive approach

12:26 justin_smith: technomancy: with cdt it is just a function called locals, and I don't have to try to recreate the error, because it stops wherever the error happens, when it happens, and lets me get the args

12:26 and I am not modifying the source at all

12:26 technomancy: justin_smith: oh gotcha; I thought this was an &env thing

12:26 justin_smith: cdt is run in a separate jvm

12:26 connecting to the dt-thread

12:27 no, it is using the same functionality jvisualvm or jdb use

12:27 to directly investigate the stack and byte code that is running in each thread at the time of the error

12:27 technomancy: I should know this; I actually used this to debug a clojure bug that was breaking leiningen

12:27 but it was like three years ago

12:28 justin_smith: heh, I had to use jdb to figure out what was breaking a ring app ages ago, and after that cdt is a real breath of fresh air

12:29 I think ritz tries to do a bunch of the same stuff, but it is very editor-centric it seems, and we are not going to sell the whole team on using emacs

12:29 muhoo: that's the dirty little secret i've found with FP, it's so nice to have very little global state, but state is inevitable in the real world, and if something breaks deep inside a chain of pure functions, it's not so easy to figure out what or why without the actual data that broke it

12:29 justin_smith: also it is big and I just don't get it

12:30 muhoo: so, clojure.tools.trace is nice, and it looks like cdt might save my ass someday too

12:30 technomancy: yeah, you hope that you never need anything more than tracing, but the world is an ugly place

12:31 tbaldridge: muhoo: if something breaks deep inside clear functions, then a debugger gives you nothing over tracing

12:31 *pure functions

12:31 justin_smith: my big problem is that ring controllers get a lot of input that is not serializable

12:31 so I can't just save and recreate these stateful things like the request body

12:32 technomancy: you could with a middleware

12:32 justin_smith: well, for example, the body can be a stream, which is stateful

12:32 technomancy: sure, just c.j.io/copy it to a file for later repro

12:32 justin_smith: yeah

12:33 it's just not as simple as reset! to put the args in an atom for experimentation is all

12:33 unlike a normal function where that is usually all you need

12:33 technomancy: yep, because that middleware doesn't exist yet =)

12:33 justin_smith: good point

12:33 muhoo: technomancy: what would it do, exactly?

12:34 technomancy: I wonder if the weaving jester would like it added to ring-devel

12:34 justin_smith: I would imagine it would create a function that outputs a duplicate of the request

12:34 muhoo: save state somewhere for future replay/debugging?

12:34 justin_smith: state and all

12:34 technomancy: yeah

12:34 the middleware fn could take a directory to store replay state in

12:35 TimMc: My kingdom for a reversible debugger.

12:35 muhoo: a directory with lots of disk space

12:35 technomancy: muhoo: well I don't think it'd be appropriate for production

12:35 muhoo: that's usually where bugs show up :-)

12:35 justin_smith: I think each request should generate a new function, each of those functions would make a duplicate of the request, include state of each object in the request map

12:36 technomancy: justin_smith: nice

12:36 muhoo: seems like a good idea, and might be pretty simple unless i'm missing something obvious.

12:36 technomancy: muhoo: yeah, maybe so. save it with logrotate-style expiry or something?

12:36 justin_smith: muhoo: depends what kinds of stateful objects we need to duplicate

12:37 muhoo: the devil will be in the serialization/deserialization details i bet

12:37 justin_smith: in practice, we are probably just talking cookies, and request bodies - io streams

12:37 or am I missing something?

12:38 muhoo: yeah, there's this nagging sense that it can't possibly be as simple as it sounds.

12:38 justin_smith: ignoring app-specific state, of course - that is provably not generally solvable

12:39 dobry-den: Has anyone happened to bind slamhound's reconstruct to hotkey that'll run it in nrepl?

12:39 technomancy: justin_smith: bonus points for getting it to emit clojure.test/deftest forms =D

12:39 muhoo: dobry-den: i have (compile "lein do slamhound, check")

12:39 technomancy: dobry-den: that's basically what nrepl-discover is for

12:39 muhoo: there's also (local-set-key (kbd "C-c C-c g") 'slamhound)

12:39 technomancy: dobry-den: haven't hooked it up to slamhound yet, but it shouldn't be too difficult

12:40 yeah, it does ship with slamhound.el

12:40 nrepl-discover is a better solution, but still immature

12:40 TimMc: technomancy: Did you see that legacy-PHP-testing lib?

12:40 technomancy: TimMc: can't say I did

12:41 TimMc: https://github.com/zavg/Asis

12:41 dobry-den: muhoo technomancy: thanks. doing things like setting a new hotkey usually sends me off an a 3-hour yakshaving adventure.

12:42 technomancy: TimMc: heh; neat hack

12:42 justin_smith: dobry-den: I always just go to the part of my .emacs where shortcuts are defined and copy what I did last time

12:42 TimMc: It watches you use a legacy app and generates tests to prevent regressions.

12:42 dobry-den: justin_smith: haha right, but i have no precedent for running a custom thing in nrepl yet

12:43 technomancy: dobry-den: that's what https://github.com/technomancy/nrepl-discover is all about

12:43 dobry-den: right, i'm looking at that

12:43 technomancy: generalized clojure-side descriptors for in-editor commands

12:44 it's a fun idea but possibly not fully baked yet

12:44 mdrogalis: technomancy: Hah, I've been put off by too many cores. I feel it.

12:45 muhoo: TimMc: is that yours?

12:45 technomancy: dobry-den: if you do try it I'm interested in hearing what you think

12:46 TimMc: muhoo: I wish.

12:47 (Actually, I would probably not write a tool that enables PHP to continue to function.)

12:48 muhoo: i'm happy that i haven't touched php in almost 2 years. don't want to jinx it tho.

12:50 indigo: muhoo: Lucky you

12:54 dnolen: ibdknox: ping

13:11 bitemyapp: `cbp: hullo hullo

13:17 seangrove: Trying to get clojurescript.test working on a new clojure project, and it doesn't seem like my :test build profile is picking up on tests in test-cljs

13:18 Looking at a similar, working project, all of the settings are the same... any suggestions on what to look for? The path is certainly there: {:cljsbuild {:builds [{:id "test" :source-paths ["src/cljs" "test-cljs"]}]}}

13:20 sritchie: seangrove I was having the same thing,

13:20 lots of "cemerick not found" errors

13:20 seangrove: sritchie: Same here

13:20 bitemyapp: "cemerick not found" <--- lol?

13:21 sritchie: haha, he adds that shit into his libraries!

13:21 justin_smith: well cemerick usually shows up here, so that should be fixable shortly

13:21 sritchie: haha, those errors do plague me even outside of a cljs repl

13:21 seangrove: justin_smith: Yeah, and he just updated clojurescript.test to 0.2.0 about an hour or two ago as well

13:21 rasmusto_: whoa

13:22 sritchie: seangrove: is the error persisting on that version>

13:22 seangrove: sritchie: Yeah

13:22 I'll wait to ask cemerick about it, must be something straightforward

13:23 justin_smith: well you need to find him first

13:23 /rimshot

13:26 logic_prog: is there a way to have clojurescript build auto's error messages to be piped into a clojurescript repl?

13:26 or even an emacs buffer?

13:27 seangrove: logic_prog: There's a :notify-command option if you want desktop notifications

13:27 Otherwise you could run cljsbuild auto inside of a M-x shell

13:27 logic_prog: also found https://github.com/kototama/cljsbuild-mode

13:27 how does M-x term and M-x shell compare?

13:27 mdrogalis: Ah D:

13:28 bitemyapp: mdrogalis: well we can tell who just had downtime.

13:28 lol cloud.

13:29 S11001001: logic_prog: shell is extremely unlike a terminal; its raison d'etre is to let you treat the shell backlog like a normal text buffer. Which is extremely convenient and awesome, so I rarely use term unless I need the specific features of an honest terminal.

13:29 mdrogalis: bitemyapp: Hah

13:34 bitemyapp: arrdem: http://i.imgur.com/mtt8e3D.gif

13:36 arrdem: bitemyapp: good morning to you too <yawn>

13:37 mdrogalis: This isn't another one of your gross snapchats, is it?

13:39 arrdem: mdrogalis: it was safe. if you're thinking about what he sent me

13:39 mdrogalis: otherwise no idea

13:39 mdrogalis: I heard talk of a windmilling man. D:

13:40 arrdem: urhg. yeah that was two days ago

13:43 bitemyapp: mdrogalis: that was gf3, not arrdem.

13:43 mdrogalis: You're all the problem children in my mind. D:

13:43 arrdem: hey now... I've behaved since that night we were playing with chord

13:44 bitemyapp: this is true.

13:47 mdrogalis: Fair enough. I'm watching, though.

13:47 bitemyapp: tbaldridge: under what circumstances does one need to close channels anyway?

13:47 tbaldridge: I didn't even know he was complaining about resource lifecycles WRT core.async, it didn't even occur to me that that would be a big deal.

13:49 tbaldridge: yeah, see? wasn't even about (chan)

13:49 tbaldridge: bitemyapp: GOs attached to GC'd channels will be GC'd as well.

13:50 bitemyapp: yeah, I've just seen this guy complaining that "hopes that core.async would be the solution to my woes are out the window" that makes me want to help

13:50 bitemyapp: that makes sense from what I know of Java's GC, but I still don't see how close! affects it.

13:50 mdrogalis: Who's this?

13:51 bitemyapp: tbaldridge: that rankled me a bit. I don't mind constructive criticism but wide-open stuff with no real substance bothers me.

13:52 tbaldridge: bitemyapp: my point is that some people assume that if you don't close a channel, GOs trying to read from it will block forever and somehow end up sitting around. The reality is that channels that never close are not really an anti-pattern.

13:52 I wonder of golang has that problem. Anyone know if go routines are GC'd in golang?

13:53 guess not https://groups.google.com/forum/#!topic/golang-nuts/uiySuH8_3Y4

13:54 although core.async's thread macro suffers from this same problem.

13:55 bitemyapp: I also wonder if with-open inside a go block would solve some of this guy's problems.

13:55 technomancy: stuartsierra: having some chatter in #leiningen about your CLI post if you want to discuss further

13:55 stuartsierra: technomancy: OK.

13:58 bitemyapp: tbaldridge: to me it sounds like he need a "control" channel sending a single "go ahead and close this resource" go block.

13:58 tbaldridge: at the most.

13:58 with-open alone would probably work anyway.

13:58 tbaldridge: bitemyapp: yeah, there's like 20 ways of solving issues like this in core.async. It really depends on what he's trying to do.

13:58 bitemyapp: tbaldridge: this all goes back to why I don't understand what he's complaining about :(

13:59 I think some of the patterns/use-cases in core.async can be a little subtle and could use a cookbook.

13:59 I love being Dan Dan the Answer Man on Twitter.

14:00 seangrove: Oh god, I have to work with google's OpenID. I expect this to be horribly painful.

14:05 Hrm, maybe today is the day I make use of friend

14:06 arrdem: seangrov: let us know how that goes

14:11 mdrogalis: The downside of being the one who introduced generative testing to company: You become 'that guy' who reports all the bugs

14:11 bitemyapp: ucb: https://www.youtube.com/watch?v=Yf_xl99pGNY

14:12 seangrove: what arrdem said. I want to know how that goes.

14:15 `cbp: bitemyapp: hi

14:17 bitemyapp: `cbp: RethinkDB people have jumped on getting revise added to their drivers page.

14:19 `cbp: bitemyapp: oh cool

14:20 dnolen: Bronsa: I don't suppose preserving the string of the original source is in tools.reader yet?

14:23 `cbp: bitemyapp: what is this rethinkdb docs fork? :-)

14:32 bitemyapp: `cbp: they initially wanted me to PR the docs.

14:32 `cbp: they changed their minds when they realized I couldn't upload static assets.

14:32 dnolen: unless somebody has something they really want to get into the next release of CLJS I'm going to cut a release now.

14:33 `cbp: bitemyapp: was taht just to add the little button or do we get a nice page like the official api docs too? :-)

14:34 bitemyapp: `cbp: twas for this page: http://www.rethinkdb.com/docs/install-drivers/ dunno what else you mean.

14:34 `cbp: bitemyapp: http://www.rethinkdb.com/api/javascript/

14:34 bitemyapp: `cbp: we're not an official driver and you know that :P

14:35 `cbp: an index would be nice though :p

14:35 bitemyapp: `cbp: you can add one to MD yo.

14:36 `cbp: do you want me to demonstrate in the README.md? Could also make a wiki.

14:36 `cbp: bitemyapp: on another note i was trying to add backtraces but ended up confused and not knowing what to look for so i just left it

14:37 bitemyapp: a demo would be nice, i hope its not the same as selmer's "index"

14:37 bitemyapp: `cbp: ...? @ backtraces - should I take a look or be worried? :P

14:37 `cbp: yes it's Selmer's index, but you can create separate pages and link around.

14:37 with a separate docs/ dir.

14:38 `cbp: bitemyapp: no when you make a mistake rdb gives you a backtrace or so i thought so you can debug

14:38 bitemyapp: yeah the errors.

14:38 `cbp: bitemyapp: right now it just gives you {} And I have no clue if it should be giving you more

14:38 bitemyapp: I'm not totally sold we should reify that to Clojure exceptions.

14:38 `cbp: :backtrace {} i mean

14:38 bitemyapp: i think its just a pprint of a stack trace

14:38 * bitemyapp nods

14:39 `cbp: I guess ill just wait till someone makes an issue "where the f are my backtraces"

14:39 bitemyapp: I'm down with that.


14:42 `cbp: bitemyapp: the FIXMEs are order-by and set-intersection if you're interested in that

14:42 order-by needs some weird syntax and set-intersection gives you weird stuff

14:43 bitemyapp: `cbp: I could look into that. I'm mostly concerned with error handling atm though.

14:43 right now if you stray off the happy path, you end up on the very-unhappy path.

14:43 `cbp: bitemyapp: ok

14:43 bitemyapp: bja expressed an interest in that work, but it needs to happen sooner than later so I'll need to ping them for a status update.

14:44 `cbp: is bja from this channel?

14:44 bitemyapp: `cbp: da

14:49 dnolen: CLJS 0.0-2014 going out

14:49 mdrogalis: Huh, Presto was open sourced. Neat.

14:51 gtrak: is that like better hive?

14:53 mdrogalis: From what I gather, yes.

14:54 Jarda: guys do you use something for freezing time for tests?

14:54 mdrogalis: Jarda: Usually you want to push time out of whatever you're doing. But if you can't, you can use with-redefs

14:55 Jarda: mdrogalis: I need to assert XML output (and I want to do it using strings) so I can't really rule out dates

14:56 mdrogalis: Jarda: I'm not really sure what you mean.

14:57 Jarda: mdrogalis: I have a library that outputs xml with timestamps

14:57 `cbp: mdrogalis: I think he wants to test a (now)

14:57 Jarda: and the timestamps are the current timestamp

14:57 mdrogalis: Right.

15:05 sveri: hi, i read about parallelism and concurrency in the programming clojure book, now i try to rebuild a parallel reduce function and wonder what is best used for this, agents, atoms or futures?

15:05 i tried futures, but somehow i cannot get them to work parallel

15:06 tbaldridge: sveri: futures are the way to go, paste your code?

15:06 TimMc: sveri: refheap.com for pastes

15:07 (Or gist or whatever.)

15:09 dnolen: cemerick: hey I cut 2014, it would be nice to get a version of cljsbuild out that does the right thing for incremental builds

15:09 sveri: tbaldridge: TimMc https://www.refheap.com/20532 there it goes

15:10 justin_smith: technomancy: regarding the debug middleware for replaying ring conversation earlier, I just did a postwalk on a bunch of requests, conjing the class of each object in the request map:

15:10 #{nil org.eclipse.jetty.server.HttpInput clojure.lang.PersistentVector java.lang.Integer clojure.lang.PersistentArrayMap clojure.lang.Keyword java.lang.String clojure.lang.PersistentHashMap}

15:10 so HttpInput is the only stateful thing to look out for, it seems

15:11 bitemyapp: dnolen: we're living in the future now?

15:11 it's 2014 already?!

15:11 TimMc: bitemyapp: Only in Australia, I think.

15:11 tbaldridge: sveri: I think your issue is that you're de-reffing it right after you create it. Create all the futures first, then do @

15:12 sveri: tbaldridge: ah, i see, i hope, so because i deref it in the recursion it executes in every recursion step and then waits until its finished?

15:12 cemerick: dnolen: will do. I already have the commit on the develop/1.0.0 branch, mostly just waiting for 2014 to show up on central

15:12 bitemyapp: sveri: also, addIt -> add-it

15:12 noncom: i am trying to implement an algorithm with loop-recur, but i get "can recur only from tail position" on line 9 https://www.refheap.com/20533 anyone has idea why?

15:12 dnolen: cemerick: cool

15:12 tbaldridge: sveri: right

15:12 sveri: tbaldridge: thank you, i try that

15:13 bitemyapp: are there any "official" coding style guidelines for clojure?

15:13 S11001001: noncom: line 14 is the only thing in tail position in that loop; the if on line 5 is not in tail position

15:13 bitemyapp: sveri: http://dev.clojure.org/display/community/Library+Coding+Standards

15:13 S11001001: noncom: reindent your code and you'll see it

15:13 justin_smith: noncom: recur has to be the very last thing a function does, you need to make it so there is no more work to be done in that function once recur is called

15:13 sveri: bitemyapp: thank you

15:14 TimMc: sveri: Although the bit in that page about keyword args is a very bad idea.

15:14 noncom: so i have to remove the last recur on line 14 then

15:14 TimMc: s/very/pretty/ I guess

15:15 noncom: weehee, worked!

15:15 TimMc: noncom: With that indentation it looks like a three-body if.

15:15 noncom: yes, sorry for that, i corrected it in the refheap. for some reason did not notice initially

15:15 TimMc: Ah, I see.

15:15 Yeah, that whole last line means that the if on line 4 is not itself in tail position.

15:16 sveri: http://mumble.net/~campbell/scheme/style.txt also mostly applies.

15:17 Not official, but widely followed -- and if you use clojure-mode in Emacs, the indentation is nicely standardized.

15:17 sveri: TimMc: well, thats extensive :D

15:17 thank you

15:17 TimMc: Yeah...

15:18 The spacing and indentation stuff at the top is most relevant.

15:25 dnolen: cemerick: the new compiler environment things is great. For making compiler.clj and closure.clj thread safe were you thinking about having a worker queue over the disk? Would be sweet to have real parallel builds.

15:26 justin_smith: I am working on a ring middleware that will replicate requests for replay

15:26 should I bother trying to create an actual org.eclipse.jetty.server.HttpInput object for the body, or just make something that implements the same methods properly?

15:26 dnolen: source map support in CLJS is now rocking

15:26 sritchie: awesome!

15:27 cemerick: dnolen: honestly, nothing is *safe* until we stop using the disk like a global scratchpad

15:27 justin_smith: looks like I could maybe get away with the methods of java.io.InputStream plus a readLine method

15:28 gtrak: dnolen,cemerick: clojurescript gets more fun every day :-)

15:28 justin_smith: I think it just needs to be an inputstream, I've replayed requests by storing the data as strings and creating a bytearrayinputstream over them at runtime.

15:28 dnolen: cemerick: but what's the alternative you have in mind? just always recompile everything from a cold JVM?

15:29 seangrove: dnolen cemerick: Thanks for the ClojureScript release, looks good. Looking forward to getting a new cljsbuild too.

15:29 justin_smith: gtrak: we allow image upload, so instead of string I will do a base64 step then string, but sounds good :)

15:30 or maybe that is already base64 - but I don't want to take for granted that body is 8 bit clean

15:30 cemerick: dnolen: gosh, no. But, writing to disk should be the last thing the compiler does, optionally.

15:31 This is all aside from maybe using the disk for caching compilation results, but in that case, it should be keyed on a hash of the input or something, not filenames or namespace names.

15:32 dnolen: cemerick: I don't see the problem with namespace names - they must be unique

15:35 bitemyapp: justin_smith: not everybody uses Jetty :(

15:35 cemerick: dnolen: for a single build, yes, but they're absolutely not if you have e.g. multiple cljsbuild :builds. Things get mighty strange if you have e.g. the same namespace defined in different files, with different impls (for different JS env targets, using different test frameworks, whatever).

15:36 Right now, nuking out/.repl/target from orbit is the only reliable way of getting proper output in certain cases.

15:36 justin_smith: bitemyapp: what would be my best bet for adapting this so other people could use the middleware and replay - just assume that body is somthing I can io/copy?

15:37 dnolen: cemerick: well I don't see how this is a problem currently, you're not supposed to share :output-dir across builds, cljsbuild doesn't even allow it

15:37 jcromartie_: why is Clojure *so much faster* on my i7 laptop running Linux than it is on my i7 laptop running Mac OS X?

15:37 is it attributable to the JDK?

15:37 bitemyapp: you can't pass a vanilla Ring request object to the damn app?

15:37 jcromartie_: err, JVM

15:37 bitemyapp: justin_smith: I mean, that's how you mock requests for app testing in Ring.

15:37 just a mpa.

15:37 map*

15:38 justin_smith: bitemyapp: I want something I can serialize, what I get from ring has a stream as its :body

15:38 llasram: I wish the JVM supported coroutines

15:38 That'd be so nice

15:38 justin_smith: ie. I want to be able to replay post requests, and get the same thing when reading from the post body

15:38 I realize the outer container is a map, that's great, I want to replicate all the contents too

15:38 bitemyapp: justin_smith: a vanilla BSI might work.

15:39 justin_smith: BSI?

15:39 hiredman: jcromartie_: depends what you mean by faster, and how you are starting the jvm

15:39 cemerick: dnolen: fair point on that. I think I was projecting from having stale .repl around across sessions.

15:39 hiredman: jcromartie_: and what jvm you are using on each

15:40 jcromartie_: hiredman: on OS X, Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)

15:40 gtrak: justin_smith: for reference: https://github.com/mmcgrana/ring/blob/master/ring-servlet/src/ring/util/servlet.clj#L34

15:41 that's all there is o a ring request-map

15:41 to*

15:41 cemerick: dnolen: anyway, my point is, if you're looking to doing something like build parallelization, then the first thing I'd do is eliminate the elephants in the room, if only to eliminate the potential for large classes of errors. Life's too short to be worried about whether intermediate compiler state is correct/live on disk.

15:41 justin_smith: gtrak: OK, so I want to replicate the inputstream and serialize, and have a deserialization (probably using base64 so it can be a literal in a file for a unit test)

15:41 bitemyapp: destroy all state!

15:41 hiredman: jcromartie_: I am not saying if you tell me all those things I'll have answer, I am just listing all possible things

15:41 bitemyapp: robashton: welcome to the club.

15:42 jcrom_linux: on Linux: OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)

15:42 `cbp: anarchist!

15:42 jcrom_linux: starting with "lein repl"

15:42 bitemyapp: `cbp: <3

15:42 justin_smith: gtrak: yeah I figured that out by calling conj on a set atom with a post walk checking the class of everything that came in

15:42 robashton: not promising I'll hang around, I'm awful at remembering to start irssi and it doesn't look like I backed up my scripts on my last laptop that got stolen so...

15:42 justin_smith: the :body was the one stateful thing I found :)

15:42 robashton: but I WILL GIVE IT A GO

15:42 bitemyapp: robashton: just run a persistent irssi session like I do.

15:42 gtrak: justin_smith: yea, that oughta be enough.

15:43 bitemyapp: sits on a $5 VPS in GNU Screen, connect to said server via mosh.

15:43 robashton: I have a server to do that with

15:43 bitemyapp: welp.

15:43 robashton: but the only private key was on my stolen laptop :D

15:43 so I need to rebuild that

15:43 gtrak: justin_smith: only a few middlewares slurp the body, it can be a pain to deal with :-).

15:43 justin_smith: gtrak: yeah, tell me about it

15:43 stuartsierra: What's the Typed Clojure channel?

15:43 gtrak: wrap-format-params will do it

15:43 clojurebot: Excuse me?

15:43 dnolen: cemerick: I'm not tied to the current strategy of course, just happy to have to somebody else work on it - and whatever they come up with needs to deal w/ all the different build settings that need information about what's on disk (importantly source maps)

15:43 justin_smith: bbl lunch, thanks guys

15:44 bitemyapp: stuartsierra: #typed-clojure

15:44 jcromartie_: running this: (dotimes [_ 10] (time (last (map str (range 10e6)))))

15:44 average is about 1.8X longer on OS X

15:44 it would be good to run the same JVM I guess :P

15:45 Uatec: o/

15:45 stuartsierra: thansk

15:46 hiredman: jcromartie_: use criterium for benchmarks

15:50 Jarda: java.lang.UnsupportedOperationException: nth not supported on this type: Character

15:50 hiredman: jcromartie_: others would know better, but I think lein may pass different flags to the jvm on osx and on linux to try and improve startup time

15:50 Jarda: oh that was a helpful error message, thank you clojure

15:51 and the stacktrace isn't helping either..

15:51 it comes somewhere inside xml/emit-str

15:51 bitemyapp: Jarda: you're iterating over a string and then trying to iterate over a character.

15:51 Jarda: not that hard to understand.

15:51 llasram: Jarda: Usually happens when you passed a string instead of a sequence of strings somewhere

15:51 cemerick: dnolen: Sure. I don't think it's a *huge* priority compared to other things, though? I mean, what is your primary objective w.r.t. state management, parallel builds, or other/more?

15:52 bitemyapp: ,(doseq [c (str "blah")] (println c))

15:52 clojurebot: b\nl\na\nh\n

15:52 Jarda: llasram, bitemyapp yeah. But _I_ don't iterate over anything. clojure.data.xml/emit-str does

15:52 bitemyapp: ,(doseq [c (str "blah")] (doseq [x c] (println x)))

15:52 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character>

15:52 dnolen: cemerick: yes, not a priority at all at the moment :)

15:52 hiredman: Jarda: but you pass it data, and the data is in the wrong format

15:52 Jarda: hiredman: yeah, and it's a very complex data structure. I'm just cursing that I have to now reduce it element by element..

15:53 hiredman: e.g. {:tag :span :content "foo"} vs. {:tag :span :content ["foo"]}

15:53 dnolen: cemerick: the :libs stuff and :main support way more important

15:53 cemerick: yeah

15:53 hiredman: Jarda: writing a little function to walk the structure and verify it is not hard

15:53 cemerick: :libs [""] is getting very tedious :-)

15:54 hiredman: Jarda: even less hard if you use something from clojure.walk to do the walking for you

15:55 dnolen: cemerick: :main would mean people have to be more disciplined then they are about how they use a namespace (especially macros that assume a the lib will get included anyway)

15:56 ucb: bitemyapp: good stuff

15:56 hiredman: (fn [x] (assert (or (not (map? x)) (and (contains? m :tag) (contains? m :attrs) (contians? m :content) (keyword? (:tag m)) (or (empty? (:content m)) (coll? (:content m))))) m))

15:59 jared314: Is there something already built that merges two ns forms?

15:59 cemerick: dnolen: I need to understand the specifics of the compilation process more before I touch :main. :libs I can do straight away.

16:00 dnolen: cemerick: yeah :main is going to be tricky

16:13 bitemyapp: robashton: http://dev.clojure.org/display/design/Resource+Scopes

16:14 Bronsa: dnolen: I'm sorry I was away

16:14 dnolen: cemerick: oh, I was thinking about about renaming the default-warning-handler* multimethod to error-string so that tools get the standard error string for an error/warning?

16:14 Bronsa: dnolen: btw no -- I'm waiting for a patch from aredington

16:15 dnolen: Bronsa: got it, we could definitely use it for REPLs especially browser REPL

16:15 Bronsa: xeqi has shown that it's possible to do dynamic source maps today

16:16 bitemyapp: I don't know how I feel about dynamic/nearest-enclosing scopes.

16:17 sritchie: seangrove: any luck from before?

16:17 with that test issue?

16:17 seangrove: sritchie: No, trying to deploy a new blog post and suddenly heroku's config has changed out from under us

16:17 sritchie: huh, weird

16:17 new buildpack or something?

16:17 seangrove: Will circle back to the clojurescript.test stuff in a bit

16:17 sritchie: cool

16:18 seangrove: cemerick's right there though, could ask him

16:19 melipone: hello! how can I spit out to file a lazy sequence so that it can be read back by slurp?

16:19 cemerick: dnolen: so they *can* get the standard error string? Yeah, +1.

16:20 dnolen: cemerick: ok cool

16:20 cemerick: dnolen: error-message?

16:20 dnolen: cemerick: sure

16:20 TimMc: melipone: Bind *out* to a writer (use with-open) and pr it.

16:20 it = the lazy seq

16:20 melipone: timMc: okay, no spit then?

16:21 gtrak: would this not also work? #(spit *out* '(1 2 3 4 5))

16:21 melipone: gtrack: the problem is that it's a lazy sequence

16:22 gtrak: melipone: ah, gotcha, spit doesn't use print-dup

16:24 TimMc: Yeah, I don't know why it just uses str.

16:26 gtrak: turns out there's a private pr-on method.. silly

16:28 Bronsa: dnolen: cool. FYI I just pushed a patch to add end line/column info, once I get the source info patch I'll release a 0.8.0

16:39 yeoj____: should i be concerned if I have a tendancy to have massive let bindings.

16:39 i guess i'm wondering on whats the rule for when i should break things out into functions...

16:40 bitemyapp: yeoj____: they can be made into constituent fns. Not uncommon though.

16:41 yeoj____: bitemyapp: thanks.

16:41 bitemyapp: yeoj____: I have a 40 something LOC long let body in bulwark. meh.

16:41 hasn't merited refuctoring yet.

16:43 gtrak: useful for splitting those up, pass a map around: https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L8

16:43 cemerick: oh, I just realized what :declared metadata does, sweet

16:49 akurilin2: What do you do when something funky happens such as not being able to find a certain function under ring.util.response even though it worked just fine up until a second ago

16:49 Last time I had accidentally edited a library .jar contents

16:49 and nuking them was probably helpful

16:49 bitemyapp: akurilin2: lein clean && rm -rf ~/.m2 && lein deps && lein test

16:49 akurilin2: can I forge lein to clean and re-download deps to be on the safe side?

16:49 bitemyapp: you can elide the call to deps.

16:50 gtrak: akurilin2: you can be more specific about deleting stuff out of ~/.m2 as well

16:50 otherwise you're downloading the internet

16:50 bitemyapp: gtrak: don't be weak.

16:50 gtrak: bitemyapp: I'm not weak, I'm lazy and easily frustrated :-)

16:51 akurilin2: Let me try that

16:51 bitemyapp: gtrak: Downloading the internet means I have time to read about monads or pull pranks on my coworkers.

16:52 arrdem: gtrak: those seem to be a common personality traits among programmers...

16:54 gtrak: we have 'lein test' for that, takes like 10 minutes a pop.

16:54 gotta make sure it all still works!

16:57 akurilin2: Where are the contents of a library such as ring? I just unzipped ring-1.2.1.jar from my .m2 and only got a META-INF folder in there

16:58 App can't seem to find "get-header" function which should be there, so I'm trying to see by hand

17:01 Oooh it's defaulting to ring-core 1.1.7 for some reason :|

17:01 Odd, project.clj uses 1.2.1

17:01 joegallo: run `lein deps :tree` to see what's pulling in that version

17:04 akurilin2: joegallo, indeed, just done that. Compojure 1.1.5 kept using 1.1.7, so I had both versions of ring i nthere

17:04 Updating to 1.1.6 fixed it, HOWEVER I'm still not sure how the version is decided

17:04 when I reload a namespace

17:06 arrdem: anyone know a good writeup on core.typed HMaps?

17:12 muhoo: for some reason, whenever i read "compojure", i find myself wanting to sing it like http://www.youtube.com/watch?v=hzFsDQeTUT4

17:12 * muhoo is not normal

17:12 nDuff: muhoo: Who here is?

17:19 seangrove: bitemyapp: Like blackwater, but wouldn't mind seeing output for the ddl stuff as well

17:20 bitemyapp: seangrove: I just need a repro/example and it can be added.

17:21 seangrove: would you be willing to file a github issue please?

17:22 gtrak: akurilin2: the easiest way to inspect lib code is M-. in emacs

17:22 after that, I look at github.

17:22 akurilin2: gtrak, that's what I do right now with fireplace, that's how I discovered that I was using 1.7.1

17:23 gtrak, the point I'm trying to make is that I'd love to know how it decides which version to load

17:23 *require

17:23 gtrak: akurilin2: well, what you probably want is to force a specific version

17:23 seangrove: bitemyapp: Sure, will do after a quick nap

18:34 logic_prog: I'm looking for something better than pprint. I want (print-this-sexp-as-it-appears-in-main.clj ... ) -- the point being, I have a chunk of code. I want to output a HTML file saying, "here is the chunk of code / here is the output" -- and I'd prefer the "here is the chunk of code" preserve the newlines I have in main.clj (when I wrote the iringial chunk of code) rather than wahtever alogirhtm pprint uses to format my code

18:44 bitemyapp: arrdem: http://i.imgur.com/tqkhfz7.jpg

18:44 arrdem: DINNA TIME

18:45 Apage43: logic_prog: look at what (source) does

18:46 logic_prog: (source source) teehee

18:46 Apage43: (What it does is this: it looks up the :line metadata for a var and then reads the first form on said line, wrapping the PushbackReader the reader is reading through and capturing what it reads)

18:47 thereby capturing whitespace, comments and such

18:48 logic_prog: actually

18:48 (source source-fn) returns for me:

18:48 Source not found

18:48 is my clojure installation screwed up?

18:48 I'd really like to be able to use (source) from the repl

18:48 or, --- is source-fn a java primitive?

18:48 Apage43: have you (use 'clojure.repl) 'd

18:49 source is in clojure.repl

18:49 https://github.com/clojure/clojure/blob/master/src/clj/clojure/repl.clj#L134-L154

18:49 logic_prog: ah, it worksnow :-)

18:49 Apage43: thanks!

18:50 justin_smith: I am working on a ring middleware that duplicates the request in order to replay for testing / debugging

18:50 the only stateful part of the request is the :body

18:51 I can duplicate the :body of the request to a bufferedinputstream but this seems to break my middleware - I guess I need to create some other kind of readable stream

18:51 does anyone know what may be going wrong here?

18:51 there is no error, its just that the webapp acts like the request had no body (it is a post that should update the db)

18:53 arrdem: bitemyapp: go away... core.typed is calling me names. don need u helpin

19:03 bitemyapp: arrdem: lawl


19:04 core.typed insults <3

19:06 arrdem: bitemyapp: core.typed is fun... you get to facepalm at all the key not found cases you forgot to account for

19:06 bitemyapp: the upside is that you feel smart as shit when the error count goes down

19:07 bitemyapp: arrdem: I ride the GIGO-LEL LEL LEL LEL train too much in Clojure.

19:07 I think my code would upset technomancy.

19:09 arrdem: bitemyapp: that's where I stand normally, but this is an experiment in c.c.t comma damnit and I'm gonna make this shitty single cycle processor typesafe if it's the last thing I do

19:11 * devn stares at core.logic for a few hours, trying to think of how to use it with the getclojure data

19:12 bitemyapp: devn: I'd be jazzed as all get-out if you just stopped using Heroku so getclojure didn't break every 24 hours :(

19:13 arrdem: devn: can we get a "top 100 least understood symbols" list? :D

19:14 jared314: devn: what data sources do you use for getclojure?

19:22 bitemyapp: devn: datalog yo.

20:17 jtoy: anyone here made lein templates before?

20:17 seangrove: jtoy: Yeah, but I just took another one and hacked on it until I liked it

20:41 devn: jared314: I use the clojure irc logs from the last 5-6 years

20:41 parse sexps, eval in sandbox, capture, repeat

20:42 jared314: (str "including this one?")

20:42 or do you have criteria?

20:42 sritchie: lynaghk, do you have any naming convention advice for cljx code?

20:42 specifically,

20:42 I'm thinking about namespaces that are mostly cljx, but need some extra cljs or clj specific additions

20:43 oh, now that I say it, I bet there's some reader macro that lets you demarcate sections

21:26 reiddraper: hey dude

21:26 around?

21:26 reiddraper: qq about simple-hceck

21:27 is it possible to combine properties?

21:28 reiddraper: sritchie: there's no explicit functions for it now

21:28 sritchie: I'm writing the monoid laws

21:28 and need to say "associative", plus "zero is identity"

21:31 reiddraper: sritchie: sort of like this? https://github.com/reiddraper/simple-check/blob/v0.5.3/test/simple_check/core_test.clj#L12-L26

21:31 so the short answer is right now, you'll just need to encode all of those things into a single expression/function that returns a boolean

21:32 right now there's no helper to say, these two passed, but this one failed, if that makes sense

21:34 sritchie: reiddraper: boom

21:35 https://gist.github.com/sritchie/7348015

21:35 like that, sort of

21:35 thanks dude

21:36 minikomi: hello from tokyo, fellow clojurians

21:36 reiddraper: sritchie: yeah looks solid to me

21:38 minikomi: hi

21:40 devn: jared314: including the one you just pasted. anything that looks valid and is unique gets run in the sandbox.

21:40 jared314: devn: very cool

21:41 arrdem: bitemyapp: a couple hours and coffee later, c.c.t points out that my program is fundimentally type unsafe. facepalm.

22:10 sritchie: reiddraper: any plans to make simple-check work for cljs?

22:10 via cemerick's clojurescript.test?

22:11 looks like random is the only thing that doesn't work

22:34 bitemyapp: arrdem: hey

22:35 arrdem: bitemyapp: yarrr

22:35 bitemyapp: arrdem: do you have the bro-dude's computer handy?

22:35 arrdem: bitemyapp: probably

22:35 bitemyapp: writing patch for c.c.t then totally down for w/e

22:36 bitemyapp: yisssssss

22:36 arrdem: oooh, patch! you'll have to tell me about in mumburrrr

22:47 `cbp: bitemyapp: I fixed the group-by, set-intersection stuff

22:48 group-by now works properly, i deployed a new version with it

22:48 We now support pretty much every rdb query :-P

22:49 bitemyapp: `cbp: awesome.

22:49 `cbp: if bja doesn't pop up I will proceed with error handling

22:49 `cbp: ok

22:50 bitemyapp: `cbp: I take it 0.0.3 has your changes?

22:50 `cbp: bitemyapp: yeah

22:50 bitemyapp: `cbp: also, start keeping a changelog.md

22:50 `cbp: it'll save yours and users' sanity.

22:50 seangrove: thanks for the github issue btw

22:51 `cbp: bitemyapp: group-by now doesnt give you "cannot divide by 0" now :P

22:51 bitemyapp: lol.

22:51 `cbp: bitemyapp: good idea

22:51 seangrove: bitemyapp: Easy enough to open a ticket, you can thank me if I send a pr (which I don't see happening) ;)

22:51 bitemyapp: `cbp: just start by adding 0.0.3 and explaining what you added/changed/fixed/removed

22:51 seangrove: not that blackwater is hard to understand, that's fine.

22:53 seangrove: not that I disagree with adding it, I'm a little surprised anybody cared about logging migrations.

22:53 I guess it makes sense if they're generated rather than hand-written.

22:53 seangrove: bitemyapp: Tried to give a rationale of why it would be nice for us

22:53 bitemyapp: yup, makes sense to me.

22:54 seangrove: mostly I'm just happy somebody is using it.

22:54 seangrove: bitemyapp: I like that it's a separate library, something very simple that anyone else can come along and use. Makes me happy to see.

22:56 bitemyapp: seangrove: I'm an advocate of interchangeable tools, micro-libraries, etc. Especially when the build/dependency tooling is as good as Leiningen.

22:57 `cbp: bitemyapp: er the commit message should be group-by not order-by.. oh well..

22:57 bitemyapp: `cbp: you can amend commits yo.

22:57 `cbp: it's your baby, amend the commit and -f push that.

22:57 seangrove: of course, it's easier to write micro-libs like this when you abuse AOP :)

22:58 I should try to make a round-trip of PR'ing API changes to every library Corfield works on.

22:58 just to see if I can

22:59 gvickers: xg

22:59 bitemyapp: gcmalloc: indeed!

23:08 muhoo: (comp face palm)

23:12 bitemyapp: muhoo: ?

23:23 my sanity and clojure.java.jdbc are like oil and water.

23:23 when one arrives on the scene, the other vanishes, not to be seen for another week.

23:28 satshabad: is there a way to peek at the next value in a reduce?

23:28 or is that Bad?

23:32 bitemyapp: satshabad: bad.

23:32 satshabad: explicitly make an overlapping series of partitions if you must.

23:32 ,(partition 2 1 (range 10))

23:32 clojurebot: ((0 1) (1 2) (2 3) (3 4) (4 5) ...)

23:36 Raynes: devn: I only care if I have to work with their code. :p



23:43 * bitemyapp coughs and clears throat.

23:44 muhoo: settle down, cowboy

23:45 bitemyapp: muhoo: jdbc and databases make me unhappy.

23:45 muhoo: keep calm and use datomic. in-memory database + fixtures = repeatable tests

23:46 uvtc: What are the naming conventions around leading and trailing dashes in function names? The first one that comes to mind is `defn` and `defn-`, but my Clojure apps have a `-main` in them...

23:46 xuser: bitemyapp: that's because jdbc is the only way to go

23:46 +sad

23:46 marco1: uvtc: defn- is private while defn is public

23:46 pretty sure -main is just by convention

23:46 muhoo: defn- isn't convention, it's code

23:47 ,(doc defn-)

23:47 clojurebot: "([name & decls]); same as defn, yielding non-public def"

23:47 uvtc: Yes. I see that one. I was wondering about reconciling all the places where I see a leading or trailing dash.

23:47 But those are the only places I've seen them so far. :)

23:48 ,(apropos #"^-[^>]")

23:48 clojurebot: (-' -reset-methods -cache-protocol-fn)

23:49 uvtc: ,(apropos #"-$")

23:49 clojurebot: (- defn-)

23:49 uvtc: Mm.

23:50 Ok. Not many of them, it would seem. And I think I need to learn

23:50 more about genclass to learn the significance of the `-main` naming.

23:52 bitemyapp: muhoo: I'd be using Datomic right now if I could, sadly Blackwater is written to ameliorate the damage SQL databases do to peoples' sanity.

23:53 xuser: bitemyapp: is Datomic production ready?

23:53 bitemyapp: xuser: I'm using it in production at work right now.

23:54 xuser: It's best suited for the scrappy soul at the moment, but it's already quite nice and gets the job done.

23:54 xuser: bitemyapp: how's the performance?

23:54 bitemyapp: xuser: I'm working on releasing a migration toolkit for it.

23:54 xuser: better than you'd expect @ perf.

23:54 technomancy: uvtc: leading dash signifies gen-class methods

23:54 that's why -main has it

23:55 xuser: bitemyapp: a migration toolkit to migrate from where? SQL?

23:55 marcopolo2: technomancy: huh, cool

23:55 Is that necessary, or just convention?

23:55 bitemyapp: xuser: a migration toolkit to migrate datomic databases.

23:55 xuser: ah}

23:56 technomancy: marcopolo2: you can override it in the :gen-class clause, but IMO that's silly

23:56 uvtc: technomancy, thanks. Need to read up on that.

23:56 technomancy: uvtc: if you're lucky you won't =)

23:57 uvtc: :)

23:57 bitemyapp: seangrove: it's done.

23:57 uvtc: What, in general, does the trailing asterisk signify? (For example, `list` vs. `list*`.)

23:57 xuser: ship it!

23:58 uvtc: Naming-convention-wise, I mean.

23:58 seangrove: bitemyapp: Cut a new release?

23:58 bitemyapp: uvtc: stuff with an asterisk is typically "primitive"

23:58 seangrove: doing so right now as soon as maven stops giving me a noogie and calling me names.

23:59 uvtc: bitemyapp, "primitive"?

23:59 bitemyapp: seangrove: pushed

Logging service provided by n01se.net