#clojure log - Mar 29 2013

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

0:01 thm_prover: dnolen: Professor Nolen, why is http://hpaste.org/84801 invalid match code?

0:03 technomancy: ,(apply merge-with #(if (coll? %1) (conj %1 %2) [%1 %2]) '(["tyler" 23] ["tyler" 34] ["don" 64]["don" 82]))

0:03 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.util.Map$Entry>

0:04 technomancy: you get the idea

0:04 dnolen: thm_prover: are you doing this in ClojureScript?

0:04 thm_prover: dnolen:, no in clojure, cljs is "list of files ending with *.clj"

0:04 tyler: technomancy: thnx

0:04 thm_prover: dnolen: yeah, sorry about bad var name

0:06 dnolen: thm_prover: lists are special in core.match, they denote some special syntax

0:06 thm_prover: dont use () use []

0:07 admitted it should give you a more sensible error

0:08 technomancy: is there a gsoc project to fix that? =)

0:08 thm_prover: dnolen: ah, https://github.com/clojure/core.match/wiki/Overview has it under "Special Syntax"

0:10 dnolen: technomancy: heh :)

0:17 `arrdem: hum... fnparse is mucking with me agian and this time it isn't a function of my return values.

0:18 https://www.refheap.com/paste/13067

0:18 thm_prover: does (java.io.File. ...) actually open the file (and thus use up a descriptor), or does it just create a File object?

0:20 technomancy: thm_prover: the latter

0:20 you need to create a reader or input-stream to open it

0:21 thm_prover: technomancy: are the following two staements correct? (1) I do not need to manually close it and (2) I do not need to use with-open

0:21 technomancy: true of a File object, sure

0:22 thm_prover: technomancy: great, thanks!

0:22 technomancy: ,(isa? java.io.File java.io.Closeable)

0:22 clojurebot: false

0:22 technomancy: np

0:24 muhoo: is this already in clojure somewhere, and did i reinvent the wheel? https://www.refheap.com/paste/13068

0:25 `arrdem: I think I've seen this before... but I won't say for certain.

0:25 no that was core/replace

0:25 muhoo: my brain thinks in SQL, so i was trying to make a function to do f to all values in column y in a "database", can't help thinking of lists of maps as rows in an sql database

0:26 `arrdem: muhoo: I think you're in the clear here.. nice snippet too. core/replace is the only similar thing I've seen and that just takes a replacement map not an update-fn map

0:31 muhoo: `arrdem: thanks. i've been hammocking that snippet all day, finally took a walk to the grocery store and went "oh! duh!" on the way back.

0:31 supersym: assoc keys can't be variables? Key must be integer exception

0:32 dnolen: supersym: you probably have a simple error somewhere in your code

0:32 ,(assoc [0 1 2] nil :hello)

0:32 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer>

0:33 supersym: (defn update-atom [n] (swap! section (assoc @section n 1)))

0:33 dnolen: supersym: somehow n is not an integer

0:34 momomomomo: I've never seen that bot before; that's neat.

0:34 supersym: yes very :)

0:34 muhoo: momomomomo: there's two of 'em, never can keep them straight

0:34 one is , the other is &&, i think.

0:34 momomomomo: haha, I like it.

0:35 This weekend is the weekend! Only a few projects to work on, and I'll for sure (hopefully) have some time to finally crack open a clojure book

0:36 supersym: weird (update-atom 3) is an integer I think

0:36 dnolen: supersym: your swap! is wrong

0:36 ,(doc swap!)

0:36 clojurebot: "([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

0:37 supersym: ah

0:37 dnolen: supersym: you don't need those parens, not deref of section

0:37 s/not/nor

0:37 supersym: parens did it

0:37 dnolen: (swap! section assoc n 1)

0:37 supersym: thanks m8!

0:37 dnolen: supersym: make sure to remove @section too

0:40 supersym: riiight... how did I get that wrong. Cue to get to bed

0:41 thanks a bunch for the insights/aid

0:58 augustl: looking for some tips on how to do websockets from a Clojure app. Thinking I'll just deploy with java -jar. I've used Faye with Node.js before, and it seems it should work fine with the comet.d Java lib. Any other suggestions?

0:59 s/websockets/websockets with xhr fallback/

0:59 `arrdem: so what's the difference between next and rest?

1:01 amalloy: &((juxt next rest) [1])

1:01 lazybot: ⇒ [nil ()]

1:01 `arrdem: feh ok

1:01 cheers amalloy

1:02 dnolen: `arrdem: rest can be lazy, next isn't

1:03 `arrdem: that makes more sense. thanks dnolen.

1:27 maybe-m just escapes at the first nil return value, right?

1:31 amalloy: depends whose implementation of maybe-m, `arrdem. that's what algo.monads does, but that's breaking the monad laws: using nil for Nothing means it's impossible to represent things like Maybe Maybe Int

1:33 `arrdem: amalloy: okay.. I think I understand that but I sure don't grok it.

1:33 SegFaultAX: `arrdem: Are you just curious about monads or are you trying to do something in particular?

1:34 `arrdem: SegFaultAX: so at the moment I'm trying to trace a bug that's somewhere between Factual/fnparse and monads since I seem to be able to reproduce it no matter what the return values from my code are.

1:35 however my monad-foo is weak and I need to understand them it seems before I can really follow what's going on under the covers here.

1:36 that said it's 0035 and this project was due at 0000 so I may just hit the sack and look at this again after I get 8.

1:36 SegFaultAX: `arrdem: Clojure is probably a less than ideal language to learn about Monads in. May I suggest this: http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html

1:37 `arrdem: The material is not necessarily to Haskell and the introduction is sufficient to get you started assuming you already have a solid understanding of type system fundamentals.

1:40 tomoj: consider a protocol fn which returns either another object of the same type as `this`, or nil

1:40 can we eliminate truth calls in some other way than (if (nil? (f this)) ...) ?

1:42 ..if you tag it boolean, it will be marked as a safe test, and it will actually be safe, even though it's not boolean?

1:42 s/protocol//

1:43 looks like the 'seq tag has a closer meaning

1:43 SegFaultAX: tomoj: Why not just (if (f this) ...)

1:44 tomoj: nil is false in a boolean context.

1:44 tomoj: background: in cljs, (if x y z) emits a call (cljs.core/truth_ x) if x is not known to be safe to put directly in a JS if test

1:45 SegFaultAX: tomoj: Ah, cljs.

1:47 `arrdem: SegFaultAX: good post, thanks

1:48 gah 10 to read that? I'm worthless good evening gents

1:48 tomoj: dnolen: would you consider a patch which just adds a direct 'safe-test pseudotag, for use in performance sensitive code (similar to not-native)?

1:49 hmm

1:49 it wouldn't really be similar to not-native though, because I'd be tagging my public api functions 'safe-test

2:05 ivan: are there any reasons to have multiple classloaders other than class reloading (in the miraculous case where you manage to lose references to all objects) and tiny performance improvements in initial loading?

2:06 I guess I'm really asking if OSGi and similar do anything useful than I couldn't do in a hundred lines of clojure

2:40 amalloy: huh? of course there are reasons. for example, clojurebot can run under clojure 1.2 and also have clojure 1.5 loaded for when he evaluates user code (i think he actually does this, but i could be way off)

2:42 if there were only one classloader, what class would be called clojure.core$read? does it support #inst literals, or not? with one classloader for each clojure version, there are two classes named clojure.core$read

2:43 likewise, a repl would be impossible with just one classloader: once you define user$foo by (defn foo [] 1), you can't possibly change it with (defn foo [] 2), because classes, once loaded, are immutable

2:44 ivan: ^

2:46 tieTYT2: i'm writing my first clojure project. I notice most of my functions start with a "let" and declare 2-3 things. Each result is usually passed in as a parameter to the next. The function body usually is just the last value of the "let". Does it sound like I'm doing something wrong?

2:49 ivan: amalloy: ah, thanks. I knew about the REPL case but forgot about about multiple versions

2:49 tieTYT2: here's an example: https://www.refheap.com/paste/b7e696a9b4fc50e03bf00f084

2:50 does that look wrong?

2:50 amalloy: tieTYT2: there's nothing wrong with that, if you think the names for the intermediate results help readability

2:50 tieTYT2: not only that, it would just be a nested mess if it was all together

2:51 amalloy: IMO it reads better as just (map get-url-to-image (html/select post image-links)), but that's a matter of taste

2:51 you don't get to call anything a nested mess unless it has at least ))))) in it somewhere

2:51 and i'll probably disagree with you unless it has at least ))])}))])

2:52 scottj: tieTYT2: I suspect most clojurists would write that with no let. If you don't like the nesting, you can use threading (-> and ->>)

2:52 tieTYT2: yeah I learned about threading after I wrote this

2:52 amalloy: what's your opinion on scottj's comment?

2:53 (fight fight fight)

2:53 amalloy: *shrug*

2:53 tieTYT2: actually, I was more concerned about, "You're doing functional programming all wrong!" more than anything

2:53 scottj: tieTYT2: I agree with amalloy :) there's nothing wrong with the lets if you like them

2:53 tieTYT2: and it sounds like I'm not doing that, at least in an obvious way from this snippet I assume

2:55 ok thanks for the help guys

3:29 cornotahti: ,"I worship His Shadow"

3:29 clojurebot: "I worship His Shadow"

3:33 cornotahti: ,(print "I worship His Shadow")

3:33 clojurebot: I worship His Shadow

5:07 supersym: is it ok to use functions as values for atomic hash keys like (atom {:player 1 :ops inc})?

5:08 mpfundstein: supersym: thats the whole point of first class functions

5:08 supersym: thats what I thought maybe atom was a 'special case' though

5:08 sorry for asking the obvious ><

5:08 mpfundstein: supersym: :-) no prob

5:08 supersym: yeah.... me like :)

5:08 mpfundstein: supersym: maybe you want to read the Joy of Clojure

5:09 supersym: there is a nice chapter about handling such things

5:09 supersym: ah yea...thnx

5:09 i should buy it :)

6:01 squidz: i'm trying to use the Shoreleave library for ajax calls, but I am getting a 404 not found error for localhost:5000/_shoreleave. Does anybody have any experience with this? anybody know why the middleware isnt creating the routes

6:04 Willyfrog: I probably can't help, as I'm pretty new, but you should probably show the code for defining your server accepted routes

6:05 I suppose you are using compojure for the server, right?

6:08 squidz: yes

6:08 Willyfrog: here is a paste https://www.refheap.com/paste/13080

6:09 Willyfrog: you haven't defined a _shoreleave route

6:09 you have /, but no /_shoreleave, I mean

6:09 squidz: as far as I know, the middleware should do that

6:09 but maybe not

6:09 what should I pass as the handler though?

6:20 Willyfrog: no idea :S, sorry

6:21 Glenjamin: squidz: a quick look at the source implies that you're loading the old namespace

6:21 https://github.com/shoreleave/shoreleave-remote-ring/blob/master/src/shoreleave/middleware/rpc.clj

6:21 vs https://github.com/shoreleave/shoreleave-remote-ring/blob/master/src/cemerick/shoreleave/rpc.clj

6:25 squidz: Glenjamin: ah yes, I was confused to which one I should use ill see if switching helps

6:27 so the source with shorleave.middleware.rpc is the newer version

6:50 borkdude: I'm watching Simple made easy. Doesn't Clojure complect the language and it's hosting platform? =)

6:52 *ducks*

6:53 ucb: heh

6:53 Willyfrog: why do you think so?

7:02 squidz: Willyfrog: okay I am using the right namespace now, but for some reason still getting the error

7:03 Willyfrog: it was Glenjamin who helped you ;) as I said, I haven't used that library

7:03 squidz: oh sorry I mean Glenjamin then

7:40 TimMc: hiredman, Raynes, amalloy_: Y'all run sites/bots with REPLs with untrusted users. Would your security be affected by this patch? http://dev.clojure.org/jira/browse/CLJ-1176?focusedCommentId=30840#comment-30840

7:54 squidz: Raynes: for some reason I cant seem to edit pastes on refheap using the alt+ctr+e

8:31 yedi: recently realized that chinese programmers have to just memorize arbitrary pictures/blobs of text yet some are still able to program at high levels

8:31 so http-kit makes me happy

8:31 supersym: what

8:32 they arent arbitrary are they

8:33 yedi: well i'm speaking for the majority that don't understand english

8:38 Willyfrog: you only need a couple of words in "english" to be able to program

8:39 there are many people with a bad grasp of english who can program (with variyng degree of hability)

8:45 supersym: right

8:49 cornotahti: yedi, well, truth be told, some of the names of stuff also don't really make sense in English.

8:49 And really, if it were Latin no one would care.

8:49 It's easy enough to memorize si for if.

9:05 TimMc: It's not as if langauge keywords even mean what they say in English.

9:05 The names are just mnemonics that help you remember/guess/internalize their actual meanings.

9:07 "reduce" can make a thing bigger than the input, "map" refers to a bit of mathematical jargon that I've only seen in linear algebra, "or" is different than the "or" we use in conversational English...

9:07 Glenjamin: i don't see how or is different

9:07 john2x: anybody else having trouble skipping ahead through blip.tv videos? 

9:08 borkdude: just my opinion: localized formulaes in Excel drive me nuts (my Excel version assumes Dutch)

9:08 Glenjamin: i presume the bigger issue with localisation is fragmentation, rather than understanding

9:09 TimMc: borkdude: That's the worst.

9:09 Glenjamin: In English, "or" usually means xor, whereas in Clojure and basically every other PL it means inclusive or.

9:10 Glenjamin: oh, i see

9:10 good point

9:10 TimMc: Hence the oft-used joke: "Would you like pizza or bagels?" "Yes!"

9:11 borkdude: TimMc indeed, this also drives me nuts, because a lot of the times I don't know if people really mean xor or inclusive or

9:11 TimMc: (among programmers and mathematicians, at least...)

9:11 borkdude: TimMc and if you ask for clarification on the subject, sometimes they don't even understand the difference

9:12 TimMc: :-(

9:12 borkdude: in our building is a sign: Don't eat and drink in the lecture room. Some have interpreted this as: don't do it at the same time.

9:17 jcromartie: sexy music + Clojure programming = weird feelings

9:17 but I am OK with who I am

9:19 the Clojure Programming book really promotes the point-free style eh

9:26 I feel like midje is great but I'm missing something

9:26 are facts really intended to be declared at the top level?

9:28 I think I'm just thrown off by the fact that loading facts runs them, so I feel like side effects are happening by just loading the namespace but that's not what's going on

9:35 jemafeller: whats a functional way to go from ["a", "b", "c"] to ["a", "ab", "abc"]

9:36 I'm thinking reduce left but i think i have side effects there

9:37 borkdude: jemafeller mapv

9:37 jemafeller no wait, I responded too fast ;)

9:37 jemafeller reductions

9:37 jemafeller: reductions?

9:38 borkdude: ,(reductions concat ["a", "b", "c"])

9:38 clojurebot: ("a" (\a \b) (\a \b \c))

9:38 jemafeller: oh, neat!

9:38 Glenjamin: ,(doc reductions)

9:38 clojurebot: "([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."

9:38 Glenjamin: oh, clever

9:39 jemafeller: but what's

9:39 \a \b

9:39 borkdude: ,(reductions #(apply str (concat %&)) ["a", "b", "c"])

9:39 clojurebot: ("a" "ab" "abc")

9:39 jemafeller: a reference?

9:39 borkdude: jemafeller those are characters

9:39 jemafeller: it moves from string to characters freely?

9:39 Glenjamin: ,(= "ab" '(\a \b))

9:39 clojurebot: false

9:40 borkdude: ah wait, even simpler:

9:40 ,(reductions str ["a", "b", "c"])

9:40 clojurebot: ("a" "ab" "abc")

9:40 borkdude: if you want a vector, wrap vector around it:

9:40 ,(vec (reductions str ["a", "b", "c"]))

9:40 clojurebot: ["a" "ab" "abc"]

9:41 jemafeller: perfect

9:59 perfect

9:59 oops

10:11 supersym: ,(defn board (let [field 0 box (apply vector (repeat 6 field))] (atom {:box1 box :box2 box})))

10:11 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Parameter declaration let should be a vector>

10:12 borkdude: supersym def

10:12 supersym: thought so

10:13 would there be a way to combine key values within the hash-map? like :area box1 box2 ..

10:13 borkdude: supersym use a vector or something

10:14 supersym: (atom {:box1 box :box2 box :area ?)

10:14 borkdude: supersym I don't know what you're trying to do, but if you need multiple values under one key, you can do ##{:a [1 2], :b [3 4]}

10:14 lazybot: ⇒ {:a [1 2], :b [3 4]}

10:15 supersym: thank you

10:15 that was it!

10:15 jemafeller: i'm find myself doing a ton of work inside a let block - is that normal?

10:15 borkdude: jemafeller try looking at ->, ->> or as->

10:15 jemafeller: i mean, turns out almost all of my code is in the let block

10:17 borkdude: gtg

10:17 supersym: duplicate key... hm

10:18 i get it

10:21 jemafeller: is there a primitive to process a collection over another collection?

10:21 like [1,2,3] and [a,b,c] and now map with 1 and [a,b,c] then 2 and [a,b,c] etc

10:25 `arrdem: mornin

10:27 skelternet: Good morning!

10:31 ToBeReplaced: is there a shorthand function for (zipmap xs (map f xs)) ?

10:38 stuartsierra: jemafeller: Perhaps you want (map f [1 2 3] (repeat [a b c]))

10:38 ystael: ToBeReplaced: clojure.algo.generic.functor/fmap

10:39 mikerod: jemafeller: If you mean you want to apply a list of functions to a collection with map, you could do something like (map (compose f1 f2 f3) [a b c d e]).

10:40 jemafeller: i see.. i kind of did (map (fn (map …) ) ..)

10:41 ToBeReplaced: ystael: not quite, but that is cool

10:41 jemafeller: also is tuple or vector preferred if I want to generate pairs of things?

10:42 ystael: ToBeReplaced: sorry, I completely misread your code :|

10:42 ToBeReplaced: jemafeller: usually vectors

10:43 ,(seq {:foo 1 :bar 2})

10:43 clojurebot: ([:foo 1] [:bar 2])

10:43 jemafeller: is vectors the most light weight for this?

10:44 supersym: How would one add a .jar reference inside the repl, ns macro? I know I'm supposed to use leiningen for this (want to play with incanter a bit) but I was wondering if anyone ever does this, if it is a pain...or

10:44 could be part of the reason leiningingen was made in the first place, i don't know just curious :)

10:45 stuartsierra: jemafeller: Clojure doesn't have a built-in "tuple" type. Vectors are it.

10:48 nDuff: jemafeller: ...since vectors are immutible, they're usable as keys just as Python's tuples are.

10:49 jemafeller: '(1 2), by the way, is a list -- and unlike a vector, lists aren't set up for fast random access.

10:52 gtrak: hey, any classlojure guys here? We're trying to use it and wondering why it doesn't do print-dup on returned objects from eval-in-cl, it calls RT/printString.

10:53 ToBeReplaced: What core function does (fn [f x] (f x)) ? (not apply...)

10:53 bbloom: ToBeReplaced: isn't that just f ?

10:53 jcromartie: yeah the value itself should suffice

10:54 ToBeReplaced: (!= (f f x) (f x))

10:54 i need it for a merge-with

10:55 ,(merge-with (fn [f x] (f x)) {:foo inc} {:foo 1})

10:55 clojurebot: {:foo 2}

10:55 bbloom: oh misread.

10:55 gtrak: ninjudd: ^^ re: classlojure

10:58 ravster: When doing a 'lein deps', I'm getting the leinjacker-0.3.3 from clojars instead of 0.4.1. I don't understand why this is, since lein-ring is at the 0.8.3 version, which asks for leinjacker-0.4.1. How do I fix this?

10:58 bbloom: ToBeReplaced: i don't think there is any such core function for "call" instead of "apply" in the javascript sense of those names

10:59 ravster: I've already tried deleting leinjacker and lein-ring from my .m2 directory.

10:59 ToBeReplaced: bbloom: yeah i can't find one... first time i've ever had it come up

10:59 weavejester: ravster: It's likely you have a plugin or dependency that references the old version.

10:59 ravster: Check your ~/.lein/profiles.clj file for out of date plugins

10:59 bbloom: there isn't really much need for one, since there would never be any advantage over calling the function directly

10:59 ravster: weavejester: okay

11:00 bbloom: thinking aloud: javascript only provides .call in addition to .apply because .call accepts a target "this" argument

11:00 ravster: I don't have a .lein/profiles.clj, weavejester

11:00 weavejester: ravster: If you run "lein deps :tree" in your project directory, is lein-jacker referenced anywhere?

11:00 jcromartie: I hear people aren't wild about midje?

11:00 I like core.test well enough

11:01 ravster: I thought that lein-ring would download the dependencies and versions that it needs too, instead of just working with whatever another lib wants.

11:01 weavejester: will try that

11:01 weavejester: ravster: You might also want to check which plugins are being loaded in the project.clj directory

11:01 ravster: It does, but you can only have one version of a library loaded in the classpath, so another plugin might take priority.

11:02 bbloom: ToBeReplaced: i think your little (fn [f x] (f x)) is clearer, but if you want to 1) support variable arities or 2) be slightly more cryptic: #(apply %1 %&)

11:03 ,(#(apply %1 %&) + 5 10 15)

11:03 clojurebot: 30

11:03 ravster: weavejester: weird. leinjacker isn't anywhere in the output of "lein deps :tree"

11:04 ToBeReplaced: yea or just #(%1 %2) in the single arity case

11:04 TimMc: ravster: lein-ring has a version range dependency on lainjacker :-(

11:04 *leinjacker

11:04 weavejester: ravster: I don't think lein deps :tree shows plugin dependencies, so it was a bit of a long shot.

11:04 TimMc: A version range dependency?

11:05 TimMc: The result is that you get some pretty weird dependency resolution behavior.

11:05 ravster: TimMc: noooooooo . I get weird vector? (:dependencies ...) errors with 0.3.3, and its a closed issue on lein-ring with the solution of just using the latest leinjacker.

11:05 TimMc: Hmm, now I can't find it...

11:06 ravster: https://github.com/weavejester/lein-ring/issues/61

11:06 weavejester: TimMc: Lein-Ring depends on Lein-Jacker 0.4.1, not a version range

11:06 ravster: What other plugins do you have in the project?

11:07 ravster: the plugins are lein-beanstalk, -datomic, and -ring

11:08 weavejester: ravster: Which versions?

11:08 TimMc: weavejester, ravster: Cancel that, I was thinking of lein-guzheng.

11:08 https://github.com/dgrnbrg/guzheng/issues/8

11:08 ...which is probably the culprit here.

11:09 weavejester: ravster: lein-datomic uses leinjacker 0.3.3

11:10 ravster: If you remove lein-datomic from your plugins, lein-ring and other plugins that use lein-jacker should work okay.

11:12 ravster: nooooooo, lein-datomic

11:12 *grumble, grumble*

11:12 cool, thanks weavejester

11:12 TimMc: ravster: You should be able to exclude that dependency from lein-datomic but still use it.

11:13 ravster: *eye-brow raise*

11:13 nice, didn't know i could do that.

11:15 will look into it

11:15 aroemers: [A

11:15 [A

11:15 whoops

11:22 jcromartie: I am *really* confused about the deprecated fns in clojure.java.jdbc

11:22 why in the world would they deprecate all of the primary functions in the example code?

11:22 what's the alternative?

11:23 jeezus the whole thing is practically deprecated...

11:23 asteve: ,~

11:23 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading character>

11:23 nDuff: well, for delete-rows the obvious alternative is delete!, for connection it's db-connection...

11:23 asteve: ,(help ~)

11:23 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

11:23 asteve: what does ~ do?

11:24 jcromartie: nDuff: every single fn used in the example code is deprecated in 0.3.0… maybe that's just a forward-looking thing?

11:24 nDuff: asteve: ~ is unquote

11:24 asteve: so, if you have `[foo ~bar], then everything but the bar is quoted

11:24 asteve: see http://clojure.org/reader

11:25 asteve: ...notably, unquote only works inside syntax-quote, which is ` as opposed to '

11:25 asteve: nDuff: thanks

11:29 borkdude: ,`~+

11:29 clojurebot: #<core$_PLUS_ clojure.core$_PLUS_@37c9ec>

11:29 borkdude: ,`~,

11:29 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

11:31 Glenjamin: heh, helpful compiler error :D

11:33 nDuff: ...well, it's a _reader_ error; the compiler isn't involved yet :P

11:33 borkdude: ,`~#{#{}#()[]}

11:33 clojurebot: #{#{} [] #<sandbox$eval35$fn__36 sandbox$eval35$fn__36@1336fcf>}

11:34 asteve: this may be a very novice question but why would I want to dereference a function?

11:35 nDuff: asteve: IFn isn't dereferencable in and of itself.

11:35 asteve: what's the context?

11:35 asteve: nDuff: http://i.imgur.com/Loc0p52.png

11:36 nDuff: asteve: ...so, that isn't a dereference...

11:36 asteve: ...it's an unquote-splice

11:36 bbloom: asteve: sadly, ~ and @ are tokens, but ~@ is a single token

11:36 asteve: ah

11:36 borkdude: ,(let [x '(1 2 3)] `[x ~@x])

11:36 clojurebot: [sandbox/x 1 2 3]

11:37 borkdude: ,(let [x '(1 2 3)] `[~'x ~@x])

11:37 clojurebot: [x 1 2 3]

11:37 borkdude: argh

11:37 bbloom: yeah, it's (clojure.core/unquote-splicing x) instead of (clojure.core/unquote (clojure.core/deref x))

11:37 borkdude: ,(let [x '(1 2 3)] `[~x ~@x])

11:37 clojurebot: [(1 2 3) 1 2 3]

11:37 bbloom: if you actually DID want a deref inside an unquote, you'd need to do something like ~(deref x) or ~(-> @x)

11:38 shoulda been ~& or something else less ambiguous :-)

11:38 borkdude: bbloom yeah, I like ~&

11:41 asteve: more novice questions, (1 2 3) is a sequence?

11:41 borkdude: asteve '(1 2 3) or (list 1 2 3) is a normal list, but sequences get printed the same as lists

11:42 ,(map inc [1 2 3])

11:42 clojurebot: (2 3 4)

11:42 borkdude: ,(type (map inc [1 2 3]))

11:42 clojurebot: clojure.lang.LazySeq

11:42 borkdude: ,(list 2 3 4)

11:42 clojurebot: (2 3 4)

11:42 borkdude: ,(type (list 2 3 4))

11:42 clojurebot: clojure.lang.PersistentList

11:42 asteve: ,(2 3 4)

11:42 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

11:42 asteve: ok

11:43 borkdude: asteve the list representation is also a way to call functions, so now you are trying to call 2 as a function on 3 and 4

11:43 asteve: borkdude: right

11:43 my confusion is in and around people interchanging `(1 2 3) and [1 2 3]

11:43 [1 2 3] is a vector?

11:44 borkdude: asteve yes and vectors are kind of the default for sequential data over lists which you normally only use in macro's

11:44 jcromartie: oops I made a document database :|

11:44 asteve: ,(= `(1 2 3) [1 2 3])

11:44 clojurebot: true

11:44 jcromartie: not one that actually makes any sense, mind you

11:45 borkdude: asteve this is true because = compares contents of collections

11:45 ,(doc =)

11:45 clojurebot: "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison."

11:46 Willyfrog: ,(type '(1 2 3))

11:46 clojurebot: clojure.lang.PersistentList

11:46 asteve: ,(type [1 2 3])

11:46 clojurebot: clojure.lang.PersistentVector

11:46 Willyfrog: ,(type [1 2 3])

11:46 clojurebot: clojure.lang.PersistentVector

11:46 Willyfrog: ;)

11:46 asteve: ,(type `(1 2 3))

11:46 clojurebot: clojure.lang.Cons

11:49 jemafeller: is there any 'finally' in clojure?

11:49 Glenjamin: yes

11:50 http://clojure.org/special_forms#Special%20Forms--%28try%20expr*%20catch-clause*%20finally-clause?%29

11:50 asteve: ,(type `(1 2))

11:50 clojurebot: clojure.lang.Cons

11:50 asteve: so it's a constant but it's still a sequence, right?

11:51 weavejester: asteve: Cons doesn't mean constant, if that's what you're thinking.

11:51 technomancy: https://en.wikipedia.org/wiki/Cons

11:51 asteve: weavejester: that is what I was thinking

11:51 foolish of me

11:52 technomancy: that said, looking at the underlying classes of lists is a good way to go crazy =\

11:52 weavejester: asteve: It's a natural assumption if you haven't happened across cons cells before

11:58 squidz: cemerick: I am having a problem with the namespace change in your shoreleave-remote-ring library. I was getting a 404 not found error for the default /_shoreleave route, and I found out I was using the wrong namespace in my declarations. After changing it to shoreleave.middleware.rpc I am still getting the error. Do you have any ideas?

11:59 I can also verify in the repl that the default-remote-uri var points to "/_shoreleave"

12:01 jemafeller: i'm trying to guarantee a return of a resource to a pool.. with try/finally but seems to not work (scope of definition)

12:01 am I doing it wrong?

12:02 nDuff: jemafeller: Could you provide more detail about what you're doing and how it's failing?

12:02 jemafeller: looks similar to this https://groups.google.com/forum/?fromgroups=#!topic/clojure/hsh-H8SxNHw

12:03 cemerick: squidz: I'm aware of the issue, though haven't dug into it (ohpauleez did the ns refactoring, and I'm still using the older bits). There's an issue for the documentation issue (https://github.com/shoreleave/shoreleave-remote-ring/issues/6). Make sure you're applying the wrap-rpc middleware properly?

12:03 nDuff: jemafeller: If you're generating a lazy sequence that uses the resource, that's one ready situation in which try/finally can fail to behave as expected (returning the resource before everything using it is consumed)

12:03 squidz: cemerick: here is a paste of how im using the wrapper https://www.refheap.com/paste/13083

12:03 nDuff: Ahh.

12:04 jemafeller: The solution given there (wrapping the try/finally within the let) isn't an entirely unreasonable one.

12:04 cemerick: squidz: that won't work

12:04 jemafeller: nDuff, you mean 2 try blocks?

12:04 nDuff: ...likewise, building a wrapper macro.

12:04 squidz: cemerick: what am I doing wrong?

12:04 cemerick: squidz: Look at the compojure example in the doc. handler/site comes last

12:05 nDuff: jemafeller: See the with-api-connection macro; that way, the inner try block doesn't have to be explicit.

12:05 squidz: do I then have to manually supply the route? I get a 'wrong number of arguments passed' error

12:06 cemerick: squidz: Not sure what you mean by "manually". Should be (-> app-routes rpc/wrap-rpc handler/site)

12:08 squidz: cemerick: I dont think I have to restart my server right?

12:09 cemerick: squidz: if you passed a var into the ring adapter, no

12:09 squidz: hmm it doesnt seem to have an effect

12:10 cemerick: https://www.refheap.com/paste/13085

12:10 cemerick: squidz: you're passing app-routes to the jetty adapter, not handler

12:15 squidz: cemerick: hmm I passed #'handler to it now instead and restarted but still no change

12:21 fantadrink: Hello, I am having the hardest time writing a tiny gzipping function. Does anyone see what I'm doing wrong? (The un-gzipping works on test data, so I think it's the gzipping.) https://gist.github.com/anonymous/f50ea593ac5f13e64a4d

12:24 jemafeller: when i do this (let [^Pipeline p (.pipelined conn) ]

12:24 squidz: cemerick: okay nevermind, that did change something. It seems to work because now i'm getting a 500 error instead of a 404 so the route is now defined. Thanks for helping

12:24 jemafeller: looks like the type hint doesn't work.. is there a proper way to type hint in a let block?

12:25 nDuff: jemafeller: That _is_ the proper way.

12:25 jemafeller: hmm ok

12:25 nDuff: jemafeller: I take it that's "didn't work" in the sense that you're still getting reflection warnings?

12:25 jemafeller: What exactly is the call you're getting those warnings on?

12:25 jemafeller: yes.. I'm checking perhaps it's just me

12:27 squidz: Raynes: I messaged earlier about not being able to edit refheap pastes. I found out, that it is becaues I have my ctrl key mapped to caps-lock

12:29 jemafeller: nDuff, well i'm trying to use bare-bones Jedis, looks like when I get a Pipeline it won't recognize 'incr' on it

12:30 example: http://pastie.org/7163515

12:31 nDuff: jemafeller: Ahh -- it doesn't know the type of the %1

12:31 arcatan: fantadrink: i tried your example and it worked for me with no problems

12:32 fantadrink: arcatan: Aaargh. :) How weird.

12:32 nDuff: jemafeller: I don't know the libraries you're using, but if the %1 is supposed to be a Long, for instance, try (fn [^Long x] (.incr p x))

12:32 fantadrink: arcatan: Thanks, I'll restart my REPL and try again.

12:32 jemafeller: nDuff, yep it working, thanks!

12:32 nDuff: jemafeller: ...by the way, I think some of that might be easier to read with doseq rather than (doall (map ...))

12:34 jemafeller: ah! looks like carmine was my bottleneck. using Jedis i get great performance

12:34 nDuff: Hmm. Sounds like something worth reporting to carmine's maintainership

12:34 fantadrink: arcatan: OMFG, restarting the REPL worked. Even though I just created namespace 'foo to have a "clean space". Thanks again.

12:37 cemerick: squidz: np :-)

12:37 squidz: cemerick: just another quick question defremote only supports returning certain types right? I couldnt pass it a clojure map could I?

12:38 cemerick: squidz: anything that can be printed and read should work

12:39 squidz: cemerick: okay thanks

12:43 mpenet: jemafeller: did you use pipelining with carmine as well?

12:43 jemafeller: mpenet, yes. i think i can identify a difference though

12:43 when I use Jedis, and MONITOR on Redis, I don't see the results immediately in the MONITOR

12:44 with carmine I always do see it immediately

12:44 perhaps Jedis has some sort of queue and workers that batch even pipelines

12:44 mpenet: right, so jedis is fire and forget (async)

12:44 jemafeller: i'm not sure.. it doesn't say it is on the tin

12:45 mpenet: it is async: https://github.com/xetorthio/jedis/wiki/AdvancedUsage#pipelining

12:45 jemafeller: perhaps its pool makes for a better performance

12:45 mpenet: you need to call .sync on the pipeline obj to wait for the response it seems

12:46 jemafeller: hmm what the… i've never seen that. I call .exec on the pipeline

12:47 mpenet: both jedis and carmine use the same underlying pools (more or less), from apache commons

12:48 tyler: is there heredoc in clojure so i can do something like (def example-json (heredoc {"foo":"bar"})) ?

12:49 mpenet: jemafeller: aleph redis client works like this too: every command is pipelined and async by default. I never profiled/benchmarked it though

12:49 jemafeller: mpenet, any idea why .exec worked for me?

12:51 mpenet: jemafeller: because it's one of the possible way to use it. At least it's a public method of Pipeline

12:51 jemafeller: looks like it works faster than sync

12:51 mpenet: jemafeller: it makes sense since very often you don't care about the reply when using pipelines

12:52 tyler: i guess i could make a json tagged literal

12:54 st3fan: can anyone point me to a simple ISeq or ASeq example? i am trying to create my own collection for a special indexed dataset

12:55 squidz: is there something like the Maybe Monad in clojure, or is that not so idiomatic? if not, whats the usual way with working with exceptions

12:56 antares_: squidz: there is algo.monads but monads are not used heavily

12:56 mpenet: jemafeller: I doubt it's faster in reality, you just get your thread back faster since it's non blocking, but I doubt it paralelises the calls (using a pipeline would be pointless). If exec does return you the replies, then maybe it's a matter of difference in how the pools are configured

12:56 squidz: antares_: so its not so usual, then what is the prefered way of working with exepctions

12:56 antares_: squidz: start with exploring if-let, when-let and some-> in Clojure 1.5

12:57 squidz: if by "exceptions" you mean nil values, see above

12:57 squidz: thanks that is what I was looking for

12:57 antares_: squidz: nil evaluates to false in Clojure, that is heavily used

12:57 squidz: no, I dont mean nil values, but exceptions thrown by other libraries, java that is

12:57 jemafeller: mpenet, i'm not sure what exec is then.. googling doesn't bring up a definite answer

12:58 antares_: squidz: then try/catch/finally and ex-info

12:59 mpenet: jemafeller: it seems it maps to a redis EXEC call

12:59 jemafeller: mpenet, that doesn't make sense..

12:59 mpenet: https://github.com/xetorthio/jedis/blob/master/src/main/java/redis/clients/jedis/Pipeline.java#L105

13:00 jimduey: squidz: https://github.com/jduey/protocol-monads

13:00 squidz: jimduey: thanks ill take a look

13:10 momomomomo: Afternoon all

13:11 jack_rabbit: (dotimes [_ 5] (print "mo"))

13:11 hyPiRion: ,(repeatedly 5 #(pr 'mo))

13:11 clojurebot: (momonil monil monil monil nil)

13:13 jack_rabbit: ,(dotimes [_ 5] (print "mo"))

13:13 clojurebot: momomomomo

13:13 jack_rabbit: cool.

13:17 casion: does clojure have a decent debugger yet?

13:17 besides avoiding needing a debugger

13:18 technomancy: casion: ritz seems to be the best so far

13:18 casion: is ritz near slime level yet?

13:18 I know that's a silly question

13:19 but indulge me please :)

13:19 technomancy: ritz works with slime

13:19 and nrepl

13:19 casion: I thought using slime with clojure was passé now?

13:21 technomancy: dunno, it still works

13:21 casion: I haven't experimented with it much

13:21 technomancy: if you need slime features that aren't in nrepl you can keep using it while you wait for nrepl to catch up =)

13:22 casion: still have to use swank-clojure or?

13:22 technomancy: ritz is a swank-clojure replacement

13:22 casion: oh

13:22 I guess I need to look into ritz

13:22 thank you

13:22 technomancy: I think the video from the clojure conj is up? it's pretty good.

13:23 casion: ok, great

13:23 thank you again

13:23 technomancy: sure; hope it works for you

13:23 hyPiRion: Is there anyone here who knows if there is any testing framework for Clojure 1.0?

13:24 technomancy: hyPiRion: there's really just clojure.contrib.test-is more or less

13:24 casion: hmm, video is not up yet it seems

13:24 but I found slides

13:24 technomancy: test-is became clojure.test

13:24 hyPiRion: technomancy: Hmm, okay

13:24 technomancy: hyPiRion: very old versions of leiningen support it

13:25 archaeology!

13:25 hyPiRion: Oh sweet

13:26 Not sure if I can include the :license in the project map anymore though =/ Not enough space

13:27 Oh well, research time, thanks.

13:30 oh man, I have to go pre 0.5.0 then

13:30 jcromartie: technomancy: someone was saying you had some opinions on Midje vs alternatives?

13:30 I am curious

13:31 I feel like clojure.test is much more straightforward

13:32 asteve: why would you need to use an anonymous function literal #() instead of ()?

13:32 jcromartie: and most of what Midje does could be accomplished on top of clojure.test through libraries

13:33 dnolen: asteve: #(* % 2) vs (fn [x] (* x 2))

13:33 jcromartie: ,()

13:33 clojurebot: ()

13:33 jcromartie: ,#()

13:33 clojurebot: #<sandbox$eval69$fn__70 sandbox$eval69$fn__70@2eb03d>

13:33 hyPiRion: ,'#()

13:33 clojurebot: (fn* [] ())

13:33 hyPiRion: ,(= (#()) ())

13:33 clojurebot: true

13:33 hyPiRion: hmm

13:34 asteve: dnolen: and what is % here?

13:34 dnolen: asteve: an argument

13:34 hyPiRion: asteve: the first argument passed to the function

13:34 moredogmeat: hi, is there a way to easily print to stderr instead of stdout? an equivalent of println for *err*?

13:34 hyPiRion: (binding [*out* *err*] (println "I am now printing to stderr")) <-

13:35 asteve: %1 is the second argument passed?

13:35 scottj: asteve: first

13:35 asteve: so % and %1 are the same?

13:35 scottj: asteve: % and %1 are same

13:35 hyPiRion: asteve: yes

13:35 dnolen: ,(#())

13:35 clojurebot: ()

13:35 dnolen: that is pretty weird hyPiRion

13:35 moredogmeat: Hi hyPiRion thank you again

13:35 dnolen: a reader ambiguity?

13:36 tyler: how do you define tagged literal from repl?

13:36 nDuff: asteve: there's never a reason to use #(...) instead of (fn [...] ...) other than terseness.

13:36 hyPiRion: dnolen: Yeah, it's most likely because #(...) expands into (fn* [] ( ...))

13:36 tyler: i saw miner do it in his talk

13:36 dnolen: ah no

13:36 hyPiRion: yeah

13:36 nDuff: asteve: Sometimes, terseness is enough.

13:36 dnolen: ,(macroexpand '(#()))

13:36 clojurebot: ((fn* [] ()))

13:36 asteve: nDuff: makes sense

13:36 hyPiRion: moredogmeat: you're welcome :)

13:37 asteve: ,#(str "?" (name %))

13:37 clojurebot: #<sandbox$eval246$fn__247 sandbox$eval246$fn__247@dc4653>

13:37 asteve: "?" is input?

13:38 nDuff: asteve: '?' is a string literal, just like "foobar" or "hello world"

13:38 err, "?"

13:38 dnolen: ,(#(string "?" (name %)) 'foo)

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

13:38 dnolen: ,(#(str "?" (name %)) 'foo)

13:38 clojurebot: "?foo"

13:38 asteve: ah, so it's concatenating

13:38 jcromartie: asteve: yeah, str is used to build strings

13:38 dnolen: ,(doc str)

13:38 clojurebot: "([] [x] [x & ys]); With no args, returns the empty string. With one arg x, returns x.toString(). (str nil) returns the empty string. With more than one arg, returns the concatenation of the str values of the args."

13:39 asteve: ,(#(str "?" (name %)) 'foo)

13:39 clojurebot: "?foo"

13:39 asteve: ,(str "?" (name %) 'foo)

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

13:39 asteve: ,(str "?" 'foo)

13:39 clojurebot: "?foo"

13:40 asteve: ,(map (#(str "?" (name %)) 'foo))

13:40 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$map>

13:41 asteve: ,(map #(str "?" (name %)) 'foo))

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

13:41 kotarak: ,(map #(str "?" (name %)) [foo])

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

13:41 kotarak: ,(map #(str "?" (name %)) '[foo])

13:41 clojurebot: ("?foo")

13:42 asteve: what did map do there?

13:43 ("?foo") is now a lazy sequence of exactly 1 item?

13:43 kotarak: asteve: it applied the function to each item in the vector

13:43 asteve: yes

13:43 ,(map #(str "?" (name %)) '[foo bar baz])

13:43 clojurebot: ("?foo" "?bar" "?baz")

13:43 asteve: ah!

13:45 ,(concat ["?moo" "?oop"] (map #(str "?" (name %)) '[foo bar baz]))

13:45 clojurebot: ("?moo" "?oop" "?foo" "?bar" "?baz")

13:46 asteve: ,(vec (concat ["?moo" "?oop"] (map #(str "?" (name %)) '[foo bar baz])))

13:46 clojurebot: ["?moo" "?oop" "?foo" "?bar" "?baz"]

13:46 asteve: bam! learnin this

13:46 kotarak: asteve, rather into than vec + concat

13:47 asteve: ,(into ["?moo" "?oop"] (map #(str "?" (name %)) '[foo bar baz]))

13:47 clojurebot: ["?moo" "?oop" "?foo" "?bar" "?baz"]

13:47 asteve: the more you know

13:48 kotarak: asteve, it's faster because it works in the vector instead of going to sequence land and then going back again with vec.

13:49 hyPiRion: ,(into ["?a" "?b"] (map (partial str "?") '[c d e]))

13:49 clojurebot: ["?a" "?b" "?c" "?d" "?e"]

13:49 asteve: what editor do you guys use? I'm wondering if there's a visualizer for vim to ensure I'm properly parenthesis'd

13:50 moredogmeat: asteve: I'm not an expert but I use http://www.vim.org/scripts/script.php?script_id=2501 with vim

13:50 JohannVon: Real programmers code with a magnetic needle and a steady hand

13:50 asteve: JohannVon: sure

13:50 jack_rabbit: asteve, I use emacs.

13:50 JohannVon: God, tardive dyskenesia is a bitch, I can actually see my hands shaking if I look at them.

13:51 moredogmeat: Does clojure have a reflection API for java methods and etc or just use the Java one?

13:54 hyPiRion: moredogmeat: clojure.reflection

13:55 tyler: seq? is to [] as what is to {} ?

13:55 bbloom: tyler: do you mean seq? or sequential?

13:56 ,(map (juxt seq? sequential?) ['(1 2 3) [4 5 6]])

13:56 tyler: i think i mean seq

13:56 clojurebot: ([true true] [false true])

13:56 tyler: im too newbish to be positive

13:56 ah

13:56 hyPiRion: ,(seq [])

13:56 clojurebot: nil

13:56 hyPiRion: ,(seq {})

13:56 clojurebot: nil

13:56 bbloom: ,(map (juxt seq? sequential? associative?) ['(1 2 3) [4 5 6]])

13:56 clojurebot: ([true true false] [false true true])

13:56 bbloom: tyler: ##(doc associative?)

13:56 lazybot: ⇒ ------------------------- clojure.core/associative? ([coll]) Returns true if coll implements Associative nil

13:57 moredogmeat: ok thanks hyPiRion let me go take a look at clojure.reflection

13:57 tyler: bbloom: thnx

13:57 hyPiRion: ,(mapv seq [[1 2] {:one :two}])

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

13:57 bbloom: ,(map (juxt seq? sequential? associative?) ['(1 2 3) [4 5 6] {:foo :bar}])

13:57 clojurebot: ([true true false] [false true true] [false false true])

13:57 hyPiRion: ,(mapv seq [[1 2] {:one :two}])

13:57 clojurebot: [(1 2) ([:one :two])]

13:58 tyler: bbloom: im trying to recurse a json object im trying to write something using tree-seq

14:05 anyone know of a lib that takes a datastructure and generates an image of that structure with graphviz?

14:06 lynaghk: cemerick: do you have any suggestions for how to stub out friend's openid workflow during a test?

14:07 cemerick: i.e., change the openid provider URL in the login form to point to a stub under my control, and have that return the appropriate bits?

14:07 cemerick: lynaghk: that's the long way 'round. OpenID is *big*. If you've stubbed it effectively, you've just implemented an OpenID provider.

14:07 lynaghk: cemerick: or would jacking into the friend openid workflow itself be a better solution? My gut feeling is that stubbing out the identity provider makes more sense

14:08 cemerick: hmm. There's not a Java servelet somewhere you're aware of that I can just jack into?

14:08 cemerick: Better would be impl'ing a workflow fn that returns previously-captured credentials (or failure redirects) as provided by actual openid endpoints.

14:09 lynaghk: Just searching for 'java openid provider' produces a bunch of potential options, though I've not investigated any

14:09 lynaghk: cemerick: yeah. I dug around google for a hot minute but couldn't find any clear examples of what people do to test.

14:10 cemerick: standing up a conformant openid or oauth provider is not straightforward AFAIK

14:10 lynaghk: cemerick: oh yeah, I believe that.

14:11 cemerick: lynaghk: if you have a limited set of options (just google right now?), then just capturing successful and failed responses should be fine for automated testing, right?

14:11 I mean, you don't actually want to include the openid junk in your test window.

14:12 lynaghk: cemerick: dunno, that's why I wanted to ask =) I.e., if there is expry crypto timeout stuff going on that would prevent replays

14:12 cemerick: yeah, there's a 60-second nonce in there, but I'm suggesting "replaying" the result of the workflow fn, so that wouldn't ever come into play

14:13 supersym: yeah baby!

14:14 I love how keys are functions that self-evaluate :)

14:14 hyPiRion: symbols are too, and vectors, and maps, and sets

14:14 supersym: I just so much enjoy clojure programming...its like coming home

14:15 TimMc: hyPiRion: Symbols don't evaluate to themselves.

14:15 well...

14:15 (def foo 'foo)

14:15 supersym: right

14:15 lynaghk: cemerick: not sure I follow: you mean just stub out the workflow function to return the authentication map?

14:15 cemerick: lynaghk: and/or return any auth map appropriate for the test(s) you're running, yeah

14:16 lynaghk: cemerick: hmm, okay. I'll look into that. thanks

14:16 hyPiRion: TimMc: oh right, in that sense no

14:16 amalloy: TimMc: supersym meant self-lookup, not self-evaluate, i think

14:16 cemerick: e.g. just have it respond to POSTs on the :openid-uri, and the whole openid redirect game will just get short-circuited

14:16 hyPiRion: ,('foo {'foo :bar})

14:16 clojurebot: :bar

14:17 aroemers: TimMc: symbols can look themselves up though, I think that is what hyPiRion meant

14:17 cemerick: lynaghk: applying your patch in a minute, BTW

14:17 lynaghk: cemerick: awesome, thanks

14:18 cemerick: lynaghk: now, before I start thinking about interaction workflows properly: what pen and type of paper do you prefer for that?

14:19 lynaghk: cemerick: I prefer pen and paper that optimize for the programmer experience.

14:19 cemerick: lynaghk: nm, I was trying to troll you :-P

14:19 lynaghk: cemerick: in particular, pens with which I can make a single stroke and automatically expands into an entire twitter bootstrap wireframe

14:20 cemerick: it's pretty limited and not composable, but the important part is that it takes me only a few minutes to make a website.

14:20 cemerick: someone needs to do a pencil review tumblr like the speaker-knob-feel tumblr

14:20 lynaghk: oh, all wizard-like!

14:21 supersym: amalloy: literal text from the Joy of Clojure

14:21 amalloy: really? what page?

14:21 supersym: Because keywords are self-evaluating and provide fast equality checks, they're almost always used in the context of map keys.

14:22 lynaghk: cemerick: in all seriousness, I mostly use pens that I find on the ground at hotels and other conference venues. Sometimes I go to art schools because you're more likely to score those rad micron pens and drafting pencils.

14:22 supersym: but I see where you'd easily mix up that term in this case though, lookup resolves using itself to return the value

14:23 cemerick: lynaghk: Yeah, I developed a pencil preference some years ago, bizarrely.

14:23 amalloy: well, that's certainly true. "keys are functions that self-evaluate" is even an accurate summary of that statement, but out of context it sounds like you mean self-lookup

14:23 supersym: right

14:23 cemerick: lynaghk: you were *supposed* to say something like: WTF, just gd do it! :-)

14:27 lynaghk: ping: stuartsierra

14:28 stuartsierra: lynaghk: pong

14:28 lynaghk: stuartsierra: thanks again for your talk last week---I've gotten the tools.namespace stuff up and running with those ideas and it's pretty neat

14:28 stuartsierra: lynaghk: great!

14:29 lynaghk: stuartsierra: I think there may be a problem with the refresh fn, though---if one of the namespace errors out during loading I pretty much can't load any namespaces anywhere until I restart my jvm

14:29 stuartsierra: lynaghk: you can, actually

14:29 fix the error, then call `refresh` again, but you may have to use the fully-qualified name `clojure.tools.namespace.repl/refresh`

14:30 lynaghk: stuartsierra: no dice---is this something that's fixed on master?

14:30 stuartsierra: lynaghk: can you describe the problem in more detail?

14:30 lynaghk: stuartsierra I'm on 0.2.2. I can give you a minimal case if you want

14:31 stuartsierra: OK.

14:31 In 0.2.3, `refresh` will attempt to recover aliases in the current REPL namespace after a failed refresh.

14:32 lynaghk: stuartsierra: the problem actually crops up before I've even run refresh---it's just if I try to require an ns with a toplevel exception and c.t.n.repl into a scratch namespace

14:33 stuartsierra: lynaghk: I think I need an example to diagnose that.

14:33 lynaghk: stuartsierra: I get an exception when I execute (ns scratch ...) and then running (ns scratch ...) after that gives me an error like "namespace 'ns.with.original.problem' not found"

14:34 stuartsierra: sure. let me whip up a git repo for you.

14:34 stuartsierra: ok cool

14:36 lynaghk: Wait, before you do that, is anything in your project ever AOT-compiled?

14:37 lynaghk: stuartsierra: nope, not that I'm aware of, though I do specify a :main key in my project.clj

14:38 stuartsierra: Some versions of Leiningen automatically AOT-compile :main namespaces, even when you tell them not to. Make sure there are no files in `target/classes`

14:38 lynaghk: stuartsierra: yeah, it's empty

14:38 stuartsierra: ok

14:39 lynaghk: stuartsierra: actually, this may be unrelated to c.t.n. since I still get the issue without that on my classpath.

14:40 stuartsierra: hrm

14:41 I got nuthin'. :)

14:42 jcromartie: do people really use agents?

14:42 I've asked this before I think...

14:42 but I feel like they get no love

14:43 stuartsierra: jcromartie: Simulant makes heavy use of agents

14:43 technomancy: they get frequently abused as "a way to start a thread without touching java" I feel

14:43 cemerick: jcromartie: extensively

14:43 technomancy: or a way to avoid using executors

14:43 stuartsierra: I've used them for asychronous HTTP responses, e.g. long-polling

14:44 hyPiRion: It sounds like a sound way to log stuff, but I've never used them myself.

14:44 jcromartie: I need to cache some things that are loaded periodically from various URLs

14:45 and an agent would seem like a good thing to say (send news-cache update-from url)

14:45 send-off, that is

14:45 lynaghk: stuartsierra: okay, got it. It was a problem with the ns form itself---loading up something that throws an exception will only happen once, and then any namespaces after that will think that they've already loaded the bad namespace up and won't try again. Adding a :refresh-all in my scratch namespace solves the problem.

14:45 mabes: I've used them to write to a csv from multiple threads

14:46 lynaghk: stuartsierra: sorry to attribute that negativity on your project

14:47 stuartsierra: lynaghk: no worries. I don't quite follow your explanation, but I'm glad you found the culprit.

14:47 jcromartie: tools.namespace is my homeboy

14:47 lynaghk: stuartsierra: just that the `ns` form won't retry a failed require unless you explicitly tell it to.

14:47 hyPiRion: Oh right, namespaces may be partially loaded.

14:48 stuartsierra: jcromartie: glad to hear it :)

14:48 lynaghk: stuartsierra: also, just fyi 0.2.3 hasn't been published yet.

14:48 stuartsierra: yes

14:48 very soon

14:48 lynaghk: cool =)

14:48 stuartsierra: maybe today even

14:48 jcromartie: although it seems to have issues with midje autotest

14:49 asteve: ,(map symol ["?one" "two"])

14:49 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: symol in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:49 asteve: ,(map symbol ["?one" "two"])

14:49 clojurebot: (?one two)

14:50 stuartsierra: jcromartie: not surprising, since Midje autotest is trying to do the same thing.

14:50 asteve: ,(vec (map symbol ["?one" "two"]))

14:50 clojurebot: [?one two]

14:50 jcromartie: yeah

14:53 hyPiRion: asteve: mapv would do the same job :)

14:54 asteve: ,(mapv symbol ["?one" "two"])

14:54 clojurebot: [?one two]

14:54 asteve: ,(atom [])

14:54 clojurebot: #<Atom@e6be76: []>

14:55 asteve: I'm going to assume atom does not mean atomic

14:55 so what does it mean? :)

14:55 nDuff: asteve: atoms are one of Clojure's concurrency primitives.

14:55 asteve: ...and actually, yes, changes to them _are_ atomic

14:55 technomancy: Tom Swift and his Atomic Reference Type

14:55 gfredericks: an atom is a reference type

14:55 antares_: asteve: atoms are atomic references, see http://clojure-doc.org/articles/language/concurrency_and_parallelism.html

14:56 nDuff: asteve: ...atomic and uncoordinated, vs refs which are coordinated in transactions

14:56 TimMc: asteve: You're wondering about atoms in the not-a-cons sense, yeah?

14:56 asteve: "This is one of the most hardcore guide of the entire Clojure documentation project. "

14:56 hah

14:56 clojure where cons means construct and atom means atomic

14:57 nDuff: asteve: The dead-tree books cover this well

14:57 asteve: ...and no, atom doesn't exactly mean atomic.

14:57 asteve: ...(atom []) creates an atom

14:57 asteve: ...which is one of the reference type used for atomic operations, but that doesn't mean "atom" means "atomic".

14:58 asteve: I do strongly recommend Programming Clojure (for something focused on practice), or The Joy Of Clojure (for something focused on theory).

14:58 asteve: ah, my mistake

14:58 lynaghk: cemerick: does the auth map have to have the ::friend/workflow metadata?

14:59 cemerick: having (constantly {:identity ... :roles #{...}}) as my workflow function isn't workin' (nil response)

14:59 nDuff: asteve: ...in particular, IMHO, The Joy of Clojure has a gentler introduction to the concepts behind Clojure's concurrency model than what that page has.

14:59 cemerick: lynaghk: it needs :type ::friend/auth meta

14:59 the ::friend/workflow meta is merely informative IIRC

15:00 asteve: nDuff: ok, I've got a lot of time for reading next week so I'll pick it up

15:00 thanks

15:00 lynaghk: cemerick: okay, cool. So I should use the `make-auth` fn in friend.workflows

15:00 cemerick: lynaghk: yeah, probably easier

15:01 nDuff: Err, sorry -- the focused-on-practice book I meant to recommend was Clojure Programming [http://www.clojurebook.com/], not Programming Clojure.

15:02 tieTYT: when should I decide to use comp vs expression threading?

15:02 antares_: asteve: not sure I understand your remark

15:03 asteve: you expected atom to mean something else?

15:03 jcromartie: tieTYT: it is a style decision, sometimes it seems cleaner one way or another

15:03 tieTYT: you can go way overboard with comp and partial, but sometimes it's the right tool for the job

15:04 tieTYT: i see

15:04 jcromartie: ,(map (partial str "prefix-") [1 2 3])

15:04 clojurebot: ("prefix-1" "prefix-2" "prefix-3")

15:05 jcromartie: is clean, but not shorter than #(str "prefix-" %)

15:05 gfredericks: partial would be useful if it were a single character long

15:05 hyPiRion: Then again, (partial str "prefix-") is exactly the same as #(str "prefix-" %).

15:05 isn't*

15:06 jcromartie: not exactly, no

15:06 hyPiRion: ,(map (partial str "prefix-") [1 2 3] [:a :b :c]) ; Useful in certain contexts

15:06 clojurebot: ("prefix-1:a" "prefix-2:b" "prefix-3:c")

15:06 jcromartie: sexy!

15:06 comp/partial always win when it's variable arity

15:06 Apage43: ,(for [n [1 2 3]] (str "prefix-" n))

15:06 clojurebot: ("prefix-1" "prefix-2" "prefix-3")

15:07 Apage43: is still shorter than the original partial

15:07 jcromartie: but the original question was about vs -> and ->>

15:07 and we failed completely to address that

15:07 hyPiRion: which is now totally derailed

15:07 yeah

15:08 tieTYT: that's ok, i learned other things

15:09 jcromartie: ,(->> [500 600 700] (map str) (map reverse) (apply str))

15:09 clojurebot: "(\\0 \\0 \\5)(\\0 \\0 \\6)(\\0 \\0 \\7)"

15:09 jcromartie: not quite what I had in mind

15:09 ,(->> [500 600 700] (map str) (map reverse) (map #(apply str %)))

15:09 clojurebot: ("005" "006" "007")

15:09 lynaghk: cemerick: ah, (constantly ...) doesn't work because it'll put you into a redirect loop. You need to check the uri in the workflow fn and only return an auth map once. in this case, just returning an auth map when the user hits "/openid".

15:09 jcromartie: ,(map (comp (partial apply str) reverse str) [500 600 700])

15:09 clojurebot: ("005" "006" "007")

15:10 Apage43: ,(map #(->> % str reverse (apply str)) [500 600 700])

15:10 clojurebot: ("005" "006" "007")

15:10 hyPiRion: ,(for [v [500 600 700]] (->> v str reverse (apply str)))

15:10 clojurebot: ("005" "006" "007")

15:11 jcromartie: too many ways to do one thing !

15:12 Apage43: For me it comes down to what seems like a nicer way to read what's going on. ->/->> read to me as "take x, then do f to it, then do g to it"

15:12 jcromartie: if you were going to use a Java method or constructor, then you would have to use threading

15:12 Apage43: I read comp as "f of g of x"

15:12 jcromartie: threading macros*

15:12 danneu: "too many ways to do one thing" <- from whence idioms are born

15:12 hyPiRion: hm, is there no function which takes a seq of chars and return a string?

15:12 jcromartie: danneu: "I propose a new unified way!"

15:12 now there are n + 1 ways :)

15:12 hyPiRion: apply str, no?

15:13 (apply str (seq "asdf"))

15:13 ,(apply str (seq "asdf"))

15:13 clojurebot: "asdf"

15:13 hyPiRion: jcromartie: yeah, but that's using apply.

15:13 jcromartie: (partial apply str) :)

15:13 now it's a function :P

15:13 cemerick: lynaghk: Yeah, the workflow fn is still a handler (and so needs to match only appropriate routes, etc). Sorry, glossed over the `constantly` in your previous msg.

15:13 hyPiRion: ,(clojure.string/join "" (seq "asdf")) ; I suppose

15:13 clojurebot: "asdf"

15:14 jcromartie: ,(clojure.string/join (seq "asdf"))

15:14 clojurebot: "asdf"

15:14 jcromartie: we have a winner

15:14 hyPiRion: oh bleh

15:14 today I learned.

15:14 (inc jcromartie)

15:14 lazybot: ⇒ 3

15:14 jcromartie: 3… dang

15:14 I gotta get cracking

15:15 lynaghk: cemerick: thanks for the tips---this approach is working great. Maybe after it's running for a few months I'll factor all of this stuff out into some real docs+example repos.

15:15 zerokarmaleft: hyperion: clojure.string/join just does (apply str coll)

15:15 cemerick: lynaghk: PR's welcome for concrete use cases in friend-demo

15:15 lynaghk: cemerick: will keep that in mind.

15:16 danneu: (map (comp join reverse str) [500 600 700])

15:16 hyPiRion: zerokarmaleft: oh, I see why now

15:17 apply str [...] needs to only read two items to know what to dispatch on

15:17 and it's using a stringbuilder under the covers, so apply str isn't that bad.

15:17 tieTYT: Apage43: isn't threading more like "take x, then do f to it, then take that and do g to it"?

15:18 hyPiRion: tieTYT: yeah, that's correct

15:18 Let me find a good example (if I have any)

15:19 https://www.refheap.com/paste/13090 <- example from actual code I have

15:20 tieTYT: that looks clean

15:20 why all the parens? Those are optional right?

15:20 if you're just passing one param total

15:21 hyPiRion: yeah, they are optional, I just want to indent properly

15:21 tieTYT: eg: showdown doesn't need the parens

15:21 oh ok

15:21 hyPiRion: It's just a matter of preference, I guess.

15:28 st3fan: does anyone know a project that implements ASeq?

15:28 hyPiRion: st3fan: I suppose you mean ISeq?

15:29 Well, Clojure does anyway

15:35 amalloy: hyPiRion: why :on-turn instead of just :turn or [:on :turn] or something? it seems like you lose the connection between turn-card and turn-betting, for no real gain

15:38 tomoj: is that CPS'd or are all the players bots?

15:38 or neither

15:39 hyPiRion: tomoj: depends, all players may be bots, but may have people in the game too

15:40 amalloy: because it reads better, and because it doesn't really matter in the rest of the code

15:41 Perhaps I could've done :on :turn, but well

15:41 tomoj: so just block in that function on their responses

15:42 hyPiRion: tomoj: yeah

15:42 jayunit100: hmm Could not locate clojure/tools/logging__init.class or clojure/tools/logging.clj on classpath: <-- isn't this standard in clojure? or is there a lein dep i need to add .

15:43 __zero: Is there any way to limit the number of threads launched by calling future?

15:43 (I don't know if what I'm asking actually makes sense)

15:44 stuartsierra: __zero: future uses the same thread pool as send-off

15:45 You can change that to a thread pool with a maximum size with `clojure.core/set-agent-send-off-executor!`

15:45 amalloy: jayunit100: no, it's in the clojure.tools.logging project

15:45 jayunit100: [org.clojure/tools.logging "0.2.6"] <-- thanks

15:46 __zero: stuartsierra: thanks i'll look that up

15:53 jcromartie: isanybody from Prismatic here?

15:56 jayunit100: is there a way at the repl to see what is available in the "clojure.tools.logging" namespace? sorry… forgot some clojure

15:57 stuartsierra: jayunit100: clojure.repl/dir

16:00 jayunit100: stuartsierra: ah thanks thats a really important trick

16:02 stuartsierra: You're welcome.

16:02 supersym: weet

16:02 *sweet even

16:03 rads: I'm trying to get set up with the project at https://github.com/emezeske/lein-cljsbuild/tree/master/example-projects/simple

16:03 it doesn't seem like my server files are reloading when I change them

16:03 is there something more I need to do to make that work?

16:05 jayunit100: ok - so I've got the lib working in "lein test", but for some reason the (use *) directive fails in the "lein repl" . https://gist.github.com/jayunit100/5273274 <-- am i doing something crazy here?

16:05 hyPiRion: jayunit100: you need a ' in front of the vector

16:06 ,(use '[clojure.string :only ()]) ;; example

16:06 clojurebot: nil

16:06 jayunit100: gotcha thanks

16:06 * jayunit100 keeps forgetting how to metaprogram

16:12 Raynes: That's a feature.

16:12 cztomsik: is it possible to filter collection using predicate taking two parameters? filtered item and last successfully tested item?

16:13 hyPiRion: cztomsik: last successfully tested item?

16:14 Elaborate on that one.

16:14 mpenet: anyone knows how to pass optional params to carmine such as limit, withscores etc?

16:15 cztomsik: to turn [1 2 3 1 4] into [1 2 3 4] (testing if next item is bigger than previous one)

16:15 mpenet: probably just as strings + value, but I am not 100% sure

16:15 ex for zrevrangebyscore

16:15 cdh473: cztomsik: afaik, there isn't a core function for that

16:15 rads: does anyone have an example of a compojure project that does automatic reloading?

16:15 cztomsik: previous == previous which was bigger last time :)

16:15 TimMc: cztomsik: I think I'd go straight to loop/recur for that.

16:15 hyPiRion: well, if you're happy with not being lazy:

16:15 cdh473: you can definitely roll your own though

16:16 weavejester: rads: If you're using lein-ring, that will handle it automatically for you

16:16 cztomsik: I'd like to not solve it in terms of recursion

16:16 rads: does it matter if I'm using clojurescript, thus my server files are in src-clj, not src?

16:17 weavejester: rads: Not with the very latest lein-ring

16:17 cztomsik: but i am not sure if it is solvable otherwise :)

16:18 hyPiRion: ,(let [v [1 2 3 1 2 4]] (reduce (fn [a b] (if (< (peek a) b) (conj a b) a)) (-> v (get 0) vector) v))

16:18 clojurebot: [1 2 3 4]

16:18 rads: weavejester: aha, that was it, my lein-ring was outdated

16:18 the example project from lein-cljsbuild is very out of date

16:19 ty

16:19 cztomsik: hyPiRion: how about feeding it with range?

16:20 hyPiRion: cztomsik: well, this one isn't lazy, so that would bork stuff

16:20 You'd have to make a lazy-seq function then.

16:20 cztomsik: yep, anyway thx - I think the best I can invent here is lazy-seq :)

16:21 hyPiRion: thx, I am still quite new to this :)

16:21 hyPiRion: np

16:23 oh, might be valuable to know that you could do ##(let [foo (fn f [x] (if (zero? x) x (f (dec x))))] (foo 10))

16:23 lazybot: ⇒ 0

16:23 hyPiRion: the (fn f [...] part

16:24 cztomsik: hyPiRion: self-referencing?

16:31 rads: has anyone worked with the git api using clojure?

16:31 it looks like there are no bindings for libgit2 for java

16:32 cdh473: http://www.autismgames.com.au/game_eyecontact.html

16:33 crap

16:33 that was the wrong channel, excuse me

16:37 dnolen: ,(let [v '(1 2 3 1 4)] (first (reduce (fn [[xs l] x] (if (< x l) [xs l] [(conj xs x) x])) [[] (first v)] v)))

16:37 clojurebot: [1 2 3 4]

17:01 gynna: http://xeroticmomentsx.blogspot.com/2013/03/amateurgallery.html

17:02 Raynes: I guess if you read the URL it is fairly obvious that that link is NSFW, but I'll go ahead and put this here anyways.

17:02 stuartsierra: Probably full of malware too.

17:03 Raynes: It's full of boobs, mostly.

17:03 I unfortunately did not read the link before clicking it.

17:03 rboyd: you're fired

17:07 http://michaeldrogalis.tumblr.com/post/46560874730/beautiful-separation-of-concerns

17:07 "I was going to write a nice narrative about how I wrote some beautiful code, but I’m just going to show it to you."

17:08 I'm trying to imagine how beautiful the code would have to be in order for that soundbite to not rub me the wrong way

17:10 nDuff: That _is_ actually pretty awesome.

17:10 * nDuff is much more impressed with the code than offended by the soundbite.

17:15 tieTYT: i don't get how this works

17:15 that link

17:15 ohh, there's no def(n)

17:15 so it just runs that code when you require it

17:19 tomoj: it seems pretty obvious to me that "simply don’t require dire-example.logging!" is not an acceptable answer

17:22 mjg123: Anyone know if it's possible to use something like (read-line) to get user input in light-table?

17:29 ravster: how do I get a printout of all liberator resources for a request? with their values?

17:32 `arrdem: what happened to #clojure....

17:33 these links I don't even

17:33 ravster: `arrdem: ?

17:34 `arrdem: my scrollback shows Raynes and cdh473 posting random stuff. anyway.

17:34 Raynes: I didn't post anything

17:35 `arrdem: anyone tried to fake a goto in clojure?

17:35 Raynes: I hope not.

17:35 cdh473: `arrdem: hmm? i made an accidental post to a site, just because i was in the wrong channel

17:35 amalloy: $google lambda the ultimate goto

17:35 lazybot: [The Original 'Lambda Papers' by Guy Steele and Gerald Sussman] http://library.readscheme.org/page1.html

17:35 `arrdem: amalloy: relax I know this is evil

17:36 Raynes: Dude, you're getting people way mixed up.

17:36 amalloy: why would i need to relax? i linked you to a paper

17:36 Raynes: amalloy: He thought you were me, I think.

17:37 `arrdem: Raynes no I'm just insane. all is well.

17:37 brain_shim_: heyo

17:37 `arrdem: amalloy: thanks for the link, those papers are in my to read stack but I forgot about em

17:38 mjg123: What options do I have for teaching clojure to a group of 20-ish people? Not going to have reliable internet so I'd like some easy self-contained repl or ide to work with.

17:38 brain_shim_: If I have a LazySeq, and it looks like a hash map, how do I return only values that match a specific key?

17:39 Like I have a big list of :text and :href, and I only want the :href

17:39 `arrdem: brain_shim_ filter?

17:39 ,(doc filter)

17:39 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

17:39 brain_shim_: gracias

17:41 `arrdem: I was just curious.. my compiler builds to a GOTO based IR and it'd be humorus if I could directly evaluate it in Clojure since it's already almost valid clisp

17:41 s/clisp/cl ; before someone else points it out

17:41 supersym: ahhh... tech rush of good music and programming Clojure :)

17:41 *floats away to turn op teh vol*

17:42 `arrdem: supersym: share ze gud stuff my track just ended

17:43 supersym: I'm actually making my first youtube lists :P

17:44 http://www.youtube.com/playlist?list=PLxz13xdIVCTbte5elY5f_sCgMVFDdweas

17:44 a bit nostalgic but great dance tunes :)

17:45 `arrdem: (inc supersym)

17:45 lazybot: ⇒ 1

17:46 supersym: :D

17:49 aaelony: if I use Compojure in a project and start up with lein ring server-headless, can can I connect via repl and make live changes, or do I need to (use or) require clojure.tools.nrepl.server in my project?

17:50 technomancy: aaelony: better to launch with lein repl and run a jetty from inside it

17:50 aaelony: technomancy: I'm unfamiliar, can you recommend a good link to read up?

17:51 hyPiRion: aaelony: not sure if this is what you want, but lein ring server-headless listens to changes in the source files, and would reload them if needed

17:51 aaelony: by run a jetty inside, that is a function call to jetty ?

17:51 technomancy: aaelony: yeah, lemme find a link

17:51 `arrdem: a while ago I answered some guy's question here about how to embed a port-bound repl in an application. Is that something anyone's ever seen done seriously?

17:52 technomancy: aaelony: https://github.com/technomancy/syme/blob/master/src/syme/web.clj#L139

17:52 aaelony: hyPiRion: yes, that is really awesome. I'd like to continue to test out new things though while its live though...

17:52 hyPiRion: aaelony: ah, right

17:52 aaelony: things that might break

17:52 :)

17:52 ;)

17:53 technomancy: that's awesome, thanks for the link :)

17:54 technomancy: aaelony: yeah, I basically never use lein ring; I much prefer the primacy of the repl

17:54 it reloads when you tell it to vs some imperfect heuristic of file-watching

17:55 brain_shim_: how can i retrieve a key from a PersistentArrayMap?

17:55 like the value of that particular key

17:55 aaelony: honestly, I'm looking to read up on examples to do it with nrepl but a bit confused as to where the use cases are and how they match up with what I want ...

17:56 `arrdem: brain_shim_: get or treat the map as a function with the key as an argument

17:56 aaelony: reloads on demand are exactly what I want.

17:56 `arrdem: or if you have a keyword key then you can make it the function with the map as an arg

17:56 aaelony: on demand meaning "when you tell it"

17:57 brain_shim_: `arrdem: I can almost see what you're saying.

17:58 technomancy: aaelony: yeah, IMO starting a ring server should be no different from calling any other repl function

17:58 `arrdem: brain_shim_ (get map key) or (key map) or (map key)

17:58 brain_shim_: `arrdem: ah

18:00 aaelony: technomancy: cool. basically I'd like to start the server up (within screen or something) and repl-in (if that's a verb) when I want to, do make changes or try things out, debug, etc...

18:00 technomancy: aaelony: oh, for production?

18:01 not so keen on that for production unless it's a toy app

18:01 aaelony: it's a toy app

18:01 technomancy: I'm thinking of that more as a development strategy

18:02 aaelony: that said though, it'd be interesting to hear what people recommend from experience, both as a dev strategy and in production

18:08 amalloy: `arrdem, brain_shim_: note that (key map) only works for keys which are keywords or other similar self-looking-up objects. very handy, and works most of the time, but (get map key) is the most general

18:12 jemafeller: i'm trying to rationalize choosing Clojure over Scala.

18:13 the logic i'm applying is - I can use Clojure for what it is, and for performance - I can always use bare Java (which is faster than Scala in any case)

18:13 so based on that logic, I rarely have a reason to bother with Scala

18:13 jack_rabbit: jemafeller, How about the syntax? Lisp is much nicer than what I've seen from scala, IMO.

18:14 jemafeller: jack_rabbit, it's already given I like clojure better than Scala - the syntax, the developer tooling and the community

18:14 nDuff: jemafeller: http://hammerprinciple.com/therighttool/items/clojure/scala

18:14 jack_rabbit: Well I'd call that reason enough right there.

18:14 jemafeller: i'm just trying to handle my own mental challenges - the "what if's"

18:15 `arrdem: yeow... good link nDuff


18:16 jack_rabbit: very funny.

18:16 jemafeller: lol

18:16 jack_rabbit: I've been to that site before when considering haskell vs erlang.

18:18 tieTYT: why is there 7% for this: THIS LANGUAGE HAS A STRONG STATIC TYPE SYSTEM

18:18 `arrdem: does Clojure provide any gurantee that a macro won't infinitely expand? I don't think so...

18:19 amalloy: `arrdem: how could it? you can write any macro you want

18:19 `arrdem: tieTYT because scala compiles to static types while clojure is entirely dynamicly typed

18:19 jack_rabbit: I think he means why is there even 7%.

18:19 amalloy: (demacro explode [x] `(explode (list ~x)))

18:20 hiredman: the compile expands macros in a non-iterative way, so the stack will eventually blow

18:20 or did last I checked

18:20 `arrdem: amalloy: yeah... just contemplating whether to provide a "real" (infinite OK) macro system inside this compiler or whether I should stick to C's "fake" (one expansion only) macro system.

18:20 jack_rabbit: Maybe we can kill clojurebot?

18:20 `arrdem: jack_rabbit: it's been done before... he's even been rooted before.

18:20 jack_rabbit: Heh.

18:20 amalloy: hiredman: still does

18:21 jack_rabbit: Can you spam the channel with it? I'm tempted to try, but don't want to get booted.

18:21 Also don't really want to spam the channel.

18:21 `arrdem: jack_rabbit: not really. I've tried..

18:21 the bots ignore each other so no mutual recursion..

18:21 Apage43: Typically you can only get it to send one line of output per line of input

18:22 `arrdem: and that.

18:23 oh the heck with it. I clearly need a real macro system to implement pascal.

18:23 jack_rabbit: ,(map #(println %) (range 10))

18:23 clojurebot: (0\n1\n2\n3\n4\n5\n6\n7\n8\n9\nnil nil nil nil nil ...)

18:24 jack_rabbit: ,(doseq [x (range 10)] (println x))

18:24 clojurebot: 0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n

18:24 jack_rabbit: Heh. I see those newlines in there.

18:26 tieTYT: `arrdem: so why didn't clojure get 0%?

18:26 `arrdem: tieTYT: probably because you can argue that clojure is staticly typed under the hood

18:26 it's just that the exposed runtime (what we think of the language) is dynamicly typed.

18:26 jack_rabbit: Also you can provide type "hints" for performance.

18:27 Which sort of exposes the static nature of the underlying system.

18:27 Wait. I'm thinking weak vs. strong.

18:27 `arrdem: so the clojure we're talking about here goes to Java at the end of the day. hence the (:gen-class) stuff, interfaces and IFn etc.

18:28 amalloy: `arrdem: that's a silly argument. go further under the hood, and it's all just registers and RAM in any language

18:28 `arrdem: amalloy: heh I just reached that conclusion when I started thinking about Lisp 1

18:28 amalloy: the language that you actually use, clojure, is dynamically typed

18:29 `arrdem: All hail the Turing Machine, integers are all we have and all we shall ever need. HAIL!

18:30 jack_rabbit: Poor Alan.

18:34 holo: hi

18:36 jack_rabbit: hola, holo.

18:36 holo: hello jack_rabbit

18:37 can someone point me in the right direction to implement captchas? I can't find any clj lib

18:38 jack_rabbit: Might look into a Java captcha library.

18:38 I'm sure there's one or two floating around.

18:38 holo: jack_rabbit, I guess that would be the second best way hehe

18:38 mpenet: recaptcha is good enough for most cases

18:39 jack_rabbit: I would think it would be trivial to nicely wrap the most common functions of one of those libraries in a nice clojure-ey way.

18:40 I'm excited for clojure to get onto Microsoft's CLR, purely for the reason that I think it'll gain some momentum there.

18:40 holo: I could summon myself to do that

18:41 thanks jack_rabbit mpenet

18:41 jack_rabbit: Any time, dear holo.

18:44 tjgillies: is there a reason symbols can't start with numbers?

18:45 jack_rabbit: Probably makes symbols unnecessarily difficult to parse.

18:45 (My guess)

18:45 tjgillies: ah

18:45 (inc jack_rabbit)

18:45 lazybot: ⇒ 1

18:45 `arrdem: wow... a recursive implemntation of macroexpand is only 11 lines... I love lisp.

18:45 Willyfrog: many languajes don't allow variables to start with numbers

18:46 amalloy: 11 lines?! how did you manage to spend 11 lines on that?

18:46 jack_rabbit: I know in CL, numbers can have suffixes, etc. that modify them, so differentiating symbols that start with numbers from numbers with suffixes would be difficult.

18:46 `arrdem: jack_rabbit: to be more exact the Java definition of a symbol requires that it match approximately [a-zA-Z][a-zA-Z0-9]*

18:46 tjgillies: ,(var? 'symbol)

18:46 clojurebot: false

18:47 Willyfrog: I was pointing it to reinforce the parse, not meaning a symbol is a var

18:47 `arrdem: amalloy: https://www.refheap.com/paste/13101

18:47 tjgillies: ahh

18:47 its java thing

18:47 (inc `arrdem)

18:47 lazybot: ⇒ 1

18:48 `arrdem: $karma arrdem

18:48 lazybot: arrdem has karma 1.

18:48 `arrdem: Q_Q this is what I get for changing nics

18:48 amalloy: java doesn't have symbols (or at any rate, they're an internal thing that's totally different from clojure symbols)

18:48 jack_rabbit: $karma jack_rabbit

18:48 lazybot: jack_rabbit has karma 1.

18:48 jack_rabbit: cools.

18:48 amalloy: and your macroexpander does something totally different from clojure's. you have to expand the outer form first, not the inner forms

18:49 `arrdem: amalloy: no.. I recur over the sub-expressions first using map

18:49 line 3

18:49 amalloy: yes, that is exactly what i am saying you must not do

18:49 `arrdem: oh I misread your first.

18:49 ah ok.

18:50 tjgillies: (inc amalloy)

18:50 lazybot: ⇒ 46

18:50 amalloy: anyway, 11 lines is reasonable if you're actually walking the whole form; i thought you had managed to spend 11 lines just expanding the outermost form

18:51 and you should really map macroexpand over the whole expr, not just the rest. eg, what about ((memfn size) (ArrayList. 10))?

18:52 Willyfrog: you can have a symbol like _1

18:52 it would be weird, but close to "starts with a number"

18:53 `arrdem: Willyfrog: I use that one all the time, the _ prefix is for "ignored value". it's great in argument destructuring.

18:53 amalloy: hum... so really I want to map macroexpand... and just return the result?

18:54 no I still have to do the first lookup and apply.

18:54 amalloy: right. but once you do that, you just map macroexpand over the result

18:56 `arrdem: hum.. so I really want to define macroexpand to be macroexpand of first, lookup & transform on rest, macroexpand rest & cons.

18:58 tjgillies: can i set data readers from lein user profile?

18:59 seems weird i have to keep them in a file

19:07 brain_shim_: If I have a LazySeq of strings, how can I perform a split on "\n" on each of the strings?

19:11 Apage43: brain_shim_: do you want a seq of seqs or just a single seq of all ines?

19:11 *lines

19:12 brain_shim_: seq of seq

19:12 Apage43: ,(map clojure.string/split-lines ["a\nb\nc" "d\ne\nf"])

19:12 clojurebot: (["a" "b" "c"] ["d" "e" "f"])

19:13 brain_shim_: I love this bot

19:13 Thanky!

19:13 Apage43: you'll want to require clojure.string of course

19:14 brain_shim_: :)

19:18 tjgillies: damnit datomic has ruined me, now im pissed theres no datalog for ruby (that i can find)

19:21 hiredman: https://github.com/spariev/mini_kanren

19:28 rads: why is there a libgit2 binding for "Chicken Scheme" and not clojure? :(

19:28 amalloy: $google java libgit2

19:28 lazybot: [libgit2: a Git Linkable Library · GitHub] https://github.com/blog/752-libgit2-a-git-linkable-library

19:29 amalloy: (i dunno if there is one, but my point is you should be looking in java)

19:30 rads: it doesn't look like there are any java bindings either

19:30 which is surprising to me

19:30 you think clj-native would be the way to go?

19:38 john2x: trying out Luminus, when I do a login with reddit.clj (https://github.com/sunng87/reddit.clj), how do I save a session of it?

19:39 Willyfrog: maybe with http://www.luminusweb.net/docs/sessions_cookies.md

19:40 hyPiRion: Oh, sexy, the new clojure-mode is more pleasing to the eye in zenburn.

19:44 Bronsa: oh, I didn't even notice

19:45 john2x: Willyfrog: oops missed the topics list at the right. thanks!

19:45 Willyfrog: :)

19:45 I'm currrently looking at luminus, so it was easy to link ;)

19:54 technomancy: rads: probably because everyone on the jvm uses jgit?

19:55 (even though it's not as good)

19:55 rads: yeah, you're right

19:55 it seems to be good enough for my purposes (trying to aggregate the git log of multiple repos)

19:57 technomancy: jgit is fine for read-only stuff

20:03 Willyfrog: time to hit the bed

20:03 good night!

20:20 moredogmeat: hi, does anyone know how to convert a vector [] to an array of Java Object?

20:20 Object[]?

20:20 clojurebot: ,(let [testar (fn [x y] (if (= (reduce + (filter odd? (range 0 x))) y) (str y " is an square perfect")) )] (testar 10 25))

20:21 tieTYT: CompilerException java.lang.RuntimeException: Unable to resolve symbol: doc in this context, compiling:(NO_SOURCE_PATH:1:1)

20:21 this is in counterclockwise

20:22 amalloy: (into-array Object ...)

20:25 moredogmeat: (into-array Object [3 4])?

20:26 thank you amalloy

20:29 john2x: can't i use a defrecord outside of a file?

20:30 (outside of the defrecord's namespace?)

20:30 referring to this code: https://github.com/sunng87/reddit.clj/blob/master/src/reddit/clj/core.clj `login` can use the `RedditClient` record, but I can't refer to it in the REPL.

20:31 bttf: been learning clojure for a little while now, wondering what are some of the best libraries to use to host a personal blog? i'm running nginx on my webserver and would like to reverse proxy it to an clojure-run webserver.. ring and compojure look good, any suggestions ?

20:31 john2x: *use it in the REPL

20:33 bttf: I'm trying out Luminus at the moment (built on ring and compojure). Coming from a Python/Django/Flask background, it's pretty familiar. But maybe it's overkill for a personal blog, I dunno.

20:33 bttf: interesting

20:34 john2x: mostly because it uses clabango as the templating engine.

20:34 bttf: how does clabango compare with hiccup ?

20:38 brain_shim_: I have a LazySeq of PersistentArrayMap's (yay type!). How can I select-keys for each entry in my LazySeq?

20:38 `arrdem: (inc supersym) ;; damn good playlist

20:38 lazybot: ⇒ 2

20:38 john2x: bttf: haven't tried hiccup, but from what I can see, they look completely different. all the other templating engines are really alien to me, since I've only been exposed to Django/Jinja. :-/

20:38 bttf: oh ok

20:39 john2x: clabango was such a relief

20:42 ah, so you need to require and import the record to use it in a different namespace

20:48 amalloy: brain_shim_: how is this different from your last question?

20:50 brain_shim_: amalloy: I googleled until I could phrase it in clojure nomenclature?

20:53 `arrdem: .. and from that you can't google up the selection operations?

20:54 hyPiRion: ,(map #(select-keys % [:a :c]) [{:a :b :d :g} {:b :c :a :e :c :g} {:a 1 :b 2}])

20:54 clojurebot: ({:a :b} {:c :g, :a :e} {:a 1})

20:55 hyPiRion: of just as a list comprehension

20:55 brain_shim_: hyPiRion: Thanks.

20:56 jack_rabbit: Is it possible to have "static" variables inside functions similar to how it's done in C?

20:56 (without declaring them globally)

20:56 amalloy: every variable is static if you never mutate it

20:57 jack_rabbit: But I can't reference x inside a function unless I def it, which changes its value.

20:58 And static in C doesn't mean that it doesn't change. It means that it retains its value across calls.

20:59 hyPiRion: jack_rabbit: then no.

20:59 technomancy: clojure has locals and vars

20:59 hyPiRion: just define an atom outside or within a closure

21:01 `arrdem: jack_rabbit: so I think you need to clarify what behavior you are looking for.

21:01 amalloy: my point was that if values never change, you can't tell a c static from a c constant

21:02 and since clojure encourages you not to change things...

21:02 jack_rabbit: I'm writing a function memoize-fn which accepts a function and its arguments and either executes it or returns the previous results of that function which will be stored in a map. The map therefore will need to be maintained across calls, but I don't particularly want it to be accessible outside the function.

21:02 `arrdem: are you looking for a global static value, a global but mutable value or a local static?

21:02 amalloy: jack_rabbit: is there a reason you don't want to just use clojure.core/memoize?

21:02 SegFaultAX: jack_rabbit: Why you no use memoize?

21:02 jack_rabbit: amalloy, It's just an exercise.

21:03 amalloy: so read the source of memoize. you'll see what techniques are available in clojure

21:03 then you can write it your own way

21:03 `arrdem: jack_rabbit: so what you want to do (probably) is define a closure with an atom.

21:04 jack_rabbit: Okay. I understand clojures, but don't understand what you mean by that, which signals to me that I need to continue reading before I try to implement this function. Thanks, guys.

21:04 SegFaultAX: jack_rabbit: Do you know what a closure is?

21:04 jack_rabbit: Yes.

21:05 SegFaultAX: jack_rabbit: I just want to make sure you're not getting confused with Clojure, the language.

21:05 jack_rabbit: No.

21:05 `arrdem: ,((let [x 3] (fn [] x))) ;; closure should work...

21:05 clojurebot: 3

21:06 jack_rabbit: But even that would need to be stored globally, right?

21:06 `arrdem: what do you mean by stored globaly?

21:06 jack_rabbit: How would I keep track of the closure?

21:07 Except for a globally accessible symbol?

21:07 `arrdem: you don't have to.


21:07 that binding is constant across calls to the returned anon function.

21:07 hyPiRion: (let [x (atom 0)] (defn foo [y] (do-something-with y) (println "called" (swap! x inc) "times"))) <- example of a clojure

21:07 SegFaultAX: jack_rabbit: I think you don't know what a closure is. Google or StackOverflow might help here.

21:07 hyPiRion: dangit, closure

21:07 jack_rabbit: Okay. Back to reading for me, then.

21:07 Thanks, guys.

21:07 hyPiRion: jack_rabbit: ^ look at that example and play with it, it should work

21:08 jack_rabbit: OH! It's a closure around a function definition?

21:09 hyPiRion: jack_rabbit: yeah

21:09 jack_rabbit: VERY VERY cool! I'd never even considered that possibility!

21:09 Good then. I do understand closures, I just hadn't considered the possibility of using them in that way.

21:10 `arrdem: jack_rabbit: there's a book on this.. let over lambda. if you want to see evil & amazing things done with closures.

21:10 hyPiRion: heh

21:10 SegFaultAX: jack_rabbit: Now if you do (source memoize) at your repl as amalloy suggested, you'll have a good idea of how the clojure.core function works by comparison.

21:10 `arrdem: I still only understand about a quarter of it.

21:10 jack_rabbit: I'll check it out.

21:10 hyPiRion: jack_rabbit: you can also do (def foo (let [x (atom 0)] (fn [y] ...)))

21:10 jack_rabbit: SegFaultAX, Do you by chance know where source is defined? It's not interned in my user package.

21:11 holo: (inc jack_rabbit)

21:11 lazybot: ⇒ 2

21:11 SegFaultAX: jack_rabbit: clojure.repl/source

21:11 holo: (inc mpenet)

21:11 lazybot: ⇒ 1

21:11 jack_rabbit: Cool.

21:11 gfredericks: ,(apropos "source")

21:11 clojurebot: (*source-path* source source-fn resource)

21:12 gfredericks: ,(map resolve (apropos "source"))

21:12 clojurebot: (#'clojure.core/*source-path* #'clojure.repl/source #'clojure.repl/source-fn nil)

21:12 SegFaultAX: ,`source

21:12 clojurebot: clojure.repl/source

21:13 jack_rabbit: cool.

21:13 Judging by the memoize source, I was on the right track.

21:13 (You guys too with the closure)

21:14 holo: (inc amalloy)

21:14 lazybot: ⇒ 47

21:15 `arrdem: DAE think that should really be inc! ?

21:15 hyPiRion: (swap! amalloy inc)

21:15 jack_rabbit: Must be legacy CL syntax. :)

21:20 hyPiRion: ,((`[~@(ns-map((`[~@(meta #'source)](*))(*)))](#(* % %)(*(+(*)(*))(+(*)(#(* % %)(+(*)(*)))))))(*))

21:20 clojurebot: #'clojure.repl/source

21:28 MikeSeth: i think i accidentally wrote a nrepl client

21:30 jack_rabbit: congrats. Most accidents aren't that happy.

21:42 Okay. When I do (def x (ref 5)), why can I then do (def x (ref 3))?

21:42 And the change is seen across threads?

21:43 Is it just that clojure allows you to do something dangerous?

21:43 `arrdem: as C is evidence languages have no duty to protect agains programmer stupidity...

21:44 s/agains/against

21:44 jack_rabbit: Sure, but HLL's often times do.

21:44 I wasn't sure if this was the case or not.

21:44 `arrdem: if I just (doc) var, it isn't clear what the multithreaded behavior is.

21:44 however atoms provide multithreaded gurantees so I'd just use those.

21:44 jack_rabbit: So to be clear: In this case, clojure allows you to do something dangerous by redefining bindings to that reference.

21:45 seancorfield: def changes the root binding of x (as I understand it) so all threads see the change to x

21:45 `arrdem: correct.

21:45 seancorfield: you shouldn't use def to change a var tho', just to create it initially

21:46 jack_rabbit: What should you use to change a var?

21:46 seancorfield: you should instead use the appropriate functions for operating on the ref (or atom)

21:46 jack_rabbit: (I understand I should use ref-set to change a reference.)

21:46 Okay. That's what I thought. I was just experimenting with the language.

21:47 So re-def'ing a binding to a reference is a dangerous no-no.

21:47 seancorfield: In Clojure, you don't change Vars (except in weird situation).

21:47 `arrdem: jack_rabbit: it isn't dangerous.. it's just weird.

21:47 seancorfield: Re-def'ing any Var is a bad idea / weird/

21:47 jack_rabbit: `arrdem, But can't you run into concurrency issues when you do that?

21:47 seancorfield: Mostly, data is supposed to be immutable.

21:48 `arrdem: jack_rabbit: no, var defs are atomicaly synchronized.

21:48 seancorfield: Then you use controlled mutability (atom, ref, agent) to deal with state that really has to exist and be mutable.

21:48 SegFaultAX: jack_rabbit: Vars have a root binding and a thread local binding. Also, see clojure.core/alter-var-root

21:49 jack_rabbit: According to this article I'm reading, alter-var-root is used to atomically set a new root value, implying that def does not atomically achieve this.

21:49 SegFaultAX: jack_rabbit: See the first part of what I said.

21:50 seancorfield: which article?

21:50 fyi, from our production code base... Clojure source 65 files 10834 total loc, 881 fns, 445 of which are private, 123 vars, 2 macros, 17 atoms

21:50 SegFaultAX: jack_rabbit: It is possible to have a thread local binding differentiate from the root. You might also be interested in defonce.

21:50 seancorfield: only 17 atoms in 11kloc and no refs

21:50 jack_rabbit: seancorfield, http://java.ociweb.com/mark/clojure/article.html

21:50 seancorfield: and almost all of those atoms are caches

21:51 SegFaultAX: seancorfield: Not much coordination needed, eh?

21:51 jack_rabbit: seancorfield, Look at the reference types section.

21:51 seancorfield: jack_rabbit: that article should be more clear that its very rare to change Vars

21:51 jack_rabbit: So why have alter-var-root if def does it atomically anyway?

21:51 seancorfield: although the article does say "The use of Vars is often frowned upon because changes to their values are not coordinated across threads."

21:52 jack_rabbit: Right!

21:52 That's my confusion.

21:52 What does "coordinated across threads" mean?

21:52 seancorfield: SegFaultAX: our mutable state lives in MongoDB and MySQL mostly :)

21:52 jack_rabbit: pretend the article doesn't show you how to change Vars - it isn't ideiomatic Clojure so don't worry about it

21:53 SegFaultAX: seancorfield: Sure, but refs provide coordination where atoms do not. That's why I said that. :)

21:53 jack_rabbit: Except for when you need to change vars, that is.

21:53 hyPiRion: jack_rabbit: you know that cores have their own L1(and possibly L2) cache? It essentially means that those caches won't be updated, which may mean that other threads use an older version of the contents of a var

21:53 jack_rabbit: That's not a satisfactory answer in my view. I'll google it if I have to, but if you all have an answer, I'm interested in knowing the answer.

21:53 seancorfield: Simple answer: never change a Var.

21:53 ivaraasen: hyPiRion: just Clojure stickered all the thing, BTW

21:53 SegFaultAX: Unless you need to.

21:54 seancorfield: Clojure's Vars are not like variables in other languages.

21:54 hyPiRion: ivaraasen: nice, seet

21:54 jack_rabbit: hyPiRion, Okay. So even though my thread saw the update to the binding, there's no guarantee that it will at any particular time when I re-def it?

21:54 hyPiRion: *sweet

21:54 tomoj: def can't do it atomically

21:54 you would have to read the current value and then def

21:54 hyPiRion: jack_rabbit: as far as I can understand, yes.

21:55 jack_rabbit: hyPiRion, Okay. Thanks a ton. That's exactly what I wanted to know.

21:55 SegFaultAX: jack_rabbit: Always be cautious of people who use words like "always" and "never".

21:55 seancorfield: esp. when they have both in the same sentence :)

21:55 jack_rabbit: SegFaultAX, I'm learned in the ways of avoiding those terms.

21:55 * Sgeo decides to be cautious of SegFaultAX

21:56 * jack_rabbit caught that as well.

21:56 `arrdem: (inc Sgeo)

21:56 lazybot: ⇒ 2

21:56 SegFaultAX: I can think of at least one reasonable usage of var altering I've seen.

21:56 seancorfield: I'm always cautious of SegFaultAX ... doh!

21:56 SegFaultAX: ;)

21:56 `arrdem: the one time I altered a var was when I stuck a repl port in the back of my server as an experiment.

21:56 hyPiRion: I always avoid those terms. muahahah

21:56 `arrdem: 5/5 do not recommend.

21:56 but it did work.

21:57 ivaraasen: seancorfield: nice amount of macros, BTW. I tend to overuse them myself

21:57 SegFaultAX: I was thinking more along the lines of technomancy's robert.hooke lib.

21:57 seancorfield: `arrdem: yeah, actually just today i ran two def's via nrepl on our running production servers

21:57 SegFaultAX: hook-scopes is basically just a ball of var altering goodness.

21:57 seancorfield: needed to apply a hotfix to a function without restarting the app

21:58 SegFaultAX: seancorfield: What could possibly go wrong!?

21:58 seancorfield: we don't run nrepl servers all the time... we start and stop them when we need them

21:58 and mostly try to avoid hotfixes on the live, running app

21:58 but we're sure glad clojure gives us the _option_

21:59 hyPiRion: Erlang is interesting when it comes to that. You can do safe code updates and version bumps without shutting down the service.

22:00 SegFaultAX: And what a painful thing that could be. Especially before rebar.

22:00 hyPiRion: Oh yeah. Without rebar, stuff is amazingly painful. Though I still find it painful, mostly because I haven't mastered the arts yet.

22:01 ivaraasen: hyPiRion: this is the lib I was talking about earlier today: https://github.com/MichaelDrogalis/dire

22:01 seancorfield: anyways jack_rabbit welcome to clojure!

22:01 jack_rabbit: :)

22:01 I'm a CLisper, so I'm working my way into the purely-functional world from the mutable-mess world.

22:02 *purely*

22:02 seancorfield: ah, yes, I often forget traditional Lisp was impure in that respect...

22:02 SegFaultAX: ivaraasen: That's pretty cool.

22:02 jack_rabbit: seancorfield, You can write it functionally, but the opportunities not to are too present to avoid.

22:03 SegFaultAX: Well CL isn't really functional at all. I mean, sure you can write it that way, but lots of idiomatic CL is fairly imperative.

22:03 jack_rabbit: SegFaultAX, Exactly.

22:03 seancorfield: back in the 80's, when i first started doing FP, i used LispKit (Peter Henderson's subset of Lisp), Miranda and SASL... plus a little ML... and then developed my own FP lang as an academic research project

22:03 jack_rabbit: seancorfield, You're old.

22:03 SegFaultAX: Strange.

22:03 jack_rabbit: :)

22:03 * `arrdem remembers how young he is

22:03 SegFaultAX: You used all the precursors to Haskell but not Haskell?

22:04 seancorfield: "Lispkit Lisp is a lexically scoped, purely functional subset of Lisp" - wikipedia

22:04 SegFaultAX: I've used Haskell as well, but by the time it appeared, I was a professional C / C++ developer... :(

22:04 jack_rabbit: Haskell is pretty cool. I'm working my way through LYAH, as well as picking up clojure.

22:05 seancorfield: I went from the glory of pure FP to the horror that is C and the hell that is C++... then Java for a decade... then finally Groovy, Scala and now Clojure! Yay!

22:06 hyPiRion: ivaraasen: oh, the supervisors lib. Thanks a bunch

22:06 jack_rabbit: seancorfield, C is pretty cool. C++ isn't bad as long as you can avoid the extreme black-hole-like pitfalls.

22:07 seancorfield: I was on the C++ Standards Committee for eight years so I probably helped create some of those black holes... sorry! :)

22:07 hyPiRion: The issue is that you can't avoid those black holes, it seems like.

22:07 SegFaultAX: From my limited experience with C++ plus the horror storries my colleagues have shared with me over the years, I'm inclined to disagree.

22:07 cdh473: jack_rabbit++; pure FP makes me feel too limited, i need some side effects snuck in there

22:08 hyPiRion: I tend to say I use C with a data structure interface, because that's essentially what I do when I write C++.

22:09 jack_rabbit: In my mildly-experienced opinion, (just an opinion) you CAN avoid pitfalls in C++ if you are some sort of guru. But most programmers writing C++ apps are far from gurus, and C++ makes it really easy to shoot yourself in the foot.

22:09 SegFaultAX: hyPiRion: That's probably a pretty inefficient way to use C++. Why not just use C, then?

22:09 cdh473: hyPiRion++; i end up writing C in C++ whenever i try c++

22:09 jack_rabbit: I just write my own vtables...

22:10 ivaraasen: at least C++ isn't Matlab. just saying.

22:10 jack_rabbit: giant ugly dereferencing bedamned.

22:10 hyPiRion: SegFaultAX: Legit question, indeed. I tend to use it for programming competitions, where quick and dirty is what counts

22:10 SegFaultAX: hyPiRion: Ah, yea. That's basically the only time I ever use straight Java as well. TopCoder.

22:11 jack_rabbit: I've grown to hate programming competitions. Having a clock be the deciding factor in the "goodness" of a program seems completely bass-ackwards.

22:11 hyPiRion: SegFaultAX: yup

22:12 SegFaultAX: I worked on a team that built a cross-platform game engine targeting Android 2.3+ and iOS 5+. It was an interesting experience which probably colors my opinion of C++ a lot, especially since most of /my/ work on the project was on the cross-platform piece.

22:12 It was really, really challenging.

22:13 jack_rabbit: How well does C++ interface with Apple's Objective-C?

22:13 SegFaultAX: Most of the other engineers were on the graphics part of the engine. But me and one other guy worked on the device facing native parts.

22:14 jack_rabbit: C++ actually works pretty well on iOS from my experience. Of course we were doing something rather specific (game engine) so I can't really talk about the overall level of compat.

22:14 But for our purposes it actually was pretty smooth.

22:15 mattmoss: I don't understand why people hate C++. Used it for years just fine.

22:15 SegFaultAX: That's essentially the only time I've ever worked in C++ in a professional context. And if I had to choose, I mightn't ever return.

22:15 jack_rabbit: mattmoss, I agree.

22:16 SegFaultAX: mattmoss: In my case, I think it was more trying to build native wrappers for two relatively disparate platforms. I can't speak to the experience of others.

22:16 jack_rabbit: Granted, I think that maintainability is a big issue.

22:16 It seems to me that the older a chunk of C++ software gets, the more bugs develop in it, and the more slowly it incorporates new features.

22:17 tomoj: s/C++//

22:17 SegFaultAX: jack_rabbit: That's just software.

22:17 jack_rabbit: It seems to lack some of the abstraction necessary to build on an existing code-base.

22:17 SegFaultAX, True.

22:17 SegFaultAX: jack_rabbit: Bitrot is language agnostic.

22:17 `arrdem: how valuable do you guys think a Clojure implementation not backed by the JVM would be?

22:17 jack_rabbit: SegFaultAX, True, but some languages make it easier than others to avoid it.

22:17 SegFaultAX: `arrdem: You mean like backed by JS or the CLR?

22:17 jack_rabbit: And C++ seems particularly bad at avoiding it.

22:17 mattmoss: I'd say that poorly-written C++ is *really* bad, but well-written C++ is fine and dandy. I spent a few years doing one platform port after another will few issues (Aside from older experience as well).

22:18 `arrdem: SegFaultAX: sorta.. I've been kicking around this idea for an OS designed to do nothing but run clojure in some sort of micro-runtime.

22:18 where that runtime != jvm

22:18 SegFaultAX: Wee, lisp machines are coming back!

22:18 mattmoss: Let's put a lisp machine on a GPU, that'd be fun.

22:18 jack_rabbit: SegFaultAX, `arrdem, There are already a few OSes out there that are lisp-based.

22:18 `arrdem: that's bloody stupid and you know it

22:18 SegFaultAX: `arrdem: First I think you should build a game where you can do anything. ;)

22:19 `arrdem: SegFaultAX: Minecraft. done. next?

22:19 mattmoss: lol

22:19 jack_rabbit: Pfft.

22:19 `arrdem: that shit's turing complete man..

22:19 mattmoss: Clojure on redstone?

22:19 `arrdem: frikkin z80 in redstone.

22:19 mattmoss: no.

22:19 mattmoss: heh

22:19 jack_rabbit: Yeah, my brother built a 7-bit calculator with a decimal display.

22:20 ivaraasen: anyone care to recommend some decent C++ tutorials?

22:20 SegFaultAX: ivaraasen: C++ Primer!

22:20 ivaraasen: Also, bookmark this: http://en.cppreference.com/w/

22:20 `arrdem: ah that brick of a book...

22:20 mattmoss: I'm hesitant to start recommending tutorials at the moment until I see some good stuff for C++11.

22:20 jack_rabbit: Also cplusplus.com.

22:21 mattmoss: Then again, I haven't really been looking, spending most time lately with clojure. And lua (omg).

22:21 SegFaultAX: mattmoss: Probably take another year before the books start catching up.

22:21 mattmoss: SegFaultAX: Yup. Until then, there's Dylan! (wtf)

22:21 j/k

22:21 SegFaultAX: mattmoss: I love Lua! And I hate it. Lua's a great language. :)

22:22 Lua is*

22:22 jack_rabbit: It's interesting how fast C++ shifted towards Objective-C once Objective-C started rising in popularity.

22:22 ivaraasen: SegFaultAX: thanks

22:22 SegFaultAX: jack_rabbit: Huh?

22:22 mattmoss: SegFaultAX: I'm tempted more toward Squirrel over Lua, but don't use any of it enough right now.

22:22 jack_rabbit: SegFaultAX, All the new pointer types have been around in Objective-C since its invention.

22:23 ^new C++11 pointer types.

22:23 And a lot of the other features, IIRC, are already implemented in Objective-C.

22:23 SegFaultAX: mattmoss: We use Lua heavily in our game engine so I've worked with it quite extensively. Fun tidbit: I also looked at integrating gambit into our engine so I could use Lisp instead of Lua for scripting our engine!

22:23 jack_rabbit: yeah, gambit is pretty awesome.

22:24 SegFaultAX: Used* The company is now defunct.

22:24 jack_rabbit: I've actually read that you can compile gambit binaries to run on bare metal.

22:24 mattmoss: SegFaultAX: Haven't seen gambit. If I worked on another game engine, I might do Squirrel (lua-like), or some wild genetic mangling of functional and event driven.

22:25 SegFaultAX: Where were you at?

22:26 jack_rabbit: Regardless of the actual underlying dialect, I haven't found a language yet whose syntax I prefer to a Lisp.

22:26 SegFaultAX: mattmoss: PM'd

22:38 jack_rabbit: []

22:40 Well okay, but I don't think I typed that^

22:43 tjgillies: what do you guys use to encrypt passwords?

22:44 jack_rabbit: MD5

22:45 tjgillies: ....

22:45 i hope you're joking

22:45 jack_rabbit: :)

22:45 tjgillies: i used bcrypt in ruby land

22:45 but i don't see any bcrypt clojure stuff jumping out from google

22:46 egghead: tjgillies: we use http://www.mindrot.org/projects/jBCrypt/

22:46 xeqi: yep, jbcrypt

22:46 tjgillies: egghead: thnx

22:47 i love that clojure has such every interop with java

22:47 easy*

22:47 xeqi: also take a look at https://github.com/cemerick/friend if you're building a web app

22:48 egghead: ya, friend is great

22:49 tjgillies: ah i saw the friend talk at clojure west

22:49 looked pretty cool

22:54 SegFaultAX: I like friend in particular because in a lot of ways it's a pretty direct translation of warden.

22:55 And warden could not be more simple for what it does.

23:18 `arrdem: is there a good way for me to run tests via lein & nrepl?

23:18 google is looking pretty sparse on this matter.

23:18 jack_rabbit: What do you mean by tests?

23:19 `arrdem: if I define tests using core.test, I can invoke them via `lein tests` or such from zsh

23:19 I'd like to do so w/o leaving The One True Editor

23:19 jack_rabbit: hmm.

23:20 SegFaultAX: `arrdem: Check out Midje! https://github.com/marick/Midje

23:20 `arrdem: cheers Seg

23:21 jack_rabbit: (inc SegFaultAX)

23:21 lazybot: ⇒ 1

23:21 jack_rabbit: Oh, the novelty!

23:21 gtrak: anyone have an example of coordinating a version number between a dependency and a corresponding lein-plugin?

23:21 I'm just hard-coding it in a project middleware right now, feels wrong: (update-in project [:dependencies] conj '[nodisassemble "0.1.0-SNAPSHOT"])

23:24 can a lein plugin access its own version number? that would help a lot

23:24 SegFaultAX: gtrak: I like the name of that lib, by the way. Johny 5 would be proud.

23:24 gtrak: thank you :-)

23:25 SegFaultAX: Tiff-an-y.

23:25 gtrak: basically, I'm storing all the bytecode of classes in a map, then I can disassemble run-time eval'd classes

23:25 jeremyheiler: gtrak: I don't see why not. The plugin accepts the project map as its first argument.

23:25 gtrak: the plugin exists to turn on jvm instrumentation

23:25 hrm..

23:26 I guess the plugin would look itself up then

23:27 thm_prover: I have a string s, which contains xml. What is the correct way to parse s? (clojure.xml/parse s) appears to want a file rather than a string; and I'd prefer to not write out to a temporary file.

23:27 technomancy: https://lein-survey-2013.herokuapp.com/results <- posted a summary of the results to the Leiningen survey

23:27 thm_prover: it seems kind of stupid to go from memory to disk, only to go back to memory

23:27 technomancy: kind of interesting to me; not sure if it's interesting to others =)

23:27 gtrak: thm_prover: http://clojuredocs.org/clojure_core/clojure.core/xml-seq ?

23:27 st3fan: omg -> also accepts partials .. (-> {:a {:b 20}} :a :b (* 20))

23:27 andyfingerhut: thm_prover: Take a look at with-in-str

23:27 st3fan: i had no idea .. this will simplify my code so much

23:28 gtrak: st3fan: -> is syntax, not quite the same as partial-eval

23:28 jeremyheiler: thm_prover: You could use clojure.data.xml/parse-str

23:30 gtrak: thm_prover: clojure.xml/parse probably takes a stream

23:31 http://docs.oracle.com/javase/6/docs/api/java/io/ByteArrayInputStream.html is what you want, dunno if there's a shortcut somewhere

23:31 tomoj: &(clojure.xml/parse (java.io.StringBufferInputStream. "<foo></foo>"))

23:31 lazybot: ⇒ {:tag :foo, :attrs nil, :content nil}

23:32 tomoj: oh, that's deprecated

23:32 says you're supposed to use StringReader, but what if you need an InputStream?

23:32 gtrak: or StringReader is fine I guess

23:32 you can call clojure.java.io/input-stream on the reader if you like

23:33 tomoj: oic

23:34 doesn't appear to work

23:35 gtrak: huh

23:36 tomoj: &(-> "<foo></foo>" java.io.StringReader. org.xml.sax.InputSource. clojure.xml/parse)

23:36 lazybot: ⇒ {:tag :foo, :attrs nil, :content nil}

23:37 gtrak: maybe it goes the other way, stream to reader

23:37 thm_prover: gtrak: clojure.data.xml worked great, thanks!

23:37 tomoj: &(-> "<foo></foo>" .getBytes clojure.java.io/input-stream clojure.xml/parse)

23:37 lazybot: ⇒ {:tag :foo, :attrs nil, :content nil}

23:38 tomoj: I wonder if those are different?

23:38 thm_prover: tomoj: do you not have to close the new input-stream?

23:38 or are input-streams not file descriptors?

23:38 gtrak: yea... check out (def default-streams-impl {:make-reader (fn [x opts] (make-reader (make-input-stream x opts) opts)) ....

23:38 tomoj: well close is a noop on byte array input streams

23:39 jeremyheiler: technomancy: The summarized comments were interesting to read.

23:44 technomancy: jeremyheiler: cool; glad I'm not the only one who likes reading that kind of thing =)

23:45 jeremyheiler: technomancy: Also, some of the non-summarized comments are humorous :-P

23:45 technomancy: jeremyheiler: yeah, like the guy who wants me to visit the bay area clojure group, huh? =)

23:47 jeremyheiler: technomancy: haha yeah. and the guy that claims it sets his hair on fire.

23:47 `arrdem: lolwat

23:47 jack_rabbit: `arrdem, must be an old conversation.

23:48 andyfingerhut: It is mentioned in the first sentence at leiningen.org

23:50 jack_rabbit: Good to know, yogthos.

23:51 andyfingerhut: Inspired by the story "Leiningen versus the ants" http://www.classicshorts.com/stories/lvta.html (I still haven't read it despite being intrigued by the story idea a year or so ago -- now is a good time)

23:51 jeremyheiler: andyfingerhut: ooo, thanks for that link! Ive been meaning to check it out, but it always slips my mind.

Logging service provided by n01se.net