#clojure log - May 30 2011

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

1:49 seancorfield__: evenin'

1:49 i have a string and want to load and execute a specific function from a namespace based on the string

1:50 basically i want (stringA/stringB 42) to execute given two arbitrary strings

1:54 i can get a symbol for the namespace and require that

1:55 but i can't figure out how to get the function as a qualified symbol

1:55 amalloy: seancorfield__: resolve

1:55 seancorfield__: ah, bingo! resolve

1:55 jinx

1:55 but thanx

1:56 amalloy: (PS it won't work for *any* two strings like if stringA is 42. but you knew that)

2:00 seancorfield__: i'm porting my CFML MVC framework to Clojure

2:02 it auto-maps /uri/routes to controllers and methods so i'm just playing with ring and figuring out how to calls methods in namespaces based on routes without predefinition

2:08 amalloy: seancorfield__: have you considered looking at geni's new product, wakeful?

2:09 it's still very new, but i think it already does what you describe

2:09 https://github.com/ninjudd/wakeful

2:11 seancorfield__: that's part of what FW/1 does but not enough :)

2:11 amalloy: sure, of course you want more for a full mvc. but reuse or steal some of it

2:11 seancorfield__: i'll look at the source code for "ideas" :) thank you!

2:22 interesting approach...

2:22 why does it use ns-resolve instead of plain resolve?

2:23 (or should i just go read the docs :) )

2:23 amalloy: &(doc ns-resolve)

2:23 sexpbot: java.lang.SecurityException: You tripped the alarm! ns-resolve is bad!

2:23 amalloy: ,(doc ns-resolve)

2:23 clojurebot: "([ns sym]); Returns the var or Class to which a symbol will be resolved in the namespace, else nil. Note that if the symbol is fully qualified, the var/Class to which it resolves need not be present in the namespace."

2:23 amalloy: ,(doc resolve)

2:23 clojurebot: "([sym]); same as (ns-resolve *ns* symbol)"

2:23 seancorfield__: ah, ok

2:24 i'll need ns-resolve to make fw/1 work then... thanx...

2:24 amalloy: seancorfield__: no, you could do it with resolve if you wanted

2:24 by reconstituting a single symbol out of two strings, as you were doing

2:25 in fact because ns-resolve wants a namespace, not a string/symbol *denoting* a namespace, plain resolve might be more convenient for your needs. one enver knows

2:26 seancorfield__: 'k thanx... i'll have to keep pushing ahead and see how things work out

2:27 my biggest question mark right now is what to do about views... CFML allows code in the HTML template (which I don't like much) but i'm not sure i like enlive's complete separation either

2:27 so i haven't figured out how that should pan out yet

2:52 thorwil: i copied my project, removed enlive to replace it with hiccup. did "lein clean" and "lein deps". cleared classes.

2:52 now i get fun stuff like "java.lang.NoClassDefFoundError: appengine_magic/services/datastore/EntityProtocol (models.clj:39)"

2:52 or "java.lang.ExceptionInInitializerError (NO_SOURCE_FILE:0)"

2:57 nevermind, after clearing classes again, now it works, so i must have had the order wrong

2:59 if only things would be rebuild from scratch if they have to, automatically

3:05 amalloy: thorwil: if that problem were as simple as you make it sound, i'm sure it would work perfectly already

3:08 thorwil: what, (when have-to rebuild) doesn't do it? :)

5:53 with this short defhtml, http://paste.pocoo.org/show/397592/ hiccup does not produce the <dt>

5:53 what am i overlooking?

5:55 i already confirmed that l and p have the expected values

6:04 so it returns only the last vector, but i can't put [] all around it :/

6:04 hoeck: thorwil: that let only returns the last vector [:dd ]

6:05 thorwil: why not?

6:05 thorwil: because java.lang.IllegalArgumentException: [:dt "Updated:"] is not a valid tag name. (NO_SOURCE_FILE:0)

6:09 hoeck: can you somehow change the way hiccup handles this? e.g. instead of using a the defhtml macro write a function that returns a vector of tags and insert this into your resulting html tree?

6:11 thorwil: looking at the code, it sould work when you return a seq or list of tags

6:12 thorwil: http://paste.pocoo.org/show/397597/

6:13 ah, screw that, I'm wron

6:13 g

6:14 thorwil: no, works

6:14 thanks, hoeck

6:15 and here i was about to create a defn only to call the defhtml ...

6:16 hoeck: defhtml just creates a fn wrapping the body in a (html ...) form

7:25 ilyak: Hi *

7:25 I have a (fn

7:25 How do I call itself recursively?

7:25 (I know about Y combinator but that's not the point)

7:26 Specifically, I have a (fn ([arg] (do-something-with arg)) ([] (recur nil))) and it doesn't work

7:26 How can I recur to another arg-branch? I thought I can

7:27 raek: ilyak: you can name the anonymous function like this: (fn f [...] ...). f will refer to the function itself in the scope of its body

7:27 ,((fn f [] f))

7:27 clojurebot: #<sandbox$eval3012$f__3013 sandbox$eval3012$f__3013@1acb7>

7:28 lucian: raek: i love that neat trick. more languages should have it

7:28 raek: ,((fn f [n] (when (pos? n) (cons n (f (dec n))))) 5)

7:28 clojurebot: (5 4 3 2 1)

7:46 ilyak: Is it possible to make a finite lazy seq from function?

7:47 Like with (repeatedly), but end the sequence when f returns nil

7:49 hoeck: ilyak: (take-while identity (repeatedly ...))

7:50 ilyak: hoeck: Yeah, thanks, figured it out

9:51 SergeyD: hi! Is there an opposite of "{:keys [key1 key2]} my-map" destructuring? I mean the way to rewrite (merge map1 {:key1 key1 :key2 key2 :key3 key3}) to make it shorter, i.e. not to repeat keyX twice

10:03 raek: SergeyD: not really. the names of the locals are not available at runtime.

10:04 SergeyD: so that means no function can do it, but in fact a macro could

10:05 also, (merge m {:a 1, :b 2}) is more commonly written as (assoc m :a 1, :b 2}

10:05 SergeyD: raek, yes, I mean a macro or the reader functionality.

10:05 raek, thanks, I have missed the fact that assoc takes multiple key-value pairs.

10:07 raek: SergeyD: (defmacro make-map [& names] {:pre (every? symbol? names)} (zipmap (map keyword names) names))

10:08 SergeyD: raek: thanks :)

10:08 raek: this will of course only work if the local variables have exactly the same names as the keys

10:09 so (make-map (inc a) (inc b)) doesn't make sense

10:10 (hrm, apparently preconditions don't work in macros as I though...)

10:11 SergeyD: And I have just thought what a cool way to use preconditions )

10:21 sn197: hi there, are there any cases where (func arg) does not produce the same result as (-> arg func)

10:23 for example "(-> [1 2 3 4 5 6] (partial take 2))" yields a different result than "(-> [1 2 3 4 5 6] (partial take 2))". Why?

10:25 manutter: sn197: re-read what you just typed :)

10:25 SergeyD: sn197: did you wrote the same code twice?

10:25 manutter: you mean the -> version produces a different result than ((partial take 2) [1 2 3 4 5 6]) ?

10:25 sn197: oops, I meant that the result is different compare to "((partial take 2) [1 2 3 4 5 6])". Bad paste job

10:26 manutter: Ok, your question makes more sense now

10:26 but those should produce the same result

10:26 sn197: I agree but they don't. I am puzzled

10:27 * manutter is firing up jark now

10:27 raek: sn197: (-> [1 2 3 4 5 6] (partial take 2)) expands to (partial [1 2 3 4 5 6] take 2)

10:28 SergeyD: second that :)

10:28 manutter: Heh, that's subtle, but I see it now

10:29 raek: -> does not work with function and applications per se, it just rewrites expressions

10:29 * manutter is still wrapping his mind around the intricacies of macro expansions

10:29 sn197: aha, one has to be careful then because it's not obvious

10:29 manutter: Indeed

10:30 sn197: thanks guys, off to write more clojure code...

12:46 ilyak: Suppose I have defrecord-ed org.foo.Record

12:46 How do I get :Record from the instance of that?

12:53 (keyword (.. r getClass getSimpleName))?

12:53 Is there a less pityful way?

12:53 opqdonut: that seems like a good solution IMO

12:56 ilyak: I have (defmulti muz-ru-element identity)

12:56 Then I try to run (muz-ru-element [:foo :bar])

12:56 and it fails with "Wrong number of args (2) passed to: core$identity"

12:56 Is it a bug or feature that it explicitly destructurizes my list? How to combat?

13:03 (defmethod syntax is strange

13:04 :default accepts default dispatch value

13:04 why not the default dispatch fn?

13:10 Is there a function that returns the first arg and does nothing else?

13:18 cemerick: ilyak: if your fn accepts rest args, then use first (fn [& args] (first args))

13:18 which is equivalent to #(first %&) if you prefer the literal syntax

13:19 ilyak: cemerick: My form was (fn [x & xs] x)

13:19 cemerick: sure, same thing

13:22 danlarkin: dakrone: good news! pull request merged

13:23 dakrone: danlarkin: excellent!

15:28 bpr: I'm writing a protocol, and I'd like one of the types i'm extending to be function. In the extend form what do I put for the type?

15:30 gfrlog: bpr: you're talking about one protocol inheriting from another?

15:30 bpr: well, i've written a protocol, and I want to extend some existing types to use it

15:31 and one of those types is function

15:31 gfrlog: I know IFn is the clojure interface for functions

15:31 you want anything that is an IFn to implement your protocol?

15:31 bpr: thanks, that should do

15:31 gfrlog: okeedokes.

15:31 bpr: yes

15:31 gfrlog: ,IFn

15:31 clojurebot: java.lang.Exception: Unable to resolve symbol: IFn in this context

15:31 gfrlog: ,clojure.lang.IFn

15:31 clojurebot: clojure.lang.IFn

15:32 bpr: thank you

15:32 gfrlog: yep

15:32 bpr: that's what I was clumsily trying to ask :-p

15:33 gfrlog: I just wish I understood protocols well enough to know what you're doing :)

15:35 bpr: yeah, i had to watch a number of talks about protocols before I rly got it. Stuart Halloway has a good one

15:35 iirc it's titled "Solving the Expression Problem"

15:36 googling for "clojure expression problem" should bring it up. It's on vimeo

15:36 gfrlog: the talk called "Protocols"?

15:36 bpr: maybe

15:36 let me find the link

15:36 gfrlog: $google clojure expression problem vimeo

15:36 sexpbot: First out of 200 results is: Clojure 1.2 Protocols on Vimeo

15:36 http://vimeo.com/11236603

15:37 gfrlog: that is what I'm looking at

15:37 kencausey: clojure.blip.tv

15:37 bpr: http://vimeo.com/11236603

15:37 yup, u got it

15:38 gfrlog: cool, thanks. I'm on it.

15:44 Bronsa: can someone explain me why this is happening? http://sprunge.us/gMQT?cl

15:48 Chousuke: Bronsa: .. is a special form and doesn't work like that.

15:48 it requires a class name as the first argument

15:49 Bronsa: so, in order to do that the only way is to create a macro?

15:49 Chousuke: Bronsa: java Class instances have .newInstance methods

15:50 Though if it's specifically the EMPTY constant you need, then I'm not sure what you need

15:50 :P

15:57 gfrlog: ,(doc sort)

15:57 clojurebot: "([coll] [comp coll]); Returns a sorted sequence of the items in coll. If no comparator is supplied, uses compare. comparator must implement java.util.Comparator."

15:57 gfrlog: If I want to write a fn to pass in as a java.util.Comparator, I should use proxy?

16:41 technomancy: gfrlog: nah, just pass the function to clojure.core/comparator

16:48 gfrlog: ,(doc comparator)

16:48 clojurebot: "([pred]); Returns an implementation of java.util.Comparator based upon pred."

16:48 gfrlog: that's some weak docs right there

16:51 had to look at the source code to confirm that it meant what I thought it did

17:26 imade: I'm having difficulties with eval, please take a look https://gist.github.com/999502

17:27 billy_: can't seem to figure out why this is saying class not found - http://pastebin.com/xQRJcREz

17:35 imade: billy_: did you do 'lein deps' ?

17:37 billy_: imade: yup

17:37 raek: imade: eval evaluates at the top level, so it can't use local variables

17:37 imade: are you sure you actually need eval here?

17:37 imade: how else can I dynamically build up such a for loop to yield the desired result

17:38 raek: imade: a macro?

17:38 imade: ookey, I need to go read a tutorial about macros then, thanks :)

17:40 billy_: hmm

17:40 apparently the jar lein pulled in is no good

17:40 wierd

17:41 imade: can clojars find jcurses 1.0.0 ?

17:41 raek: billy_: maybe you could try this version: http://www.jarvana.com/jarvana/archive-details/com/baulsupp/kolja/jcurses/

17:41 billy_: i found a working version

17:41 raek: jcurses is a java project, right?

17:41 billy_: yea

17:41 jcurses 1.0.0 is in clojars

17:42 it doesnt appear to work though

17:42 raek: then the authors are probably not pushing it to clojars

17:43 leiningen accesses the central maven repo too, where most of the java libs are

17:43 technomancy: billy_: I think it's intended to be used with native-deps rather than regular :dependencies

17:43 there is probably some weird jar-in-a-jar stuff going on

17:43 billy_: technomancy: hmm i didnt know there was such a thing, ill try that

17:44 technomancy: billy_: it's going to be merged into Leiningen 1.6, but that's still a work in progress

17:45 there aren't any good conventions for distributing native libraries on the JVM yet

17:52 billy_: technomancy: thanks for the help, clears up all the confusion regarding that

17:59 aav-: $seen lpetit

17:59 sexpbot: lpetit was last seen quitting 5 days and 6 hours ago.

18:43 nanarpuss: Curious if anybody knows of a good OAuth library?

19:38 Raynes: nanarpuss: I've used clj-oauth. It's good.

19:42 bdesham: hi all. simple question: I have a list like ((:foo :bar) (:baz :xyzzy)) and I'd like to turn it into (:foo :bar :baz :xyzzy). how can I do this?

19:43 amalloy: &(apply concat [[1 2] [2 3]])

19:43 sexpbot: ⟹ (1 2 2 3)

19:44 darevay: &(flatten [[1 2][2 3]])

19:44 sexpbot: ⟹ (1 2 2 3)

19:44 amalloy: darevay: NO

19:44 darevay: ...which might be too agressive

19:44 * amalloy hates flatten :P

19:44 darevay: enlighten me

19:44 bdesham: amalloy: great, thanks! I knew it had to be something simple

19:44 tomoj: this is amalloy's thing

19:44 amalloy: &(flatten [[[1 2] [3 4]] [[5 6] [7 8]]])

19:44 sexpbot: ⟹ (1 2 3 4 5 6 7 8)

19:45 darevay: which might be what you want :)

19:45 bdesham: darevay: I thought of that but I've actually got vectors in this thing that I need to preserve :-)

19:45 tomoj: it's always the same pattern "I have a list like ...". the question is, _why_ do you have a list like that?

19:45 amalloy: darevay: sure. on rare occasions that is what you want

19:46 darevay: I guess that's true. Now that I think of it, I rarely use flatten.

19:47 bdesham: tomoj: well, if you're curious... I have a vector like [[(:a :b :c) 3], [(:d :e) 5]] and I'd like to turn it into [[:a 3], [:b 3], [:c 3], [:d 5], [:e 5]]

19:47 which I just figured out how to do ;-)

19:47 tomoj: ok

19:47 gfrlog: that looks like a good use case for mapcat

19:47 darevay: Now I at least know how to push amalloy's buttons though :p

19:48 tomoj: my point is just that framing things like "I have this data and want this data" is less likely to lead to enlightenment

19:48 I mean, you learn stuff in getting it done

19:49 but often you'll get better help with more context

19:49 gfrlog: (mapcat (fn [[ks v]] (for [k ks] [k v])) data)

19:50 bdesham: gfrlog: ah, that does exactly what I want! thanks

19:53 gfrlog: cool

20:09 bdesham: tomoj: http://www.perlmonks.org/?node_id=542341

20:25 amalloy: github looks like they'll have their one millionth public gist today. we should have a gist-fest to see if we can get clojure to be the language of that gist

20:26 bpr`: wow, 1 million already? How long have they had gist?

20:26 gfrlog: do they have bot deterrents?

20:26 amalloy: bpr`: dunno. they say they've had 250k or so public gists this year

20:27 https://gist.github.com/gists

20:27 and afaik from looking at the monthly stats, they mean since january, not since last june

20:30 tomoj: given a zipper loc, how do you do a depth-first iteration of the descendants of the loc?

20:31 well, go next until you see right?

20:32 no, need to look up too..

20:36 Frozenlock: Gentlemen, I'm in need of some kind of tutorial. I'm offering 20 BTC (~180$ @ current rate) as a bounty if you can help me. Details here: http://forum.bitcoin.org/index.php?topic=10740.0

20:36 I hope I'll be giving this to one of you soon ^^

20:39 bpr`: BCs are worth $9?

20:40 tomoj: Frozenlock: I have no clue after reading that what you are actually trying to do, other than get a clojure dev environment set up

20:40 Frozenlock: Pretty much yeah

20:41 gfrlog: there are Java libraries for the networking stuff?

20:41 bpr`: is there some site acting as a central market for BC?

20:42 Frozenlock: bpr`: http://bitcoinwatch.com/ for current price. Central market would probably be Mtgox

20:43 tomoj: I have some BACnet devices. I want to be able to interact with them with my LAN.

20:43 There is some java libraries for Bacnet, but I have no clue how to use them

20:43 ...and interact with ethernet with clojure

20:44 Like I said: I`m awful :p

20:45 Was I more clear?

20:45 tomoj: I got that much, I guess the problem was I have no idea how bacnet works

20:46 are you hoping some clojurist will?

20:47 Frozenlock: No, I'm hoping the current libraries are enough - I could be wrong

20:47 bpr`: the bidding price and the asking price are pretty far spread aren't they?

20:49 Frozenlock: It's still small market I would say

20:51 gfrlog: ain't nobody know of a way to get the last-insert-id in clojureql do they?

20:51 it seems surprising that I have no reliable way to create foreign keys :/

21:12 bdesham: is there a built-in function to go from {:a 1 :b 5} to [[:a 1] [:b 5]] ?

21:12 (I have code to do it but wondered if there was already a way in core)

21:13 gfrlog: ,(seq {:a 1 :b 5})

21:13 clojurebot: ([:a 1] [:b 5])

21:13 gfrlog: it's not quite the same thing but likely it's good enough

21:14 depending on what you're doing with the result, you might be able to just use the map

21:14 e.g., ##(doseq [pair {:a 1 :b 5}] (prn pair))

21:14 sexpbot: ⟹ [:a 1] [:b 5] nil

21:15 bdesham: I think seq might work, let me give it a try

21:15 gfrlog: A lot of core functions call seq on their inputs anyhow

21:16 bdesham: yeah, I was using (for [k (keys v)] [k (v k)]), which seems to do the same thing as (seq v)

21:17 gfrlog: yeah. learning clojure is fun because your code keeps shrinking

21:18 bdesham: haha, I'm simultaneously pleased and annoyed when I spend an hour writing a function and then find that the same thing is built into the language

21:18 it happens a lot...

21:19 gfrlog: I've been using clojure for almost two years now and it still happens

21:20 two recent ones are reset! and mapcat

21:22 bdesham: I haven't used atoms yet, but mapcat seems pretty useful

21:23 gfrlog: I don't know how many times I wrote out (apply concat (map #(blargity blarg) mydatas)

21:23 )

21:26 bpr`: i've only just started using clojure. One of the instant pleasure points has been destructuring

21:26 gfrlog: if only it worked with sets

21:26 bpr`: it's *so* usefull. You had to use special forms to do destructuring in CL

21:27 tomoj: bpr`: have you seen moustache?

21:27 amalloy: bpr`: surely not special forms. destructuring-bind must be a macro

21:28 bpr`: how would you want it to work with sets? something like: [foo :foo] #{:foo} ==> (= foo true) and [foo :foo] #{:bar} ==> (= foo false)

21:28 amalloy: yes, it's a macro

21:28 sorry

21:28 tomoj: no

21:29 tomoj: http://gist.github.com/109955 I seem to remember that moustache takes destructuring to an extreme, but looking at the walkthrough I'm not sure that it justifies this memory

21:30 gfrlog: bpr`: I've been doing a lot with undirected graphs, for which I use two-element sets. So something like (let [#{a b} edge] ...) would be nice, where the ordering is undefined.

21:30 tomoj: compared to pattern matching in other languages?

21:30 tomoj: I really don't know anything about pattern matching in other languages

21:31 bpr`: gfrlog: oh, that's neat

21:31 tomoj: enlive does this also to a lesser extent I think

21:31 bpr`: grab a subset real quick...

21:31 tomoj: destructuring is embedded into these little special grammars

21:31 gfrlog: bpr`: in my case it would be the entire set, as it would only ever have two elements. But sure, subsets for bigger sets would be fine.

21:32 tomoj: what, a random subset?

21:32 gfrlog: well at the very least you could just say that the set gets (seq) called on it before destructuring

21:33 I think that would be pretty natural

21:33 tomoj: I see

21:33 gfrlog: so the syntax would be (let [[a b] edge] ...)

21:33 tomoj: that happens to be convenient for minhashing I think..

21:33 gfrlog: eh?

21:33 what minhashing is?

21:34 tomoj: set similarity by taking minimums of hashes of elements in the sets

21:34 except, that would be pretty silly

21:34 you'd just (take n) of the hashes

21:36 gfrlog: ...sure

21:36 so in summary, destructuring is cool, but it could be slightly better.

21:38 tomoj: I think letting the internal order of the set leak out that way would be strange

21:39 for a sorted set it seems to make sense

21:39 gfrlog: but that already happens whenever you pass a set to a function for seqs

21:39 tomoj: right..

21:40 gfrlog: I'm not really asking for special behavior for sets, I'm more wishing that when you try to sequentially destructure something, it gets treated like a seq

21:40 ,(sequential? #{:WHAT})

21:40 clojurebot: false

21:40 gfrlog: rather than that

21:40 tomoj: &(let [[a b c d] (seq (set (range 10)))] [a b c d])

21:40 sexpbot: ⟹ [0 1 2 3]

21:40 tomoj: &(let [[a b c d] (seq (set (range 100000)))] [a b c d])

21:40 sexpbot: ⟹ [0 32768 65536 98304]

21:41 tomoj: yeah

21:49 gfrlog: why does a tweet say that clojure contrib is deprecated?

21:50 amalloy: because it is?

21:50 gfrlog: where will it all go?

21:50 amalloy: as of 1.3 clojure-contrib doesn't exist as a monolithic entity

21:51 the libs get split up

21:51 gfrlog: this primarily has implications for my project.clj file?

21:51 or also the namespaces?

22:26 amalloy: gfrlog: the namespaces are getting renamed

22:26 clojure.tools.xml or something, for example

22:28 gfrlog: I guess the compiler will always check what got missed

23:44 bdesham: what would be an idomatic way to implement the algorithm shown at http://en.wikipedia.org/wiki/Schulze_method#Implementation ?

23:45 there's one pass through a 2-d array, and then another; the results of the second pass depend upon the second pass

23:45 if that makes sense

23:47 bpr`: what do you mean the results of the second pass depend on the second pass? Results of processing element 10 in pass 2 depend on the value of pass 2 for elements 0-9?

23:48 bdesham: bpr`: yes, that's what I was trying to say :-)

23:49 my attempt to implement this used let [p ...] for the first pass, but I'm not sure how to deal with the fact that the array may be changing in the second pass

23:53 http://pastebin.com/taDAQSM8 - my attempt so far

23:57 bpr`: my first impulse is to tell you to make each element a ref and just set it's value. But, that's really just punting... I don't know enough clojure yet to know what the idiomatic way would be

23:57 of course if you were to do that, you'd have to use a mutable data structure

23:59 bdesham: right... I also don't know enough clojure to know whether there's a more idiomatic way

Logging service provided by n01se.net