#clojure log - Jun 27 2010

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

0:00 polypus: all that said, my fantasy is a lightweight gedit/textmate like editor with paredit written in and scriptable in clojure

0:16 itistoday: i think i know why you guys like paredit so much, it's because you stack up your parenthesis instead of using them to specify scope like braces in C

0:17 or rather, i bet that's one of the major reasons

0:32 night!

0:43 TeXnomancy: I know I'm late, but I think the reason people balk at having parens on their own line is that it makes it obvious that you're still counting them manually

0:44 if you just go with the flow and let paredit handle your parens then you don't care how many there are... why waste space on them?

0:45 did they ever get those windows issues figured out?

4:40 quizme: approx. how much memory does it take to deploy ring on a 64-bit Ubuntu box?

5:38 LauJensen: Good morning all

5:39 patrkris: mornin'

5:45 Bahman: Morning LauJensen!

10:40 polypus: ,(= (fn []) (fn []))

10:40 clojurebot: false

10:41 polypus: is that false guaranteed to always be the case?

10:49 Chousuke: polypus: should be, as functions do an identity comparison

10:49 polypus: Chousuke: ty. thought so.

10:51 for a larger datastructure, is it's hash (or whatever is compared in an identity equality), cached?

10:52 i assume so given that DSs are immutable

10:52 Chousuke: Hmm, I'm not sure if Clojure does anything like that

10:58 polypus: mornin all, btw

11:25 mmarczyk: polypus: yeah, hash codes are cached

11:25 polypus: mmarczyk: ty

11:30 systay: I'm having a problem where if I do an action on one item in the seq, everything works fine. when I try to do it on all of the items using map, I get a "org.neo4j.graphdb.NotInTransactionException: No transaction found for current thread". Could it be that clojure is running stuff in multiple threads without telling me about it?

11:39 polypus: systay: probably you are not cosuming your whole seq inside the transaction. try wrapping it in a dorun or doall.

11:40 you can get simlar errors with binding in pure clojure, i got bit by that the other day. won't forget it

11:40 s/cosuming/consuming

11:53 systay: polypus: I solved it by wrapping the function map was running in a transaction. it feels sub-optimal, but speed is not an issue right now. I'll try the doall though

11:57 polypus: systay: yeah probably is suboptimal, try (transaction (dorun (map ...)))

11:58 systay: polypus: but dorun returns nil, right? I think I want doall

11:58 polypus: yeah, if you need the head doall

11:59 systay: polypus: that worked wonders. thanks! :)

11:59 lazy is tricky to wrap my head around

12:00 polypus: systay: np :) once you get bit enough times you won't forget :)

12:05 systay: I love clojure. It's soooo refreshing to work in it, compared to my dayjob...

12:05 polypus: woot

14:34 serp_: does clojure have support for some kind of event system? I would like to somehow register a function with an event and get have it become called when the event is triggered

14:40 Chousuke: serp_: there are watchers for reference types.

14:41 serp_: yes, but that's not exactly what I want.

14:41 I guess I could have a dummy reference for each event type, but that doesn't feel too clean

14:47 semperos: swank/slime confusion

14:47 have very simple hard-coded grammar (copy from Paradigms of Artificial Intelligence Programming in Clojure): http://lisp.pastebin.com/LfRBQFD4

14:48 wrote it as part of a lein project, under src/hardcoded_grammar.clj

14:48 started swank with lein swank from project root

14:48 connected with slime (M-x slime-connect) in emacs

14:48 at repl, did (use 'pai.hardcoded-grammar)

14:49 get normal output for simple functions like (noun) and (article)

14:49 but when I call the (noun-phrase) or (verb-phrase) functions, it's as if the str-utils2 (join) function doesn't work correctly

14:49 output like "aman" instead of "a man"

14:49 if I follow the same process running a simple clojure + clojure-contrib inferior lisp process

14:49 and use my file

14:49 those functions work as expected

14:49 "a man"

14:50 any thoughts? (and apologies for lengthy expl.)

14:58 polypus: what's the advantage of == over = for numbers, performance?

15:01 jcromartie: so I had this latent thing in the back of my mind that was bothering me

15:01 when working in most OOP languages I usually use really long variable names

15:02 but in Clojure one word or one letter is usually fine

15:02 but it bothered me to see such short identifiers

15:02 bobo_: polypus: depends on if you want 2.0=2 to be true or not.

15:02 if i understood it correct

15:02 qbg: jcromartie: Several functional languages do that

15:02 jcromartie: so I had this cognitive dissonance because it's been ingrained that "identifiers should be more descriptive"

15:03 but the thing that I realize is: in FP, identifiers describe simpler things

15:03 like simple values

15:03 polypus: serp: see http://richhickey.github.com/clojure-contrib/dataflow-api.html

15:04 serp_: also http://github.com/gcv/dgraph

15:04 serp_: also http://github.com/straszheimjeffrey/dataflow

15:05 ,[(= 2.0 2) (== 2.0 2)]

15:05 clojurebot: [true true]

15:05 polypus: bobo_: no diff

15:05 serp_: polypus: was those links really for me?

15:07 polypus: serp_: yeah, may be of use depending on your problem

15:11 serp_: I don't understand how it is related, but I'll have a look. thanks

15:13 polypus: serp_: (let [registered (atom [])] (defn register [f & args] (swap! registered conj [f args])) (defn fire [] (doseq [[f args] @registered] (apply f args))))

15:21 serp_: polypus: that would work. I wonder though, since it's not built-in, if I am trying to force clojure into doing something it doesn't want to do

15:23 I'll ponder some more..

16:05 systay: ,(doc ==)

16:05 clojurebot: "([x] [x y] [x y & more]); Returns non-nil if nums all have the same value, otherwise false"

16:05 systay: ,(doc =)

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

16:05 * systay wonders.

16:53 LauJensen: ,(do (println (= [1 2 3] [1.0 2.0 3.0])) (println (== [1 2 3] [1.0 2.0 3.0])))

16:53 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

16:54 LauJensen: ,(clojure-version)

16:54 clojurebot: "1.2.0-master-SNAPSHOT"

16:54 LauJensen: $(do (println (= [1 2 3] [1.0 2.0 3.0])) (println (== [1 2 3] [1.0 2.0 3.0])))

16:54 sexpbot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

16:54 LauJensen: Odd

16:54 mmarczyk: can't use == with vectors

16:54 LauJensen: mmarczyk: Works fine locally, prints true \n false

16:55 mmarczyk: really? now *that* is odd :-)

16:55 polypus: i want to repeatedly drop items from a sequential collection at given inices. i never have to re-add items to the collection. which collection would be most performant, and is there a single function which drops at a specific index, cuz i can't see one.

16:55 s/inices/indecis

16:56 mmarczyk: LauJensen: which branch?

16:57 LauJensen: master, 1.2 snapshot

16:57 polypus: Lau: yeah i thought i remembered that behavior. i get the cast exception noe that i updated

16:57 now*

16:57 LauJensen: oh ok, its just me thats still in the old-school then

16:59 mmarczyk: ahh, wait, right

17:00 but the old behaviour was that it would *always* return false

17:00 even for, say, (== [1 2 3] [1 2 3])

17:01 polypus: mmarczyk: i think i remember it returning true, but i may be wrong

17:01 mmarczyk: basically clojure.lang.Numbers.equiv had an overload returning false in absence of a better idea

17:02 LauJensen: polypus: perhaps you could use replace to alter your collection

17:02 ,(replace {1 5 2 6} [1 2 3])

17:02 clojurebot: [5 6 3]

17:02 mmarczyk: http://github.com/richhickey/clojure/blob/1.1.0/src/jvm/clojure/lang/Numbers.java#L181

17:03 so if either x was not a Number or y was not a Number, false would be returned with no actual comparison being performed

17:03 that's 1.1; I don't remember anything in between that and the current behaviour, but that might be a lapse in my memory

17:04 LauJensen: Dont think there has been any change

17:04 mmarczyk: polypus: as in (drop-every-nth 3 [1 2 3 1 2 3]) => (1 2 1 2) ?

17:05 polypus: or actually generalised... (skip-at [2 5] [1 2 3 1 2 3]) => (1 2 1 2)

17:06 polypus: or are you hoping for efficient access by index after you drop an item?

17:06 polypus: mmarczyk: no, i need to drop some arbitrary index from the collection in a loop where i don't know before hand the index

17:06 LauJensen: polypus: Do you only have the index, or the value as well ?

17:06 polypus: (loop [c coll] (recur (drop-some-index 0 coll))

17:06 only the index

17:07 mmarczyk: polypus: well ok, but how do you work with the collection? do you generally go left-to-right, while occasionally needing to mark an item n slots ahead for skipping, or do you use it as a vector, where efficient lookup by index is required?

17:09 polypus: efficient lookup is required, i guess i should use a map huh?

17:09 LauJensen: Or a set if possible

17:09 mmarczyk: yeah, one idea would be to use a (sorted-map) with numeric keys, dissoc for item removal, subseq to start a sequential walk at a given index

17:10 $(seq (sorted-map 1 :a 2 :b 3 :c))

17:10 sexpbot: => ([1 :a] [2 :b] [3 :c])

17:10 mmarczyk: $(seq (dissoc (sorted-map 1 :a 2 :b 3 :c) 2))

17:10 sexpbot: => ([1 :a] [3 :c])

17:11 LauJensen: Would something like this work?

17:11 (defn drop-idx [idx coll] (reduce #(if (= (key %2) idx) %1 (conj %1 (val %2))) [] (zipmap (range (count coll)) coll)))

17:11 clojurebot: inits is http://paste.lisp.org/display/63514

17:11 mmarczyk: $(subseq (dissoc (sorted-map 1 :a 2 :b 3 :c 4 :d 5 :e) 2) <= 2)

17:11 sexpbot: java.lang.ClassNotFoundException: clojure.core$mk_bound_fn$fn__4192

17:11 mmarczyk: huh? whatever

17:12 would have been a better example with >= anyway

17:12 polypus: ok, ty guys. i have to copy paste this stuff and digest a bit. my situation is actually slightly more complicated than i stated cuz i have two collections which are both indexed by the same indices, but which are used in different ways.

17:13 LauJensen: alright :)

17:14 mmarczyk: ah, the sorted-map would of course not reindex itself properly...

17:14 anyway, good luck & have fun :-)

18:18 Raynes: mmarczyk: Another one of those stupid bugs. I guess I'll spend all day tomorrow with Licenser. See if we can figure out what is causing that thing.

18:18 mmarczyk: Raynes: always happy to put yummy bugs on your plate ;-)

18:19 Raynes: It's the same thing that causes rseq and iterate to fail.

18:20 It's subseq causing it in this particular situation.

18:20 mmarczyk: Raynes: how about whitelisting clojure.core/mk-bound-fn?

18:20 Raynes: $(rseq [1 2 3])

18:20 sexpbot: java.lang.ClassNotFoundException: clojure.lang.APersistentVector$RSeq

18:21 Raynes: It's not *exactly* the same. But you might be on to something, I suppose.

18:21 $(take 3 (iterate inc 0))

18:21 sexpbot: java.lang.NoClassDefFoundError: clojure/core$iterate$fn__3750

18:21 Raynes: Hrm, it is differen't.

18:21 different*

18:21 mmarczyk: not sure how you'd go about whitelisting inner classes

18:21 Raynes: I don't think that's it though.

18:22 Because it still works when it's not started up with swank.

18:22 Which is isane.

18:22 insane* /me can't type today.

18:23 mmarczyk: hm, right

18:24 Raynes: mmarczyk: I can fix it dirtily by just running it through the shell script instead of a swank server, but that sucks, because I don't get to muck with it as much.

18:25 mmarczyk: yeah, I can see that

18:25 Raynes: I mean, I can still live-update because I have a reload command for reloading plugins, but still.

18:25 mmarczyk: sure

18:27 $(clojure.lang.Var/intern "clojure.core" "foo")

18:27 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: ()

18:27 Raynes: I'll go ahead and do that for now.

18:27 mmarczyk: so ClassNotFound isn't likely to be whitelist-related

18:27 I guess

18:28 Raynes: mmarczyk: The next thing I need to test is whether or not a fresh sandbox is working via a swank server with rseq and friends.

18:28 If it is, then something is wrong with sexpbot.

18:28 mmarczyk: good idea

18:28 Raynes: If not, I can just throw it on Licenser's plate. :D

18:29 mmarczyk: :-)

18:29 Raynes: $(rseq [1 2 3])

18:29 sexpbot: => (3 2 1)

18:29 Raynes: Enjoy. <3

18:29 mmarczyk: :-)

18:30 Raynes: I'd rather not run it in swank than have people not like sexpbot because half of everything is broken. :p

18:31 Also, that thing you tried to do earlier should work now. $#(subseq (dissoc (sorted-map 1 :a 2 :b 3 :c 4 :d 5 :e) 2) <= 2)#$

18:31 sexpbot: => ([1 :a])

18:36 mmarczyk: ohhh, $#(:is-this-cool? (reify clojure.lang.ILookup (valAt [_ _] true)))#$

18:36 sexpbot: java.lang.NullPointerException

18:36 mmarczyk: huh?, again

18:36 Raynes: That's your bug, not mine. :p

18:37 mmarczyk: not at all, works at my repl

18:38 Raynes: That's weird.

18:38 ,(:is-this-cool? (reify clojure.lang.ILookup (valAt [_ _] true)))

18:38 clojurebot: true

18:39 Raynes: Licenser: ^ ping

18:39 mmarczyk: :-)

18:39 Raynes: It still isn't my bug.

18:39 It's his! :p

18:39 I'll gist it and show him later.

18:43 mmarczyk: good, making clj-sandbox more robust is a great service to the community :-)

18:43 Raynes: Indeed. Just making it work is a service to the community. >_>

18:46 mmarczyk: that's another valid way of putting it ;-)

19:09 lancepantz: hey guys

19:10 anyone know binding that makes the *slime compilation* buffer disappear after a compile error?

19:12 rfg: C-x k :)

19:12 Well C-x o then C-x k

19:12 lancepantz: but then you have to type in the name of a buffer

19:13 rfg: lancepantz: I would also like to know.

19:15 lancepantz: :/

20:19 ,(let [foo {:a 1 :b 1 :c nil}] (into {} (filter #(not (nil? (val %))) foo)))

20:19 clojurebot: {:a 1, :b 1}

20:19 lancepantz: ^ anyone know of a more idiomatic way to remove nil values from maps?

20:20 tomoj: remove is at least a bit more idiomatic

20:21 ,(into {} (remove (comp nil? val) {:a 1 :b 1 :c nil}))

20:21 clojurebot: {:a 1, :b 1}

20:21 tomoj: (filter val ..) works if you don't have to bother about false

20:22 lancepantz: ,(into {} (remove (comp nil? val) {:a 1 :b 1:c nil :d false}))

20:22 clojurebot: Invalid number: 1:c

20:22 lancepantz: ,(into {} (remove (comp nil? val) {:a 1 :b 1 :c nil :d false}))

20:22 clojurebot: {:a 1, :b 1, :d false}

20:22 tomoj: vs:

20:22 ,(into {} (filter val {:a 1 :b 1 :c nil :d false}))

20:22 clojurebot: {:a 1, :b 1}

20:23 lancepantz: oh, i follow

20:23 cool, thanks tomoj

20:57 Lajla: tomoj, I challenge you to become a greater programmer than I.

21:04 defn: I issue a formal challenge to try and write code as poor as mine.

21:05 Lajla: defn, give me a sample code.

21:05 defn: Lajla: That was a joke, bub.

21:05 Lajla: I issue a formal challenge to prove that evolution happens according to MY demands.

21:05 Which includes that rock magically can turn into human beings, this is what evil satanic scientists believe.

21:06 * defn emails Dan Dennett

21:07 tomoj: <3

23:05 lein-js was disappointing :(

23:11 somnium: what is it?

23:12 omg

23:13 http://benfirshman.com/projects/jsnes/

23:13 (found searching for lein-js on github)

23:14 tomoj: it just copies src/js to war/js or something trivial like that

23:43 maravillas: sorry tomoj, i'm just messing about with stuff

23:43 my plans are to wrap up juicer

23:44 tomoj: no reason to be sorry

23:44 I was just puzzled at what strange thing could come out of combining leiningen and javascript

23:44 maravillas: ah :)

23:45 Bahman: Hi all!

Logging service provided by n01se.net