#clojure log - Dec 09 2011

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

0:14 semperos: devn: leiningen definitely would do the job

0:15 have a Maven requirement for maintaining consistency with other parts of a larger build

0:15 kumarshantanu: thanks for your help, I got everything working

0:20 kumarshantanu: semperos: \m/

0:37 vivekn: I've heard that code of a running Clojure program can be modified and it will be reflected immediately. What are the conditions for it and how does one go about doing it, for example if I want to change a particular defn?

0:45 duck1123: vivekn: if you have an editor that supports it, it's as simple as running a command to re-eval that function. Or, if you have a running repl, you can send that definition again

0:47 vivekn: What if I'm already running the code in a REPL

1:17 zakwilson: Does one of the file interop libraries have a recursive delete directory function?

1:19 c.c.java-utils had one, but I'm hoping for something maintained.

1:20 * zakwilson will wait five minutes before copying the code from c.c.java-utils in to his personal utility library.

1:22 amalloy: zakwilson: (doseq [file (reverse (file-seq root))] (.delete file))?

1:22 zakwilson: amalloy: I did not know about file-seq.

1:23 That's a really bloody useful function. Thanks.

1:26 amalloy: zakwilson: it's really just a special case of tree-seq

1:29 zakwilson: I need to spend more time just reading the Clojure and popular library APIs. I'm probably duplicating things.

1:29 amalloy: help yourself to https://github.com/flatland/useful

1:31 zakwilson: https://github.com/zakwilson/zutil-clj <-- I wonder how much of that is already in here

1:34 A little overlap. Not as much as I thought there might be. Good stuff there.

1:35 amalloy: zakwilson: i just gave a presentation today on how everyone should have their own utility library. nice to see that you're already doing that

1:36 zakwilson: Yeah. I need to make mine a little cleaner. I'm pretty sloppy about just sticking stuff in it, and I think it still depends on clojure.contrib.

1:36 amalloy: zakwilson: whoa, lookup-with is a terrible function

1:36 zakwilson: My zpmap looks a lot like pcollect

1:36 lookup-with? What's that? I can't even remember it.

1:37 amalloy: it's in map

1:37 it doesn't let you distinguish between "not in map" and "value is nil/false". it's also duplicating a feature that maps already have

1:37 zakwilson: It looks like it does the same thing get does.

1:38 Now I have to look to see where I actually used that, if anywhere.

1:39 It looks like it's used exactly once in a scratch file from a personal project.

1:41 I have no idea why I wrote that.

1:41 amalloy: presumably you didn't know about the not-found behavior of get

1:42 notostraca: hey, I am trying to figure out what to do to call a function n times and collect all the calls in a seq

1:42 zakwilson: Or even get itself.

1:43 amalloy: &(doc repeatedly)

1:43 lazybot: ⇒ "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"

1:43 notostraca: oh, thanks

1:43 I was looking right at it, I thought it was just for side effects

1:44 zakwilson: (dorun (repeatedly launch-the-nuclear-missiles))

1:50 amalloy: notostraca: well, it obviously is for side effects; either the function produces side effects or it depends on side effects

1:51 notostraca: my code uses repeatedly to call a function that shuffles a list differently every time

1:51 amalloy: yep. depends on the side effects produced by the random-number generator

1:53 technomancy: amalloy: is reverse on file-seq guaranteed to work?

1:53 I mean for deletions

1:54 it's a sweet trick, but I've avoided using it in non-test code because it feels like it's relying on implementation details

1:54 amalloy: technomancy: i don't know about guaranteed

1:55 technomancy: zakwilson: delete-file-recursively was not promoted because pre-jdk-1.7 there was no way to distinguish directories from symlinks to directories

1:55 amalloy: haha ouch

1:55 zakwilson: technomancy: I... can see reasons to want to be careful about that.

1:55 technomancy: yeah, it chews

1:56 zakwilson: Still, I want it in this case. My app is creating the directories, so it can delete them. If a user goes and sticks a symlink to / in one, they're an idiot.

1:56 technomancy: welcome to the jdk, where we sometimes pretend unix isn't really a thing.

1:56 amalloy: you should use clojail to set up a jvm sandbox around what you *really* want to delete, then do it

1:56 technomancy: yeah

1:56 * technomancy sentences amalloy to life without parole in clojail

1:57 * zakwilson adds clojail to the list of things he should probably know about some day.

1:59 amalloy: zakwilson: well, i'm mostly just recommending it for fun in this case

2:03 zakwilson: Yeah, but it sounds like something useful.

3:16 kral: hi all

4:05 AWizzArd: Moin.

5:22 pyr: b

6:09 lnostdal_: hum, java.sql.SQLException doesn't contain the query? O_o .. i'm working via org.clojure/java.jdbc

6:58 kumarshantanu: Inostdal_: Not sure why should the exception have the query

6:59 the exception can occur even when you don't fire a query yet

7:00 lnostdal_: true, but when there is a query; why is it not available?

7:00 maybe i'm missing something

7:01 kumarshantanu: Inostdal_: This is way SQLException is designed

7:02 http://docs.oracle.com/javase/6/docs/api/java/sql/SQLException.html

7:06 lnostdal_: yeah, it seems so .. and it seems kinda dumb

7:07 Borkdude: it is the same with a lot of other exception: cannot cast a string to whatever. Please tell me what the string was! *sigh*

8:45 Saturnation: Sometimes using emacs is a royal pain in the ass :(

8:47 hhutch: "sometimes" ? ;)

8:48 clgv: Saturnation: if "sometimes" becomes "often" check the alternatives ;)

8:48 Saturnation: it doesn't :)

8:49 Just trying to set up my environment after moving to a Mac and feeling some friciton, mainly around emacs at the moment...

8:49 anyone know the command in emacs for showing a key-binding?

8:49 TimMc: Saturnation: The command tha tis bound to a key, or vice-versa?

8:50 Borkdude: Saturnation: C-h k followed by the key bidning?

8:50 Saturnation: the command that is bound to a key

8:50 Borkdude: for example: C-h k C-h k ;)

8:50 Saturnation: Borkdude, thanks, that did it

8:50 :)

8:54 hmm, slime doesn't seem to have bound C-up in my custom build of emacs :(

8:55 clgv: Saturnation: I heard Aquamacs would be the choise on Mac

8:55 Saturnation: was hoping for a terminal based emacs, so did my own build, but thanks, I'll look into that

8:56 first day of 20% time and I'm fighting emacs :)

8:58 everyone I saw at the Conj seemed to be using a terminal based version

8:58 hhutch: Saturnation: you built from source? homebrew didn't help?

8:59 * Saturnation is very new to Mac

8:59 Saturnation: homebrew?

9:00 hhutch: homebrew is like apt/rpm on linux

9:00 * Saturnation is comfortable with ./configure & make install

9:00 hhutch: http://www.unschooled.org/2011/10/how-to-setup-emacs-for-clojure-on-mac-os-x-lion/

9:00 Saturnation: in my experience, emacs is something better gotten in binary form

9:02 Saturnation: hmm, wanted 24 since it had package.el built in, that's why I built me own

9:02 Borkdude: Saturnation: I switched to Mac OS X recently

9:02 Saturnation: from that page, it's version 23

9:02 Borkdude: Saturnation: first I tried Aquamacs but switched back to normal Cocoa based Emacs

9:03 Saturnation: what's confusing me at the moment is that one version got it right and the other didn't, but they both "appear" to be using the same .emacs.d/ setup O_o

9:03 Borkdude: Saturnation: I picked the 24 version from here: http://emacsformacosx.com/builds

9:04 Saturnation: and then 'installed' marmalade and the emacs start kit thingies, and clojure thingies from elpa

9:04 Saturnation: Borkdude, yeah, that's the one I picked up as well, but again, was hoping to get it running in a terminal

9:04 sounds like what i've done as well

9:04 Borkdude: Saturnation: I can do that as well

9:05 Saturnation: Borkdude: how do you run it in the terminal?

9:06 Borkdude: Saturnation: let me find out again, I think with some options to emacsclient

9:07 Saturnation: just type "emacsclient -nw" in the Terminal, as a matter of fact I'm typing this from Terminal now.

9:08 Saturnation: http://twitpic.com/7qshx8

9:08 Saturnation: oops, it's getting my custom build, so it isn't working :)

9:08 will fix that

9:10 Borkdude: I am wondering though what will happen when I quit the Emacs in the terminal...

9:10 ah

9:10 phew.. it just returns to the shell without killing the "normal" Emacs

9:10 Saturnation: not quite right, it expects a server to be running?

9:11 Borkdude: Saturnation: I put this at the top of my init.el:

9:11 ;; To connect with emacsclient, the socket is at ~/.emacs/server/server

9:11 (setq server-use-tcp t)

9:11 (server-start)

9:11

9:12 Saturnation: don't know exactly why I did this tcp thing

9:12 Saturnation: looks like it can communicate via unix sockets or tcp, so that makes sense

9:13 Borkdude: Saturnation: and you can always be sure where to look for it, instead of some random port to connect to

9:13 Saturnation: what do you get for "which emacsclinet"?

9:14 Borkdude: Saturnation: /usr/bin/emacsclient (it is probably the emacsclient from osx I realize now...)

9:14 Saturnation: yep

9:14 that's what I thought

9:14 it looks like its attaching to your running 24 version?

9:14 Borkdude: I disabled the OS X emacs though

9:14 which emacs -> /Users/Borkdude/bin/emacs

9:15 Saturnation: I think I need to dive into the emacs doco :)

9:15 thanks for the help

9:16 Borkdude: this is weird though

9:16 I made a script in ~/bin/ called emacs which just calls emacsclient, I thought I wanted to be clever, but never use this as such

9:17 it calls emacsclient -f ~/.emacs.d/server/server ;)

9:20 Saturnation: doesn't work for me

9:20 like I said, I think I need to get my head around emacs a bit better :)

9:22 Borkdude: Saturnation: me2

9:24 Saturnation: Borkdude: do you know how to get the bindings for a function? The opposite of C-h k?

9:24 Borkdude: Saturnation: C-h f

9:24 Saturnation: thanks :)

9:24 both instances of emacs seem to be using the same slime files, which is really weird

9:25 Borkdude: Saturnation: I only use one instance

9:25 Saturnation: I would too, but trying to debug one of them :O

9:25 Borkdude: I just disabled the OS X one

9:26 by renaming it

9:26 Saturnation: I set my PATH to get my custom build before the OS X one

9:29 I'm beginning to think that slime-repl hasn't been set up in my custom build? :(

9:35 Borkdude: got it figured out now. I just made a script in ~/bin/ called emacs, with this line in it: emacsclient -f ~/.emacs.d/server/server -nw $1

9:35 so whenever I'm in the terminal and need to edit something, I can just type: emacs foo.txt

9:36 also core.editor in gitconfig is just "emacs" now

9:36 bobhope: Hey clojuristas, I'm wondering if there's a way to redefine the if special form so that it behaves as normal unless the condition matches some predicate, in which case it takes the true and false results and does something else with them

9:36 Borkdude: bobhope: don't redefine it

9:37 bobhope: Borkdude, I want to embed a DSL in clojure that has "if"

9:37 is there a way to refer to it in a qualified way?

9:38 I found a post showing that if I (def if println), then (if true 1 2) behaves as usual but ((var if) 1 2) uses the new def

9:38 do I just need to do something like h:if or something?

9:39 Borkdude: bobhope: if is not associated with a var, but is a special form

9:39 bobhope: so i'd need to modify the clojure runtime to modify its behavior?

9:39 like, the part wirtten in java?

9:39 Borkdude: bobhope: just don't go there. why don't you just write a new "my-if"

9:40 cemerick: bobhope: special forms cannot be redefined by definition :-)

9:40 bobhope: suppose I wanted to go there

9:40 :)

9:41 cemerick: You can certainly write a macro wherein `if` symbols are expanded into something else.

9:41 bobhope: Could I, for instance, change the special form to be called clojure-default-if

9:41 and then make if a macro

9:41 Borkdude: I guess not

9:41 bobhope: which I can selectively redefine?

9:41 cemerick: what are you trying to do?

9:42 bobhope: if the condition's a boolean, I want it to be normal

9:42 if the condition meets a certain predicate, I'd like the quoted true & false branches

9:42 and those branches to be packed into another data structure

9:43 cemerick: I think that's called an "interpreter". ;-)

9:43 bobhope: yeah...

9:44 Borkdude: bobhope: can you give an example?

9:45 bobhope: (if true 1 2) == 1

9:45 (if ['a] 1 2) == {:cond ['a] :truebranch 1 :falsebranch 2}

9:46 Is that clear/

9:47 Borkdude: not entirely, but are you building some kind of ast?

9:47 bobhope: yes, but only selectively

9:47 so if I pass an ast fragment into the condition, I want to return more ast fragment

9:48 but if I pass a boolean into the condition, I want to return the result of evaluating the appropriate branch

9:48 so that clojure's runtime because a metaprogramming facility for the ast

9:48 not "because", "becomes"

9:49 Borkdude: so what is the problem with using something different than if for it, for example your own my-if?

9:50 ast-if

9:50 bobhope: i'd really, really like to be able to use idiomatic clojure throughout

9:50 and have it seamlessly work

9:50 I suppose I could use a macro in the "defn" equivalent to transform all "if" into "my-if"

9:50 but that seem fragile

9:51 Borkdude: bobhope: sounds like very tricky stuff

9:51 bobhope: that's the best stuff to do :)

9:51 Borkdude: bobhope: a lot of normal functions have their parallels in clojure.core (I think, haven't dug into it very deeply) and slightly renamed them, it makes sense to me

9:52 bobhope: because they are not the same, but are -like- it, used in a different way

9:52 bobhope: in fact it would be very confusing if the same names were just used in the logic programming context

9:53 bobhope: same with your example, my opinion

9:53 cemerick: bobhope: idiomatic Clojure branches control flow on `if`; doing anything else would be absolutely bizarre. Useful perhaps, but not idiomatic.

9:53 Thus, the macro route.

9:55 bobhope: indeed

9:55 the ast I generate is executable

9:55 it just allows me to codegen for non-java

9:55 while still also running it on the jv

9:55 jvm*

9:59 Borkdude: bobhope: good luck with it. gtg

11:32 ambrosebs: given an existing namespace symbol, I want to slurp the file that defines it. Any straightforward ways of approaching this?

11:37 wiseen: are :pre and :post conditions always executed or only if *assert* is defined ?

11:38 that is is it safe to use pre and post without them being executed in production ?

11:39 jeremyheiler1: ambrosebs: what do you mean by "the file that defines it"?

11:40 ambrosebs: clojure.core -> "clojure/core.clj"

11:44 ihodes: ambrosebs: i don't think there is. you could of course just mangle ths string into a path, but that's rather brittle and assumptive. of course, someone else might have a better idea

11:45 ambrosebs: ihodes: I'm sure it's buried in `load` somewhere

11:45 but wasn't immediately obvious

11:46 stuartsierra: ambrosebs: the `source` function in clojure.repl works this way

11:46 ihodes: ambrosebs: oh yeah, i'm sure there's a way, but no obvious way haha

11:47 ambrosebs: stuartsierra: great, thanks

11:48 sirvaliance: I am just starting playing around with clojure, but are there any REPL's that have history?

11:49 Or, why does the clojure repl not have history?

11:49 ihodes: (:file (meta (resolve 'map)))

11:49 stuartsierra: sirvaliance: I think JLIne will give you history.

11:49 ihodes: ambrosebs: the above should work, i think.....

11:49 * sirvaliance looks up JLIne

11:50 stuartsierra: it's a command-line wrapper, adds simple things like navigation & history to any Java console app

11:51 Any editor / IDE environment should also work.

11:51 TimMc: wiseen: Good question, I've not played around with :pre and :post. I guess you could give it a try with a :pre that always fails. :-)

11:59 wiseen: TimMc, how do I disable *assert* ?

12:00 simply set! *assert* false ?

12:00 if so, it's still evaluated :(

12:01 ambrosebs: ihodes stuartsierra: what if I don't have a var name, just the namespace name?

12:02 source-fn takes the metadata of an existing var

12:02 wiseen: actually, if you (set *assert* false) before you define the function with {:pre :post} conditions they are *not* evaluated :)

12:03 that should be noted somewhere in the docs :)

12:09 licenser: dun dun dun mornin

12:10 ihodes: ambrosebs: (:file (meta (resolve (ffirst (ns-publics 'clojure.core)))))

12:10 ambrosebs: comes to mind. might be a better way, but that works.

12:11 ambrosebs: though, if it doesn't have publics/anything in it to examine, that of course wouldn't work. lemme check something

12:11 ambrosebs: yep

12:17 jebberjeb: I want to learn lisp. I'm familiar with java. Would it be wise for me to start my lisp journey with clojure?

12:17 ihodes: jebberjeb: i'd say it's as good of a place to start as any; better, in fact, because you know Java

12:18 jebberjeb: alirght, I assumed that was the case -- just wanted a sanity check before I dove in

12:18 TimMc: wiseen: Yes, I think that *assert* is read by the compiler at the function's definition time.

12:21 technomancy: clojurebot: ಠ_ಠ

12:21 clojurebot: Huh?

12:30 Saturnation: Is anyone here using emacs 24 in a terminal? If so, where did you get it and how did you set it up?

12:30 clojurebot: no, anyone is a funny thing.

12:30 technomancy: Saturnation: I just build from source

12:31 Saturnation: I build from emacsmirror on github, but the C-<up> and C-<down> keys aren't bound correctly in *slime-repl nil* :(

12:32 been on #emacs all day trying to figure what's wrong

12:32 technomancy: cheating answer: it's best if you avoid using the arrow keys

12:32 Saturnation: how do you scroll through repl history?

12:32 technomancy: M-n/p

12:33 Saturnation: hmm

12:33 thank you and WTF

12:34 TimMc: heh

12:34 Saturnation: seriously, shouldn't it just map to arrow keys as well, or is that just broken in 24? Ah, but what, it works for the windows 24 O_o

12:34 TimMc: Saturnation: I use arrow keys for navigation in Emacs quite frequently, but it is good to know the standard keybindings in case you are working through a weird terminal.

12:35 Saturnation: but I can set-local-key bindings when in the repl and it WORKS, so I'm a bit confused

12:36 technomancy: yeah, generally anything using modifiers and arrow keys is going to be broken in the terminal whether using emacs or not; terminals just don't have the capability to represent certain key combinations.

12:37 Saturnation: But I can get it to work on a session only basis using set-local-key, so again, color me confused

12:37 * Saturnation moves on

12:40 * Saturnation tries to move on, but muscle memory is a bitch

12:46 kumarshantanu: wiseen: Is that on the REPL?

12:47 Saturnation: technomachy: what does your M-n bind to?

12:47 wiseen: kumarshantanu, no "java -c clojure.jar clojure.main test.clj" changing *assert* in REPL didn't work last time i tried it AFAIK

12:48 kumarshantanu: wiseen: It doesn't work on the REPL AFAIK -- in the file maybe you can try (binding [*assert* false] ...)

12:49 technomancy: Saturnation: slime-repl-next-input

12:50 wiseen: kumarshantanu, put the defn expression in (binding ) ?

12:50 kumarshantanu: wiseen: err no, use the binding when you don't want assert to work

12:53 wiseen: kumarshantanu, nope - still the same, https://gist.github.com/1452590 - it prints false for *assert* value but still throws an exception from precondition

12:54 works the same if you (set! *assert* false) after (defn foo ...) but if you set it to false before it doesn't throw

12:55 jonasen: Is it impossible to extend a protocol with another protocol?

12:57 dnolen: jonasen: no.

12:57 jonasen: sorry I mean no, it's not possible

12:59 jonasen: dnolen: ok. Is it a due to some technical reason or is it simply never necessary to do so?

12:59 kumarshantanu: wiseen: (set! *assert* false) before the defn form seems the only way to deisable it

13:00 dnolen: jonasen: Clojure discourages inheritance.

13:01 jonasen: dnolen: Yes, though I don't really see why it's the same as inheritance.

13:04 dnolen: jonasen: the protocol is inheriting definitions from some other protocol right? What do you see is the benefit?

13:08 jonasen: Say I define a Point2D protocol with (x [p] ...) and (y [p] ...). Next, I define a Distance protocol containing a dist function. Now it would be nice to extend Point2D to Distance. Usually I would simply define a function dist (i.e., not a protocol) but there are other distances that are not defined between points (for examples lehvenstein distance between strings

13:22 Borkdude: Simple question: how do I get "lein repl" to create a Clojure 1.3 repl, when I'm outside a lein project? (now it does 1.2.1), should I "install" or remove something?

13:22 dnolen: jonasen: I don't see why Point2D and Distance should be combined.

13:23 jonasen: dnolen: I'm probably complicating things needlessly. Thanks!

13:25 TimMc: Borkdude: You can't, I think.

13:25 Borkdude: Outside a project, Leiningen uses its own JVM for the REPL (for speedier launch).

13:26 Borkdude: TimMc: yes, but what clojure version get used by default?

13:26 TimMc: I keep a ~/tmp/clj/project.clj lying around with 1.3.

13:26 Borkdude: Whatever Lein uses, which I think is 1.2.1.

13:26 Borkdude: TimMc: I see.

13:27 TimMc: I think it's a bit unfortunate.

13:27 Borkdude: TimMc: I also have a project called "repl" just for spinning up a repl when I want one

13:28 sirvaliance: Any vim users that program clojure have any suggestions?

13:28 TimMc: sirvaliance: I've heard of something called "evil".

13:28 and "vimclojure".

13:28 Borkdude: (waiting for the suggestion: "use emacs instead" to come up)

13:29 TimMc: Use whatever works. If Notepad does it for you, more power to ya.

13:29 sirvaliance: TimMc: I just setup vimclojure

13:30 Borkdude: At least Notepad has an almost constant learning curve. http://bc.tech.coop/blog/060302.html

13:30 * sirvaliance just understands what "evil" refers to ;)

13:30 jodaro: haha

13:31 sirvaliance: It took googling to get the joke

13:32 I really want to get into game dev through learning clojure

13:32 Not necessarily for others to "play", more for a personal learning experience

13:37 TimMc: *nod*

13:40 sirvaliance: Are there any sort of package managers for clojure? Like pip for python or gems for ruby?

13:41 Borkdude: I don't know those, but I think you might want to use leiningen

13:41 jodaro: if you use leiningen for your project it will handle getting dependencies

13:41 not exactly the same thing but

13:42 Borkdude: you can push your things to clojars and get it using leiningen

13:42 https://github.com/technomancy/leiningen

13:43 sirvaliance: Also, do most people (as suggested from an online book) just write a script called clj which basically links to "java -cp clojure-1.4.0-master-SNAPSHOT.jar clojure.main"

13:43 TimMc: sirvaliance: I don't think so.

13:44 sirvaliance: What is the best way to "install" clojure?

13:44 ibdknox: leiningen ftw

13:44 Borkdude: sirvaliance: no, most people I know use lein(ingen)

13:44 sirvaliance: Ahhh

13:44 ibdknox: sirvaliance: https://github.com/technomancy/leiningen

13:44 sirvaliance: So I did it the wrong way by compiling and building the jar

13:44 TimMc: You don't really install it. It is pulled in as a dependency, and packaged with your code.

13:45 sirvaliance: Ok, I will install it and give it a rap

13:46 Borkdude: sirvaliance: it's nice to see that clojure is just a jar, so for the purpose of learning it might be good to experiment a bit from the command line

13:47 sirvaliance: but if you want to get up to speed and use other people's jar files, then leiningen is a lot easier

13:48 ibdknox: leiningen is easier just in general

13:48 Borkdude: ibdknox: yes

13:48 ibdknox: if you just want to try clojure, you could check out tryclj.com :)

13:48 Borkdude: ibdknox: I keep running into "can't copy this character into tryclj" issues ...

13:49 ibdknox: Borkdude: when you do what? (Raynes ^^)

13:49 Borkdude: ibdknox: for example when I want to insert a "

13:50 ibdknox: I use US International keyboard setting, it might be just that

13:50 ibdknox: wait, I'm saying it wrong. I can copy the chars, but just not type them in

13:50 ibdknox: weird

13:51 sounds like it might be a bug in the JQuery console implementation

13:51 Borkdude: I use US International to create characters like ë, which are common in Dutch

13:51 then I have to type " + e

13:52 so two keystrokes, the same for just a ", but maybe it handles this wrongly

13:52 sirvaliance: Hmm, so I like from reading the docs about lein. How do I install clojure from it?

13:52 ibdknox: I bet it intercepts keystrokes and freaks out

13:52 Borkdude: ibdknox: ah, yes, when I put it to another keyboard setting it just works

13:53 ibdknox: sirvaliance: instead of thinking of it as installing clojure, think of clojure as just a dependency of your app

13:53 Borkdude: sirvaliance: just make a dependency in your project.clj

13:53 ibdknox: sirvaliance: you just need clojure in the right place, the rest is magic

13:53 Borkdude: sirvaliance: or if you just want a repl, just type "lein repl"

13:53 ibdknox: it just downloads clojure right?

13:54 sirvaliance: Gotcha

13:54 Borkdude: ibdknox: it even asked if I wanted to install a JVM on my machine ;-)

13:54 ibdknox: Borkdude: more or less

13:54 sirvaliance: Oooo, I like lein repl

13:54 Borkdude: sirvaliance: what OS are you on, just curious

13:54 sirvaliance: Osx, could be linux but lately osx

13:55 jodaro: sirvaliance: one thing that i've depended on a lot is to create a "scratch" project to play around in when i want to make sure some stuff i do in the repl lives on

13:55 lein new scratch

13:55 cd scratch

13:55 and bam, you have a little playground

13:56 sirvaliance: Gotcha, doing that now

13:56 jodaro: put that action into source control and you'll never, ever forget how you did something again. ever.

13:57 Borkdude: sirvaliance: what is also cool, if you do lein swank, you can connect to it from... emacs! o wait... ;)

13:57 sirvaliance: I like how lein deps just downloads the clojure jar

13:57 Zing!

13:57 tmciver: What is the best way to gracefully exit a hung slime repl in emacs?

13:57 It's for a buddy of mine; he keeps writing infinite loops . . . idiot!

13:57 TimMc: haha

13:58 Borkdude: tmciver: I always start a swank session and connect to it using slime-connect, then you can just ctrl-c the swank session if things go wrong

13:58 tmciver: I've tried typing '.' (comma) followed by 'sayoonara'

13:58 sirvaliance: YEEESSSS, lein repl is awesome! I love that it has the JLine built in!

13:58 TimMc: tmciver: Does it work to kill the repl's buffer?

13:58 Borkdude: tmciver: happened to me also a lot, repl consuming infinite seqs :)

13:58 sirvaliance: So I am sold on clojure now

13:58 ideally_world: thank goodness for re-find

13:59 Borkdude: sirvaliance: that's quick

13:59 TimMc: sirvaliance: You *like* jline? Install rlwrap, which is much better, and lein will use it.

13:59 ideally_world: M-x clojure-jack-in is so much better :)

13:59 tmciver: TimMc: not sure, but it would be nice if I didn't have to start all over.

13:59 TimMc: Ah, you need a way to kill the current evaluation, got it.

13:59 tmciver: Borkdude: let me try the slime-connect method.

14:00 Borkdude: tmciver: you need to enter the project directory and type "lein swank"

14:00 TimMc: Borkdude: C-c with your method will kill the whole REPL, yeah?

14:00 tmciver: Borkdude: yup, thanks.

14:00 Borkdude: TimMc: yes

14:01 tmciver: :(

14:01 Borkdude: ideally_world: I tried clojure-jack-in but it doesn't work here...

14:02 ideally_world: follow technomancy's guide for getting emacs up and running

14:02 tmciver: So there's no way to cleanly break the repl out of an infinite loop?

14:02 ideally_world: I think it's starter-kit or something

14:03 Borkdude: ideally_world: error in process filter: clojure-eval-bootstrap-region: Search failed: "(run-hooks 'slime-load-hook) ; on port"

14:03 error in process filter: Search failed: "(run-hooks 'slime-load-hook) ; on port"

14:03

14:03 ideally_world: did that

14:03 TimMc: tmciver: M-x slime-interrupt?

14:03 tmciver: TimMc: trying . . .

14:03 ideally_world: leiningen has swank insgtalled?

14:03 Borkdude: ideally_world: let me see, should I type smth like "lein install swank" or?

14:03 ideally_world: Borkdude: have you ever gotten slime to work with leiningen? I.e. lein swank?

14:04 Borkdude: ideally_world: yes, doing that all the time

14:04 ideally_world: lein install plugin swank something

14:04 hmm

14:04 Borkdude: ideally_world: also I like this method, so I have full control over the swank server

14:04 (ctrl-c to be specific)

14:04 ideally_world: I got sick of lein swank and then slime-connect

14:05 tmciver: TimMc: Nope. Get an exception thrown by the swank server.

14:05 Oh well.

14:05 TimMc: hold on, let me see

14:06 ideally_world: not sure what that error meant, but it almost makes sense after diving into emacs today :)

14:07 sirvaliance: What is the best clojure/opengl lib, penumbra?

14:07 ideally_world: Borkdude, do you use lein swank or do you start swank so other way?

14:07 Borkdude: ideally_world: got it working now

14:07 ideally_world: Yay!

14:07 Borkdude: ideally_world: I always do "lein swank"

14:08 ideally_world: How did you fix it?

14:08 Borkdude: ideally_world: I think I needed to update swank-clojure

14:09 ideally_world: when I did M-x clojure-jack-in it seemed to compile a bunch of slime elisp files also in emacs...

14:09 ideally_world: ah, that makes some sense, I was under the impression that it wasn't installed...

14:09 sirvaliance: Any thoughts?

14:09 TimMc: Similarly, does anybody know how to interrupt a long-running evaluation in Leiningen's REPL?

14:09 (without killing the REPL)

14:09 Borkdude: now let me try an infinite loop

14:09 ideally_world: sirvaliance, no ideas, sorry

14:10 Borkdude: I typed (loop [] (recur)) now in the "jacked" REPL. How do I kill it?

14:11 My processor is warming up.

14:11 slime-interrupt doing nothing

14:11 ah wait, it does work

14:11 raek: C-c ?

14:12 Borkdude: but you have to type it in the repl buffer itself

14:12 why... , because you could have multiple running?

14:13 When I try another clojure-jack-in I get an error. But fair enough, this works ok for me. Clojure-jack-in!

14:14 sirvaliance: What is the preferred clojure web framework? Or the most popular?

14:14 ideally_world: :)

14:14 tmciver: Getting in to an infinite loop in the repl is a pain because you not only have to destroy your slime-repl but you have to kill the underlying Java process.

14:14 Borkdude: sirvaliance: Noir

14:14 ideally_world: sirvaliance, haven't tried anything, but noir sounds interesting

14:14 Borkdude: tmciver: slime-interrupt worked for me

14:14 sirvaliance: That is what google would like to think, didn't know if there were some that didn't have the google rank

14:14 tmciver: Borkdude: you can 'slime-connect' back into the existing swank server but you have to find its port number.

14:14 ideally_world: Borkdude, but do you still have a java process running in the backgroung some where?

14:15 Borkdude: sirvaliance: http://www.webnoir.org/

14:15 tmciver: Borkdude: really? Hmm, let me try again.

14:15 Borkdude: tmciver: hmm no

14:16 tmciver: let me see if there is one

14:16 sirvaliance: What is the difference between running something like "lein search noir" then "lein install" vs "lein plugin install noir" ?

14:17 Borkdude: tmciver: how I can discover an existing swank server and its port?

14:17 tmciver: Borkdude: probably not the best way but I've determine the swank session started from within emacs by trying to kill emacs; it then lists the existing running process asking you if you want to kill them first.

14:17 I don't know a better way yet.

14:18 ibdknox: sirvaliance: lein install will install your current project into a local cache

14:18 sirvaliance: Ohh

14:18 ibdknox: sirvaliance: lein plugin install will go get a jar from clojars and put it in leiningen's path

14:18 sirvaliance: allowing you to use it from leiningen's process

14:18 sirvaliance: Ie, from the repl?

14:19 ibdknox: sirvaliance: in lein-noir's case, it let's you run the noir command: lein noir new

14:19 raek: sirvaliance: no, from lein build tasks

14:20 sirvaliance: install library in other language == add to :dependencies in project.clj and run lein deps in clojure

14:20 Borkdude: ah, lsof -i | grep 'java.*LISTEN'

14:20 then I found the port and I could reconnect

14:20 tmciver: Borkdude: cool

14:20 sirvaliance: Ahh

14:22 * ideally_world bows to technomancy's wisdom and get used to M-n/p

14:22 sirvaliance: So, more annoying questions from me ;)

14:22 Is is possible to work through sicp with clojure?

14:22 ibdknox: sirvaliance: a few people have

14:22 sirvaliance: It has been staring at me from my bookshelf for way too long

14:23 Borkdude: sirvaliance: I found myself trying examples from common lisp, but things are so mutable in common lisp, it is sometimes not a direct translation

14:23 sirvaliance: for example, you can just do (setf (car my-list) 1) to change the head of a list

14:24 sirvaliance: I see.

14:24 Borkdude: sirvaliance: whereas in Clojure you always construct a new list

14:24 tmciver: Borkdude: Genius! That works.

14:24 sirvaliance: I was wondering that from briefly reading about clojure last night. Does that create memory issues?

14:25 tmciver: slime-interrupt worked for me that time.

14:25 ibdknox: sirvaliance: because of structural sharing, no

14:25 sirvaliance: Constantly reconstructing new lists

14:25 Borkdude: sirvaliance: clojure does this very efficiently

14:25 sirvaliance: Ohhh, so it snags pointers to gen the new list? (laymens understanding)

14:25 *layman?

14:25 Borkdude: sirvaliance: exactly

14:26 sirvaliance: Gotcha

14:26 That is pretty cool then

14:26 tmciver: Borkdude: that also kills the underlying Java process which I had to kill manually.

14:26 sirvaliance: I was wondering how that worked, seemed inefficient at first glance

14:26 :)

14:26 tmciver: TimMc: thanks to you as well!

14:27 ideally_world: sirvaliance, everything is imuttable so sharing between lists is cool, nothing will change :)

14:27 Borkdude: tmciver: sorry, killing? I lost track

14:28 I guess lein could keep track of this port and reconnect after a slime-interrupt?

14:29 eh slime

14:29 eh never mind

14:29 sirvaliance: So, just to clarify, lein install will install it in the local repo, lein plugin install will install it "globally" to lein? Right?

14:29 clojurebot: elein is https://github.com/remvee/elein

14:31 raek: sirvaliance: lein plugin install will install a leiningen plugin, this gives you new "lein ___" commands

14:31 sirvaliance: Oh

14:32 That clarifies it

14:32 raek: sirvaliance: and lein install will package the project you are working on and add it to your local repository (so that you can include is as a dependency from other projects)

14:32 tmciver: Borkdude: before when I killed the hung repl I would also have to go kill the Java process separately.

14:33 Borkdude: tmciver: and now?

14:33 tmciver: Borkdude: slime-interrupt seems to take care of it.

14:33 sirvaliance: raek: So if I run "lein search penumbra", then lein install, I can include it as a dependency for any of my projects, not just the local repo?

14:34 Wait I am missing something

14:34 TimMc: I'm wondering if it's actually Clojure's own REPL that is lacking "kill currenct evaluation" support.

14:34 raek: sirvaliance: no, you can always include it as a dependency

14:34 Borkdude: tmciver: when I do slime-interrupt, the java process is still there

14:35 sirvaliance: Ok, so lein install is to install the jar that I am currently working on. Once I run lein search x, it is cached and can be used?

14:35 tmciver: Uh oh, let me make sure.

14:35 raek: sirvaliance: when you find a library you are interested in, you add it to your project.clj and then run "lein deps"

14:35 sirvaliance: Ooooh

14:35 ok

14:35 Borkdude: tmciver: also I can reconnect to it

14:35 tmciver: Borkdude: does it take up 100% of cpu?

14:35 raek: after that it is available when you start a new repl

14:35 sirvaliance: raek: Thank you for the explaination. Probably saved me plenty of time figuring this out via trial and error

14:35 tmciver: Perhaps it's not the Java process that was running your infinite loop.

14:36 raek: sirvaliance: think of "lein install" as "make install"

14:36 sirvaliance: Ahhh, ok

14:37 raek: a certain version of a lib is downloaded and cached (added to the local repo) the first time you have a project that uses it as a dep and you run lein deps

14:37 sirvaliance: So when I run lein search penumbra, and get returned "org.clojars.dnolen/penumbra "0.5.0"", I can just add that to my project.clj depen list?

14:37 Borkdude: tmciver: hmm. let me try this again. I'll kill all java processes first.

14:38 sirvaliance: Then run lein deps?

14:38 raek: sirvaliance: exactly

14:38 you add [org.clojars.dnolen/penumbra "0.5.0"] to the vector

14:38 sirvaliance: Got it

14:39 Borkdude: tmciver: ok only one java process now, resulted from clojure-jack-in

14:39 tmciver: this thing is listening on 64697. now let me do an infinite loop

14:40 tmciver: Borkdude: it does seem to do the right thing.

14:40 sirvaliance: raek: So lein install would make sense if I wanted to install from source in most cases, right?

14:40 Borkdude: tmciver: now I got a java process taking 100% cpu.

14:40 tmciver: pid is 11839. same as the one which is listening at the port I mentioned

14:41 tmciver: now I will do a slime-interrupt. Thread Death message

14:41 tmciver: still there is a java process listening, let me try to reconnect...

14:41 raek: sirvaliance: yes. you don't do that very often though (except for when you want to fix a bug in someone else's project and use the fixed version right away)

14:42 Borkdude: tmciver: reconnecting worked. I'm slightly confused about what happened though.

14:42 every operation from the repl gets its own thread which can be killed or what?

14:42 tmciver: Borkdude: Ahh, I think it is I who am confused. I'm looking at output from top. I guess the Java process isn't killed; it's just not at 100% anymore.

14:43 Borkdude: tmciver: to be sure I used this loop: (loop [] (+ 1 2 3) (recur))

14:43 tmciver: Borkdude: doing slime-interrupt doesn't kill my repl . . . no need to reconnect.

14:43 Borkdude: tmciver: it will be 99% cpu at my machine

14:44 tmciver: Borkdude: I think it makes sense to me now. No Java process is killed nor needs to be killed.

14:44 Borkdude: tmciver: wait, slime-interrupt just kills what is running, and then returns to the repl, indeed. nice

14:45 tmciver: Borkdude: yes, does exactly what I wanted. Thanks again.

14:45 Borkdude: so, every expression is executed in a thread which gets killed by slime-interrupt I guess?

14:45 tmciver: thanks to you, I have learned this also just now

14:45 tmciver: Borkdude: actually, it was TimMc who initially suggested it. Thanks!

14:46 Borkdude: TimMc: yeah, tnx :)

14:46 TimMc: np, stumbled across it while looking for something else

14:47 sirvaliance: Can I run a clojure script through the lein repl command?

14:47 Or, how can I run a clojure script with out java comp.

14:47 TimMc: tmciver: Wait, so slime-interrupt lers you stop the current command and continue with your coding?

14:48 technomancy: sirvaliance: try "lein help run" and also "lein help tutorial"

14:48 TimMc: you still have all your defs?

14:48 Borkdude: sirvaliance: you can do loaf-file I guess? http://clojure.org/evaluation

14:48 load-file

14:48 sirvaliance: but just do what technomancy tells you

14:49 TimMc: always a good move

14:49 * ideally_world nods

14:50 tmciver: TimMc: yes

14:50 TimMc: sweet

14:50 Imma start using lein swank instead of lein repl.

14:50 Borkdude: TimMc: he doesn't use emacs

14:50 tmciver: TimMc: Oh yee-ah boi!

14:51 Borkdude: sirvaliance: (I learned emacs just because of Clojure..)

14:52 sirvaliance: (and still learning...)

15:10 jcromartie: I don't remember when I started learning Emacs, but it might have been for clojure. I know I did more Lua than anything else at first, and then started using it for pretty much everything but Objective-C and C#.

15:20 OMFG

15:20 sirvaliance: So in your project.clj file, do you define the main function?

15:20 jcromartie: a coworker asked me some question in chat, and I responded with this image link http://imgur.com/gallery/NgkfY

15:21 and he told customer service to forward it to the client as an answer to their issue

15:21 I mean jesus christ

15:21 sorry for the OT but I am losing it here

15:21 terom: ouch...

15:22 TimMc: jcromartie: At least you're not in the line of fire if that goes badly, yeah?

15:23 Borkdude: If I were that customer I would lmao

15:23 TimMc: sirvaliance: you define the main class: ":main foo.core"

15:23 jcromartie: no, I'm not in the line of fire

15:24 TimMc: That's pretty wild.

15:27 sirvaliance: Gotcha

15:36 Borkdude: What is the recommended way to reconnect to freenode and get back to #clojure after a disconnect, just M-x erc again?

15:48 fdaoud: clojurebot: haskell

15:48 clojurebot: "you have to see features like that in the context of Haskell's community, which is something like Perl's community in the garden of Eden: detached from all shame or need to do any work." -- ayrnieu

15:49 fdaoud: clojurebot: ML

15:49 clojurebot: XmL is like violence; if it doesn't solve your problems, you're not using enough of it.

15:49 fdaoud: clojurebot: OCaml

15:49 clojurebot: No entiendo

15:49 fdaoud: clojurebot: F#

15:49 clojurebot: Excuse me?

15:49 fdaoud: clojurebot: Miranda

15:49 clojurebot: I don't understand.

15:49 fdaoud: clojurebot: haskell

15:49 clojurebot: "you have to see features like that in the context of Haskell's community, which is something like Perl's community in the garden of Eden: detached from all shame or need to do any work." -- ayrnieu

15:50 amalloy: *polite cough* you can /msg clojurebot if there's no reason to make this interrogation public

15:50 fdaoud: amalloy: didn't know; noted; apologies.

15:50 Borkdude: I like his opinion on Haskell though

15:51 amalloy: he's more opinionated and less subtle about python

15:53 Borkdude: Is there a substantial part of Clojure programmers coming from Python, like is the case with Ruby and why (not)?

15:54 cemerick: ok, gotta do it

15:54 clojurebot: survey is http://cemerick.com/2011/07/11/results-of-the-2011-state-of-clojure-survey/

15:54 clojurebot: In Ordnung

15:54 cemerick: ~survey

15:54 clojurebot: survey is http://cemerick.com/2011/07/11/results-of-the-2011-state-of-clojure-survey/

15:54 cemerick: Borkdude: ^

15:55 hiredman: https://www.facebook.com/notes/facebook-engineering/the-hiphop-virtual-machine/10150415177928920 you have to wonder why they don't just adopt the php on the jvm thing

15:55 cemerick: That's sort of a stupid ~ command for that :-/

15:55 * cemerick can never remember the clojurebot syntaxi

15:55 hiredman: clojurebot: where is the survey?

15:55 clojurebot: survey is http://cemerick.com/2011/07/11/results-of-the-2011-state-of-clojure-survey/

15:56 cemerick: sure; but there's some |is| thing for defining new stuff, right?

15:56 Borkdude: cemerick: hehe

15:56 nice, equal part almost

15:57 TimMc: cemerick: Yeah, you can put pipes around the verb or whatever.

15:57 Borkdude: and no GW Basic..

15:57 hiredman: if you want to define the relationship between the left hand side and the right hand side to be something besides is, you can use lhs | relationship | rhs

15:57 and the pipes are required when deleting

15:57 TimMc: and a <reply> after the |relationship| to have clojurebot only respond with the rhs

15:58 hiredman: I can't seem to delete the Chouser/namespaces factoid (to fix some typos and stuff)

15:58 I was able to delete some spurious factoids that were getting irritating, but that one wouldn't die.

15:59 ~namespaces

15:59 clojurebot: namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

16:00 TimMc: I tried both the "are" and the "is".

16:00 Borkdude: It is interesting to see that only 2% came from Haskell but if clojure disappeared 36% would choose Haskell next

16:01 although they could choose more than one

16:02 TimMc: Hrmf, I think hiredman has me on /ignore -- he hasn't responded to anything I've said to him in the last 2 months or so.

16:03 amalloy: TimMc: his parser doesn't work very well if there's an "is" partway through the statement in my experience

16:03 TimMc: amalloy: Even if there's explicit ||?

16:03 amalloy: yes

16:03 TimMc: ugh

16:10 goodieboy: is there a function like select-keys but instead of returning a new hash-map, it returns the values of the specified keys?

16:10 cemerick: ,((juxt :foo :bar) {:foo 5 :bar 6})

16:10 clojurebot: [5 6]

16:10 goodieboy: ahh right! thanks

16:11 amalloy: welllll, i'm a big fan of juxt, but this only works if the keys are keywords

16:11 Raynes: You're nuts for juxt.

16:11 amalloy: &(map {:foo 5 :bar 6 :baz 7} [:bar :foo]) ;; works in general

16:11 lazybot: ⇒ (6 5)

16:12 Raynes: cemerick: I didn't realize until after I tweeted about your ideas that I might have put you on the spot (re: the apidocish stuff you plan to add to marginalia at some point).

16:12 If you don't do it, I will, just so you don't feel bad.

16:12 goodieboy: amalloy: ahh yep, makes sense

16:12 Somelauw: clojurebot: arc

16:12 clojurebot: POLO! nya nya you can't see me

16:12 Somelauw: I don't get the joke?

16:14 rmarianski: clojurebot: marco?

16:14 clojurebot: POLO! nya nya you can't see me

16:14 cemerick: Raynes: I blame you for all my ideas. ;-)

16:14 I will add some things to either marg or story, but I can't imagine working on both. I'm hardly married to marg.

16:14 Raynes: Story is a bit of a mess.

16:15 cemerick: I figure I'll get around to it soonish. Probably not this year. "Before Clojure/west" seems like a good, safe timeframe. :-P

16:15 Raynes: Heh

16:15 Do it *at* ClojureWest. With Fogus. I'm sure he'll be there.

16:15 cemerick: I'm shaving enough yaks around tooling at the moment to keep my spare moments busy.

16:16 Somelauw: I don't get the marco polo joke

16:16 cemerick: I don't get the impression that either is a pinnacle of clean design. The domain sort of forces a hack-and-slash approach.

16:17 `fogus: cemerick: If I increase the dowry, would you consider marrying Marg?

16:18 cemerick: Gosh, I didn't know dowries were around still. I'll have to ask my wife where hers is. :-P

16:19 "I've got a nice offer from this cute named Marg."

16:19 `fogus: :p

16:19 cemerick: `fogus: honestly, I suspect I'd make a hash of either marginalia or story, insofar as I'd probably run roughshod over various literate programming idioms I've no awareness of.

16:20 `fogus: I hope I can make it to Clojure/West... regardless of the Marg marrying situation

16:20 cemerick: I'd have to come up with a new proposal. The well is dry at the moment, it seems.

16:20 Raynes: `fogus: The ideas we're talking about are some kind of accordion-style list of vars that anchor to the vars themselves. Among other things, but that's my favorite part of it. It would make marginalia autodocish enough to be useful for API documentation while sticking to what Marginalia is and always will be good at: kinda-sorta-literate programming.

16:21 ilyak: I'm getting a very strange behavior in clojure

16:21 hiredman: Vars: What The Hell?

16:21 `fogus: I haven't looked at story. Is it more LP?

16:21 * dnolen hopes he can make it to Clojure/West as well, especially if Oleg Kiselyov is going to be there

16:21 hiredman: cemerick: -^ there's your talk

16:21 Raynes: I want to and would work on that myself, but web design makes me want to kill myself.

16:21 ilyak: if I do (some-fn [calculate-int calculate-int]) I get (some-fn nil) called

16:21 Raynes: `fogus: http://jedahu.github.com/story/

16:22 ilyak: but when I do (let [tuple [calculate-int calculate-int]] (some-fn tuple)) it's okay

16:22 cemerick: hiredman: what, running roughshod over other people's work? Just another day at the shop.

16:22 ilyak: What am not I getting?

16:22 `fogus: Oh, so it's comment based too?

16:22 hiredman: cemerick: Vars: What The Hell?

16:22 cemerick: ah

16:22 Raynes: `fogus: The outlines are what we'd like to see in marginalia. And it can actually work with the side-by-side if we can collapse things.

16:22 cemerick: And asciidoc. Don't forget about asciidoc. :-P

16:23 hiredman: too long for a lightening talk, might be a little short for a full talk

16:23 ilyak: I also have a problem: Color.getRGB returns int

16:23 which is perhaps less than zero

16:23 Raynes: Story looks for single-semi-colon comments and not double semi-colons. The author uses Vim and thus the comments in the application are all indented weird and stuff, so I'm not sure if this would even work properly on my own projects.

16:23 ilyak: clojure immediately promotes it to Long

16:24 and then it can't call BufferedImage.setRGB

16:24 How would I make it not do that?

16:25 Oops, I might be interpreting it incorrectly

16:25 cemerick: ilyak: coerce it via (int rgb-value) http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics

16:25 hiredman: Yeah, maybe I should go angsty.

16:25 ilyak: disregard that

16:26 cemerick: "What sucks about Clojure and why you'll love it anyway."

16:26 `fogus: I'm working on a tool called trout that is the next step above Marg... it's source files look like https://gist.github.com/1453362.

16:27 Raynes: I don't think I'm into that level of literate programming.

16:27 I like marg style.

16:27 hiredman: oh, no, how I imagine the talk it would be sort of an examination of vars, some use cases, pitfalls, maybe some javap output

16:27 `fogus: Raynes: So do I. :-) For most libs

16:28 hiredman: things you can run into if you do runtime conditional loading of namespaces but expect the compiler to resolve vars for you

16:28 static vs. dynamic vs. the now default non-dynamic vars

16:29 `fogus: I see autodoc -> API consumers. marg -> code readers. story -> masochists. trout -> sadists... errrr writers

16:29 TimMc: cemerick: I could go for angsty 'round 'bout now.

16:30 `fogus: Alright gentepersons. I need to run.

16:30 cemerick: `fogus: I don't think there's much to distinguish the former two, esp. when the source is the only documentation in certain corners.

16:30 oh well.

16:31 Raynes: With a little tweaking, marginalia can serve much of the purpose that autodoc serves.

16:32 cemerick: hiredman: Sounds like you've written half of your proposal ;-)

16:32 hiredman: but I don't want to

16:36 cemerick: I feel pretty talked-out on foundational stuff.

16:36 Makes me shudder to think of what the training grind is like.

16:36 pjstadig: hiredman: let's present together

16:36 we'll tag team

16:36 hiredman: to my knowledge no one talks about vars

16:37 technomancy: I submitted a talk on vars to last year's Conj, but for some reason they wanted me to speak on Leiningen.

16:37 Raynes: technomancy: Can't imagine why.

16:37 hiredman: "for some reason"

16:37 pjstadig: hiredman: no one talks about atoms either

16:37 LHC

16:38 hiredman: well, atoms don't come in the same variety as vars

16:38 * pjstadig opens a jira ticket for dynamic/static atoms

16:39 hiredman: yes! we need threadlocal stack compare and swaps! like atoms in javascript!

16:39 clojurescript

16:39 pjstadig: technomancy: you should submit a talk titled "For: it's not a loop"

16:39 technomancy: not bad

16:42 Raynes: technomancy: Aren't you supporting my path fixing method somewhere in the clojure-mode or swank-clojure docs?

16:43 If so, stop. It's nuts. Didn't work after I upgraded to Emacs 24 and after I actually looked at what it did, nuts. https://github.com/Raynes/dotfiles/blob/master/.emacs.d/init.el#L76 is better.

16:44 sdeobald: Hey.

16:44 * sdeobald waves

16:50 technomancy: Raynes: not sure which fix you're talking about

16:52 Raynes: technomancy: Looks like you've got another method for fixing it in the swank-clojure readme. Nevermind.

17:02 ilyak: zipmap sucks

17:02 I wonder why doesn't clojure have a solid collection stream operations out of box

17:02 zip, zip-with, map-entries, group-by, all of that stuff

17:03 hiredman: what do you mean?

17:03 amalloy: hahaha

17:03 clojure doesn't have good lazy-sequence operations. good times

17:03 ~zip

17:03 clojurebot: zip is not necessary in clojure, because map can walk over multiple sequences, acting as a zipWith. For example, (map list '(1 2 3) '(a b c)) yields ((1 a) (2 b) (3 c))

17:06 tscheibl: damn... if I had read the "map" docs more carefully this would have spared me some "reduce"

17:08 technomancy: map/reduce map/reuse map/recycle

17:09 boodle: Hiya how to I add a backslash to a space? This won't work: (.replaceAll "Add a backslash in between teh spaces" " " "\ ")

17:09 s/to/do/

17:09 tscheibl: actually I meant it would have spared me some "loop recur" constructs

17:10 dnolen: ,(.replaceAll "Add a backslash in between teh spaces" " " "\ ")

17:10 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unsupported escape character: \ >

17:10 dnolen: ,(.replaceAll "Add a backslash in between teh spaces" " " "\\ ")

17:10 clojurebot: "Add a backslash in between teh spaces"

17:10 boodle: lol what I'm seeing

17:10 dnolen: ,(.replaceAll "Add a backslash in between teh spaces" " " "\\\\ ")

17:10 clojurebot: "Add\\ a\\ backslash\\ in\\ between\\ teh\\ spaces"

17:10 Somelauw: How to iterate from 2 to infinity? (take 2 (range)). There is always a neither way that write it and one should not get obsesses with finding the neatest way to write something I think.

17:10 dnolen: ,(.replaceAll "Add a backslash in between teh spaces" " " "\\\ ")

17:10 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unsupported escape character: \ >

17:11 amalloy: ,(iterate inc 2)

17:11 clojurebot: (2 3 4 5 6 ...)

17:11 dnolen: (println (.replaceAll "Add a backslash in between teh spaces" " " "\\\\ "))

17:11 ,(println (.replaceAll "Add a backslash in between teh spaces" " " "\\\\ "))

17:11 clojurebot: Add\ a\ backslash\ in\ between\ teh\ spaces

17:11 dnolen: boodle: ^

17:11 boodle: dnolen: oooh ty :)

17:12 dnolen: boodle: you'll see \\\\ in the string, but it prints correctly.

17:12 boodle: dnolen: trying to escape a filename in noir with a post-route filter (I hope)

17:12 amalloy: dnolen: surely just see \\

17:13 dnolen: ,(.replaceAll "Add a backslash in between teh spaces" " " "\\\\ ")

17:13 clojurebot: "Add\\ a\\ backslash\\ in\\ between\\ teh\\ spaces"

17:13 dnolen: amalloy: oh yeah sorry

17:14 boodle: I read somewhere how clojure's regexp engine's changed (since early days) so dunno if a side effect

17:14 amalloy: i'd be pretty surprised if clojure ever had a regex engine

17:14 boodle: based on docs, seems "\\" should be enough (per java's)

17:15 1.3 btw

17:15 dnolen: boodle: yeah clojure regexp's are just java regexp, so it hasn't really changed at all.

17:15 boodle: was referring to this: http://items.sjbach.com/406/clojures-new-regex-syntax

17:16 amalloy: boodle: that's reader syntax, not the engine; and you weren't typing regexes, you were typing strings which java later chooses to interpret as regexes

17:17 boodle: amalloy: ok. is this worthy of a bug report? and I guess more java's than clojure's

17:17 amalloy: no, it is not a bug

17:18 boodle: amalloy: so 4 backslashes give the correct behavior for 1 slash in front of each space?

17:18 amalloy: it's just a failure to understand the three levels of quoting/escaping that are happening in your example

17:19 dnolen: boodle: heh yes, 2008 early days that. Matt Might and Peter Seibel on that thread.

17:19 comment thread.

17:20 TimMc: boodle: Welcome to the Leaning Toothpicks.

17:20 boodle: heh ty :)

17:21 TimMc: Using Clojure's regexp reader syntax helps.

17:21 ...but not with the replacement expression I guess.

17:22 asavu: hi guys! can someone explain this http://pastie.org/2993365 to me?

17:22 boodle: TimMc: That's what I found.. great for pulling out matches but would be sorta 'manual' for replacement… course I could just roll my own..

17:23 amalloy: asavu: pretend hashmaps and arraymaps are the same thing. if you care about the difference you're usually doing something wrong

17:23 TimMc: asavu: Clojure changes implementations under the hood for performance reasons. Ignore the man behind the curtain.

17:24 asavu: amalloy: TimMc thanks! that a was a bit unexpected

17:26 TimMc: &(map map? [(array-map) (hash-map) (sorted-map)])

17:26 lazybot: ⇒ (true true true)

17:27 asavu: it seems like the conversion happens if a map has >= 10 elements

17:28 I was trying to use this to find the distinct elements from a sequence but maintain the initial order

17:29 hiredman: (doc distinct)

17:29 clojurebot: "([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"

17:29 asavu: hiredman: yeah, I know but without using distinct

17:30 hiredman: ~soure distinct

17:30 clojurebot: It's greek to me.

17:30 hiredman: ~soucre distinct

17:30 clojurebot: excusez-moi

17:30 hiredman: ~source distinct

17:30 amalloy: haha

17:30 hiredman: clojurebot: do as I say

17:30 clojurebot: Excuse me?

17:31 asavu: hiredman: thanks! I was trying to avoid that - still learning clojure

17:31 amalloy: asavu: maps are fundamentally un-ordered. array-maps happen to preserve an order, sorta, but you should never depend on it. if you need something ordered, you don't want a map. (ignoring here sorted-map, which is a different kind of sorting)

17:31 hiredman: then you should be reading code

17:32 asavu: amalloy: I know but the behaviour is unexpected. I think an array-map should be handled as a sorted-map

17:32 dnolen: asavu: I'm surprised array-map is public, but you want sorted-map anyhow.

17:32 amalloy: i don't understand your suggestion but i'm fairly sure it's not a good idea

17:33 dnolen: asavu: actually looking at your paste - probably sorted-set

17:34 asavu: dnolen: nope, sorted by initial position not by value

17:34 hiredman: or, do what distinct does

17:34 being new to clojure, avoiding reading code is dumb

17:34 asavu: amalloy: a sorted-map remains sorted over multiple insertions (doesn't become a hash-map) - I think the same should happen for array-map

17:35 hiredman: I am solving things on 4clojure - reading code without trying is like cheating

17:35 amalloy: absolutely not. array-map is just an optimization for small hash-maps

17:35 asavu: amalloy: so why not hide the array-map completely? why a public api?

17:35 dnolen: asavu: array-map is not something you should ever use directly.

17:35 hiredman: asavu: what is better, to make up some horrible solution for 4clojure without reading good code, or reading good code and learning something?

17:35 duck1123: if you simply use the java methods, do they still auto upgrade?

17:36 dnolen: asavu: it probably shouldn't be public, it's been around for a long time, pre 1.0

17:36 amalloy: asavu: you should do whatever causes you to learn best. we didn't put 4clojure there as a competition, it's there as a learning tool

17:36 if reading code in core helps you understand (and often it will), you should do that. if you prefer to challenge yourself to reinvent everything from scratch, then go ahead

17:37 but i think a certain core level of competency is necessary before that becomes a fun/useful challenge

17:37 asavu: amalloy: I do that but as the last resort not after 5 minutes of trying

17:37 amalloy: and btw I have learned something new about array-map by asking, thanks!

17:37 jgrimes: Is there a way to get the protocol a function is for?

17:39 amalloy: jgrimes: for a function in general: no. if you have the var, then yes

17:39 asavu: hiredman: I would say both - first try and as a last resort or after finding a solution read existing code. thanks for info!

17:40 dnolen: jgrimes: look at the metadata of the protocol fn var

17:40 (defprotocol IFoo (bar [this])) (meta #'bar)

17:40 jgrimes: ^

17:42 jgrimes: dnolen: awesome thanks

17:42 hiredman: asavu: if you want to learn clojure, reading core.clj and writing code is the best way, I doubt solving problems on 4clojure will get you very far

17:43 asavu: hiredman: don't worry, this is not the only thing I do :)

17:49 jodaro: http://nakkaya.com/2009/11/16/java-native-access-from-clojure/

17:49 that rules

18:37 hiredman: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java <-- it is funny how the javadoc mentions rest

18:37 amalloy: hiredman: clojure.core doesn't always have javadoc; but when it does, it's drastically out of date

18:38 well, clojure.lang i guess

18:39 https://github.com/clojure/clojure/commit/b8e333fb3437dca760f16136ed074a4dd463fe35#diff-19 is the commit that got it out of date, if anyone cares

18:42 hiredman: also, the file is full of \r\n

18:45 sirvaliance: I have another dumb question for the room. I am about to start learning clojure though sicp. What would be the best way to structure my repository?

18:45 Could I have each chapter be a .clj file?

18:52 amalloy: hiredman: a sign of real quality design

19:07 dnolen: sirvaliance: I would not study SICP w/ Clojure.

19:07 sirvaliance: dnolen: Why so?

19:07 dnolen: sirvaliance: Scheme is just too different from Clojure, IMO

19:08 sirvaliance: Hmm

19:09 dnolen: sirvaliance: which isn't to discourage studying SICP at all. just that I don't think that it's a great way to learn Clojure.

19:09 sirvaliance: I was trying to kill two birds with one stone

19:11 dnolen: sirvaliance: people seems to like doing it - but I think you'll just end missing the point of Clojure.

19:11 sirvaliance: And what point would I miss?

19:13 dnolen: a few: real function polymorphism (big), non-mutable locals, persistent data structures, good concurrency tools

19:16 sirvaliance: dnolen: Have you gone through sicp? What repl would you recommend? I am liking gambit scheme, others say just use mit-scheme, but I don't like how the repl doesn't have history

19:17 dnolen: sirvaliance: I used mit-scheme, didn't really care for it. I started using Petite Chez Scheme and that's pretty nice.

19:18 * sirvaliance googles petite chez scheme

19:18 dnolen: I like Racket, but when you're trying to use r5rs and r6rs there are some annoynaces

19:21 rickmode: dnolen: So Racket doesn't have a Scheme flavor that works well with SICP?

19:23 dnolen: rickmode: sorry Racket works just great for SICP, but there some impedance between features you want to use from Racket in r5rs or r6rs if you're playing around.

19:24 one issue I ran into is that Racket cons is purely functional, and Scheme cons isn't. Again if your only working on SICP not much of an issue.

19:25 sirvaliance: I've gone through the first 3 chapters and some of the 4th. SICP is a *lot* of work, if you want to learn Clojure, just learn Clojure :)

19:32 sirvaliance: Yeah, that is probably a good poit

19:32 point

19:35 dnolen: Over how long of a period of time do you think you spent on sicp

21:33 TimMc: $findfn '+ `+

21:33 lazybot: []

21:35 clizzin: anyone used incanter and know what the equivalent to R's reshape is?

22:35 amalloy: clizzin: just looked up reshape, and it's not easy to understand. if you actually explained what reshape does, you'd broaden your respondent base from "people who use R and clojure" to "people who use clojure"

22:39 clizzin: amalloy: for my use case, reshape lets you specify a column whose values then become new columns on the dataset. this is most useful when you have a dataset with columns "user_id", "month", "page views". if i then reshape with idvar="user_id" and timevar="month", i'll get a dataset with columns "user_id", "month0", "month1", etc., where the value for each month column is the associated "page views" value.

22:41 so instead of [[:user-id :month :page-views], [1 "Jan" 4], [1 "Feb" 10], [2 "Jan" 20]], i'd get [[:user-id :month-Jan :month-Feb] [1 4 10] [2 20 nil]]

22:45 TimMc: clizzin: Interesting, not at all what it sounded like.

22:46 clizzin: TimMc: well, i have limited exposure to the r function, so this might only be one use case of reshape (parameterized by direction="wide"). i'm just trying to see if i can reproduce with clojure/incanter something a friend did in R.

22:48 sorry, in the example above, the column names after reshaping should be [:user-id :page-views-Jan :page-views-Feb]

22:49 TimMc: alexbaranosky: Fn names are now linking: http://www.brainonfire.net/files/seqs-and-colls/main.html (any thoughts on licensing?)

22:50 alexbaranosky: TimMc, high five

22:50 TiMc: no preference licensing-wise

22:50 clizzin: so input [[:user-id :month :page-views], [1 "Jan" 4], [1 "Feb" 10], [2 "Jan" 20]], i'd get [[:user-id :month-Jan :month-Feb] [1 4 10] [2 20 nil]] => output [:user-id :page-views-Jan :page-views-Feb] [1 4 10] [2 20 nil]]

22:51 alexbaranosky: TimMc, gotta run

23:16 zackmaril: Hey is github down for anybody else?

Logging service provided by n01se.net