#clojure log - Dec 04 2012

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

0:25 basicsensei: hey guys, in eclipse+ccw how could I specify javadoc sources to leiningen dependencies(they are unmodifiable and I cannot add them manually) maybe something to add in project.clj ?

0:29 I'll try :classifier "sources"

2:14 replaca: Didn't someone just post a new tuorial on zippers? I thought it was on clojuredocs, but I don't see it there. Does anyone know what I'm talking about?

2:19 oh, it's on clojure-doc.org. confusing naming

2:19 Raynes: replaca: Yeah, Michael should write documentation on the names of the documentation websites.

2:19 Since is so gung-ho about documentation.

2:22 replaca: hah!

5:55 WokenFury: anyone run into java.lang.ClassNotFoundException: clojure.tools.logging.impl.LoggerFactory when using clojure.tools.logging?

5:56 pops up randomly on deployments and only a lein clean seems to fix it

5:56 can't reproduce it reliably either

6:03 Anderkent: Does anything other than dot (. Class member) treat classname symbols specially (i.e. Class != (do Class))?

6:03 (and who came up with that -.-)

6:08 clgv: WokenFury: I got that one when I did not have org.slf4j/slf4j-log4j12 as dependency

6:09 Anderkent: better use (Class/member) for static constants and methods and (.member obj) for non-static ones

6:11 WokenFury: clgv: how strange. I'm using logback tho. let me try

6:12 aha. datomic docs told me to exclude that from deps

6:12 Anderkent: clgv: I'm not writing code, I'm instrmenting code, don't have the luxury of choosing which form to use :)

6:13 clgv: WokenFury: I dont want to say it *is* the reason but I had the same behavior when I did not have that dep

6:14 Anderkent: well then a short comment: it is java interop there has to be some special form to enable it ;)

6:18 Anderkent: clgv: yes and I can handle the . special form, I was just wondering if any other form also did this stupid ClassName != (do (whatever) ClassName). try/catch could, I guess, it also handles class names

6:21 clgv: Anderkent: when you use a symbol it will be resolved to the class and you get a Class object. in the dot special form that needs to be omitted since you want to access a static member of the class whose symbol you used and not on the instance of the class "Class"

6:22 &(type Math)

6:22 lazybot: ⇒ java.lang.Class

6:22 Anderkent: clgv: that's exactly the annoying behaviour I am talking about, I'm aware of how that works, what I was asking is whether there are any *other* special forms than dot that do it

6:22 and yes seems (catch Exception) does the same

6:23 clgv: Anderkent: yeah. and deftype/defrecord constructors as well: (deftype MyType ....) (MyType. ...)

6:25 Anderkent: but you can detect special forms automatically via `special-symbol?`

6:25 Anderkent: yes, but not whether they do this or not

6:25 clgv: &(special-forms)

6:25 lazybot: java.lang.RuntimeException: Unable to resolve symbol: special-forms in this context

6:26 Anderkent: I want to recurse into special forms, but for some I have to handle their arguments specially

6:27 clgv: you will have to read their docs and try them out to be sure.

6:27 Anderkent: unfortunately many are not documented :)

6:27 clgv: what exactly do you do?

6:27 Anderkent: code coverage

6:27 clgv: of test? docs?

6:28 yediyedi: is there a standard or spec or something for making persistent models of boolean relations

6:28 Anderkent: pardon? Of arbitrary code, though I only run clojure.test tests currently

6:29 clgv: Anderkent: I meant what should cover the code ;)

6:30 Anderkent: I instrument the code by walking the source with statements that record whether a particular form was executed, run clojure.test and then collect the results

6:30 clgv: ah ok.

6:31 did you try loop-recurs yet? that might give you another dimension of problems ;)

6:32 fn-recur is the same...

6:32 Anderkent: no, they're fine, loop have the same syntax as let and recur I can wrap

6:32 clgv: no. I meant that you can't wrap code arround a recur since it has to be in tail position

6:32 Anderkent: I wrap it so that it stays in tail position

6:33 clgv: so you do not wrap the recur itself and also not transitively its surrounding forms?

6:34 do you use a look-ahead to detect a nested recur then?

6:35 Anderkent: do you have an elegant implementation for that that you are allowed to share?

6:36 Anderkent: I don't need to - all my wrappers put the original form at tail position so recur 'just works'. Think (recur (f1 arg1) (f1 arg2)) -> (do (capture <id>) (recur (do (capture <id2>) (f1 arg)) (do (capture <id3>) (f2 arg2))))

6:36 the recur is still in tail position

6:36 and I'll be open sourcing this eventually, but right now it's not ready yet

6:39 havent thought of protocols yet, that might be trickier

6:39 clgv: ah ok. I have the problem that I need to capture the return value - so I would need a look-ahead or avoid wrapping completely.

6:40 you mean capturing the protocol invocation for different types?

6:43 Anderkent: ah, defprotocol just does deftype* ? Then it might just work. But reify I'll have to handle like new/./catch I suppose

6:44 still undecided whether I should match these before or after macroexpansion.

6:44 clgv: yeah defprotocol is a deftype with several interfaces implemented

6:45 you could also hook into deftype before it is called (robert.hooke lib)

7:14 rkz: ddd#

7:34 tgoossens: In a board game. A robot has a position {:position[ x y]}. There is also a "board". I have move functions for robot position but they do not involve the board. Is it a good idea to make a "move-on-board" function that uses the move-robot functions?

7:34 for the record, a board must contain a collection of all the pieces that are on the board in some form (like a set or a map of position -> piece)

7:35 and if i move the robot forward this should also change in the board that contains the piece

7:36 or was it an initially bad idea to define position on the robot?

7:36 maybe those position keys in the robot map should be added by the board

7:36 so that a robot is defined indepentently of the type of board it is used on

7:39 Anderkent: having the board know where each robot is makes sense to me. The robot then can ask the board what's around it no matter what shape the board has

7:42 tgoossens: anderkent: do you suggest that a robot has a reference to its board?

7:42 *are you suggesting

7:43 Anderkent: ah, depends. Is a robot a piece controlled by something else, or an individual actor? If it's controlled by something else then it doesn't have to, but if it acts on its own it has to know what's around it

7:43 tgoossens: how i currently see it is

7:44 a client will ask the board what pieces are on each position

7:44 and then it must be able to say

7:44 that pieceX on position [a b] must be moved "forward"

7:44 currently i'm using no references, atoms or whatsoever

7:45 so

7:45 move-on-board

7:45 should return a new board to that client

7:46 i need to go now. But please if you were intending to answer / say something please type so that later i can read it :)

8:08 Anderkent: What's the point of doing (let [] <exprs>) ?

8:09 tomoj: tgoossens: why does a robot need to know its position?

8:09 clgv: Anderkent: I heard it is used to avoid locals-clearing which could happen in a (do <exprs>) - but that was a while ago

8:09 tomoj: my position is always (0,0,0)

8:10 clgv: Anderkent: you found it in some macroexpansion I guess ;)

8:19 cshell: What is the best way to flatten a nested map structure (graph)?

8:23 Anderkent: clgv: yeah, I'm looking at defrecords as it seems I'm not handling them right :P

8:23 cshell: does flatten do what you want?

8:24 ah, doesn't work on maps, just sequential colections

8:24 cshell: yeah, it's returning an empty sequence

8:24 thanks though :)

8:24 clgv: cshell: tree-seq might help you if you want a traversion

8:25 cshell: clgv: I'll give that a try, thanks!

8:25 clgv: but only if it is a tree (not a general graph)

8:25 cshell: so no cycles?

8:26 and everything connected to the root?

8:26 Anderkent: no backlinks

8:27 and only one route from root to any given node

8:27 clgv: cshell: no. you'd get an infinite sequence that might not visit all of your graph

8:28 cshell: ah okay

8:28 clgv: cshell: well if it is a general graph you now have to define what "flat" means

8:29 cshell: Yeah, I'm just trying to go through a nested map and extract all the keys

8:29 clgv: well you can do that with tree-seq

8:30 since your nested persistent map has leafs at some level

8:30 *leaves

8:32 cshell: so the branch? is just a check to see if there are any children?

8:33 clgv: branch? checks if there might be children. the other function returns them but it is allowed return an empty seq

8:37 vakosel: hi all, newcomer .. what is the best way to get familiar with the language ? resources, ide.. i googled but i 'd appreciate any opinion

8:38 cshell: vakosel: cemerick's Clojure Programming is a good book

8:38 clgv: vakosel: what's your background?

8:39 vakosel: as a programmer? or so? win32 c++, python , c# litlle java

8:39 clgv: in general: read a book and play with the exampoles and concepts presented in it...

8:39 vakosel: windows ok

8:39 ide?

8:39 clojurebot: (as an aside, 1 is a symbol designating the numeric value 1)

8:39 clgv: do you like ides like eclipse?

8:40 vakosel: i know it from pydev

8:40 sam7: I'd like to change parts of a string, driven by a simple pattern matcher. So far, I have the following, but it looks real inefficient as it goes from string to list and back. Any better ways? (apply str (map #(if (= %2 \-) %1 %2) old-str new-in-template))

8:40 vakosel: so eclipse witn counterclockwise is ok?

8:41 clgv: I use CCW for 2 years now

8:41 vakosel: excellent..i will do that

8:41 clgv: its development speed increased since laurent is sponsored for one day a week

8:42 sam7: clojure.string/replace

8:44 sam7: clgv: I looked at string/replace, but didn't see how to make it do what I want. If old-str is "12345" and new-str is "-B-D-", I want the function to return "1B3D5"

8:47 clgv: sam7: like that #(do (require 'clojure.string) (clojure.string/replace "12345" #"[24]" (fn [x] (case x "2" "B" "4" "D"))))

8:47 oops

8:47 &(require 'clojure.string)

8:47 lazybot: ⇒ nil

8:47 clgv: &(clojure.string/replace "12345" #"[24]" (fn [x] (case x "2" "B" "4" "D")))

8:47 lazybot: ⇒ "1B3D5"

8:48 clgv: sam7: if you replace everything you can also iterate over each character and use a stringbuilder to creat the new string incrementally

8:49 sam7: clgv: That's just a hardcoding of one case. I want each character in old-str to remain the same where new-in-template is "-", but to be replaced by the new char otherwise. (See my code above.... it's way more succint than I can write in prose)

8:50 clgv: sam7: the iterate over each character and build the enw string within a stringbuilder

8:51 sam7: clgv: Not 100% sure what you mean. Looking up stringbuilder now.

8:52 cshell: It's Java StringBuilder

8:54 sam7: cshell, clgv: I see. Ok, guess it's time for me to learn the interop stuff... unless one of you would be kind enough to write a code snippet for lazy me.

8:55 clgv: sam7: well you could also profile whether you really need that change. if it's no bottle neck you could use your time better ;)

8:56 the-kenny: ,(let [old "12345", new "-B-D-"] (reduce str (map #(if (= \- %2) %1 %2) old new)))

8:56 cshell: clgv: could he convert his string to a sequence of chars and then apply a map to the converted sequence and his transform rule?

8:56 clojurebot: "1B3D5"

8:56 sam7: That's exactly what I have now. (see above).

8:56 the-kenny: Whoops.

8:56 Didn't read that much backlog, sorry

8:56 sam7: (I'll be back in about 20 minutes; need to shuttle my kids around)

8:57 clgv: cshell: yeah, he is doing that like in the-kenny's snippet^^

8:58 cshell: if you need fast string construction on the jvm you'll end up with stringbuilder sooner or later

8:59 cshell: clgv: ah, gotcha thanks

9:05 cemerick: cshell: thanks for the mention :-)

9:07 cshell: cshell: np :)

9:08 cemerick: I'm trying to collapse the results of aether/dependency-hierarchy into a sequence - do you have any recommendations for how to do that?

9:11 sam7: (back)

9:12 cemerick: cshell: just the keys of the graph coming out of resolve-dependencies will give you a seq of dependencies

9:13 clgv: cshell: a dependency hierarchy is a DAG so you could use tree-seq on each "root"

9:13 but if there is a better api function use that one ;)

9:16 cshell: cemerick: I'm trying to get to it via leiningen.core/dependency-hierarchy - it's kicking back the DAG

9:17 clgv: I've been trying tree-seq but I can't figure out what the right inputs are - I'm using map? for the branch? param

9:18 clgv: cshell: if those are all maps `map?` is fine. as child function you probably have a keyword, e.g. :depends-on

9:22 gfredericks: so there's still not an easy way to specify CLJS-version with lein-cljsbuild?

9:23 the-kenny: gfredericks: Yes! Include it as a dependency

9:23 gfredericks: oh hm. so if I publish my own on clojars, will it recognize it given it would have a different group-name than org.clojure?

9:24 probably it will end up with both and they will have a maven-off to determine the winner?

9:24 the-kenny: Hm, maybe. But you could :exclude the original one, right?

9:24 gfredericks: that sounds plausible

9:25 cemerick: cshell: hum, ok; you'll have to walk it, then; might as well rip off the walk-deps fn from https://github.com/technomancy/leiningen/blob/master/src/leiningen/deps.clj

9:26 Anderkent: How can I update the version of reply lein is using? Do i just put a newer one on classpath?

9:28 the-kenny: :*

9:29 clgv: Anderkent: since leiningen is installed via a standalone jar I doubt that

9:29 Anderkent: sucks, because tab completion seems broken

9:29 oh well, guess I wait for next preview someday

9:31 cshell: cemerick: Awesome, that's perfect - thanks!

9:33 clgv: cshell: so these are no maps after all ;)

9:33 cshell: (tree-seq sequential? second deps) should work then

9:34 cshell: ah no. you want to visit the first entries... well then walk-deps is easier...

9:35 cshell: clgv: I'm still learning - but thanks for all your help:)

9:36 clgv: cshell: that's it (map first (tree-seq sequential? second deps))

9:37 cshell: clgv: where did you get deps from?

9:38 leiningen.core/resolve-dependencies?

9:38 clgv: cshell: that's your input. the same you would give to walk-deps

9:38 cshell: I just inferred it's structure from the code of `walk-deps`

9:39 cshell: ah, yeah it's dependency-hierarchy :)

9:43 Anderkent: nooooooooooooooooooooooooooooooo, dynamic classloader gets me again

9:43 and this time I have no idea how to fix it, geh.

9:47 .. Can I modify a clojure.core private variable somehow? (without using java reflection, that is)

9:49 mdeboard: that's probably not what you want to do

9:49 Anderkent: nevertheless

9:51 clgv: Anderkent: what happens with dynamic classloader?

9:52 Anderkent: clgv: currently I'm loading the ns to instrument, then instrumenting it, then evaling the instrumented form (thus redeffing everything in the namespace)

9:52 the problem is when a namespace declares some types, they will already exist and when redeffed clojure will create a new dynamic classloader that *should* capture all resolutions for that class name

9:53 however it seems that references to the class name within the instrumented code resolve to the *old* class, so things like instance? checks will fail

9:54 I could try to work around this by not loading the ns before instrumentation, but then I need to trick clojure into thinking this ns was already loaded (so it doesn't re-load it from file on any requires)

9:54 thus my question about private vars

10:04 clgv: Anderkent: you could just read the namespace file an instrument it and then compile it

10:05 Anderkent: reloading can be prevented as well, there is map or set that contains loaded namespaces and is used to decide whether to load a namespace or not

10:07 tgoossens: i have a function "place-on-board" which is used to place a piece on a board. if for example an invalid position is given. Should the function just return the original board? return nil? exception (yuk?) ?

10:07 just returning the board, then you don't know whether something went wrong

10:08 exceptions can be used to identicate a particular problem

10:08 nil just says "you screwed up"

10:10 ivaraasen: cshell: any luck solving your problem?

10:10 cshell: ivaraasen: I'm looking at the walk-deps function and trying to base my solution of that

10:10 nDuff: tgoossens: personally, I'd use slingshot's throw+ to pass back an exception that actually has context/data attached.

10:11 ivaraasen: cshell: any particular requirements? do you just want the keys?

10:11 cshell: ivaraasen: yes, just the keys

10:11 ivaraasen: all the way down

10:11 ivaraasen: cshell: gimme a sec

10:11 cshell: ivaraasen: awesome, thanks

10:14 ivaraasen: cshell: this might work https://www.refheap.com/paste/7283

10:16 cshell: ivaraasen: yes, I think that does it!

10:17 ivaraasen: thanks much!

10:18 ivaraasen: cshell: np

10:23 clgv: cshell: use mapcat instead of map+flatten

10:24 ivaraasen: clgv: good point

10:24 clgv: cshell: keepcat would be perfect but does not exists ;)

10:28 tgoossens: vector [1 2 2 1] how can i remove only 1 element that matches predicate : (remove-first 2 [1 2 2 1]) --> [1 2 1]

10:29 mdeboard: so (remove-first 2 [1 2 2 2 1]) would yield (remove-first 2 [1 2 2 1]) ?

10:29 er, would yield [1 2 2 ]

10:29 wow, nevermind, you know what I mean.

10:30 tgoossens: ok :p

10:30 just a function that removes the first element that matches the predicate and then stops

10:31 mdeboard: Well, doesn't stop, it continues iterating through the collection based on your example

10:33 tgoossens: yeah. but i need a function that only removes first occurence. If it doesn't exist already in core, i'll write it myself

10:33 just wondering :p

10:34 joegallo_: ,((fn [e s] (let [r (take-while #(not= e %) s)] (concat r (drop (inc (count r)) s)))) 1 [2 1 1 2 3])

10:34 clojurebot: (2 1 2 3)

10:34 mdeboard: ,(into #{} (filter #(= 2 %) [1 2 2 2 1]))

10:34 clojurebot: #{2}

10:34 joegallo_: can almost certainly be made cleaner

10:34 tgoossens: mm

10:35 hyPiRion: ,(let [[a b] (split-with (partial not= 2) [1 2 2 2 1])] (concat a (rest b)))

10:35 clojurebot: (1 2 2 1)

10:35 joegallo_: ooh, yes, i like that.

10:38 mdeboard: Man this channel will eat all your time if you let it, it's like a constant drip of brain teasers

10:38 tgoossens: thanks

10:38 mdeboard: i know

10:38 mdeboard: e.g. tgoossens's question :P

10:38 tgoossens: i really should start studying now :p

10:39 hyPiRion: mdeboard: It's scary, yes.

10:39 DrPheltRight: It's interesting even for those who don't speak much if at all

10:39 tgoossens: :D

10:42 borkdude: tgoossens hehe…

10:42 tgoossens: borkdude: 4real :p

11:12 jweiss: ,(let [templ (partial partial format)] ((templ "foo %s %s") "baz" "quux"))

11:12 clojurebot: "foo baz quux"

11:13 jweiss: something seems weird to me about (partial partial format) but seems the most succinct way to write it.

11:15 hyPiRion: Uh, wouldn't just (partial format "foo %s %s") be just as good?

11:17 clgv: (let [templ #(apply format %&)] ((templ "foo %s %s") "baz" "quux"))

11:17 ,(let [templ #(apply format %&)] ((templ "foo %s %s") "baz" "quux"))

11:17 clojurebot: #<MissingFormatArgumentException java.util.MissingFormatArgumentException: Format specifier 's'>

11:18 clgv: ah forget that ^^

11:59 borkdude: if I want a VPS, what is a recommended minimum amount of memory for basic JVM apps (so, what does it take to boot Arch linux for example and run the JVM)

11:59 mdeboard: jvm for what?

11:59 borkdude: clojure

12:00 mdeboard: Depends what your Clojure program does

12:01 I'm not being obtuse/difficult btw

12:02 borkdude: mdeboard I know. but would for example 256 MB suffice to host a tictactoe game (theoretical example) ;)

12:02 mdeboard: Sure

12:03 ucb: anybody going to the skillsmatter meet up tonight?

12:18 borkdude: btw how do people host a leiningen/compojure app on a linux server, just start lein run&?

12:26 technomancy_: borkdude: lein trampoline run or uberjar from inside an upstart job is probably the simplest

12:27 borkdude: technomancy_ tnx

12:27 technomancy_ trampoline isn't yet default behavior?

12:28 technomancy_ upstart is ubuntu specific?

12:30 S11001001: borkdude: correctness over speed.

12:30 borkdude: S11001001 what do you mean?

12:31 S11001001: borkdude: that safety by default, rather than speed by default, is good general practice

12:32 borkdude: you have too many variables to eliminate already when debugging without worrying about whether some unnecessary optimization is screwing you up

12:33 borkdude: S11001001 ok I see

13:15 ohpauleez: For all Vim users: https://github.com/tpope/vim-foreplay

13:15 Tim Pope's nREPL env for vim works nicely

13:15 paredit + VimClojure + Foreplay is working well for me

13:24 technomancy_: huh; why does it still need vimclojure if it's using nrepl?

13:25 thmzlt: syntax highlighting/indenting?

13:25 technomancy_: oh, I see

13:28 thmzlt: I haven't tried it myself, I use emacs for lisp stuff and vim for the rest

13:29 ohpauleez: thmzlt: I was in the exact same camp until Clojure - Vim support is pretty nice

13:32 pbostrom: I want to build a simple RPC handler where I send a message to the handler which then reads the message and dispatches the specified function. I can think of three ways to implement this: 1) Send a symbol to the handler, which then resolves the symbol in some predefined namespace 2) Send a keyword to the handler, which then does a lookup in some predefined map of functions 3) Send a keyword, but pass it to some predefined multimetho

13:32 Any thoughts on the best approach? I prefer 2 (map of functions) but wanted to solicit other opinions.

13:33 technomancy_: pbostrom: a multimethod *is* a map of functions

13:33 pbostrom: yeah, but it's a lot more typing

13:33 they are essentially the same though?

13:34 technomancy_: well a multimethod can dispatch on an arbitrary function rather than just a key, but apart from that yeah

13:38 thmzlt: ohpauleez: after playing with it for 10min, my impression is that it doesn't feel right :)

13:38 ohpauleez: thmzlt: Fwiw, I have a repl instance running in the footer panel of a tmux window

13:39 so I'm in vim, banging on cpp and c!!

13:39 then toggle over to the repl to poke at stuff

13:39 or just have a scratch file

13:40 but it supports all the things I need: omnicomplete, multiple nrepl, goto file, source, evaling, and the repl tools (docs, apropos, etc)

13:40 plus, redefine (working correctly)

13:42 mpenet: pbostrom: also a multimethod is extendable at runtime, a map not so much, unless you wrap it in a atom

13:44 thmzlt: ohpauleez: I guess I can get used to it. I just didn't like the editing part, but it feels pretty solid

13:44 plus I am spoiled by emacs-live

13:45 ohpauleez: thmzlt: emacs-live is pretty solid. paredit.vim, surround.vim, and VimClojure are the bare-minimum for me.

13:48 andrewmcveigh: ohpauleez: Is there a trick for getting it to work? I'm getting classpath errors.

13:49 ohpauleez: andrewclegg: No, but I have found one bug I don't know how to fix (regarding it shutting down and exiting cleanly)

13:49 andrewmcveigh: ^

13:49 I have started up on a lein2 project from a cold start

13:50 and I've done it for a lein2 project that I had a running repl isntance for

13:50 both worked just fine for me

13:50 andrewmcveigh: hmm, I think it's trying to fall back to "java clojure.main"

13:50 ohpauleez: ahh

13:51 pbostrom: thanks technomancy_ and mpenet, I've tried it both ways, I think it's more obvious what's going on with the multimethod, and easier to extend like you said, I wasn't sure if maybe a mulimethod was overkill, I also felt weird disregarding the first argument in every defmethod for some reason

13:51 ohpauleez: Yeah, Tim put a note in the README that he's in way over his head (which is hard to believe)

13:52 andrewmcveigh: I'll give it an hour to try getting it working... got real work to do :-)

13:52 mattmoss: &(mapcat (fn [a] (map (fn [b] [a b]) [1 2 3 4 5])) [:a :b :c :d :e]))

13:52 lazybot: ⇒ ([:a 1] [:a 2] [:a 3] [:a 4] [:a 5] [:b 1] [:b 2] [:b 3] [:b 4] [:b 5] [:c 1] [:c 2] [:c 3] [:c 4] [:c 5] [:d 1] [:d 2] [:d 3] [:d 4] [:d 5] [:e 1] [:e 2] [:e 3] [:e 4] [:e 5])

13:52 mattmoss: Anyone know of lib fn that does that?

13:53 amalloy: wat. just use 'for

13:53 mattmoss: oh, duh. *smack self*

13:53 amalloy: &(for [a [:a :b :c :d :e] b [1 2 3 4 5]] [a b])

13:53 lazybot: ⇒ ([:a 1] [:a 2] [:a 3] [:a 4] [:a 5] [:b 1] [:b 2] [:b 3] [:b 4] [:b 5] [:c 1] [:c 2] [:c 3] [:c 4] [:c 5] [:d 1] [:d 2] [:d 3] [:d 4] [:d 5] [:e 1] [:e 2] [:e 3] [:e 4] [:e 5])

13:54 mattmoss: thanks

13:54 brain dead today, i am

13:58 negev: whats wrong with this? (fn mult [x y] x * y)

13:58 borkdude: negev infix vs prefix notation

13:58 negev this ain't no Haskell

13:58 negev (fn mult [x y] (* x y))

13:58 negev: well im reading a book called the joy of clojure

13:59 ahh i see

13:59 so why when i try to do this on the next line: (println "The result of 9 x 9 is " (mult 9 9))

14:00 does it say it can't find mult in the current context

14:00 S11001001: negev: fn is pure

14:00 negev: it doesn't bind a variable or have any side effect whatsoever

14:00 negev: did i want def?

14:00 S11001001: negev: yep.

14:00 * josteink has written his first leiningen plugin :)

14:00 negev: ok, so what does fn do ?

14:00 josteink: for those interested: https://github.com/josteink/lein-drip

14:00 andrewmcveigh: ohpauleez: this "target/repl-port" is just a file with a number in right?

14:00 S11001001: negev: there are *lots*, *lots* of times when you *just* want to make a function.

14:01 josteink: negev: syntax to create a lambda

14:01 without binding it to a variable name

14:01 negev: ah i see

14:01 so you use the fn block in the def

14:01 josteink: what would be a first step if I want to move my lein-pluging from githib to clojars? :)

14:01 negev: i get it now

14:02 josteink: negev: can also be used in a map

14:02 (map (fn [x] (+ 1 x)) numbers)

14:02 tpope: andrewmcveigh: I tried to make the classpath stuff (and everything, really) completely transparent. don't be shy about opening a bug if it doesn't work out of the box

14:03 andrewmcveigh: tpope: Trying to work out if it's my vim. I'm getting back "nREPL: {}" at the moment.

14:04 tpope: that's a catch all error, shouldn't happen :/

14:04 technomancy_: tpope: fwiw calculating the classpath only hits the network if you have snapshots

14:04 tpope: ah

14:06 technomancy_: and even that's only once every 24h

14:06 tpope: is there a way to opt out? feels like something that I shouldn't be kicking off behind the scenes

14:07 technomancy_: tpope: you can do `lein -o classpath` or `lein -o repl`

14:07 which is kind of cheating; "-o" is actually the name of a higher-order task that activates the :offline profile

14:07 tpope: awesome. is that safe on older versions of lein?

14:08 technomancy_: at a guess I'd say around preview5

14:08 amalloy: wouldn't -o mean he also doesn't hit the network to resolve new dependencies he doesn't know about yet?

14:08 basicsensei: hey guys, how can I execute this with java code ? (set! *warn-on-reflection* true)

14:08 technomancy_: true; it's not good for general use

14:08 tpope: well then I'll probably shy away from it

14:08 technomancy_: there's a way to disable it for snapshot updating only, but there's not a good CLI shorthand for it

14:09 tpope: andrewmcveigh: is that error happening on any command?

14:10 if foreplay.vim doesn't understand the response from nREPL, it throws basically a vim representation of the decoded bencode packet it received

14:10 andrewmcveigh: tpope: Yeah, I get the feeling that there's no communication. Not sure if that's possible. Just putting in some echo lines to see if I can work out where it's coming frome.

14:12 tpope: I saw it a few times when authoring the plugin, but it was always when I was doing something wrong else where

14:12 like sending a blank string as code to eval

14:12 technomancy_: there's an example of printing middleware in sample.project.clj that might be helpful for debugging

14:13 basicsensei: is it freaking this? clojure.lang.Var.intern(clojure.lang.RT.CLOJURE_NS, Symbol.intern("*warn-on-reflection*"), clojure.lang.RT.T, true);

14:13 tpope: thanks, I may have a look later

14:13 I need to get back to my day job, but please hit me up later andrewmcveigh if it's still an issue

14:14 cemerick: tpope: foreplay looks great. Ping me if you need any help w.r.t. nREPL, etc.

14:14 tpope: cemerick: I *might* with andrewmcveigh's error :). we'll see

14:16 andrewmcveigh: tpope: I'll probably leave it until tomorrow, if I don't get anywhere with it shortly.

14:16 cemerick: tpope: I haven't been following. :-) But, sure.

14:16 tpope: nothing worth following yet

14:18 basicsensei: that seems to have been it

14:20 ohpauleez: tpope: Is there a shorthand to shut off foreplay in vimrc?

14:21 I'm digging through the plugin stuff now (more than happy to add it in, if it's not there). Sometimes I just want to make a quick edit to project.clj (and I don't want want the whole environment up)

14:21 cemerick: tpope: FWIW, nearly all of the clojure tooling leads are on http://groups.google.com/group/clojure-tools

14:38 tpope: cemerick: well now so am I

14:39 ohpauleez: please open a github issue, can't get into it right now

14:39 ohpauleez: tpope: Will do, thanks!

14:40 andrewmcveigh: tpope: I think I've tracked down the problem.

14:43 tpope: andrewmcveigh: brilliant

14:45 andrewmcveigh: tpope: It's because my code is in maven layout "src/main/clojure" but I switched to lein2. So my namespaces are getting detected as "main.clojure.my-ns".

14:45 borkdude: well, I hosted a noir app on a vps.. http://vps794.directvps.nl:8080/ -- but no idea what's going wrong… normally I see some kind of exception

14:45 tpope: andrewmcveigh: does lein classpath report the right thing?

14:47 andrewmcveigh: tpope: OK, sorted it.

14:48 tpope: I have too many :source-paths in project.clj

14:49 tpope: so foreplay.vim was seeing "src" in the classpath and presuming that my namespace was "main.clojure.my-ns"

14:49 tpope: I guess that could be a "user error"?

14:52 tpope: andrewmcveigh: yep. which doesn't excuse a worthless error message

14:52 andrewmcveigh: could you make an issue so I can handle it better in the future?

14:55 andrewmcveigh: tpope: Sure. Will do.

15:00 cpetzold: anyone know if udp multicasting is possible with aleph?

15:02 borkdude: any chance of getting more info from noir on why this goes wrong? http://vps794.directvps.nl:8080/

15:03 it doesn't run locally either as uberjar, it runs with lein run though

15:03 well it runs, but same noir error page

15:03 with lein run it works well

15:07 technomancy: borkdude: noir isn't very transparent with its routing unfortunately

15:07 compared to compojure

15:08 andrewmcveigh: tpope: Made an issue, if you need more, let me know - I found that kinda weird to write.

15:11 borkdude: I read somewhere that requiring the views could help, but when trying that I get a file not found… appname/views/common.clj argh

15:11 kzar: Haven't played with Clojure for a while, is noir still the main web framework?

15:12 gfredericks: every time somebody asks that question 80% of the responses are "just use compojure"

15:12 or "use libraries, not frameworks"

15:12 borkdude: oh I'm sorry, I typed commmon....

15:13 tpope: andrewmcveigh: makes perfect sense. I assumed (require 'clojure.main.my-ns) would blow up if clojure.main.my-ns wasn't defined

15:14 andrewmcveigh: tpope: Yeah, spot on.

15:14 technomancy: borkdude: noir's approach of having loading the view namespaces alter an atom results in weird situations that are hard to debug when they go wrong

15:15 tpope: and that's how nrepl responds if you try to eval in a non-existant ns

15:17 andrewmcveigh: yeah, not really used nrepl much, other than on the side of vimclojure.

15:21 stuartsierra: cemerick: ping

15:21 borkdude: technomancy ok

15:25 cemerick: stuartsierra: hi :-)

15:26 borkdude: yeah, app works now

15:26 all memory is in use though, so very slow :)

15:31 stuartsierra: cemerick: Hi. I think I found a bug in Friend.

15:32 cemerick: Just one?

15:32 stuartsierra: :)

15:32 cemerick: That's the mandatory response, of course.

15:32 borkdude: I found a friend in bugs.

15:32 stuartsierra: Using http-basic auth, if the request doesn't include any authentication headers, you always get a redirect to "/login", not a 403.

15:33 If some anonymous requests are allowed.

15:33 cemerick: stuartsierra: I think Craig reported that already?

15:34 stuartsierra: heh, maybe he did. Didn't see a matching issue on GitHub,

15:34 cemerick: stuartsierra: oh, I'm thinking of https://github.com/cemerick/friend/issues/28

15:34 stuartsierra: Yeah, different issue.

15:38 This is just that it tries to redirect instead of returning 403.

15:38 cemerick: stuartsierra: not so much an issue with the http basic workflow; more that there's no parameterization available to override `redirect-unauthorized`

15:38 stuartsierra: I think I have a fix, not sure if it's correct.

15:39 By returning an empty auth map from `http-basic` with the metadata `::friend/redirect-on-auth? false`

15:40 cemerick: heh, no, you don't really want to do that :-)

15:40 stuartsierra: ok

15:41 cemerick: The real fix is to add a new kwarg to friend/authenticate* that will be used instead of (the really badly-named `redirect-unauthorized`)

15:41 Which should be called unauthenticated-handler or somesuch.

15:44 That will allow you to specify what response should be sent in any unauthenticated circumstance. Reasonable prefab options would be one handler that redirects to a :login-uri (the current behaviour), another that sends a 403.

15:44 stuartsierra: OK. Would that still allow anonymous requests on routes that don't require auth?

15:45 cemerick: Yes. There are only two circumstances where that handler is (and would be) invoked:

15:45 (a) when no credentials are provided, and :allow-anon? false

15:46 (b) when credentials are provided, but an authorization error is tossed

15:46 s/when/when no

15:46 Does that sound right?

15:47 stuartsierra: I think I have a third case: no credentials are provided, `:allow-anon?` is true, AND an authorization error is tossed.

15:48 cemerick: Isn't that (b)?

15:49 stuartsierra: Oh, sorry, didn't see your s///

15:49 Yes, that is (b).

15:49 cemerick: If credentials *are* provided, and an authorization error is tossed, then that's already parameterizable via :unauthorized-handler

15:50 (thus why the `redirect-unauthorized` handler's name is so gawd-awful)

15:54 stuartsierra: cemerick: OK. Tracking this at https://github.com/cemerick/friend/issues/38 . If I have time to look more into it later this week, I'll send a patch.

15:55 cemerick: stuartsierra: Sounds good, I've added a couple of notes to that.

15:55 stuartsierra: cemerick: Thanks. Talk to you later.

16:01 Raynes: devn: You endorsed me in Python and Ruby on Rails on linkedin? O.o

16:02 ucb: cemerick: you seem to be active on the couchdb/clojure front; do you think it'd make sense to have a ref system on top of couchdb?

16:02 devn: Raynes: You endorsed me so when I went to your profile it had a few things listed and said: "Do you endorse this person"

16:02 speaking of which

16:02 Raynes: Haha. Python *maybe*, but I've done precisely no RoR.

16:03 devn: there is nothing weirder than: "Does Rich Hickey know about Clojure?"

16:03 Raynes: lol

16:03 Hodapp: devn: that is classic

16:03 amalloy: didn't someone ask recently "who understands persistent data structures?" and have only SPJ raise his hand?

16:03 devn: oh wait, it's better

16:04 "Does Rich Hickey know about Java?"

16:04 *facepalm*

16:04 Raynes: amalloy: I highly doubt it was *only* SPJ.

16:04 dnolen was there.

16:04 amalloy: Raynes: i may have misread https://twitter.com/samaaron/status/275930177714937857

16:05 Raynes: Yeah, it sounds like that's what he is saying, but I have trouble believing it is all.

16:05 Unless dnolen wasn't in the room it *had* to be at least two.

16:05 devn: man, some of these endorsements... I need to prune my linkedin tree.

16:05 "Does [NAME REDACTED] know about Servers?"

16:06 No, but they know about Vague...

16:06 cemerick: Questions like that are purely rhetorical.

16:06 devn: haha

16:06 cemerick: or, that's how I treat them, anyway

16:06 devn: Bo knows Clojure. Bo knows Java.

16:06 cemerick: *unless* there's a free hammock up for grabs :-P

16:07 devn: haha

16:07 technomancy: linkedin is purely rhetorical

16:07 devn: oh man, so... speaking of linkedin, quick story...

16:07 I know this guy I went to high school with

16:08 cemerick: stuartsierra was like, "oh c'mon, anyone else besides cemerick?!"

16:08 devn: His mom wrote a recommendation for him because she runs a business

16:08 and she wrote something like "Timmy will be sorely missed."

16:08 so embarassing...

16:09 almost as embarrassing as spelling embarrassing wrong

16:10 "Does [REDACTED] CISM, PMP, MSPM, GCIH know about Cross-functional Team Leadership?"

16:11 * devn pukes blood

16:11 Hodapp: what are all those acronyms?

16:11 devn: dude...no one knows

16:11 that's the beauty of them

16:12 Hodapp: I made a buzzphrase generator. Let's see what it has to say.

16:12 cemerick: devn: If you see any of those, run, run far away.

16:13 Hodapp: Unified Digital Programming From the Platform of Internet Projection By Opening the Doors of Systematized Transitional E-Business Concept Through the Power of Guaranteed Statistical Software: Collaboratively Agile Third-Generation Consolidation

16:13 devn: "empower viral ROI"

16:13 "implement granular supply-chains"

16:13 etc.

16:13 Hodapp: Revising Platform: Conservatively Revolutionary Client Economic Synergy . . . wow, that's some cognitive dissonance

16:13 devn: this challenges me to revise my buzzword generator.

16:14 devn: Hodapp: haha -- i use a gem call faker now and then when i need double-talk

16:14 http://faker.rubyforge.org/rdoc/classes/Faker/Company.src/M000024.html

16:14 it has a nice list

16:18 zerokarmaleft: i was about to say leverage wasn't on the list, but it is

16:18 devn: brb i need to productize transparent partnerships

16:19 just something i do before i revolutionize 24/7 e-business

16:20 reminds me of: http://projects.haykranen.nl/java/

16:20 IdentifierPrinterServerConfigurationProducerStrategyFacadeTag

16:21 ProducerExceptionThreadExporterServiceAutowirePrinter

16:21 etc.

16:22 mattmoss: brain asplode

16:22 buzzwords make me ill

16:26 mudge: looking for a definition of reference type, what is a reference type?

16:26 bbloom: mudge: depends on the context

16:27 mudge: bbloom: well how can I understand what a reference type is?

16:27 devn: mudge: mudge perhaps this helps? http://clojure.org/atoms

16:27 bbloom: devn: eh probably too much too fast :-)

16:28 mudge: in the context of java, there are two categories of types

16:28 devn: /perhaps/ :)

16:28 bbloom: reference types and primitive types

16:28 in a C# or .net context, there are also value types

16:28 a reference type is transferred by aliasing: you copy a pointer

16:29 a value type is transferred by copying

16:29 devn: mudge: what got you looking for a definition? is there a blog post or some documentation you're reading?

16:29 bbloom: all primitives in java are value types

16:29 their VALUES are copied to make new variables that point to them

16:30 for a reference type, a REFERENCE to the object is copied to make new variables that point to them

16:31 but in the clojure context, it's a bit different...

16:31 mudge: blloom: i see, and it is the same idea in clojure? So reference type is a pointer to a value

16:31 bbloom: I understand references in Java

16:32 devn: I'm reading the Clojure Programming book

16:32 bbloom: ok so in clojure, there are "reference types" in the sense that there is a distinction between values and identities

16:32 mudge: okay

16:33 bbloom: the idea of a "value" extends to things that you pass around by reference…. a value is somethign that is immutable

16:33 it doesn't change

16:33 an "identity" refers to some value at some point in time

16:33 for an email address, for example, is an identity

16:34 or better yet, a physical address

16:34 you can say "who lives at this street address now?"

16:34 devn: ,(def fred (atom {:name "fred", :address "sycamore street"}))

16:34 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

16:34 bbloom: so a reference type in the clojure sense is an object that encapsulates an identity and a value as state

16:35 I recommend watching http://www.infoq.com/presentations/Simple-Made-Easy

16:35 devn: (let [fred (atom {:name "fred", :address "sycamore street"})] @fred)

16:35 ,(let [fred (atom {:name "fred", :address "sycamore street"})] @fred)

16:35 clojurebot: {:name "fred", :address "sycamore street"}

16:35 bbloom: actually

16:35 devn: ,(let [fred (atom {:name "fred", :address "sycamore street"})] (deref fred)) ;; @ aka deref

16:35 clojurebot: {:name "fred", :address "sycamore street"}

16:35 bbloom: mudge: watch this one first http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey

16:36 Raynes: devn: I don't like fred.

16:36 devn: heh

16:36 bbloom: what about "Are we there yet?"

16:36 mudge: bbloom: thanks, I get it

16:36 bbloom: sure that one too i guess

16:36 i forget which one has the good overview of the speed walker and the photo finish and what not

16:37 devn: bbloom: the second video you posted is good

16:37 i believe that's the one

16:38 crease: there's no reason to run lein clean before lein deps, right?

16:39 devn: crease: i used to do it semi-religiously, but i dont believe so, no

16:40 crease: devn: thanks, yeah, same… I'm trying to wean myself off unnecessary debug rituals

16:41 devn: crease: the only place i would maybe still use it, and again it might be ceremony, but i just dont know the answer is: between lein 1.7 and 2.0

16:41 if you had a lein 1.X project and are now using 2, maybe it makes sense to use it there?

16:42 crease: devn: yeah, during the transition I suppose it makes sense to throw every harmless hygeine-related tool at your project

16:47 shoutout for lein-pedantic, by the way. saved my butt

16:48 devn: yeah, it's really handy

16:51 frenchy64/analyze + Datomic/codeq = ???

16:51 lazybot: devn: How could that be wrong?

16:51 devn: thank you lazybot

16:54 lazybot: You're does not exist in my database.

16:55 * Raynes feeds lazybot richicken noodle soup.

16:55 tomoj: interesting that clojure.core.reducers/flatten only checks for sequential?, and doesn't check for CollReduce

17:03 black_joe: I still don't fully understand how to link namespaces together.

17:03 I have one file that is (use)ing another, but that isn't enough for functions to be recognized.

17:04 And when I tried lein uberjar, it deleted the entire project. So I had to backup from git.

17:04 mthvedt: black_joe: you need to pass the --dont-delete-everything command line switch

17:04 black_joe: So what more does it take to be able to use one namespace within another?

17:05 technomancy: crease: there are a few cases it can be needed for snapshots with native deps

17:05 clojurebot: lein clean?

17:05 clojurebot: lein is http://github.com/technomancy/leiningen

17:05 technomancy: hrm

17:05 lein clean most of the time is the equivalent of taking out the NES cartridge and blowing on it

17:08 crease: technomancy: hm… what are those snapshot edge cases?

17:09 technomancy: crease: if you pull in a new snapshot version and the native dependencies have changed, I don't know if it will clear it out necessarily

17:09 s/clear it out/unpack the latest version/

17:10 crease: technomancy: ah, okay… I'll remember that, thanks

17:12 black_joe: that's weird, what's your ns form?

17:13 black_joe: crease: Actually, I found the problem. It was a Java-ism that Clojure websites / books hadn't explained.

17:13 crease: black_joe: oh, what was the Java-ism?

17:13 black_joe: Having to put code into a src directory, rather than having it thrown into x place like C.

17:21 tgoossens: I'm really having a hard time when not intrudocing any "refs" in my board game. not sure whether it is because i'm more familiar with OO or whether it is just a sign that in fact i should use identity

17:22 ohpauleez: tgoossens: What game are you making? Can you pass the transformations of the board along?

17:22 tgoossens: i'll throw it in a gist :)

17:28 ohpauleez:https://gist.github.com/4209494

17:28 ohpauleez: some explanation is at the bottom file

17:31 Raynes: https://www.refheap.com/paste/7285 without the 50 space indentation.

17:31 tgoossens: What are you using to write the code?

17:32 solussd: is there a way to represent "now" with an #inst reader dispatch?

17:33 (just curious)

17:34 technomancy: I think that kind of goes against the point of reader literals

17:35 they're meant to represent values, and "the current time" is a reference, not a value

17:36 tgoossens: raynes: i'm using sublime text 2 . why?

17:36 Raynes: tgoossens: Set your indentation to 2. :p

17:36 tgoossens: its on 4 aparently

17:37 changed it :p

17:37 Raynes: <3

17:37 technomancy: ouch

17:37 Foxboron: tgoossens, might wanna have tabs to space, and set idention to 2 :P

17:37 indention*

17:38 tomoj: technomancy: how about #db/id[:db.part/user] ?

17:38 cemerick: ,#=(java.util.Date.)

17:38 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

17:38 cemerick: oh well

17:39 technomancy: tomoj: I don't know what that means

17:39 cemerick: solussd: ^^ is the closest you'll get to a readable representation of "now"

17:39 but, don't use that :-P

17:39 tgoossens: lol its funny how you criticise my indentation but do you also maybe have some tips on what might be some better ways (maybe using identity?) ^^?

17:40 technomancy: the idea of the reader always returning values is violated by j.u.Date anyway, but I think that's a known design bug =(

17:41 solussd: cemerick: ha. I thought the first rule of #= club is not to talk about #= club

17:41 or, is that "ok" w/ data?

17:42 * cemerick wrote the rules

17:42 cemerick: ;-0

17:42 ;-)

17:42 solussd: and the second rule?

17:42 cemerick: heh, no, putting any #= into something intended to be data-ish is nutty

17:44 tgoossens: i'm confused now. When do you use "2 spaces" and when "one space"?

17:45 the-kenny: Just use Emacs' default.

17:45 solussd: one space when putting the first argument to the function on a new line. :)

17:45 tgoossens: solussd: thanks :D

17:45 technomancy: if you have to think about indentation at all you've already lost =(

17:46 (unless you're the one implementing editor support)

17:46 cemerick: one space indents in clojure? yak

17:46 solussd: this is also true- emacs indenting works great for me

17:46 the-kenny: cemerick: I think it's about aligning [a \n b]

17:47 solussd: I prefer putting arguments to cond and case on a new line- emacs uses a single indent in that case

17:47 the-kenny: so b is directly under a and not under [

17:47 cemerick: oh, ok

17:47 whew

17:57 tgoossens: i think i'm just going to try using identity

17:57 and see how that works out

17:58 it might be quite useful for a game perhaps

18:01 solussd: clojure needs a conj-if e.g. (conj-if expr coll new-item) that returns the original collection if expr is falsey

18:03 jweiss: i'm looking for a suggestion for when you have 2 dimensions of namespaces, seems like no matter how you lay them out, one dimension gets repeated over and over. is putting the dimension with the most # of namespaces as the directories, and repeating the smaller dimension in each directory, the best I can do?

18:07 ChongLi: solussd: (defmacro conj-if [expr coll new-item]

18:07 `(if ~expr (conj ~coll ~new-item) ~coll))

18:08 solussd: ChongLi: yeah.. I wrote it too. :) actually, mine takes any number of [expr new-item] pairs so you can conditionally build up a collection

18:08 bbloom: sorella: ChongLi: clojure 1.5 has a more general form

18:08 sorella: bbloom, ?

18:08 ChongLi: solussd: ah

18:09 bbloom: ,(clojure-version)

18:09 clojurebot: "1.4.0-master-SNAPSHOT"

18:09 bbloom: &(clojure-version)

18:09 lazybot: ⇒ "1.4.0"

18:09 bbloom: hm ok those are 1.4 still :-)

18:09 1.5 will have cond-> (maybe called something else)

18:10 (cond-> x (test y) (conj z))

18:10 and cond->>

18:12 solussd: bbloom: neat

18:12 bbloom: solussd: https://github.com/clojure/clojure/blob/372f03e2fa63ff7c3544be82d85e8943e85e640b/src/clj/clojure/core.clj#L6728-6754

18:13 in case you want to use them now

18:14 solussd: i do, and i will!

18:18 seangrove: Ah, seems you can't destructure funargs in cljs with string keys if a js object is passed in

18:18 Bummer

18:20 brehaut: never underestimate the power of javascript to cause you sadness

18:20 Foxboron: brehaut,

18:21 dude

18:21 Never underestimate the power of ActionScript3 to cause you deep eternal sorrow.

18:21 bbloom: seangrove: you mean via :strs ?

18:21 brehaut: Foxboron: a proprietary fork of javascript is woeful you say? i never would have guessed!

18:22 seangrove: bbloom: Didn't know :strs, was using :keys

18:22 Will try it again once I fix the function

18:22 bbloom: seangrove: yeah, there is also :strs and :syms

18:23 seangrove: Will that work though if a plain js-obj is passed in?

18:23 Basically doing a (.-property arg) lookup

18:23 bbloom: seangrove: no.

18:23 ILookup isn't defined on js objects

18:23 seangrove: Yeah, didn't think so

18:23 bbloom: somewhat intentionally

18:23 i think

18:23 seangrove: Makes sense, didn't really expect it to

18:24 bbloom: destructuring maps expands to very simple get calls

18:24 but get depends on ILookup

18:25 you could trivially define ILookup in terms of aget

18:25 but you wouldn't really want to

18:25 because then EVERY OBJECT would have a unwanted implementation ILookup

18:25 alternatively, you could do something like (deftype Dictionary [] ILookup …)

18:26 or (deftype Expando ...

18:26 seangrove: Yeah, although it's just sugar, it would be nice to have in order to make the function args more explicit

18:26 Hmm, wouldn't that still have the same problem?

18:26 bbloom: it's also more general, so you'd pay protocol dispatch cost when a simple aget would be fastest

18:26 seangrove: It's not such a big deal, it's for rendering templates

18:28 The flow is render template-name with cljsobject, render converts cljsobject to a js-obj, it's passed into the rendering system, but that rendering system calls out to helpers (it's Handlebars), and those helpers are looking cluttered and magical

18:28 bbloom: seangrove: if you always except a js-obj as the only argument, you could do a macro simpler to the fnk that's been floating around

18:29 seangrove: Yeah, because when the helper is called from the template, it's already been converted into a js-object

18:29 bbloom: if (fnk [x y] …) expands to (fn [{:keys [x y]}] …) you could have (fnobj [x y] …) expand to a let binding with the appropriate agets or property lookups

18:30 i assume you're trying to do something similar to the common with(templateContext) { template body here … } thing in client side template engines

18:31 seangrove: Yeah, this is getting a bit messy anyway, but I've been putting off refactoring it and adding macros because it works for the time being

18:31 I'll add that in during factor though, it looks like a great idea

18:40 holo: is there any way for map, or other related builtin form to keep the data type from the input sequence without explicitly calling into?

18:42 AimHere: Well that's a tall order for map, since it can take multiple different collection types to begin with

18:42 Regardless, I don't think such a thing is part of clojure, though it doesn't seem like it'd be hard to write

18:43 *multiple collections of different types

18:43 brainproxy: holo: no, but could always do something like (apply list (map ...))

18:44 if say, you wanted to be sure you got a list as the final output of your map-based transform

18:44 (vec (map ...)) could be used to similar effect, also (apply hash-map (map ...)), you get the idea

18:45 holo: brainproxy, that implies the input would be a list too, if the intention was to preserve the collection type. but i heard into is the idiomatic way of doing it

18:45 AimHere: Well mapv already exists as a builtin version of (vec(map

18:45 holo: AimHere, thanks, i will try to do it

18:45 AimHere: IIRC, the source code for the likes of map and filter and reduce already have some type-specific code based on each collection type

18:45 brainproxy: holo: i'm doing something similar similar in my fork of protocol-monads

18:46 that is, when you use a m/do or a monad utility like m/lift or m/seq, you get the same type out as you put in

18:47 holo: AimHere, weird, i don't have mapv

18:47 AimHere: It was introduced in 1.4

18:48 Also filterv

18:49 holo: brainproxy, but i have to know what is the input type with your examples so that i can try to preserve it

18:50 brainproxy: yes, in what I suggested above you do

18:50 protocol-monads does it automatically

18:51 but I don't know what kind of transforms your're donig, so I'm not sure whether to suggest you look into using p-m

18:51 holo: brainproxy, oh.. thanks .. i will definitely look into it

18:51 brainproxy: holo: i've got a snapshot out on clojars, the parent project doesn't incoporate my changes, at least not at present

18:52 holo: https://clojars.org/org.clojars.michaelsbradleyjr/monads

18:52 jkkramer: (into (empty coll) (map f coll)) preserves type, although doesn't necessarily preserve order

18:52 brainproxy: holo: my latest work is on this branch, but nothing in there yet which introduces an api change w.r.t. to the snapshot out on clojars

18:52 https://github.com/michaelsbradleyjr/protocol-monads/tree/return-and-factory-refactoring

18:54 holo: jkkramer, maybe order is not so important, for the moment. thank you

18:54 brainproxy, looking at the source. thanks

19:01 jkkramer, that "empty" is genious

19:04 brainproxy: holo: just keep in mind you could run into an ordering issue w/ empty/into

19:05 holo: brainproxy, yes, jkkramer generously warned me of that issue. thank you for the attention

19:23 devn: cond-> in action https://github.com/Datomic/codeq/blob/master/src/datomic/codeq/analyzers/clj.clj#L44

19:31 seangrove: How can I do something like (comp .getButton .getButtonSet) in cljs?

19:35 lynaghk: Any ruby metaprogrammers have thoughts on making record-like things in Ruby?

19:35 Gist with deets here: https://gist.github.com/4210677

19:53 bbloom: lynaghk: metaprogramming in ruby is pretty easy via string interpolation

19:53 lynaghk: bbloom: yeah, I found this SO suggestion: http://stackoverflow.com/questions/4113479/ruby-dynamic-class-definition-with-a-class-name

19:54 bbloom: lynaghk: you can use define_method with either a block or a HEREDOC

19:54 lynaghk: actually, that SO suggests that I wouldn't be able to do dynamic class definition just via string interpolation

19:56 bbloom: you can do things like:

19:56 er hm

19:56 how to convey this tersely....

19:56 the common meta programming pattern is to put class functions on the base type

19:56 and then call them

19:56 so basically self.do_meta_thing

19:57 and in there, you can call self.class.send :define_method, name do |arg|

19:57 lynaghk: hmm

19:57 bbloom: lynaghk: you need to learn about ruby's "metaclasses"

19:58 lynaghk: here is a decent tutorial, but the idioms are a bit old

19:58 lynaghk: newer versions of ruby and activesupport include many of these helpers by different names:

19:58 http://ruby-metaprogramming.rubylearning.com/html/seeingMetaclassesClearly.html

19:58 lynaghk: bbloom: thanks!

19:59 bbloom: lynaghk: i've got to run, but basically just study how metaclasses work and maybe peek at the source of some popular DSLs to see how they function

19:59 good luck :-)

20:00 technomancy: oh man, I thought for sure "metaprogramming is easy via string interpolation" was making fun of ruby

20:00 scriptor: isn't that perl?

20:03 mdeboard: yeah. everyone knows metaprogramming via string interpolation is done best with Python https://gist.github.com/16010d1fcda091024bc8

20:07 nDuff: Question about Emacs Live -- how does one get out of its open dialog without actually selecting anything? <ESC> <ESC> <ESC> doesn't work anymore...

20:08 Bergle_1: nDuff - ctrl-g

20:08 squidz: whats the easiest way to use a anyonmous partial function in clojure? I want to do something like (reduce (partial (fn [x] ...

20:08 nDuff: Ahh; thanks.

20:08 Bergle_1: nDuff = hangon esc stops for me as well

20:08 ChongLi: C-g becomes such a habit in emacs

20:08 * Bergle_1 still a emacs newby... and been payig with emacs-live

20:08 ChongLi: that I hit it in other programs too

20:08 technomancy: ESC ESC ESC is equivalent to C-g

20:09 Bergle_1: just ESC once stops it for me.

20:09 * nDuff just did a git pull today, and behavior changed.

20:09 Bergle_1: oh.

20:09 ive had emacs live just out and crash on me 3 times yesterday :( not to happy aobut it.

20:09 also amazed they changed ctrl-v :(

20:10 squidz: but I get wrong number of argument exceptions

20:10 ChongLi: Bergle_1: scroll-up-command

20:10 what did they change it to?

20:10 technomancy: that's just crazy

20:10 Bergle_1: repeat last i think.

20:10 ChongLi: that doesn't make any sense

20:11 C-x z does repeat for me

20:11 Bergle_1: repeat last execute

20:11 ChongLi: I use scrolling way more than repeat

20:11 Bergle_1: as in "." in vim.

20:14 squidz: https://www.refheap.com/paste/7290

20:18 antoineB: hello

20:18 ChongLi: hi

20:18 antoineB: is it possible to change the clojure[script] reader for parsing anything?

20:20 ChongLi: afaik clojure doesn't have user-definable reader macros (a la CL)

20:21 so if you want to work with some arbitrary (non-clojure) syntax you'll have to write your own reader or parser

20:21 antoineB: ok

20:22 hiccup style also possible

20:22 ChongLi: yeah hiccup just embeds a dsl in clojure syntax

20:28 ticking: does anybody know whats up with the misterious deps.js file with clojurescript ^^?

20:29 I assume it hase something to do with external libs and closure, but I'd be interested if it is of any significance to clojurescript development ^^

20:30 antoineB: it is marked as missing?

20:31 ticking: antoineB yeah ^^

20:31 antoineB: remove your main.js and rebuild it

20:31 make sure you run your experiment on a webserver, not localhost

20:32 ticking: antoineB, hm interesting, why is that important?

20:33 antoineB, I cleaned and recompiled without change, probably because of that localhost thing

20:33 nevertheless I'd be intrigued to know why this could make a difference :D

20:33 antoineB: ticking: clojurescript repl don't works on localhost

20:34 ticking: antoineB, I never used it's repl so far, autobuild always sufficed :D

20:35 antoineB: ticking: try serving your stuff with a webserver

20:35 ticking: antoineB, k any quick reccomendations :]

20:36 antoineB: recomendations for what?

20:36 ticking: quick and dirty webservers for noir ^^

20:37 antoineB: i use cherokee

20:37 ticking: thanks :D

20:37 antoineB: nothing special, you setup a new name in /etc/hosts

20:39 ticking: i probalbly wrong, noir use jetty or netty

20:39 nevermind cherokee

20:40 ticking: antoineB, hrhr, k when there's not _the_ obvious solution I'll do some research ^^

20:40 tomoj: hmm, I use localhost for my repl

20:40 just file:/// doesn't work, I think?

20:41 antoineB: tomoj: you right i made a mistake, that is file which don't work

20:42 ticking: i remmember how i resolved it with noir

20:43 i make a fake deps.js in ressources/public :)

20:44 tomoj: just add <script type="text/javascript">var CLOSURE_NO_DEPS = true;</script> before your cljs script


20:46 ticking: hrhr

20:46 tomoj: so satisfies? is slow, huh?

20:46 muhoo: it may be slow, but it is so satisfying.

20:46 * muhoo ducks

20:48 tomoj: noticed cheshire is doing (get (:impls JSONable) (class obj))

20:48 which fails if (deftype Foo [] JSONable ..)

20:49 ticking: tomoj, yeah that did the trick, turning on advanced optimisations seems to be the third way to solve it, I'm still wondering what it is used for :D

20:49 thanks

20:50 tomoj: satisfies? being slow makes me want to go ahead and take all my (if (satisfies? Foo foo) (-foo foo) ...) and just make the ... a default impl of the protocol :/

20:51 amalloy: tomoj: i think that's the intended use case for default protocol impls, right?

20:51 ticking: alright thanks for the fish and good night :D

20:53 tomoj: amalloy: dunno.. the fact that satisfies? becomes useless has made me wonder if there are even any good use cases for default impls at all

20:53 I guess if you can provide an impl for everything, then it makes sense for everything to satisfy

21:09 amalloy: satisfies? is a bit yucky by definition, i think. it's runtime introspection of the polymorphic structure, rather than just...using polymorphism

21:42 squidz: I feel like i'm having to reinvent the wheel while coding in clojure. I have to implement lot of basic functionality like get the nth element of an vector, or combine two vectors. Am I missing something?

21:42 amalloy: &(doc nth)

21:42 lazybot: ⇒ "([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."

21:42 amalloy: $findfn [1 2 3] [4 5 6] [1 2 3 4 5 6]

21:43 lazybot: [clojure.set/union clojure.core/lazy-cat clojure.core/concat clojure.core/into]

21:43 squidz: sorry i meant remove the nth element from a vector

21:44 amalloy: neither of those operations are things that vectors can do efficiently, so there's no built-in to encourage you to be inefficient

21:45 squidz: what should I use instead of vectors for that then?

21:45 amalloy: usually lazy sequences, since you'll usually find you don't need indexes at all, just a stream of items

21:46 using nth is a pretty rare event for me

21:46 squidz: i am usually doing matrix type operations

21:46 working with rows and columns

21:47 amalloy: sure, and vectors are great for that. but you don't need to remove items

21:47 or concat two matrices

21:47 squidz: so far ive just ben using vectors like so [[1 1] [2 2]]

21:47 i have to manipulate the values in the matricies usually

21:48 amalloy: so? assoc, assoc-in, update-in, get, and get-in are all you need

21:48 &(update-in [[1 1] [2 2]] [0 1] inc)

21:48 lazybot: ⇒ [[1 2] [2 2]]

21:49 tos9: &(doc get-in)

21:49 lazybot: ⇒ "([m ks] [m ks not-found]); Returns the value in a nested associative structure, where ks is a sequence of keys. Returns nil if the key is not present, or the not-found value if supplied."

21:49 tos9: &(doc get)

21:49 lazybot: ⇒ "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."

21:50 squidz: okay, i think i'm just not familiar with those functions yet. I haven't seen assoc-in/update-in/get-in

21:51 amalloy: yes, those are the functions you want. if you had functions named remove-nth and combine-vector, they'd be terrible for matrix operations :)

21:52 squidz: i just made these functions that deal with manipulation https://www.refheap.com/paste/7292

21:53 n-col and n-row return the nth row/col or return everything excluding row/col when a negative index is passed

21:54 tomoj: b

21:54 squidz: was there any way I could have avoided those functions?

21:57 amalloy: or is there anyway I could have used clojure'S built-in functionality more when writing my functions?

23:19 patrickgombert: quick language question, why don't protocols work like interfaces? Is there a reason for only having to implement a part of a protocol?

23:21 tomoj: they sort of do work like interfaces, in that it is similarly possible to implement only part of an interface in clojure

23:21 I don't know the answer you're looking for, though :)

23:22 patrickgombert: In Java, for example, it's a compile error to not implement the whole interface. In clojure, however, it's not a requirement to implement the whole protocol

23:22 ohpauleez: patrickgombert: Also, you can use protocols as a form of safe monkey-patching to redefine behavior/participation, so you'd want piecewise definitions then

23:22 patrickgombert: Ah, that makes sense

23:23 is there a construct more binding, like an interface, that requires all functions to be implemented?

23:23 ohpauleez: Protocols specify behaviors you want to participate in (the interfaces to larger systems/components). If you want to participate in only a part of that system, so be it

23:24 patrickgombert: You most likely do not want to do that. There's no real advantage

23:24 but if you're dying for some raw interface action: http://clojuredocs.org/clojure_core/clojure.core/definterface

23:25 patrickgombert: thanks

23:25 tomoj: ..but again, clojure will happily allow you to leave out methods in an interface implementation

23:25 ohpauleez: again, I strongly encourage you to make use of protocols and frame your problem in terms of participation and composition. It might help you get more mileage out of them

23:32 alex_baranosky: can you add docstrings to the individual methods of a protocol?

23:32 if so, anyone have an example link?

23:33 tomoj: ..see (doc defprotocol)

23:35 alex_baranosky: tomoj: shows no way of doing so… but it looks like defprotocol is in fact generating vars for each methos

23:35 tomoj: your docs must be different than mine

23:36 but since defprotocol was added in 1.2, and the 1.2 docs show an example of this, not sure how.. http://clojuredocs.org/clojure_core/1.2.0/clojure.core/defprotocol

23:37 ohpauleez: also here at 1.3: http://clojuredocs.org/clojure_core/clojure.core/defprotocol

23:37 alex_baranosky: The short answer is they go at the end

23:37 alex_baranosky: thanks guys

23:37 ohpauleez: np

23:37 totally welcome

23:38 tomoj: wonder if clojuredocs will ever disappear

23:38 alex_baranosky: neither link shows doc strings do they?

23:38 I'm doing this, but it seems ridiculous to have to: (alter-meta! #'not-a-map-error assoc :doc "asdffdsfasfd")

23:39 oh I see

23:39 thanks guys!

23:39 ohpauleez: alex_baranosky: (deprotocol SomeProto "This is about this behavior" (take-one [this] "take one thing from it"))

23:39 tomoj: clojure-doc.org doesn't seem to do well on google yet

23:39 ohpauleez: tomoj: hopefully that'll change in the future

23:40 alex_baranosky: that syntax is unfortunately not what you'd expect… but I'll live :)

23:40 ohpauleez: :)

23:42 alex_baranosky: I like to write tests like this for my open source projects:

23:42 (is (= [] (map str (remove (comp :doc meta) (vals (ns-publics 'clj-schema.schema))))))

23:59 Knor: tomoj,

23:59 I am the best programmer in the world save only for the microsoft Chief Software Architect

Logging service provided by n01se.net