#clojure log - Aug 27 2012

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

0:58 Sgeo: So, is my unamb too dangerous to use due to possible uncollectable garbage creation?

0:58 (The creation of unstoppable infinite looping threads)

1:06 wmealing_: Sgeo: when you say it like that.. it sounds like an evil creation.. just saying

1:07 all that is missing is maniacal laughter

1:18 gzmask: Hey folks, I got a question about overtone: why the saw function in the tutorial has three parameters? I checked odoc and it only requires one. Code: https://github.com/overtone/overtone/blob/master/src/overtone/examples/getting_started/basic.clj#L9

1:53 emezeske: gzmask: That's one one parameter -- it's a vector of length three

1:53 gzmask: From looking at that code, I'd guess that each entry in the vector will produce an additional saw wave

1:53 gzmask: It's pretty common to stack multiple detuned saws to get a "fat" sound

2:09 Sgeo: ClojureScript doesn't have promises?

2:10 wmealing_: empty, empty promises

2:13 emezeske: Sgeo: Javascript is single threaded, so a lot of Clojure's concurrency primitives don't make much sense. Although I guess they could be implemented in some kind of async way.

2:14 Sgeo: Promises strictly speaking don't need threading, although they might be not as useful without it

2:14 Although, doesn't a lot of Javascript library stuff do things that take callbacks?

2:18 Hmm, might not be useful without threading even there

2:18 emezeske: Tons of callbacks, everywhere.

2:19 But I don't know how you'd implement a promise in Javascript -- you can't really do coroutines like that, AFAIK

2:19 Maybe if there was a Thread/yield function or something that let the event loop run

2:21 But, JS doesn't have a yield function. If it did, there could be a lot less callback soup

2:21 Sgeo: It's not a question of implemeting them, it's a question of using them usefully.

2:21 A promise could be as simple as a mutable container that contains either no value or a value.

2:22 deliver sets the value if there is no value

2:22 emezeske: I'm pretty sure that's not what a promise is in clojure.

2:23 Sgeo: Although then what would deref do if there is no value... "blocking" would not be ... helpful

2:23 emezeske: It's totally pointless, you can't do that in JS

2:23 Sgeo: emezeske, hmm?

2:23 (The "hmm" as to "not what a promise is")

2:24 emezeske: I was saying that a promise as just a "mutable container that contains eithe rno value or a value" is not what a promise is in Clojure

2:24 The key feature of a promise in Clojure is that it "Calls to deref/@ prior to delivery will

2:24 block"

2:24 Which you can't do in JS, so it's pointless.

2:25 Sgeo: Hmm... I'm sure someone has written continuation stuff for Clojure, that should be portable to ClojureScript right?

2:27 emezeske: The closest thing I know of to continuation passing in Clojure is trampoline

2:28 Which should work fine in ClojureScript

2:28 amalloy: $google clojure delimc

2:28 lazybot: [swannodette/delimc · GitHub] https://github.com/swannodette/delimc

2:30 emezeske: Neato!

2:30 amalloy: do cljs atoms support watchers? if so you can build promise on top of that

2:30 ibdknox: amalloy: yes

2:30 emezeske: amalloy: How would that work?

2:31 amalloy: emezeske: actually, i think the thing i was thinking of uses promises to get blocking, so not really a viable implementation strategy for getting promises

2:31 ibdknox: you can't do it without code-rewriting

2:32 emezeske: amalloy: Yeah, the blocking-until-available part is what kills promises for the JS target

2:32 amalloy: Even if you made deref just poll, you'd be tying up the only thread

2:32 ibdknox: you need a CPS transformer :)

2:32 emezeske: ibdknox: Yeah, it would have to turn your code into continuations behind the scenes

2:32 ibdknox: that's how the C# async stuff was done

2:32 amalloy: emezeske: presumably we've made an ajax call that's set to call something when it's completed? i don't do a lot of js, but i thought that's what people did?

2:33 emezeske: amalloy: Yeah, but if you made that async ajax call and then, e.g. went into an infinite loop, you'd never get the result

2:33 amalloy: There's no preempting, nor yield

2:33 amalloy: for what it's worth, i was thinking of https://github.com/flatland/useful/blob/develop/src/useful/state.clj#L53, which lets you block until a reference's value satisfies some condition: (wait-until evel? my-atom)

2:34 even?

2:35 emezeske: So desu

2:36 Hey, it's meta-circular. Just use promises to implement themselves, QED.

2:37 If only clojure was a native browser language...

2:37 Or really anything less stupid than JavaScript

2:38 Sgeo: Dart?

2:38 * Sgeo is suddenly thinking about NaCl

2:38 tomoj: I think it shouldn't be too hard to port lamina's async macro to cljs

2:39 but I feel like future seqs (better channels) are more important anyway

2:39 emezeske: Sgeo: Heh, NaCl running a java vm running clojure? Hell yeah.

2:39 Yo dawg...

2:41 Sgeo: "Why is it so bad with many threads you might wonder. Well, first of all they are expensive, both in the JVM and on .NET."

2:41 :/

2:41 Haskell has rather lightweight threading

2:42 emezeske: Java threading may not be the lightest weight thing ever, but I think quite a few shops get by with ridiculous numbers of threads

2:43 Anyway, pooling often makes more sense anyway. Even greenlets have some overhead.

2:49 nkkarthik: In lein2 project.clj, how can I include some jars in the lib folder?

2:51 amalloy: ~repeataibility

2:51 wmealing_: i used lein-localrepo

2:51 clojurebot: Titim gan ?ir? ort.

2:51 amalloy: ~repeatability

2:51 clojurebot: repeatability is crucial for builds, see https://github.com/technomancy/leiningen/wiki/Repeatability

2:51 wmealing_: but i a agree with amalloy

2:51 you'll get less suck if you make it work.. ie publish your jars

2:52 amalloy: don't agree with me, that's technomancy's article. i mean, i basically agree with it, but even if you disagree you should read: iirc it includes workarounds, as well as an explanation of why you shouldn't use them

2:55 Sgeo: Workarounds?

2:55 nkkarthik: wmealing_, amalloy... thank you... so there is only the holy approach

2:56 Sgeo: I take it things like Smalltalk and certain Common Lisp implementations are poisonous?

2:56 wmealing_: Sgeo: localrepo,

2:57 Sgeo: iirc SBCL was forked from CMU CL in order to have a cleaner build process

2:57 wmealing_: is it easy to run your own .. clojars ?

2:57 nkkarthik: what's the harm in quickly testing out a jar?

2:58 why have a repl then... repl is neither used in build or production

3:00 I think, tool should allow good practices not mandate them with one holy approach

3:00 but I might be wrong

3:00 anyways thank you guys... and sorry if I have said something wrong out of ignorance

3:01 I will look at the localrepo

3:09 emezeske: nkkarthik: I gather that :extra-classpath-dirs was something of a pain from a support perspective /speculation

3:11 nkkarthik: emezeske: oh... you mean for lein developers or extra-classpath-dirs users?

3:12 devn: ,(require '[clojure.pprint :as pp])

3:12 clojurebot: nil

3:12 emezeske: nkkarthik: For developers.

3:12 Pure speculation on my part, though.

3:13 nkkarthik: emezeske: oh ok

3:13 devn: (with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (^:once fn* [x] x)] [(f 1) (f 2)])")))

3:14 ,(with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (^:once fn* [x] x)] [(f 1) (f 2)])")))

3:14 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

3:14 devn: ,(with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (^:once fn* [x] x)] [(f 1) (f 2)])"))))

3:14 Sgeo: Why are macros not allowed in the sandbox?

3:14 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>

3:14 nkkarthik: emezeske: thank you... I will try out something else then

3:14 hyPiRion: Sgeo: Macros are allowed, but defs aren't

3:14 Sgeo: &(defmacr sg-macro [])

3:14 lazybot: java.lang.RuntimeException: Unable to resolve symbol: defmacr in this context

3:14 Sgeo: &(defmacro sg-macro [])

3:14 lazybot: java.lang.SecurityException: You tripped the alarm! def is bad!

3:14 hyPiRion: afaik

3:14 Sgeo: Oh

3:15 devn: can anyone help me figure out the above mystery

3:15 Is it complaining about the (^:once...)

3:15 hyPiRion: ,(with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (fn* [x] x)] [(f 1) (f 2)])"))))

3:15 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol>

3:15 Sgeo:

3:15 hyPiRion: doesn't look like it.

3:16 devn: the use of fn* is weird

3:16 hyPiRion: devn: oh, blimey

3:17 devn: ,(fn* [x] (+ x 1))

3:17 clojurebot: #<sandbox$eval135$fn__136 sandbox$eval135$fn__136@695d9f0>

3:17 devn: ,((fn* [x] (+ x 1)) 100)

3:17 clojurebot: 101

3:17 hyPiRion: ,(with-out-str (pp/with-pprint-dispatch pp/code-dispatch (pp/pprint (read-string "(let [f (^:once fn* ([x] x))] [(f 1) (f 2)])"))))

3:17 clojurebot: "(let [f (fn* ([x] x))] [(f 1) (f 2)])\n"

3:17 Sgeo: What's fn*?

3:17 devn: hyPiRion: except!

3:17 the former is valid clojure

3:18 hyPiRion: yeah, I noticed.

3:18 devn: ,(let [f (^:once fn* [x] x)] [(f 1) (f 2)])

3:18 clojurebot: [1 2]

3:18 hyPiRion: ,(let [f (^:once fn* [x] x)] (mapv f [1 2]))

3:18 clojurebot: [1 2]

3:18 devn: :(

3:18 noidi: ,(doc fn*)

3:18 clojurebot: Excuse me?

3:19 devn: ,(use 'clojure.repl)

3:19 clojurebot: nil

3:19 devn: ,(doc fn*)

3:19 clojurebot: No entiendo

3:19 hyPiRion: $source fn*

3:19 lazybot: Source not found.

3:19 devn: fn* is internal

3:19 but obviously not that internal

3:20 hyPiRion: It's in the clojure/java transition area, isn't it?

3:20 devn: transition area?

3:20 (yes if you mean what i think you mean)

3:21 hyPiRion: the area where clojure fns are written in java

3:21 or converted/parsed

3:21 amalloy: &(macroexpand-1 '(fn [x] x))

3:21 lazybot: ⇒ (fn* ([x] x))

3:21 amalloy: fn* forms are always generated with the wrapped parens, so pprint probably relies on that. if you're creating fn* forms yourself, you probably shouldn't be

3:22 oh, except that the lazy-seq macro generates the thing you pasted?

3:22 devn: amalloy: *nod* I think so

3:22 amalloy: it does. i don't really use pprint much, so i'm not bothered or surprised that it's broken

3:23 devn: amalloy: im not bothered or surprised either, but i figure it was worth asking

3:23 well, let me elaborate

3:23 i was surprised, but after talking it out I'm not bother, nor do I think it is generally surprising

3:24 bothered*

3:27 amalloy: thanks for the help

3:27 amalloy: clojure/conj this year?

3:28 amalloy: not planning on it

3:28 devn: :(

3:30 magopian: man kodowa is recruiting

3:30 that is just so awesome

4:00 Sgeo: How careful do I have to be to avoid accidentally rebinding functions?

4:00 I know Lisp-2 proponents say things like they like not having to name variables lst, but what if you do in Clojure name a variable list?

4:00 In a local binding, I mean?

4:01 hyPiRion: Sgeo: it's not a problem

4:01 ,(let [list '[a-list of elements]] (println list))

4:01 clojurebot: [a-list of elements]

4:02 hyPiRion: ,(let [f (fn [a] (let [list [1 2 3]] (a list)))] (f list))

4:02 clojurebot: ([1 2 3])

4:02 Sgeo: Hmm. Suppose a macro expands into some code that uses list, and you've rebound list like that?

4:02 And use the macro from within there?

4:03 hyPiRion: Use gensyms if that's a problem

4:03 amalloy: Sgeo: then the macro is badly written

4:03 Sgeo: ...for using the list function?

4:03 amalloy: &`(list 1 2 3)

4:03 lazybot: ⇒ (clojure.core/list 1 2 3)

4:03 hyPiRion: Oh, right

4:03 they are namespaced, so it shouldn't be a problem

4:03 unless you go full retard with ##`(,'list 1 2 3) it should be okay

4:03 lazybot: ⇒ ((quote clojure.core/list) 1 2 3)

4:04 hyPiRion: ,`(~'list 1 2 3)

4:04 clojurebot: (list 1 2 3)

4:04 hyPiRion: i mean.

4:05 Chousuke: usually hygiene isn't a problem with clojure macros

4:05 Sgeo: &(let [list '(1 2 3)] (namespace 'list))

4:05 lazybot: ⇒ nil

4:05 Sgeo: (namespace 'list)

4:05 &(namespace 'list)

4:05 lazybot: ⇒ nil

4:07 Chousuke: it's difficult to screw things up so that you get hidden misbehaviour

4:08 hyPiRion: Chousuke: Well, yeah, as long as you know about gensyms, you should be fine

4:08 Chousuke: you don't even need gensyms, though they make things easier.

4:08 hyPiRion: Oh, you do.

4:08 Sgeo: Uh. I think writing macros without knowing gensyms is probably a recipe for failure.

4:08 Chousuke: oh, wait, yeah. I was thinking of autogensyms

4:09 hyPiRion: Well, autogensyms are just syntactic sugar. But it's very clean though.

4:10 Chousuke: it's a good feature. no point in leaving it out :)

4:11 hyPiRion: Clojure itself seems like the royal bathroom if you compare it to common lisp.

4:12 Sgeo: There are some things in Common Lisp I like. The ability to rename namespaces, the condition system

4:12 Chousuke: The best feature Clojure has is all the features together. :P

4:12 none of them alone is anything earth-shattering but the way Clojure combines everything just works nicely.

4:13 Sgeo: And then protocols get thrown in the mix in a non-interchangeable way with multimethods

4:14 Chousuke: how could they be interchangeable?

4:14 besides both creating functions as the interface.

4:14 Sgeo: Well, protocols could be built on top of multimethods in a clear way.

4:15 Chousuke: no they couldn't.

4:15 they wouldn't perform well enough

4:15 tomoj: :D

4:15 Chousuke: the whole point of having protocols in addition to multimethods is performance :P

5:40 nz-: what is the home row?

5:42 hughfdjackson: asdfjkl;

5:42 nz-: isn't it those keys on your keyboard? ^

5:43 asdf on your left hand, jkl; on your right; where your fingers should (in theory) rest

5:43 :3 or am i wildly off the mark here?

5:43 magopian: hughfdjackson: i would have answered nearly the exact same

5:43 nz-: the "home row" is the middle row, the one which has two keys with "bumps" on them

5:44 those keys are where the index of both your hands should 'rest'

5:44 nz-: goofed with irc history, somebody answered already

6:00 Sgeo: Is Clojure arithmatic really supposed to take 1/10th of a second?

6:00 Clojure> (time (* 1 1))

6:00 "Elapsed time: 103.083431 msecs"

6:01 (On tryclj.com )

6:01 magopian: $(time -

6:01 $(time (* 1 1))

6:02 a(time (* 1 1))

6:02 &(time (* 1 1))

6:02 lazybot: ⇒ "Elapsed time: 221.855607 msecs" 1

6:02 magopian: &(time (* 1 1))

6:02 lazybot: ⇒ "Elapsed time: 225.222137 msecs" 1

6:02 magopian: mmmm

6:02 that looks long indeed

6:02 maybe the repl is fired up each time?

6:07 algernon: probably some sandbox.

6:08 it's 0.025 locally (clojure 1.3)

6:22 Raynes: Sgeo: tryclojure and lazybot are completely worthless for benchmarking. The sandbox adds code and such.

6:22 magopian: ^

6:49 magopian: Raynes: thanks a lot for the information ;)

7:28 Sgeo: Is it possible for the same jar to have two different versions of a library?

7:28 Say, if my code uses library A which relies on X version 1 and library B which relies on X version 2

7:32 Scorchin: I'm trying to write a crawler that will check that all links on pages for a given domain (e.g. mysite.com) are valid (return status 200 OK). I have an idea of what I'd like to achieve, but I'm not sure how to make it concurrent. Currently I'm starting with a set of URLs that I call, check their status, and then get a list of URLs for the same domain on the page which I add to the set to be checke

7:32 d. What are the best ways to tackle this in a Clojure-like way?

7:33 I was originally thinking about using futures, but that could bloat the number of threads

7:36 jml: I'm feeling a bit dense. How do I specify jenkins (org.jenkins-ci.jenkins) as a dependency in leiningen?

7:36 I've got :repositories [["jenkins" "http://repo.jenkins-ci.org/public/&quot;]] in my project.clj

7:37 and [org.jenkins-ci/jenkins "1.26"] in the :dependencies vector

7:37 and http://repo.jenkins-ci.org/public/org/jenkins-ci/jenkins/ seems to be there, merrily existing away

7:38 but I get 'Could not find artifact org.jenkins-ci:jenkins:jar:1.26 in jenkins (http://repo.jenkins-ci.org/public/)' during 'lein run'

7:51 xeqi: jml: http://repo.jenkins-ci.org/public/org/jenkins-ci/jenkins/1.26/ only has a pom, so you might try :extension "pom"

7:52 Sgeo: I'm going to have to learn what a pom is, aren't I?

7:52 :/

7:52 xeqi: Sgeo: not usually. The jvm loads the first instance of the class it finds on the classpath, so having v1 and v2 leads to bad interaction

7:53 Sgeo: xeqi, :/

7:53 xeqi: not usually

7:53 Sgeo: I think the last time I actually liked/wanted/anything'd the JVM or the JDK was as a kid

7:53 I was excited by a book about Java that I bought, since I didn't see any other ways to start programming for free.

7:54 I eventually found Python, which was the first time I actually started writing code outside of Visual Basic and VBA

7:54 xeqi: how does python handle having two of the same library?

7:55 jml: xeqi: it takes the first thing it finds on sys.path

7:55 xeqi: sounds like the same thing to me

7:55 Sgeo: My Python mention was a tangent

7:58 magopian: poor lad, vb and vba

7:58 :)

8:06 clgv: Scorchin: you can use java's ExecutorSevices

8:09 Sgeo: I feel like I'm going to end up learning way more than I ever wanted to know about Java.

8:12 clgv: Sgeo: do not complain to soon about vague feelings ;)

8:34 llasram: Sgeo: I felt the same way at first, and everyone knows about the amazingly bad parts of the Java standard library and Java frameworks, but there's some amazingly high-quality parts too

8:35 Sgeo: Clojure wouldn't happent to have built-in not-blatent-Java-FFI file access, would it?

8:35 *happen

8:35 llasram: If you look at Clojure's concurrency support, it's pretty interesting how much of it is just bolting the STM to a thin veneer over the Java standard library concurrency libraries

8:35 antares_: Sgeo: clojure.java.io

9:02 jsabeaudry: Is there anything besides lein-deps-tree that will print a dependency tree for my project? (lein-deps-tree crashes on a could not locate leiningen/core/classpath__init....)

9:02 llasram: jsabeaudry: lein2, `lein deps :tree` ? Or is that what you're talking about?

9:02 clgv: jsabeaudry: lein2 deps :tree - but only for leiningen2

9:03 jsabeaudry: Oh yes, for lein 1.7.1, I'm still waiting for the official release before I move to lein2

9:04 Raynes: There isn't a real reason to do that.

9:04 llasram: I'd suggest going ahead and switching. My understanding is that the only reason technomancy hasn't done an official 2.0 release is because he's waiting on new clojars infrastructure. It's not because the lein2 codebase isn't ready

9:05 Raynes: Pretty much everyone has moved already and lein 2 is generally complete.

9:06 But if you insist on using old lein, mvn dependency:tree should work with your lein-generated pom.xml file.

9:07 pyykkis: has anyone installed lein2 with homebrew? I wonder if there's an updated recipe somewhere or should I make pull req

9:10 clgv: pyykkis: what was different from normal lein installation with homebrew?

9:10 Raynes: The commands used. *shrug*

9:11 Oh, never mind. Misunderstood the question.

9:12 pyykkis: oh, and one can actually install 2.x with 'brew install leiningen --HEAD'

9:15 clgv: it's pretty much the same under the hood, just easier with homebrew one-liner

9:15 https://github.com/mxcl/homebrew/blob/master/Library/Formula/leiningen.rb

9:16 I wasn't awere of --HEAD flag, though. Maybe it's time to actually read homebrew docs..

9:18 clgv: pyykkis: well, that seems to get you 1.7.1

9:24 Sgeo: Don't have time to fix my copy of labrepl now, but when I get it working, does it provide a REPL in the browser, or will it expect me to do it in the REPL I launch labrepl from?

9:28 pyykkis: clgv: hm...works on my laptop?

9:28 $ lein version

9:28 Leiningen 2.0.0-SNAPSHOT on Java 1.7.0_05 Java HotSpot(TM) 64-Bit Server VM

9:29 clgv: pyykkis: I just read the link where 1.7.1 was explictely named. maybe there is some magic besides that.

9:29 I have not the slightest idea of how homebrew works ;)

9:31 pyykkis: clgv: there's also 'head' defined in the homebrew recipe, which points to master branch

9:32 ..which is used with 'brew install leiningen --HEAD'

9:32 clgv: ah ok.

9:37 Sgeo: If I'm on JRE 7 why does (javadoc System) bring me to the thing for 6?

9:38 hyPiRion: $source javadoc

9:38 lazybot: Source not found.

9:38 xeqi: pyykkis: that is a weird lein version number

9:41 robermann: Sgeo: http://clojuredocs.org/clojure_core/clojure.java.javadoc/javadoc

9:42 xeqi: pyykkis: I have a suspicion that your getting the 4month old -SNAPHSHT on https://github.com/technomancy/leiningen/downloads

9:42 pyykkis: xeqi: well..yeah, it isn't any of the previews, it's the HEAD from master branch https://github.com/technomancy/leiningen/blob/master/project.clj#L4

9:43 xeqi: right, but I don't see the homebrew script bootstrapping lein

9:43 just calling self-install, which pulls from the github download page

9:44 naeg: how often do you actually use -> and ->> in real code? like (f (g v)) instead of (-> v g f)

9:44 pyykkis: xeqi: ah..thanks, I haven't even looked so far. Maybe I'll do manual install then, afterall.

9:45 xeqi: -> is not uncommon, ->> is rarer

9:46 pyykkis: naeg: more often than not. I'd be close to say "always"

9:46 naeg: is it rarer because people just don't need ->> that often or because peopl like to write it out instead of using ->>?

9:47 xeqi: I usually start using -> when I get to a chain of 3

9:47 naeg: do other lisp's have this too? I can't remember such a macro from CL

9:47 antares_: naeg: -> is pretty commonly used. In the example you've demonstrated I just do (f (g v)), though

9:47 xeqi: ->> is rarer cause things like assoc are designed for ->

9:47 robermann: Sgeo: maybe you should check/set the *remote-javadocs* var

9:49 jweiss: would it be frowned upon to use the extensible reader to create a group of common imports (eg, require's, use's)? like (ns blah #=(my-common-stuff-a) #=(my-common-stuff-b))

9:50 jsabeaudry: ,(str (doall (map int [1 2 3 4])))

9:50 clojurebot: "clojure.lang.LazySeq@e93c3"

9:51 S11001001: ,(str (proxy [Object] [] (toString [] nil))) ; my favorite, jsabeaudry

9:51 clojurebot: nil

9:52 jsabeaudry: S11001001, Looks good, unfortunately I cannot really appreciate it as I am not familiar with proxy :(

9:53 Ah, I think I get it, str call tostring and you deined an bject that returns nil when you call tostring on it?

9:53 hyPiRion: ,(= (proxy [Object] [] (equals [x] 'foobar)) nil)

9:53 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.UnsupportedOperationException: nth not supported on this type: Symbol>

9:54 S11001001: hyPiRion: sorry, there's only one trick :)

9:54 hyPiRion: S11001001: Apparently.

9:54 chouser: jweiss: that's an interesting idea. Certainly not one I've seen.

9:54 S11001001: ,(let [snil (proxy [Object] [] (toString [] nil))] (str snil snil))

9:54 clojurebot: #<NullPointerException java.lang.NullPointerException>

9:54 chouser: jweiss: where would my-common-stuff-a be defined?

9:54 S11001001: neat

9:55 ,(let [snil (proxy [Object] [] (toString [] nil))] (-> snil str str))

9:55 clojurebot: ""

9:56 S11001001: the point of this being that ∃v. (str v) ≠ (str (str v))

9:57 jweiss: chouser, it'd be a function in some other namespace. i suppose i'd have to refer to it by its fully qualified name and ensure that it's already loaded.

10:04 augustl: anyone know how to get the raw Set-Cookie headers from clj-http? It seems to remove them from :headers and add the parsed result to :cookies

10:04 chouser: jweiss: yeah, interesting. The 'ns' block was supposed to be declarative so as to support tooling in general, and such use of #=() might break that. ...but I'm not aware of any tools that read the ns block anyway, so *shrug*

10:06 jweiss: chouser, declarative meaning a literal list and no calculated values?

10:07 chouser: well, yeah -- that's why you're having to use #=(), because the bodies are essentially quoted for you

10:08 augustl: can't find any reference to :cookies anywhere in the code of clj-http, weird

10:08 chouser: and also declarative in that ns uses :require instead of the symbol require

10:08 jeremyheiler: augustl: if you don't need the wrap-cookies middleware, you can remove it.

10:08 it's in src/clj_http/cookies.clj

10:08 augustl: ugh, was looking at someones fork on github

10:08 or something like that

10:08 jeremyheiler: ah lol

10:09 augustl: do I need to build my own set of middlewares from scratch?

10:12 by reading https://github.com/dakrone/clj-http/blob/0.5.3/src/clj_http/cookies.clj#L129 you'd think setting :cookie-store to false in the request would do the trick, but that doesn't seem to help

10:13 jeremyheiler: yeah, the wrap-cookies function is the culprit.

10:13 more specifcally, decode-cookie-header

10:13 augustl: ugh, when :cookie-store is falsy, it wil use its own internal one

10:16 jeremyheiler: would it be possible just to encode the cookie again?

10:19 augustl: probably yeah

10:20 jeremyheiler: that's probably the less painful solution

10:21 robermann: in emacs, is there a way to do a "in-ns" to the namespace in the currently open .clj file?

10:23 never mind, found it: C-c M-p

10:23 (I was wrongly remembering C-c C-z)

11:12 estebann: is there any easy way to prevent c3p0 from spewing stuff into the repl? it makes useful output hard to find...

11:16 ohpauleez: lynaghk: ping

11:20 nz-: I think that c3p0 prints stuff via log4j so add log4j.xml under test. configure that log4j.xml so that nothing is printed to STDOUT

11:21 estebann: nz-: cool, thanks

11:23 nz-: estebann: example of suitable log4j.xml is here

11:23 https://github.com/korma/Korma

11:23 estebann: nz-: nice, thanks again

11:24 naeg: is someone aware of a bigger game written in a functional language? preferably clojure, but doesn't have to be

11:25 ejackson: dammit - laziness kicks my arse *again* !

11:25 psii: naeg: what do you mean by "bigger"?

11:27 jml: what do I need to add to my projects.clj to be able to depend on Jenkins (in order to be able to make a jenkins plugin)? (a pom.xml here: http://paste.ubuntu.com/1170038/; generated by following instructions at https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial#Plugintutorial-SettingUpEnvironmen)

11:29 naeg: psii: just more than a few hundred lines

11:29 psii: naeg: http://joyridelabs.de -- although in haskell

11:29 naeg: psii: the actual question is whether the functional style could extend to larger (2d) games

11:29 psii: well then, this link is for you :)

11:30 naeg: thanks psii

11:31 jml: I think I'm just a vanilla fool

11:39 xeqi: jml: you might be able to figure it out by reading https://github.com/pyr/jenkins-leiningen 's pom

11:40 * jml looks

11:40 xeqi: though I'm not sure there is an equivalent for plugin-repositories ...

11:41 jml: xeqi: thanks. I'm looking for an equivalent projects.clj, but I think I've got something that's working well enough for me to move on to the next problem :)

11:41 xeqi: I think you could use :pom-additions for that, but its prolly not well documented

11:41 jml: is there a syntax for importing inner classes?

11:41 xeqi: OuterClass$InnerClass

11:42 jml: thanks

11:44 TimMc: jml: Inner classes are a Java lie. :-)

11:45 s/lie/concept/

11:46 unlink: `lein ring server` takes a shocking long time to start (~15 seconds), and code reloading is anything but infallible. How do people work around this?

11:47 weavejester: unlink: There's something wrong with the code reloading I need to look into. I suspect the namespace dependencies aren't being calculated correctly.

11:48 unlink: Oh, OK.

11:48 weavejester: unlink: In the meantime, you could always start a server in a REPL and reload manually

11:49 unlink: How would I do that?

11:49 weavejester: unlink: (run-jetty your-handler {:join? false :port 3000})

11:49 unlink: And then (require 'your.namespace :reload-all)

11:50 unlink: oh, great. I'll try that.

11:50 brainproxy: I like to do it the other way around; I use `lein ring server ...` to fire up the dev server, and inside whatev.core I fire up a repl server which I can connect to from emacs

11:50 augustl: unlink: I've had problems with code reloading as well, for what it's worth :)

11:50 so you're not alone

11:51 weavejester: It probably won't be too long until I fix the namespace reloading, as I'm getting bored of it myself.

11:51 augustl: some times I get a 500 error in the form of a blank page, and then on the next request everything works, as it was before I changed the code and introduced the error. I very rarely get the stack trace etc.

11:51 weavejester: I suspect the problem is in the ns-tracker library

11:51 augustl: That indicates a compile error. e.g. the require itself is failing

11:52 augustl: ah, I see

11:52 weavejester: augustl: And because the require throws an exception, it's not loading the new code.

11:52 thorbjornDX: Is there a well-defined C interface for clojure/java?

11:52 augustl: in this case I'm one of those "I don't care I just want it to work" peeps :)

11:52 weavejester: augustl: Hm, but… I guess I could say that if there's an exception, it keeps trying to reload so you get the same error and it's not lost when you refresh.

11:53 augustl: that would rock :D

11:53 would ofc also be nice if some kind of error could be displayed on the page

11:53 weavejester: augustl: Don't you get a stacktrace?

11:53 augustl: quite often it's just a blank page

11:54 and then the "previous version" on subsequent requests, until restart

11:54 weavejester: Maybe the stacktrace middleware is below the reload middleware. So if there's an error requiring the file, the stacktrace middleware won't catch it.

11:55 Yeah, it is.

11:55 augustl: ah

11:55 weavejester: That's an easy fix at least.

11:55 augustl: so apparently code reloading is not black magic, it's just code like everything else?

11:55 weavejester: augustl: Yes :)

11:57 In a nutshell it looks for modified files when a new request comes in, then uses ns-tracker to calculate any dependencies. For instance, if namespace A is changed, but namespace B requires A, then both A and B need to be reloaded.

11:57 Then it reloads the namespaces with (require namespace :reload)

11:58 The stacktrace middleware is designed to catch exceptions and display a nice stacktrace, but the stacktrace middleware is currently placed below the reload middleware

11:58 So if a require fails because there's a syntax error (for example), then there won't be a stacktrace.

11:59 I suspect there's also a problem with the namespace tracking in ns-tracker. I'm finding that dependent namespaces aren't being reloaded all the time.

12:00 BTW, if anyone has problems with Lein-Ring or whatever, raise an issue on Github.

12:05 llasram: weavejester: Oh, BTW, lein2 now has support for explicit framework-provided dependencies via a :provided profile. I contributed it for Hadoop job JAR building, but my hope is that it'll simplify things like WAR construction

12:10 weavejester: llasram: Thanks for the info

12:29 hughfdjackson: other than the ability to define records that can have protocols defined for them, doesn't defrecord seem a slightly second-rate way to define datastructures?

12:29 as far as I can tell, it doesn't seem to support named fields on construction

12:30 which ends up with ordered params instead

12:30 :D i'm thinking that i probably misunderstood this

12:31 technomancy: yeah, don't use records if you can get away with multimethods

12:31 multimethods and maps, rather

12:31 llasram: And if you do need them, the work-around is that you have a Clojure factor function rather than directly use the JVM class constructor

12:31 s,factor,factory,

12:31 hughfdjackson: hrm, drat

12:32 augustl: I'm mostly using records when I need "private" data structures

12:32 i.e. where initialization only happens one or two places, in the same namespace

12:32 hughfdjackson: is it the 'named type rather than duck type' side of it that irks, or is it the problem with instantiating them without key:val pairs that i mentioned?

12:32 llasram: Yeah. I really really wish deftype let you specify custom constructors. I'd let me ditch most of the remaining cases where I need to squiggle some Java into the codebase

12:33 Sgeo: I'm having problems with Eclipse

12:33 * weavejester sighs

12:33 weavejester: I hate SQL so much

12:34 Sgeo: Surely there are things for Clojure that let you avoid using SQL directly?

12:35 weavejester: Sgeo: Yes, for querying and such, but less for generating schema. There's lobos, but it can't do everything.

12:36 llasram: SQL truly is the worst query language, except for all the others

12:36 technomancy: schema generation isn't even really standardized

12:36 weavejester: The main problem is that SQL syntax is such a horrific ball of mud that even the simplest things are difficult or impossible

12:36 nz-: what is missing from lobos?

12:36 weavejester: llasram: Actually… I can't think of a worse query language than SQL...

12:37 nz-: It might be that lobos can actually do everything I want

12:37 But "to keep it simple" I've gone with files of SQL for migrations

12:37 technomancy: nz-: I get the feeling it's just got too much

12:38 weavejester: The problem is that I forgot you can't execute multiple SQL statements of certain types in the same command

12:38 And there doesn't appear to be any library to split them up in Java

12:38 Or any language.

12:38 llasram: weavejester: Yeah, fair enough. Really the only contrast I'm familiar with is SQL over full relational data model vs. limited data-access API for much more constrained data model, which doesn't really cover the case of e.g. Datalog

12:39 weavejester: llasram: Admittedly most of the better query languages I can think of don't have as much functionality as SQL.

12:39 tvladeck1: quick question; is there any way to use the "map" function in the new reducers library, if you don't actually need to reduce the result?

12:40 Bronsa: (into [] (r/map ..))

12:41 tvladeck1: cool; and does that achieve the same sort of fork/join goodness that exists in the "par" branch?

12:41 hughfdjackson: isn't the point of the reducers that all common forms of operations over sets can be 'reduced' (gettit) to a reduce with an appropriate fn?

12:41 Bronsa: into calls reduce

12:41 hughfdjackson: (:p this Q is more for me than for you)

12:41 weavejester: technomancy: I'm using the code you wrote for Ragtime ages ago. Did you happen to give any thought to putting more than one SQL statement in a migration file?

12:42 dnolen: hughfdjackson: not sure what you mean.

12:42 hughfdjackson: dnolen: i watched the rich hickey talk while i was kinda nodding off i'm afraid :#

12:42 technomancy: weavejester: not really; best I came up with was splitting on ;; and a big old "don't use ;; inside actual SQL" comment at the top

12:42 tvladeck1: Bronsa: so into calls "reduce", but isn't it necessary to call "par/reduce" to get the advantage?

12:42 augustl: hughfdjackson: that's my impression as well. The actual units of work only describe what needs to be done with one item. Then there's a generic tool to parallelize the actual operation.

12:43 weavejester: technomancy: I was afraid of that :)

12:43 hughfdjackson: but i thought the point of it was that reduce an abstract operation that you can define reduce/map/each in terms of

12:43 technomancy: weavejester: but I also have experimented with doing it from Clojure itself: https://github.com/heroku/buildkits/blob/master/src/buildkits/db/migrate.clj

12:43 the main downside there is you don't get syntax highlighting, which is awful and terrible

12:43 Bronsa: tvladeck1: they both call coll-reduce

12:43 tvladeck1: ok got it

12:43 technomancy: but on the other hand data manipulation is a lot nicer

12:44 and ordering too

12:44 weavejester: technomancy: True...

12:44 technomancy: I'm currently turning Ragtime into a Lein plugin

12:44 technomancy: maybe a helper defn to load a single SQL statement from a file, but it lacks immediacy

12:44 really? why's that?

12:44 I don't see the point of running anything inside leiningen's process

12:45 weavejester: technomancy: Well, ragtime core wouldn't be changed

12:45 But I was adding an extra ragtime.lein so you could run "lein migrate"

12:45 technomancy: you can do that easily already

12:45 :aliases {"migrate" ["run" "-m" "ragtime.core"]}

12:45 weavejester: Hm. How?

12:46 Hm… problem with that is that you have to write your own migrate code

12:47 technomancy: that doesn't mean that you have to run code inside leiningen's process though

12:47 it's all still project-isolated

12:47 weavejester: Oh, I'm using eval-in-project

12:47 So it's a very thin wrapper

12:47 technomancy: sure; but you should use eval-in-project via the run task rather than calling it directly

12:48 jweiss: does the extensible reader support spliciing? (eg, #foo/bar 1 -> 1 2 3 ) ?

12:48 weavejester: technomancy: Hm...

12:48 Bronsa: jweiss: dont think so

12:49 weavejester: So if one was making a plugin for Leiningen that primarily execute code in project


12:49 weavejester: Perhaps instead of using eval-in-project, it would inject alieases instead into the project map

12:49 Sgeo: I'm trying to import labrepl

12:49 weavejester: Oh wait, that wouldn't work...

12:49 Sgeo: It complains that it overlaps another project: labrepl

12:49 I think it's downloading the files then noticing that there are files there

12:50 technomancy: weavejester: if you're going to have to add one line to project.clj for a :plugins entry why not add a line for :aliases instead?

12:50 * technomancy gets the feeling partial aliases need to be better documented and/or promoted

12:50 weavejester: technomancy: Because you'd need lines for rollback as well, and some configuration too.

12:50 Currently I have two config vars

12:51 Sgeo: Any help?

12:51 technomancy: weavejester: suggest loading config from resources

12:51 weavejester: :ragtime {:migrations ns.for.func.that/generates-migrations, :database "jdbc:h2:mem:test_db"}

12:51 technomancy: also: a single -main function can support migration and rollback

12:52 lein run -m ragtime.main [REVISION]

12:52 weavejester: technomancy: That's an idea. lein run -m ragtime.main migrate

12:52 technomancy: But I don't like the idea of scattering configs around.

12:53 technomancy: Leiningen has never encouraged using project.clj for runtime config

12:53 weavejester: I know

12:53 But...

12:54 technomancy: I suspect any app nontrivial enough to need migrations is already going to have to be reading config from somewhere already

12:54 weavejester: There isn't a better alternative IMO.

12:54 bhenry: looks like someone needs to rewrite ants.clj http://news.stanford.edu/news/2012/august/ants-mimic-internet-082312.html

12:54 weavejester: technomancy: In production, that would be the environment, according to 12factor.net :)

12:55 But in development...

12:55 Adding configs to Lein profiles is very nice.

12:56 So we either need to build a separate profile/config system

12:56 Or we could tie into Leiningen's

12:56 Although Lein isn't designed to be used in this fashion, I don't see why it couldn't be.

12:57 Frozenlock: `find' is to be used with a map, but is there an equivalent function for a collection? I want to check if I have a given item in a vector.

12:58 nDuff: Frozenlock: some?

12:58 xeqi: (some #{1} [2 3 4 1])

12:58 weavejester: Frozenlock: some?

12:58 technomancy: I like the idea of a ragtime.main though

12:58 Frozenlock: Yes! Thanks!

12:59 thorbjornDX: ,(some #{1} [2 3 4 1])

12:59 clojurebot: 1

13:01 thorbjornDX: ,(some #{:a :b} {:a 1 :b 2})

13:01 clojurebot: nil

13:01 thorbjornDX: I guess that's where find is used?

13:02 Frozenlock: I guess I must be too used to elisp's find function.

13:02 thorbjornDX: Frozenlock: I'm used to python's 'in'

13:02 nDuff: ...the thing about 'in' is that it can behave in ways with wildly different performance characteristics

13:03 whereas Clojure tends to have functions in its standard library with well-defined performance characteristics

13:03 Frozenlock: Eh python.... one day, one day :)

13:03 thorbjornDX: nDuff: yeah, it's hard to know what it's doing behind the scenes

13:03 nDuff: ...if you're using some, you _know_ that it's an O(n) operation.

13:04 technomancy: weavejester: yeah, some people are using project.clj for runtime config

13:04 thorbjornDX: 1 in [1, 2, 3, 4] is O(n), 1 in {1: 1, 2: 2, 3: 3, 4: 4} is O(1), yea?

13:05 nDuff: thorbjornDX: Exactly.

13:05 technomancy: it's this weird thing where I can't point to any specific reasons it's a bad idea; it's just that I haven't thought it all the way through yet. there are a lot of design decisions that were made without factoring it in at all

13:05 weavejester: technomancy: If it makes you feel better, I'm only using it in development :)

13:06 technomancy: I'm just wary because as soon as I start encouraging it I may push myself into a corner where there'd be some great feature I'd like to implement but can't because it doesn't jive with runtime-level config

13:06 weavejester: technomancy: I tend to use environ and profiles to configure dev stuff, and then in production environment vars or system properties.

13:06 technomancy: Noted.

13:07 technomancy: so I guess I should encourage people to experiment with it unofficially for a while and have them report any issues =)

13:07 weavejester: technomancy: But in that case, we'd likely need something to replace Lein. Like… a runtime config/profiles thing.

13:07 technomancy: weavejester: have you seen configleaf?

13:07 weavejester: technomancy: No...

13:07 technomancy: I think it does some of the stuff you're describing

13:08 weavejester: technomancy: Hm, that goes a little further than I was thinking...

13:09 technomancy: In my case I'm just using it as a way to populate env vars during development.

13:10 And I guess to specify how to run the application.

13:10 But Lein does that already with :main, so that seems to be in line with how it works already

13:11 Specifying :main or specifying a :handler seem similar.

13:20 technomancy: yeah, in fact IMO lein run with the right aliases covers most of the use cases of lein ring

13:20 lein ring server, I mean

13:20 if you're using embedded jetty

13:21 weavejester: technomancy: Yes, apart from the configuration

13:21 technomancy: lein run + aliases + some kind of config with profiles would cover my use cases at the moment

13:21 technomancy: weavejester: lein-ring says it does stack traces in development; does it just check LEIN_NO_DEV, or what?

13:22 weavejester: technomancy: Yes, by default, but you can be more exact with profiles

13:22 technomancy: It seemed like a reasonable default to have.

13:22 technomancy: yeah, unfortunately LEIN_NO_DEV is specific to 1.x

13:23 weavejester: technomancy: You can still set it for 2.0 - it just wouldn't do anything to Lein itself.

13:23 technomancy: That said, for Lein 2 you'd probably want to use profiles.

13:23 technomancy: sure, it's just no longer a documented convention

13:23 Sgeo: ,(some #{:a :b} (keys {:a 1 :b 2})

13:23 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

13:23 technomancy: might help to be clearer about that in the lein-ring readme

13:23 Sgeo: ,(some #{:a :b} (keys {:a 1 :b 2}))

13:23 clojurebot: :a

13:23 Sgeo: Oh, I was scrolled up

13:23 weavejester: technomancy: True

13:24 jbarrios: ,graph

13:24 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: graph in this context, compiling:(NO_SOURCE_PATH:0)>

13:25 jbarrios: where's the old clojure.contrib.graph package now?

13:27 raek: jbarrios: nowhere. it is unmaintained.

13:27 http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

13:27 jbarrios: so I guess dgraph is the best choice atm?

13:28 https://github.com/gcv/dgraph

13:31 jml: is there a recommended pastebin for this channel?

13:31 llasram: jml: https://www.refheap.com/paste

13:31 jml: llasram: thanks.

13:32 pretty.

13:32 hyPiRion: gists are also nice if you wonder whether the code is idiomatic or not

13:32 'cause of forking possibilities

13:32 sh10151: quick leiningen/clojure-jack-in question for emacs people:

13:33 things in my resources/ directory don't appear to be on the classpath in a repl started in clojure-jack-in ... does that sound right? if so, any way to change that?

13:34 jsabeaudry: what kind of "things" ?

13:34 sh10151: xslt file

13:34 null pointer returned by clojure.java.io/resource on its name

13:35 technomancy: sh10151: did you create the resources/ dir after starting the JVM?

13:35 sh10151: hmm good question. does clojure-jack-in tear down the whole JVM or not?

13:35 i think i have just been repeatedly calling that

13:35 saying to get rid of the exsting process

13:36 technomancy: it does restart the JVM, yeah

13:36 sh10151: ok, so no

13:36 it's been there

13:36 if it's supposed to work, I can look for typos or something

13:36 just wanted to make sure it's supposed to work

13:36 after not seeing any typos

13:36 raek: yeah, it is supposed to work

13:37 technomancy: it definitely should work

13:37 sh10151: ok, I see making the uberjar puts the file in there

13:37 jsabeaudry: it does work here, just tested it

13:37 what path did you give to (resource ) ?

13:37 raek: sh10151: so if you have a file in resources/foo/bar.txt you use (io/resource "foo/bar.txt") to get it?

13:37 sh10151: "/filename.xsl"

13:37 it's at top level of resources dir

13:38 maybe no leading "/" ?

13:38 jsabeaudry: try without the leading slash?

13:38 raek: I can't remember what happens if you have a leading slash

13:38 jsabeaudry: returns nil if i had a leading slash here

13:38 sh10151: relative to package of the classloader loading the resource I think

13:38 jsabeaudry: add*

13:39 sh10151: I mean, that's what Java does, not sure about java.io.resource

13:39 raek: it uses the java stuff under the hood

13:40 sh10151: that did it, thanks for the help. I should have tried that

13:40 deeplloyd: I have been trying to pick up clojure over the past couple of weekends. i find a decent amout of people's learning experiences w/ clojure plus the normal documentation. What I feel I have not found is a non lisp, non clojure, python/c ish dev's account of coming blind from said technologies to writing a web app in clojure. webnoir is about the best. I have a decent background in programming, and know that it will take time to get

13:40 sh10151: just porting some clojure 1.0.x era code with maven-clojure-plugin to current stuff

13:40 and I know it used to work back in the day :)

13:41 dnolen: deeplloyd: have you checked out the O'Reilly book?

13:41 Frozenlock: Perhaps I was doing it the wrong way, but in clojure I could get the value of a symbole simply by doing (eval my-symbol). How can I do it in cljs?

13:41 deeplloyd: dnolen: clojure programming?

13:42 synfinatic: yep that one

13:42 dnolen: deeplloyd: yes

13:42 xeqi: ,(resolve '+)

13:42 clojurebot: #'clojure.core/+

13:42 sh10151: deeplloyd: In my experience the Java/JVM adds quite a bit of complexity too, if you're not already familiar with it. my last question is an example of such complexity. :-/

13:43 Sgeo: Hmm

13:43 cemerick: deeplloyd: http://clojurebook.com if you'd like a precis (or, the closest you'll get to one for a technical book I guess)

13:43 Sgeo: &(resolve '+)

13:43 lazybot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

13:43 Sgeo: So, there's a difference between clojurebot's sandbox and lazybot's sandbox

13:43 deeplloyd: synfinatic: dnolen not past the free samples. i dont pirate and would prefer to hold out on spending the bucks until finances are a bette

13:43 technomancy: you'd run into the problem of complexity around the ability to load files transparently either off disk or from a compressed archive no matter the runtime

13:43 deeplloyd: cemerick: precis?

13:43 Sgeo: ,(future (+ 1 1))

13:43 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

13:44 cemerick: $google define:precis

13:44 lazybot: [Précis - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Pr%C3%A9cis

13:44 cemerick: oh well

13:44 deeplloyd: ah

13:44 xeqi: Sgeo: quite abit, clojurebot resets the sandbox every ~15m or so and uses classloaders to prevent some bad stuff; lazybot uses clojail to achieve the same thing

13:44 Sgeo: classloaders?

13:44 sh10151: technomancy: sure, but in other runtimes that's not really something that's valued enough to bake into the system

13:45 Sgeo: I've heard the term before but don't know much about it

13:45 cemerick: A brief abstract of some material (paper, book, etc), usually written by a student to verify comprehension, etc.

13:45 deeplloyd: okay. well then that is the way I suppose. hopefully il be able to make what im looking for in the process

13:45 sh10151: technomancy: here I'm thinking of Python/C per deeplloyd's question :)

13:45 xeqi: Sgeo: think path to search for libraries

13:45 Sgeo: I thought that's classpath

13:45 technomancy: sh10151: so if you don't want the ability to read contents transparently from either an archive or disk why are you using resources?

13:46 xeqi: they both have to load other libs to run, but want to present a repl w/ a limited subset

13:46 classloaders are the objects that load classes from the classpath

13:46 deeplloyd: btw cemerick i enjoyed the state survey

13:46 Sgeo: Ah

13:46 technomancy: you can always fall back to loading a file from a specific path on disk

13:46 Sgeo: I'm pretty sure that I won't be mentally designing ClojureNomic

13:46 sh10151: technomancy: oh, I am interested in doing it either way, but only because these things are often deployed as a jar but developed running from files

13:46 cemerick: deeplloyd: Glad for that :-)

13:47 Sgeo: I think newLisp is good for a nomic because of save

13:47 deeplloyd: cemerick: what did you write your blog in?

13:47 cemerick: cemerick.com is on wordpress.com

13:48 So is mostlylazy.com

13:48 deeplloyd: do you have a clojure site i can scour?

13:49 sh10151: technomancy: which is something that a person who's primarily billing themselves as Python/C might not know off the bat.

13:49 cemerick: deeplloyd: What, of strictly clojure-related content? http://cemerick.com/category/clojure/ I suppose. :-P

13:50 technomancy: sh10151: sure, so you're trading a bit of up-front complexity for an easier single-file deployment

13:50 weavejester: technomancy: I think I'm going to have a ragtime.main with two arguments. The first to specify a function that returns a list of migrations. The second to specify a database URL.

13:50 technomancy: Then I'll add a Lein plugin that will thinly wrap ragtime.main and take the arguments from the project map.

13:50 technomancy: weavejester: yeah, since aliases support partial application you can put the function in project.clj

13:51 weavejester: technomancy: Yes, though I'll also add a plugin to do the same thing, but in a nicer way

13:51 sh10151: technomancy: yep, and that complexity's the kind of thing that can trip people up if they're not prepared. just pointing out to deeplloyd that understanding Java is at least as important to production Clojure as is understanding Lisp.

13:51 weavejester: technomancy: I want to see which I like best.

13:52 technomancy: weavejester: I guess the other thing you get with a plugin is a docstring

13:52 I dunno. I don't think it's worth it, but try it and see for yourself =)

13:52 weavejester: technomancy: Yeah. And if we decide to move away from plugins, it's only going to be a thin wrapper.

13:53 deeplloyd: cemerick: IE9 > FF ?!?

14:02 Sgeo: http://www.reddit.com/r/netsec/comments/ywbhq/new_java_0day_exploited_in_the_wild/

14:04 * synfinatic wonders how many times Oracle will have to fix that bug

14:17 cemerick: deeplloyd: ??

14:17 lazybot: cemerick: Uh, no. Why would you even ask?

14:20 Sgeo: I feel like I'm about to give up on labrepl

14:20 Or maybe just Eclipse

14:20 cemerick: Sgeo: What's tripping you up? I can help with Eclipse/ccw, but I know nothing of labrepl.

14:21 Sgeo: cemerick, when I try to import the thing via git, at the end of the wizard it says there's already a project there

14:22 (Following the instructions at http://dev.clojure.org/display/doc/Getting+Started+with+Eclipse+and+Counterclockwise )

14:24 (Specifically, after "Import as general project", it says "C:\Users\Sgeo\DEV\Eclipse\labrepl15 overlaps the location of another project: ;labrepl15'

14:24 cemerick: Sgeo: Worked for me; perhaps you've done this a couple of times, and so the project is already cloned with an eclipse project set up therein?

14:24 Sgeo: Erm, 'laprepl15'

14:25 cemerick, would that effect it even if I keep using different numbers for the directory?

14:25 cemerick: Sgeo: Wouldn't think so, but apparently…

14:25 darklajid: Hi. Probably I'm missing something obvious. I'm just getting started, playing with some simple http tools. I'm using ring, and a request seems to be just a map, right? Where would I find the structure/keys of this beast? I'm looking for the remote ip/port of the underlying socket, specifically

14:26 cemerick: Sgeo: Try: Import > General > Existing projects, and see if there's one already in place ready to go

14:26 Is labrepl even maintained anymore? Last change was 10 months ago.

14:26 technomancy: darklajid: just print the request

14:27 Sgeo: No projects are found to import

14:27 technomancy: or return it in the response: (defn app [req] {:headers {"Content-Type" "text/plain"} :status 200 :body (prn req)})

14:27 ohpauleez: cemerick: I'm not sure, but it is a good learning tool

14:27 cemerick: Sgeo: it looks like labrepl is just another leiningen project, so you can just use a clone of it as such

14:28 Sgeo: ?

14:28 xeqi: darklajid: https://github.com/ring-clojure/ring/blob/master/SPEC for the structure

14:28 cemerick: ohpauleez: dunno, it's starting people off with clojure 1.3.0, and old compojure, ring, etc.

14:28 darklajid: technomancy: Gives me two problems. a) I don't see the required data there (I get a :remote-addr, but that seems to be a string/ip address. No port) and b) Is that the normal way? I did that already, but I was kind of hoping for a missing link to some docs.. :)

14:29 cemerick: Sgeo: Are you specifically looking to use labrepl for something, or are you just wanting to get started with programming in Clojure in general?

14:29 ohpauleez: cemerick: Ah wow, I wasn't aware it was that out of date

14:29 4clojure would definitely be better

14:29 technomancy: darklajid: you could read the SPEC file for ring, but you should also get comfortable with exploring the API interactively

14:29 Sgeo: cemerick, getting started with Clojure in general, although I have learned a bit already I think

14:29 technomancy: that's the whole request object though

14:30 darklajid: xeqi: technomancy: Cool, the spec looks neat. But .. no port. So ring is not for me, I guess? Back to sockets?

14:30 cemerick: Sgeo: As long as you can get a Clojure+Leiningen project going in ccw with a REPL, you're on your way. :-)

14:30 * Sgeo tries lein repl from the command line

14:30 Sgeo: I seem to have gotten independent leiningen installed finally

14:32 labrepl working now

14:35 xeqi: darklajid: yeah, you'll prolly need something else.. why are you interested in the client's port out of curiousity?

14:37 darklajid: *cough* Quite frankly I suck at Clojure, but have cemerick's book on my kindle for ages. There's a current ctf from stripe and I'm trying to solve the last level -> The only one that needs code -> "Maybe I can learn some clojure with this particular goal"

14:37 xeqi: ah, I solved that one in python

14:37 darklajid: Problem: I need the addr/port to get even started. So the whole 'explore all these web stuff I've read about in clojure land' dies before I even begin :)

14:37 xeqi: since it was already on l2

14:37 darklajid: xeqi: ;-)

14:38 xeqi: Yeah, but .. I'm worse at python than at clojure, even. :) But I don't care about learning python very much, so.. Hmpf.

14:39 xeqi: heh, I didn't want to deal with installing a jdk

14:39 *jre

14:40 lucian: xeqi: i didn't even bother getting twisted there

14:40 even that is too much trouble

14:40 xeqi: yeah, I went singlethreaded python w/ sockets and httplib

14:57 Sgeo: "Starting in 1.3.0, Clojure no longer auto-boxes this type of operation for you."

14:57 Hmm, why?

14:58 S11001001: Sgeo: what?

14:58 Sgeo: S11001001, arithmatic that might overflow

14:58 nDuff: Sgeo: Performance.

14:58 S11001001: MORE SPEED

14:58 ohpauleez: Sgeo: Most developers are aware of the numeric scope they're operating in, so the performance trade-off of auto-boxing and converting up the numeric tower wasn't worth it

14:58 clojurebot: stuartsierra has come to the conclusion that dynamic scope is a bug.

14:59 ohpauleez: Sgeo: you can still get that behavior if you want it

15:08 Frozenlock: If any of you have 1 or 2 min to spare, could you look at this code https://www.refheap.com/paste/4660 (view the result here, try to click Bar Foo and Zon) and tell me if I'm doing crazy things?

15:19 acheng: clojure style question: to take a map and return a new one where any nil values have been replaced with empty strings, i wrote an fn that maps an if-statement, flattens, then apply's assoc on {} and the result. is there a better clojure way to do it?

15:19 amalloy: ~flatten

15:19 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

15:20 amalloy: i wonder how rude it would be to have lazybot notice any message with "flatten" in it and respond like that

15:21 acheng: i wouldn't mind if it provided an example as well :-P

15:21 technomancy: acheng: sounds like a classic reduce

15:23 Sgeo: amalloy, I wonder if its uselessness can be noticed by how in Haskell such a function can't be given a type

15:23 xeqi: ,(into {} (map (fn [k v] (vector k (if (nil? v) "" v))) {:a nil :b "b" :c "c"}))

15:23 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval27$fn>

15:23 Sgeo: Well, in Haskell, you can't even have lists that have different nesting levels

15:24 But flattenOneLevel :: [[a]] -> [a]

15:24 xeqi: ,(into {} (map (fn [[k v]] (vector k (if (nil? v) "" v))) {:a nil :b "b" :c "c"}))

15:24 clojurebot: {:a "", :c "c", :b "b"}

15:24 Sgeo: Pretty sure there's a real Haskell function

15:24 amalloy: Sgeo: it's concat

15:24 Sgeo: amalloy, indeed. I hoogled it >.>

15:24 amalloy: xeqi: (map (fn ...)) makes me so sad; just use (for ...)

15:24 xeqi: haha, habits

15:26 ,(into {} (for [[k v] {:a nil :b "b" :c "c"}] (vector k (if (nil? v) "" v))))

15:26 clojurebot: {:a "", :c "c", :b "b"}

15:26 acheng: thanks folks!

15:26 xeqi: will remember for next time

15:27 jkkramer: ,(= (vector :a 1) [:a 1])

15:27 clojurebot: true

15:27 xeqi: I've stopped using data literal syntax with variables, even though I know its safe here

15:27 acheng: oh. so in this case, which is preferable.. reduce or into ... or are these approaches basically equally good?

15:28 Chousuke: into is usually better if you're building a data structure.

15:29 jkkramer: into is shorter here. vs e.g. (reduce-kv (fn [m k v] (assoc m k (if (nil? v) "" v))) {} m). but either approach is fine

15:29 Sgeo: I really want to be able to browse the source of an item on clojars

15:30 llasram: IMHO `into` more directly expresses intent (vs just being shorter), and has the side effect of being more efficient due to internally using transients

15:31 alcy: cemerick: ping

15:31 cemerick: alcy: pong

15:31 mk: acheng: https://github.com/flatland/useful/blob/develop/src/useful/map.clj#L46 ?

15:31 alcy: cemerick: hi, had a question about the book you authored, is this one of the right mediums to ask ? :)

15:31 cemerick: sure, fire away

15:32 acheng: mk: ooh

15:33 alcy: cemerick: thanks, so i've made till destructuring, which started to pose some semantic confusion (coming from perl), but I have _just_ been able to understand the point minus the technical terms ... is this expected and things gonna get better ?

15:33 cemerick: for eg., the book doesnt tell me about seqs/vectors etc. formally, but I can kinda make out

15:33 cemerick: well by book, right now, I mean the first initial few topics

15:34 mk: acheng: I ended up asking the same question on the 14th, I think that was the best answer (provided by gtrak). You can look at what was said at http://clojure-log.n01se.net/date/2012-08-14.html , by ctrl-f "of map entries"

15:34 cemerick: alcy: seqs and vectors and all the rest are covered in depth later on; if you're still in chapter 1, the (significant) differences between seqs and vectors can be glossed over.

15:35 mk: acheng: I think I was worried about efficiency

15:36 alcy: cemerick: ah thanks, I suppose it will be two passes of the book & terminology when I start making real programs ;)

15:36 amalloy: Sgeo: petition library authors to include a :url entry in their project.clj

15:36 cemerick: alcy: Make sure you've got a working REPL going so you can experiment along the way. As for whether it's going to "get better"…well, part I of the book is purposefully intensive. Of course, feel free to jump around in order to get a better feel for details (e.g. certainly read about data structures straight off if that interests you).

15:36 alcy: cemerick: ah yes, definitely, I have been doing that

15:36 Sgeo: Why can't clojars just open the jar itself?

15:37 cemerick: alcy: tryclj.com is a good default, if you don't want to mess around with setting up tools, etc.

15:37 alcy: cemerick: oh trust me I have done that tutorial twice, in fact, I have been waiting for someone to complete it ;)

15:37 amalloy: why can't you? it's a lot easier to do on a local filesystem than it is for clojars to reinvent githubj

15:37 alcy: cemerick: unless you just meant to get the repl

15:37 :)

15:37 xeqi: and not every jar includes source

15:37 cemerick: alcy: well, I meant that it's a reasonable REPL in general.

15:38 alcy: cemerick: yep

15:38 Sgeo: Unless you want to mess with futures or agents

15:38 alcy: cemerick: do you think, a preliminary knowledge of some particular concepts help ? prerequisites of sort ?

15:38 cemerick: alcy: Well, carry on, and feel free to ask questions here; lots of people that know their stuff. :-)

15:39 alcy: cemerick: cool, thanks

15:39 cemerick: alcy: We refer to various resources along the way in the text, but I'd hope that nothing would be a prerequisite.

15:39 mk: if I have a map that's a few million entries long, and I want to do map-vals, which I expect to only change 3 values, how might I implement that in a way that doesn't create a brand new and huge map?

15:40 alcy: cemerick: hmm, alright. wonder if its just me who finds the info to be a little dense

15:43 SegFaultAX|work2: mk: If your only changing 3 values, then it's possible that most of the rest of the data structure will be shared.

15:43 mk: Clojure uses persistent data structures to help ameliorate problems like the one you just outlined.

15:43 wkelly: alcy: coming from a similar background, I think there's a pretty steep initial learning curve for clojure no matter which book you choose, but there really aren't too many fundamental concepts, so it does not stay too steep for too long

15:44 ordnungswidrig: is there a path for midje-mode to support nrepl?

15:44 s/path/patch/

15:44 alcy: wkelly: ah, thanks for the validation :)

15:44 mk: SegFaultAX|work2: the map-vals implementation I posted above doesn't seem to share that much structure

15:45 alcy: cemerick: thanks for your help too ! kinda like zen & the art of motorcycle maintenance where Pirsig leaves the difficult/dense part for a later chapter ;)

15:45 SegFaultAX|work2: wkelly: Unless you're new to functional and declarative programming entirely. That might increase the learning complexity.

15:45 mk: Oh? Is it possible you're using the wrong data structure or the wrong algorithm?

15:45 mk: For example. would a zipper be more suitable to your needs?

15:47 scriptor: mk: it doesn't share any structure because theoretically every element could be different

15:47 mk: so if you have a a map of entirely different values then of course you won't share any structure, but there's nothing to share

15:47 SegFaultAX|work2: I see. I don't really know of a good way to side-step that.

15:48 mk: How big is the map in question?

15:50 naeg: I /quit

15:51 mk: SegFaultAX: I'm imagining a very large map, for example a map of word pair frequencies, or something

15:52 amalloy: mk: map-vals isn't doing any structural sharing, because each key has a new value that it can't predict

15:52 scriptor: mk: you don't really need map-vals if you need to update frequencies or anything like that

15:52 amalloy: personally i don't advocate the use of any of the map-* or filter-* functions in useful.map

15:53 mk: scriptor: what do you suggest?

15:53 scriptor: mk: nothing wrong with assoc

15:54 SegFaultAX|work2: mk: Why would you only need to update 3 keys in a frequency map?

15:54 mk: my general idea is that I might have a large map where I only need to update a few keys. Assoc would do that?

15:54 amalloy: it's exactly what assoc is for

15:55 dnolen: what is decaf? https://gist.github.com/3491702

15:55 TimMc: SegFaultAX|work2: Perhaps when new data comes in?

15:55 ninjudd: dnolen: https://github.com/flatland/decaf

15:56 mk: SegFaultAX|work2: might be adding a 4-word sentence to a large frequency list

15:56 SegFaultAX|work2: Why does that require map-vals?

15:56 mk: amalloy: great - is there an impl of map-vals that's better suited for that?

15:57 amalloy: no, because map-vals is not a tool for doing what you said you need to do

15:57 map-vals iterates the whole map; you have a small number of known keys

15:57 dnolen: ninjudd: ah interesting approach - so it just always a keeps a second JVM ready to go.

15:58 tomoj: ninjudd: sounds like a great idea. but how to cleanup the reserve jvms? manually kill?

15:58 mk: SegFaultAX|work2: not sure, it might not. I don't really remember what case I had in mind earlier. I guess the idea was that you would map-vals over the map, and there's a good chance that only a few would be updated. Like map-vals-when?

15:59 tos9: a/11

16:01 amalloy: tomoj: i think he already has code to kill them after an hour or whatever length of time if they just sit idle. if he doesn't yet, he will soon

16:02 ninjudd: tomoj amalloy: haven't written that code yet but i did make an issue https://github.com/flatland/decaf/issues/2

16:02 tomoj: oh, cool

16:11 pbostrom_: does anyone know of a good "intro to Clojure" slide deck? I found a couple that look pretty good: http://stuartsierra.com/download/2011-09-18-strangeloop-clojure-intro.pdf and http://www.slideshare.net/theceo/introduction-to-clojure-9639369

16:20 alcy: pbostrom_: don't know about slide decks, probably just search on speakerdeck but http://blip.tv/clojure is also full of resources

16:20 pbostrom_: and infoq as well

16:24 Frozenlock: If any of you have 1 or 2 min to spare, could you look at this code https://www.refheap.com/paste/4660 (view the result here, try to click Bar Foo and Zon) and tell me if I'm doing crazy things? I wouldn't want to start my cljs adventure on a bad foot :-)

16:26 naeg: Frozenlock: did you ask on stack overflow for code review already?

16:27 nDuff: Isn't there a separate StackExchange site for review?

16:27 StackOverflow is more for specific questions

16:27 naeg: nDuff: dunno, but there is: http://stackoverflow.com/questions/tagged/code-review

16:27 nDuff: ..."please review this code" questions tend to get closed quickly

16:27 Frozenlock: No, I've never used it and it didn't think it was a question worth of it...

16:27 amalloy: http://codereview.stackexchange.com

16:27 nDuff: ^^ that.

16:28 naeg: oh, but still in beta. You either use that or stack overflow's code-review tag

16:28 why not try it Frozenlock? can't hurt I guess

16:29 (sry, new to Clojure too, can't help that much)

16:29 * nDuff would have to look at Meta -- he thought the agreed-on policy was that code review questions got closed for open-endedness.

16:30 Frozenlock: naeg: Sure I'll give it a try

16:30 naeg: Frozenlock: but use that codereview stackexchange

16:31 this questions suggest so: http://stackoverflow.com/questions/12098078/how-readable-is-this-line-of-code

16:33 Frozenlock: Oh wow... "To create code blocks or other preformatted text, indent by four spaces:" I wasn't on Emacs, I would cry.

16:34 Raynes: Frozenlock: copy them all and then ctrl+k

16:34 nDuff: Frozenlock: There's a javascript button to do that for you.

16:34 Frozenlock: ...so you can select your code in the browser's editor, click the {} symbol, and it does the indent.

16:34 * technomancy notes to his dismay that conkeror doesn't implement rectangle commands =(

16:36 Frozenlock: Raynes: That's for inline, no?

16:36 Raynes: I don't think so, no.

16:36 Frozenlock: nDuff: Indeed... I don't know why I stopped looking once I found the `code' button.

16:36 Raynes: There is a command that does it regardless, but what nDuff just said would work too.

16:37 emezeske: Frozenlock: I am not sure about this, but I kind of seem to think that things like (js/jQuery.plot) only work by accident, and that you should use (.plot js/jQuery) instead

16:37 Frozenlock: I could be wrong though.

16:37 amalloy: hah, i never even noticed SO had wysiwyg-style editor buttons. i just have a keybinding in emacs for "copy all this, and indent it by four spaces"

16:39 Frozenlock: emezeske: I have found js/jQuery to be working sporadically. I still don't know why :(

16:39 casion: technomancy: rectangle commands are out there for cokeror

16:39 emezeske: Frozenlock: What do you mean by sporadic?

16:39 casion: there was someone on the IRC channel who implemented them

16:39 conkeror*

16:40 technomancy: casion: as a third-party lib?

16:40 casion: technomancy: yes

16:41 technomancy: huh; cool

16:41 Frozenlock: emezeske: Sometimes it works, other it doesn't.

16:41 technomancy: I wonder if it'd be good enough to merge into mainline

16:42 emezeske: Frozenlock: Can you be more specific? Like, what happens when it doesn't work? An exception? A compile warning? Does it ever fail without recompiling, and just refreshing the browser?

16:45 bosie: technomancy: are you responsible for clojure at heroku?

16:46 technomancy: bosie: yeah, what's up?

16:46 bosie: technomancy: no, nothing. was just wondering if you do ruby or clojure there

16:46 technomancy: I do a bit of ruby here and there

16:47 bosie: why the heck are you fluent in indonesian/malaysian?

16:48 technomancy: I grew up in Indonesia

16:48 also, it's literally the easiest non-artificial language in the world

16:48 bosie: cool

16:48 Frozenlock: emezeske: Sure, sorry about that. So if it works for a function, it will always work, but not all function are ok with this. For example, If I want to use the .datepicker from jQuery, I need to call it directly: (.datepicker ($ :#datepicker)). Calling it as I did with the .plot, (js/jQuery.datepicker ($ :#datepicker)) will result in this: #<TypeError: Property 'datepicker' of object function (a,b){return new p.fn.init(a,b,c)} is

16:48 function>

16:48 bosie: easy to say if you grew up there ;)

16:49 emezeske: Frozenlock: I think sporadic is not the right word for that. Inconsistent, maybe?

16:49 Frozenlock: Anyway, I'm pretty sure js/Something.anything is wrong

16:49 Frozenlock: If you want to call something on the jQuery object iself, (.member js/jQuery)

16:49 Frozenlock: If you want to call something on a jquery container: (.member ($ thing))

16:50 Sgeo: http://nathanaeljones.com/45/clojure-cross-platform-fast-concurrent-concise/

16:50 Frozenlock: Definition of SPORADIC

16:50 : occurring occasionally, singly, or in irregular or random instances (from merriam-webster)

16:50 Sgeo: What's this about edit-and-continue?

16:50 Frozenlock: I like my words :)

16:50 emezeske: Frozenlock: "irregular"

16:50 Frozenlock: I promise that it works regularly, just not how you expect

16:50 Frozenlock: Sporadic would be if js/jQuery worked when you ran the code once, but not the next time you ran the same code

16:52 Frozenlock: Anyway, you want to avoid js/Stuff as much as possible. Wrap js/jQuery in a function, and use that, and never use js/Whatever anywhere else in your code, and you'll be fine

16:53 Frozenlock: Ok, for a particular instance, it's consistent (js/jQuery.plot), but for the usage of js/jQuery it's irregular.

16:53 But what's wrong with it?

16:54 Shouldn't js/jQuery be able to call ev-e-ry thing?

16:55 emezeske: Well, the fact that it does unexpected things seems like a great reason not to use it

16:55 And again, I really don't think js/Thing.member is supposed to work, I think that's an accident

16:55 Anyway, feel free to not listen to me, I'm just throwing out some suggestions

16:56 SegFaultAX|work2: emezeske: Why should you wrap js/* in a function?

16:56 emezeske: (I have never used cljs)

16:57 Frozenlock: Hey, I really appreciate, I just didn't want to rely on rule of thumbs.

16:57 Please, feel free to suggest anytime :)

16:58 emezeske: SegFaultAX|work2: I just suggest it to keep the code as clojure-y as possible

16:58 SegFaultAX|work2: js/ is a bit of an escape hatch to JS, and you can do silly things with it -- it's nice to just hide it away and do everything clojure-y

17:00 Sgeo: ,(.toUpper "hm")

17:00 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: toUpper for class java.lang.String>

17:00 hyPiRion: ,(.toUpperCase "hm")

17:00 clojurebot: "HM"

17:00 Sgeo: ,(map .toUpperCase '("hm" "argh"))

17:00 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: .toUpperCase in this context, compiling:(NO_SOURCE_PATH:0)>

17:00 Sgeo: ,(map #(.toUpperCase %) '("hm" "argh"))

17:00 clojurebot: ("HM" "ARGH")

17:01 hyPiRion: ,(map (memfn toUpperCase) ["hm" "argh"])

17:01 clojurebot: ("HM" "ARGH")

17:01 hyPiRion: ,(doc memfn)

17:01 clojurebot: "([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."

17:01 brehaut: ,(map (memfn toUpperCase) ["hm" "argh"])

17:01 clojurebot: ("HM" "ARGH")

17:02 Sgeo: is there an equivalent for static methods?

17:16 tanzoniteblack: Sgeo: generally I just use the #() for statics

17:16 ,(map #(String/valueOf %) [2 3])

17:16 clojurebot: ("2" "3")

17:17 Sgeo: I'm going to end up learning the Java standard library, aren't I? :/

17:17 tanzoniteblack: what static method do you need?

17:17 SegFaultAX|work2: Is there a function to get every nth element of a seq given some step. Like the first, third, fifth, seventh, etc.

17:18 Ah, take nth.

17:18 magopian: guys, i'm pondering at problem 113 on 4clojure at the moment (http://www.4clojure.com/problem/113), but can't find how to tackle it

17:19 Sgeo: tanzoniteblack, I mean, just in general for using Clojure

17:19 magopian: may i have a hint on what to use? I'm just a noob in clojure, so i'm believing i'm missing some kind of language construct/feature that would allow some data to be represented differently if it's "str" or "seq"

17:20 for example, using python, i would play with __str__ and __iter__

17:20 brehaut: magnars: i havent solved that one, but it looks like reify might be a good play to start

17:20 tanzoniteblack: ,(let [my-list '("one" "two" "three" "four")]

17:20 (map #(nth my-list %) (range 0 4 2)))

17:20 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

17:20 tanzoniteblack: whoops, messed that up

17:20 but nth will get the nth item from a set

17:20 and you can use that as a function

17:20 SegFaultAX|work2: tanzoniteblack: If that's for me, take-nth is a thing.

17:20 magopian: brehaut: i think that was for me and not magnars ;) thanks for the tip, i'm going to find some documentation on reify

17:21 brehaut: magopian: yes. sorry

17:21 magopian: brehaut: no problem, thanks for the tip ;)

17:21 tanzoniteblack: Sgeo: the nth thing was for you

17:21 ,(let [my-list '("one" "two" "three" "four")] (map #(nth my-list %) (range 0 4 2)))

17:21 clojurebot: ("one" "three")

17:21 Sgeo: tanzoniteblack, wait, what? why am I being told about nth?

17:21 brehaut: magopian: you now about the doc command?

17:22 s/command/function/

17:22 tanzoniteblack: no wait...I'm confusing myself now, that was for SegFaultAX|work2

17:22 SegFaultAX|work2: tanzoniteblack: And see my reply.

17:22 magopian: brehaut: i think so (doc reify)

17:22 however, it doesn't seem to work in the LightTable playground ;)

17:23 &(doc reify)

17:23 lazybot: ⇒ "Macro ([& opts+specs]); reify is a macro with the following structure: (reify options* specs*) Currently there are no options. Each spec consists of the protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodNa... https://www.refheap.com/paste/4663

17:23 tanzoniteblack: SegFaultAX|work2: cools, I hadn't seen take-nth before, thanks

17:24 mpenet: Sgeo: not necessarly, there are lua, c, js, gambit scheme, clr, python and probalbly more implementations out there

17:27 At this point it depends on what you intend to do. Playing with the language, or getting things done, if that is the later the JVM or clojurescript is your best bet for now.

17:27 magopian: brehaut: wow, the doc of reify speaks chinese to me ;)

17:27 brehaut: haha

17:27 sorry

17:28 ordnungswidrig: you'll understand the doc when you understand reify

17:28 magopian: brehaut: however, the doc seems to more or less answer the exact problem stated in 4clojure ;)

17:29 (with str and seq ;)

17:29 i should be able to work something out

17:29 ordnungswidrig: that's scary :)

17:29 ordnungswidrig: and will i understand reify when i understand the doc? ^^

17:29 hyPiRion: Wow, the reify-doc is horrible.

17:30 magopian: hyPiRion: dunno, i can hardly understand half of it

17:30 but i keep re-reading it, i'll make some sense out of it ;)

17:30 hyPiRion: magopian: Look at examples, they give you a better understanding.

17:31 ordnungswidrig: the best part: (reify options* specs*) … Currently there are no options.

17:31 magopian: hyPiRion: yup, thanks for the tip

17:31 ordnungswidrig: this is what I call a real optional parameter

17:31 * Sgeo wonders if this can be used to make a sane way to do return-type based polymorphism

17:31 ordnungswidrig: Sgeo: no

17:36 magopian: mmm i'm going to get some sleep now, i'm sure it'll make more sense tomorrow ;)

17:36 SegFaultAX|work2: For http://www.4clojure.com/problem/50, is this cheating? (comp vals (partial group-by type))

17:36 magopian: SegFaultAX|work2: why would it be cheating?

17:36 amalloy: any solution that works isn't cheating. you heard it here first, folks

17:37 magopian: amalloy: thanks for 4clojure ;)

17:37 it's what drives me to learn more clojure, day after day ;)

17:37 (and keeps my brain awake)

17:37 SegFaultAX|work2: amalloy: It just seems slightly abusive. :)

17:37 magopian: well, it's going to sleep now, but you get my point ;)

17:37 good night folkds

17:38 Raynes: amalloy: I saw something implement the nth problem with '.get'

17:38 I lol'd

17:38 amalloy: nice

17:49 hiredman: ob

17:58 SegFaultAX|work2: To do #53 on 4clojure, I've written the following: https://www.refheap.com/paste/4665 Does this seem generally useful? Is there a better way?

18:00 Frozenlock: Am I a bad person for never using defn- ?

18:01 dnolen: Frozenlock: no

18:01 ordnungswidrig: Frozenlock: No, unless you're using (defn ^:private) :-)

18:01 Raynes: Implying that (defn ^:private ..) is bad?

18:02 SegFaultAX|work2: Is it functionally different from (defn- ...)?

18:02 Raynes: No.

18:02 xeqi: I don't like to make functions private, but when I do I use (defn ^:private ..)

18:02 Raynes: And it is much more consistent with the rest of Clojure.

18:02 SegFaultAX|work2: Ah.

18:02 Raynes: defn- is more of an artifact of the past than anything.

18:02 hyPiRion: SegFaultAX|work2: If you generalize it, it would proably be a bit more... general

18:02 Raynes: Which is why there isn't any def-, for example.

18:03 ordnungswidrig: dnolen: is core.logic capable of generating solutions that are lists in a "minimal" way? it's finite domain.

18:03 SegFaultAX|work2: Is there something wrong with private functions? It seems like keeping your namespace API uncluttered with internal functions is a good thing.

18:03 dnolen: ordnungswidrig: what do you mean?

18:03 ordnungswidrig: dnolen: so, give a list of chess queen positions such that every field on the board is attacked.

18:04 dnolen: there are a lot of solutions, some are smaller than others

18:04 nDuff: SegFaultAX: The place where they annoy me are cases where I want to replace some parts of functionality in 3rd-party code while retaining those which overlap, but where the overlap is all in functions marked private.

18:05 ordnungswidrig: dnolen: i'm not interested in the theoretical minimum, though. building the constrainst, such that the "first" solution is a small one would do.

18:05 nDuff: SegFaultAX: ...and with respect to namespace cleanliness, there's an argument to be made that global refers are Doing It Wrong anyhow.

18:05 SegFaultAX|work2: nDuff: Well if it's private that probably means "internal implementation detail," right? Do wouldn't monkey patching that be pretty bad anyway?

18:05 So wouldn't*

18:06 dnolen: ordnungswidrig: are you specifically interested in an nqueens solution? Martin Trojer did one.

18:07 Frozenlock: Thanks guys, I wasn't expecting so much details :)

18:07 SegFaultAX|work2: dnolen: That's a pretty compact solution, too.

18:08 dnolen: ordnungswidrig: but perhaps I understand what you are asking ... and I believe the answer is yes. the new core.logic alphas support constraint logic programming over finite domains.

18:08 ordnungswidrig: dnolen: no, it was only an example. I have a list of devices which have each some properties which values are in a finite domain. I want to generate a set of devices such that 1) every possible value of a single property is covered. 2) every pairwise combination of two properties values are coverred.

18:09 dnolen: like device1: big, yellow, expensive device2: big, green, cheap, device3: big, yellow, cheep.

18:09 dnolen: (d1,d2) would cover every property value.

18:10 dnolen: but for pairwise it would miss a device that is "yellow+cheap"

18:14 hyPiRion: ordnungswidrig: So put differently, given a set of vectors on the form [x_1 x_2 ... x_n], find the minimal solution where every pair [x_a x_b], 1 <= a, b <= n, is contained within the solution.

18:15 dnolen: ordnungswidrig: you could encode those values as integers - I've been thinking about some sugar to make it less tedious.

18:15 ordnungswidrig: hyPiRion: yes, I think this is the formalized variant

18:15 dnolen: integers would be ok

18:15 I can map them back later

18:15 dnolen: ordnungswidrig: will have to wait for some refactoring of the constraint solver.

18:15 ordnungswidrig: then yes that works just fine.

18:16 ordnungswidrig: that's precisely what I did here, http://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic/bench.clj#L398

18:17 ordnungswidrig: dnolen: how would I ensure that a "minimal" solution will be found?

18:19 dnolen: ordnungswidrig: hmm ... I believe there are some ad-hoc tricks for that in CLP(FD) literature. More explicit support may be possible a la Mozart/OZ, but I've got nothing planned in the near future.

18:19 ordnungswidrig: ok

18:19 I'll dig the literature then

18:20 hyPiRion: ordnungswidrig: It's an interesting problem though, thanks for sharing.

18:20 dnolen: ordnungswidrig: google for "Finite Domain Constraint Programming in Oz. A Tutorial.". Most of my understanding of CLP(FD) and far beyond is from their. Haven't time to dig into - there are some things that need fixing first to tackle even the simplest CLP(FD) problems they talk about.

18:21 ordnungswidrig: dnolen: ok, thanks!

18:21 I'll go to bed now. Hammock time, or like that.

18:22 dnolen: ordnungswidrig: I would like a lot of that text to applicable to Clojure. Though the search strategy may be challenging since that's not really covered in the original cKanren design.

18:22 ordnungswidrig: dnolen: I'd love it!

18:22 bye!

18:23 XPherior: with-redefs.. It redefines something within the scope of it's calling that macro. But it doesn't seem to redefine it in other namespaces?

18:24 IE, I redefine the function b to be something else. Within the with-redefs, function a calls b. b appears to be the original b, not the one I substituted in.

18:27 I guess what I'm asking for is a "global function redefinition"

18:30 technomancy: XPherior: with-redefs works in terms of vars. if someone has a copy of the original version in a local or some such, there's no way to change it.

18:31 other than to pass around vars instead

18:31 XPherior: technomancy: It's merely calling the other function via namespace. No functions with side effects.

18:31 SegFaultAX|work2: hyPiRion: Was that about my code post?

18:31 XPherior: How would one "hold onto" a function in Clojure?

18:31 Well, I guess with def. But I don't see a case where I used that.

18:38 technomancy: the classic example is with (run-jetty app {:port 8080})

18:38 Sgeo: It occurs to me that if I keep getting bothered when I see individuals who are crucial to an ecosystem in an IRC channel, I will always be bothered

18:39 technomancy: with-redefs and recompilation won't be visible to jetty since you're passing the value of app; you have to pass in #'app

18:39 XPherior: technomancy: Go on

18:39 hyPiRion: SegFaultAX|work2: oh, second.

18:39 XPherior: Hm..

18:39 SegFaultAX|work2: hyPiRion: I'm interested in your thoughts on how I could make it better.

18:39 XPherior: Okay, I think that puts me on the right track, technomancy

18:40 I'll be back. Gonna switch out to Linux so I can hack on the problem more.

18:40 Thanks again!

18:40 hyPiRion: SegFaultAX|work2: So instead of taking 2 elements, namely prev and current, you could take more than 2

18:41 Like n-2 n-1 and n.

18:41 SegFaultAX|work2: hyPiRion: I don't know how to make that very general. The usage I was looking at was something like (take-seq #(= (inc %1) %2) [1 2 3 4])

18:42 hyPiRion: It would return [1 2 3 4]. But if that seq was, say, [1 2 3 5 6 7] it would only return [1 2 3]

18:42 hyPiRion: SegFaultAX|work2: What would that one return?

18:42 oh, okay.

18:43 hmm, second

18:43 SegFaultAX|work2: hyPiRion: So where take-while returns values as long as the predicate is true, take-seq does the same thing but it allows you to work with the current and last value to recognize a sequence.

18:55 hyPiRion: SegFaultAX|work2: https://www.refheap.com/paste/4667

19:01 SegFaultAX|work2: hyPiRion: Awesome!

19:03 hyPiRion: SegFaultAX|work2: It's not perfect though - it cannot take in an infinite seq and return a new infinite seq

19:04 Though if it helps you in any way, then I'm glad to be of help :)

19:04 SegFaultAX|work2: hyPiRion: I wanted mine to work on infinite seqs which is why it's so verbose. But your solution is a lot cleaner and more general than mine.

19:05 partition* are awesome.

19:06 wmealing_1: SegFaultAX|work2: did you find an built-in function to split a list on a condition (dichotomize-by ?

19:06 hyPiRion: yeah, partition and partition-all are more powerful than I thought they would be

19:06 SegFaultAX|work2: wmealing_1: Not a built-in, no.

19:06 * technomancy implements trichotomize-by

19:07 * emezeske implements quadchotomize-by

19:07 SegFaultAX|work2: wmealing_1: (juxt remove filter) was good enough for my purposes.

19:07 * emezeske preemptively implements polychotomize-by

19:07 hyPiRion: split-with?

19:07 SegFaultAX|work2: hyPiRion: Nope.

19:08 wmealing_1: had me scratching my head for a bit.

19:08 hyPiRion: Hum, okay

19:08 Oh, yeah, I see.

19:08 wmealing_1: i ended up writing my own, but i wasn't happy.

19:08 SegFaultAX|work2: wmealing_1: The only downside is running through the list twice instead of separating it in one pass.

19:09 hyPiRion: ,(vals (group-by odd? (range 10)))

19:09 clojurebot: ([0 2 4 6 8] [1 3 5 7 9])

19:09 hyPiRion: The order is scary though

19:09 ,(vals (group-by even? (range 10)))

19:09 clojurebot: ([0 2 4 6 8] [1 3 5 7 9])

19:09 hyPiRion: So scratch that.

19:10 SegFaultAX|work2: hyPiRion: Yea. This was for a quicksort so I wanted to have all the numbers >= pivot separated from the rest.

19:11 hyPiRion: My initial solution started with a group-by. The juxt one was better, minus the aforementioned speed penalty.

19:11 (Better in terms of code size.)

19:12 amalloy: SegFaultAX|work2: shouldn't take-seq just use partition?

19:13 hyPiRion: ,(separate odd? (range 10))

19:13 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: separate in this context, compiling:(NO_SOURCE_PATH:0)>

19:13 SegFaultAX|work2: amalloy: How do you mean? I wanted it to be able to recognize arbitrary sequences, not just increasing or decreasing.

19:13 XPherior: Hey technomancy. The function I'm trying to redefine in used by a route in Compojure's defroutes macro. It must be hanging onto the value of the function that I told it to call when it hits the respective route, huh?

19:14 amalloy: &((fn take-seq [pred coll] (map second (filter (partial apply pred) (partition 2 1 coll)))) #(= %2 (inc %1)) [1 2 3 5 6 9])

19:14 lazybot: ⇒ (2 3 6)

19:15 SegFaultAX|work2: amalloy: That's not correct.

19:15 technomancy: XPherior: yeah, just using a var instead should do the trick

19:15 amalloy: it matches your docstring

19:15 XPherior: technomancy: Hm? Instead what?

19:16 technomancy: instead of the value of the var

19:16 amalloy: if you want to include the 1 at the front, then you can do the three-arg vs two-arg thing, but i was just demonstrating using partition instead of lazy-seq

19:16 SegFaultAX|work2: amalloy: Then my docstring sucks. For context I was working on 4clojure #53

19:16 amalloy: Longest subseq of increasing integers.

19:16 amalloy: Yours does not return the correct answer.

19:17 XPherior: technomancy: Yeah, that seeems correct. I don't see how to be able to override it for testing though. Is it just not possible? Sorry, my understanding is a little fuzzy here.

19:18 SegFaultAX|work2: amalloy: Did you catch hyPiRion's solution? https://www.refheap.com/paste/4667

19:18 amalloy: I'm still looking for a good way to implement the general take-seq/take-while-partition "take the longest contiguous sequence given some predicate" function.

19:19 XPherior: Oh technomancy, sorry I read that wrong. Makes more sense now.

19:26 amalloy: SegFaultAX|work2: useful.seq/glue has a pretty thorough implementation of that sort of "split a sequence up into N chunks" idea, although it's so flexible it's a bit unwieldy to use in most real-life cases. https://gist.github.com/3493313 has an example usage, and docstring is at https://github.com/flatland/useful/blob/develop/src/useful/seq.clj#L193

19:33 hyPiRion: Ah, SegFaultAX|work2, https://www.refheap.com/paste/4669 works on infinite lists too.

19:35 XPherior: Why would something like with-redefs [#'ns/func substitute-fun] throw lojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

19:35 Werd

19:36 amalloy: &(doc with-redefs)

19:36 lazybot: java.lang.SecurityException: You tripped the alarm! with-redefs is bad!

19:36 amalloy: ,(doc with-redefs)

19:36 hyPiRion: haha

19:36 clojurebot: "([bindings & body]); binding => var-symbol temp-value-expr Temporarily redefines Vars while executing the body. The temp-value-exprs will be evaluated and each resulting value will replace in parallel the root value of its Var. After the body is executed, the root values of all the Vars will be set back to their old values. These temporary changes will be visible in all threads. Useful for mockin...

19:36 amalloy: XPherior: read the docstring

19:37 XPherior: amalloy: I have many times. =/

19:37 #' returns a var, as far as I understand. Passing that in as the first element in the vector should be fine

19:37 amalloy: what do you suppose var-symbol means? i would bet money that it means "this should be a symbol"

19:38 XPherior: I suppose that makes a bit more sense. But, when I do that, I just get that 'cons cannot be cast to symbol'

19:38 I mean, when it says it rebinds vars, it seems like it wants a var to target.

19:39 Apage43: it does (var) aka #' internally.

19:40 https://github.com/clojure/clojure/blob/d0c380d9809fd242bec688c7134e900f0bbedcac/src/clj/clojure/core.clj#L6589

19:40 XPherior: I can't just pass in the function value, because as technomancy were talking about earlier.. Another function already has the value of that function. I'd need to redefine the function at the var level

19:41 Apage43: with-redefs is a macro, so you're passing it symbols, not values

19:46 Frozenlock: I've stumbled uppon this nice little function in a C2 demo code: (defn evt->key [e] (get {13 :enter} (.-keyCode e))) Is it the idiomatic way to get a keypress?


19:47 dnolen: Frozenlock: yes

19:48 Frozenlock: dnolen: thank you

20:01 SegFaultAX|work2: amalloy: Awesome, thanks for the tip. I hadn't heard of useful until now.

21:18 cjfrisz: Everybody must be hard at work here

21:20 stankley: cjfrisz: Very much so...

21:22 cjfrisz: Seeing as though I broke my parser last night and it's still mad at me, I should probably be harder at work

21:27 Frozenlock: Ah crap, I think I opened a can of worms.

21:28 -=keyCodes=-

21:28 uvtc: Hey, where did all these worms come from? ... Frozenlock!

21:31 cjfrisz: Man...sometimes I think Clojure has too few parentheses

21:31 * cjfrisz is not trolling

21:31 shaungilchrist: ahaha

21:32 cjfrisz: Take "cond" for instance

21:32 Frozenlock: cjfrisz: Yeah, I don't feel the rush of adrenaline caused by closing 20 parentheses! ))))))))))))))))0

21:33 cjfrisz: Scheme has an extra set of brackets around each clause

21:33 This makes indent functions in text editors much happier if you need to make a line break after the test

21:33 shaungilchrist: I like to accelerate as I type them so it's literally a rush

21:49 Frozenlock: Before I waste a night trying to make some hotkeys functions for cljs, does anybody know if there's already a library for this? (in cljs)

21:59 Raynes: Frozenlock: Why does it have to be in cljs?

22:03 Frozenlock: It could also be in google closure (I haven't found one). If I understand correctly, google closure or cljs are what is required to be able to use the compiler efficiently.

22:31 Spaceghostc2c: Please sir, may I have some clojure?

22:34 cjfrisz: Spaceghostc2c: ...yes?

22:34 Spaceghostc2c: cjfrisz: I think my british accent was off.

22:34 cjfrisz: Oh!

22:34 Spaceghostc2c: More?

22:34 Spaceghostc2c: You want *MORE*??

22:34 lazybot: cjfrisz: What are you, crazy? Of course not!

22:34 * Spaceghostc2c has left

22:36 Spaceghostc2c: Well done gents! We'll be here all week.

23:06 emezeske: Frozenlock: You can use any javascript library you want from cljs, as long as you provide an :externs file

23:07 Frozenlock: (The :exterms file lets you compile with :advanced optimizations)

23:10 Frozenlock: emezeske: But the extern files won't be included in the generated js?

23:10 (that might not be a big deal)

23:11 emezeske: Frozenlock: This probably will answer your question: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html

23:11 Frozenlock: Thanks!

23:45 TimMc: Frozenlock: Man, who even types closing parens?

23:45 That's so... without paredit. :-P

23:46 cjfrisz: So...I used to use paredit

23:46 tomoj: that's surprising

23:46 cjfrisz: And I had a couple of very prolific Schemers convince me that it can be detrimental to hacking out scraps of code

23:47 There are things I miss about it, but I think I am overall happier

23:47 You inherently get corralled into writing your code in a particular way when you use tools like paredit that force structure on your coding while you're in the process of writing it

23:48 uvtc: TimMc: I have not yet drank of the paredit coolaid. I kinda' like watching those matching parens light up when I type the closing ones. :)

23:48 cjfrisz: There's nothing necessarily wrong with it, but it is something I hadn't thought about when I started using it

23:48 uvtc: I totally drank the paredit coolaid at first ;-)

23:48 arohner_: cjfrisz: it convinces you to *type* your code in a different way, but I'm reasonably sure I'm net productive on it

23:48 Frozenlock: TimMc: Yeah, paredit is among the numerous tools I've yet to try.

23:49 arohner_: never having misbalanced parens has definitely improved my flow

23:49 cjfrisz: arohner_: Mileage may vary

23:49 arohner_: I don't doubt that you are very productive, and you may even be moreso than me

23:49 tomoj: you get corralled into writing your code in valid forms

23:49 how could that be a bad thing?

23:49 eggsby: did anyone itc finish stripes CTF and mind lending a hint ?

23:49 emezeske: cjfrisz: You get corralled into writing code that has balanced and structurally correct paranthesis, but that's about it

23:50 Every time you balance parens manually, God kills a kitten and replaces it with a slightly less productive kitten

23:52 Frozenlock: Eh, the time I waste writing parens in clojure is negligible.

23:52 I waste way more time by being stupid.

23:52 \o/

23:52 tomoj: it's not just auto-balancing

23:53 uvtc: Might save my right pinky some fatigue though ... not having to reach for that closing paren. :)

23:53 tomoj: (and you must also count the time spent dealing with balance errors)

23:53 emezeske: Tell me this: do you literally count the number of parens at the end of a function sometimes? And that doesn't drive you bats?

23:53 Frozenlock: (show-paren-mode)

23:54 emezeske: Still, you're basically counting. Keep moving the cursor until the paren you want is highlighted, right?

23:54 uvtc: I never count ... just let Emacs show me the matching one. It smartly highlights it when the cursor is just after the closing one.

23:55 Frozenlock: Yes.

23:55 * emezeske cringes.

23:55 Frozenlock: I can has bad methodz?

23:55 emezeske: To each his own.

23:55 TimMc: You don't have to use it, but you do have to try it.

23:56 cjfrisz: emezeske: That's really the crux of it

23:56 I used to have a workflow that jived with paredit

23:56 Frozenlock: Yes it's on my todo list. This and elnode are on the top.

23:56 uvtc: Will try it, at some point ... just need to get this program working ...

23:56 cjfrisz: And then I worked with some people who showed me a workflow where paredit kinda got in the way

23:56 emezeske: cjfrisz: Like what?

23:56 cjfrisz: And for now I use the latter

23:56 TimMc: It's more than paren balancing -- it is structural editing. Kill a whole form at a time, or transpose it with another, or convolute them...

23:56 emezeske: I cannot possibly see how it could get in the way.

23:57 tomoj: cjfrisz: any possibility you can give an example?

23:57 Frozenlock: TimMc: To select forms I like expand-region.el

23:57 TimMc: It's hard to give examples, since code evolves in weird ways.

23:57 emezeske: You can always shut paredit off temporarily while you do some crazy pasting, and then turn it back on

23:58 Frozenlock: http://emacsrocks.com/e09.html

23:58 cjfrisz: Maybe it's less that it gets in the way and more that it's just not helpful

23:58 I've started writing more of an unfinished scrap here, moving on, and then coming back to the unfinished bits

23:59 emezeske: I refuse to believe that it's more productive to write in units of not-even-structurally-correct code.

23:59 cjfrisz: I found it more helpful when there were no scraps; only plunking out complete thoughts at a time

23:59 emezeske: That's fine; you don't have to

Logging service provided by n01se.net