#clojure log - Dec 16 2011

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

0:00 cemerick: It's probably going to include three transport impls itself, just to prove out the interface(s).

0:01 technomancy: which three?

0:01 cemerick: I was thinking socket, jmx, and maybe some mq

0:02 hrm, the mq would have to be external due to deps

0:02 technomancy: yeah, that's no fun

0:02 cemerick: do you use elastic beanstalk for snowtide?

0:02 lancepantz: rich was a fan of hornetmq, if i remember correctly

0:02 cemerick: anyway, I want to make sure they're as different as possible

0:03 lancepantz: yeah, whichever. I don't have use for an mq transport at the moment, so I'm hoping someone else will write it. :-)

0:03 technomancy: yeah

0:03 technomancy: cool; seems like a natural fit if you're used to warfile-slinging

0:04 cemerick: and I get a killer management console for free

0:04 i.e. one-click rollback is pretty nifty

0:04 technomancy: I have actually gotten over my urge to make jokes every time someone mentions war files, but I must confess don't think that will ever happen with ear files.

0:04 seriously, ear files?

0:04 cemerick: goodness, are they still used by sane people?

0:05 technomancy: I have no idea.

0:05 cemerick: I had to make one once.

0:05 wolfjb: is there something like file-seq which will only work in the top-level directory ?

0:05 ie I don't want it to recurse through the file system

0:06 amalloy: technomancy: ear files are for elves who are tired of racial persecution

0:06 $javadoc java.io.File

0:06 lazybot: http://download.oracle.com/javase/6/docs/api/java/io/File.html

0:07 technomancy: amalloy: took me a minute

0:08 cemerick: wolfjb: I think file-seq is depth-first, so no.

0:09 It wouldn't be hard to produce a breadth-first implementation though, and (take-while …) using a predicate that returns false for files below the current dir.

0:09 amalloy: cemerick: that implementation is java.io.File/list

0:10 which is why i linked to the javadocs

0:10 cemerick: Mmm, I'm losing it already. :-P

0:13 technomancy: cemerick: I was going to email a review of the web deployment chapter, but it essentially boils down to just making a case for containerless deployment. =)

0:13 cemerick: heh

0:13 That's fair.

0:13 technomancy: the only real concrete thing you miss out on going containerless is monitoring

0:14 cemerick: I'd be interested in a post on the topic. It's absolutely a blind spot for me.

0:14 technomancy: especially if your book is targeting the python/ruby crowd, that's absolutely bread-and-butter stuff for them

0:15 ruby has been all about "toss an nginx in front of an embedded mongrel or unicorn" since people gave up on fastcgi back in '06 or so

0:15 cemerick: java/python/ruby, but yeah

0:16 Well, the problem is that there isn't a defined approach for doing that in Clojure, outside of heroku.

0:16 Or, I can't recommend any of the ones I've seen, anyway.

0:17 technomancy: cemerick: the Play! framework is pushing the containerless approach

0:18 it seems to be pretty popular in java and scala land

0:18 cemerick: Can't say I've looked at it.

0:19 Web dev in Java or Scala? Um…

0:19 technomancy: I hang out in chats with the Java people at work since everyone else is Ruby. =)

0:20 lancepantz: i'm pro-container

0:20 maybe not jetty and war's neccessarily

0:20 but it's nice to be able to swap a classloader out for a hot deploy

0:21 cemerick: The thing about containerless is that you're necessarily getting caught up in a ton of admin around services and lifecycle stuff that I don't think anyone wants to actually think about.

0:21 Again, unless you're on a platform that takes care of that for you.

0:22 technomancy: I dunno; it really wasn't a problem at sonian

0:22 we had an application that was primarily centered around working off queues, and it was trivial to just drop a web server into it.

0:23 if you widen your scope to "general deployment tools" instead of just JVM stuff, everyone is about managing processes; they're the universal unit of deployment abstraction.

0:23 cemerick: so it already had something in /etc/init.d or whatever, took care of jsvc, and had its lifecycle established

0:24 That's a hard thing to say to someone that *only* works with JVM stuff :-)

0:24 er, not *only*, but 90% perhaps.

0:25 technomancy: clojars uses upstart for its process management; it's just a very simple config: https://github.com/technomancy/clojars-web/blob/vagrant/config/clojars.conf

0:26 cemerick: sure; not saying it can't be done and done well

0:27 technomancy: sure; and I'm not saying that you should cover containerless deployment in your book, I just don't buy the argument that app servers are the golden path.

0:27 cemerick: heh

0:27 *nothing* is the golden path in this department.

0:27 All deployment options suck in roughly equal amounts.

0:27 Just in different vectors.

0:27 technomancy: all the ruby and python guys are going to have these existing process-centric deployment systems; there's no reason clojure can't fit into those.

0:28 yep, sure.

0:29 probably not what you want to be thinking out the last night of book editing; sorry =)

0:29 cemerick: In that case, it seems this calls for a well-maintained containerless deployment *thing* that made it all dead-nuts easy for Clojure/ring apps.

0:30 technomancy: nah, it's a marathon 'til tomorrow night, not a sprint :-D

0:31 technomancy: LEIN_NO_DEV=y lein run -m myapp.web # is actually what I recommend

0:33 (as long as you prepare things up-front so each deployment doesn't need to fetch its own deps)

0:33 cemerick: man, you could probably run that in screen or something in a snap!

0:33 technomancy: hehe

0:33 lancepantz: lol

0:33 technomancy: basically: have the CI server run "lein tar && s3cmd put myapp-$VERSION.tar s3://sekritbukit/" as its last step

0:33 lancepantz: i on the other hand like containers, and the ruby and python guys just don't know what they are missing out on imho

0:34 technomancy: though really there's nothing wrong with an uberjar either

0:34 cemerick: I dunno if I like containers, but I certainly know them. Especially tomcat, inside and out, for better or worse.

0:35 technomancy: I'm just saying the "work with existing infrastructure" argument cuts both ways

0:35 cemerick: yeah, perspective is everything

0:36 technomancy: oh hang on; that should be "lein trampoline run" in order to avoid the overhead of two JVMs

0:36 anyway

0:36 cemerick: I did *all* my web stuff in python for ~2 years; that was a long time ago, but the deployment side was the flakiest part of it. *shrug*

0:37 How much of that was due to my ineptitude with such things…who knows.

0:39 * hiredman likes uberjars and uberwars

0:42 technomancy: cemerick: anyway, very happy with what I've seen of the book so far; best of luck wrapping it up.

0:42 cemerick: technomancy: Thanks very much for taking a look at it so late into things. :-)

0:42 And hey, now you have a perfect lead into a post.

0:43 "Emerick's a dope with that web deploy madness."

0:43 ;-)

0:45 technomancy: admittedly I'm not as familiar with app servers, but I'll mention it to the Java team at Heroku tomorrow since they've been on both sides of the fence (and a big part of their job is convincing the Java crowd that they can do without a container)

0:46 mindbender1: and they need to show us POC with a bigger app

0:46 technomancy: POC?

0:46 mindbender1: Proof Of Concept

0:46 technomancy: mindbender1: for raw Java specifically?

0:47 mindbender1: yes

0:47 cemerick: technomancy: it's a bloody platform, *that's* your container. Is that not an effective argument?

0:47 technomancy: cemerick: well, it's also getting them to use the command-line

0:47 cemerick: oh

0:48 knock out one of those eclipse plugins and you're in

0:48 technomancy: it's on the way =)

0:48 cemerick: amazon has command line tools too, and I avoid them too ;-)

0:48 mindbender1: technomancy: they should use an app that previuosly ran on jboss or glassfish as an example

0:48 technomancy: mindbender1: sure; I'll mention that

0:49 cemerick: well, that's a different conversation though

0:49 a lot of teams build apps for jboss or glassfish — the API coupling is often very tight

0:49 technomancy: true. asking them to give up both simultaneously is a hard sell I guess.

0:49 hiredman: technomancy: I think our single monolithic codebase at sonian has become similar to an app server, it provides a lot of functionality that can be used easliy just by nature of the code running in the same code base

0:50 if we had more teams working on more services I could see something where it became the environment where you "deployed" your app into

0:50 cemerick: technomancy: maybe give away copies of small pieces loosely joined to spread the message? :-P

0:51 technomancy: hiredman: yeah, I guess when you factor in the declaring of init namespaces it starts to feel more like that

0:51 hiredman: I was thinking specifically of the ring side being a good argument in favour of embeddability.

0:52 hiredman: well, as are rest api builds out, more and more pieces are sort of discrete units that get rooted in the api somewhere

0:52 our

0:55 it's nice, just about anything I want is already available via the 'platform' configured in a good way

1:15 devn: http://clojure-log.n01se.net/date/2008-04-22.html#13:58

1:39 amalloy: devn: thanks for the link. always fun to see the birth of ideas we take for granted now

1:41 i'm reading along, excited to get to the point where they realize {:strs a b} is not a legal map

1:41 Scriptor: hmm, how old is #clojure?

1:47 amalloy: between 3 and 4 years?

1:47 not sure

1:48 i certainly wasn't here at the time, that's just what i vaguely recall hearing

1:50 cemerick: Was first made public in late 2007 IIRC.

2:29 triyo: I get strange behavior when running `lein uberjar` and have my :main set. It starts compiling the namespaces and then it actually fires the :main -main function. In my case -main starts my jetty server so the uberjar process never completes.

2:30 amalloy: doubtful. more likely, your namespace has some side-effecty stuff in it, like it ends with a call to (-main)

2:31 devn: "* rhickey_ is trying to avoid a destructuring mini-language" - guess he lost that battle against himself

2:33 triyo: amalloy: well yes only side effect stuff in it is to start the jetty server

2:33 amalloy: right. that's your problem

2:33 don't cause loading a namespace to have side effects

2:34 define -main, let someone else call it

2:34 triyo: hmm, I didn't answer that correctly, I mean that namespace has no direct calls to -main itself

2:35 amalloy: if you gisted your namespace, someone could comment

2:35 triyo: so I can in repl load that namespace and -main doesn't get called

2:36 https://gist.github.com/1484983

2:37 amalloy: side effect: you start a server in your very first (let)

2:37 triyo: oh I see the problem :((((

2:37 *blind*

2:37 the let

2:37 bit

2:39 so best way I guess is to bind the let in the -main itself and pass the arg on to start/stop fn

2:40 amalloy: what doesn't make any sense to me is why you're calling start/stop at all

2:40 just start the server in main, and you're done

2:41 triyo: Reason was because once the ref was defined, I could in REPL do nice start/stop of the server if needed to

2:42 but not quite required guess since I;b musing ring middleware `reload`

2:42 *i;b =I'm

2:46 amalloy: Do you have to use :gen-class in order to be able to call the main from when the jar file is executed?

2:47 I get no class def found exception

2:48 lein run works though

2:52 raek: triyo: to be able to use -main as a java main function you must have both :main ... in your project.clj and :gen-class in your ns

2:53 triyo: raek: thanks

2:53 raek: (ns foo ... (:gen-class))

2:59 triyo: that worked thanks

3:23 lnostdal__: is there a way to tell maven, via lein i guess, to not do its "checking for updates" thing?

3:23 i found this, http://stackoverflow.com/questions/994857/stop-maven-from-checking-for-updates .. but how do i "forward" that from lein?

3:30 raek: lnostdal__: maven only performs the "checking for updates" step if you have SNAPSHOT dependencies

3:32 lnostdal__: yes, and i want that; i work with checkouts from git

3:32 , raek

3:32 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: raek in this context, compiling:(NO_SOURCE_PATH:0)>

3:32 lnostdal__: ,(println "silence, bot")

3:32 clojurebot: silence, bot

5:29 dribnet: testing 1,2,3.

5:35 wei_: does anyone have a good resource on setting up a ClojureScript browser-connected repl?

6:56 _Vi: How to make Leiningen to also compile *.java sources to class files that are in src/ directory?

6:59 Found myself: ':java-source-path "src"'

7:20 licenser: okay a silly question, could it be that cljs misses list?

7:20 so list? not list

8:05 tsdh: ,(list? '(1 2 3))

8:05 clojurebot: true

8:05 tsdh: licenser: ?

8:06 licenser: tsdh: in clojurescript it does not exist

8:06 tsdh: licenser: Ah, cljs is ClojureScript. Makes sense... :-)

8:06 licenser: ^^

8:13 I wonder where do I report bugs in cljs?

8:13 found 2 so far

8:15 pyr: licenser: http://dev.clojure.org/jira/browse/CLJS#selectedTab=com.atlassian.jira.plugin.system.project%3Aissues-panel

8:15 tsdh: licenser: http://dev.clojure.org/jira

8:15 licenser: thanks thanks :)

8:15 tsdh: licenser: There is a "ClojureScript" entry in the Projects listing.

8:39 Sunng: it seems that clojars.org cannot accept ssh connection now

9:21 devn: Sunng: are you sure you are using the right key? Have you pushed to clojars before?

9:23 wei_: there is documentation on the browser-connect REPL on github that explains how to set it up. brenton ashworth recorded a screencast which I believe is linked from there.

9:40 Sunng: devn: finally, it works now.

9:42 devn: Maybe it was on maintenance

9:52 Saturnation: what's the best lib for reading json?

9:54 clojure-json looks decent, but was wondering if anyone had an opinion?

9:54 Sunng: Saturnation: do you mean clj-json ?

9:55 Saturnation: yep, just saw the note on github that it isn't being maintained and a pointer to Chesire

9:56 cheshire even :)

9:58 Sunng: Saturnation: cheshire is well maintained

10:00 Saturnation: both cheshire and clj-json are based on jackson, also they have similar API :generate-string, parse-string

10:27 semperos: I used a Java method that returned me something with a class of java.util.Vector$1

10:27 what is the $1?

10:29 real question is why none of the normal java.util.Vector methods seem to be working on it

10:32 TimMc: semperos: What is the method's return type?

10:32 OlegYch: Vector$1 means first anonymous class in Vector

10:32 TimMc: The $ usually means "inner class" -- maybe it is an anonymous inner class.

10:32 OlegYch: who uses Vector nowadays anyway?

10:32 TimMc: I guess using a number prevents collisions.

10:34 stuartsierra: It's probably an Iterator

10:35 TimMc: Sounds about right.

10:36 semperos: checking...

10:37 TimMc: the method is getAllAppenders in log4j's Logger class, return val is just specified as an Enumeration

10:38 TimMc: THere you go.

10:38 Also, I shudder to think what you might be doing with direct calls to log4j.

10:38 semperos: :)

10:39 TimMc: Hopefully writing a superior API. :-P

10:39 semperos: yesterday I implemented a custom log4j appender, so I could push log files into a JTextArea for a swing app (via daveray's seesaw)

10:39 TimMc: nvm, the main problem I have with log4j is writing the .properties file.

10:39 semperos: I've already got things working using (not a properties file) an XML config file

10:40 but my app has both a gui and headless mode, so I want to configure the logger programmatically to use the right appenders in the right context

10:40 I was just exploring the Logger class

10:41 thanks for the help, as always

10:41 erujolc: just output to stdout and let something outside the program handle the log rotation, colorizaton or log shipping to wherever

10:41 semperos: what would that "something" be?

10:41 (this is a simple, developer-facing app)

10:42 TimMc: erujolc: That doesn't help the GUI situation.

10:43 erujolc: our server apps run under supervisord that can pipe stdout and stderr to log files, swapping the fds when required to handle log rotation, can tail the logs, pipe through sed for colorization, can even ship to one of shitty service like logly by piping to curl

10:43 granted, missed the GUI part

10:43 there are others, im sure monit and god does it too

10:43 semperos: erujolc: cool

10:44 erujolc: i just found these logging library heavyweight, if you need multiple appenders, you have tee etc..

10:44 for gui yeah its probably makes sense

10:44 semperos: yep

10:45 it was simple enough, just had to implement a simple interface and pass the custom appender class to log4j

10:46 all of my Java/JVM knowledge I've learned through Clojure, so I'm frequently in the process of filling in the gaps :)

10:49 erujolc: semeros what stack have you came from?

11:12 TimMc: semperos: ^

11:14 semperos: TimMc: ?

11:14 what in particular

11:16 TimMc: semperos: erujolc asked you a question but misspelled your nick. THey're gone, but I'm curious about the answer too.

11:16 semperos: gotcha

11:16 I saw he left, so I left it be

11:18 my background is actually in foreign language and linguistics; got into software development as a hobby, started with a little Java, Python, a little Common Lisp, an unfortunate period of PHP followed by delivernace via Clojure and Ruby

11:18 I now do Ruby and Clojure for a living and enjoy language study on the side :)

11:19 TimMc: "an unfortunate period of PHP" haha!

11:19 semperos: paid the bills at the time, and gave me plenty of mental room to learn Clojure at the time

11:19 TimMc: OK, so you've had a small amount of Java before.

11:20 semperos: enough to know where to start filling in the gaps, I supose

11:20 *suppose

11:21 I do my Ruby development in JRuby as well, so I have every intention of learning the space well

11:37 bhenry: what differences besides the name are there between durendal-jack-in and clojure-jack-in

12:39 technomancy: bhenry: clojure-jack-in is the one that's maintained

12:40 the rest of the stuff from durendal should probably get moved over to being piggybacked in by swank.

13:42 TimMc: Raynes: What do you like about Hiccup?

13:42 ibdknox: composition

13:43 it naturally encourages you to make small pieces out of your views and reuse them

13:43 TimMc: hmm

13:43 Raynes: Specifically, things that differentiate it from Enlive.

13:43 ibdknox: Enlive does that too, but probably differently.

13:44 ibdknox: it does, but doesn't it require you to have bunch of singular html files?

13:44 TimMc: I'm not too familiar with Hiccup's composition mechanisms. defpartial, right?

13:44 ibdknox: I'm not going to create a file and stick one line in it. I'll create a function and stick one line in it.

13:44 TimMc: ibdknox: No, you say (defpartial blah "something.html" [:head] ...)

13:44 so you could have a snippets file.

13:44 ibdknox: I see

13:44 TimMc: and select the bits you want.

13:45 ibdknox: My only complaint is the syntax then :)

13:45 which is entirely subjective

13:47 TimMc: hmm

13:49 ibdknox: Another aspect is having to look in two places to understand how a view is constructed

13:49 TimMc: Locality is a good argument for Hiccup.

13:50 ibdknox: look at .html file, look at .clj to see how things are injected into it, look at snippets file, back to .clj, back to .html

13:50 technomancy: it would be pretty cool if you could do the equivalent of M-. (jump to definition) on a call to io/resource

13:52 TimMc: ibdknox: When I'm coding it isn't a problem, since I keep the HTML buffer in a second window. Someone *reading* the code might have more trouble.

13:53 ibdknox: TimMc: yeah, but will you keep 3 open if you have shared snippets?

13:54 TimMc: Not sure what you mean.

13:54 ibdknox: you mentioned that I could have a snippets file

13:55 or maybe I misunderstood what you were saying

13:55 so I have my page

13:55 which is one .html

13:55 I have a .clj, which reads that in and then fills in pieces of it.

13:56 and I have another file with lots of shared "components", this is the html for a header button and so on

13:56 .html file that is

13:58 cemerick: man, is the enlive v. hiccup thing still going on?

13:58 ibdknox: howdy, stranger :-)

13:58 ibdknox: cemerick: heya :)

13:58 cemerick: when are we getting more podcasts?!

13:59 cemerick: next week

13:59 the book deadline is today; thus, no 'casts

13:59 ibdknox: haha that sounds reasonable

14:00 cemerick: I wanted to get one out last Friday, but chaos intervened.

14:00 ibdknox: such is the way of things, I think

14:00 there's always chaos

14:00 cemerick: It's nice that people are looking forward to them :-)

14:01 ibdknox: yeah, I want to hear what some of the other guys had to say while we were at the Conj :)

14:03 cemerick: so the book is done as of today?

14:03 cemerick: yup

14:03 ibdknox: congrats!

14:03 cemerick: whatever state it's in when I fall on my face tonight is it

14:03 ibdknox: haha

14:03 cemerick: heh, I've got miles to go before I sleep

14:05 tmciver: cemerick: congratulations! Looking forward to it.

14:05 cemerick: thanks :-)

14:06 let's not get ahead of ourselves, lest Murphy strides by

14:06 TimMc: cemerick: No, it's just starting -- there hasn't actually been any discussion until now, just stating of preferences.

14:06 * stuartsierra enters, dressed as Murphy.

14:06 cemerick: There goes Sierra. Typical.

14:06 :-D

14:06 ibdknox: always coming to rain on the parade :p

14:06 stuartsierra: ohai

14:07 what parade did I rain on?

14:07 cemerick: Nothing, oh, nothing.

14:07 ibdknox: stuartsierra: today is the deadline for cemerick's book :)

14:07 stuartsierra: oh yeah, the book

14:08 cemerick: Is someone here writing a book? Cool!

14:08 stuartsierra: I'm finishing up my novel titled "I Was a Teenage Were-Hacker"

14:09 ibdknox: I'm also finishing one about using food names as the title of various programmatic libraries.

14:13 dnolen: woot, rhickey approved CLJS property syntax change.

14:13 ibdknox: sweet

14:13 now all we need is a release :p

14:14 TimMc: And gosh it would be nice if I could pull it via maven.

14:14 technomancy: TimMc: you mean apart from all the unofficially-published artifacts =\

14:15 devn: dnolen: I love you man.

14:15 ibdknox: I want my lein cljs plugin. lest I hear otherwise, I'm gonna end up having to push one too :/

14:15 devn: I was reading cljs commits last night. Thank you for all of the work you've done on it.

14:16 technomancy: I'm still not sure that the whole "set CLOJURESCRIPT_HOME and run everything from git" mandate isn't there to intentionally create an mindset of "don't expect too much stability"

14:16 ibdknox: dnolen: is clojurescript stable? ^

14:18 dnolen: ibdknox: there's a release branch now which includes helpers scripts for producing a CLJS jar, script/release, script/make-jar, done

14:18 ibdknox: !

14:19 technomancy: whoa

14:19 ibdknox: dnolen: that's fantastic. What needs to happen for an official push of it somewhere? Even if it's "cljs-SUPER-ALPHA-DONT-USE-FOR-REALZ"

14:20 dnolen: ibdknox: I think just bugging core get it on clojure hudson right?

14:20 stuartsierra: FYI there was a discussion with Rich this morning about making CLJS releases.

14:20 technomancy: stuartsierra: where?

14:20 * ibdknox bugs stuartsierra

14:21 stuartsierra: on the phone

14:21 amalloy: ibdknox: did you see Raynes is porting 4clojure to noir?

14:21 ibdknox: amalloy: I did :)

14:21 stuartsierra: It's not in my hands right now. Once Rich settles on a versioning strategy I'll add it to Hudson.

14:22 ibdknox: amalloy: I also noticed you created a new website and didn't use it... such SIN!

14:22 ~guards

14:22 clojurebot: SEIZE HIM!

14:22 ibdknox: stuartsierra: that's great news

14:23 I will happily create awesome little tools around it

14:23 TimMc: Does CLJS have an API I can call to compile stuff, or do I have to do everything with shell calls?

14:23 ibdknox: TimMc: there's an API

14:23 TimMc: Sweet.

14:23 What role does the Google Closure thingy play?

14:23 Just compression, runtime libs, or what?

14:24 stuartsierra: both

14:24 TimMc: I'm writing a Try-CLJS with some folks, you see.

14:24 ibdknox: oo

14:24 TimMc: And part of the reason is that I don't know CLJS at all. :-P

14:25 ibdknox: pinot FTW ;)

14:25 TimMc: hm?

14:25 Tell me about pinot.

14:25 ibdknox: http://github.com/ibdknox/pinot

14:25 TimMc: hrmf

14:26 ibdknox: TimMc: includes lots of goodness so you don't have to deal directly with the goog apis

14:26 because those are painful

14:26 TimMc: Ah, I see.

14:26 ibdknox: also, it has a client-side hiccup ;)

14:26 TimMc: Very alpha... this will go well with CLJS. :-)

14:26 ibdknox: hehe

14:27 TimMc: Interestingly, I *like* the idea of using Hiccup on the client.

14:27 ibdknox: I'm starting to reach the point where I believe that we should just use jquery for dom manipulation stuff :/ It's just that a cljs library of some kind should limit the amount of that you need to do

14:30 cemerick: stuartsierra: reading cljs near hudson makes me all warm and fuzzy. Thanks for slogging away in the mines.

14:30 dnolen: ibdknox: I think there are some things afoot that might make jQuery moot

14:30 stuartsierra: you're welcome

14:30 ibdknox: dnolen: ?

14:30 stuartsierra: I said I would take care of the Hudson bit, "because I sinned"

14:31 cemerick: "For thy transgressions, say thricely, 'I will not break the build'. Oh, and write a hudson configuration templating system."?!?!

14:32 dnolen: ibdknox: https://github.com/levand/domina

14:32 stuartsierra: yep

14:33 ibdknox: dnolen: oh god... xpath???

14:33 lazybot: ibdknox: Yes, 100% for sure.

14:33 technomancy: how can dom manipulation be functional? isn't it one big side-effect?

14:33 ibdknox: that's not ok

14:33 dnolen: ibdknox: look at the bottom

14:33 ibdknox: todo, mapping to CSS selectors, this how all the CSS selector engines work. XPath inside, CSS interface.

14:34 ibdknox: dnolen: I see

14:34 I guess I don't see the value over JS

14:34 err

14:34 JQuery

14:35 we'll never get the same level of battle testing with our own solution and I agree with technomancy, dom manipulation isn't functional by nature

14:35 stuartsierra: something written in CLJS has the opportunity to benefit from optimizations in Google Closure

14:36 ibdknox: I'm not sure that's a strong argument in reality: as long as you serve jquery from a CDN, it's already cached on a user's machine

14:36 stuartsierra: dunno, never used either

14:37 dnolen: ibdknox: advanced compilation is a big benefit. I wouldn't judge too quickly - a little bird tells me some people are hacking away at some neat stuff w/ this.

14:38 cemerick: dnolen: any idea if those top-level defs (e.g. the EMPTY values IIRC) are going to eventually not impact optmization?

14:39 dnolen: cemerick: ? how do those impact optimization?

14:39 cemerick: They ensure that some amount of the stdlib is always included, ~30k last I saw.

14:40 I was able to hack them away to get clojurescript couch views down to < 1K, but not in a way that left things workable generally.

14:40 ibdknox: dnolen: in what way is advanced compilation a benefit? The vast majority of sites never even have to think about performance, as they're doing very, very simple stuff

14:41 dnolen: and size is handled by using the google CDN

14:41 dnolen: cemerick: rhickey seems pretty strong on sticking with Google Closure libs. I think CLJS at 30K is a reality for the time being unless people really push for stripping that stuff out. I tried, but I understand the hesitation.

14:41 cemerick: dnolen: oh, it has nothing to do with gclosure. The code that ends up being included in the output is from core.cljs.

14:43 This was my point (2) from http://groups.google.com/group/clojure-dev/browse_frm/thread/9da8b9d8ec81d049#.

14:44 dnolen: ibdknox: given the depth, richness of CLJS I don't see websites with 50 lines of JS adopting CLJS. But there's plenty of sites that have 1K LOC of JS, CLJS has something to offer.

14:44 cemerick: Not a high priority for me, just a psychological tidiness thing. :-)

14:44 dnolen: ibdknox: even so, I think with some of the CLJS frameworks/libs that might appear, and CLJS debugging infrastructure, CLJS could easily smoke other solutions.

14:44 ibdknox: dnolen: using JQuery doesn't mean that advanced compilation won't work

14:46 dnolen: ibdknox: have you tried? It seems like I have heard that people have and it hasn't worked out so well.

14:47 ibdknox: you don't advanced compile JQuery, just your own code. As long as you have an externs file, it works fine

14:47 dnolen: cemerick: I think that's pretty low priority. Using CLJS is like using Backbone.js in your CouchDB views.

14:47 ibdknox: there's no value in advanced compiling JQuery, since it's already on people's machines

14:48 dnolen: ibdknox: I don't have anything more to add since I'm not working on this stuff. Wait and see. If I'm doing anything I'm working on debugging infrastructure.

14:48 ibdknox: dnolen: which I'm very excited about :)

14:49 dnolen: ibdknox: I think has to potential to be awesome. Node.js/V8, Rhino, and Webkit all have awesome rich debugging APIs.

14:49 has the potential to be

14:49 ibdknox: definitely

14:50 technomancy: does the locals-clearing problem affect debugging in cljs as well?

14:50 dnolen: technomancy: heh

14:52 technomancy: I don't think CLJS has locals clearing.

14:52 technomancy: oh, hehe. right.

14:55 TimMc: Locals-clearing... removing locals that are no longer referenced so they can be GC'd?

14:56 technomancy: aye

14:56 TimMc: s/no longer referenced/not referred to later/

15:23 technomancy: (swap! a empty) is so much better than (reset! a [])

15:25 TimMc: Why?

15:25 clojurebot: http://clojure.org/rationale

15:25 hiredman: I just learned about compare-and-swap! yesterday

15:26 kotarak: o.Ô)

15:27 technomancy: TimMc: because reset! isn't as functional.

15:27 ibdknox: there's a compare-and-swap! ?

15:27 I only know of set

15:27 ,(doc compare-and-set!)

15:27 clojurebot: "([atom oldval newval]); Atomically sets the value of atom to newval if and only if the current value of the atom is identical to oldval. Returns true if set happened, else false"

15:27 ibdknox: ,(doc compare-and-swap!)

15:27 clojurebot: Huh?

15:27 kotarak: TimMc: because it also works with maps, sets, etc

15:27 TimMc: kotarak: That's a good reason.

15:28 kotarak: TimMc: also specific maps and set => sorted variants, hash variants, etc.

15:28 TimMc: One more place you can ignore implementation details.

15:28 hiredman: ibdknox: ah, yeah, that

15:29 I was all (swap! a (fn [x] (if (= x :state1) :state2 x)) and sgilardi was all "just use compare-and-set!" and I said "isn't that what I am doing? or do you mean the primitive on atomic reference?" "no, compare-and-set!" "what now?"

15:29 TimMc: SOunds like it uses identical?, not =.

15:32 kotarak: ,(source compare-and-set!)

15:32 clojurebot: Source not found

15:32 hiredman: ~def compare-and-set!

15:33 my firefox always has a hard time loading core.clj from github

15:33 TimMc: hiredman: I switched to using Chrome for that repo. >_<

15:34 Mozilla should add that page to their perf tests.

15:35 hiredman: and I guess they changed the format of their anchor tags sometime ago

15:44 jkkramer: weavejester: following up from yesterday, adding attribute maps to all hiccup tags didn't speed things up, but adding ^String type hints did. Also, it seems attribute maps aren't pre-compiled as thoroughly as they could be. I would offer to submit a patch, but if you're in the middle of a refactoring, I will hold off

15:55 pandeiro: ibdknox: any chance your materials from ClojureWest will show up on the net afterwards?

16:05 brett_h: is there no equivalent to "show" in 1.3 as referenced here: http://stackoverflow.com/questions/4637615/python-dir-equivalent-in-clojure

16:07 hiredman: 1.3 has clojure.reflect, which is not the same as show, but can do give you similar information

16:09 brett_h: hiredman: thank you

16:21 accel_: is htere something liek sqlite3, but implemented in java/clojure?

16:21 i want to see how a simple db is implemented

16:22 Vinzent: Hi. I'm trying to match the following html fragment with enlive: http://pastie.org/3028274 I'm using [:a.search_result_row] and it works, but the :content doesn't contain any tags, just whitespaces: http://pastie.org/3028305 What could be the problem?

16:23 devlol: hello #clojure, what do you think about this small code ? http://pastebin.com/huL5GZHG

16:23 Vinzent: accel_, check out fleetdb, altough it's not sql

16:23 accel_: Vinzent: in ram is even better

16:23 whoa; it's written in clojure

16:23 hiredman: https://github.com/danlarkin/subrosa has a little in memory relational db

16:23 (it's an irc server)

16:24 danlarkin: yeah and it's totally sweet!

16:24 ibdknox: haha

16:25 pjstadig: actually it's totally savory!

16:27 hiredman: whenever I look it, I exclaim "UMAMI!"

16:27 danlarkin: Hmmmmmm umami

16:27 s/Hmmmmmm/Mmmmmm/

16:27 pjstadig: needs salt

16:28 there now we've covered 'em all

16:28 Vinzent: hm, i've tried parsing the same page with the xml/zip and it also returns the empty :content... looks very cryptic for me

16:28 jkkramer: Vinzent: the default enlive parser has issues when you use block elements (div) within inline elements (a)

16:30 Vinzent: jkkramer, ah, and it's tagsoup too, so yeah that's the problem. Can you advice me an alternative one?

16:31 jkkramer: Vinzent: I ran into that and never really came up with a proper solution, besides horrible hacks like regex-replacing all <span> tags with <div> tags

16:36 Vinzent: I tried using various parsers and options, but all broke in various ways when dealing with tag soup in the wild

16:37 Vinzent: jkkramer, have you tried jsoup? it looks very promising

16:38 pandeiro: ibdknox: i only ask because i am looking for any example code using noir and korma together to see how one would organize models... (assuming you saw my ? above)

16:39 ibdknox: pandeiro: There will definitely be some examples of that coming out

16:39 before ClojureWest

16:39 jkkramer: Vinzent: when I checked it out about a year ago, it had issues. Looks like it's improved a lot since then

16:40 pandeiro: cool, that's great... am i understanding correctly that korma isn't for DDL?

16:41 ibdknox: pandeiro: 0.3.0-alpha7 has basic support

16:42 it seems like I can actually add it as a completely separate lib

16:42 which is cool

16:42 but yes, for now

16:42 use something else

16:44 pandeiro: ibdknox: straight SQL is fine for that, just wondering how i automate creating the tables while developing

16:45 amalloy: so i want a function which, given a map and a key, returns nil (or empty) if the map does not contain the key, and returns [[k v]] if it does (i'm folding the one-key logic into the N-key logic, so i want a seq of entries). i can write (when-let [e (find m k)] [e]), but surely there's something nicer than that?

16:45 pandeiro: could i ask how you do it?

16:45 ibdknox: pandeiro: we had an older system that used django, so we continued to use python's south for it

16:46 pandeiro: when I'm just messing around, I either write the SQL or use some visual database creation tool

16:46 hiredman: there is a method on maps that returns map entries

16:46 amalloy: hiredman: yeah, find. i used that in my example

16:47 my problem is that i want a "singleton list" thing if an entry exists, not just the entry. i can't write [(find m k)], because then i get a non-empty list when it's not in the map

16:48 hiredman: huh?

16:48 ,(find {:a 1} :a)

16:48 clojurebot: [:a 1]

16:48 hiredman: ,(find {:a 1} :b)

16:48 clojurebot: nil

16:48 amalloy: hiredman: i want [[:a 1]]

16:49 (and nil in the second case)

16:49 hiredman: ,(#(if % [%] %)(find {:a 1} :b))

16:49 clojurebot: nil

16:49 hiredman: ,(#(if % [%] %)(find {:a 1} :a))

16:49 clojurebot: [[:a 1]]

16:49 pandeiro: ibdknox: cool, that's what i wanted to know... i have some other doubts but i will take them to the noir group when they're better organized... thanks

16:50 cemerick: amalloy: (-?> {:a 1} (find :a) vector) :-P

16:50 pjstadig: breaking out the -?>

16:50 hiredman: amalloy: have you considered concating your maps (as lists of pairs) and filtering based on key?

16:51 cemerick: pjstadig: I might whip out the-?>>, who knows.

16:52 pjstadig: let's not be hasty

16:53 cemerick: serendipitous typo

16:53 * cemerick writes a new macro called what-the-?>>

16:54 pjstadig: wtf-???>>

16:54 amalloy: hiredman, cemerick: thanks for the suggestions. not sure what winds up being most readable; i'll ponder it

16:54 cemerick: threads values at random positions, and may or may not short-circuit nulls. Forces you to program defensively.

16:55 pjstadig: non-determinism is the new determinism

16:55 amalloy: it might be. you never know

16:55 pjstadig: har har

16:58 nickmbailey: is it impossible to proxy an interface that defines a function 'get(…)'?

16:58 amalloy: (a) no, (b) you should probably use reify instead of proxy, for interfaces

16:59 hiredman: nickmbailey: interfaces don't have functions

16:59 nickmbailey: java.lang.IllegalArgumentException: Method 'get' redefined

16:59 hmm reify you say

17:00 hiredman: nickmbailey: most likely you are not proying correctly

17:00 your method doesn't match the interfaces

17:00 nickmbailey: well that isn't surprising

17:00 amalloy: holy cow the code in core-proxy is intense

17:01 nickmbailey: any chance its because the interface overloads the function definition?

17:01 i have to implement get() twice with diff param numbers

17:01 amalloy: yes, you're probably doing that part wrong

17:03 it's in the docs for proxy: f => (name [params*] body) or (name ([params*] body) ([params+] body) ...)

17:04 nickmbailey: aha

17:04 yep doing it wrong

17:06 ok, so is it impossible to call one implementation of the overload function in the other implementation

17:06 hiredman: you have the object, right?

17:06 nickmbailey: Unable to resolve symbol: get in this context

17:07 hiredman: the first parameter

17:07 so just call whatever methods you want on it

17:08 amalloy: hiredman: proxy doesn't have an explicit this

17:08 nickmbailey: Each method fn takes an additional implicit

17:08 first arg, which is bound to 'this

17:08 aha

17:08 it isn't the first arg its just automatically bound

17:08 amalloy: nickmbailey: this is one of the reasons proxy is on the vile side, if you can avoid it

17:08 nickmbailey: about to look at reify

17:09 hiredman: amalloy: sure sure

17:21 Vinzent: jkkramer, so i finally decided to use http://about.validator.nu/htmlparser/ and xml\zip instead of enlive. Thank you for pointing me to the problem!

18:00 Guest43669: I could use some help please: How would I "splat" a seq as parameters to a function?

18:01 tscheibl: (apply fn-name sequence)

18:01 if I understood your question correctly...

18:02 Guest43669: i.e. (str "I'd like " (map (fn [fruit] str " a " fruit) ["apple" "pear" "banana"]))

18:02 I've tried apply & map, but they seem to do the same thing

18:04 tscheibl: ,(apply str "I'd like " (map (fn [fruit] str " a " fruit) ["apple" "pear" "banana"]))

18:04 clojurebot: "I'd like applepearbanana"

18:04 cemerick: I think he wants " a " interposed between them.

18:04 tscheibl: ahh

18:04 cemerick: ,(->> ["apple" "pear" "banana"] (interpose " a ") (apply str))

18:04 clojurebot: "apple a pear a banana"

18:05 Guest43669: My example is certainly contrived, in a more complex example, suppose the underlying map was not doing something as simple as interposing?

18:06 cemerick: ,(apply str "I'd like " (map (fn [fruit] (str " a " fruit)) ["apple" "pear" "banana"]))

18:06 clojurebot: "I'd like a apple a pear a banana"

18:07 cemerick: the function you were originally passing to map was dropping `str` and `" a "` on the ground, and returning `fruit`.

18:07 Guest43669: That's terrific, thank you

18:07 tscheibl: (str "I'd like an " (clojure.string/join " and a " ["apple" "pear" "banana"]))

18:07 should also do it :)

19:03 cemerick: what happened to the ring adapter for grizzly?

19:32 chessguy: i wish clojure stack traces would pipe through "grep -v 'at clojure'" by default

19:33 mrevil: is there a way to get better stack traces from clojure? I'm writing test code and it's hard to tell whether or not the exception is from the test code or application code

19:33 amalloy: chessguy: clj-stacktrace?

19:33 hiredman: mrevil: you should name your test functions better

19:34 if you name all your functions 'foo' and your stack traces all just say 'foo' is it the fault of the stacktraces you can't figure it out?

19:37 pinetree: good afternoon

19:38 mrevil: i know which test, I'm using (testing "some description") for all of my tests, it's just when you get an exception like expected: (= (package/validate {} true))

19:38 actual: java.lang.ClassCastException: java.lang.Character cannot be cast to java.util.Map$Entry

19:38 at clojure.core$key.invoke (core.clj:1465) I have no idea how to track it down

19:38 pinetree: newbie here: does anyone have a favorite guide to setting up AquaMacs and SLIME? I've followed a few different tutorials but still haven't found the magic combination. any suggestions?

19:38 chessguy: amalloy: hmm, looks cool, but installing that plugin doesn't seem to have done anything

19:38 pinetree: oh, and I'm using clojure 1.3

19:38 chessguy: amalloy: i added the snippet to my init.clj too

19:39 amalloy: pinetree: step 1 is uninstall aquamacs and install emacs, usually

19:39 pinetree: amalloy: haha

19:39 chessguy: (+1 amalloy)

19:39 pinetree: amalloy: carbon emacs?

19:39 ibdknox: brew install emacs

19:39 amalloy: i don't use a mac, but i'm told you want cocao

19:39 ibdknox: (says the vim users)

19:39 amalloy: brew install emacs --cocao

19:39 hiredman: ,(key \c)

19:39 ibdknox: -s

19:39 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Character cannot be cast to java.util.Map$Entry>

19:41 cemerick: http://emacsformacosx.com/ is the canonical build IIRC.

19:41 hiredman: brew install emacs doesn't seem to work right for the patches it claims to have

19:41 pinetree: cemerick: ah, yes, I've heard that called "Carbon Emacs" also

19:41 okay

19:41 so

19:41 hiredman: e.g. enabling the fullscreen patch through brew doesn't install it for me

19:41 pinetree: once that's all installed

19:41 hiredman: (doesn't enable it)

19:42 pinetree: best way to get some clojure editing happiness going?

19:42 :)

19:42 cemerick: pinetree: follow http://dev.clojure.org/display/doc/Getting+Started+with+Emacs if you're using emacs

19:42 and don't google anything, the internet is generally wrong

19:43 pinetree: hahahaha

19:43 chessguy: wrong, but entertaining

19:43 pinetree: I haven't used the emacs link you just sent me in a while

19:44 IIRC my primary gripe was that I couldn't use the Command key as Meta

19:45 cemerick: don't people usually want to swap Command and Control in emacs given the predominance of the latter?

19:45 hiredman: (which is crazy, alt is meta, cmd is cmd)

19:45 pinetree: the primary reason for me is actually just the size of the keys on the keyboard

19:45 plus, I don't want to remap everything just for the sake of emacs

19:46 mrevil: what do most people use for validations? I'm attempting to validate input to a rest API before committing records to a database.

19:49 cemerick: mrevil: so there's no form associated with the request? In that case, conditionals are the new hotness. :-P

19:50 If there is a form that you'd like to decorate with error messages and such, sandbar is the ticket. https://github.com/brentonashworth/sandbar

19:50 mrevil: cemerick, you are correct there is no form

19:50 ibdknox: mrevil: or if you're using noir

19:51 mrevil: noir.validation

19:51 cemerick: In that case, you just need to check what you need to check, and return an appropriate response code

19:51 ibdknox: showoff :-D

19:51 ibdknox: I try. ;)

19:54 mrevil: ibdknox: noir.validation looks about right. I wasn't using noir, but maybe I should be.

19:54 ibdknox: mrevil: I hear all the cool kids are using it these days.

19:55 mrevil: it's close to active record validations in rails

20:08 cgray: suppose i've got a vector v that i'd like to turn into a map, is there a prettier way to do it than (let [[foo bar] v] {:foo foo :bar bar}) ?

20:09 hiredman: ,(keyword 'foo)

20:09 clojurebot: :foo

20:09 hiredman: I forget if that works

20:10 cemerick: cgray: maybe you're looking for ##(zipmap [:foo :bar] [5 6])

20:10 lazybot: ⇒ {:bar 6, :foo 5}

20:10 cgray: cemerick: yep, that's it

20:10 hiredman: ,(let [[foo bar] '(foo bar)] {(keyword foo} foo (keyword bar) bar})

20:10 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: }>

20:10 hiredman: ,(let [[foo bar] '(foo bar)] {(keyword foo foo (keyword bar) bar})

20:10 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: }>

20:11 hiredman: ,(let [[foo bar] '(foo bar)] {(keyword foo) foo (keyword bar) bar})

20:11 clojurebot: {:foo foo, :bar bar}

20:21 amalloy: i agree zipmap is the way to go, but if you had foo/bar as locals already, you can use https://github.com/flatland/useful/blob/develop/src/useful/map.clj#L8 to write (keyed [foo bar]) - expands to {:foo foo :bar bar}

20:22 cgray: that's cool... it's more what i had in mind when i asked the question

20:23 but (zipmap (map keyword '[foo bar]) v) worked just as well

20:30 amalloy: i just realized that code has a (juxt (comp (partial ...))) in it, if you inline the let. i may need treatment for a point-free disorder

20:42 chessguy: so...i'm confused. if i (defstruct pair :x y) and i let [foo (struct pair 1 1)], how can i create a new pair from foo with, say, a y value of 2

20:42 hiredman: don't use defstruct

20:42 chessguy: ugh, ok

20:42 what shouuld i be using? records?

20:43 gfredericks: chessguy: what motivated you to use defstruct?

20:43 cemerick: or regular maps, yes

20:43 chessguy: i'm porting common lisp, and that's what it used

20:43 cemerick: CL structs are not Clojure structs

20:43 chessguy: well i didn't figure they were identical, but i thought they were close enough

20:44 amalloy: chessguy: echoing cemerick here: you probably just want hashmaps

20:44 chessguy: amalloy: cemerick: fair enough

20:44 amalloy: if they all have the same two keys...well, so what, keys are just a cheapo pointer

20:44 cemerick: chessguy: https://github.com/cemerick/clojure-type-selection-flowchart

20:45 chessguy: whoah, that url sounds epic

20:45 duck1123: ,(let [foo {:x 1 :y 1}] (assoc foo :y 2))

20:45 clojurebot: {:y 2, :x 1}

20:45 cemerick: omnigraffle has that effect :-P

20:46 technomancy: structs and records don't have nearly as good of a theme song anyway: maps are the besthttp://www.youtube.com/watch?v=oIIxlgcuQRU

20:46 oops

20:48 amalloy: technomancy: what the hell, who puts a QR code next to a youtube video? if you want to link to some information from a webpage...link to it

20:49 technomancy: youtube isn't really a place where you expect stuff to make sense

20:49 tcrayford: man it's been a long time since I heard that song

20:49 thanks

20:50 hiredman: technomancy makes a good point

20:50 technomancy: clojurebot: maps?

20:50 clojurebot: maps are *AWESOME*

20:50 technomancy: ^ also a good point.

20:50 tcrayford: clojurebot: pointfree?

20:50 clojurebot: Excuse me?

20:50 tcrayford: no points :(

20:51 amalloy: i can't find a link: anyone know who said "If I can only have one data structure, let it be a hashmap"?

20:51 hiredman: obviously not a lisp programmer

20:53 technomancy: we can probably rule out chuck moore too

20:53 gfredericks: a pothead of some sort?

20:53 cemerick: all you need is alists

20:53 hiredman: ~#34

20:53 clojurebot: 34. The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information. -- Alan J. Perlis

20:54 gfredericks: all you need is finger trees

20:54 tcrayford: I'd hazard a guess at Larry Wall :/

20:56 cemerick: weavejester: do you know what happened to the grizzly ring adapter?

21:16 weavejester: cemerick: Nope, sorry

21:22 cemerick: no worries, just taking inventory a bit

21:22 interesting that someone wrote a mongrel2 adapter

22:03 hugod: amalloy: a belated (-> {:a 1} (select-keys [:a]) vec)

22:20 amalloy: hugod: slick

23:58 jcromartie: how do I reference a proxy object itself within one of its methods

23:59 TimMc: Ugh, I can't get cljs.compiler/compile-file to write out to file when I run my program, although it works fine from the REPL.

23:59 jcromartie: say, (proxy [Foo] [] (someMethod [] (.redraw this)))

Logging service provided by n01se.net