#clojure log - Dec 26 2012

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

0:27 Raynes: Here #clojure, have some markdown https://github.com/Raynes/cegdown

0:28 Frozenlock: Even if I prefer org-mode, I thank you for this :)

0:28 Raynes: technomancy: Christmas is the time for miracles and miraculous libraries.

0:28 philr: "You can use the with to-html" s/the/them/

0:28 technomancy: Raynes: I was basically about to say that in my announcement tweet.

0:28 Raynes: philr: Fixed.

0:29 philr: pedants can sleep easy once more.

0:29 technomancy: Raynes: now that you maintain an .md library may we look forward to future rants about how horrible the state of markdown is?

0:30 Raynes: technomancy: It is a pretty thin wrapper. I don't have the right to rant.

0:30 But for your sake, I agree with you on every point.

0:31 technomancy: completely bats

0:34 bbloom: ,()

0:34 clojurebot: ()

0:34 bbloom: wow. i find that surprising....

0:34 i'd have expected an error, but i guess () wouldn't possibly mean anything else but an empty list

0:34 technomancy: https://github.com/technomancy/slamhound <- it's out; 1.3.0 doesn't suck for :require :as and will not tell you to use :use

0:34 thanks primarily to alex baranosky

0:34 Raynes: technomancy: That sentence could have been worded so much better.

0:35 technomancy: "it's out; 1.3.0 doesn't suck for :require :as and will tell you not to :use"

0:35 Like drugs. Get it?

0:35 technomancy: So what is slamhound useful again?

0:35 technomancy: Raynes: I live in Washington; things are different here.

0:35 Raynes: useful for*

0:35 I can't envision a usage right this second.

0:36 technomancy: Raynes: it will clear all the leftover crud out of your ns forms that has accumulated over time

0:36 plus it'll organize/alphabetize them

0:36 Raynes: I have a dream of integrating tools like this and kibit (or whatever) with refheap.

0:36 That does sound cool.

0:36 technomancy: and pprint

0:36 Raynes: Wouldn't it be cool to have a "slamhound" button on refheap that gave you a namespace form from your pasted code?

0:36 Would you like this? Because I can make this happen.

0:37 technomancy: weeeeell

0:37 it's basically impossible to sandbox

0:37 because it's all just compile over and over

0:37 Raynes: Oh, it actually runs code?

0:37 technomancy: ayup

0:37 Raynes: Yuck

0:37 I mean, i get why

0:37 * technomancy cacles maniacally

0:37 Raynes: But yuck for me.

0:37 technomancy: yeah

0:37 oh, but also you can use it for other coolness

0:37 Raynes: Oh well, was a fun idea.

0:38 technomancy: if you want to start using a var but you can't be arsed to look up what the ns is and add it to your :require clause, you can just run slamhound on it, and it'll do it for you

0:38 liek magicks

0:38 Raynes: Haha

0:38 Nice

0:39 technomancy: although slamhound.el still uses slime; dang.

0:39 needs a refresh

0:39 still, it's rad

0:39 Raynes: Rad.

0:39 You're old.

0:41 Frozenlock: Sorry man, but I ain't doing corg-mode.

0:41 I wonder how many repos I have now.

0:42 Nice, I guess they don't give you an easy way to count them now.

0:42 To the tentaclemobile!

0:44 85

0:44 Not bad.

0:44 I wonder if that translates to epeen inches.

0:46 technomancy: You have 145 public repositories.

0:46 I just thought you should know.

0:47 technomancy: Didn't amalloy_ have some kind of github epeenometer somewhere?

0:48 technomancy: Raynes: yeah but it only measures when you joined =)

0:48 Raynes: Aw.

0:48 technomancy: http://github-percentile.herokuapp.com

0:48 Raynes: amalloy_: Let's do a github epeenometer with number of repos.

0:48 technomancy: heh

0:49 Raynes: I'll provide the laser and the tentacles, you provide the web.

0:50 technomancy: it's been done a bunch of times

0:50 though yours might distinguish itself by being honest about being an epeen-contest

1:06 Frozenlock: Cljs in cljs awoke an old desire of mine... something like emacs/konkeror in clojure. Is there such a thing yet?

1:07 Raynes: No.

1:16 Okay guys. I've given you laser and cegdown. Now I need to play video games and whatnot. Merry Christmas.

3:29 callen: I've been reading the docs, feeling a little silly asking this, but how does one go about embedding a lein task/plugin in a project?

3:29 like for running scripts.

3:58 dsantiago: callen: Are you trying to add a plugin to a project?

4:10 callen: dsantiago: sorrrta. I'm actually on to a different problem now.

4:11 No suitable driver found for jdbc:postgresql://localhost/dbname when I try to run a migration.

4:11 Been flipping around my database url and deps for a bit now.

4:11 dsantiago: was I was thinking of is less of a proper plugin, and more of a way to run one-off scripts.

4:11 what I*

4:11 dsantiago: but that's far more tractable than this damnable JDBC URL thing I'm somehow futzing u.

4:11 dsantiago: Did you add the postgres jdbc jar to your deps?

4:12 callen: o' course, [postgresql/postgresql "9.1-901.jdbc4"]

4:12 deps and dev-deps

4:12 dsantiago: Huh, I dunno on that one then.

4:12 callen: live is hell :(

4:12 life*

4:12 dsantiago: how have you been?

4:13 dsantiago: Good, good. Holidays.

4:14 callen: dsantiago: fantastic. I ended up coming to terms with Hiccup, using that until or unless somebody comes up with something better :)

4:15 dsantiago: I'm still working on it, I am. Had so much family in town this past week.

4:15 Haven't gotten anything done.

4:15 callen: I didna expect nuthin.

4:16 that's why I went with Hiccup for now. There's no pressure or anything, I'm happy with it for now.

4:16 dsantiago: Good, good.

4:17 callen: dsantiago: I'm only getting away with it because frontend guy wants to learn ClojureScript anyway

4:17 so I told him he'd be getting tossed off the dock into the lake and told to learn to swim.

4:19 dsantiago: Well, if he can handle JS coding, then surely he can write HTML in hiccup, I'd think.

4:20 callen: dsantiago: people are more persnickety about syntax and attached to familiarity than you might generally suspect.

4:20 I for one, rather like Hiccup now simply because of how *compact* it is.

4:20 dsantiago: you wouldn't happen to know how to reset the dependencies and force a re-download in a leiningen project would you?

4:21 lein clean && lein deps doesn't seem to have done it.

4:21 meh. nuked ~/.m2

4:21 that kinda sucked though.

4:23 no dice. jfc.

4:24 how do I always have these errors?

4:24 Anderkent: callen what's the error you're getting?

4:27 callen: Anderkent: No suitable driver found for jdbc:postgresql://localhost/dbname when I try to run a migration.

4:27 and yes, I have the postgres jdbc dep in my :deps

4:27 and yes, I tried nuking my m2

4:28 and yes, I'm getting to the point where I'm going to close my laptop and polish off that bottle of Russian vodka instead.

4:28 dsantiago: We might be at the point where you should paste some code and/or project.clj somewhere.

4:29 callen: oh yay, refheap is back up.

4:29 https://www.refheap.com/paste/7861

4:30 dsantiago: ^^

4:30 dsantiago: nevermind...figured it out...

4:31 dsantiago: let me know if you can detect from that paste what an utter pillock I am.

4:31 dsantiago: Well, you trying to splice the url in from getenv?

4:32 callen: dsantiago: that wasn't the problem and I tested that the getenv thing was working earlier.

4:32 dsantiago: notice the profiles.clj? it runs in a different context than the project

4:32 dsantiago: project has the jdbc dep...my ~/.lein/profiles.clj did not...

4:33 this is how much the gods hate me.

4:33 dsantiago: Ah, OK.

4:33 callen: now to find out why it's not detecting my migration.

4:33 dsantiago: right? see. SOY ESTUPIDO.

4:34 dsantiago: If only you were talking right this moment to the guy who advocated for the addition of profiles to lein, and tell him off.

4:36 callen: dsantiago: I'm bad at detecting sarcasm, I take it that was you?

4:37 dsantiago: so uh, I'm cool with profiles. I mean it caused me some pain when I had to move from lein v1 to lein v2, but a big fat warning about how the context for the ~/.lein/profiles.clj vs. ./project.clj woulda been cool.

4:37 dsantiago: try to have some mercy for the intellectual Tiny Tims of the world such as myself.

4:39 dsantiago: Heh, yeah, I overstate it a bit. I wrote the original profile support back in cake, but Phil did all the work in lein 2.

4:39 callen: dsantiago: either way, that was an unpleasant lesson with no clear GooglePath to wisdom. :P

4:40 at least I had the brainwave myself

4:40 Feel proud o' me self for that much.

4:42 that lying son of a bitch

5:00 pjstadig: you wouldn't happen to be 'round, wouldya?

5:36 yogthos: how much experience do you have wrangling leiningen profiles, plugins and/or migratus?

5:44 is anyone here using Migratus?

5:51 pjstadig: i am now

5:52 callen: ^

5:53 callen: pjstadig: I'm having a huge problem with migratus. I beg of you, please help me.

5:53 pjstadig: i shall try

5:53 callen: pjstadig: I've actually had a bit of a journey up to this point, but I'll tell you what's happening right now

5:53 pjstadig: migratus doesn't seem to have my project's classpath when it runs, so it says it cannot find any migrations

5:53 my migrations are under src/migrations

5:53 with the appropriate filename

5:53 I double-checked that it matches the exact regex and splitting code that migratus uses

5:54 I injected classpath dumping code into the migratus jar to verify, it doesn't have my project's classpath at runtime.

5:54 pjstadig: it tells me to go fly a kite here: https://github.com/pjstadig/migratus/blob/master/src/migratus/cli.clj#L40

5:54 pjstadig: how are you configuring migratus?

5:54 callen: boy lemme tell you.

5:55 pjstadig: first question, are you using lein v2.0?

5:55 pjstadig: no

5:55 not yet

5:55 callen: then I am likely totally fucked

5:55 https://www.refheap.com/paste/7863

5:55 I've been using 2.0 for some time now, and it's been 100% loss of my time, no gain at all.

5:55 sadly it's where things are going

5:55 so I don't really have a choice.

5:56 bawr: Is it just me, or are all Clojure introduction / environment setup guides like a year old or more?

5:56 callen: bawr: yes

5:56 2.0 broke a lot of stuff.

5:56 bawr: That's... suboptimal.

5:56 callen: pjstadig: I've been assuming so far that I need to see /Users/callen/code/garbwell/test:/Users/callen/code/garbwell/src in my classpath

5:56 for it to see src/migrations

5:57 if we assume that's correct, only my dependencies from my .m2/ are in my classpath when migratus is running.

5:57 bawr: yes it is. I'll do a write-up if and when I can get all this shit working

5:57 pjstadig: callen: moving migratus to 2.0 means i have to split out the lein part into a separated plugin project, which i've wanted to do anyway

5:57 callen: bawr: until then my hair is falling out and I'm alternating between drinking vodka and gulping coffee

5:57 pjstadig: but i haven't worked it all out yet

5:57 callen: pjstadig: so it's totally broken?

5:57 and I'm boned?

5:58 pjstadig: callen: you are correct that only our dependencies from your .m2 would be in your classpath when running

5:58 * callen loads laptop into a slingshot and defenestrates it

5:58 pjstadig: if you want src/migrations to be on the classpath, then you need to run your app from a jar

5:58 lein package first or something

5:58 callen: vut. then how does migratus work?

5:58 `lein migratus migrate` should just work.

5:58 Anderkent: ls

5:58 lazybot: bin data dev home lost+found media opt sbin selinux src swap tmp usr

5:59 Anderkent: oups

5:59 callen: there's a Rails hacker laughing at me somewhere.

5:59 Anderkent: wrong window

5:59 pjstadig: callen: that works in your dev environment because generally src is on the classpath

5:59 callen: Anderkent: I'm still working on that problem btw.

5:59 pjstadig: er, false, doesn't work in my dev environment.

5:59 Anderkent: sorry, I asked you about it then my laptop hung

5:59 and i rageleft to have breakfast

5:59 callen: Anderkent: I'm about to ragequit life.

5:59 Anderkent: so I didn't actually get your response or look at your problem :(

6:00 callen: pjstadig: I'm sitting here on my laptop, running it in my terminal on my thingy and it's "dev" insofar as the project running on my laptop locally is dev.

6:00 pjstadig: and it's not working.

6:00 Anderkent: let me look at the logs

6:00 bawr: callen: looks like starting with the new leiningen at least makes one pull less hair

6:00 pjstadig: not deployed to production?

6:00 but in a git checkout on your machine?

6:00 callen: pjstadig: no, I'm just trying to use your library for the first time ever

6:00 pjstadig: I added migratus as a dependency, I'm trying to run my first migration ever locally

6:00 to a local postgres instance

6:01 it's a little .sql file named in the way your system defines

6:01 bawr: callen: although I already had to patch it up to have sane repl (up/down arrows not working in Windows, switched to cygwin, and needed to patch lain even then).

6:01 callen: I just need the goddamn migrations directory to be on the classpath

6:01 bawr: that's weird, nrepl has always been fine for me in that respect.

6:01 pjstadig: what is the exact path of the file you're trying to run as a migration?

6:01 Anderkent: callen: lein or mvn?

6:01 callen: bawr: my issues usually concern the classpath and the stuff 2.0 changed

6:01 Anderkent: lein

6:01 $ ls ./src/migrations/

6:01 20121226014541-create-user-table.up.sql

6:02 $ pwd

6:02 /Users/callen/code/garbwell

6:02 pjstadig: and don't tell me the file is mis-named, I checked it against your code with the regex personally.

6:02 and I saw it gets split and destructured

6:02 and that all worked fine

6:02 pjstadig: no the same looks right

6:02 s/same/name/

6:02 Anderkent: and if you do lein repl, go to the migrations namespace and try to open a resource called '2012....sql', does it give you null?

6:02 callen: Anderkent: the REPL has the right classpath

6:03 Anderkent: I'd said that earlier

6:03 pjstadig: yeah so i think this is a lein 2.0 issue

6:03 Anderkent: sorry, wasn't here

6:03 callen: Anderkent: but when I dump the classpath in the migratus runtime it doesn't have it because it's a leiningen plugin that doesn't know about the project.

6:03 bawr: callen: if you get the newest lein and do "lein repl", do up and down arrows work on windows?

6:03 Anderkent: ah!

6:03 callen: pjstadig: I've established as much, I really just want to know how to fix it.

6:03 pjstadig: because when you are running `lein migratus migrate` it is using the plugin classpath, and your src dir is not on the class path

6:03 bawr: Could be some weird locale issue, I guess.

6:03 callen: bawr: I don't use windows

6:03 bawr: sorry, might've misunderstood.

6:03 Anderkent: shouldn't the plugin do eval-in-project then?

6:03 bawr: Yeah, normally neither do I. :)

6:03 callen: what Anderkent said. how do I do eval-in-project?

6:04 pjstadig: callen: unless there's a way to get lein2 to add a specific directory to the classpath, then there's no way at the moment

6:04 migratus needs to be upgraded to work with lein2 and have its lein plugin split into a separate project

6:04 it's been on my todo, and i should probably just do it

6:04 callen: so I'm fucked until then.

6:05 pjstadig: let me check though, cause we just upgraded to lein2 at work and migratus is still working for us

6:05 callen: wat.

6:05 how is it...

6:05 Anderkent: I see eval-in-project. Seems to be what's needed. Not sure what's required to port migratus though.

6:06 pjstadig: callen: yeah, we just have migratus as a dependency in our dev and "normal" profiles

6:07 Anderkent: yeah, that seems too specific to this particular plugin that i've never used.

6:07 pjstadig: not in the plugin list

6:07 callen: pjstadig: I tried defining it in my profiles.clj, under :plugins, but it didn't work

6:07 pjstadig: could you please explain?

6:07 Anderkent: are you tied to this migration library? I used drift without much issue

6:08 callen: Anderkent: it seemed lower friction than drift/ragtime/lobos

6:08 in particular I wanted something I could use from the command line

6:08 Anderkent: drift has a lein plugin

6:08 callen: drift and ragtime, IIRC, are too generic

6:08 and require that you define everything

6:08 I really just wanted something to execute some SQL and let get back to work.

6:08 pjstadig: callen: something like this https://gist.github.com/4379615

6:09 Anderkent: drift requires you to use a DSL to describe migrations, which i specifically wanted to avoid with migratus

6:09 SQL is already a DSL

6:09 callen: what pjstadig said. I just wanted .sql files.

6:09 pjstadig: plus drift doesn't work with git

6:10 callen: pjstadig: I did that. 'migratus' is not a task.

6:10 pjstadig: it assumes a single global version for your database

6:11 Anderkent: I don't see how that claches with using git?

6:11 callen: Anderkent: try using feature branches sometime with an incrementing global version

6:11 Anderkent: let me know how well that works for you.

6:11 Anderkent: the workflow git encourages (non-linear) doesn't work with linear migration schema

6:11 pjstadig: if you have a git branch that has a migration named 15-something that gets merged after a branch that has a migration 17-something, then 15-something will never run

6:11 Anderkent: oh, I'd scratch and rebuild the database on dev when you switch branches

6:11 oh

6:11 use dates

6:11 :)

6:12 callen: that's kinda the point

6:12 drift doesn't work like that.

6:12 drift uses a global incrementing version

6:12 pjstadig: rails fixed this by using dates for migrations and allowing migrations to execute independently

6:12 Anderkent: no, drift allows you to use timestamp-based versioning

6:12 pjstadig: instead of assuming "17 has run...oh then i can ignore anything less than that"

6:12 callen: it doesn't run the migrations independentlly

6:13 with or without timestamps

6:13 pjstadig: callen: what does your project.clj look like now?

6:13 callen: just because you change your global incrementing version to a timestamp doesn't change how it works

6:13 pjstadig: https://www.refheap.com/paste/7864

6:13 Anderkent: you have to have independent migrations for it to work.

6:13 Anderkent: I don't see the problem, yes you have to pay more attentnion when merging two branches that both did migrations, but you have to do it anyway with any migration framework...

6:14 what do you mean by independent migrations?

6:14 callen: pjstadig: what am I doing wrong?

6:14 pjstadig: callen: oh, you know what, we don't use the lein plugin at work, which is why we don't have this problem

6:14 callen: wat.

6:14 Anderkent: hah

6:15 callen: dfkohjosrjoighjogiorsethrdopjkgh AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGH

6:15 pjstadig: the dev classpath is separate from the plugin classpath so that's why you don't see the migratus task when you have migratus in the dev classpath

6:15 we have fixtures in our test suite that run the migrations for us

6:15 callen: I just want to run the migrations from the commandline.

6:15 that's all I want.

6:15 pjstadig: and we don't generally need to run our app apart from the tests

6:15 Anderkent: you can try just making an alias for lein run -m leiningen.migratus

6:15 pjstadig: callen: yeah your screwed by lein2

6:16 Anderkent: oh nvm that wouldn't work

6:16 pjstadig: i'll take this as a vote to work out the lein2 upgrade more post hastily

6:16 callen: pjstadig: that would be nice, but I'm kinda fucked until then.

6:16 pjstadig: callen: you can't use lein1?

6:16 Ralt: hi

6:17 pjstadig: there's really no reason to upgrade except peer pressure

6:17 Ralt: what's the difference between + and +' ?

6:17 callen: pjstadig: I'm not downgrading my leiningen for a migrations library.

6:17 pjstadig: suit yourself :)

6:17 callen: cemerick: migrations library: go.

6:17 Anderkent: you can make a trivial plugin that just adds the migratus libraries to a projects runtime and then eval-in-project's the leiningen.migratus/migratus call

6:18 callen: nope. fuck it, running the SQL myself with psql

6:18 pjstadig: callen: you could actually install a lein1 executable and run them concurrently

6:18 callen: pjstadig: fuck that, I'm done.

6:18 Anderkent: callen: see https://github.com/JacekLach/cloverage/blob/master/cloverage-lein-plugin/src/leiningen/cloverage.clj

6:18 callen: I have work to do.

6:18 Anderkent: it's 9 lines :P

6:18 callen: this has sucked off the last like 3 fucking hours

6:18 I'm done.

6:18 Anderkent: well, guess that's a solution as well

6:19 pjstadig: sorry it hasn't worked out for you

6:19 callen: pjstadig: so is my sanity.

6:20 pjstadig: it's too bad that the whole clojure community seems to think they need to move to lein2 before it's actually released

6:20 lein1 works perfectly well

6:20 callen: pjstadig: the project I'm working on is partly a proof of concept of me trying to demonstrate that Clojure can be a practical choice to some colleagues.

6:20 pjstadig: this isn't helping.

6:20 pjstadig: haha

6:21 Anderkent: so, coming back to running migrations independently, do you assume all migrations are idempotent and can be ran in any order?

6:21 callen: does anyone here have any opinions for managing scripts in a Clojure/Leiningen project?

6:21 Anderkent: or do you sillently take any migrations with n > x down if you notice x wasn't ran, and then redo them?

6:22 callen: I'd like to not just start adding a bunch .sh files to my project with some semblance of structure

6:22 Anderkent: both of these look like asking for trouble to me

6:22 Ralt: where can I get the list of attribute maps?

6:23 cemerick_: callen: what are you trying to do?

6:23 Ralt: I'm trying to understand the difference between + and +', and I see the only difference is in the attribute maps. Specifically, the inline attribute not being the same. But I can't find anything about this attribute...

6:23 pjstadig: Anderkent: no there is a table in the database that keeps track of each migration that has run, instead of just a single integer that represents all migrations that have run

6:23 Anderkent: pjstadig: so if you have migrations 1 2 and 4 ran, and you see migration 3 was not ran, what do you do?

6:24 pjstadig: cemerick_: i suck, so he wants you to write a migration library

6:24 Anderkent: run 3

6:24 cemerick_: pjstadig: what, for RDBMS?

6:25 Anderkent: pjstadig: I don't think that's correct though, running 3 then 4 and running 4 then 3 might have different results...

6:25 pjstadig: cemerick_: yes

6:25 callen: cemerick_: yes

6:25 cemerick: gtfo

6:25 pjstadig: Anderkent: then don't do that

6:25 cemerick: :-P

6:25 callen: cemerick: hatred for RDBMS? 4rlz?

6:25 cemerick: what should I use instead, MangoDB?

6:25 Anderkent: well that's my point, you always want to run migrations in a well defined order, so tracking which one was most recent is sufficient

6:25 cemerick: callen: no hatred, just no interest

6:26 pjstadig: Anderkent: if you want to merge git branches in unpredictable order, then you have to consider migrations independently

6:26 cemerick: I should have saved my gtfo for the mongo question.

6:26 Anderkent: if you add migrations in the 'middle', then you just have to roll back to state 0 and run all migrations

6:26 pjstadig: Anderkent: they always run in non-monotonically increasing order, but it only runs the migrations that are: on your branch, and haven't been run yet

6:27 Anderkent: obvlsy you don't want to ever push out something like that to production, but I suppose reordering migrations in dev is fine

6:27 pjstadig: regardless of what other migrations have run

6:28 cemerick: callen: I've enjoyed couch (Cloudant, actually). Nothing wrong with RDBMS (I've abused pg occasionally, and some things you just need to use oracle or teradata for), but they're often just a PITA.

6:28 migrations being one aspect, of course

6:28 bawr: pjstadig: uh, "increasing" is a subset of "monotonic"

6:28 callen: cemerick: I *hate* Couch

6:28 cemerick: sorry, I was being sarcastic earlier. I actually spend more time with NoSQL at work than I do RDBMS

6:29 bawr: pjstadig: I think you wanted "unevenly" or something

6:29 callen: cemerick: which is partly why I don't have an established choice in migrations.

6:29 I'm pretty close to saying fuggit and using MangoDB

6:29 particularly since psql is bitching about my .sql now.

6:31 zilti: Is clj-sandbox the only whitelist sandbox for clojure?

6:33 echo-area: Is it possible to write java files, that depends back on clojure, in leiningen?

6:34 I feel like I'm messing up leiningen, I make some clojure modules depend on java, and some java modules depend on clojure

6:37 callen: pjstadig: thanks for taking the time to investigate my issues with me

6:37 pjstadig: I really appreciate it.

6:40 pjstadig: callen: sure, sorry it wasn't a better experience, but like I said I'll prioritize upgrading to lein2

6:40 i've been avoiding it

6:41 callen: pjstadig: I'd love it so I can stop futzing around with my executing my SQL files manually :)

6:41 also, word to the wise, user is a reserved word in postgresql.

6:41 derp.

6:47 augustl: callen: if you're gonna say fuggit, you should consider datomic imo :) Been porting a mongo system to datomic over the weekend, works great

6:48 and yes, we're yet another item in the set of "chose mongodb because it's easy to get started with but it wasn't really a good choice for the system"

6:48 zilti: Is there some thing like full-text search in Datomic?

6:49 augustl: zilti: there is, it comes with lucene

6:49 zilti: I use elasticsearch though

6:51 callen: augustl: not on your life

6:51 zilti: augustl: I'm almost sold. Don't need those fancy http-search-stuff things though, so lucene'll just be fine

6:51 callen: I'm not letting somebody else hold me hsotage for my data.

6:51 augustl: callen: and fyi, we use the free version, seems to me that you only really need to pay when you need to scale a lot

6:51 callen: because you can't access the source code you mean?

6:51 callen: augustl: I don't care if it's free unless you're colored purple

6:51 augustl: I am not letting somebody else have control over my data

6:52 period, end of story.

6:52 zilti: The only thing I can't find are the docs of Datomic. That just gives me a page header "Development Resources" without content.

6:52 augustl: callen: and you're saying that because of source code access?

6:52 callen: augustl: I'm not really in the mood to discuss it.

6:52 augustl: zilti: http://docs.datomic.com/

6:52 callen: augustl: it's 100% out of the question though.

6:52 augustl: callen: heh, you shouldn't throw out bombshells then :)

6:52 you tickled my curiousity!

6:52 callen: augustl: It hardly takes a genius to see that Datomic's setup is no different from Oracle's

6:52 Raynes: Datomic smells like dirty sumo underwear to me too, callen. Don't feel bad.

6:52 zilti: augustl: Just checked it, the page is broken for Opera.

6:53 augustl: zilti: it took me a while to understand the basics though, the docs are kind of abstract

6:53 callen: CompilerException java.lang.RuntimeException: Unable to find static field: getenv in class java.lang.System, compiling:(garbwell/utils.clj:4)

6:53 https://www.refheap.com/paste/7866

6:53 augustl: zilti: hopefully this will help you: your schema defines attributes. In transactions, you create entities that gets IDs. You can associate any attribute with any entity (there's no tables/documents/etc)

6:53 callen: seriously? what am I doing wrong.

6:54 Raynes: speaking of refheap, I noticed it's back up. Did heroku come back up or did you flip it around?

6:54 augustl: callen: so is this still about source code? Not sure what you mean with setup.

6:54 zilti: augustl: So it's some kind of "semantic database"?

6:54 augustl: callen: (System/getenv key)

6:54 callen: augustl: business model, licensing, source access are all identical to Oracle

6:54 aw shit.

6:54 I see it now.

6:54 Raynes: callen: Heroku came back up at like 11AM yesterday or something.

6:54 augustl: or does System/getenv return a map when given no args? If so it should work

6:55 callen: augustl: it returns a map given no args

6:55 augustl: but your suggestion told me what I did wrong anyway.

6:55 Raynes: callen: I'm strongly considering moving it back to amalloy_'s and my linode.

6:55 augustl: callen: ah, (get (System/getenv) key) :)

6:55 callen: augustl: da.

6:55 augustl: zilti: not sure what that means :)

6:56 Raynes: I pay $20 a month for something I can get for free with better uptime on Heroku, and I think my original reasons for moving to Heroku were silly anyways. I'll probably set up some sort of git-based deployment though, because I've grown attached to that part.

6:56 zilti: augustl: I probably don't, either :)

6:56 Raynes: on linode*

6:56 augustl: zilti: the other stuff is pretty clear in talks, that queries are on the client, transactor only does writes, etc. But the part I Just explained wasn't that evident to me at least

6:56 callen: Raynes: I've done a lot of automation of deployment at my day job, let me know if you want any pointers.

6:57 Raynes: pity you weren't here earlier. I was bashing my head against the wall for a solid 3-4 hours. It's 0348 here and I've been awake since yesterday

6:57 Raynes: callen: Will do, and I appreciate the offer.

6:57 It's 5:48AM here and I've been awake since yesterday.

6:57 You and I are like two peas in a stay-awake pill commerical.

6:57 commercial*

6:57 zilti: augustl: I'll definitely will check it out for my next project, but for my current one it's too late (I don't like changing things so deep down in a project, it might screw up everything)

6:58 callen: Raynes: heroku, MongoHQ, Datomic, they all tickle my spidey sense for various reasons. I don't really like being directly dependent on third party entities like that. Amusingly, technomancy had the same problem with grove.io admittedly of a less serious sort.

6:58 augustl: zilti: we're 6 months in and changed from mongo to datomic over a weekend, pretty happy with the modularity we achieved

6:59 callen: I'm not sure why I don't mind datomic being closed source.. Guess I'm too much of a fanboy or something, normally I resent proprietary stuff in my systems.

6:59 Raynes: callen: I moved to Heroku because a bunch of pastebins shut down one after the other over DDOS attacks and I don't have any experience handling anything like that. AFAICT, 'handling' a ddos attack appears to mostly mean just shutting it off until it is over and crying.

6:59 callen: augustl: if you normally resent proprietary stuff and you're okay with Datomic, then you're being irrational and fanboyism is a plausible explanation.

7:00 Raynes: there are ways to mitigate DDOS, but if you're a small operation, it's rough.

7:01 zilti: Too bad fleet db is dead. I really liked the way it works.

7:01 callen: augustl: I cannot in good conscience allow anything I make, side project or in my day job, be unduly controlled by a third party entity like that.

7:02 it's bad enough I'm subject to the whims of technomancy via lein ;)

7:02 augustl: callen: datomic hasn't caused any problems for me yet though, unlike proprietary blobs on Linux desktop setups that breaks when I update the kernel etc.

7:02 callen: You're really missing the point.

7:02 augustl: listen, I used to be a Microsoft .NET developer for a living.

7:03 augustl: I've heard every excuse on the planet for explaining away how it doesn't matter if it's not proprietary.

7:03 augustl: it matters and I'm not allowing it anything I build.

7:03 if it's proprietary*

7:03 Raynes: Deep breaths

7:03 * Raynes breathes in

7:03 * Raynes breathes out

7:04 callen: Raynes: how was your Christmas anyway?

7:04 Raynes: Well, there was a tornado outbreak so I monitored meteorological data all day, but we escaped danger.

7:05 I wrote https://github.com/Raynes/cegdown and did some laser stuff.

7:05 callen: does anyone here know how to override/shutoff that obnoxious log4j shit in Korma?

7:05 Raynes: Ate leftovers from Christmas eve.

7:05 Played Far Cry 2 and Snapshot.

7:05 It was a good day.

7:05 callen: Raynes: ah, you like indie games too?

7:05 Raynes: HIB?

7:06 Raynes: All the time

7:06 Anderkent: callen: log4j is usually controlled from a config file like src/log4j.xml

7:07 Raynes: Or resources/log4j.xml if you don't hate yourself.

7:07 Anderkent: yeah ment that but forgot the canonical place :)

7:08 the readme for korma says to set logger "com.mchange" to WARN

7:09 callen: I know, I just resent being forced to use log4j.

7:13 Raynes: I wish somebody would take over Korma.

7:13 It's sad that so many people use it yet are unwilling to manage it.

7:14 callen: I couldn't get log4j to stop breaking

7:14 I'm getting a little frustrated.

7:14 No appenders could be found for logger <--- despite having made that example xml

7:15 guess I now need to learn how to configure log4j

7:15 which I don't even want to use

7:15 but am forced to because of korma.

7:18 Raynes: do you have a project that uses log4j that i can reference?

7:18 Raynes: Not sure if I have any open source ones. Might be one. Let me check

7:19 callen: I hate editing XMl.

7:19 Anderkent: well, i think it's c3p0 actually, not korma. And unfortunately it seems it uses log4j directly, not slf4j, so yeah you've got no choice

7:19 you can configure log4j with properties instead of xml if you prefer

7:19 callen: that doesn't change much for me.

7:19 it's still awful java shit leaking into my clojure

7:20 Raynes: callen: https://github.com/geni/geni-gedcom with the caveat that I do not remember if I ever got logging to actually work (I had to consult with a co-worker, but it was a while ago).

7:20 I think I did.

7:20 borkdude: Raynes read the README of laser, it looks nice

7:21 dbushenko: hi all

7:21 can you please point me any presentations showing best of the clojure? some clojure propaganda

7:21 callen: got it working now.

7:21 Raynes: borkdude: It does lots more than what is in the README. I've just been working on it so fast that I haven't kept the README up to date. I'm changing things as I discover problems/things that need to be added while I rewrite refheap's views to use it.

7:22 callen: Did my stuff help?

7:22 I bet just my talking about it helped.

7:22 I have that effect on you.

7:23 callen: Raynes: I googled the appender syntax for XML, put it in resources/ as you suggested, eventually got it working after futzing around

7:23 my database layer seems to be working now for pathological definitions of working

7:24 I might go grab my vodka and have myself a good cry now, having spent 5+ hours just getting migrations and database access working

7:24 Raynes: callen: I've got some hard lemonade if you need.

7:26 callen: Raynes: 'ppreciate the offer. I'll just dump out my tea and coffee, switch to vodka, and call it a night. At least I'm close to implementing actual stuff now.

7:26 things were a lot easier when it was all lein1, Noir, and Mongo. I'll say that much.

7:26 Raynes: callen: Have a nice ... whatever time it is now.

7:26 callen: moving to lein2, postgres/korma, ring/compojure all in one shot was not a great idea.

7:27 Raynes: I've made that mistake before.

7:27 callen: Raynes: 0418, cheers.

7:27 Raynes: I do one thing at a time now.

7:27 Cheers.

7:27 callen: Raynes: yeah, lesson learned.

7:27 I should really know better, too.

7:33 dbushenko: is it possible to aot-compile records?

7:33 jml: I'm working on a clojure project w/ a lein project.clj and nrepl-jack-in in my emacs. How do I do the equiv of 'lein run' from emacs?

7:33 callen: jml: M-x shell?

7:36 Raynes: callen, jml: M-& RET lein run

7:38 jml: thanks.

7:39 abaranosky: Raynes: what's the issue I hear about Korma not having a maintainer?

7:40 Raynes: If needed I could consider maintaining it

7:41 its pretty nice software, that I've been using happily.

8:18 jml: with incanter, how do you tell it that one of the columns of a dataset is a categorical variable? I've found categorical-var, but don't know how to actually use it to do what I want.

8:28 deg: Using nrepl in emacs, what's the best way to switch between multiple leiningen projects?

8:56 pjstadig: callen: if you would be willing to give it a try, i think i may have something that works with lein2

8:56 callen: set up your project.clj something like this https://github.com/pjstadig/migratus-lein/blob/master/test-project/project.clj

9:06 ferd: pjstadig: Thanks... migratus looks interesting. Could you give us a quick comparisson with other options? like ragtime ?

9:06 https://github.com/weavejester/ragtime/

9:11 zilti: add-watch is described as "alpha - subject to change". How high is the possibility that it gets severly altered or removed? Is it still there in 1.5?

9:12 pjstadig: ferd: ragtime it a bit more complicated IMO, with conflict resolution strategies, and originally didn't use straight sql

9:13 ferd: it also does not wrap a transaction around the entire transaction, which doesn't matter for mysql, but for databases with transactional DDL it does

9:14 drift is nice, but it doesn't work with our git workflow where topic branches can be merged in different order that they were created

9:14 drift also has a DSL, and I prefer to just use SQL, since it's already a DSL, and generally applications don't need data base independence (if that is even possible)

9:15 libraries might, but applications usually don't

9:16 also, if you're doing migrations in a library... God help you

9:17 Anderkent: well, it's nice not to have to install postgres on every dev machine, seeing how much pain setting it up is

9:19 pjstadig: i've always found postgres very easy to setup if you use ident-based authentication

9:19 Anderkent: I still don't get the git issue, seems like you need to modify your migrations on merge anyway if you had both branches create some

9:19 since you have to choose the canonical order to run them and handle any conflicts ..

9:20 pjstadig: you don't need to modify migrations

9:20 if i create a branch and add a create table migration, why should i have to rename the file on a merge

9:20 and what about people that may have already run it with the old name

9:20 Anderkent: well you still need to inspect for conflicts

9:21 pjstadig: if you have dependencies between your migrations, then you start your branch on a commit that contains the migrations you need to depend on

9:21 otherwise they have no business caring about each other

9:21 Anderkent: rails used to use a single global version for dbs like you are saying, but after they switched from svn to git they realized that that doesn't work so well with git workflows

9:21 and they changed to the way migratus does it

9:24 Anderkent: I always had a lot of issues with merging in migrations because of that, as they would run in wrong order instead of just scrapping the db and running everything in the right order

9:24 f.e. say you have two parallel branches and both add a column to a table

9:24 if you run them in different orders the order of columns will be different, which may matter

9:24 even though the migrations do not really depend on each other

9:32 ferd: thanks pjstadig. I've run into the problem of merging from multiple branches... but as Anderkent points out, you still must pay close attention not to incur in "semantic" conflicts

9:33 pjstadig: Anderkent: yeah, i mean if other migration libraries work for you, that's cool, they weren't working for me

9:34 ferd: regarding the use of an internal DSL or plain SQL, I also prefer plain SQL. However, it'd be great if you could run arbitrary Clojure code as part of the migration steps... I found that need more than once

9:34 Anderkent: mhm, I kinda am thinking I'd like one that explicitly checks if all migrations < current state were ran and *fails* when they weren't

9:34 ferd: drift on its own just runs your clojure code, you can use a dsl (drift-db) with it, but you can just directly send SQL to whatever db you want

9:39 ferd: looks like ragtime follows a similar approach

10:05 zilti: I have that very strange stacktrace here from running lein midje. It does not tell me what line of code in my program threw that exception nor could I find that out by uncommenting pretty much everything in my program: https://www.refheap.com/paste/7867

10:06 Exception in thread "main" java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword

10:08 ferd: may be your namespace definition ?

10:08 zilti: ^^^

10:11 zilti: ferd: Thanks! I forgot a pair of braces...

10:11 gfredericks: &(doc take-while)

10:11 lazybot: ⇒ ------------------------- clojure.core/take-while ([pred coll]) Returns a lazy sequence of successive items from coll while (pred item) returns true. pred must be free of side-effects. nil

10:11 gfredericks: ^ "returns true" is misleading

10:12 I guess once you're assuming it's a predicate...

10:13 ferd: zilti: I don't know why, but error checks on the (ns ...) macro is pretty weak (non-existent actually)

10:13 Anderkent: what else did you have in mind?

10:16 zilti: ferd: pff, why should there? I mean, who would make mistakes at such a simple thing as namespace declaration?

10:39 &(apply #(%) [{}])

10:39 lazybot: clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentArrayMap

10:40 gfredericks: &({})

10:40 lazybot: clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentArrayMap

10:41 zilti: &(apply #(identity %) [{}])

10:41 lazybot: ⇒ {}

11:08 deg: Using emacs with nrepl, I just typed something in a .clj buffer that caused emacs to switch to a *nrepl-error* buffer and forcibly go back there each time I tried returning to the source file. Acts like something was erring at read-time or some such. But, I didn't type anything that unusual. Anyone ever see this before? Where do I report it (assuming I can reproduce it)?

11:09 chouser: I guess you'd report that to the nrepl.el author

11:10 Looks like he uses github issues: https://github.com/kingtim/nrepl.el/issues

11:11 deg: chouser: thanks. Trying to reproduce the problem now. So far, no luck. (after restarting emacs)

11:13 chouser: I much prefer nrepl.el with nrepl-popup-stacktraces off

11:15 deg: chouser: Hmm, I've never heard of nrepl-popup-stacktraces. From the name, sounds like it might be very nice. thx.

11:18 chouser: Ah, I see. looks nice.

11:19 chouser: *e still gets you the exception, and (pst) prints in the repl window

11:20 deg: Also, do you know how I can switch between multiple projects? (I don't really need both active concurrently, thought that would be nice too. My workflow is to spend a few hours on one project,then shift gears. And, I'd rather not have to restart emacs in between)

11:22 chouser: I think you can close the nrepl buffers and jack in again

11:24 deg: ok

11:40 In nrepl, is *1 not bound to the last value returned?

11:41 tpope: it is

12:02 deg: tpope: Hmm, then something is faking me out or misconfigured.

12:04 in a cmdline lein repl, if I do (+ 3 4), then *1 is bound to 7. In the emacs *nrepl* buffer, it is bound to ().

12:10 dimovich: hello ppl

12:10 could someone drop me some code using edn?

12:22 technomancy: callen: did you see the clojars migration code?

12:23 callen: a lein plugin to run migrations is silly IMO; it should just be an alias to lein run -m ...

12:23 run is how you expose in-project code on the command line

12:25 deg: what version of nrepl.el? works for me on 1.5

12:40 deg: technomancy: 1.6-preview

12:43 technomancy: must be a regression

12:46 yedi: do you guys end up using SQL or noSQL more often?

12:47 gtrak: yedi: http://news.ycombinator.com/item?id=2416566

12:52 zilti: yedi: I always use SQL because I'm too lazy to start with one of those NoSQL DBs.

12:53 konr_trab: What's the best way to implement in clojure a timer thing that calls a function every N seconds?

12:54 technomancy: konr_trab: executors!

12:55 zilti: ,(loop [counter] (do (Thread/sleep 5000) (if-not (< counter 10) nil (recur (inc counter)))))

12:55 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: loop requires an even number of forms in binding vector in sandbox:>

12:56 zilti: ,(loop [counter 0] (do (Thread/sleep 5000) (if-not (< counter 10) nil

12:56 (recur (inc counter))))) ;; Always wanted to try this on here followed by...

12:56 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

12:56 gfredericks: does `lein test` do something weird when looking up code? My test helper namespace is getting eval'd twice

12:56 zilti: whatever

12:58 technomancy: gfredericks: it does require :reload

12:58 in order to support interactive things

12:58 gfredericks: I see.

12:58 hokay.

12:59 zilti: ,(loop [counter 0] (if (< counter 10) (do (Thread/sleep 5000) (println "still didn't timeout") (recur (inc counter))) nil))

12:59 clojurebot: Execution Timed Out

12:59 zilti: &(loop [counter 0] (if (< counter 10) (do (Thread/sleep 5000) (println "still didn't timeout") (recur (inc counter))) nil))

13:00 lazybot: Execution Timed Out!

13:00 gfredericks: zilti: the bots accept PMs as well

13:00 zilti: gfredericks: Sorry for spamming the channel, forgot about that...

13:01 * gfredericks uses his social skills to make some sort of magical facial expression communicating that nobody is upset

13:02 * zilti hides somewhere

13:33 Anderkent: technomancy: can i somehow stop leins test from calling System/exit when running them with clojure.test/run-tests? I wanted to try my code coverage tool on it, but it dies on some compilation tests.

13:34 technomancy: Anderkent: you should be able to bind leiningen.core.main/*exit-process?* to false

13:36 Anderkent: mhm, hoped for something that I could do without lein-specific code, guess I'll have to work with that

13:36 technomancy: Anderkent: oh, lein will never call System/exit just from run-tests

13:37 Anderkent: it does on its own tests (one of the compilation tests has compilation fail, which then triggers death)

13:37 either that or i'm doing something wrong :)

13:37 technomancy: oh, for its own tests; I see

13:38 yeah, you would have to rebind that var if you want to keep its own tests going after a failure

13:40 deg: Is there some way to compare two regex's to see if they are the same. (I need this for tests, not production code, so no comments about why this is stupid or generally not a well-formed question)

13:40 ,[(= "A." "A." ) (= #"A." #"A." )]

13:40 clojurebot: [true false]

13:41 technomancy: deg: I think you have to str them first

13:41 or prn maybe

13:41 deg: technomancy: str does the trick, thank. I hadn't realized it worked on regexes.

13:41 technomancy: str works on anything =)

13:42 deg: Tries str on his pet dog. .... nope, not everything. :-)

13:43 technomancy: wait till 1.5 is out; I think they added reader literals for mammals

13:43 Anderkent: you just need to thread it through the interpreter

13:43 technomancy: only slightly less useful than reader literals for UUIDs

13:44 zilti: Anderkent: I see problems with the animal protection

13:44 deg: Good thing it's not an OO language. I'd hate to see the standard newbie OO code of dogs barking written with reader macros.

13:45 Anderkent: zilti: you can work around that with reflection

13:46 zilti: deg: Nothing prevents you from implementing an object system for Clojure ;) Except your sanity.

13:46 deg: oh god

13:46 p_l: ... isn't there an object system already?

13:46 Anderkent: okay, different question. Can I somehow give file/line numbers for evalled statements?

13:46 p_l: in fact, isn't Clojure full of object, in the "old" style?

13:46 (before OOP became synonymous with inheritance, an orthogonal concept)

13:47 zilti: p_l: It is, but you'll have to use all those java-interop-things and a weird notation.

13:47 I would not want to use it as it is now

13:47 p_l: zilti: I'm not talking about the java interop stuff :)

13:47 Java's stilted, limited OOP is not everything :)

13:48 zilti: p_l: You mean those protocol & friends macros?

13:49 p_l: yes. As well as multimethods etc.

13:49 zilti: For me that feels like interop stuff

13:49 p_l: just because some were taught that OOP means inheritance and "methods in classes" doesn't mean it's 100% true :)

13:50 technomancy: clojure doesn't implement message-passing OO either though

13:50 p_l: technomancy: It does implement enough of "generic function" variant of OOP for me

13:51 technomancy: erlang is a lot closer to the original definition

13:52 p_l: technomancy: yes, though they don't like to hear that :)

13:54 Anderkent: i take the silence to mean there's no way to tell clojure which file/line to put in stacktrace when evalling forms?

13:54 (well, not silence exactly :P)

13:54 technomancy: Anderkent: have you tried attaching metadata to the form?

13:55 I'm not sure exactly how, but I think that's where trace data is read from

13:56 Anderkent: hm. Now that I think about it I tried setting lines, but not the file name, should try it i guess

13:56 hard to debug stack traces where every other line says 'leiningen.core.project/fn (NO_SOURCE_FILE:1)' :P

13:57 egghead: can I use the standard -Darg=whatever on lein invocation?

13:57 like `lein run -Dhttp.port=1234` or something?

13:59 yogthos: Anderkent: you can also just restart the REPL it'll actually tell you what file/line it's dying in that way

13:59 or is this something more sinister than that?

14:00 Anderkent: yogthos: alas it's not in the repl - I'm instrumenting source code and evaling the produced forms instead of original source

14:00 yogthos: ahh

14:01 technomancy: egghead: you can set :jvm-opts in project.clj

14:02 egghead: thanks technomancy

14:02 technomancy: hashmap of keys/vals ?

14:03 technomancy: egghead: vector of strings

14:03 egghead: kk, thanks

14:10 Anderkent: ah-ha, `def` can have a docstring as well... How does it differentiate between a (def mystring "stringvalue") and (def my-unitialized-value "docstring") ? I suppose the latter is not possible?

14:14 btw, how do you guys format (cond) statements? https://www.refheap.com/paste/7871 is fairly readable but shifts the code so far right you have to split even a simple statement over 3-4 lines

14:15 technomancy: there is no good way to format cond =(

14:16 Anderkent: that paste actually looks like a good fit for pattern matching

14:17 Anderkent: remind me how do I do that in clojure?

14:17 technomancy: Anderkent: you have to pull in core.match: https://github.com/clojure/core.match

14:18 Anderkent: thanks, will look into it someday

14:22 dnolen: Anderkent: these days I usually format large cond's like this http://www.refheap.com/paste/7872

14:24 * gfredericks does that too

14:24 * technomancy too, but he doesn't like it

14:24 Anderkent: yeah I don't like it either but don't see a better way :P

14:27 chouser: we need to teach clojure-mode about forms with pairs that should be indented extra for the second item of each pair

14:27 * technomancy isn't touching clojure-mode's indentation logic

14:27 chouser: bindings (let, fn, etc.), cond

14:27 technomancy: it's like three pages long, state threaded throughout, no comments

14:28 as a single defun =(

14:28 chouser: heh, yeah, I've looked at it. haven't touched it.

14:28 technomancy: I don't want to change the logic for let/fn though

14:28 chouser: I wanted to do the new syntax threading macros too, but those are extra tricky

14:29 Anderkent: hm. Can removing type hints break java interop code?

14:29 technomancy: mostly cond just sits there taunting me for not switching to core.match

14:30 I'm OK with that

14:32 chouser: Anderkent: I think it's possible.

14:32 technomancy: oh, clojure's indent is actually commented; nice. I was thinking of ruby-mode as the pit of nameless horrors.

14:34 pjstadig: Anderkent: depends on what you mean by break

14:35 koik: http://www.carolinaherrera.com/212/es/areyouonthelist?share=NVq56AQ2vxgECOtvW_3-cC_MeqWSEVkU2vlXs7SL5zHkz4rz3EUUdzs6j6FXsjB4447F-isvxjqkXd4Qey2GHw#teaser

14:35 deg: Just wondering ... why did Clojure choose top-level pairs for forms like cond and let, rather than copying the Common Lisp idea of an extra level of parens?

14:36 technomancy: deg: Clojure reserves parens for calls with a few exceptions. it leads to much more regularity

14:37 Anderkent: pjstadig: code that used to work throws exceptions (i think a different java method is called, they dispatch on type, but the error message is rather terrible)

14:37 ppppaul: i would like to use double quotes in my doc strings

14:37 any suggestions?

14:37 Anderkent: i suppose it's much more likely my macroexpansion is broken somewhere

14:37 technomancy: Anderkent: certainly possible. the main condition that would trigger that would be nil arguments. there might be others.

14:38 ppppaul: paredit will automatically escape them for you

14:38 deg: technomancy: Yup, that makes sense. But, why not [] braces for each cond term and each pair of let bindings?

14:38 Anderkent: technomancy: can you expand on the nil arguments bit?

14:38 ppppaul: but when they are escaped i can't evaluate my doc code

14:39 technomancy: deg: because that further dilutes the meaning of braces

14:39 deg: technomancy: Is there a doc anywhere that disusses the historical decisions that shaped clojure?

14:39 Anderkent: ppppaul: read-string on the doc string then eval that?

14:39 chouser: deg: you're reading it

14:39 ppppaul: ok

14:39 technomancy: Anderkent: for non-nil arguments, reflection can be used to find the "proper" method call at runtime. but that doesn't work when the arg is nil; it has to guess or something. bit fuzzy on the details.

14:39 chouser: deg: historical notes at http://clojure-log.n01se.net/ :-)

14:40 deg: chouser: Sigh. Besides the intense length of years of chat, is it even archived anywhere?

14:40 Anderkent: that makes sense, thanks

14:40 ppppaul: read-string isn't doing anything different

14:40 chouser: deg: so in short, no not really.

14:40 ppppaul: i get errors when trying to eval the \"

14:40 chouser: deg: the archive exists but yes, it's a lot of text.

14:41 deg: technomancy: But [] is already used for the outer grouping around let bindings.

14:41 technomancy: deg: exactly

14:42 deg: technomancy: ?? Are you saying "that was already a bad decision, so why compound it", or "it would be too confusing to overload '[' to mean both levels of bracketing"?

14:42 Anderkent: (let [[[[a b] & others] source]]

14:42 no thanks.

14:43 technomancy: deg: it would be overloaded and probably introduce ambiguity when it comes to destructuring

14:43 also, it wouldn't improve readability

14:43 deg: Yup, I forgot about destructiong. Definitely a big win of Clojure over CL.

14:43 technomancy: plus you can always drop commas in if you need more visual separation

14:44 deg: But, the nice thing about parens in CL was how well it interplayed with emacs indentation.

14:44 pjstadig: Anderkent: when clojure compiles code it can only dispatch on arity, so if you have a Java class with more than one overload for a single method, and each overload has the same number of arguments, but different types, then type hints are necessary and removing them can break code

14:44 but the exception you'd get would be like method not found or something

14:44 if you're experiencing some other kind of problem, then it is probably not type hint related

14:44 technomancy: pjstadig: that doesn't take into account runtime reflection though

14:45 deg: technomancy: Do folks really use commas much? I had assumed they were mostly just thrown in as a nicety for java programmers used to them.

14:45 ppppaul: i use commas everywhere

14:45 technomancy: deg: you see them sometimes when keeping multiple let bindings on a single line

14:45 deg: But, getting back to the original question, I wonder if commas could enhance readability in a cond form too?

14:45 technomancy: I usually use line breaks instead

14:45 zilti: I never use them. It clutters the code

14:46 commas

14:46 ppppaul: (->> foo-array (map identity ,,,))

14:46 technomancy: deg: IMO newlines are better in cond, but sometimes when the test clause is long it's not feasible

14:47 deg: but even then you'd put the commas at the end of the value, which is not that helpful because the ambiguity is present at the beginning of the line

14:48 deg: Agreed. I'm not a fan of commas. I am a strong fan of proper indentation, and I want my editor to do the work for me. So, I guess the only answer that would make me happy is smarter indenting by Emacs.

14:48 Anderkent: when adding a debug log statement fixes the bug, you know you're screwed :S

14:48 technomancy: deg: or stop using cond =)

14:49 deg: technomancy: commas at the beginning of the line would look a bit weird (especially to anyone coming from a CL macro world!), but would actually force the indentation to be more readable. I can't believe I'm suggesting this, though.

14:49 pjstadig: technomancy: even with non nil arguments there are type based overloads that are ambiguous at runtime

14:49 technomancy: pjstadig: true; nil is just the most common case

14:50 deg: yeah, it might improve readability at the expense of offending taste =)

14:51 deg: You just need to bring some old teco programmers into the community. They'd love it.

14:52 technomancy: heh

15:07 dsop_: hmm where did datalog.utils go?

15:07 from old contrib

15:07 in particular the map-values fn

15:13 yedi: can someone link to an article that presents reasons for using clojure in the browser

15:14 lucian: jedi: there are quite a few. the main reason anyone would use something other than js in a browser is to avoid js

15:19 kovas: yedi: if u are using clojure on the backend, it makes for a sweet combination. can just pass clojure data structures. also just need to keep 1 language paradigm in your head.

15:20 yedi: clojurescript without clojure on back end has advantages, buts its a harder sell imho

15:22 lucian: kovas: it's not js, that's enough for me. it's just a pain to work with because it depends on the slow-ass jvm

15:23 if clojurescript was self-hosting, it'd be a much easier sell

15:23 yedi: lucian: thats what it seems like, but i like JS which makes me a bit hesitant to switch

15:23 kovas: lucian: I agree totally :)

15:23 lucian: yedi: JS is quite flawed, so pretty much anything beats it

15:23 kovas: lucian: still i think cljs is harder to get into for a clojure newbiew

15:24 (if you aren't already sold on clojure)

15:24 2013: the year of cljs self hosting

15:24 they are getting closer

15:25 bbloom: s/they/we/ you can help too :-)

15:25 kovas: trust me ill be an early adopter

15:25 need that shit for session

15:26 but i don't understand the core language stuff well enough

15:26 "vars and their discontents"

15:26 bbloom: kovas: i learned clojure by studying the cljs compiler. it's actually quite approachable. dig in, you might have fun!

15:26 tpope: sounds terrifying

15:27 kovas: bbloom: i will get there!

15:27 "twilight of the namespaces"

15:28 jonasen: kovas: Any reason you track changes to cljs generated js files? It's hard to read the diffs ( https://github.com/kovasb/session/commit/3cc368ba42ead84894861a6c8f8a426fe69f22a6 )

15:29 kovas: jonasen: the idea was so people could run session without first running cljsbuild

15:29 jonasen: but maybe that is a misguided idea

15:29 Anderkent: AH! it was indeed the nil issue technomancy, shame on me for doubting you. Now I need to make my instrumentation preserve type hints...

15:29 kovas: jonasen: what do you think?

15:30 jonasen: kovas: I don't think "lein cljsbuild once" is particularly difficult to type :)

15:30 kovas: jonasen: yeah, I guess I just wanted to minimize the chances of something going wrong.

15:30 jonasen: but at this point, better to optimize for dev happiness

15:31 jonasen: should I just put the output directory into .gitignore and then git rm those files?

15:32 jonasen: kovas: that should work. And update the README

15:32 kovas: ok i am on it

15:43 jonasen: ok, purged the files. in general the clojure files come last in the diffs

15:48 Anderkent: anyone know how type hints work? :P

15:50 bbloom: ~anyone

15:50 eh, our bots are slow.... Anderkent: *somebody* must know. so just ask your question & maybe somebody will answer it :-)

15:52 Anderkent: that was pretty much my question ^^ I'm looking for how they're parsed from the form and how to preserve them when doing modifications on source, but even a pointer to the related compiler code would help

15:53 bbloom: Anderkent: the keyword to grep for is :tag

15:54 Anderkent: I'm also rather confused by how the FN special seems to have no parser assigned in Compiler.java ..

15:54 chouser: ,(read-string "^Foo bar")

15:54 clojurebot: bar

15:54 chouser: ,(meta (read-string "^Foo bar"))

15:54 clojurebot: {:tag Foo}

15:54 chouser: ,(type (:tag (meta (read-string "^Foo bar"))))

15:54 clojurebot: clojure.lang.Symbol

15:55 Anderkent: how do I extract one for function args?

15:55 (function return is easier, just (meta #'function-symbol)

15:56 chouser: ok, it's time to talk about compiler phases. :-)

15:56 bbloom: chouser: hurray! i want them in cljs :-)

15:57 chouser: cljs has them

15:57 bbloom: analyze vs emit doesn't count

15:57 chouser: if anything it has more, or at least better defined, phases

15:57 it does count! It's what Anderkent needs to know, I think.

15:57 bbloom: what phases are you talking about?

15:58 bbloom: dur, i read "phases" as "passes"

15:58 i'd like to see analyze broken up into parse, expand, hinting, etc

15:58 there's lots of stuff all mixed together in analyze right now

15:59 Anderkent: ah! so the :arglist keyword in a functions meta has its arguments, and these are tagged with types

15:59 bbloom: codeq, for example, wants to be able to search over the unexpanded source code, which isn't possible currently b/c analyze expands

15:59 plenty of other use cases too

16:00 Anderkent: to answer your question about the FN special, grep "FnExpr.parse", it's in analyzeSeq

16:00 Anderkent: thanks

16:00 I think I might be able to avoid that

16:00 bbloom: avoid what where?

16:00 Anderkent: if I just make sure to keep all the meta in the right places...

16:00 avoid looking into that

16:01 bbloom: won't hurt you to look (as long as you don't show hidden whitespace... *cringe*)

16:02 Anderkent: well kinda want to get stuff done so looking into compiler internals is not the preferred course of action

16:10 gtrak: is there a way to create a top-level lexical binding for all compojure routes in a defroutes statement without resorting to a var? I'm afraid this is one of these 'macros don't compose' cases

16:12 I might make a macro that wraps them all and makes the binding available

16:13 jlewis: is there a canonical union find implementation for clojure?

16:13 and if not, is the community interested in non-persistent data structures living in clojure contrib?

16:13 bbloom: jlewis: "union find"? do you mean set itersection?

16:14 jlewis: union find keeps track of elements that live in a bunch of disjoint sets

16:15 amalloy: jlewis: i have a closed-source implementation of union-find somewhere. let me see how much of it is salvageable

16:16 jlewis: i wrote one too, having not been able to find a nice one on the internets... but it's all ref-y, i'm not sure if people like non-persistent data structures here in clojure land :P

16:17 amalloy: jlewis: no, and i think it's a good exercise doing this without refs. mostly you end up passing/returning the forest around to a bunch of functions, instead of mutating it globally

16:17 mine doesn't have any mutation, but i'm afraid there's rather a lot of business logic mixed in, since we couldn't afford the space or time to be more general

16:18 jlewis: amalloy: i think you end up killing the nice time bounds if you make it persistent with path copying, though :/

16:18 amalloy: naw

16:19 the paths are extremely shallow in unino-find, and even if they weren't log32(n) is near enough to constant

16:19 eg, we ran this on a dataset of, i dunno, a few hundred million items, and were easily outpacing the speed with which we could get nodes from the database

16:21 have you read the wikipedia page on union-find? i was floored by a couple sentences in there about the complexity guarantees

16:21 bbloom: hm, i've done things like this before, had no idea it was called this... thanks i learned something :-)

16:21 jlewis: i don't think it helps that much that the paths are shallow, unless you're imagining doing it in a different way than me

16:21 imagine you have 5 elements pointing at the root r

16:21 and you're looking up the the 3rd element, or something

16:22 if you do the path compression optimization, then i think you end up having to do a search to fix up the first couple of elements if its not mutable, right?

16:22 because you're going to create a brand new node for the middle elements, up to the root

16:22 but then the nodes at the bottom will still be pointing at the old elements..

16:22 well that was as clear as mud, do you know what i mean though?

16:26 amalloy: jlewis: like i said, you need to pass and return the forest to more functions than if you were mutating. for example, the find operation can't just return a node, it has to return a new path-compressed forest, like https://gist.github.com/2df01576cd9843d34b10

16:32 jlewis: amalloy: i sent you a comment on that gist

16:35 gtrak: is there such a thing as macro-level apply?

16:36 I want to make a macro that wraps a bunch of forms and returns a bunch of forms, but not as a seq

16:36 amalloy: no there isn't

16:36 chouser: A macro can return a list starting with 'do

16:36 S11001001: gtrak: no, macros aren't fun

16:37 gtrak: damn

16:37 specifically, I want to wrap each handler in defroutes

16:37 amalloy: gtrak: then chouser's advice is relevant

16:37 gtrak: hmm

16:38 chouser: I don't know compojure well enough to say, but if there's functionality that accessible only via macro, this is exactly the kind of pain you end up in.

16:38 gtrak: yea, that's the case

16:38 amalloy: chouser: there isn't any; compojure is pretty good about that

16:38 gtrak: ah, then I am unwise

16:38 amalloy: weavejester says he regrets adding defroutes, because it makes people think routes doesn't exist

16:39 chouser: interesting

16:39 gtrak: :-)

16:39 jkkramer: GET and friends are macros

16:39 however, you can probably still do what you want with functions

16:39 gtrak: I can wrap an individual GET easily enough

16:39 I have to use a macro for the sake of symbol-capture

16:39 amalloy: that's fair, jkkramer. i bet they delegate to a function pretty fast, though

16:39 jkkramer: gtrak: are you sure? can you explain the scenario?

16:40 amalloy: yeah, and it's a sensible choice, I think - it allows easy request/param destructuring

16:40 gtrak: jkkramer: we (not I) don't want to use a var, but are ending up with a lot of destructuring boilerplate in every handler, so I'm going to bind a symbol to a get-in call and wrap the handler definition

16:41 amalloy: i guess GET uses compile-route, which does an awful lot of macro magic. i guess the good news is you never seem to need GET as a function

16:41 gtrak: my first choice would be to use a middleware and a var... but hopefully this workaround is enough to make my colleagues reconsider :-)

16:44 jkkramer: gtrak: middleware sounds like a good option but it's hard to say without seeing specifics

16:45 gtrak: jkkramer: yea, I hate when implementation is specified from above, but I can work around constraints, especially in a lisp :-)

16:46 it's easy enough to write something that acts like a var without being a var

16:47 jkkramer: it's considered bad practice by some, but I often end up having handlers take a full request maps or params instead of doing elaborate destructuring in the routes

16:47 I like thin routes

16:47 gtrak: jkkramer: yea, I do that sometimes

16:47 in particular when I want to decomplect body-params from params

16:50 I agree in general with thin routes, but sometimes it gets so hairy that pulling things out into functions makes it worse

16:51 I blame it on the increased likelihood of control-flow in routes over normal clojure

16:52 nil-punning and things are harder to deal with when they're more spread out

16:54 rbxbx: are there any OSS apps that demonstrate proper route/route-handling decomposition? The only larger app I've been able to reference has been 4clojure /c gtrak

16:54 gtrak: proper.... don't know the answer to that

16:55 the nice thing about clojure is how easy it is to avoid patterns...

16:55 rbxbx: Proper was perhaps a poor choice of words

16:55 maybe... "generally agreeable" :)

16:56 Hodapp: gtrak: avoid patterns?

16:56 gtrak: I haven't looked at anything like that myself :-).. though our routes layer is about 1k right now

16:56 1k lines

16:56 amalloy: hah. glad to hear 4clojure's counts as proper

16:57 gtrak: Hodapp: yea... there's very little repetitiveness, therefore it's hard to read code and see trends

16:59 Hodapp: gtrak: very compressed, in other words?

16:59 gtrak: yes

16:59 Hodapp: gtrak: but if it's *hard* to read code, why is it a good thing that Clojure makes it easy?

16:59 gtrak: because it's more signal than noise

16:59 hopefully

16:59 Hodapp: hah

17:00 gtrak: it's certainly easier to read 5 lines that all look the same, in terms of lines-read per second

17:00 Hodapp: but repetition is certainly a red flag that something could be abstracted better

17:00 gtrak: yea... therefore good clojure code is really hard to read :-)

17:01 but after you understand it, you might not want to change it

17:01 at least, that's what I think

17:01 Hodapp: Well... I dunno if 'hard to read' is what it is. It can be concise without being overly dense.

17:02 Programming Clojure, I seem to recall, talked about how often lower-level code would be 'hiding' a pattern inside it

17:04 gtrak: yes..

17:04 would you rather read code via reading the leaves (java)? or be given a choice of how to traverse the tree? that's kinda how I see it.

17:06 kevin_rh80: Does anyone know if "lein nrepl" ignores the jvm-opts from your project.clj file?

17:07 Hodapp: gtrak: well, my point is just that usually in the latter, it's not harder to read, it's easier because the structure is laid bare

17:08 gtrak: yes, I think it feels harder, but in meaning-per-time it's faster

17:10 bbloom: gtrak: totally. i can read java at extremely high speed. but there's just so much of it to read and i need to do so much navigating and back tracking and control flow following and playing-computer in my head that total time is far less for me to read comparable clojure functionality

17:10 gtrak: but busy-work feels good!

17:10 bbloom: also, functional programming & immutable data has a tendency to force complexity to the surface. you run into data dependencies quickly

17:11 combine that w/ the interactive development workflow, and suddenly you type 4 lines before you say "oh shit, i didn't think about X" and you stop typing

17:11 it's discouraging for folks who are used to writing class Foo {} and then slowly evolving out a solution

17:12 while you're busy copy/pasting to refactor, you have lots of time to think, but your brain is pre-occupied, so your thinking is lower quality and you don't realize that your net time is much greater

17:14 Hodapp: bbloom: I have definitely run into this when trying to write things.

17:15 bbloom: i think it's a phenomenon that needs to be better understood and explained. would certainly help people who start to learn functional programming and then decide that they aren't smart enough for it.... right before they *get* it

17:15 really, the opposite is true: i'm not smart enough for big OO mutable balls of hair :-)

17:15 yogthos: that's what I always found too

17:16 oo and mutability are expert features

17:16 you can do it well if you really know what you're doing, but it's much easier to shoot yourself in the foot

17:16 with fp and immutability the language steers you to doing things properly

17:16 often when it feels more difficult it's because you're forced to consider cases you just gloss over otherwise

17:17 Hodapp: bbloom: I need to get through "Can programming be liberated from the von Neumann style?" but I feel that this paper said something about this

17:17 yogthos: wrt reading speed though, I find you can understand individual lines in imperative code faster, but the overall meaning is often harder to divine

17:18 bbloom: yogthos: being forced to consider cases you'd otherwise gloss over requires you to *WRITE SHIT DOWN*

17:18 gtrak: mmm tasty Von Neumann... the funny thing is these issues of mutability and shared-state vs message-passing apply to the hardware level too

17:18 bbloom: which is why any considerable project i have has a HUUUGE scratch file

17:18 Hodapp: yogthos: surely the meaning of an individual line is clear, but all too often this just gives you very specific implementation details

17:18 bbloom: w/ tons of bullshit code that doesn't actually do anything

17:18 and prose

17:18 yogthos: exactly

17:18 bbloom: and random thoughts spelled out

17:18 yogthos: and you lose the forest for the trees

17:18 bbloom: that no one on earth could make sense of

17:19 yogthos: the problem is in mixing what's being done with how it's done

17:19 the code which solves your problem should be declarative

17:19 Hodapp: well, functional programming is really declarative, not imperative, so there is a lot less of the 'how'

17:19 yogthos: exactly

17:19 Hodapp: object-oriented, at least as in C++ and Java, tends to be imperative too

17:19 as much as people try to say it's not

17:19 yogthos: well the thing is objects don't protect their internal state in most langauges

17:20 it's an honor system

17:20 Hodapp: you're giving a bunch of explicit state-manipulation commands in sequence, which looks pretty imperative to me

17:20 yogthos: I give you a reference and please don't modify it :)

17:20 Hodapp: SEGMENTATION FAULT'ED!

17:20 * Hodapp hits yogthos with chair

17:20 yogthos: lol

17:20 bbloom: objects are really useful for maintaining/coordinating invariants for a collection of mutable cells

17:20 yogthos: if objects could only be modified through setters and guaranteed atomic transactions it would be a lot nicer :)

17:21 gtrak: munge the data (values) with tools that make sense for that, do the side effects with tools that make sense for that

17:21 bbloom: well it becomes your only organization strategy

17:21 yogthos: you also lose the temporal aspect of your data, state is simply a view into the overall process

17:21 Hodapp: bbloom: this annoys me a lot.

17:22 yogthos: and if you're dealing with concurrency there might not be one definitive view that's correct for all parties

17:22 Hodapp: bbloom: it gets into a bunch of hand-waving... "The world is made of objects, therefore objects are the most natural organization blahblahblh"

17:22 bbloom: getters and setters are silly b/c it implies that you can change any property in any order and maintain the invariant

17:22 yogthos: I find classes are a case of premature contextualization

17:22 bbloom: consider a trivial (deftype Range [a b])

17:22 where b >= a

17:23 yogthos: what I mean is that you might want to view the same data differently depending on the context

17:23 Hodapp: yogthos: premature contextualization... haven't heard that one before.

17:23 bbloom: if a and b are mutable, then what happens if you change a to be better than b? you have to move b to equal a

17:23 so the order you change a or b matters

17:23 yogthos: if I have a namespace with related functions and I apply those functions to the data at runtime I get the context when appropriate

17:23 but now I can take the same data and put it in a different context

17:23 bbloom: so setters make no sense in that context

17:24 Hodapp: I'm also getting through "How To Organize Programs Without Classes"; this is another interesting take

17:24 yogthos: in oo this is difficult and you see wrapper and adapter patterns as a result

17:24 Hodapp: or is it "Organizing Programs Without Classes"? Can't remember

17:24 yogthos: you can really think of namespaces as runtime version classes

17:24 the other big difference is that you don't care where data came from

17:25 with imperative you make a label for a memory location and keep referencing and poking it

17:25 with fp you call a function and get a result

17:25 it's exactly same as working with services

17:25 I call a service get a result now I can do whatever with it

17:25 bbloom: yup, services sorta == objects

17:26 except services really == objects + latency&failure

17:26 yogthos: I think erlang is probably the only proper oo language :P

17:26 Anderkent: smalltalk?

17:26 yogthos: smalltalk still has the mutability problem

17:26 Hodapp: Lua and JavaScript actually do a surprisingly good job with OO... so does Python

17:26 C++ and Java on the other hand can go suck it

17:27 reeses: kay admits mutability was a design mistake

17:27 yogthos: well you also have to consider the history

17:27 bbloom: reeses: where?

17:27 yogthos: resources used to be pretty expensive and architecture was predominantly single core

17:27 Hodapp: reeses: [citation needed] on that one :)

17:27 yogthos: so mutability made a lot of sense

17:27 Anderkent: so if running something used ta break stuff, and not it stopped, does it count as fixed even if i didn't change anything? :S

17:27 bbloom: iirc, the smalltalk-like language that kay's viewpoints research thing uses has the ability to capture the entire world

17:27 yogthos: now the overhead of having immutable data and gc is far outweighed by the benefits

17:27 Hodapp: yogthos: but at the same time Kay conceived of objects as things that didn't even need to be on the same computer

17:28 bbloom: not sure how that works tho, i assume it implies persistent data structures

17:28 Hodapp: yogthos: he proposed, for instance, that maybe even each object would have a URL

17:28 bbloom: Hodapp: that's basically true in erlang

17:28 yogthos: yeah and then they would work like erlang :P

17:28 bbloom: each erlang process has a pid

17:28 joevandyk: is there a reason to run more than one JVM process on a single machine? i'm used to running dozens of processes (web apps, background jobs, cron thingies, services). All those things could be consolidated to a single JVM process, right?

17:28 yogthos: it's kind of beautiful really

17:28 well erlang processes are very lightweight, it's 1 vm

17:29 but each "thread" is a green process on it

17:29 bbloom: joevandyk: the JVM's isolation guarentes are pretty weak

17:29 yogthos: and it takes only a few bytes of overhead

17:29 Hodapp: and I know in Self, which was very similar to Smalltalk in many ways, they were somewhat strict in their handling of OO and the way that it was always supposed to further the illusion that it was real (presumably mutable) objects you were manipulating

17:29 yogthos: jvm threads are system threads on the other hand

17:29 Hodapp: and while this is still mutable, I prefer it greatly to OO as languages like C++ handle it

17:29 bbloom: yogthos: clojure's agents are, in many ways, similar to erlang agents

17:29 joevandyk: bbloom: any reading on that?

17:29 bbloom: is there a distributed version of clojure's agents?

17:29 yogthos: bbloom: yup there'd definitely a lot of similarity

17:29 yeah avout

17:30 reeses: http://programmers.stackexchange.com/a/81261 was where I first saw his comments implying immutability was preferred

17:30 joevandyk: thinking of moving to jvm (with zero experience), trying to figure out how to structure things

17:30 bbloom: joevandyk: what are you trying to accomplish?

17:30 yogthos: http://clojure.com/blog/2011/11/29/avout.html

17:30 Hodapp: reeses: thanks!

17:30 reeses: np

17:30 bbloom: yogthos: avout is awesome, but no agents afaict

17:30 gtrak: lol, answered by Alan Kay, awesome

17:30 reeses: more digging will get more usenet posts, etc.

17:30 yeah, I love it

17:30 bbloom: but holy hell are zk-atoms more pleasant to work with than zk

17:30 yogthos: I haven't looked at it in a little while, you might be right :)

17:31 reeses: "what did alan kay..."

17:31 joevandyk: bbloom: standard web app things. multiple sites. things constantly running in background at intervals and async. emails being sent.

17:31 bbloom: joevandyk: JVM apps tend to use a lot of threads

17:31 yogthos: yup

17:31 bbloom: poorly written jvm apps use a lot of locks

17:31 yogthos: do you need push or pull type stuff?

17:31 bbloom: better written ones use a lot of queues

17:32 clojure apps tend to use agents (queues), atoms (compare-and-swap) etc

17:32 Anderkent: joevandyk: multiple sites is probably one JVM hosting the servlet container (tomcat/jetty etc.) and then these handle spinning up threads to handle your sites

17:32 yogthos: yeah you definitely want to use an app server

17:32 each app can be packaged in a war, and then each one gets its own context

17:32 bbloom: joevandyk: yeah Anderkent is right. those servlet containers are what act as the operating systems of sorts

17:33 yogthos: you basically just package them up and drop them in the webapps folder

17:33 joevandyk: ah, ok

17:33 yogthos: I recommend glassfish personally

17:33 joevandyk: anyone use immutant?

17:34 yogthos: you might want to check this out for restful services too http://clojure-liberator.github.com/

17:34 bbloom: yogthos: *cringe* there's that meaningless word again: REST.

17:35 yogthos: I just kinda take it to mean using http methods and urls for routing

17:35 in that context it's kind of a useful distinction from simply using http as a pipe and having your own separate protocol on top of it

17:36 gtrak: end-result: wrap-request-binding: https://gist.github.com/4383596

17:36 Hodapp: bbloom: REST originally meant plenty, though that doesn't mean any modern usage respects that :-/

17:36 joevandyk: for a small amount of work that i do, i need to make a some basic CRUD forms, where 80% is operating on a single table at a time. Best library for that sort of thing?

17:36 yogthos: indeed

17:37 bbloom: joevandyk: rails.

17:37 :-P

17:37 zilti: ,(= (true? nil) (false? nil)) ; Isn't that weird?

17:37 yogthos: joevandyk: shameless plug :P http://luminus.herokuapp.com/ :P

17:38 zilti: &(= (true? nil) (false? nil))

17:38 yogthos: it's basically a compojure template with some utility libs that will build into something deployable

17:38 for actual db access I'd recommend https://github.com/clojure/java.jdbc

17:39 joevandyk: yogthos: i've been looking at that. would be super nice to have a library that integrates bootstrap into it. it's probably pretty simple, but would be nice to have!

17:39 yogthos: yeah it's very much work in progress :)

17:39 I'm planning on adding bootstrap and jquery in as defaults

17:40 I figured I'll release something usable to start and then see what seems to be missing once it gets some usage :)

17:41 joevandyk: one of the more annoying problems i've ran into that activerecord neatly supports is nested forms (via the accts_nested_attributes_for method, see http://railscasts.com/episodes/196-nested-model-form-part-1?view=asciicast for details).

17:42 i don't think i've seen a library that does that stuff outside of activerecord

17:42 zilti: Is there a reason that nil is neither false nor true? I thought it's a Lisp convention that (= nil false).

17:42 joevandyk: accepts_nested_attributes, i mean

17:43 gtrak: zilti: nil is 'falsy', it's not equal to false

17:44 ,[(if nil true false) (nil? false) (boolean nil) (boolean false)]

17:44 &[(if nil true false) (nil? false) (boolean nil) (boolean false)]

17:44 bbloom: lazy bots.

17:44 Hodapp: is 'falsy' like 'truthy' as in 'truthiness'?

17:44 bbloom: anyway, this is a case for.... juxt!!!

17:45 zilti: Someone killed the bots! They're still warm! Quick, the murder's probably still in this room!

17:45 gtrak: the answer's [false false false false]

17:45 bbloom: ,((juxt false? boolean) nil)

17:45 gtrak: Hodapp: yes, anything is truthy except false and nil

17:45 bbloom: (map (juxt true? false? boolean) [false true nil]) ;=> ([false true false] [true false true] [false false false])

17:46 zilti: bbloom: => [false false]

17:46 gtrak: even ##(Boolean. false) is truthy

17:46 bbloom: gtrak: grumble grumble java

17:46 mpan: clojure doesn't use java boxed booleans?

17:47 gtrak: it does... but it doesn't do an extra check for the pathological case

17:47 joevandyk: best xml processing library in clojure?

17:47 zilti: How do I check for truthyness/falsyness?

17:47 mpan: gtrak, huh?

17:47 bbloom: (doc boolean)

17:47 Anderkent: zilti: either (boolean <sth>) or just put it in your if

17:47 gtrak: mpan: nothing's supposed to call the Boolean constructor

17:47 unfortunately, it happens

17:48 mpan: seems ##(= false (Boolean. false)) is fine though

17:48 where does the problem happen?

17:49 gtrak: I guess in 'if'

17:49 bbloom: mpan: = is polymorphic

17:49 mpan: eek

17:49 ok ##(if (Boolean. false) 1 0) isn't giving the answer I wished it would

17:49 joevandyk: https://github.com/dakrone/clj-http is the best way for interacting with http?

17:49 bbloom: identical? isn't

17:49 arrdem: what do :strs ad :syms do in destructuring?

17:50 bbloom: polymorphism isn't free, so identical? is used where possible

17:50 arrdem: joevandyk: it works nicely, that much I can say

17:50 bbloom: and ##identical? false (Boolean. false))

17:50 (identical? false (Boolean. false)) ;=> false

17:51 gtrak: arrdem: it's to specify what kinds of keys you have, generally I stick to keywords or convert beforehand, so I always use :keys

17:51 mpan: does this happen outside of creating Booleans?

17:51 joevandyk: the latest stable release is 1.4? no point releases?

17:51 bbloom: if-tests are evaluated as if by the java: x != null && x != Boolean.FALSE

17:51 and == and != are not polymorphic like .equals in java

17:52 otherwise, every if statement would be mega slow w/o type hinting :-/

17:52 gtrak: ah, I guess it would be terribly slow to abstract over if minus the null-check

17:52 arrdem: gtrak: I've been using :keys blindly for some months now and just discovered the {symbol :key} syntax. I assume that :strs is the same idea of [sym key]?

17:52 gtrak: arrdem: unrelated

17:52 callen: technomancy: fair.

17:52 mpan: ah thanks for the explanation

17:52 gtrak: {sym :key} could also be {sym 'sym2}

17:53 arrdem: right as 'sym2 is a valid key

17:53 callen: pjstadig: hrm. hrm. yes.

17:53 pjstadig: I'll try it.

17:53 gtrak: symbols are just objects, the difference is in how they're eval'd

17:55 joevandyk: is there a recommended style-checker for clojure?

17:55 bbloom: joevandyk: https://github.com/jonase/kibit/ can do some form-level checking for you

17:55 but it's rule set is relatively limited currently

17:56 there are no popular source text level tools that i know of

17:57 callen: pjstadig: Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: sql/get-connection in this context, compiling:(migratus/database.clj:162)

17:57 joevandyk: (:cookies (client/get "http://google.com")) ===> {"NID" {:domain ".google.com", :expires #inst "2013-06-27T22:48:02.000-00:00"….

17:57 what's the #inst?

17:58 callen: pjstadig: (#'sql/get-connection (:db config))

17:58 pjstadig: inside (begin [this]

17:58 bbloom: joevandyk: https://github.com/edn-format/edn#tagged-elements

17:59 callen: technomancy: you're a fan of interactive programming as much as I am, is there a live debugger I can trip in arbitrary Clojure code to create a REPL that can step/next etc?

17:59 joevandyk: bbloom: so it's kind of a type indicator?

18:00 bbloom: joevandyk: tag != type

18:00 types imply implementation, behavior, protocols, etc

18:00 tags are just a value that can be used to guide interpretation

18:01 what is the type of '(+ 2 2) is it integer? or is it a list? or is it an addition expression?

18:02 arrdem: ,(type '(+ 2 2))

18:02 AimHere: ,(type '(+ 2 2))

18:02 bbloom: arrdem: of course.

18:02 but i'm saying it actually depends on the context

18:02 tagged values are values and some information about how to interpret that value

18:02 they don't necessarily imply type

18:02 #inst can be a java.Date or a joda.Instant

18:03 it's up to you to interpret it

18:03 callen: technomancy: I guess swank.core/break

18:03 arrdem: bbloom: sorry. my inner wise-ass spoke.

18:03 bbloom: arrdem: i don't mind. the whole tag vs type this was a pretty big epiphany i had when playing with Mathematica

18:03 it's worth understanding :-)

18:08 joevandyk: so i made a new lein project with `lein new app rooster_shipment_tracker`. using latest lein. haven't changed anything. tests are failing with "Exception in thread "main" java.lang.Exception: namespace 'rooster_shipment_tracker.core' not found after loading '/rooster_shipment_tracker/core'"

18:08 code at https://github.com/joevandyk/rooster_shipping_tracker

18:08 bbloom: joevandyk: latest lein == lein 2?

18:08 joevandyk: bbloom: yes

18:09 arrdem: bbloom: ah so the "tag" is really just a quoted symbol being the name of a function f defining (eval) of the following expression

18:10 bbloom: arrdem: in the context of clojure code, yes

18:10 tags are meaningless without context

18:10 in fact, all symbolic anything are meaningless without context

18:10 dnolen: core.logic gets deep constraints, http://github.com/clojure/core.logic/commit/a48f6450f20b90a46be3b8eb7d3f110404325206

18:10 bbloom: and languages offer us inherent context. we can all agree: we're communicating with a base context: version 1.X of clojure, etc

18:11 edlothiol: joevandyk: the ns declaration says shipment, the directory name is shipping (did you change one of them?)

18:11 arrdem: bbloom: right. I only knew tags from Lisp machine tag bits... which were really hardware types.

18:11 joevandyk: edlothiol: yeah, the git repo should be rooster_shipment_tracker

18:11 but i don't think that would matter

18:11 it's checked out on my machine as rooster_shipment_tracker

18:12 jkkramer: joevandyk: https://github.com/joevandyk/rooster_shipping_tracker/blob/master/test/rooster_shipment_tracker/core_test.clj#L3 - looks like the lein template didn't convert underscores to dashes

18:12 joevandyk: should it have?

18:12 jkkramer: yes

18:12 on that line

18:13 filenames use underscores, namespaces use dashes

18:13 bbloom: joevandyk: hmmm bug? report that to technomancy or the other folks in #leiningen ?

18:13 joevandyk: i'll do that

18:13 arrdem: look and see if it's a Lein bug or just your template tho...

18:14 zilti: I'm a bit worried. I've got some code here I wrote I don't dare touching.

18:15 jkkramer: maybe offer it some incense and gentle chanting?

18:15 zilti: That could break it.

18:16 arrdem: zilti: that's some awful fragile code there

18:17 jkkramer: maybe it will spontaneously improve if you stop looking at it

18:18 zilti: I highly doubt that. And it does something wrong. And I just fixed that, but it didn't have any effect... Oh well.

18:19 * zilti gets himself a snack

18:27 zilti: How awful is that? I've got an if-clause (if reversed? ...) which no matter if reversed is true or false always evaluates the true-expression.

18:30 joevandyk: https://github.com/clojure/data.xml a decent way to process xml?

18:31 is there a way to get vim-style keybindings in the repl?

18:37 jkkramer: joevandyk: data.xml has worked quite well for my purposes. I believe it has limitations wrt xml namespaces

18:43 TimMc: zilti: Time to go back to your axioms, eh?

18:44 zilti: TimMc: Which axioms?

18:45 I think I broke "if".

18:46 TimMc: zilti: You almost certainly haven't broken "if", which means one of your assumptions or inferences is wrong.

18:47 Debugging by iterative fallback to broader and broader assumptions.

18:47 ...from "do I have a typo" to "did I save the file on the right machine".

18:48 zilti: TimMc: I have a variable "reversed?" which is set to either true or false. Simply said, I have this now:

18:48 TimMc: What happens if you put "false" in there?

18:49 zilti: (println reversed?) (if reversed? (println "if said true, actual: " reversed?) (println "if said false, actual: " reversed?))

18:49 joevandyk: Hm, getting this error when using data.xml: "createXMLStreamReader for class com.sun.xml.internal.stream.XMLInputFactoryImpl"

18:49 zilti: If always says "true". If I replace it with (if (= true reversed)) or (if (true? reversed)) if always says "false".

18:50 joevandyk: only in repl

18:50 maybe i need to restart

18:50 zilti: If I replace it by (if true) it says false.

18:51 ...now it always says true. luckily.

18:51 TimMc: zilti: What about (boolean reversed?)

18:51 Put that in the if statement.

18:52 joevandyk: odd, i only get that error in the repl. all i'm doing is calling this function: (defn parse [xml] (xml/parse xml))

18:52 TimMc: zilti: I'm voting for you having (Boolean. false) in there somewhere.

18:52 zilti: TimMc: Always gives true

18:52 jkkramer: joevandyk: if you're trying to parse a string, you need to use (java.io.StringReader. "<foo>bar</foo>")

18:53 joevandyk: ah, right

18:53 jkkramer: joevandyk: otherwise it assumes a file path

18:53 zilti: I never used (Boolean. false) in my whole life, not even when I was still programming Java

18:53 joevandyk: why, btw?

18:53 oh

18:53 ick

18:53 jkkramer: it probably piggybacks clojure.java.io, which does a similar thing

18:54 TimMc: ?

18:54 nvm

18:55 zilti: Did you try (if false ...)?

18:56 zilti: TimMc: Yes.

18:56 joevandyk: if I have (fn1 (fn2 (fn3 arg))), do i use the comp function to simplify that?

18:57 TimMc: joevandyk: You could. There's also the stitching macros: -> ->>

18:57 callen: TimMc: winchester.

18:57 TimMc: (-> arg fn3 fn2 fn1), ((comp fn3 fn2 fn1) arg)

18:58 zilti: TimMc: Oh goddammit the variable was in a list...

18:58 TimMc: ?

18:59 joevandyk: awesome. lots of neat stuff in here. so much to learn!

18:59 TimMc: (list reversed?)

18:59 zilti: My next question was going to be (println (class reversed?))

18:59 zilti: TimMc: exactly. Because it's an optional argument that I just appended as "& reversed?"

18:59 joevandyk: is there a preferred format? (println (parse (fetch url))) vs (-> url fetch parse println)

19:23 abaranosky: joevandyk: not sure if there's a community standard but I'd usually go with the latter.

19:46 hyPiRion: Go with the most readable one

20:46 gfredericks: when I've submitted a patch and feedback is given, is it expected that I make a new patch with just the feedback material, or a new patch with everything?

20:47 bbloom: clojure committers tend to prefer squashed patches

20:48 i usually go with something like CLJ-1234-v002.patch

20:48 use `git rebase -i`

20:50 gfredericks: coothx

20:51 hyPiRion: gfredericks: What issue is it?

20:53 gfredericks: CLJ-1121

20:53 hyPiRion: &'foo

20:53 Oh, that one

20:58 bbloom: gfredericks: pardon my for snooping, but is reduce available at that point in core.clj ?

20:58 gfredericks: I believe it isn't

20:58 bbloom: hm ok

20:58 gfredericks: or else it's not usable for some more subtle reason

20:59 but I definitely tried that first :)

20:59 bbloom: :-)

20:59 reading core makes me cringe sometimes until i remember that stuff may or may not have been defined yet, so it's better to do it the dumbest way that works

20:59 * gfredericks copy and pastes some tests

20:59 hyPiRion: heh

21:00 amalloy: gfredericks: they prefer you make a new patch file with all changes, but i think whether it's squashed or a two-commit patch is up to you

21:00 hyPiRion: They will probably squash it anyway though.

21:00 amalloy: i don't see why. afaik it just gets applied with git am

21:01 bbloom: amalloy: i think it more depends on the committer :-)

21:01 dnolen has been pretty strict about squashed commits on cljs

21:02 hyPiRion: Sure? I'm not sure who was talking about it, but they considered squashing doc changes at some point.

21:16 * gfredericks tries to figure out how to make a two-commit patch

21:17 tomoj: two patches :/

21:17 bbloom: no

21:17 use git format-patch refspec --stdout > CLJ-123-v001.patch

21:17 where refspec is any old normal git ref spec, including ranges

21:17 so for example:

21:18 head~2..

21:18 git format-patch head~2.. --stdout

21:18 will make a patch with the two most recent commits on the current branch

21:18 tomoj: hmm, two patches, one file?

21:18 bbloom: tomoj: yes, git formatted patches support that

21:18 hyPiRion: yeah, I wouldn't be surprised if they're just catted

21:20 bbloom: tpope: i've basically committed cpap to muscle memory over cpp, dunno if that's still up for debate or not :-P

21:21 gfredericks: bbloom: cool, thanks

22:25 SegFaultAX: Does paredit have something that can shift a sublist left or right in its container? Like (aaa (bbb ccc) ddd) -> ((bbb ccc) aaa ddd)

22:25 Sorry, paredit.vim

22:31 callen: SegFaultAX: nothing to contribute, would just like to say that I still don't understand paredit users :)

22:31 hyPiRion: ~paredit

22:32 SegFaultAX: Don't think so.

22:33 http://emacswiki.org/emacs/PareditCheatsheet is the cheatsheet, and I don't think any of them has it

22:35 SegFaultAX: hyPiRion: Thanks.

22:35 callen: Why?

22:37 callen: SegFaultAX: brittle, requires a lot of jousting with your text editor

22:37 SegFaultAX: OTOH, that a vim user would find such an arrangement acceptable is no surprise (bwahahahaha)

22:37 SegFaultAX: callen: What's your editor of choice?

22:38 callen: And for the record, I'm new to paredit. Still trying to get a feel for it to see if it's something I should integrate into my existing muscle memory.

22:39 callen: SegFaultAX: I use what 70% of Clojure users use. I actually technically use vim as well here and there, but just for occasional quick-dives.

22:40 SegFaultAX: You're an emacs user? That doesn't use paredit?

22:40 callen: SegFaultAX: no, I don't use paredit.

22:40 SegFaultAX: it's the bondage-and-discipline of text editing.

22:40 SegFaultAX: callen: Haha. I'm not sure I fully understand your dislike for paredit.

22:41 callen: SegFaultAX: I'm an ex common lisper, I thought it was ridiculous back then too.

22:41 Rich_Morin: callen: have you tried VIMClojure?

22:41 SegFaultAX: Being a CLer is like being a marine. There is no such thing as an "Ex-Marine", simply a "Former Marine". :D

22:41 callen: SegFaultAX: you've got a point there.

22:42 Rich_Morin: I'm highly unlikely to. I've used Emacs and vim both enough to know where I'm more productive.

22:42 SegFaultAX: callen: No matter what language you're using, you're still using CL at heart. Greenspuns 10th and all that.

22:42 callen: SegFaultAX: careful with that talk of the good old days, or I might start writing reader macros for SQL.

22:44 Rich_Morin: in the end, unless you're spending a considerable amount of time doing bulk amounts of editing of one or two files, vim optimizes for the wrong things.

22:44 hyPiRion: Oh lord, I made clojure dispatch macros in CL the other day

22:44 SegFaultAX: callen: But generally, what's wrong with making your editor aware of the structure of your language?

22:44 hyPiRion: Now I only need to make the data structures and make them behave properly

22:44 callen: SegFaultAX: nothing, I just don't like the way paredit works.

22:45 SegFaultAX: callen: Anything in particular?

22:45 callen: SegFaultAX: everything? it defaults to very restrictive circumscription of how your editor works.

22:45 SegFaultAX: it's irreconciliable with how I work.

22:46 SegFaultAX: callen: Well, I can see you're determined to be vague. Thank you for your thoughts. :D

22:47 callen: SegFaultAX: I don't know how else to explain it, forces your edit motions and traversal motions to be along the lines of how it structures the text

22:47 SegFaultAX: any attempt to break from that mold or otherwise make editorial "broad strokes" gets blocked by its nagging insistence on keeping to the parens.

22:51 does anybody here know how to access a non-public var in another namespace?

22:51 gfredericks: #'foo.bar/baz

22:51 callen: I need to hack up some code to pierce the veil.

22:51 gfredericks: CompilerException java.lang.RuntimeException: Unable to resolve var: clojure.java.jdbc/get-connection in this context

22:51 https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L151

22:52 gfredericks: callen: you're sure you're on the same version as the github code?

22:53 callen: god I hope so.

22:53 I'll check momentarily, I've been raping and pillaging the jars in my ~/.m2

22:54 gfredericks: I get your meaning. #' really should've worked.

22:54 bbloom: i'm watching this talk: http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers

22:54 Odersky is clearly a very smart dude

22:55 but man, Hickey's talks are so much more enlightening...

22:55 callen: gfredericks: do you know how to check what version of a library leiningen is using that I'm not necessarily defining myself?

22:55 bbloom: Odersky I see as being like Stroustrup. An integrator and peace-maker, but not much sense with regards to design.

22:56 nobody who has any design sense lets Scala's syntax get the way it did.

22:56 Raynes: callen: oooooh, burn

22:56 callen: and I say this as someone who likes Scala, in a hypothetical alternate universe.

22:56 bbloom: i've said it before, ill say it again: Scala is Java++

22:56 callen: incidentally, Stroustrup made C++

22:56 so theres you goes.

22:58 gfredericks: lein still hates the idea of "running a clojure file", right? as in, without a project?

22:58 Raynes: Yes.

22:59 mpan: is there a nicer way than (read-file) from lein-repl for that need?

22:59 Rich_Morin: Hickey is awesome (and I don't use that word lightly), but there are places where I long for Matz's taste in language design.

22:59 * Raynes twitches

22:59 gfredericks: mpan: the clojure.main class can run files

22:59 callen: Raynes: yes, some people like Ruby.

22:59 mpan: ah thanks

23:00 bbloom: Rich_Morin: matz has good taste in the absence of self control: "include everything! but make it not suck"

23:00 scala says "include everything! make it statically typed!"

23:00 callen: I still say the finishing touch Ruby has always needed was a COME FROM statement.

23:00 gfredericks: man you couldn't even write a lein plugin to do that could you

23:00 mpan: callen: what would that do, though?

23:00 Raynes: callen: Yes, some people state the obvious.

23:00 callen: mpan: reverse of goto.

23:01 mpan: label: blah

23:01 mpan: COME FROM label;

23:01 gfredericks: ruby needed...refinements?

23:01 mpan: as in, unconditionally?

23:01 devn: in some ways I think matz did something that was accidentally brilliant: He said yes so often that now it seems the serious maintainers of Ruby are stepping in to say no when appropriate

23:01 callen: mpan: as conditionally as your gotos.

23:01 bbloom: steve yeggie had that post about clojure needing to say "yes"

23:01 im quite glad rich said "no"

23:01 devn: please don't go there lol

23:02 callen: yegge is a flake anyway.

23:02 gfredericks: callen: so if you COME FROM label in two different places is that a fork of some kind?

23:02 devn: steve yegge is full of sour grapes

23:02 Rich_Morin: Yes, there is a small fracas going on in the Ruby community. See http://www.youtube.com/watch?v=BagNfTbXn3w

23:02 mpan: what happened to yegge? I used to play this game he made and then one day it just disappeared

23:02 and a few years later I learned his name was yegge (and not just rhialto)

23:02 callen: gfredericks: let me consult my INTERCAL manual, h/o

23:02 bbloom: yegge has written a bunch of good (and a bunch of bad) articles tho

23:03 it's obvious that he realizes some smart things, but has a hard time distilling them, hence the absurdly long posts

23:03 but i can't point fingers, since i often write long posts too

23:03 (but not that long)

23:04 for example http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html is worth reading 35% of it

23:04 Rich_Morin: Something like refinements could be very useful in shared Ruby environments (eg, SketchUp plugins), but I defer to the Ruby implementors as to when and how to add them.

23:04 bbloom: but the 35% that is worthwhile is scattered throughout the whole post

23:04 callen: gfredericks: I am downloading an interpreter that supports comefrom to test my hypothesis.

23:04 mpan: callen: that sounds like a nightmare for the compiler/interpreter

23:04 callen: gfredericks: okay yeah, it's implementation specific

23:05 wastrel: p/qin 19

23:05 callen: it can defined invalid, exhibit non-deterministic behavior, or execute on parallel/concurrent threads.

23:05 gfredericks: so it's really up to the implementor.

23:05 devn: anyone here have an opinion on migration libraries for clojure?

23:06 callen: devn: dude.

23:06 gfredericks: callen: that sounds like it would fit in ruby pretty well then

23:06 devn: I see drift and ragtime -- are there others I should pay attention to?

23:06 callen: dude

23:06 callen: devn: the last third of my soul that drained down my bathtub was due to migration libraries.

23:06 devn: I...am your weary soul for this one.

23:06 gfredericks: my migration library is a pile of three functions that technomancy gave me

23:06 callen: I was battling this just 24 hours ago.

23:06 devn: callen: as in, migration libraries in general?

23:06 callen: devn: yes.

23:06 devn: I've tried several now.

23:07 devn: callen: what sucked?

23:07 callen: I have strong opinions, weakly referenced and rapidly deallocated.

23:07 mpan: I'm curious, what are you migrating?

23:07 devn: what was good about what you tried?

23:07 mpan: a database :)

23:07 callen: devn: ragtime's refusal to express an opinion of any sort sucked. It reminded me of Tom Sawyer.

23:08 devn: heh

23:08 callen: and drift?

23:08 callen: devn: migratus is closest to what I wanted, being vanilla SQL files, able to be migrated independently/individually but has some serious issues with lein2 for me.

23:08 devn: lobos generally just works but uses a bumfucked retarded DSL for the migration statements. Seems to be imitating Rails in more form and less function.

23:09 devn: Drift is a hybrid of ragtime and lobos. I'm not very happy with the global migration version counter thingy.

23:09 devn: i tried lobos and I didn't like it.

23:09 callen: so... let's write a better one?

23:10 or fix migratus?

23:10 callen: yeah uh, kinda working on the fix migratus thing

23:10 I'm debugging what seems to be an invalid reference to a private var in jdbc.

23:11 devn: pjstadig has been helpful and communicative as of yesterday (he made migratus, Sonian uses it), but there are more fixes to be made beyond his initial attempts at a 0.6.0-SNAPSHOT lein2 version.

23:11 that or I'm retarded. Equally plausible.

23:12 devn: pjstadig is helpful and communicative all the time

23:12 just sayin'

23:13 Frozenlock: Is `fetch' the commonly used library for client/server clj/cljs interaction?

23:14 https://github.com/ibdknox/fetch

23:14 callen: devn: I was highlighting my lack of experience, not making a statement about him.

23:14 my lack of experience with *him* that is.

23:14 devn: callen: nono, wasn't trying to correct you, was just making a positive statement in general about him

23:14 callen: Frozenlock: I don't know if common is the word.

23:15 Frozenlock: there's a lot of room for idioms to be defined for frontend/backend interaction in the Clojure/CLJS world right now.

23:15 devn: anyway, I am in general fond of migratus and if I wrote my own lib, it'd just end up being a fixed up migratus anyway.

23:15 devn: I just need uh, it to work.

23:15 devn: callen: heh

23:15 that's usually good with migration libs

23:16 Frozenlock: I see. Well, is there other libraries? I would like to compare.

23:16 callen: devn: use lein2 and [migratus "0.6.0-SNAPSHOT"], [migratus-lein "0.1.0-SNAPSHOT"] to join the fun.

23:16 Frozenlock: it's not "libraries", it just that the alternative is usually doing your own AJAX back-n-forth.

23:16 or websockets. whatever the cool kids use.

23:17 xeqi: Frozenlock: theres https://github.com/shoreleave/shoreleave-remote-ring

23:18 devn: https://github.com/thegeez/clj-browserchannel

23:18 ^-I've used that and I liked it, but it is kind of a pain to get set up.

23:19 see: https://github.com/thegeez/clj-browserchannel-demo

23:19 Frozenlock: Thank you very much!

23:20 devn: also this Frozenlock: http://thegeez.net/2012/04/03/why_browserchannel.html

23:20 callen: gfredericks: the problem is the jdbc version, something wacky is happening here.

23:21 devn: gah! I wish lein-pedantic would shut up when I'm in a hurry

23:21 `lein deps --no-pedantry`

23:23 callen: devn: has it ever saved you any trouble?

23:24 devn: callen: it makes me sleep a bit easier I guess, but prior to using it I don't think I ever ran into an issue

23:24 so, uh... *comments out lein-pedantic*

23:25 callen: devn: I avoid lein-pedantic because it reminds me of cabal.

23:25 devn: then I break out into hives, the walls start bleeding, and people die.

23:25 xeqi: devn: haha, use ":pedantic :warn" in the project.clj

23:26 mpan: anyone have particular recommendations for guides/tutorials on starting out in clojurescript?

23:26 callen: SON OF A BITCH

23:26 HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA HAHAHAHAHAHA

23:26 devn: I got migratus to work, FOR SIE FIRST TIME

23:27 * callen dances an irish jig and runs off to the freezer to grab the vodka

23:27 mpan: callen: you sound quite happy, so congratulations

23:28 Raynes: callen: I fear you might be an alcoholic.

23:28 callen: mpan: Through fire and water. From the lowest dungeon to the highest peak, I fought these damn migration libraries. Until the last, I threw down my enemy and smote his ruin upon the mountainside.

23:29 Raynes: what's to fear?

23:29 mpan: callen: I know that feeling of fighting one's own tools

23:30 callen: I've got to be winning some curse words per commit message rankings.

23:31 mpan: who are these meant for? self? friends? coworkers?

23:34 callen: mpan: the universe.

23:55 juldre: Hi all, getting started on clojure here. I have a CounterClockWise + Noir development question: what is the best way of quickly restarting the server to test small changes in code?

23:56 when working in pure Java, eclipse reloads the context automatically, is that possible with counter clock wise? if not, whats the next best thing ?

Logging service provided by n01se.net