#clojure log - Jun 25 2011

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

1:24 justinlilly: what's the name of that site where you can submit answers to problems with clojure? Like: Reverse a list. and you paste in a function that will do it.

1:26 aha! 4clojure.org

1:28 amalloy: justinlilly: do we have .org? i thought we just had .com

1:30 ah, right. dbyrne bought that when someone mis-tweeted the domain

3:21 bsod1: I installed clojure-contrib, and it has a clojure-contrib-xx.jar in target/, should I still build it, because I don't have mvn installed(and my package manager doesn't have too)..

3:27 amalloy: bsod1: don't build it or install it. just use leiningen or cake. you can just say "i need contrib" for a project, and the build tool will go fetch you a prebuilt jar

3:49 bsod1: amalloy: I'm trying to install vimclojure, is leiningen OK? I think vimclojure needs contrib installed

3:50 amalloy: bsod1: i'm an emacs user, alas. link me to your vimclojure install guide and maybe i can help?

3:50 bsod1: amalloy: http://www.duenas.at/new_homepage/vimclojure and http://blog.darevay.com/2010/10/how-i-tamed-vimclojure/

3:53 amalloy: jesus, this is messier than getting slime/swank versions right

3:54 maybe gfrlog knows? he's probly in bed but i don't know who else uses vim

3:55 bsod1: amalloy: how can I test if I installed clojure and clojure-contrib?

3:55 amalloy: at any rate i don't see any reason you should have to build the clojure or contrib jars. you can just get them from clojars

3:58 bsod1: i haven't tried to do any of this by hand for like a year; i'm not much help. you might try the simpler "use leiningen to get up and running" before the apparently-huge hurdle of vimclojure

3:59 https://github.com/technomancy/leiningen

4:00 faust45: hi guy's

4:00 just have a question, is it possible have async io in clojure?

4:01 amalloy: yes

4:01 java.nio or aleph are good places to look

4:01 mids: https://github.com/ztellman/aleph

4:03 faust45: thanks guy's

6:55 bsod1: how can I be sure I installed clojure and clojure-contrib correct?

6:56 Vinzent: bsod1, just add it to the project.clj's :dependencies

6:57 or what do you mean by "install"?

6:58 bsod1: Vinzent: I'm new to clojure, I downloaded latest version of clojure and clojure-contrib, and build clojure, now should I be in the same directory with clojure to run it? is only way to run clojure `java -cp clojure.jar clojure.main` ?

7:00 Vinzent: bsod1, I think you should download and install leinengen - build tool for clojure. Then, you can just run lein new my-project && cd my-project && lein deps && lein repl and you'll got working clojure REPL

7:01 bsod1: Vinzent: will it work for vimclojure repl? I'm trying to setup vimclojure

7:03 Vinzent: bsod1, I'm using emacs, but I believe that vimclojure compatible with leiningen

7:04 See https://github.com/technomancy/leiningen/wiki/Plugins: lein-nailgun Launch a vimclojure nailgun server.

7:17 bsod1: what sould I add to my project.clj to use clojure-contrib?

7:40 terom: bsod1: http://clojure.org/downloads, see the bottom of the page

7:48 longfin: is there anyone who knows swank-clj?

7:58 terom: Link in the Leiningen plugins page for lein-nailgun (https://github.com/brandonw/lein-nailgun) gives 404 for me. (Found it on clojars, though: http://clojars.org/lein-nailgun or http://clojars.org/org.clojars.gfodor/lein-nailgun)

8:11 bsod1: (:require clojure.xml) gives me ClassNotFoundException, what did I do wrong? should I install clojure-contrib for this?

8:22 faust45: bsod1: something like this http://friendpaste.com/6mi5vQswJGTpctHMvd2I7k

8:23 bsod1: faust45: thanks but I'm not running REPL vie lein, I'm using nailgun

8:25 faust45: bsod1: why not lein?

8:28 bsod1: faust45: if you explain me how can I use lein with vimclojure..

8:30 faust45: bsod1: i dunno how to integrate vimclojure with lein, but you can use them separate

9:08 hugod: longfin: you have a question on swank-clj?

9:08 longfin: yes...

9:09 in-ns doesn't work when using swank-clj

9:09 but it works using swank-clojure...

9:14 hugod: longfin: in-ns at the repl?

9:15 longfin: yes. using slime

9:15 hugod: you found a bug…

9:18 https://github.com/hugoduncan/swank-clj/issues/10

9:18 longfin: okay..

9:46 hugod: longfin: ,!p works, if you are looking for alternatives

9:47 longfin: ok thanks

10:14 Norrit_: Hi, I have a little question. I want to use a string to reference a binding var, something like this: (let [name "World"] (str "Hello " (find-var (symbol "name"))))

10:14 Any ideas how I can do that?

10:23 Vinzent: Norrit_, you should use binding to rebind the var. Also, as wroted in find-var's docs, symbol must be namespace-qualified

10:23 (str @(find-var (symbol "user/foo")))

10:28 Norrit_: Vinzent, that doesnt seem to work .. it only returns an empty string

10:29 Vinzent: Norrit_, you should do (def foo "your-string") in the user namespace before that

10:30 Norrit_: Ah ok, now I get it .. but is there no way to access "local" let bindings?

10:31 Vinzent: I have no idea why someone may want to access to local bindings in this way :)

10:31 Norrit_: Hehe :-)

10:33 I want to write something like the el-strings in java ... (let [foo "bar"] (print (my-string "Hello ${foo}")))

10:34 Vinzent: I guess it's better to use format for this purpose, but if you really want this, probably you should write my-string macro and manually extract the symbols from the given string

10:37 Norrit_: Well, first of all I want to play around with the language ;-) but I will try to write the macro .. thanks for your help

10:38 Vinzent: Norrit_, ah, ok :) it'd be something like this (defmacro foo [s] `(str ~(str s) " is " ~s)), (let [q 5] (foo q)) => "q is 5"

10:40 Norrit_: that looks nice, I will give it a try

12:37 gfrlog: is there ever a reason to use a single ref?

12:37 offby1: ?

12:37 oops, never mind

12:37 gfrlog: rather than an atom

12:38 manutter: I'd say only if you know there's going to be more refs later one

12:38 gfrlog: manutter: so essentially no :)

12:39 manutter: Atom ought to cover any single-update transaction you would need

12:39 gfrlog: I was just making sure I didn't misunderstand what refs did. I've never had a reason to use one.

12:39 though I've used atoms and agents and vars plenty.

12:39 manutter: So far I haven't needed them either

12:39 gfrlog: strange, that

12:39 manutter: but I'm not in the kind of coding that would require synchronized updates of multiple entities, so I wouldn't need them

13:16 __name__: Why can you not use macros with apply?

13:16 ,(apply and [true true])

13:16 clojurebot: java.lang.Exception: Can't take value of a macro: #'clojure.core/and

13:18 Scriptor: __name__: from looking at the source, it calls applyTo() on the passed function

13:18 maybe macros don't have that method?

13:20 so it looks like there are 5+ parser libraries for Clojure, which ones do people have experience with here so I'll have better luck with asking questions? :p

13:22 fnparse seems to have the most documentation

13:49 sritchie: has anyone run into this error before? -XX:MaxPermSize=128M

13:49 whoops

13:49 java.lang.OutOfMemoryError: PermGen space

13:49 derp__: I am trying to create a lazy sequence of lists such as (999 999) (999 998) ... (0 0)

13:49 and I am using this as a guide: http://clojure.org/lazy#Making%20Clojure%20Lazier--Recipe%20-%20How%20to%20write%20lazy%20sequence%20functions%20in%20new%20model

13:49 but I still don't really have a clue how to do this

13:50 sritchie: derp_: (for [x (range 1000) y (range 1000)] [x y])

13:50 ,(for [x (range 5) y (range 5)] [x y])

13:50 clojurebot: ([0 0] [0 1] [0 2] [0 3] [0 4] [1 0] [1 1] [1 2] [1 3] [1 4] ...)

13:51 sritchie: ,(type (for [x (range 1000) y (range 1000)] [x y]))

13:51 clojurebot: clojure.lang.LazySeq

13:51 derp__: sritchie: thank you again

13:52 jamiltron: That's pretty cool.

13:54 derp__: now how would one create that list in reverse?

13:54 cause I am assuming accessing the last causes it to compute all members, which would be a waste, right?

13:55 jamiltron: Use (range 5 0 -1) to reverse it.

14:04 gfrlog: I'm using clojure.contrib.json, and I want to be able to add to the set of types that it can encode. You'd think it would have been implemented as a multimethod to make that easy, but it doesn't look like it has, and I looked at clj-json and that seems to be the same situation. Is there no clean way to do this?

14:06 oh wait I think there is a protocol in c.c.json. That's probably what I need.

14:16 high five, clojure.

14:21 derp__: just out of curiosity, what is the functional way of finding the max number in a list?

14:22 mrBliss`: ,(reduce max [1 3 4 2 9 8 3])

14:22 clojurebot: 9

14:22 derp__: mrBliss: thanks

14:25 bsod1: can anyone help me? vimclojure's eval paragraph(<leader>ep) always gives me an exception, but eval file(<leader>ef) works

14:29 derp__: I am running into a weird error with this code: http://pastebin.com/yXNirFe0

14:29 I am getting a null pointer exception after a little bit

14:29 I think it has something to do with java heap size or something, no?

14:29 sritchie: derp__: ,(reduce max [1 5 3 2 9 7])

14:30 ,(reduce max [1 5 3 2 9 7])

14:30 clojurebot: 9

14:30 sritchie: whoops

14:30 should have read other comments

14:30 sorry, mrBliss`

14:30 bsod1: can anyone help me? vimclojure's eval paragraph(<leader>ep) always gives me an exception, but eval file(<leader>ef) works

14:32 sritchie: derp__: (defn palindrome? [num] (let [s (str num)] (= s (->> s reverse (apply str)))))

14:33 derp__: sritchie: what does the ->> syntax mean?

14:33 sritchie: derp__: sorry, you weren't asking for a new version of that function, didn't mean to just toss it out there

14:33 ->> is the threading macro

14:33 it takes the first form, and "threads" it into the second form at the last position, then keeps doing that

14:33 gfrlog: you can use ->> even funnerer than that...

14:34 (defn palindrome? [num] (->> num str reverse (apply str) (= (str num))))

14:34 I guess that's mildly repetitive though :/

14:34 sritchie: and if something doesn't have parens inside of the body of ->> , just pretend it does. So, in this case, we start with s -- that gets threaded into (reverse) at the last position, making (reverse s)

14:35 then that gets threaded into the next form, making (apply str (reverse s))

14:35 derp__: wow, that's crazy

14:35 sritchie: commas are whitespace, so you can use commas to visualize... (->> s (reverse ,,,) (apply str ,,,))

14:35 gfrlog: derp__: it seems pretty weird until you've been writing ugly code for a while :)

14:36 and by ugly I mean "heavily nested"

14:37 and "makes more sense when you read it backwards"

14:37 derp__: seems like an awfully complicated technique

14:37 or does it just become another useful tool after becoming familiar with the language?

14:37 gfrlog: derp__: exactly

14:37 because otherwise we end up writing things like (a (b (c (d))))

14:38 instead we can (-> (d) (c) (b) (a))

14:38 which better reflects the order of the operationsa and isn't so painfully nested

14:38 derp__: so the reason your code is crashing is because you have a recursive function with no base case :)

14:39 derp__: ah, now I'm sort of getting it

14:40 gfrlog: derp__: you could try fixing that just for fun, but it might be ultimately more helpful to rework palFinder

14:40 all the recursion isn't necessary

14:41 you could do everything there with (filter)

14:41 sritchie: derp__: here's an example from my own code: https://gist.github.com/1046756

14:41 the second version uses threading to make everything a little clearer

14:41 derp__: gfrlog: wow, can't believe I missed that, thank you

14:41 gfrlog: derp__: no problem

14:41 derp__: I had to stare at it for a few minutes myself

14:48 sritchie: derp__: there's a nice opportunity for the threading macro in your final solution

14:49 gfrlog: I like the contrib macros -?> and -?>>

14:50 sritchie: gfrlog: here are some fun threading macros I've been helping with: https://github.com/pallet/thread-expr

14:50 different flow control macros like for->, if->, for->> etc that work within the body of a call to one of the threading macros

14:51 gfrlog: sritchie: I have to say those examples are not immediately clear :)

14:51 you should add "expands to..." after each of them

14:51 sritchie: haha, that's an excellent point

14:52 I'll tweak those shortly

14:52 gfrlog: easy to forget when you already know them yourself

14:52 sritchie: derp__, don't take this as nitpicky, but one style thing that I might recommend is the use of lowercase letters in var names, with dashes between words instead of caps

14:52 * hugod is guilty of writing those examples

14:53 sritchie: that'll distinguish your variables from java methods

14:53 hugod: :) maybe we can just change the word "Examples" to "Koans"

14:53 gfrlog: hugod: better than not writing examples ;)

14:54 sritchie: hugod, all of the pallet threading stuff really helped, writing this text based blackjack game I'd been playing with

14:54 hugod: well, they're copied from the unit tests, which probably explains it

14:55 sritchie: it was nice to realize that game state threading made as much as sense as the incremental transformations on threaded requests

14:56 hugod: sritchie: glad you have found other uses for them

14:56 I still think there has to be a better solution than threading for pallet…

14:57 sritchie: I stalled on my monad investigation

14:57 I'm working through the seasoned schemer... reasoned schemer and core.logic come next

14:57 you've made enough intriguing comments in that direction

15:00 derp__: sritchie: thanks for the suggestion, I just got used to camelcaps after writing java for so long ;P

15:08 dnolen: hmm odd :import doesn't convert - to _

16:30 aaelony: hi, I'm trying to access the :name element of the following, but something is not right because it returns nil

16:30 test=> (pprint (take 1 (:properties (first j))))

16:30 ({:name "blah",

16:30 :newValue "e92c6344-3af5-47c2-abd1-fce681f48fd0",

16:30 :oldValue "2ba3ebeb-94c5-4528-9bec-45eeb6d4da40"})

16:30 nil

16:30 test=> (:name (take 1 (:properties (first j))))

16:30 nil

16:31 any ideas?

16:32 test=> (class (take 1 (:properties (first j))))

16:32 clojure.lang.LazySeq

16:32 amalloy: aaelony: https://gist.github.com is one idea

16:32 aaelony: amalloy: thanks will check it out

16:33 amalloy: not sure what you mean. I see an empty page at your link.

16:33 amalloy: aaelony: yes. you can paste code there instead of long chunks of code here, where it's hard to read

16:33 aaelony: ah, i see. sorry about that

16:34 amalloy: aaelony: anyway, (take 1 x) will return a list, not an item from the list

16:34 (:name (first x)) would work

16:34 aaelony: (:name (first x)) does not work

16:35 https://gist.github.com/1046871

16:36 pcavs_: aaelony: try (:name (first (:properties (first j))))

16:36 aaelony: pcavs: that works!

16:37 pcavs_: aaelony: amalloy was correct, I just rewrote it to be more like your example

16:37 aaelony: I'm sure it is something that I am doing wrong due to poor understanding on my part

16:38 thanks, for the help. Now I need to loop, for, or map this such that I extract certain keys from this structure. :name is the first of those.

16:39 rpglover64: I'm new to clojure (hello from Haskell-land) and I'm trying to understand why my program is behaving in a way that I find very unintuitive.

16:39 http://hpaste.org/48331

16:39 which is a straightforward translation of http://hpaste.org/47339

16:40 amalloy: rpglover64: clojure's self-recursive data structures don't really work as well as haskell's in some cases

16:41 rpglover64: (take 10 primes) gets me (2 3 5 7 9 11 13 15 17 19)

16:41 and 15 isn't a prime

16:41 gfrlog: nor is 9

16:41 rpglover64: yeah

16:42 amalloy: rpglover64: in this case, the problem is that (range) produces a chunked sequence

16:42 if you replace (drop 3 (range)) with (iterate inc 3), it will work

16:43 rpglover64: thank you

16:43 amalloy: chunked meaning that it realizes a bunch of (32?) elements all at once, and that means there are 32 integers in a row all relying on the old definition of primes before they get inducted into the hall of primes

16:43 (you could also write (iterate #(+ 2 %) 3) for the ultimate in performance *chuckle*

16:44 gfrlog: amalloy: (iterate dinc 3)?

16:44 rpglover64: at that point, i'm just going to start writing a wheel sieve

16:44 amalloy: rpglover64: fwiw clojure already has a wheel sieve. i assume you're doing this for your own edification, but just so you know

16:45 rpglover64: amalloy: OOH where?!

16:45 amalloy: http://clojure.github.com/clojure-contrib/lazy-seqs-api.html

16:46 gfrlog: of course if you're not interested in writing your own code, there's always BigInteger#isProbablePrime

16:47 rpglover64: gfodor: true

16:53 gfrlog: amalloy: did you say yesterday than an ISeq always has a first element?

16:54 amalloy: gfrlog: was i wrong?

16:54 gfrlog: amalloy: () is an ISeq, isn't it?

16:54 aaelony: what is the correct way to specify that api (http://clojure.github.com/clojure-contrib/lazy-seqs-api.html) in the project.clj ?

16:55 amalloy: &(supers (class (map inc nil)))

16:55 sexpbot: ⟹ #{clojure.lang.ISeq java.util.List java.io.Serializable clojure.lang.Obj java.util.Collection clojure.lang.IPersistentCollection clojure.lang.IMeta clojure.lang.IObj java.lang.Object clojure.lang.Seqable clojure.lang.Sequential java.lang.Iterable}

16:55 amalloy: gfrlog: okay, i was wrong

16:55 gfrlog: amalloy: okay just checking

16:56 amalloy: &(supers (class (seq (map inc [1]))))

16:56 sexpbot: ⟹ #{clojure.lang.ISeq java.util.List java.io.Serializable clojure.lang.IChunkedSeq clojure.lang.Obj java.util.Collection clojure.lang.IPersistentCollection clojure.lang.IMeta clojure.lang.ASeq clojure.lang.IObj java.lang.Object clojure.lang.Seqable clojure.lang.Sequential java.lang.Iterable}

17:00 gfrlog: amalloy: I'm not sure why I thought of that just now

17:01 amalloy: presumably i was helping so many people you were worried it might go to my head, and i needed to be brought down to earth

17:02 gfrlog: "helping so many people" made me think of Mother Theresa for some reason

17:03 * gfrlog imagines amalloy helping impoverished children learn the differences between haskell and clojure

17:04 amalloy: every one of them a precious snowflake, so dear to my heart

17:04 aaelony: i certainly appreciate the help

17:06 I've got a collection. For each number of times in the collection, I need to perform a few tasks. Not all tasks relate to the collection but some do. How do I construct a loop around this ?

17:07 gfrlog: aaelony: what does "for each number of times in the collection" mean?

17:08 symbole: Is it possible to destructure a map, and require certain keys to be present?

17:08 gfrlog: symbole: no, I think you have to check that separately

17:08 symbole: if you're destructuring function arguments, you can add preconditions

17:08 aaelony: I've got a complex json object. When I drill down to the right level in that obect, there are 274 rows. I need to extract some keys from those rows, but also bring in some keys from higher levels in that json as well

17:09 amalloy: you could also write a macro to do it, symbole?

17:09 gfrlog: oh yes macros are good for that

17:09 aaelony: if you want to select some elements from a collection, filter is good for that

17:10 symbole: Thanks. I'll look into both options.

17:10 gfrlog: as far as how to combine them with you're other stuff, that kind of depends on the details

17:10 aaelony: well, i need all the elements of a subcollection

17:10 gfrlog: s/you're/your

17:10 sexpbot: <gfrlog> as far as how to combine them with your other stuff, that kind of depends on the details

17:10 aaelony: traditionally it would be:

17:10 gfrlog: aaelony: I'm confused, you said "I need to extract some", but then you say you need all of them...

17:12 aaelony: for example, at a nesting depth of say 4-deep I need all the rows. for each of those rows, I need to bring in extra things (say they are at level 2-deep) besides the things that are at level 4-deep

17:13 gfrlog: aaelony: I guess it's hard to specify how to construct a loop without more details

17:13 aaelony: in perl, I would loop through the things that are at the 4-deep level, and output the things at the 4-deep level but additionally print things that were static.

17:14 it is precisely this loop that is unknown to me in clojure

17:14 gfrlog: aaelony: you're saying for a given level-4 collection there is some constant data that you want to add to each thing?

17:14 aaelony: yes, something very close to this situation

17:15 gfrlog: aaelony: you can use map to change all the elements of a collection in some way

17:15 aaelony: it can be viewed as static, because I already have access to it

17:15 gfrlog: ,(map #(assoc % :foo "bar") [{:id 10} {:id 12}])

17:15 clojurebot: ({:foo "bar", :id 10} {:foo "bar", :id 12})

17:16 aaelony: let me think about that

17:16 amalloy: gfrlog: ##(for [m [{:id 10} {:id 2}]] (assoc m :foo "bar"))

17:16 sexpbot: ⟹ ({:foo "bar", :id 10} {:foo "bar", :id 2})

17:16 gfrlog: amalloy: yes

17:16 amalloy: longer, but easier to layer if you want to iterate over multiply-nested things, which i bet aaelony will

17:17 rpglover64: so this is going to be a very noob question, partially dependent on my personal setup, but how do I get access to contrib libraries in the repl?

17:17 amalloy: rpglover64: how do you launch your repl?

17:17 aaelony: i think i need more fine grained control than map and assoc but not sure

17:17 rpglover64: clj-rlwrap.sh

17:17 aaelony: i probably need a more traditional loop

17:18 gfrlog: aaelony: why so?

17:18 amalloy: rpglover64: you *could* download contrib, put it on your classpath (which i guess clj does), and then (use 'clojure.contrib.lazy-seqs) for example

17:19 aaelony: I am trying to follow an example, and that would be closer to the example I am following.

17:19 amalloy: in the long run you'll be happier installing cake or leiningen and letting it manage your dependencies, instead of clj-rlwrap

17:19 rpglover64: huh; that didn't work when I tried it <_<

17:19 aaelony: perhaps as long as I can emit a vector with static and non-static elements that would work

17:20 gfrlog: aaelony: an example in another language?

17:21 aaelony: something like for(my $i=0;$i<@collection; $i++) { print join("\t",$x, $y, $z, $coll[$i]), "\n"; }

17:22 amalloy: rpglover64: imo cake is better for experimentation since it's easier to set up a "global project" with dependencies on things like contrib

17:22 gfrlog: aaelony: I'm not sure why for/map can't handle that kind of thing

17:23 (for [el collection] [x y z el])

17:23 aaelony: well, map takes a function and I need several functions

17:23 several function calls for each iteration

17:23 gfrlog: aaelony: you can combine several functions into one function

17:23 aaelony: gfrlog: that is the part I am unclear on in clojure

17:24 gfrlog: aaelony: let me back up real quick -- are you trying to return a data structure, or perform side effects like printing things?

17:26 in clojure you tend to handle the two cases differently

17:27 aaelony: Well, the long story of it is that this that I am writing a function that will be used by Cascalog. That function needs to construct a vector of fields. There are fields I have ready access to without a loop and those will be constant fields. I need to add the constant fields to the variable fields that i get from some looping mechanism. The ultimate output needs to be a vector of rows i believe.

17:28 gfrlog: aaelony: okay, so it sounds like no side effects; so what did you mean by having to make several function calls? What do you do with the return values of the function calls?

17:29 aaelony: the big ugly json I have has various nesting levels. Some items come from level-2 nestings, others come from deeper in the structure. I need to have calls that ask for the values of these variously nested values

17:30 no side effects, just extracting from various keys

17:31 gfrlog: aaelony: okay. it sounds like you're approaching the problem imperatively. I'm having trouble trying to convert the problem to functional style without a bit more tangibility. Can we try to create a simple example JSON?

17:32 e.g., from what you've said so far I'm thinking of this kind of thing: {:a 10, :b 12, :items ["one" "two" "three"]}

17:33 but maybe it has to be more complex? :/

17:33 hiredman: what is the state of the art for processing streams of xml in clojure?

17:34 aaelony: gfrlog: https://gist.github.com/1046871

17:34 gfrlog: aaelony: okay, so we're focusing on the :properties collection?

17:35 aaelony: gfrlog: yes

17:35 and I need to extract the 3 keys from the properties collection

17:35 gfrlog: aaelony: and you want to change the properties collection using the other keys (timestamp, instance, entityId, etc)?

17:36 aaelony: but in a way such that the other fields are output as well

17:36 (timestamp, instance, entityId, etc..., name, newValue, oldValue)

17:37 and have that repeated for each "row" of properties, 274 rows in this case

17:37 gfrlog: aaelony: okay. Making sense so far. The last detail is the high level stuff -- your json is a list of property-havers, so do we ultimately want a list of lists of properties?

17:38 aaelony: gfrlog: unclear on your question. essentially want to list out each row of properties, but also prepend the other data

17:38 gfrlog: okay, let's try this

17:39 https://gist.github.com/1046928

17:40 derp_: is "incr" a keyword? is there an easy way to test if I am accidentally using a keyword for a function/variable name?

17:40 gfrlog: that will merge all the keys from the top level (except :properties) with all the keys from the bottom level

17:40 derp_: type it into the repl?

17:40 ,incr

17:40 clojurebot: java.lang.Exception: Unable to resolve symbol: incr in this context

17:42 amalloy: derp_: there are very few keywords

17:42 gfrlog: :)

17:42 aaelony: gfrlog: I think that does it!! That is what I need to study and learn

17:42 derp_: gfrlog: that is a simple test, thanks

17:42 gfrlog: aaelony: nice

17:42 amalloy: i counted last night, as it happens, and there were 20, or a couple fewer

17:42 aaelony: gfrlog: never used merge nor dissoc before ... cool :)

17:42 gfrlog: amalloy: :now :there :are :five :more

17:42 AWizzArd: When you scroll down at http://download.oracle.com/javafx/2.0/binding/jfxpub-binding.htm and look at the box, containing example Java code, then you can see “new DoubleBinding() { …”. Then there is this piece of code: { super.bind(a, b, c, d); } <-- what is that?

17:43 gfrlog: aaelony: glad I could help

17:43 AWizzArd: no @Override annotation.. but it looks like an “anon constructor”?

17:43 amalloy: AWizzArd: anonymously extending/implementing a class/interface; that's a method body for some overridden method

17:44 AWizzArd: Can I do this with a proxy in Clojure? To me it seems they don’t call the super class’ Constructor, but instead another method of the super class.

17:44 amalloy: derp_, gfrlog: typing it into the repl won't really help. eg, deftype* is a special form, but:

17:44 ,deftype*

17:44 clojurebot: java.lang.Exception: Unable to resolve symbol: deftype* in this context

17:44 amalloy: AWizzArd: they implicitly call the no-arg super-constructor

17:45 rpglover64: Is there an introduction to Clojure for Haskell programmers specifically?

17:45 aaelony: gfrlog: That is really cool. There is one more wrinkle I need to contend with, sometimes some of the keys will be absent. In the case where a given key is absent, I need to output a "" placeholder for it. Normally, I would think to use (or :key "") for this. How would this be accomplished?

17:45 AWizzArd: amalloy: Otherwise proxy takes a vector, with args for the super class constructor. But in this piece of code they seem to call the bind() method?

17:45 amalloy: rpglover64: not as far as i know. if you hang around in here you can ask brehaut next time he's around

17:45 AWizzArd: incorrect parsing on your part

17:46 oh weird

17:46 i see

17:46 i was looking at the wrong snippet

17:46 yeah, that's a...what, local initializer block?

17:47 not a very common feature in java, but easy to do with clojure

17:47 AWizzArd: I don’t know, I interpreted this block as an anon class’ constructor?

17:47 Anyway, how can I do this with proxy? :-)

17:47 gfrlog: aaelony: I would probably create a helper function called assure-keys

17:47 amalloy: (doto (proxy [DoubleBinding] [] (computeValue [] ...)) (.bind a b c d))

17:48 gfrlog: (defn assure-keys [m ks] (reduce #(if (contains? %1 %2) %1 (assoc %1 %2 "")) m ks))

17:48 amalloy: if bind is a protected function that you can only call from the proxy itself, there's some functionality where proxy will make-public existing protected methods

17:48 gfrlog: aaelony: then you can call that function after merge, or something like that

17:48 AWizzArd: amalloy: ah okay, so simply moving this code outside could work here.

17:49 gfrlog: aaelony: I'm heading out

17:49 amalloy: AWizzArd: yes, it's effectively the anon class's constructor

17:49 it has some crazy name because it's a crazy feature

17:49 aaelony: gfrlog: many many thanks

17:49 gfrlog: maybe it should be called ensure-keys? I'm forgetting what words mean and which ones actually exist :/

17:49 aaelony: lol

17:49 thx again

17:49 gfrlog: yessir

17:51 amalloy: AWizzArd: i just looked at http://download.oracle.com/javafx/2.0/api/javafx/beans/binding/DoubleBinding.html though, which indicates that they've tried to put some more obstacles in your way

17:51 (1) bind takes varargs, so you have to pass it a java array rather than a bunch of arguments

17:53 (2) there's a protected method you have to call, and that can't be proxied (apparently)

17:53 i think you have to use gen-class to participate in this abominable API

17:53 AWizzArd: amalloy: ah okay

18:05 solussd_: chouser: re-reading JOC since it was released and I don't understand how lz-rec-step in section 6.3.2 alleviates the recursive stack overflow issue in rec-step. Is this a mistake?

18:12 amalloy: solussd_: no. that's just the magic of the lazy-seq macro

18:13 solussd_: amalloy- it doesn't work in this case

18:14 (lz-rec-step (range 20000)) ;stackoverflow

18:14 the outer seq, of length 1, contains all 20000 integers

18:15 amalloy: solussd_: that's a stackoverflow in the repl printing it

18:15 the original version has a stackoverflow just trying to create it

18:16 this is why chouser (or fogus) wrapped it with dorun

18:16 solussd_: ah

18:17 ok then. . now I'm more confused as to how lazy-seq allows the realization to happen non-recursively

18:17 or, without blowing the stack

18:17 amalloy: solussd_: are you familiar with a trampoline?

18:18 solussd_: yes. is that what is happening?

18:18 amalloy: it's very similar

18:18 solussd_: neat. thanks!

18:18 amalloy: a lazy-seq is basically a pair: [current-element code-for-next-element]

18:19 * gfrlog tries to figure out of the conversation is plausible under the assumption that solussd_ was thinking of a physical trampoline

18:19 amalloy: so the caller's code is effectively used as a trampoline: lazy-seq returns one element immediately, as well as some code the client can call to generate more if he wants

18:19 gfrlog: amalloy: so it's a cons cell where the second element is a function instead of list?

18:19 solussd_: gfrlog: only if we have two trampolines. :D

18:20 amalloy: *nod* and technically the first element is a function too

18:21 &(let [x (lazy-seq (throw (Exception. "oops"))) y (print "built x okay") z (first x)] z)

18:21 sexpbot: java.lang.Exception: oops

18:21 amalloy: hmph

18:21 in a real repl that would work

18:21 gfrlog: :)

18:22 REAL repls use vim

18:22 solussd_: emacs is a real repl. literally. :D

18:57 Raynes: amalloy: An oops exception?

18:57 amalloy: Where did we get an oops exception?

18:58 Oh.

18:58 Three cheers for actually reading the code.

18:58 amalloy: well done there

19:30 seancorfield: remind me, who owns/runs Clojars?

19:31 amalloy: seancorfield: these days i think technomancy inherited it?

19:31 but someone else is the official owner, and i think he's still around on occasion

19:32 disclaimer: this may be entirely false

19:32 seancorfield: 'k trying to sort out access for congomongo so multiple project members can push JARs

19:49 derp_: I have been working on the euler problems through one file I just keep adding to and reloading into repl (https://gist.github.com/1047049)

19:50 and recently I just tried to reload the code to get an error in my earlier code (which I am quite sure I haven't modified)

19:50 sritchie: here's a funky question -- in both cake and lein repl and swank, I find that I have to defn a var twice before a call to meta returns the right stuff

19:51 the question is, why?

19:51 https://gist.github.com/1047051

19:51 derp_: and the weirdest thing is this: as I reload the code, the line with the error increases

19:52 https://gist.github.com/1047053

19:52 I just don't get it

19:53 also I am using the cake repl, does it have known issues like this?

19:54 amalloy: sritchie: my understanding is that your meta calls should never work. the surprise is not that it takes two tries, but that it works at all

19:54 sritchie: derp_: this was my idea for the threading macro, btw -- https://gist.github.com/1046754

19:54 amalloy: (meta #'test-f) should work on the first try - defn attaches the meta to the var, not the function

19:55 sritchie: ah, I see

19:58 derp_: sritchie: wow, that is an elegant way of rephrasing the problem

19:59 amalloy: sritchie: if you figure out why it was working to begin with, i'd be interested to know

20:00 sritchie: amalloy: sounds good, looking at the source now

20:05 amalloy: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Symbol.java#L125

20:06 that's why it responds to the call... not sure why it takes two defns to update

20:06 amalloy: sritchie: for sure symbols *can* have meta

20:06 but defn doesn't attach any to them

20:07 sritchie: here, right? https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L305

20:08 you're more familiar with this than I am -- name here is the symbol, right?

20:08 amalloy: sritchie: yeah, it is. so defn creates a new version of the symbol, and passes it to def

20:09 def takes the meta from the symbol and attaches it all the the var

20:10 def can't really attach the meta to the value you're def'ing, since you might do something like (def ^{:size 10} x 1), and it can't attach meta to 1

20:11 sritchie: sure that makes sense

20:11 amalloy: so i still don't really see how any meta ever winds up attached to the *value* test-f, which is a function

20:14 sritchie: yeah, odd. playing with this, new-sym doesn't inherit the updated metadata on the second call -- https://gist.github.com/1047073

20:15 with, say, (defn test-func "some doc" [x] x), test-func gets its update after two, while the new-sym var inherits on the :name and :ns entries in the metadata map

20:18 amalloy: i guess defn does attach meta to the value after all. i didn't realize that

20:19 but it does so by looking up the *current* meta of the var x

20:20 sritchie: ah, so there's the delay. The var gets the basics, these get assigned to the value as well, then the var gets metadata updates

20:20 amalloy: yeah

20:20 sritchie: and two cycles of that is sufficient to catch up the value metadata. got it

20:20 amalloy: kinda a weird half-feature, half-bug, imo

20:21 sritchie: it does explain why (def func (fn [x] x)) (meta func) returns nil, though

20:25 amalloy: yes, i imagined that's what would happen even with defn, but apparently not

20:31 sritchie: is there some function in cake or leiningen to get the current dev-resources-path for a project?

20:33 amalloy: sritchie: i imagine it's available from cake.core/*project*

20:47 derp_: okay I really don't get what's going on, both cake and the lein repl are giving me the same weird moving error

20:48 every time I load my file (in either cake or lein) I get: java.lang.IllegalArgumentException: Parameter declaration let should be a vector (euler.clj:1)

20:48 tomoj: did you come from lisp or scheme

20:48 derp_: and if I try to load the file again, the erroring line increases (euler.clj:2, euler.clj:3) with every call

20:49 tomoj: paste euler.clj to pastebin or gist or something

20:49 derp_: https://gist.github.com/1047049

20:49 that's the code

20:50 and this is an example of the error (with no editing on the file): https://gist.github.com/1047053

20:50 I know neither scheme or cl, only java and a tidbit of python

20:51 tomoj: at the bottom you have "(defn solve-euler6 (let ..."

20:51 amalloy: derp_: you have an unbalanced paren somewhere, i think, since the code looks fine and fails for me too

20:51 tomoj: solve-euler6 needs a param array

20:51 vector I mean

20:51 amalloy: ah

20:51 tomoj: (defn solve-euler6 [] (let ..))

20:52 derp_: tomoj, amalloy thanks

20:52 man that's such a weird error, I really didn't know what to think

20:53 amalloy: derp_: yes, it's not a good error

20:54 it saw (let ...) and assumed that was the param-list, but it wasn't a vector

20:54 rather than assuming you forgot a param list

20:56 derp_: ah, well thank you for explaining that

20:57 also, I don't mean to start a flame-war or anything, but what's up with the epl licensing? I keep thinking about the cool projects I want to work with, but I am sad to learn how poorly the epl and gpl work together

20:58 or at least that's my biased/poorly informed opinion after reading a few posts about the matter

20:59 gfrlog: (epl + gpl) / 2 = fpl

21:16 davekong: How do I specify in a ":methods" takes an array of strings as an argument? when I use String[] I can a ClassNotFoundException: []

21:27 sritchie: gfrlog: tweaked the readme for you: https://github.com/pallet/thread-expr

21:28 it'll get some more love soon

21:41 gfrlog: sritchie: w000!

21:42 amalloy: davekong: ##(class (into-array ["test"]))

21:42 sexpbot: ⟹ [Ljava.lang.String;

21:42 amalloy: you want to specify that, as a string, iirc: "[LString;"

21:43 or maybe the java.lang part is necessary here? not sure

21:49 davekong: amalloy: seems I need the whole thing, but not sure it is working because I get another error "java.io.IOException: No such file or directory"

21:49 amalloy: is that "[L" talked about somewhere?

21:49 amalloy: $google java internal array classname

21:49 sexpbot: First out of 20400 results is: ArrayType (Java 2 Platform SE 5.0)

21:49 http://download.oracle.com/javase/1,5.0/docs/api/javax/management/openmbean/ArrayType.html

21:50 amalloy: ew wth is that

21:50 davekong: http://tutorials.jenkov.com/java-reflection/arrays.html maybe

21:58 daaku: i remember running across a function that iterated thru multiple sequences in parallel until the smallest one was run thru -- but can't remember the name. anyone know what i'm talking about?

21:58 amalloy: map

21:58 daaku: thanks amalloy

21:58 amalloy: &(map vector [1 2 3] [5 6 7 8])

21:58 sexpbot: ⟹ ([1 5] [2 6] [3 7])

22:22 derp_: does anyone have any suggestions for how to make this code faster? https://gist.github.com/1047149

22:24 gfrlog: derp_: welp...

22:24 you could take advantage of the laziness of (filter)

22:24 you don't need to run through the whole thing to know whether or not it's empty

22:24 at least not every time

22:24 so (zero? (count ...)) can be replaced with (empty? ...)

22:24 derp_: what do you mean?

22:24 ah

22:25 Scriptor: derp_: a lot of euler eventually relies on more mathematical tricks to be faster

22:25 gfrlog: it's not just to make the code slightly simpler, it really will be better

22:25 Scriptor: maybe Sieve of Eratosthenes will help? http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

22:25 derp_: really? huh, just looking at those functions I would have thought them equivalent in speed

22:25 gfrlog: ,(zero? (count (map println (range 5))))

22:25 clojurebot: 0

22:25 1

22:25 2

22:25 3

22:25 4

22:26 gfrlog: ,(empty? (map println (range 5)))

22:26 clojurebot: 0

22:26 1

22:26 2

22:26 3

22:26 4

22:26 gfrlog: crap dangit those chunks

22:26 derp_: wow, yeah it's a lot faster now

22:26 gfrlog: ,(empty? (map println [0 1 2 3 4]))

22:26 clojurebot: 0

22:26 1

22:26 2

22:26 3

22:26 4

22:26 gfrlog: augh

22:26 Scriptor: gfrlog: try a local repl first

22:26 gfrlog: Scriptor: but I'm never wrong!

22:26 Scriptor: especially for code that prints multiple lines :)

22:27 derp_: so I guess empty? is smart and returns no after checking the first item

22:27 gfrlog: Scriptor: and it wasn't supposed to print multiple lines, that was the whole point :P

22:27 derp_: exactly

22:27 I was hoping my println example would just print the first item and be done with it

22:27 Scriptor: gfrlog: but you used println

22:28 gfrlog: Scriptor: yes, I was trying to demonstrate that lazy seqs need not be consumed

22:28 so I expected it to just print 0 and be done

22:29 Scriptor: it gets weird when combined with IO, I think

22:29 gfrlog: well (range) is chunked. I'm not sure why it didn't work with the vector

22:29 I guess vectors are chunked too actually

22:30 Scriptor: this works too:

22:30 gfrlog: ah with a list it works

22:30 tomoj: &(chunked-seq? (seq [1 2 3]))

22:30 sexpbot: ⟹ true

22:30 Scriptor: (empty? (map #(* % %) (range 10000000000)))

22:30 gfrlog: ,(empty? (map println '(1 2 3 4 5)))

22:30 clojurebot: 1

22:30 Scriptor: gah

22:30 ,(empty? (map #(* % %) (range 10000000000)))

22:30 clojurebot: java.lang.ExceptionInInitializerError

22:30 gfrlog: Scriptor: yeah I tried it with 200 and noted it went up to 31

22:30 Scriptor: ,(empty? (map #(* % %) (range 10000000)))

22:30 clojurebot: false

22:31 gfrlog: derp_: so my last println example is what I was going for :)

22:31 but it doesn't matter since you already understood what was going on

22:34 technomancy: justinlilly: did you want to announce that vagrant image on the seajure list?

22:34 derp_: gfrlog: thanks again

22:34 technomancy: or was there more to tidy up first?

22:34 gfrlog: derp_: np

23:03 daaku: is there some syntax that says "put the elements of a seq here" -- something along the lines of ** in python?

23:04 or rather * (single star) in python, not double star

23:04 amalloy: ,`(1 2 ~@[5 4])

23:04 clojurebot: (1 2 5 4)

23:04 daaku: cool

23:05 ah, i need to use a macro

23:05 amalloy: no. depends what you want to do

23:05 daaku: i see, let me throw up a pastie with a small example

23:09 amalloy: but note that i did that without a macro. just the backtick

23:11 scgilardi: I don't know Python's *. wondering if clojure.core/apply is... applicable here.

23:12 islon: I'm creating a clojure library with lots of name clashs with clojure.core, what should I do? Change my function names or advert my users that they should use import the functions with fully qualified names namespace/function?

23:13 technomancy: islon: are your names parallel to the core ones?

23:14 islon: no, they have completely different meaning

23:14 technomancy: I'd try to come up with distinct names then

23:15 one or two here and there is not a big deal (things like get), but you don't want people to look for connections where they aren't there

23:16 scgilardi: if they load your library with (:require [some.really.long.lib.name :as isl]) they can call your functions with calls like isl/concat , isl/reduce , etc. (and I agree with technomancy about different names being desirable)

23:17 islon: yeah I dont know what to do, i didn't want to change (next :tuesday) to (next-date :tuesday), some name really are meaningfull in my context

23:17 *some names

23:17 amalloy: islon: (after :tuesday)

23:17 but i guess that has meaning too

23:17 islon: yes, next is more friendly

23:20 and (-> (january) (first :monday)) is intuitive too, i don't want to change first (nor last) to a less intuitive/friendly name

23:24 daaku: amalloy: sweet, i got it to work using ` ~ and @ -- thanks!

23:28 amalloy: daaku: scgilardi is right though, this problem is often asked by people who don't realize that what they want is apply

23:29 daaku: amalloy: i don't think apply would work in this case -- here's what i have working now: https://gist.github.com/ae25ce5f35e74c0357e0

23:30 i'm a clojure noob, so any suggestions welcome :)

23:31 amalloy: daaku: ##(let [thing-to-add '(a b c)] (into [:div {:class "test"}] thing-to-add))

23:31 sexpbot: ⟹ [:div {:class "test"} a b c]

23:31 technomancy: islon: succ for successive tuesday?

23:31 daaku: amalloy: ah, i see. lemme try it out

23:33 amalloy: cool, much simpler

23:33 amalloy: daaku: but keep the ~@ approach in mind; it's more flexible

23:33 and easy to forget

23:33 islon: technomancy: it's an option but it's not better than next, and what about first, last, second, set, sould I change all of them?

23:33 *should

23:34 technomancy: what's "first" mean? counting from 1 anno domini?

23:34 daaku: amalloy: yep, will do

23:34 islon: no, the first day of week like (-> (january) (first :friday))

23:35 technomancy: (-> (january) (fridays) first)

23:35 by which I mean clojure.core/first

23:35 islon: make your functions work in terms of seqs

23:36 then you don't need your own versions

23:37 islon: hmmm... maybe it's a good idea, I was thinking in terms of date.js (shich is very friendly and intuitive)

23:37 technomancy: well, js has a crappy sequence library. we can do better. =)

23:37 islon: but I should do a more "clojurish" version

23:38 technomancy: you're right, thanks =)

23:38 amalloy: (inc technomancy)

23:38 sexpbot: ⟹ 10

23:39 daaku: (inc amalloy)

23:39 sexpbot: ⟹ 12

Logging service provided by n01se.net