#clojure log - Jul 04 2009

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

0:00 jackdempsey: speaking of offlining

0:00 any there any well vouched for solutions for small simple db solutions

0:01 like, i've used sqlite before, and can be useful in certain cases

0:01 just wondering if there's anything idiomatic or preferred

0:01 Knekk: how simple?

0:01 key/value?

0:01 jackdempsey: sure

0:02 Knekk: bdb is good

0:02 jackdempsey: something that you can install in a few minutes and quickly store things/retrieve them......i'm familiar with a variety of solutions, but not used to connecting to them from clojure

0:02 ok

0:02 Knekk: memcachedb is also nice

0:02 jackdempsey: yeah

0:03 looks like there's some driers for sqlite

0:03 will have to check that out as well

0:03 thanks Knekk

0:03 Knekk: speaking of which, maybe I'll use memecachedb for offlining.

0:09 foox: hi, anyone pls help;

0:10 I have two sub expression inside a Let; The second expr evaluates before the First; How can I overcome this?

0:10 Knekk: how do you know it evaluates first?

0:11 foox: I was not getting result. So I added println in the first expr;

0:12 The second expr displays a JFrame;

0:12 after displaying the JFrame; the Println in the first expr printing...

0:13 Knekk: foox: do you know about lazy-seq ? They won't evaluate until needed

0:13 foox: yes, My first expr is doseq

0:14 Knekk: then it might help if you show some code

0:19 foox: Knekk: pasted here : http://paste.lisp.org/display/82989

0:21 in that I'm just trying to fill a TimeSeries object and display it with JFreeChart

0:22 Knekk: did you try wrapping with (do ... ) to make sure they are called sequentially?

0:23 I am pretty new at this myself, so I am not sure I am helping at all

0:24 ykphuah: can i use clojure to make classes in lisp that java classes use?

0:26 foox: Knekk: do didn't help me out.

0:27 Knekk: foox: someone more experienced might know. Sorry

0:28 foox: Knekk: ok thanks.

1:00 Lau_of_DK: Good morning guys

1:01 jackdempsey: morning, whew, you must be in europe?

1:02 Lau_of_DK: Denmark to be exact

1:02 jackdempsey: ah, cool

1:02 Lau_of_DK: Why?

1:02 jackdempsey: oh, no reason, was just thinking its 1am here

1:02 about time for sleep

1:02 (washington, dc)

1:03 just trying to figure out some simple java stuff

1:03 was looking to do some stuff with JSON

1:03 Lau_of_DK: Yes that can be painful at 1 am :)

1:03 jackdempsey: found this collection of classes

1:03 no kidding :-(

1:03 i thought i'd be smart and package up the .java files in a jar

1:03 then import them

1:03 but i'm doing something stupid

1:03 Lau_of_DK: hehe

1:04 I remember one such night - I asked Cemerick to take a look, I couldnt work it out - We spent 2.5 hours debugging the stuff over IRC... painful

1:04 jackdempsey: ha

1:04 i think this is simpler

1:04 i'm just so out of practice with java

1:04 is it common to create a jar by doing jar cf json.jar json/*.java

1:05 or do i need to compile those java files first perhaps

1:06 Lau_of_DK: You should make a build.xml which describes the project, and then ant build it. If you need inspiration, you could have a look at ClojureQLs build.xml, just dont get distracted by the Ivy references

1:08 jackdempsey: hmm

1:08 ok, what are my options for going simpler than that....basically, i'm surprised this person didn't jar up those java files.....but if i want to just include a class straight away

1:08 as long as its in the path i should be able to use import right?

1:09 Lau_of_DK: I guess in principle you could run javac on every java files, giving you the class file, and then you could zip it to a jar, lemme see if I can find a link

1:10 http://www3.ntu.edu.sg/home/ehchua/programming/java/J9d_Jar.html

1:10 That might help you

1:11 jackdempsey: haha, yeah i'm doing that right now :-)

1:11 Lau_of_DK: I would go for the build.xml

1:12 foox: is there any doc regarding working with side-effects & clojure?

1:12 Lau_of_DK: (doc doseq) ? :)

1:16 jackdempsey: ah, don't know how i missed this: http://github.com/danlarkin/clojure-json/tree/master :-)

1:17 Lau_of_DK: Yea Dan's a good guy - I've also learned that when it comes to web-technologies, Blackdog is always the first guy to get something running - Look him up, either on Github or on Pastebin

1:17 jackdempsey: blackdog, ok cool, don't recognize

1:18 Lau_of_DK: He sent me a Clojure/Servlet/JSON/JQuery example about a year ago I think

1:21 jackdempsey: ah ok cool

1:28 foox: Lau_of_DK: thanks

1:29 Lau_of_DK: Did it help?

1:30 foox: yes, it works; but i dont know i'm doing it in the right way. I will paste the code

1:31 Lau_of_DK: k

1:31 foox: http://paste.lisp.org/display/82992

1:32 Lau_of_DK: The first doseq [] - Is that just to keep it going ?

1:33 foox: without that it didn't work

1:34 I gave it to do the second (.addSeries ts-col ts) and third expr to eval sequentially.

1:34 Lau_of_DK: I dont think you need to forsake the functional approach for this. You could define your ticks as an infinite sequence, and perhaps send off and agent that'll pull out the next record every second or so?

1:34 >>>>>>>>>>>>>

1:34 oops

1:35 foox: I have to add all items in a java object (TimeSeries object)

1:35 hiredman: ~ping

1:35 clojurebot: PONG!

1:36 foox: given in the line -- (.add ts (Second. (first tick)) (second tick))))

1:38 Lau_of_DK: (map #(.add ts (Second. (first %)) (second %)) ticks), and then its a seq

1:39 foox: it will be a lazy-seq? ??

1:39 Lau_of_DK: Yep

1:40 hiredman: map is lazy

1:40 foox: so the ts object would have not been affected, right??

1:40 Lau_of_DK: (first seq) = ts is affected once, (take 5 seq) = ts is affected 5 times, and so on

1:40 (count seq) = it runs ad infinity

1:41 foox: ts is not a list object. it is a custom java class (TimeSeries)

1:42 Lau_of_DK: Sure

3:29 unlink1: Is lazy-cat new?

3:31 And how is it materially different from concat?

9:10 powr-toc: I'm struggling to get a multimethod to dispatch on the values of a string

9:13 lisppaste8: powr-toc pasted "multi method dispatch on string value?" at http://paste.lisp.org/display/83007

9:13 powr-toc: any ideas how to get it working?

9:15 lisppaste8: powr-toc annotated #83007 "At the REPL" at http://paste.lisp.org/display/83007#1

9:18 JAS415: hmm

9:18 powr-toc: It returns a NullPointerException, which I think can be fixed by using a :default ... but the dispatch then only ever uses the default

9:18 fullets: It works for me if you use a real fn instead of using the callable map

9:19 I notice one of the optional arguments to defmulti is a map - is it perhaps misinterpreting that argument?

9:20 In fact, how about (defmulti testmulti "" {} { "FOO" :foo }) etc

9:21 powr-toc: Cheers

9:21 that works

9:22 fullets: You may be able to omit the empty docstring too

9:23 Chouser: fullets: good catch. Does seem a bit unfortunate though, doesn't it?

9:23 powr-toc: yeah you can... my bad... should have seen the attr-map

9:24 Chouser: it's not a problem with defn because in that case you use def which doesn't support an attr-map

9:36 Chousuke: hm

9:36 the --patience switch to git diff/format-patch produces much more readable diffs :P

9:42 fullets: Chouser: something like changing the first binding of m in defmulti to (if (and (map? (first options)) (second options) (not (map? (second options)))) ...) would de-unfortunate it, but seems awfully un-clojurey

10:42 Chouser: fullets: hm, I dunno. That seems pretty reasonable to me.

11:14 jackdempsey: hey all, is this the most common way to do a val[:foo] || "test" type of construct?

11:14 (or (y :namebar) "Baz")

11:28 Chouser: jackdempsey: (:namebar y "Baz")

11:28 jackdempsey: ahh, yeah i thought there was a quicker way like that. awesome, thanks!

11:29 Chouser: that form is slightly different in that if the value of y at :namebar exists but is nil or false, it'll return that actual value not "Baz"

11:38 jackdempsey: hmm

11:38 ahh

11:39 so if the key is there

11:39 yeah

11:39 cool i think this shoudl work fine, thx again

13:31 something: I'm on mac osx using aquamacs, I noticed when I use test-is and run-tests doesn't show me the results.

13:35 so in order for me to see the results I have to eval *test-out*, on my other machine (ubuntu) it outputs to repl.

13:38 drewr: something: Have you restarted your JVM to make sure?

13:39 something: drewr: yes, I have, not sure what's going on here.

14:25 jackdempsey: so if i had a ref like this (def DB (ref {:channels #{}, :subscribers #{}}))

14:25 and i'd like to add elements to the :channels set

14:26 i'm stumped at how to reach inside...(alter DB conj {:channels id}) isn't working quite the way i'd like

14:26 any tips?

14:29 Chousuke: hmm

14:29 jackdempsey: ah

14:29 Chousuke: jackdempsey: (alter *db* update-in [:channels] conj channel)

14:29 jackdempsey: (alter DB conj {:channels (conj (@DB :channels) id)}))

14:29 ahh

14:30 cool, my janky way works it seems, but thought htere must be a nicer way to do it

14:30 Chousuke: *db* being more idiomatic naming than DB

14:30 jackdempsey: k, gotta learn update-in

14:30 yeah, nice, thank you

14:30 Chousuke: jackdempsey: there's also assoc-in and dissoc-in

14:30 jackdempsey: nice, update-in is perfect

14:30 ah ok

14:32 yep perfect

14:48 mauritslamers: question: I am trying to learn clojure by porting an application I wrote in a few other languages. For this app I need to have a function that works on a list of options and returns all valid routes through those options. Every option has a :from and :to keyword...

14:48 I feel I could use a kind of double reduce action, but my imperative mindset is playing up constantly :)

14:50 any ideas?

14:50 Chousuke: are they loopless? :/

14:51 mauritslamers: Chousuke: yes

14:52 they are a model of a movement in time

14:52 Chousuke: try solving a subproblem first: return a sequence of a single route

14:53 mauritslamers: That is what I have been trying to do, but I have no clue on how to do that non-imperatively...

14:53 the function I wrote are constantly returning nil :)

14:54 Chousuke: can you pastebin some code?

14:54 mauritslamers: yep, moment...

14:55 lisppaste8: mauritslamers pasted "route-detection" at http://paste.lisp.org/display/83016

14:55 mauritslamers: That function is intended to be used in a reduce function

14:56 as (reduce filterfunc list-with-lists-of-items)

14:56 Chousuke: hmm

14:56 mauritslamers: but this func only returns the entire first list with items without any filtering

14:59 If I would write it imperatively, I would take the first list, process it one by one by walking through the rest of the list, taking the previous to element as from element and if it fits push it to the result array

14:59 Chousuke: I really can't visualise even that :P

14:59 mauritslamers: hehe :)

15:00 Chousuke: how is your data structured?

15:00 mauritslamers: I will add an example of the source data and the result i'd love to have to the pastebin

15:03 Chousuke: maybe you could restructure it to use sets?

15:03 for every item, you would have a set of from and to items

15:04 lisppaste8: mauritslamers annotated #83016 "route-detection" at http://paste.lisp.org/display/83016#1

15:04 Chousuke: you'd have to give them unique ids and pt them in a map or something though

15:04 mauritslamers: the issue is that one item is both it's own from and to

15:04 and I cannot split them

15:05 the data is a kind of vector

15:06 Chousuke: that example is even more confusing :/

15:06 mauritslamers: sorry about that :)

15:06 Chousuke: why do you have two sequences of the same data?

15:07 mauritslamers: because the real source data is a ratio and these two sequences of the same data are options for that specific ratio

15:08 Chousuke: I'm sorry, I don't understand this problem at all :P

15:08 mauritslamers: these sequences are the same now because there is a succession of the same ratio

15:09 I cannot go into details too much, but let's image there is a drawing

15:09 the drawing exists of a series of vectors

15:09 these vectors all have more or less the same length

15:10 The input to the application is a set with vector lengths and the app needs to figure out what places in the drawing that sequence of lengths can occur

15:12 so I need to create a kind of function that can reduce all the possible options to a sequence of possible options as they occur in the drawing

15:13 Chousuke: I don't get that at all :P

15:13 mauritslamers: it is a kind of patternmatching?

15:14 :)

15:14 Chousuke: it sounds like you need to find the possible paths from A to B in a graph but hm

15:19 mauritslamers: Chousuke: that is more or less the same problem indeed

15:25 Chousuke: (fn adjacents [node] (set (map adjacents (filter #(= (:to node) (:from %)) *nodelist*))))

15:25 should give you a set of sets of sets of something until ???

15:26 the filter must be made such that eventually it returns nil

15:26 not efficient, but should work :P

15:28 actually

15:29 you'll need (if-let [adjs (seq (map adjacents ...)] (set adjs) node) to actually get useful output

15:29 mauritslamers: ok, thanks!

15:30 Chousuke: but this is all done without testing

15:30 so it might loop infinitely.

15:30 mauritslamers: np :)

15:31 I am first trying to get what you are doing exactly and then write my own code

15:31 thanks!

15:31 Chousuke: you might want to return {node (set ...)} too

15:32 but the idea is to build a hierarchy of sets so that the first set contains all the nodes that you can access from the first node, along with THEIR sets of nodes accessible from them

15:38 powr-toc: What happens if you recur inside a multi-method, do you recur to the multi dispatch, or do you just recur to the local defmethod?

15:39 hiredman: the local

15:40 powr-toc: I'm guessing it just recurs to local method, as otherwise clojure's recur would support mutual recursion, right?

15:40 cheers hiredman

15:40 hiredman: hello

16:55 Knekk: can I (make-array ) with a clojure struct?

16:56 Chousuke: you want an array of maps?

16:56 Knekk: yes

16:56 or refs to structs

16:56 Chousuke: why not just use a vector?

16:57 Knekk: I am trying to figure out what's most efficient

16:57 Chousuke: vectors are a lot easier to use than arrays

16:59 duncanm: and vectors can always turn into arrays, right? so that answers the question

17:00 Chousuke: no they don't

17:00 duncanm: oh?

17:00 Chousuke: they're persistent and immutable, so they can't.

17:00 duncanm: ahhhh

17:01 Chousuke: there's an optimised version though, if you only create the vector and never conj on it.

17:01 but that's an implementation detail :)

17:01 Knekk: I need mutable data.

17:01 Chousuke: use a ref to a vector.

17:01 Knekk: I am

17:01 Chousuke: and is it too slow? :/

17:02 Knekk: don't know. Keep blowing the heap :)

17:02 Chousuke: probably not the ref's fault.

17:02 Knekk: no

17:03 Chousuke: most likely you're holding onto a big seq somehwere.

17:03 Knekk: it's me holding on to the vector of refs I create

17:04 not sure how to create the vector and then reference it later without forcing it to instantiate right away

17:04 Chousuke: how many items does the vector contain? :P

17:04 millions?

17:05 Knekk: yeah

17:05 Chousuke: hmm.

17:06 what does it contain?

17:06 Knekk: just refs to a simple struct for now

17:07 Chousuke: you probably don't want millions of refs

17:07 Knekk: that's what I am figuring out

17:07 Chousuke: instead you could have a single ref to a huge vector of structs.

17:07 Knekk: since it's all mutable data I am probably gonna have to come up with a method to offline pieces of it

17:08 Chousuke: even with millions of items, a conj to a clojure vector only takes ~20 or so iterations.

17:09 it's O(log_32)

17:09 unlink1: O(1)?

17:09 Chousuke: not O(1)

17:09 but close enough :)

17:10 unlink1: O(log n)?

17:10 what is O(log_32)?

17:10 Chousuke: no, O(log_32 n) :P

17:10 unlink1: oh

17:10 that's the same complexity as O(log n) ;-)

17:11 Chousuke: except it grows a *lot* slower.

17:11 unlink1: A constant factor slower.

17:11 Chousuke: uh, no.

17:11 unlink1: (1/log 32) slower

17:12 log32(n) = log(n)/log(32)

17:12 1/log(32) is a constant factor

17:12 Chousuke: hm, right

17:13 unlink1: compared to say, log(log(n))

18:12 dcnstrct: has anyone tried using clojure to program Android apps ?

18:12 I'm not sure if it's possible or not

18:13 hiredman: ~google clojure android

18:13 clojurebot: First, out of 9270 results is:

18:13 Clojure and Android - Clojure | Google Groups

18:13 http://groups.google.com/group/clojure/browse_thread/thread/cf9c928f0027836a

18:14 dcnstrct: hrm... so the answer is no

18:14 sux

18:15 there is a Java bytecode -> Dalvik bytecode compiler.. but no way to support the runtime compilation used

18:15 by Clojure

18:16 O well

18:23 jackdempsey: hey guys, i'm not sure if i'm just expecting something mutable here where its not, but i would think that the second conj call here would add to the set and we'd have two values in there

18:23 http://gist.github.com/140751

18:23 am i doing it wrong?

18:39 Chouser: jackdempsey: right, update-in is just like assoc: takes an immutable map, returns a new immutable map.

18:42 jackdempsey: ok so the only reason i was able to use update-in before was on account of the alter and STM features

18:43 ah

18:43 yeah just inspected foo

18:43 {:a 1, :e {:b 2, :c #{}}}

18:43 makes sense

20:40 krumholt: what is wrong here?: (defn handle-client [counter]

20:40 (Thread/sleep 1000)

20:40 (dosync (alter counter inc))

20:40 (send-off *agent* #'handle-client counter) nil)

20:57 arbscht_: krumholt: when send-off calls a function, the first argument is the state of the agent, followed by your other args

21:00 krumholt: arbscht_, thanks

23:00 Chouser: ha. Just used javadoc on a non-builtin class. Worked perfectly.

23:01 It's like magic.

Logging service provided by n01se.net