#clojure log - Dec 28 2012

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

0:00 callen: jlewis: read it a long time ago.

0:00 nice recall.

0:00 jlewis: well, we named a program at work 'granger' for that exact reason. so it's not too crazy.

0:01 technomancy: nice

0:02 callen: I wonder if the rate of usage of literary references in library names is higher among Clojurians than other communities?

0:02 Raynes: yogthos: Do you use the twitters?

0:02 callen: Raynes: what are you in birdland?

0:02 yogthos: Raynes: never made an account :)

0:02 Raynes: probably should

0:02 Raynes: yogthos: Just wondering how we should announce this.

0:02 Perhaps a mailing list post?

0:02 callen: yogthos: believe it or not, it's actually good for following other programmers.

0:02 Raynes: Do you have an existing post about luminus, yogthos?

0:02 callen: yogthos: as long as you're very choosy about whom you follow.

0:03 yogthos: you have to learn to unfollow the people that retweet garbage.

0:03 Raynes: You have to learn to block the people who still do follow friday.

0:03 yogthos: Raynes: just the blog, I'll make one with the updates

0:03 callen: my marginal utility for twitter is higher than facebook. Boring people I'm socially obligated to "friend" are on there, Twitter is voluntary.

0:03 Raynes: Gah.

0:03 yogthos: but yeah it would make sense to twitter that sort of stuff eh :)

0:03 ok on it :)

0:03 Raynes: I twitter all my blog posts and have become pretty famous for it.

0:03 * Raynes files his nails.

0:03 callen: Raynes: what's your twitter?

0:04 Raynes: IORayne

0:04 callen: thank you.

0:04 Raynes: Because every bloody useful permutation of 'Raynes' has been taken.

0:04 yogthos: oh turns out I did make a twitter account :P

0:04 it's just very unused :P

0:05 Raynes: yogthos: If you tweet it, they will come.

0:05 yogthos: Raynes: noted :)

0:05 I just need people to follow me now ;P

0:05 mpan: I've considered getting a twitter

0:05 possibly a separate one for coding vs personal life

0:05 Raynes: Meh.

0:05 I don't bother.

0:05 If people don't like my personal tweets, they just don't like me anyways.

0:06 callen: mpan: just don't do anything "personal" on Twitter, it's a pessimal use-case.

0:06 mpan: well, I think I have two separate audiences in my life, and each is likely to get very bored of the other

0:06 callen: mpan: it's way more interesting for professional/coding stuff. Who cares if I'm going to an Indian restaurant on Twitter? jesus.

0:06 I don't use twitter because I want to broadcast minutiae.

0:06 Raynes: I don't make a habit of tweeting about my bowel movements and crude thoughts about the opposite sex.

0:06 amalloy: there are indian restaurants on twitter?

0:06 mpan: lol parsing

0:07 callen: amalloy: I didn't know comedy was allowed in #clojure

0:07 $GUARDS

0:07 yogthos: ha

0:07 Raynes: $guards

0:07 lazybot: SEIZE HIM!

0:07 callen: I even got the prefix right this time.

0:07 mpan: I heard someone recommend we write english in s-expressions to denote desired parsing

0:07 amalloy: callen: ~guards is more popular

0:08 callen: mpan: no, you have to go full-virgin and just use lojban.

0:08 Raynes: callen: I follow Gerard Way.

0:08 nodename: core.logic question: can I add a constraint that will choose a random value from what would have been the return list?

0:08 mpan: callen: is that unambiguous parse?

0:08 Raynes: He is about the most useless twitterer ever, but I <3 him anyways.

0:08 callen: mpan: unambiguous logic too.

0:08 * mpan is slightly worried

0:09 callen: mpan: what?

0:09 mpan: about such a language for humans

0:09 callen: mpan: *shrug*

0:10 mpan: dunno

0:10 not sure how happy creative writing would be about such a language

0:10 callen: mpan: I don't know, I'm pretty sure the sort of people that learn lojban are all sysadmin trekkies.

0:11 Raynes: yogthos: Anyways, good work. Happy to be working with you on this.

0:11 yogthos: Raynes: likewise :)

0:11 Raynes: Together we shall fix web development in Clojure.

0:11 amalloy: nodename: you can't do "random" anything relationally. and i don't understand what you meant by "return list"

0:11 yogthos: that is totally the plan

0:11 * Raynes dons his cape and flies away.

0:11 mpan: I like the sound of that

0:11 yogthos: :)

0:11 callen: Raynes: and your little dog too.

0:11 mpan: I would be very interested in fixed web dev in clojure

0:12 nodename: by 'reurn list' I mean the list of values returned by run*

0:12 yogthos: my main plan is to make it dead simple, especially for people who are curious about doing clojure stuff coming from python or whatever

0:12 first one's free :P

0:12 Raynes: s/simple/sexy/


0:12 callen: why is batsov trying to drop slime support in clojure-mode?

0:12 yogthos: :)

0:12 mpan: could be quite compelling if you make a good alternative to the heavy frameworks out there

0:13 and sell people on the "easier to get started" angle

0:13 yogthos: that's what I'm thinking

0:13 nodename: ah dnolen can you see my core.logic question from a few minutes ago?

0:13 callen: mpan: compojure and ring get us close to something like Sinatra, but the story isn't full yet and some people are going to be looking for something like Rails or Padrino. I haven't decided how to address that yet.

0:13 yogthos: I find with big frameworks a lot of time it doesn't actually save work, you just end up having to do different work

0:13 mpan: I mean, I'm probably going to learn <framework redacted> for the sake of a job before long

0:14 but honestly, yea, it feels like

0:14 callen: OTOH, the Rails community today was bickering over the default scaffold .gitignore, so they may not be the role models we want.

0:14 yogthos: haha

0:14 I think we have a big advantage with the jvm

0:14 mpan: the amount of work I save implementing is more than made up by the amount of work I'd need to spend mentally juggling the knowledge of said framework

0:14 yogthos: stuff like lein is way ahead of a lot of build tools

0:14 and the performance is good

0:15 really the only thing to do is to package all these nice things into a pretty bundle :)

0:15 callen: mpan: I come from Django and Flask land, so I've fully explored both ways.

0:15 mpan: in my experience, long-term, the "minimalist" path only works if you 1. Have great libraries 2. Aggressively promote the idiomatic usage of those libraries.

0:15 otherwise people will, in the absence of guidance, revert to using the heavy-handed stuff.

0:15 mpan: first part is huge

0:16 yogthos: callen: yeah I agree good libs are key

0:16 mpan: otherwise people will hit you with the argument of

0:16 yogthos: and one place for docs

0:16 mpan: "I can do X in framework F..."

0:16 yogthos: I can't stress that enough

0:16 Raynes: yogthos: lib-noir + luminus = http://www.youtube.com/watch?feature=player_detailpage&v=5110hk9W71E#t=24s

0:16 yogthos: ROFL

0:16 egghead: I like the build your own framework approach, some lein plugin or something that asks you what you want to use for templates/persistence/routes

0:17 Raynes: I highly suggest you close the browser window immediately after that scene, for what follows may offend your sensibilities.

0:17 mpan: Raynes: I was expecting informative but I got humorous instead

0:17 that works too

0:17 callen: yogthos: mpan: do not under-estimate the importance of pedagogy and idioms in teaching them to use those libraries.

0:17 yogthos: :)

0:17 callen: that's kind of the plan for the luminus site

0:17 mpan: well, I may be the poster-boy for being unable to focus long enough to learn a heavy framework

0:17 =P

0:18 yogthos: I should actually change it to pull the md files straight off gituhb :)

0:18 callen: I figured, that's why I was keen on it.

0:18 yogthos: then people can just send pull requests with tutorials and whatnot

0:18 callen: mpan: I got very familiar with Django, to the point that I was comfortable writing patches and knowing the least-pain path for most things you could want.

0:18 mpan: it took a long time before i became more productive in Flask.

0:18 and even then, it was almost a wash in some circumstances.

0:19 mpan: you cannot learn from the mistakes of others if you don't also know what they did right.

0:19 yogthos: I personally much prefer libs to frameworks, I just want lego blocks to put together :)

0:20 with a real framework you gotta get inside somebody's head and think the way they were thinking when they wrote it

0:20 callen: I eventually came to the same conclusion, but there is a *reason* Django and Rails are so popular.

0:20 yogthos: callen: easy to start with :)

0:20 mpan: and they've got huge ecosystems of stuff that only works with them

0:20 yogthos: mpan: but django is relatively new, so it ramped up pretty fast

0:20 callen: yogthos: partly, they're really productive in the beginner and intermediate stages.

0:21 yogthos: Django isn't new, it's 7 years old.

0:21 dnolen: nodename: I did not, what was it?

0:21 yogthos: callen: it's been around that long? :)

0:21 callen: yogthos: yes, keep in mind I have no small amount of affection for that community. They saved from the .NET world.

0:21 yogthos: callen: ha!

0:22 nodename: can I add a constraint that will 'choose' a random element from what would have been the list of possible values for q?

0:22 callen: yogthos: just because I believe I've found something better doesn't mean I'm going to damn them when I've seen the Hell that is ASP.NET, J2EE, etc.

0:22 yogthos: callen: I find J2EE crowd has a serious case of stockholm syndrome

0:23 callen: yogthos: spot on.

0:23 shortest and sweetest summary I've ever heard.

0:23 "Why is a monad like a writing desk?: A presentation by Carin Meier at Clojure/West" <--- the monad analogies need to stop.

0:24 dnolen: nodename: yes that's possible

0:25 nodename: yes? how?

0:25 dnolen: nodename: one second

0:25 nodename: it doesn't even require a constraint

0:26 nodename: hmm actually, I probably need more information about what you're trying to do ...

0:27 nodename: dnolen: trying to generate random legal strings in a dsl

0:27 dnolen: that conform to a dsl, that is

0:27 dnolen: nodename: and you don't need to run any other operations on them w/in core.logic?

0:28 amalloy: dnolen: i responded to him earlier, before he re-asked the question. i'm surprised you answered so quickly that he can do it; what's wrong about my answer? -- you can't do "random" anything relationally. and i don't understand what you meant by "return list"

0:28 nodename: dnolen:um I guess; I do have to do random generating recursively to a given depth

0:28 amalloy: seems dnolen knew what I meant

0:29 dnolen: amalloy: that's not totally true ... though I haven't tried it much so it possible some of the things I menat mention are "unsound"

0:29 might mention

0:29 nodename: amalloy: and there are "things" on stackoverflow about doing random in prolog

0:30 dnolen: not entirely sure core.logic is the way to do what I want but it sort of smells like it

0:31 dnolen: nodename: again I still don't have any idea what you're trying to do

0:32 nodename: it's easy to make a value that hooks into value forcing, but this doesn't account for unification and many other things.

0:32 nodename: want to genreate random expressions in the dsl defined in mikera's clisk library; the exprs when evaled will produce images

0:32 dnolen: nodename: what will (== random-unforced-value0 random-unforce-value1) mean?

0:33 nodename: dnolen: sorry I don't understand

0:33 dnolen: nodename: yeah, I can show you something, but I have no idea if it will do what you want.

0:33 nodename: dnolen: ok please do

0:33 dnolen: nodename: when you're adding custom types to core.logic you have to be aware of the interactions.

0:34 nodename: I do think a few defrels are appropriate

0:34 dnolen: (run* [q] (== q (rand-nth vector-of-stuff)) coudl just work.

0:35 nodename: yeah there no support for random selection over defrels

0:35 nodename: (def named-colors

0:35 ["black" "blue" "cyan" "darkGray" "gray" "green"])

0:36 (for [c named-colors]

0:36 (fact color c))

0:36 (run* [q]

0:36 (color q))

0:36 oh yeah there was (defrel color c)

0:36 dnolen: nodename: yes that won't work. Will had something call condp that kinda does what you want but I haven't implemented it.

0:36 nodename: damn

0:37 callen: dnolen: I take you liked Bodil's tweet too?

0:37 dnolen: nodename: support for stuff like that is definitely something I'm thinking about but I don't have bandwith for it at the moment.

0:38 callen: dnolen: it actually comforts me that I see this sort of thing in Rails and not clj.

0:38 nodename: dnlen: can't think of another approach atm

0:38 dnolen: callen: I just thought it was funny

0:39 nodename: yep sorry, list of core.logic todos is just too long at this point. I'm really at the point where if people want to see stuff they gotta send me patches.

0:39 nodename: dnolen: haha

0:39 dnolen: nodename: at the same time don't lose hope - condp is like 50 lines of code or something - so I might feel inclined one day.

0:40 tomoj: is the version someone already wrote not available? :(

0:40 nodename: dnolen: I am trying to do this project NAO

0:40 dnolen: tomoj: one second, I can paste, someone can port

0:40 callen: dnolen: No, this was the funniest one - vmg: Everybody in Rails core has great plans for the future of the framework, but they all involve cutting the brakes of a very expensive racecar

0:40 dnolen: you hae understand syntax-rules which ain't so bad

0:40 tomoj: port.. from minikanren?

0:41 callen: dnolen: have you seen gfredericks' 4clj for core.logic?

0:41 dnolen: have at it, http://gist.github.com/4394782

0:41 doesn't look very challenging.

0:41 will take a port from first person w/ a CA

0:41 callen: yes it's cool

0:42 nodename: NAO?

0:42 nodename: dnolen: yes, RIGHT NAO

0:43 dnolen: nodename: oh heh :) yeah sorry I can't help!

0:43 nodename: dnolen: so this condp, is it related to may question?

0:44 dnolen: nodename: yep, it's a weighted version of conde, so it will randomly pick a branch based on weight - it's non-terminating tho so you have to specify your # of answers I think - which may or may not work for you.

0:45 tomoj: can't just get a lazy seq of answers I guess?

0:46 dnolen: tomoj: that actually on the list of todos - I finally see how to make core.logic queries properly lazy.

0:46 tomoj: cool

0:46 nodename: dnolen: I see, well time for me to get to studyin then, I'm not too savvy w macros yet tho

0:46 tomoj: I will try to understand this condp in hopes that it will let me write a nice shuffleo

0:50 nodename: Buffalo

0:54 UberNerdGirl: hullo again

0:55 I'm a bit more familiar with Scheme than Clojure. Would the Clojure equivalent of Scheme's (null? foo) be (empty? foo) ?

0:55 dnolen: UberNerdGirl: depends, empty? if foo is a collection, but (nil? foo) works as well too depending.

0:56 mpan: what specifically are you trying to test for? note that clojure has a few more values that may be interesting to that question

0:57 UberNerdGirl: I would like to check for quality to (), or an empty list

0:57 dnolen: oh hello :)

0:57 mpan: um, would you want [] or similar to qualify?

0:57 dnolen: UberNerdGirl: hey! empty? works.

0:57 UberNerdGirl: mpan: i'm afraid all of that escapes me

0:57 okay, i shall use empty? for this case

0:57 dnolen: ,(empty? ())

0:58 UberNerdGirl: dnolen: i think that's for the HS room

0:58 dnolen: hmm clojurebot is gone.

0:58 UberNerdGirl: it works here too

0:58 UberNerdGirl: oh

0:59 dnolen: $(empty? ())

0:59 hmm, I never remember the lazybot commands

1:00 tomoj: &(empty? ())

1:00 lazybot: ⇒ true

1:00 UberNerdGirl: rad

1:00 dnolen: right

1:00 tomoj: &(if (seq ()) :not-empty :empty)

1:00 lazybot: ⇒ :empty

1:00 tomoj: &(doc empty?)

1:00 lazybot: ⇒ "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"

1:01 mpan: nil is empty, list-of-zero-elements is empty, but so are the other collections-of-zero-elements

1:05 callen: so uh...is this where we link the egal CL paper again?

1:06 Raynes: dnolen: lazybot forgives you.

1:06 tomoj: wonder how long till you saying that will automatically cause my client to show me a link to the paper

1:06 lazybot: I does not exist in my database.

1:07 tomoj: hmm, lazybot knows it's not self-aware?

1:07 lazybot: I do not forgive dnolen.

1:07 mpan: you guys have made me curious now; which paper is this?

1:08 tomoj: google says http://home.pipeline.com/~hbaker1/ObjectIdentity.html

1:10 hmm, I must not understand syntax-case, cus lambdag@ looks just like lambda

1:10 mpan: thanks!

1:10 tomoj: er, s/case/rules/

1:10 dnolen: tomoj: it is just lambda, it a macro that's done just to denote something - has no meaning.

1:10 er I mean as far as what it becomes

1:11 lambdag@ just becomes lambda

1:11 tomoj: great

1:12 dnolen: tomoj: only real weird thing is the generate-temporaries

1:16 tomoj: I'm guessing just gensyms np0# ...

1:17 dnolen: tomoj: yeah

1:21 hugod: ping

1:43 yogthos: so we have profiles now in luminus :) http://luminus.herokuapp.com/docs/profiles

2:15 dimovich: hello ppl

2:15 how can I make the fetcher function less CPU intensive...?

2:15 https://www.refheap.com/paste/7895

2:18 Ember-: dimovich: you have 5 workers doing stuff like crazy for one second? No wonder it is cpu intensive?

2:18 dimovich: Thread/sleep was an example

2:18 I'm waiting till all work queues are empty...

2:19 Ember-: yeah well, your cpu intensity comes from ;do stuff

2:19 you have 5 threads doing infinite loop (until you set the atom to false)

2:20 dimovich: how do I block these threads until sth comes up? or do I have to use some other concurrent primitive?

2:20 Ember-: place (Thread/sleep 1) inside that while to get the cpu usage down, not that it really helps you...

2:20 dimovich: use the future's return values

2:21 http://clojuredocs.org/clojure_core/clojure.core/future

2:21 when you dereference the future's return value it will block until future is done

2:22 dimovich: ok

2:22 Ember-: thus no need for (Thread/sleep 1000) and your workers will return immiadetly after they've done their job

2:23 /s/immiadetly/immediately

2:24 dimovich: the thing is, I'm using clj-http, and I'm wrapping that fetcher future in a clj-http.client/with-connection-pool

2:25 so I can reuse the connections... therefore the future can't return... it has to continually poll for new tasks and download stuff :)

2:25 Ember-: create a queue for stuff the http connections get?

2:26 dimovich: yeah, possible

2:26 Ember-: http://clojuredocs.org/clojure_core/clojure.core/seque

2:27 callen: Ember-: I snorted at the name. Also why are we still using ClojureDocs?

2:27 Ember-: use BlockingQueue with that

2:27 callen: hmm?

2:28 callen: Ember-: it's not updated to 1.4.0, he refuses to release the source, and it's in fucking Ruby.

2:28 We shouldn't have to use this for our stdlib docs.

2:28 Ember-: well, it's better than plain ol' docs due to examples

2:28 when learning stuff

2:28 but I agree, should be updated to 1.4.0

2:29 callen: Ember-: I know that, I'm just saying. It also irritates me that it isn't dogfooding.

2:29 tomoj: I remember feeling bad for complaining about that at the time

2:29 at least he put something out there.. :/

2:29 callen: tomoj: you've got a point, but I'm testing the waters to see if anybody else would even care.

2:29 tomoj: another question, do we want a wiki?

2:29 Ember-: well, it shouldn't be too hard create clojuredocs-with-clojure :)

2:30 after all, it's kinda trivial to parse documentations from clojure sources

2:30 with clojure of course

2:30 :)

2:30 tomoj: I wonder if whatever it is should go at the confusingly-named clojure-doc.org

2:30 Ember-: examples are the hard part

2:30 callen: Ember-: I don't want to just clone it, I want ++. Do you think something wikified would be valuable so that examples can be expounded upon?

2:31 clojure-doc, AFAIK, have said they don't want to touch stdlib docs, generally speaking.

2:31 Ember-: wiki isn't exactly a good way to do this, it needs some kind of release management system in it

2:31 callen: It would have that

2:31 Ember-: so that you can create an example but it isn't published right away

2:31 Raynes: Calm down, guys. Give me a month or two and I'll write a documentation site.

2:31 Ember-: an admin should do the release

2:31 Raynes: cool

2:32 Raynes: I wouldn't count on me though. I'm pretty fickle.

2:32 Ember-: anyway, clojuredocs will suite me until then, even if it is 1.3.0 :)

2:32 callen: Raynes: you're like the nature god Pan.

2:32 I think a Clojure Wiki with examples and discussions of idioms all in one place would be really nice.

2:32 Stack Overflow doesn't work great unless you have a very specific issue.

2:33 a lot of the questions that get asked here are about idioms, once answered, are essentially lost into the aether.

2:33 Ember-: a good documentation site with api docs with good examples and faq etc would be great

2:33 should be part of clojure.org (and in a way it is)

2:33 Raynes: I might really do it though.

2:34 Might.

2:34 Also, is my name not capitalized?

2:34 ._.

2:34 atyz: It's a lot of work

2:34 Ember-: 09:25 < Raynes> Also, is my name not capitalized?

2:34 Raynes: Strange. This client lower cases it.

2:34 tomoj: .. so you see "ember-" ?

2:34 Ember-: atyz: not that much really. Sure when doing it at your freetime it will take several evenings

2:35 Raynes: It's a fairly big project, but I can't see it being *that* much work.

2:35 callen: Ember-: what you describe is more of a clojure-doc.org + clojuredocs

2:35 Raynes: The hardest part is just design. Someone else might have to make it prettier.

2:35 callen: I'd really like to get something like the EmacsWiki rolling.

2:35 atyz: Documenting the language and usage examples?

2:35 Raynes: If I do it, it will be a pure documentation/source/example website though.

2:35 Ember-: atyz: producing the examples will take time, but the code providing the platform is easier

2:35 atyz: The building of the site isn't too much work

2:36 Ember-: and the documentations are already there, just generate them from sources

2:36 atyz: Don't get me wrong, I'm not trying to put anyone off it. I love the idea

2:36 Was just stating that it may or may not be more work than anticipated

2:37 Raynes: It would give me a decent opportunity to write something from the ground up with laser.

2:38 callen: nobody else is intrigued by the notion of something like the EmacsWiki? I've found the EW to be amazing.

2:39 Raynes: Clojure has/had a wiki, but nobody cared.

2:39 Ember-: callen: this? http://emacswiki.org/

2:39 callen: Ember-: yes

2:39 Ember-: and agreed, wiki in general will not work

2:39 unfortunately

2:39 wikis tend to get cluttered

2:39 callen: I don't see why, EW has shepherded the community for a long time.

2:39 Ember-: those need active moderators to maintain

2:40 callen: the clutter is the collected wisdom, a little disorder is better than losing knowledge, like what I said about idioms earlier.

2:40 Ember-: I've worked with wikis and currently work with them

2:40 the problem is, knowledge does get outdated too

2:40 callen: I'm fully aware. I have improvements to the wiki model in mind for addressing that.

2:40 Ember-: the older the wiki, the more it has of the old information which might be outright misleading

2:41 at work we have all of our documentation about *everything* in confluence

2:41 works great, except you can't find shit from it anymore since it has huge amount of stuff in it

2:41 callen: workplace environments are a pathological case for wikis.

2:42 Ember-: search just doesn't work anymore, you find stuff from 2003 with it

2:42 callen: mostly CYA documentation, nothing intended to be meaningful or actively maintained.

2:42 search is another matter. Come on dude, are you seriously comparing a potential Clojure wiki to a shitty unmaintained Confluence?

2:42 Ember-: like I care about how some java stuff was done back in 2003

2:42 callen: that's just being disingenuous and comparing the incomparable.

2:42 Ember-: callen: yes I know that is kinda unfair, but I've seen how bad full blown wikis can get

2:43 thus I'm suggesting a wiki-like experience with moderators which accept the edits before they get published

2:43 a public wiki can get really ugly really fast if it has even one moronic troll

2:44 callen: Ember-: for one thing, reverting changes and banning accounts/IPs isn't that big of a deal.

2:44 Ember-: second, I like the original wikis where actual discussions and flows happened. Not this bullshit publishing format.

2:44 that can't happen with a moderator queue.

2:45 There are plenty of ways to handle Joe Troll.

2:45 Ember-: commenting can be there

2:45 but anyway, do it the way you like :)

2:45 I'm just happy if the information is there

2:45 I'd do it in this slightly more moderated way but hell, if we get an active and maintained wiki then I'm all for it

2:47 callen: Ember-: http://c2.com/cgi/wiki

2:47 Ember-: callen: yup, seen that

2:47 callen: Ember-: you've seen it, but you don't seem to appreciate it very much :(

2:47 Ember-: no, that's kinda unreadable and unusable mess in my opinion

2:47 hate sites like that

2:48 callen: the design and delineation of content can be done sensibly.

2:54 Raynes: callen Ember-: Are guys going to kiss now?

2:56 callen: Raynes: only if you join in

2:56 Raynes: pink hair is obligatory.

3:00 Ember-: Raynes: make us our love nest!

3:03 callen: so today I learned the English J is actually a hybrid of d and zh.

3:14 technomancy: At least look at the reviews? http://www.amazon.com/Mistborn-Final-Empire-Series-Book/dp/0765350386/ref=sr_1_1?ie=UTF8&qid=1356681911&sr=8-1&keywords=Mistborn

4:05 tomoj: hmm.. condw?? https://www.refheap.com/paste/052e41e272010c7a695ec46e9

4:46 nodename: Hahahaha CompilerException java.lang.ClassFormatError: Invalid method Code length 175586 in class file clevolution/cliskenv$eval176496, compiling:(NO_SOURCE_PATH:1)

4:49 zilti: Why is ##(conj {:three 3} [{:one 1}{:two 2}]) not => [{:one 1}{:two 2}{:three 3}]? Sometimes clojure is weird.

4:49 lazybot: ⇒ {{:one 1} {:two 2}, :three 3}

4:50 borkdude: zilti because conj first takes the coll to conj on

4:50 ,(doc conj)

4:50 pyrtsa: ##(conj [{:one 1}{:two 2}] {:three 3})

4:50 lazybot: ⇒ [{:one 1} {:two 2} {:three 3}]

4:50 zilti: argh. I see

5:32 tomoj: my logic version of (rand-nth [1 2 3]) is only 250x slower..

5:34 dbushenko: :-)

5:34 "only" :-D

5:35 tomoj: :(

5:42 callen: tomoj: as in core.logic?

5:42 tomoj: yeah

6:48 ogrim: Anyone have experience using SOAP Web Services with Clojure?

6:52 dbushenko: +1

6:52 actually I had to use apache cxf for that...

6:52 ogrim: I was looking at that, seems nice enough

6:53 but would really like to have clj-soap working, that would be very usefull

6:55 dbushenko: clj-soap looks weird for me

6:56 seems like it is a bit too simple

6:59 ogrim: it's very powerfull to generate clients quickly from a wsdl. Visual Studio makes this very simple, so I'm thinking of writing a data provider in C#. It would be less hassle still to be able to auto-implement the client in native clojure

7:08 Raynes: You're best off using Java libraries for that.

7:09 SOAP is an evil, evil monstrous thing that nobody wants to mess with.

7:09 In other news, https://github.com/Raynes/laser#screen-scraping laser can do screen scraping type stuff now.

7:09 Me go night night.

7:10 dbushenko: Raynes, how does it differ from clj-tagsoup?

7:10 callen: dbushenko: it's a simplified enlive, not clj-tagsoup.

7:11 dbushenko: aha, ok then

7:11 callen: dbushenko: focuses more on zippers and tree traversal, less on CSS selectors.

7:11 ogrim: I like enlive, so will check out laser :)

7:12 callen: ogrim: enlive *and* SOAP? I'm keeping my distance from you.

7:12 ogrim: On SOAP: you can find many undocumented APIs using a man-in-the-middle proxy when surfing the web (fiddler, mitimproxy) - sometimes you need to touch the old crap to get the good stuff (data)

7:13 * algernon ponders migrating his static site generator from enlive to laser.

7:13 callen: ogrim: I'm a huge fan of carting off with data :)

7:13 ogrim: callen: also, I'm programming PowerBuilder (for work ... sometimes)

7:13 borkdude: algernon which static site generator is that?

7:13 callen: borkdude: there are only like 200 written in Clojure alone.

7:14 algernon: borkdude: my own (github.com/algernon/madness), one of the million similar ones :P

8:06 Raynes: algernon: I support this decision. If you decide to, let me know if you need help or run into any pain points.

8:10 algernon: Raynes: will do

8:49 borkdude: Raynes using laser, how to feed it html from a file, slurp it yourself?

9:01 Raynes to select an element from a particular form (div, etc) and class, write this? (laser/select-and (laser/element= :table) (laser/class= "names"))

9:04 Raynes how do I write a selector like this (from Enlive): [:table.names :tbody :tr]

9:40 moominpapa: Hi, could I ask a stupid question? Does lein always set up an nrepl connection or is it just the repl job? In particular, if I use lein ring server, can I connect via nrepl? Because it doesn't print a port.

9:44 zilti: moominpapa: lein ring server won't provide you with a nrepl connection. You'd have to add the nrepl-server-startup-code yourself to the server.

9:45 moominpapa: Ah, thankyou :)

9:47 I think it might be simpler to take lein ring out and use ring-server. Only just discovered this had been split out.

9:55 dimovich: hey people, is this idiomatic? https://www.refheap.com/paste/7898

9:59 zilti: If someone wants to have a more dynamic korma which can also create and modify tables this might be for you: https://github.com/zilti/tetrisql </shamelessplug>

10:01 dimovich: cool

10:01 moominpapa: @dimovich It's fine in context, but I'd rather see the parameters passed down explicitly.

10:01 If you're going to do things like that, the config is probably the place to do it :)

10:02 chouser: +1 moominpapa

10:02 dimovich: what you've got there makes your entire (run-program-code) impure.

10:03 Even passing in a giant config object as a single parameter, while having drawbacks of its own, is a better place to start than dynamic vars.

10:11 dimovich: thanks for feedback

10:22 cemerick: There was a fellow (and his wife) at the conj who were working on educational software; if anyone knows who I'm talking about and has contact info for him or her, please pm me. :-)

10:40 dimovich: how can I convert :some/Key to "some/Key"

10:46 oriig: ,(.substring (.toString :some/Key) 1)

10:46 don't know if that's idiomatic though :P

10:48 dimovich: thanks

10:50 zilti: https://www.refheap.com/paste/7899 What does "variadic overload" mean?

11:06 milos_cohagen: where did the syntax of mixing lispy func invocation with square brackets for args array originate? eg (myfn [args])

11:23 ?

11:29 thorwil: milos_cohagen: i would guess it is an original idea

11:30 born out of the desire to have a bit more "flavor" than all (), and having literal syntax for certain types

11:30 milos_cohagen: given function args often are represented as arrays i guess it was natural

11:32 just been getting into clojure after years of java and a bit of scheme in uni and luvin it

11:35 TimMc: I've certainly seen it in PLT Scheme (now, Racket).

11:37 Anderkent: how do I attach a debugger to leins process? Trying to add the java opts gives me errors 'ERROR: Cannot load this JVM TI agent twice, check your java command line for duplicate jdwp options'

11:53 dimovich: how can I make the second example work? https://www.refheap.com/paste/7900

11:54 thorwil: dimovich: what's the motivation for the read-string?

11:54 dimovich: I'm keeping the selectors in a separate config

11:55 lazily read-string'ing them :)

11:56 thorwil: dimovich: maybe you have a good reason, but my gut reaction to that is: that's insane ;)

11:56 dimovich: just hacking my way... and thought I would try that :)

11:56 thorwil: dimovich: however, if you insist on such acrobatics, use a macro to generate the whole elive form along with selector

11:57 dimovich: thanks, will try that

12:01 yep, that works :)

12:01 (eval `(enlive/select html ~(read-string "[:div (attr? :href)]")))

12:29 technomancy: callen: I noticed you rambling about clojure-doc.org; thought I should let you know that a re-write is already in process

12:30 there's a rest API in clojure already that cd-client (in lein repl) uses, just no HTML interface yet

12:51 Anderkent: Question: it seems the clojure compiler ignores the 'name' meta field, and only looks at the second part of (fn* ...) form to figure out the name. How come (defn foo) gives the right name in backtraces if it only supplies the meta?

12:58 ilyak: hi *.

12:58 tomoj: &(macroexpand-1 '(defn foo []))

12:58 lazybot: ⇒ (def foo (clojure.core/fn ([])))

12:58 ilyak: What's the right way to find the biggest element in the collection?

12:58 of something comparable

12:59 tomoj: &(meta (second (macroexpand-1 '(defn foo []))))

12:59 lazybot: ⇒ {:arglists (quote ([]))}

12:59 Bronsa: ilyak: apply max

12:59 ilyak: I fing the fact that < >, max and max-key work with numbers only extremelly frustrating

12:59 Bronsa: isn't max limited to numbers only?

12:59 Ember-: ,(last (sort [1 2 5 4 2]))

12:59 Bronsa: oh, i missed your second line, sorry

12:59 Ember-: &(last (sort [1 2 5 4 2]))

12:59 lazybot: ⇒ 5

13:00 Ember-: sure, ain't necessarily fast with every possible collection

13:00 ilyak: the sad thing: even though clojure is a very new language, its core library already contains quite a few bullshit

13:00 As in: "Why is X? Because life is pain, that's why!"

13:00 Why is max limited to numbers? Because life is pain, that's why.

13:01 sort is n * logn

13:01 max is linear

13:02 Ember-: true but sort works for all kinds of stuff

13:02 and it all depends on how large your collection is

13:03 ivaraasen: ilyak: do max-key

13:03 Anderkent: ilyak: (reduce (fn [x y] (if (> (.compareTo x y) 0) x y)) coll) ?

13:03 :P

13:03 ivaraasen: ,(max-key count "asd" "bsd" "dsd" "long word")

13:04 Anderkent: ivaraasen: that doesn't work if you can only compare two items instead of assign a number to them

13:05 ah, you can use compare instead of .compareTo, and there's probably some way to make the comparing a bit prettier

13:06 ivaraasen: Anderkent: yeah, you're right

13:07 tomoj: (reduce (comp pos? compare) coll) maybe ?

13:07 no, of course not

13:07 jonasen: kovas: pull request sent..

13:08 tomoj: just woke up :)

13:10 dnolen: ilyak: I don't really see why max needs to work w/ anything else besides numbers. Even if it didn't it would be any more convenient that (reduce your-max-fn some-seq) vs. (reduce (weird-max your-comparator) some-seq)

13:10 "Even if it did"

13:11 Anderkent: dnolen: having (max some-seq) when all elems implement comparable would be convenient though

13:14 dnolen: Anderkent: yeah but it's a one-liner you could add yourself - (reduce #(if (pos? (compare x y)) x y) some-seq)

13:15 Anderkent: well, so is max.

13:15 dnolen: Anderkent: looks more closely at the implementation of max and tell me why this is a bad idea :)

13:16 Ember-: the whole point of clojure and lisps is for it to be extendable

13:16 ilyak: ivaraasen: max-key is all about numbers, too

13:16 Ember-: it has a lot of stuff out-of-the-box but if you need more, then do it

13:16 writing a one liner function ain't too much work...

13:17 ilyak: dnolen: I don't really see why I should be writing my-max-fn instead of application codez

13:17 Ember-: at least in my opinion

13:17 ilyak: I've found but I do have to hack in an awful lot of stuff that should it in the standard library

13:18 dnolen: ilyak: like I said max works only on numbers for a very specific reason - it inlines on primitives numbers. At some point you will realize many decisions are made in Clojure for reasons you might not yet understand.

13:18 systems: hi

13:19 ilyak: dnolen: Cool story, but why isn't there a way to do a normal proper max?

13:19 I mean, there are a lot of objects in the world

13:19 like dates

13:19 why limit yourself to numbers? makes no sense

13:19 dnolen: ilyak: whatever, moving on.

13:19 ilyak: Special handling of primitive numbers is the kind of Javaesque crap I thought everyone is happy to run from

13:20 Life is pain :(

13:20 dnolen: ilyak: you're well on your way to ignore list now.

13:20 ilyak: dnolen: That won't hurt much as you never said anything useful

13:21 Ember-: ilyak: read the source of max

13:21 and you'll understand

13:22 and if you refuse to see the :inline -stuff then well, like dnolen said: whatever, moving on

13:22 :)

13:22 tomoj: yeah.. life is pain

13:22 ideally we wouldn't have to be pragmatic like that

13:23 but, good thing we are :D

13:23 s/we/not me/

13:23 ilyak: Ember-: We don't have a limit on a number of functions in core do we?

13:23 Anderkent: where can I find out how java methods with the same arity are resolved (using type hints)? Compiler.java? Reflector.java?

13:23 ilyak: Why doesn't it has max for humans?

13:25 And I don't see why it's OK to assume everyone does number grinding

13:26 Ember-: ilyak: like you said yourself, clojure is a new language. And if you want max-compare or whatever, then write it yourself. Even better, assign a pull request for clojure core after you've tweaked it to perfection and maybe you'll get it into core

13:26 it's an open source project, one *can* take part

13:27 technomancy: Ember-: well... in theory

13:27 Ember-: technomancy: I know, it is going to be hard going to get your own code to core

13:27 ilyak: In practice if everyone agrees "only hardcore grind in core", my pull requests will be ignored

13:28 I can have my own extras but the whole community will never get any benefits from that

13:28 Ember-: but I just don't see the reason why anyone would rave about something which could be done with a one-liner and added to one's own library if needed...

13:28 ilyak: and why's that? Because you don't want to share your code?

13:28 of course the community will get benefits if you release your code as open source in github or similar

13:29 ilyak: Ember-: Because nobody is going to dig other people's extras for the insight

13:29 People just don't do that

13:29 The only notable exception is apache commons

13:29 Ember-: eh

13:29 don't be offensed but you are wrong

13:30 google guava and a bunch of other libraries out there prove you wrong

13:30 ilyak: Most people aren't good at making tools. They don't see it as a priority. So, given a weak set of tools, they're going to use that and make weaker code than they could.

13:30 See PHP

13:30 Ember-: you are seriously calling clojure as a weak tool? o_O

13:30 ilyak: The problem is, with minimal and arcane core lib, some people are surely going to make a nice extras lib

13:31 but the most of the community will write weaker code than they could.

13:31 Ember-: Well, when it comes to tuple handling, clojure core is weak

13:31 Ember-: oh come on, Rome wasn't built in a day

13:31 ilyak: I believe it has group-by

13:31 Ember-: it has

13:32 ilyak: but no zip-with, no map-keys/map-values

13:32 of course those are trivial to write

13:32 Ember-: it also has partiton-by and frequencies

13:32 ilyak: but most people (I believe) will learn to go without

13:32 Ember-: partition-by

13:33 ilyak: partition-by is an example where clojure/core has some advanced, use with care tools. While still lacking some obvious ones

13:33 I mean, zip-with is an obvious thing. Or am I missing something?

13:34 (defn zip-with [f s] (into {} (for [k s] [k (f k)])))

13:34 dnolen: ilyak: no

13:34 &(map #(+ %1 %2) [1 2 3] [3 2 1])

13:34 lazybot: ⇒ (4 4 4)

13:34 technomancy: zip-with is a crappy name, but yeah that comes up with some regularity

13:34 dnolen: (map f (keys ...))

13:34 * technomancy would like map-vals

13:34 dnolen: (map f (vals ...))

13:35 these aren't even one liners, the fns in core compose to the point that to have a function is almost ludicrous

13:36 Ember-: composability <3

13:38 tpope: bitsweat came up with the name "associate" for this zip-with

13:38 I like it, but I guess that's confusing with assoc

13:38 ilyak: No, I mean a different thing by zip-with

13:38 (I don't know why it's called that)

13:38 technomancy: oh, misread zip-with. yeah, that's not a common function.

13:39 ilyak: it's (a -> b) -> [a] -> [(a, b)]

13:39 tpope: well *I* meant ilyak's definition

13:40 ilyak: Having zip-with and group-by changes your coding style forever

13:40 technomancy: haha

13:40 dnolen: &(map (juxt identity str) [1 2 3])

13:40 lazybot: ⇒ ([1 "1"] [2 "2"] [3 "3"])

13:40 ilyak: it's like mapreduce: you can represent most computations as a composition of zip-withs and group-bys

13:41 dnolen: yes, but (zip-with str [1 2 3]) is kind of snappier

13:42 dnolen: ilyak: yes you save a couple of characters, but honestly there many interesting equally useful other ways in which Clojure helps you save characters.

13:52 hugod: ping

13:58 tomoj: if you write a bunch of composed zip-with's and group-by's in clojure, your code will probably not be very fast :1

14:00 I suppose there is a tradeoff of putting stuff like (defn ___ (into {} (for ...))) into the language, where it may be useful, but people who use it too much without understanding it will just say "clojure is slow!"

14:00 among other tradeoffs..

14:00 Anderkent: Is there a tag/branch in clojure git repo for 1.4.0 ?

14:01 xeqi: Anderkent: tag "clojure-1.4.0"

14:01 Anderkent: thanks, couldn't find it :P

14:02 technomancy: what's the reason tag names aren't the actual version name?

14:02 tomoj: looks like they used to be, before 1.3.0. was that post-github?

14:03 I wonder if github was creating zipballs called 1.2.1.zip

14:03 technomancy: heh

14:03 the switch to github was right after 1.0 iirc

14:03 Anderkent: onto debugging the clojure compiler to find out what I'm doing wrong! TT

14:03 tomoj: looks like that is the case

14:03 not sure it's a very good reason to switch tag naming

14:13 augustl: I'm struggling with a "java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined" when I have a ref that points to a Java object inside a defmacro.. Any suggestions? My macro basically looks like this: (defmacro [& body] `(some-other-macro (with-redefs [some-thing (a-function-call ~my-java-obj)] (do ~@body))))

14:14 tomoj: don't do that?

14:14 augustl: tomoj: don't do what exactly?

14:15 tomoj: my-java-obj there needs to evaluate to some code, not a java object, in order for the macro to work

14:15 well, in order to avoid the error

14:15 don't embed objects in code :)

14:15 augustl: I think what I want is for my macro to expand to the ref itself, not the object the ref refers to

14:16 tomoj: best refheap the actual macro if you can, hard to tell where your confusion lies

14:16 if you really have a java obj at macro-time.. I'm not sure how you'd get it to runtime

14:16 augustl: allright

14:17 tomoj: normally you want the macro to expand to code that creates the java obj

14:17 instead of creating it in macro time

14:18 augustl: tomoj, anyone: https://www.refheap.com/paste/7901

14:18 I could "solve" it by using a higher order function, but that's boring!

14:19 tomoj: why not just write sso-private-key instead of ~sso-private-key ?

14:19 augustl: no idea tbh..

14:20 tomoj: try that, good luck

14:20 augustl: interesting, that worked

14:20 * augustl needs to actually learn how macros work

14:21 dbushenko: which is the default lein profile?

14:22 technomancy: dbushenko: there are a number of profiles applied by default that pull from different sources. :user, :dev, and :default

14:22 you typically set :user or :dev depending on context

14:22 dbushenko: thanks :-)

14:22 but is :user default?

14:23 yes, I've just read that there is :default

14:23 technomancy: yeah

14:23 dbushenko: so what is :default for?

14:23 technomancy: it's for settings that are built-in to Leiningen

14:23 dbushenko: thanks!

14:23 technomancy: err-sorry, that's changed

14:23 :default is now a composition of :base, :user, :provided, and :dev

14:24 :base is the stuff that ships with lein; adding dev-resources, the newnew plugin, and checkout deps

14:26 yogthos: interesting; I was wondering how long it would take before someone created a template with customization options

14:27 I wonder if it would make sense to have additions like that which could be stored in their own artifact and shared between templates

14:42 ppppaul: can someone help me out with my template? https://gist.github.com/4401133

14:43 it's working (when i run tests they are doing the right thing), when i load my file into the repl the body of the do-template evaluates and throws an error related to datomic

14:44 Anderkent: So (def ^{:name my-fn} my-fn (fn ...)) and (def ^{:name my-fn} my-fn (do (fn ...))) are not equivalent. I'm sad now.

14:56 chouser: really? how do they differ?

14:58 Anderkent: the do makes it lose track of the name, so you get an autogenerated name for the function and I *think* it might mess something up with type hints and resolving java methods, but still debugging that

15:00 chouser: That surprises me. I thought fn got its name exclusively from (fn <here> [args...] ...)

15:02 zilti: Can someone here confirm that, when having korma entities "one" and "two", when "one" has-many of "two", and "two" belongs-to "one" and has a column "one_id", (select two (with one)) merges(!) "one"'s columns into "two"'s result, but (select one (with two)) gives a result where the map entry :two only contains an empty vector?

15:02 Anderkent: chouser: unfortunately (defn ...) expands into (def name (fn [args)), without the middle part...

15:03 chouser: wow, you're right.

15:03 I wonder if that has changed...

15:04 zilti: Anderkent: I think it's pretty obvious why in the second example the fn doesn't get a name.

15:04 chouser: indeed. a year ago it changed.

15:05 zilti: It probably changed because it's inconsequent

15:05 chouser: Clojure 1.3

15:06 I was aware of the previous behavior because of long running self-recursive functions in the face of dynamic redefinition

15:06 Anderkent: well, it matters for the stacktraces, so I wouldn't call it inconsequent... I suppose I can work around it

15:06 zilti: Anderkent: I mean it's inconsequent that, in the first example, the first expression inside def gets the metadata and in the second you expect the nested expression to get it

15:06 chouser: That is, if you've got something like (defn f [a] (Thread/sleep 5000) (do-something) (send a f))

15:07 ...and start that running, and then redefine f -- if f is a local name, redefining the var does nothing.

15:07 Anderkent: In both cases the metadata is on the naming symbol, it's just the compiler carries around the 'name' but drops it when entering a do

15:07 chouser: but apparently since 1.3, defn doesn't make a local symbol anymore.

15:07 zilti: (def ^{:name my-fn} my-fn (fn [args] ...)) = (def my-fn (do (fn my-fn [args] ...)))

15:08 Is this assumption correct?

15:08 chouser: no, this is what I was just saying.

15:08 Anderkent: eh no I think that should work

15:09 dnolen: Anderkent: why should it given the init expr could be arbitrarily deep?

15:09 Raynes: technomancy: https://github.com/magnars/dash.el

15:09 zilti: ,(macroexpand '(def ^{:name my-fn} my-fn (fn [x] x)))

15:10 ,(macroexpand '(def my-fn (fn my-fn [x] x)))

15:10 technomancy: Raynes: yeah, looks promising

15:10 Anderkent: I expected the def to evaluate the init expr then tell it its name, but now I see it needs it at compile time so that cant work

15:10 dnolen: Anderkent: yep

15:10 Anderkent: I don't see how you get what you want w/o even more ugliness in the compiler

15:10 technomancy: Raynes: my biggest complaint doing elisp has always been the lack of a good associative data structure, and I don't think that can be addressed in libs =\

15:11 ppppaul: anyone have a good resource on how to deal with exceptions in clojure?

15:11 Raynes: technomancy: But… but… ALISTS

15:11 technomancy: or even if it were, you would still have to interface with libraries that use crappy hash tables, crappy vectors, and (ugh) eieio

15:11 Anderkent: dnolen: Do you know any reason why it doesn't expand to (def <name> (fn <name> ...)) ?

15:11 it being defn

15:11 dnolen: Anderkent: because of redefinition

15:12 (fn <name>) should shadow the var the name.

15:15 chouser: Also because of self-calls to fns with primitive args (looking at the comment in the source code)

15:53 yogthos: technomancy: yeah I gotta play around with that some more

16:28 ravster: does '::foo' turn into something special?

16:28 looking at slingshot code

16:28 examples

16:28 chouser: namespace-qualified keyword

16:29 ravster: been looking for documentation on it.

16:29 gfredericks: ,::foo

16:29 &::foo

16:29 lazybot: ⇒ :clojure.core/foo

16:30 ravster: chouser: oh, okay

16:30 tnx

16:38 technomancy: yogthos: also: you'll want to drop the sqlite bits out of your template. not worth the trouble

16:38 yogthos: technomancy: yeah I'll switch it to something more respectable :P

16:38 technomancy: figured it would do for proof of concept ;)

16:39 technomancy: I don't have too much experience with embedded dbs, I normally just use postgres myself

16:39 technomancy: is hsql or derby considered to be better?

16:39 technomancy: yogthos: the other danger of embedded DBs is that people think they can develop against them and then swap them out for postgres later, which never actually works =\

16:39 yogthos: I haven't looked into them in detail.

16:40 yogthos: technomancy: yeah for sure, but doesn't hurt to have the option and it gives people something to play with out of the box

16:40 technomancy: I do love the postgres userspace on the mac though, awesome for doing development with

16:40 technomancy: yogthos: yeah, as long as people don't get unrealistic expectations

16:41 * technomancy mutters something about lobos

16:41 yogthos: hehehe

16:41 technomancy: I'll add a profile for postgres as well and then expand the section to explain the benefits/drawbacks so people know what they're getting into :)

16:42 technomancy: cool

16:42 if you could strategically omit an option for mysql that would be great too =)

16:42 yogthos: for a lot of sites embedded is fine too, if you have something like a blog, postgres is probably overkill ;)

16:42 haha that's totally the plan :P

16:42 technomancy: excellent; carry on

16:42 yogthos: I can't see any reason to use mysql over postgres

16:42 p_l: yes, please "forget" mysql

16:43 yogthos: not going to encourage bad practices :P

16:43 Anderkent: what's mysql?

16:43 p_l: Anderkent: a troll

16:43 Anderkent: :(

16:43 yogthos: Anderkent: a recipe for disaster :P

16:43 to be fair it's not that horrible, it's just postgres is better all around and has saner defaults

16:46 p_l: yogthos: it is that horrible. Or at least was in the most disastrous version, that is, 3.x

16:46 (which is still the basis of many tutorials etc.)

16:47 yogthos: certain things are best left forgotten :P

16:47 p_l: yogthos: certain things are best remembered unless you get yourself pondering about using certain shit :P

16:48 yogthos: p_l: point :)

16:48 p_l: like the fact that MySQL team considered "foreign key constraint" to be "dumb something for ODBC apps to draw connections between tables"

16:48 yogthos: p_l: lol for real? this I have not heard of

16:49 * technomancy mutters something about those who fail to learn from history

16:49 yogthos: p_l: foreign keys it's just a fad, it'll pass :P

16:49 p_l: yogthos: it was in MySQL 3.23 docs, afaikl

16:49 *afaik

16:49 yogthos: which part of relational in rdbms is not clear exactly

17:07 zilti: yogthos: I toss h2-database into the game, it has some nice features, is pure-java and supports full-text search

17:08 jkkramer: +1 for H2

17:08 had a pleasant experience with H2 when I used it once. I think datomic uses it too

17:10 yogthos: zilti: noted :)

17:10 technomancy: does it roll its own search or integrate with lucene?

17:10 zilti: technomancy: both options are available

17:11 technomancy: hard to imagine they could do better than lucene =)

17:12 zilti: But the fulltext search documentation of h2 sucks enormously. Or the features are really as limited as the insight in the tutorial. At least it's enough info to get it working.

17:12 mabes_: I have a lazy-seqs of lazy-seqs (coming from repeatedly), what is the best way to concat them into a single lazy-seq? The lazy-cat macro doesn't seem to be the solution since I need to pass each lazy-seq in.

17:13 jkkramer: (apply concat …)

17:14 mabes_: jkkramer: apply would force the realization of the lazy-seq wouldn't it?

17:14 zilti: The builtin fulltext implementation is somehow funny. It creates a table where every word it has found (it only checks for spaces) is in and a join table to your table. And when you search for a word it pretty much does a "SELECT FROM indextable WHERE word = queryword" :)

17:14 technomancy: mabes_: concat is lazy

17:15 jkkramer: ,(first (apply concat [(range) (range)]))

17:15 &(first (apply concat [(range) (range)]))

17:15 lazybot: ⇒ 0

17:16 S11001001: moreover, apply doesn't force the seq used as restargs beyond...some point I'm not clear on.

17:17 ,(ffirst (apply concat (repeat (repeat 42))))

17:17 &(ffirst (apply concat (repeat (repeat 42))))

17:17 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

17:18 S11001001: &(ffirst (apply concat (repeat [(repeat [42])])))

17:18 lazybot: ⇒ [42]

17:18 S11001001: ww

17:18 technomancy: anyone have strong opinions about emacs faces? https://github.com/technomancy/clojure-mode/pull/113

17:19 S11001001: technomancy: I agree provided that the consequences of redefining core library functions/macros are undefined

17:20 which puts the lie to the "you can optimize if-not in ways you can't optimize if (not ...)" that I've seen

17:21 technomancy: S11001001: eh? not sure I follow.

17:21 this is about highlighting

17:21 S11001001: technomancy: if the consequences of redefining core functions are defined, they aren't "built in" and so shouldn't be highlighted suchly

17:21 zilti: technomancy: I find it a bit weird that they want font-lock-keyword-face for the real builtins and font-lock-builtin-face for non-builtin stuff?

17:21 technomancy: S11001001: it wouldn't be able to distinguish between redefinition of a core var vs just pulling in another var of the same name using :refer-clojure/:exclude

17:22 S11001001: technomancy: that's fair

17:22 you can see I'm more concerned with this other thing than the highlighting though

17:23 next up I'll be advocating for the elimination of loop*; I'll be here all week

17:23 technomancy: heh

17:23 zilti: yeah, I don't really follow. I think "keyword" means something different here?

17:24 but consistency with other modes is probably good

17:25 zilti: technomancy: I assume "keyword" as in "language keyword". Sure, if it's the standard, use it.

17:25 technomancy: "keyword" as in "my language doesn't expose its means of abstraction to the user" =)

17:26 S11001001: &(let [fn* list] (fn* [] 42))

17:26 lazybot: ⇒ #<sandbox7657$eval11702$fn__11703 sandbox7657$eval11702$fn__11703@72bcaa>

17:26 zilti: S11001001: What are those "loop*", "let*" and stuff anyway? Are they any different from let and loop?

17:26 S11001001: &(let [fn list] (fn [] 42))

17:26 lazybot: ⇒ #<sandbox7657$eval11724$fn__11725 sandbox7657$eval11724$fn__11725@dde202>

17:27 S11001001: ptthhhh

17:27 zilti: yeah, go look at the source of loop and let to understand

17:28 Anderkent: zilti: they're special symbols that the compiler looks for and then treats magically

17:28 zilti: while loop and let are macroes that do some work then expand to these special symbols

17:29 zilti: Anderkent: Ok

17:30 bbloom: more importantly: they are implementation details

17:30 the *documented* specials are loop and let

17:30 but in the current implementation, they are macros that expand to loop* and let*

17:31 Anderkent: bbloom: it was recently shown to me that it's not quite that simple:

17:31 ,(let [loop inc] (loop 1))

17:31 ,(let [do inc] (do 1))

17:31 uh, dead bot

17:31 &(let [loop inc] (loop 1))

17:31 lazybot: java.lang.IllegalArgumentException: loop requires a vector for its binding in clojure.core:1

17:31 Anderkent: ah! works for me in local repl

17:31 think clojail makes it not work

17:32 well, anyway, macroes can be shadowed but special symbols can't

17:32 bbloom: Anderkent: i think that's also an implementation flaw

17:32 specials are not namespaced, but should be

17:33 and the lookup table for specials is in the compiler, but doesn't necessarily have to be

17:33 there could, in theory, be metadata like isMacro on the vars: isSpecial

17:34 Anderkent: yeah, I suppose. Still that's how it currently works so sometimes you need to be aware whether someting is actually a macro or a special

17:34 bbloom: true

17:34 S11001001: bbloom: No, it's quite good that it's in the compiler.

17:35 bbloom: S11001001: why?

17:35 S11001001: It gives the compiler an invariant "there are only these evaluation strategies and no more".

17:35 bbloom: i think that's a short coming, when you start considering multiple backends...

17:36 S11001001: And any tool can also rely on that invariant.

17:36 Because all other evaluation strategies must be implemented in terms of transforms to those built-in evaluation strategies.

17:36 Multiple backends is codegen, this is a question of the language.

17:37 bbloom: cs.au.dk/~hosc/local/LaSC-1-1-pp53-75.pdf

17:37 macros are one type of expander

17:37 you can further generalize: a fn is a lambda abstraction of value -> value

17:37 a macro is of form -> form

17:37 S11001001: I know you can do more. But doing more there means you can do less elsewhere.

17:37 bbloom: and a special is of form -> target code

17:38 S11001001: Because specials aren't *just* -> target code to us

17:38 bbloom: yes, if you allow arbitrary expanders, then tools can't inspect into those

17:38 but if you require expanders be named and enumerated, ie store them in a map

17:38 then you can write tools that operate on a closed set of expanders

17:39 and then for those of us who *do* care about other backends, we can write those :-P

17:42 on a related topic, i've been spending a lot of time thinking about how to create declarative systems

17:42 *extensible* ones, that is

17:42 I think angular.js' Directives are a good model to be inspired by http://docs.angularjs.org/guide/directive

17:51 UberNerdGirl: hi…. anyone know if there is there a multi-user interactive Clojure interpreter in a browser?

17:51 something that mixes a paste bin w/ an interpreter and aids in remote teaching?

17:52 (that's precisely what ghclive does for Haskell, but I seek one for Clojure)

17:52 S11001001: bbloom: I think your special form extension interface would necessarily be unstable from release to release, unless you wanted to freeze the compiler.

17:52 technomancy: UberNerdGirl: tryclj.com isn't multi-user, but it exposes a sandboxed clojure compiler

17:53 bbloom: S11001001: wouldn't it be AST -> target-vm ?

17:53 technomancy: clojure doesn't have an interpreter

17:53 UberNerdGirl: i thought tryclj.com was a tutorial like tryruby?

17:53 ?

17:53 bbloom: UberNerdGirl: interpreter != interactive

17:53 S11001001: bbloom: In this expression, where do' is a special form that just does what do does, (let [x ...] (do' (f x)) (do' (f x))), the do's should generate different code.

17:54 ToxicFrog: I wonder if you could do it with multiple people screen(1)d into a clojure REPL

17:54 I've never used screen's sharing features, though

17:54 S11001001: bbloom: And that's setting aside whether the first do' should emit any code at all, which a compiler can figure out only with the context.

17:54 * UberNerdGirl deflects interpreter pedantic grumbling

17:54 * UberNerdGirl can elect to be mildly amused

17:54 zilti: Or open a temporary IRC channel with a clojure bot

17:54 technomancy: ToxicFrog: it's easier with tmux than screen, but it's definitely possible

17:54 we do it every month at seajure

17:55 yogthos: UberNerdGirl: have you checked out 4clojure.com ?

17:55 UberNerdGirl: yogthos: yea i went through several of those a months back

17:56 technomancy: the easiest way to share a session with someone is over SSH and tmux

17:56 bbloom: S11001001: of course. hence you need to pass the environment as an argument... which is precisely what happens now with macros. see &env in clojurescript

17:56 technomancy: a multi-user tryclj would be cool, but it doesn't exist yet

17:56 S11001001: bbloom: There isn't enough information there.

17:56 technomancy: maybe you could trick Raynes into writing it

17:56 S11001001: bbloom: the necessary piece of information is whether x will be used *later*

17:56 darius2: might not be too hard to fork ghclive

17:56 yogthos: UberNerdGirl: I found it was pretty helpful, especially seeing how others solve things

17:56 UberNerdGirl: technomancy: yeah, i'm familiar w/ setting that up in a Debian environment but not Red Hat (my friend's server)

17:57 darius2: the collab-editor stuff is largely in javascript

17:57 bbloom: S11001001: you can promote that transformation to a parent node in the AST

17:57 S11001001: however, more robustly, you'd transform to an intermediate representation

17:57 and then iteratively operate on that representation

17:57 ie compiler passes

17:58 technomancy: this kind of thing would be so much easier if it weren't for NAT

17:58 S11001001: How can you do a compiler pass on the inner forms of a special form invocation?

17:58 bbloom: S11001001: the same way the compiler does....

17:58 technomancy: NAT: destroying the Internet since time immemorial

17:58 S11001001: bbloom: The compiler can do it if it knows what the special forms do.

17:59 bbloom: It can lambda lift all day if it knows just what lexical bits to pull along.

17:59 bbloom: i'm confused by what you're arguing against/for...

17:59 UberNerdGirl: interesting

17:59 sounds like a good project to write one day. multi-user clojure repl

17:59 S11001001: That allowing arbitrary special forms would require instability in such extension interface from release to release, or crippling the compiler.

17:59 UberNerdGirl: alright thanks anywayzzzz

18:00 yogthos: technomancy: does nrepl allow multiple connections?

18:00 technomancy: yogthos: sure, but that's not the difficult part

18:00 yogthos: I guess actually seeing what's in the buffer would be handy too :P

18:01 bbloom: S11001001: *shrug* i'm not understanding your position, but i suspect it's not going to get conveyed with any fidelity via irc

18:01 S11001001: The compiler can't lift lambdas in do' unless do' tells it how.

18:01 The compiler can't pick out the last reference to x and assign it a locals-clearing unless do' tells it where its x references are.

18:02 yogthos: technomancy: I thought emacs had a shared network buffer mode no?

18:02 technomancy: yogthos: yeah, but it's not as good as tmux

18:02 enabling it on a per-buffer basis is actually really annoying in practice

18:02 you typically want to share your whole Emacs instance

18:02 zilti: yogthos: There also seems to be a multi-user nrepl emacs client.

18:03 technomancy: (unless you don't trust the other user)

18:03 though in that case you can't run clojure code either

18:03 yogthos: yup

18:04 UberNerdGirl: zilti: interesting, what is that you speak of?

18:04 technomancy: what I want is a third-party proxy server that I can add someone's pubkey to and use to allow SSH connections to a guest account on my machine

18:05 to route around the brain-damage of NAT

18:05 UberNerdGirl: technomancy: i did that on a Debian it was hella fun

18:05 i also installed chat

18:05 and screen-sharing. so fun

18:05 technomancy: actually what I really want is for https://pair.io/ to get fixed

18:05 zilti: UberNerdGirl: https://github.com/jamii/concerto/ (from https://github.com/clojure/tools.nrepl/wiki/Extensions)

18:05 technomancy: because dayum; that was amazing

18:05 UberNerdGirl: zilti: jamii is one of my bestest buddies :P

18:06 i'll get on his arse about that

18:06 technomancy: zilti: whoa; nice

18:06 UberNerdGirl: he and I were students at Hacker School, which just ended last week :)

18:06 zilti: i told him to name it concerto :D

18:07 Raynes: technomancy: Trick me into writing what?

18:07 technomancy: Raynes: multi-player tryclj

18:08 Raynes: Yeah, no.

18:08 I don't want to ever touch jquery-console.

18:08 Ever.

18:08 * Raynes shudders

18:08 Raynes: Not that I wouldn't like it, it's just unlikely that I'd ever do it myself.

18:10 UberNerdGirl: clojurescript :P

18:10 devn: Should clojure.core/range still be using Double/POSITIVE_INFINITY, or should it be using Long/MAX_VALUE?

18:10 bbloom: technomancy: step 1, trick Raynes into implementing cljs-console

18:10 devn: ,Double/POSITIVE_INFINITY

18:10 technomancy: it'd be neat if you could just wish software into existence

18:10 devn: ,Long/MAX_VALUE

18:10 bbloom: technomancy: i believe there are people who do that... they are called executivies

18:10 devn: &Double/POSITIVE_INFINITY

18:10 lazybot: ⇒ Infinity

18:10 UberNerdGirl: lolz

18:10 devn: &Long/MAX_VALUE

18:10 lazybot: ⇒ 9223372036854775807

18:10 technomancy: bbloom: where can I get me an executive?

18:11 bbloom: technomancy: how much money do you have? i hear they are for sale

18:11 *zing*

18:11 technomancy: nice

18:11 zilti: Challenge accepted. https://github.com/mui-nrepl

18:12 ivan: heh Datomic ORM https://groups.google.com/forum/#!topic/datomic/8yLTATMjUrM

18:12 technomancy: it's really surprising how often that works

18:12 zilti: *https://github.com/munrepl

18:12 devn: "ginandtomic"

18:15 Anyone know anything about numerics? I'm wondering why clojure.core/range uses Double/POSITIVE_INFINITY when called like (range) instead of Long/MAX_VALUE

18:16 bbloom: &(range 2 4 0.5)

18:16 lazybot: ⇒ (2 2.5 3.0 3.5)

18:16 bbloom: devn: i presume that's why

18:16 devn: oh, duh

18:17 err bbloom -- hm

18:17 bbloom: also fun:

18:17 devn: that wouldn't make sense bbloom i dont think

18:17 bbloom: &(range 2 4 1/2)

18:17 lazybot: ⇒ (2 5/2 3N 7/2)

18:17 bbloom: why wouldn't it?

18:18 devn: bbloom: because Double/POSITIVE_INFINITY is only used in the case of calling range like (range)

18:18 bbloom: oh dur yes

18:18 um

18:18 devn: that should be Long/MAX_VALUE, no?

18:18 AimHere: &(range 4000000000 15000000000 4000000000)

18:18 lazybot: ⇒ (4000000000 8000000000 12000000000)

18:18 AimHere: Why restrict yourself to MAX_VALUE?

18:18 S11001001: devn: probably because it used to work and since it was "fixed" in 1.3 it doesn't.

18:18 bbloom: um no b/c it's exclusive

18:18 you want MAX_VALUE + 1

18:18 which you can't represent

18:18 ivan: &(range (dec Long/MAX_VALUE) (inc Long/MAX_VALUE))

18:18 lazybot: java.lang.ArithmeticException: integer overflow

18:18 devn: thanks

18:19 that makes sense

18:19 S11001001: like so.

18:19 AimHere: &Long/MAX_VALUE

18:19 lazybot: ⇒ 9223372036854775807

18:19 devn: why does Long not have a POSITIVE_INFINITY?

18:19 AimHere: I still think in 32-bit, it seems

18:19 S11001001: no now the stream'll just crash if it's longs eventually. Hopefully you never get there

18:19 bbloom: devn: because there is no representation of infinity in two's complement integers at the machine level on all common CPUs

18:19 and hence the JVM doesn't provide such a representation

18:20 * devn inserts knowledge cartridge into brain

18:20 devn: much appreciated

18:20 thanks guys

18:20 S11001001: hence always write (iterate +' 0) instead of (range) :)

18:20 devn: that makes me curious about clojurescript's range -- i think we ended up using MAX_VALUE in there.

18:21 I assume there's no equivalent to Double/POSITIVE_INFINITY in that world?

18:21 S11001001: devn: I thought it was the other way 'round.

18:21 bbloom: javascript doesn't really support integer types, only doubles

18:21 squidz: whats the easiest way to give (partial ... ) the second argument instead of the first?

18:21 bbloom: javascript's numbers are defined as ieee doubles

18:21 (i think)

18:22 ivan: yes

18:22 bbloom: or maybe it's like a 60 bit version or something, i forget exactly

18:22 devn: js numerics are weird

18:22 technomancy: it's a truncated version

18:22 S11001001: MAX_VALUE is 1.79E+308

18:22 bbloom: technomancy: yeah, thought so

18:22 devn: ([] (range 0 js/Number.MAX_VALUE 1))

18:22 ^-clojurescript's range

18:22 tpope: 1/0.0 is positive infinity in javascript

18:22 bbloom: devn: that's probably a bug

18:23 devn: bbloom: i wrote it! :X

18:23 bbloom: that will result in the range ending, when you should expect an overflow

18:23 but you won't get an overflow in JS anyway

18:23 so it probably doesn't matter :-P

18:23 S11001001: it'll just spin there once you can't +1 anymore, right?

18:23 tpope: yeah

18:23 S11001001: which won't even be max value

18:23 bbloom: personally, i think we should define clojure.core/infinity and clojure.core/-infinity

18:23 devn: bbloom: so it should be js/Double.POSITIVE_INFINITY ??

18:23 lazybot: devn: Definitely not.

18:24 technomancy: S11001001: wait what?

18:24 tpope: with floats, at some point x + 1 == x

18:24 S11001001: technomancy: as tpope says

18:24 tpope: because they...float

18:24 technomancy: oh yeah, heh

18:24 tpope: in precision

18:24 technomancy: you just gradually lose accuracy

18:24 devn: "Everything floats down here..."

18:24 bbloom: hahaha oh right

18:24 technomancy: hilarious

18:24 S11001001: I love it, fixed-point of inc

18:25 bbloom: you'd get an infinite range! it would just tend towards a zero step size

18:25 haha

18:25 devn: bahaha

18:25 technomancy: Zeno's numerics

18:25 bbloom: fuck i hate javascript's semantics

18:25 devn: bbloom: should I make a bug for that in Jira?

18:25 bbloom: devn: well, probalby doesn't matter, given the above discussion

18:25 pppppppaul: Anyone can recommend a more complete set lib for Clojure than what is in core?

18:25 bbloom: if you can produce a test case that fails & using infinity fixes it, then by all means

18:26 ivan: http://bclary.com/2004/11/07/#a-8.5 I am confused, what makes it truncated? the 2^53 thing?

18:26 devn: bbloom: probably not, but why *not* use Double.POSITIVE_INFINITY to match Clojure?

18:26 S11001001: pppppppaul: aside from the extra fns in clojure.set you mean?

18:26 bbloom: devn: b/c matching clojure's implementation details isn't a priority

18:26 S11001001: pppppppaul: what ops are you looking for?

18:26 bbloom: however, platform independency is a stretch goal, hence my suggestion for clojure.core/infinity

18:27 devn: bbloom: it used to be, no?

18:27 pppppppaul: In verse projection

18:27 bbloom: devn: matching behavior is a priority

18:27 devn: matching implementation isn't

18:27 devn: bbloom: fair enough!

18:27 bbloom: ivan: http://en.wikipedia.org/wiki/Double-precision_floating-point_format

18:28 S11001001: pppppppaul: that's apply dissoc

18:28 pppppppaul: Oh

18:29 bbloom: ivan: hmmm you may be right & technomancy and i may be wrong

18:29 S11001001: pppppppaul: map, blah blah :)

18:30 Raynes: bbloom: I'd be surprised if you could convince me to do much of anything with cljs. :p

18:35 pppppppaul: How do I deal with cyclic deps in Clojure?

18:35 bbloom: pppppppaul: step 1: avoid making them, they are a serious code smell

18:35 pppppppaul: step 2: it depends on the particular type of cyclic dep you have, so you need to provide more info

18:35 pppppppaul: ./code smells

18:36 Raynes: The answer to cyclic deps is to not have them.

18:36 pppppppaul: It's been easy for me to avoid them so far

18:36 Just wondering

18:37 bbloom: pppppppaul: you basically need to explicitly decide which dependency is "primary" and then break the other one. then you can use a mutable cell to install the link at the end

18:38 it's ugly, but sometimes it happens with extensible systems

18:38 but in that case, the extensible module *really doesn't know* about the client

18:38 just pretend you're in that situtation

18:38 amalloy: huh? why do you need a mutable cell at all?

18:39 bbloom: amalloy: you really don't, you just need some identity where the value can change

18:39 ie how you make a graph with cycles using immutible data structures

18:40 amalloy: you don't need that either. for cyclic dependencies or for a graph with cycles. in both cases, you can do it by adding a layer of indirection

18:40 bbloom: yeah, that's what i'm failing to say

18:40 pppppppaul: Like a cake

18:42 hyPiRion: Cyclic deps? Like, say, a set containing itself?

18:43 Or two sets A and B, both containing the other?

18:43 pppppppaul: Yes

18:50 hyPiRion: Yeah, a bit hard, if not impossible, that thing.

18:50 At least without indirection

18:52 pppppppaul: (sad-face)

18:52 ahihi2: such sets do not exist in ZFC!

18:53 pppppppaul: Oh

18:53 Zfc?

18:54 bbloom: Zermelo-Fraenkel Set Theory

18:54 pppppppaul: Hmmmm

18:54 bbloom: if you've never accidentally fallen down the wikipedia set theory hole, it's worth 4ish days of not showering :-P

18:54 pppppppaul: Sweet

18:54 ahihi2: I suggest reading Enderton's Elements Of Set Theory instead

18:55 pppppppaul: I will start not showering right now

19:05 bawr: bbloom: arrgh, not the ZFC discussion again

19:06 last time it happened, I lost a week of my life

19:06 bbloom: shall we advance to the category theory discussion?

19:06 bawr: woke up with in vegas

19:06 technomancy: wake up face down in a gutter in reno with no recollection of the days gone by but a deeper knowledge and appreciation of set theory?

19:06 bawr: at a math conference

19:06 drunk in a ditcj

19:06 technomancy: dang beat me to it

19:06 bawr: xD

19:07 I approve of the way you're thinking, technomancy.

19:07 AimHere: You might want to count your kidneys

19:07 bawr: Eh, everybody knows the kidney thing is an urban legend.

19:07 (It's lungs they're after.)

19:08 technomancy: "stuff like that is so difficult to orchestrate since the 70s" http://achewood.com/index.php?date=09132004

19:09 AimHere: You complain about websites sending you on 4 day binge blackouts, then link to early-period achewood!

19:09 bbloom: AimHere: I have π/2 kidneys!

19:09 * technomancy cackles

19:09 bbloom: damn mathematicians.

19:10 (that joke was delayed while i flailed around figuring out how to type π before googling for a character to copy paste)

19:11 bawr: Uppercase π is so pedestrian. </math-hipsterism>

19:11 xD

19:12 hyPiRion: Hah, I have π on my keyboard.

19:12 And lots of other useless things

19:13 bawr: Space Cadet keyboards for everyone!

19:13 Bring back APL, I say.

19:13 ;)

19:20 ppppaul: I have a macro that starts out with a deftest call. How do I make it not expand to 'namespace/deftest'

19:22 ivan: judging by how many times I've seen ~'thing, probably that

19:23 * callen jots down note to write a book about macros, but for sane people

19:24 hyPiRion: callen: Have you read On Lisp?

19:25 ppppaul: ##[`(+ 1 2) :vs `(~'+ 1 2)]

19:25 lazybot: ⇒ [(clojure.core/+ 1 2) :vs (+ 1 2)]

19:25 ppppaul: oh, I just figured it out. Need to call the namespace-qualified deftest, and things are fine.

19:25 callen: hyPiRion: I've poked around, when I said "for sane people" I was mentally contrasting Let Over Lambda

19:26 which is decidedly not exclusively about macros, but you get my meaning.

19:27 hyPiRion: I've not read LOL, but yeah, I've heard about it.

19:28 callen: hyPiRion: author snorts parentheses and rails lambdas directly into his veins.

19:29 hyPiRion: heh

19:29 SirSkidmore: How does conj actually work on a map

19:29 Bronsa: ,(conj {} [:a 1])

19:29 &(conj {} [:a 1])

19:30 lazybot: ⇒ {:a 1}

19:30 hyPiRion: &,'nowadays

19:30 lazybot: ⇒ nowadays

19:30 hyPiRion: Where did clojurebot go by the way?

19:30 Bronsa: &(conj {} {:a 1 :b 2})

19:30 lazybot: ⇒ {:b 2, :a 1}

19:30 SirSkidmore: I should rephrase, sorry.

19:30 Bronsa: hmh

19:31 SirSkidmore: (I'm on my cell phone)

19:31 callen: SirSkidmore: that's unfortunate. https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L75

19:32 ivan: writing Clojure on your phone? ;)

19:32 SirSkidmore: &(conj {:a 5 :b 6} [:c 7])

19:32 lazybot: ⇒ {:c 7, :a 5, :b 6}

19:32 Bronsa: somebody knows the rationale of conj acceptina a map as it's argoument when conjoining int maps?

19:32 accepting*

19:32 its*

19:32 derp

19:32 technomancy: Bronsa: it's inconsistent and weird

19:32 Bronsa: technomancy: yeah

19:33 SirSkidmore: I get that. But when I put that same map in a var 'm'

19:33 Bronsa: SirSkidmore: when conjoining in a map, you have to make sure your second argument is a 2 element _vector_

19:33 won't work with seqs

19:33 SirSkidmore: And conj the same value. It returns {:a 5, :c 7, :b 6}

19:33 Bronsa: not sure if that's your case though

19:34 SirSkidmore: hashmaps are not ordered

19:34 SirSkidmore: Oh. Why does it conj differently then?

19:34 Bronsa: heh i know why

19:35 it's not a bug

19:35 but I'm pretty sure it shouldn't behave like that

19:35 hyPiRion: $source conj

19:35 lazybot: conj is http://is.gd/oWilE0

19:35 Bronsa: so, when the clojure compiler reads a map literal, if it contanins < 16 elements, it uses a PersistentArrayMap

19:35 otherwise a PersistentHashMap

19:35 &(array-map :a 1 :b 2 :c 3)

19:35 lazybot: ⇒ {:a 1, :b 2, :c 3}

19:35 Bronsa: &(hash-map :a 1 :b 2 :c 3)

19:35 lazybot: ⇒ {:a 1, :c 3, :b 2}

19:36 Bronsa: the problem there is that, when def'ing the hashmap, the compiler ALWAYS uses a hashmap if it's not an empty map literal

19:37 i got a patch in jira to fix that, but it got rejected i because the testcases i was showing were not reproduceable

19:37 SirSkidmore: Ohh okay. That makes sense. Thank you

19:37 I appreciate it

19:38 Bronsa: let me see if i remember where the problem is in the clojure compiler

19:39 SirSkidmore: Well I need to save some battery life.. I was just reading on my Kindle

19:39 Thanks Bronsa

19:39 hyPiRion: Bronsa: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L39-44

19:39 Bronsa: nvm

19:40 yeah, that doesn't make too much sense to me anyway

19:40 hyPiRion: &(conj {:a 1} (seq {:b 2, :a 3}))

19:40 lazybot: ⇒ {:b 2, :a 3}

19:40 hyPiRion: &(conj {:a 1} (vec (seq {:b 2, :a 3})))

19:40 lazybot: ⇒ {[:a 3] [:b 2], :a 1}

19:41 Bronsa: you're never going to convince me that that makes sense.

19:42 hyPiRion: &((juxt merge conj) {:a 1} {:b 2} {:a 3, :c 5})

19:42 lazybot: ⇒ [{:c 5, :b 2, :a 3} {:c 5, :b 2, :a 3}]

19:42 hyPiRion: Oh well.

19:44 S11001001: &',42

19:44 lazybot: ⇒ 42

19:44 S11001001: &'',42

19:44 lazybot: ⇒ (quote 42)

19:44 S11001001: doh

19:44 Bronsa: oh here it is

19:44 https://github.com/Bronsa/clojure/commit/28ca956d9e59e23c502b30b9a766236dba64b50f

19:44 S11001001: &'~42

19:44 lazybot: ⇒ (clojure.core/unquote 42)

19:45 Bronsa: maybe.

19:45 oh no, it had'nt been rejected

19:45 http://dev.clojure.org/jira/browse/CLJ-944 it's still there

19:46 callen: yogthos: planet clojure follows you. damn dude.

19:46 ivan: there's some hope, you included the mandatory tab/space mixup ;)

19:47 yogthos: callen: yeah Alex emailed me a while back and asked for my rss feed :)

19:47 Bronsa: ivan: the second patch doesn't include it

19:47 callen: yogthos: me likey extensions.

19:47 ivan: I think Clojure core uses whitespace mixups as a blame tool

19:47 yogthos: callen: lol at that point I didn't actually have rss ended up making this for it https://github.com/yogthos/clj-rss

19:47 callen: good to hear

19:48 callen: yogthos: I'm starting clojurewiki btw.

19:48 yogthos: callen: it's kind of draft, but seems like it should work overall

19:48 callen: yogthos: I got tired of people having to use clojuredocs

19:48 technomancy: callen: wait

19:48 did you see my message earlier?

19:48 yogthos: callen: nice! more docs is good, not using clojuredocs also good :P

19:48 callen: technomancy: no

19:48 technomancy: clojuredocs has a rest API in Clojure

19:48 just no frontend yet

19:48 callen: technomancy: but does your thing have a wiki?

19:49 technomancy: the cd-client thing included in lein repl uses it

19:49 callen: technomancy: if not, I can leave the docs to your thing, but I still need a wiki ala EmacsWiki.

19:49 yogthos: clojure-doc is kind of going in that direction too btw

19:49 callen: yogthos: it's CWZ though, so their whole stack/situation is weird.

19:50 technomancy: the only reason EmacsWiki works is that there was a huge vacuum in which there weren't any places to put emacs-related tidbits

19:50 callen: nothing wrong with it, much love for them.

19:50 yogthos: callen: what's the deal with that totally not in the loop :)

19:50 technomancy: (also because kensanata is a machine)

19:50 clojure has the opposite problem; these "I know, I'll gather all the informations" sites spring up every other week

19:50 callen: yogthos: so clojure-doc is run by the ClojureWerkz people (Timbre, etc)

19:50 yogthos: I think the idea behind clojuredocs is really good, the api + examples really works

19:50 callen: yogthos: they're like uh, a special forces strike group of people obsessed with batteries included and idioms

19:51 yogthos: callen: that doesn't sound too bad :P

19:51 callen: yogthos: it's not bad, clojure-doc is great

19:51 technomancy: clojure-doc is like a wiki, you just have to use pull requests to submit stuff

19:51 the turnaround time is really pretty impressive

19:51 callen: yogthos: it's just that their process for it is a little weird. It's a meritocratic deal though, if something inspires you, write a pull request.

19:51 yogthos: yeah I added an eclipse tutorial there, then got lazy lol

19:51 callen: technomancy: there's nothing that covers praxis or practicum.

19:52 yogthos: it's very active though, I get notifications on git activity like once an hour about it :)

19:52 callen: technomancy: too many questions get asked and answered on here regarding 'why' or what's idiomatic, they get answered and the knowledge is lost to the aether.

19:52 technomancy: you may be fine with because you're already adept at Clojure, I don't think it's fair to the noobies though.

19:52 with that*

19:52 yogthos: callen: yeah a lot of basics could be captured better in my opinion

19:52 technomancy: I think you're underestimating the effort something like that would take

19:52 bbloom: technomancy: i wish github's wikis weren't in a separate repository... i like my documentation in the code base and readable from vim

19:53 callen: yogthos: well not just bare-bones examples of an API function, but "do do this, don't do that, here's why..."

19:53 technomancy: bbloom: I like just checking a doc/ dir full of .md files in

19:53 bbloom: it would be so nice to have a wiki that makes the clojure/doc/ folder fill up

19:53 technomancy: yeah, i agree completely

19:53 technomancy: it's basically a wiki

19:53 callen: sandbar vs. friend, any opinions?

19:53 bbloom: technomancy: basically, but it misses on critical feature:

19:53 yogthos: callen: yeah that's useful too, I think you kind of go through stages, first you need bigger examples and to see idiomatic code

19:53 bbloom: being a "wiki"

19:53 callen: yogthos: yes.

19:53 bbloom: the fact that something is a "wiki" is a feature b/c it means people are less scared to change it

19:54 yogthos: callen: and then you get to the point where you kind of know your way around and you just need an easy way to find functions and examples of using them

19:54 bbloom: if there was some magic web ui wiki thing that let you contribute an edit, people would do it

19:54 technomancy: bbloom: github has a fork+edit button, doesn't it?

19:54 for arbitrtary files in the repo

19:54 bbloom: yes, i was just about to mention that

19:54 fork&edit is a huge improvement

19:54 callen: yogthos: in particular for the concurrency and macro stuff it would be nice also to have all the potential pitfalls collected in one place.

19:54 bbloom: but i wish there was an an edit without fork, if that makes any sense

19:54 yogthos: callen: it took me a long time to grok macros :)

19:54 bbloom: technomancy: it's totally a trivial, semantic detail, but this stuff counts

19:55 yogthos: callen: the main issue wasn't understanding how they work, but finding legit uses for them :)

19:55 technomancy: bbloom: yeah, but allowing that in your mainline repo would be awful

19:55 bbloom: technomancy: recall the JIRA bitching :-)

19:55 yogthos: callen: it's one of those things that just has to click eventually

19:55 bbloom: technomancy: i'm not saying edit without a PR

19:55 i'm saying, PR with a patch instead of with a fork

19:55 callen: yogthos: in general I only when macros when I want to suspend evaluation of something until I'm done reformulating the final result.

19:55 technomancy: oh, gotcha. sure.

19:55 bbloom: it has to *feel* light weight

19:55 callen: yogthos: I don't think of them in terms of syntax, unlike most guides I've seen.

19:55 bbloom: even if it's not, or even if it already is, but doesn't feel like it

19:56 technomancy: I always edit wikis with a local clone anyway

19:56 bbloom: technomancy: totally

19:56 technomancy: so forking doesn't seem like much of a difference on top of that

19:56 bbloom: but we're weirdos.

19:56 technomancy: but I can't speak for other workflows

19:56 bbloom: not so long ago, i'd see spelling errors in a README.md and just ignore them

19:56 yogthos: callen: I find I think of them in terms of templating, like if I have code repeating over and over it's a sign for a macro :)

19:56 bbloom: b/c even with the fork and edit button, it felt intrusive

19:57 now, i just don't give a shit and do the fork & edit, but it required a concious thought: "fork & edit isn't heavy weight, just do it"

19:57 callen: yogthos: that's a good way to think about it.

19:57 bbloom: it's the whole free vs a penny thing

19:57 callen: yogthos: that's how I used to think about it, but I've gotten even more conservative about it.

19:57 bbloom: right now, contributing to documentation feels like it costs several pennies of my time

19:57 technomancy: bbloom: reminds me I want to make a bot that opens pull requests that replace (C) with ©

19:57 hmm; seajure is coming up next week....

19:57 bbloom: technomancy: heh, that would be awesome

19:57 devn: make one that does kibit replacements

19:57 bbloom: technomancy: dammit, if i'm in irc before seajure, remind me

19:57 yogthos: callen: I find you don't want to be afraid of using them, but it's good to keep them short and focused

19:58 technomancy: devn: not till kibit #2 is fixed; ugh

19:58 bbloom: technomancy: i'm likely to forget, considering i'm like meeting free :-P

19:58 devn: there's a kibit 2?

19:58 technomancy: bbloom: will do =)

19:58 yogthos: callen: also kind of have to weigh whether it's really a repeating pattern or not

19:58 technomancy: devn: https://github.com/jonase/kibit/issues/2

19:58 ooooh slamhound bot

19:58 yogthos: callen: you can use same heuristic as for refactoring stuff, if I do it once or twice it's ok, if I notice myself doing it a lot then it's time to refactor :)

19:59 callen: and most of the time you can refactor with a function, but if that doesn't work I up it to a macro

19:59 technomancy: I got a pull request from a whitespace cleanup bot once

19:59 it were a blast

19:59 Bronsa: I'm the only one who thinks that the ::foo/bar syntax is not really a good idea?

20:00 technomancy: http://achewood.com/index.php?date=08162002

20:01 pppppppaul: What does that syntax mean? I I'm using it in slingshot

20:02 technomancy: are people using clojure-test-mode with nrepl successfully?

20:02 ISTR a few lingering issues

20:02 bbloom: Bronsa: yeah, i've been burned by :: a few times

20:02 Bronsa: just stopped using it and started using explicit namespaces

20:03 callen: anybody have any opinions as far as sandbar vs. friend?

20:03 yogthos: ? ^^

20:03 devn: technomancy: i think i followed the directions on the slamhound repo correctly, but it doesn't seen slamhound as a task

20:03 yogthos: callen: friend seems to be a bit more popular I think?

20:03 technomancy: callen: friend is from cemerick, a trusted household name in Clojure Library providers.

20:03 devn: an alias in your user profile?

20:04 bbloom: Bronsa: ::keywords are only really useful for private sentinel values, but i think a gensym are probably better for that

20:04 callen: I was hoping for specifics, but okay.

20:04 technomancy: callen: I don't think sandbar is actively maintained either.

20:04 bbloom: (def sentinel (gensym))

20:04 devn: in ~/.lein/profiles.clj => {:user {:dependencies [slamhound "1.3.0"]} {:aliases {"slamhound" ["run" "-m" "slam.hound"]}}}

20:04 technomancy: bbloom: eh?

20:04 devn: technomancy: ^

20:04 Bronsa: it's like one of the few places (if not the only) where the clojure reader needs to talk to the runtime

20:04 technomancy: bbloom: it's not nearly as readable when looking at the data

20:05 callen: yogthos: technomancy: works for me, thanks!

20:05 technomancy: bbloom: and you have to at least defonce it

20:05 bbloom: technomancy: yeah, so use a qualified keyword

20:05 technomancy: you're right, hence i don't ever really do that :-P

20:05 devn: technomancy: err: [[slamhound "1.3.0"]]

20:05 dnolen: bbloom: that's not re: ns'ed keywords

20:05 not true

20:06 technomancy: devn: do other aliases work?

20:06 bbloom: dnolen: i was referring to the ::keyword syntax with the automatic namespace

20:06 dnolen: not namespaced keywords in general

20:06 devn: technomancy: i don't have any others

20:07 dnolen: bbloom: oh right, I've been burned by :: as well, but still useful I think.

20:07 bbloom: dnolen: i don't think it's useful enough to justify the complication to the reader

20:07 technomancy: devn: try adding a few? maybe one that maps to a string and one that maps to a vector?

20:07 devn: technomancy: here's my full current profiles.clj

20:07 https://gist.github.com/4403577

20:07 bbloom: dnolen: it's useful at a level for which *a lot* of other clojure feature proposals were, rightfully, rejected

20:08 dnolen: bbloom: given the ubiquity of maps, I'm not sure I agree

20:08 keyword will clobber otherwise.

20:08 bbloom: dnolen: just use explicit namespaces

20:08 technomancy: devn: you defined an :aliases profile =)

20:08 bbloom: otherwise you can't copy paste your maps, which is where you get burnt

20:09 dnolen: bbloom: I'm sorry I don't think anyone will want to write :clojure.core.logic.nominal/foo

20:09 ever

20:09 anybody doing serious work with maps will want a shorthand

20:09 bbloom: dnolen: it doesn't need to be a real namespace... just use :nominal/foo

20:10 otherwise, they'd *have to* write :clojure.core.logic.nominal/foo if they aren't inside clojure.core.logic.nominal anyway

20:11 dnolen: bbloom: there's no reason to hide information from anyone - :nominal/foo is just waiting to clobber with another :nominal/foo

20:12 squidz: can anybody tell me why I get an exception when applying max on a empty list generated with filter (apply max (filter ..))? When I run it just passing in a plain ol empty list, it doesnt complain though: (apply max ())

20:12 bbloom: dnolen: if you're worried about that, write out the whole namespace.... you only have the option of the :: shortcut *in the namespace itself*

20:13 Bronsa: you got me going, feel free to jump in and get my back here anytime :-)

20:13 devn: technomancy: so... how should this look?

20:13 Bronsa: ew, i wasn't even reading

20:13 technomancy: devn: put :aliases in the :user profile

20:13 Bronsa: wait for me to check the backlog

20:13 dnolen: bbloom: not sure why I should write the whole namespace why I can take two different packages and alias

20:13 when I can.

20:14 technomancy: devn: reindent and it'll be clear

20:14 callen: yogthos: http://weavejester.github.com/compojure/compojure.handler.html hokay so.

20:14 Bronsa: 02:00:03 bbloom: dnolen: it doesn't need to be a real namespace... just use :nominal/foo

20:14 well, that's one thing that bothers me about keywords

20:14 dnolen: Bronsa: certainly we've run into this problem in CLJS as well - but I think the reliance on maps and similar named packages you want ns aliasing.

20:14 Bronsa: they *are* namespaced

20:14 callen: yogthos: am I missing something, or is the handler missing a lot?

20:14 Bronsa: but they needn't the namespace

20:14 yogthos: callen: yeah the lib-noir handler adds a lot now :P

20:14 Bronsa: :foo/bar will work even if the namespace foo doesn't exist

20:15 dnolen: Bronsa: they are not namespaced to the package level which what you want in world of maps from anywhere.

20:15 Bronsa: that's not the point for any other clojure namespaced construct

20:15 yogthos: callen: app-handler and war-handler on the bottom https://github.com/noir-clojure/lib-noir/blob/master/src/noir/util/middleware.clj

20:15 Bronsa: but the :: syntax makes them partecipate in that namespace abstraction

20:15 callen: yogthos: ah I see it. Why is the namespace noir.util instead of lib-noir?

20:15 dnolen: Bronsa: which is good, because I don't know what *your* keys mean.

20:16 yogthos: callen: it was like that when I got there :)

20:16 technomancy: Bronsa: if the namespace had to exist we couldn't hijack it for Leiningen :dependencies declarations =)

20:16 bbloom: so the main difference between keywords and symbols are that keywords always resolve to themselves and symbols resolve to something different

20:16 i think you could make the case that keywords should resolve to some expanded namespaced version of a keyword

20:16 but that's not how it is currently, and it isn't immediately obvious to me how that would work

20:16 particular with respect to the reader

20:16 callen: Raynes: ring ring, bananaphone. noir.middleware.utils -> lib-noir?

20:16 technomancy: namespaces hold vars

20:16 they don't hold keywords

20:16 Bronsa: well my point is that ##(namespace :foo/bar) is not a namespace

20:16 lazybot: ⇒ "foo"

20:17 Bronsa: where ##(namespace ::clojure.core/foo) is

20:17 lazybot: ⇒ "clojure.core"

20:17 dnolen: Bronsa: but ::foo/bar *is* which is useful, but yes complicates the reader

20:17 Bronsa: and ##(namespace +) is too

20:17 lazybot: java.lang.ClassCastException: clojure.core$_PLUS_ cannot be cast to clojure.lang.Named

20:17 Bronsa: dnolen: I'm not saying it's not useful

20:17 devn: technomancy: d'oh! thanks

20:17 Bronsa: I'm saying that in my head it's not entirely consistent

20:17 technomancy: wait, :: workon already-qualified keywords?

20:17 Bronsa: technomancy: yeah

20:17 technomancy: that's ... weird

20:17 Bronsa: ,(alias 'c.c 'clojure.core)

20:17 bbloom: dnolen: ::foo/bar isn't valid

20:17 ::bar is

20:18 Bronsa: &(alias 'c.c 'clojure.core)

20:18 lazybot: ⇒ nil

20:18 bbloom: :foo/bar is

20:18 ::foo/bar isn't

20:18 Bronsa: &::c.c/foo

20:18 lazybot: java.lang.RuntimeException: Invalid token: ::c.c/foo

20:18 dnolen: bbloom: it is, if you've aliased a namespace

20:18 technomancy: ok, whew

20:18 Bronsa: hmh?

20:18 well, in the repl it works, it must be lazybot doing something

20:19 &(do (alias 'c.c 'clojure.core) ::c.c/foo)

20:19 lazybot: java.lang.RuntimeException: Invalid token: ::c.c/foo

20:19 Bronsa: w/e

20:19 bbloom: it's not working in my repl....

20:19 Bronsa: user=> (do (alias 'c.c 'clojure.core) ::c.c/foo)

20:19 :clojure.core/foo

20:19 bbloom: i get "Invalid token"

20:19 Bronsa: it is in mine

20:19 bbloom: just tried (alias 'core 'clojure.core)

20:19 dnolen: bbloom: trust me it works, it's worked forever

20:19 like pre 1.0

20:19 bbloom: then just did ::core/inc

20:20 Bronsa: woah

20:20 oh, whell

20:20 well*

20:20 it's not working with the do

20:20 bbloom: i can't get it to work at all lol

20:21 Bronsa: user=> (alias 'foo 'clojure.core)

20:21 nil

20:21 user=> ::foo/+

20:21 :clojure.core/+

20:21 devn: technomancy: that's like...magic

20:21 bbloom: i get #<RuntimeException java.lang.RuntimeException: Invalid token: ::foo/+>

20:21 Bronsa: weird

20:21 dnolen: bbloom: probably lein repl goofiness

20:21 technomancy: devn: woooo

20:21 Bronsa: it is working in my lein

20:22 bbloom: lol ok well then let me revise my prior arguments:

20:22 Bronsa: using lein repl not in a project works fine too

20:22 dnolen: Bronsa: oops, works in both

20:22 devn: technomancy: really cool. for a minute there I didn't think it did anything, so I jump to my file and it says it changed on disk, reload, and it's the exact same ns declaration i had a moment prior

20:22 thanks

20:23 bbloom: finally got it to work: doesn't work with a project

20:23 wtf?

20:23 Bronsa: weird

20:23 bbloom: technomancy: bug report ^^

20:23 heh

20:23 technomancy: bbloom: master or a preview?

20:23 bbloom: dnolen: thanks, i had no idea that this existed

20:24 Bronsa: yeah bbloom

20:24 bbloom: technomancy: Leiningen 2.0.0-preview10 on Java 1.6.0_37 Java HotSpot(TM) 64-Bit Server VM

20:24 technomancy: I think some of the repl reader stuff has been fixed recently to be less interpretive

20:24 Bronsa: that's not working for me either

20:24 technomancy: don't know if it was after 10 though

20:24 Bronsa: only in a project though

20:24 bbloom: technomancy: try (alias 'core 'clojure.core) followed by ::core/+

20:25 dnolen: well in light of this, i revise my opinion on ::

20:25 Bronsa: user=> ::foo/+

20:25 #<RuntimeException java.lang.RuntimeException: Invalid token: ::foo/+>

20:25 user=> 1

20:25 :clojure.core/+1

20:25 i get this

20:25 bbloom: it had features i didn't know it had :-P

20:25 in fact, it has the features i was literally proposing to you as an improvement heh

20:25 technomancy: hah

20:26 bbloom: dammit that hickey guy knows wtf he is doing

20:26 technomancy: works for me

20:26 Bronsa: technomancy: beta10 inside a project?

20:26 technomancy: oh wait, this is nrepl.el

20:26 Bronsa: running clojure 1.4

20:26 * technomancy tries reply

20:27 technomancy: yeah I get Exception Ambiguous match for "::core/+"

20:28 gfredericks: what is it that depends on thneed again?

20:28 bbloom: dnolen: thanks, learned something here... actually quite relevant to what i'm working on

20:28 gfredericks: lein keeps piping up about looking for snapshots

20:28 dnolen: bbloom: yes I don't know how anyone could sell the idea of working only maps w/o real namespaced keywords

20:29 technomancy: https://github.com/trptcolin/reply/issues/new

20:29 err: https://github.com/trptcolin/reply/issues/94

20:30 Bronsa: w/e I still don't like that

20:31 bbloom: dnolen: i had just never seen a keyword of the form ::foo/bar, only ever ::bar

20:31 dnolen: Bronsa: heh

20:31 Bronsa: (read-string "foo/bar") works if foo is not defined AND if foo is an alias or a namespace

20:31 bbloom: http://clojure.org/reader says "A keyword that begins with two colons is resolved in the current namespace:"

20:31 Bronsa: i don't see why ::foo/bar requires it to be loaded

20:31 bbloom: and then provides the example ::rect

20:31 but no other examples :-/

20:32 also technomancy's stuff is broken, blame him

20:32 :-)

20:32 technomancy: bbloom: nah I never use lein repl

20:32 dnolen: Bronsa: that's a different issue, in my opinion tho I don't know anyone would read ::foo/bar from some random place, it should arrive fully-namespaced.

20:32 technomancy: I got a vim user to write it for me =)

20:33 Bronsa: dnolen: to be honest, i think it will never be a problem to me or hardly for anybody

20:33 but it bothers me.

20:33 dnolen: Bronsa: haha, that's Clojure for you.

20:34 technomancy: thinking about cutting a clojure-mode release soon; any issues remaining worth addressing?

20:34 bbloom: oh shit, *cringe*

20:34 i just did (read-string "::core/+") after making an alias

20:34 it expanded it

20:34 Bronsa: YEAH

20:34 that's exactly what bothers me

20:34 bbloom: that seems *wrong*

20:35 Bronsa: it resolves the namespace at read time

20:35 symbols resolve it at eval time

20:35 it should throw when trying to eval it

20:35 seancorfield: technomancy: will that be a clojure-mode that no longer enables slime?

20:35 Bronsa: not when trying to read it

20:35 bbloom: worse than that: it's impacted by the dynamic environment of the read caller!

20:35 technomancy: seancorfield: yeah

20:36 bbloom: surely the reader should be parameterized with aliases and that a default empty set of aliases should be used

20:36 * seancorfield does a happy dance!

20:36 technomancy: seancorfield: I vaguely recall issues with clojure-test-mode and nrepl.el, have you been using that?

20:36 Bronsa: ew

20:36 I'm still using slime

20:37 seancorfield: ah, just saw the email notifications about #108 and #115 - thanx! no, i don't specifically use clojure-test-mode (i use expectations-mode which already works with nrepl.el)

20:37 bbloom: Bronsa: please make Blind let you read with an explicitly provided set of aliases :-)

20:37 technomancy: Bronsa: slime will still work, you'll just have to copy clojure-jack-in into your own dotfiles

20:38 Bronsa: that's enough work to do to make me switch to nrepl

20:38 technomancy: maybe that should become its own lib or something

20:38 heh; or that

20:38 pppppppaul: Can I get some datomic help?

20:38 Bronsa: bbloom: what do you mean?

20:39 pppppppaul: Trying to understand cardinality many

20:39 seancorfield: Bronsa: switch to nrepl - you know you want to :)

20:39 pppppppaul: What would a db/add look like?

20:39 bbloom: when resolving ::foo/bar read-string is looking at (ns-aliases *ns*)

20:39 Bronsa: seancorfield: i'm don't really want to, I'm actually quite lazy

20:39 oh, i see bbloom

20:39 bbloom: Bronsa: it would be nice if the underlying implementation looked at some parameter

20:39 or dynamic config var or something

20:39 such that i could override it

20:40 Bronsa: yeah, it must be a dynamic var

20:40 technomancy: the whole "you have to compile the whole ns before you can do anything in nrepl" behaviour reeeeeeeeally sucks

20:40 plus I miss the inspector

20:40 but apart from that it's pretty good

20:40 bbloom: yeah, and then you have like read-string* with a config, but the default read-string produces a config from *ns* and then calls read-string*

20:40 Bronsa: bbloom: it's quite easy to do, really

20:40 https://github.com/Bronsa/blind/blob/master/src/blind/reader.clj#L508-L510

20:40 bbloom: Bronsa: yes, quite easy. hence please do it :-)

20:43 dnolen: someone w/ more concurrency chops then me wanna verify my thinking is correct here, http://gist.github.com/4403838

20:43 what I care about is whether the swap! is how this should be done.

20:44 it seems to me I do need to test contains? twice right?

20:44 bbloom: dnolen: yeaah you need to move the contains into the swap

20:45 dnolen: bbloom: there is contains? there too

20:45 technomancy: (add-hook 'nrepl-mode-hook (lambda () (setq nrepl-buffer-ns (clojure-find-ns))))

20:45 fixes the lousy default nrepl.el buffer-ns behaviour

20:45 bbloom: er, i mean more generally: you can't make a decision about a derefed value if you're then going to deref it a second time

20:45 dnolen: the swap is an implicit second deref

20:46 dnolen: bbloom: but if we deref and we have an entry there's nothing to do

20:46 bbloom: it's only if it's missing that we run into trouble, and thus the second contains check in the fn passed to swap

20:47 bbloom: dnolen: sorry, im not looking very deeply at your particular use case

20:47 all i'm saying is that if you deref, then conditionally swap, you need to recheck your assumptions inside the swap

20:47 in theory, you can just unconditionally swap, but only conditionally change the value

20:47 but i dunno about the exact impact of that with respect to perf and watcher callbacks, etc

20:47 dnolen: bbloom: ok, I'm rechecking my assumptions so I think I'm ok.

20:47 Bronsa: bbloom: http://sprunge.us/iRBN?diff is this what you wanted?

20:49 dnolen: finally tabled core.logic goals don't need to be reset via hacks

20:49 bbloom: dnolen: concurrency is hard :-) i've seen a bunch of code that does (when (pred @x) (swap! x ...)) which is just *clearly wrong* b/c they don't recheck inside the swap

20:49 Bronsa: looks like it!

20:50 Bronsa: i'm working on something that's extremely map and keyword heavy... plus i want to make a few dev tools for it, so i suspect in some months time i'll thank you and dnolen for this :-)

20:50 amalloy: dnolen: your first swap! looks fine. the second one is a little more worrying but i can't quite tell what's going on

20:50 Bronsa: oh damn

20:50 my slime-repl

20:50 i just outputted the result of reading core.clj in my repl

20:51 dnolen: amalloy: ok you're right, I'll fix that one too. Thanks!

20:51 amalloy: it looks to me like you're doing exactly what bbloom (incorrectly) thought you were doing in the first swap!: checking the whether @table# contains cache# outside of a swap, and then unconditionally modifying it inside the swap!, even if some other thread has beaten you to it

20:52 bbloom: amalloy: i didn't really read his code. i just jumped to the general principal. forgive me!

20:53 Bronsa: heh bbloom binding every read slows thing down a bit

20:53 bbloom: Bronsa: blah

20:53 Bronsa: maybe i should get *alias-map* to be public

20:53 amalloy: no blame attaches! you gave the right advice in the wrong place

20:53 Bronsa: so that you bind only once

20:54 it gets from 560ms to read core.clj 10 times to 850

20:55 loliveira: can anybody please point me the original post that states that some programmers are 10x faster than others?

20:55 seancorfield: nice to see mac os x full screen support in the emacs nightlies... i thought i'd seen mention of a pretest build but 24.2.91 is the latest i found and that doesn't have the full-screen fix

20:55 bbloom: side note, here's a macro i've used a bunch: (defmacro swapping [sym & body] `(swap! ~sym (fn [~sym] ~@body)))

20:55 maybe better named swapping!

21:00 hyPiRion: uh

21:01 dnolen: hey finally understanding swap! after 4 years of Clojure, better late than never!

21:02 bbloom: dnolen: heh. have you ever written any meaningfully concurrent code before?

21:03 dnolen: there are *a whole bunch* of places in cljs that get swap! wrong... luckily js is single threaded....

21:04 zilti: https://github.com/munrepl/server <- Multi-user nREPL proof of concept

21:05 good night

21:06 dnolen: bbloom: no, I've had no need in any of the software I do for work. Heh, yes about CLJS, but I don't see JS ever going shared memory w/ threads.

21:07 bbloom: dnolen: yeah, but it's worth doing swap! right for when some function's impl is inevitably copy pasted to somewhere that does have shared memory...

21:09 amalloy: bbloom: i'm sure dnolen would take pull requests fixing such places as you've noticed

21:09 dnolen: bbloom: yeah, the mulitmethod implementation will need some looking over ...

21:10 bbloom: amalloy: next time i spot one, i'll patch it :-P

21:10 dnolen: use my dispatch map! :-)

21:13 dnolen: bbloom: I need to find time to actually check it out :)

21:13 bbloom: dnolen & Bronsa: hmmm... do tagged literals respect aliases like ::foo/bar ?

21:14 dnolen: bbloom: don't think so

21:14 bbloom: dnolen: should they?

21:14 dnolen: bbloom: I think they should yes

21:14 bbloom: i'd agree...

21:15 gfredericks: what are the ways that a project can have a dep not listed in `lein deps :tree`?

21:15 dependency in the sense of things that lein checks for when you run it

21:17 Bronsa: bbloom: I can make blind do that, however, it's 3:07AM and I think I'm going to bed now

21:17 will do it later :)

21:17 bbloom: Bronsa: by all means, throw a ;;TODO in there and go to bed

21:23 dnolen: ok so that thing i was asking about the other day re core.logic: it's called a "Topological Sort"

21:23 i was unable to find a reasonable prolog implementation

21:25 i basically want to take a map of the form {:foo {:deps #{:bar} :before #{baz} :after #{bat}} ...} and some set of keys #{:foo} and produce a sequence of keys obeying the before and after values, sucking in all the other nodes based on dependencies

21:28 dnolen: bbloom: amalloy: thanks again on the swap! help. Only 5 more unprincipled uses of swap! in core.logic, but that's for another day.

21:28 bbloom: that's surprising I see a couple of links on google.

21:29 gfredericks: oh it's lein-ring I think

21:29 callen: is there a version of Google I can use where it stops second-guessing me?

21:29 bbloom: dnolen: i saw one or two implementations, but there was discussion of O(N) vs O(N^2)

21:29 callen: turn on the verbatim option

21:30 dnolen: it seemed like it would be easier to just hand code one of these algos with the tweaks i need: http://en.wikipedia.org/wiki/Topological_sorting#Algorithms

21:30 rather than encode it at a logic problem, which was making my head hurt

21:30 callen: bbloom: thank you

21:31 xeqi: gfredericks: yeah, plugins don't show up in lein deps :tree

21:32 are you asking about a thneed snapshot?

21:32 callen: bbloom: it's not actually showing me the option for a verbatim search. http://zipmeme.com/uploads/generated/g1334961617145439732.jpg DuckDuckGo it is.

21:32 gfredericks: xeqi: yeah I think I've traced the whole story (lein-ring), am trying to figure out the easiest place to patch it

21:32 xeqi: gfredericks: I use https://github.com/ato/clojars-web/blob/master/project.clj#L35

21:33 gfredericks: xeqi: I'd think lein-ring should upgrade leinjacker, but I know nothing about leinjacker so can't guess if that's straightforward or not

21:33 callen: oh wow. if I duckduckgo 'clojure swap!' (without quotes) it shows me the clojure doc.

21:33 dnolen: bbloom: it makes my head hurt too :)

21:33 gfredericks: xeqi: that looks like a great bandaid, thanks

21:34 xeqi: I don't htink upgrading would require much work

21:34 could file an issue / bug weavejester when hes around

21:35 ivan: it appears &tbs=li:1 turns on verbatim

21:36 callen: ivan: thank you, but it seems a little ridiculous that I have to go to those lengths.

21:36 ivan: for just one billion dollars I can make a good search engine for you

21:38 it is too bad Google didn't preserve their real indexes from 2000-2004, I would have really liked to search those

21:38 bbloom: does here anyone actively use metadata for anything outside of compiler-ish stuff?

21:38 ie convey meaningful program state

21:38 dnolen: bbloom: sometimes yes

21:38 bbloom: dnolen: curious, what?

21:39 gfredericks: xeqi: I'll file an issue

21:40 dnolen: bbloom: ad-hoc runtime stuff - it's a great way to provide extensibility - users can leverage existing types w/o committing to create new types etc.

21:40 creating

21:40 bbloom: dnolen: hm ok...

21:40 dnolen: bbloom: I don't make types w/o meta field because you just never know

21:41 bbloom: dnolen: so i've got one use case where i have a pluggable system that has a bunch of functions that run in order. however, i want to be able to convey an "abort" state of some kind, but i also need to convey the return value. the return value will *always* be a map

21:41 i'm thinking about conveying that abort signal via metadata: ^:abort the-return-value

21:41 or rather with-meta the-return-value

21:41 dnolen: bbloom: seems reasonable to me

21:42 bbloom: I use that trick to convey information about return values as well

21:42 gfredericks: https://github.com/weavejester/lein-ring/issues/57

21:43 bbloom: dnolen: my initial reaction was "well, this is a dirty hack for not having multiple return values" but then i realized that multiple return values have the problem of not knowing what they are, since they are positional... so metadata as a associative multiple return values is interesting

21:43 but only works on types that support metadata

21:43 this is the first time i've ever wanted to use metadata for something other than the compiler itself, so it feels kinda unnatural to me... but i guess i'll just go for it

21:44 dnolen: and entertainly enough, this is a short circuiting reduce situtation like we just talked about lol

21:46 dnolen: bbloom: heh

21:48 Sgeo: Short-circuiting reduce?

21:48 Where?

21:48 (Don't tell me Haskell or I'll slap you)

21:49 bbloom: loop/recur :-P

21:54 bosie: i use leiningen. i have pdfbox in my dependencies

21:55 (org.apache.pdfbox.util.PDFTextStripper. ) results in "CompilerException ClassNotFoundException)

21:56 now the obvious question is... am i doing sth wrong?

21:57 callen: bosie: refheap

21:59 bosie: callen: refheap what?

21:59 bbloom: dnolen: metadata approach worked out nicely. thanks for calming my fears :-)

22:00 dnolen: bbloom: cool!

22:00 bosie: callen: https://www.refheap.com/paste/7909

22:00 dnolen: bbloom: metadata is definitely one of those things I miss elsewhere. The fact that it works so great for compile & runtime is really sweet.

22:00 bbloom: dnolen: https://www.refheap.com/paste/7910

22:01 dnolen: bbloom: nice

22:01 bbloom: that allows some pass function to optionally restart expansion by just calling expand again

22:01 works absurdly nicely

22:11 callen: bosie: you have to add the dependency mate.

22:11 bosie: it works like maven.

22:11 bosie: callen: but thats what i am doing, no?

22:12 oh

22:12 isn't this line taking care of it? [pdfbox "0.7.3"]

22:14 callen: bosie: refheap the output lein deps :tree

22:14 of*

22:15 bosie: https://www.refheap.com/paste/7912

22:16 callen: bosie: [org.apache.pdfbox/pdfbox "1.4.0"]

22:17 hyPiRion: yeah, that should work

22:18 bosie: huh

22:18 it works

22:19 oh

22:19 i see

22:19 thank you callen

22:19 callen: bosie: all I did was google your problem.

22:19 It's not like I'm some repository of arcane knowledge.

22:19 bosie: callen: thats what i did too

22:34 Rich_Morin: I'm a bit confused by something in https://github.com/daveray/vimclojure-easy. It says "Hit \ef to evaluate the file." This doesn't work and I can't find anything about that syntax in my vi docs. Help?

22:46 wingy: hey datomic users .. can i have meta data for an attribute in datomic?

22:53 oh i can use the :db/doc key

23:10 Raynes: Watching router firmware flash is like nerd porn.

23:12 It's hilarious, they fix an issue with non-updating data usage statistics that I pretty much required, and they do it a month before I leave Alabama and no longer require this particular router because I wont be using mobile internet anymore.

23:27 wingy: i forgot .. maybe i can add my custom property to a attribute definition

23:27 yedi: should functions reformat input data to fit their needs, or should they just assume the input data is formatted correctly?

23:29 ivan: (process (fix-data junk))

23:30 Raynes: yedi: That's way too vague a question to answer.

23:31 yedi: hm yea

23:56 chouser: yedi: would you consider reformatting the input data to be a different thing from whatever else the function is going to do? Do you want your function to do two different things?

Logging service provided by n01se.net