#clojure log - Jun 02 2011

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

0:11 tomoj: clojure support?? wow

0:18 kornys: tomoj: yep - see https://gist.github.com/1001206 - it's pretty awesome

0:34 offby1: $36/month isn't that bad.

0:34 EC2 micro is a bit cheaper, but not much

0:50 dnolen: hiredman: ping

0:50 kornys: offby1: yep, though for a tiny demo app, free would be better :)

0:52 hiredman: dnolen: pong

0:53 dnolen: hiredman: I've addressed some but perhaps not all of the issues. LVar and LCons now take metadata for doing custom things.

0:53 hiredman: (unifier '(?x . ?y) [1 2]) (binding-map '(?x . ?y) [1 2]) work for first and rest matching.

0:54 hiredman: ah, cool

0:55 dnolen: hiredman: one thing I'm on the fence about is allowing people to directly pass LCons instances to the unifier ...

0:56 hiredman: if you wan to create something that you can spit out from a macro, will emitting (lcons 1 (lcons 2 ...)) not work for you? core.logic also provides convenience macro llist for doing this.

0:56 hiredman: well, if they have a pre-prepped thing, and the pre-prepping happens to create an LCons

0:57 dnolen: possibly, since you mention prepping is expensive in the readme, and my patter is static at compile time I have the macro do the prepping

0:57 patterns

0:57 are

0:58 since I am not familiar with lcons I went with what seemed like the highest fidelity (pulling the fields and passing them to the constructor again)

0:59 dnolen: yeah I have to think about LOGIC-7 some more. let me know if (unifier '[(?x . ?y) 3] '[(1 2) 3]) support satisfies 5 & 6.

1:01 hiredman: seems like it would, but yes, I'll kick it around

1:01 dnolen: latest is on github and clojars.

3:15 chouser: there. pushed a very early version of data.xml

3:15 Hm, needs a README. https://github.com/clojure/data.xml

3:20 brehaut: heh "; blame Chouser for anything broken or ugly."

3:22 chouser: is it 1.2 compatible?

5:08 andrewclegg: chouser: is data.xml fully lazy, i.e. can you parse really big files as a stream of chunks?

5:08 v. handy if so

7:48 manutter: lol, I *so* cheated on 4clojure question #65

7:50 https://gist.github.com/1004288

7:50 mrBliss: manutter: quite clever!

7:51 manutter: I couldn't resist

7:52 expect one more function to be added to the Do Not Use list very soon now...

7:56 tufflax: Does swap! "block" the thread calling swap! until it is successful? Or is it a new thread?

8:35 chouser: tufflax: swap! spins. It will not return until it is successful.

8:35 tufflax: ok

8:38 chouser: andrewclegg: That's the intention, but it needs more testing before I'm willing to claim that.

8:42 tufflax: I've got a really nasty but on my hands, has to do with java socketchannels. If anyone want to take a look it's here: http://pastebin.com/Xymx9ZgE

8:42 thank you chouser btw :)

8:48 s/but/bug and s/want/wants :p

8:57 timvisher: hey all

8:58 tufflax: hi

8:59 timvisher: I'm trying to serialize a seq to disk in a file using `pr` and then read it back in and I'm encountering `error: java.lang.ClassFormatError: Invalid method Code length 361053 in class file wallpaper_manager_core/core$eval2183`

8:59 My only guess is that it's trying to execute a function because the seq is serialized as `(...)`

9:00 Any thoughts?

9:00 stuartsierra: What are you using to read it back in?

9:00 tufflax: Paste the code

9:00 timvisher: (load-file)

9:00 stuartsierra: There's your problem. :)

9:00 `load-file` means read & eval. You just want `read`

9:00 timvisher: Ah

9:01 so should I make the file into a string and then call read on it?

9:01 or is there a convenience function for that?

9:01 tufflax: in that case read-string

9:01 raek: timvisher: no, 'read' reads from a stream.

9:01 timvisher: raek: nice!

9:02 raek: summary: pr and read work on streams (*out* and *in*, which can be rebound with 'binding'), pr-str and read-string work on strings

9:04 * tufflax wishes his problem was solved too ;)

9:21 andrewclegg: chouser: I'll test it by throwing some gigs at it and seeing what happens

9:30 markskil1eck: Any idea why get-datasets for incanter is returning some html?

9:31 kephale1: what is the best way to download files w/in clojure (files of arbitrary type incl binary)?

9:32 a la curl

9:33 drewr: kephale1: you can do something with (clojure.java.io/reader "http://foo")

9:34 raek: kephale1: if you don't need to control the headers, the simplest way is probably to pass a URL to clojure.java.io/reader (text) or clojure.java.io/input-stream (binary)

9:34 chouser: andrewclegg: cool. let me know what you find. Do beware of head-holding, though.

9:34 kephale1: drewr & raek: aha! ty

9:35 drewr: was thinking reader would polymorphically give you an input-stream, but that wouldn't really make sense

9:36 tufflax: If anyone was trying to figure my bug out, i solved it.

9:36 raek: kephale1: it is probably a good idea to pass the url string through clojure.java.io/as-url and then verify that the scheme is http or https

9:37 kephale1: my friends helped me find a bug/feature in my title-printing IRC bot but asking it to look up the title for the URL file:///dev/random

9:38 s/but/by/

9:38 sexpbot: <raek> kephale1: my friends helped me find a bug/feature in my title-printing IRC bot by asking it to look up the title for the URL file:///dev/random

9:38 raek: tufflax: what caused it?

9:38 kephale1: raek: oh good point

9:40 raek: kephale1: another point: if you want to read text, you specify the encoding of the text (the "file format" of the characters) with the :encoding option: (clojure.java.io/reader url :encoding "UTF-8")

9:40 if it is left out, UTF-8 will be used

9:41 kephale1: cool, i'm mostly going to be shuffling jars around, but might have some text

9:42 tufflax: raek: I was reading into the wrong buffer. On line 128 in my paste i should have saved the new c in the global *players*, because i was relying on :read-tmp to be set right. Now if I didnt get any more data after reading the length of the message i forgot the new read-tmp and next time read into the buf for getting the lengths

9:47 I gotta come up with a better way to debug my programs. I ran the server in a future, and prints dont show from the new thread. What I ended up doing was conjing debug msgs into a global. btw i tried bound-fn but it didnt help. In other languages ive mostly used prints to debug but it's not very convenient in clojure. is there a good debugger?

9:47 raek: tufflax: are you using emacs, btw?

9:47 tufflax: vim

9:48 raek: the prints should appear somewhere

9:48 tufflax: not before my eyes ;)

9:48 raek: in emacs, the repl and stdout are distinct, so prints from the repl thread appears in the repl and prints from other threads appear in stdout

9:49 tufflax: you could try (intern 'clojure.core '*out* *out*) in the repl where you want the prints

9:49 tufflax: oh, that explains why bound-fn didnt work

9:49 raek: this will change the root binding

9:49 tufflax: strange, bound-fn should work too

9:50 tufflax: but still, prints is not so convenient, because sometimes one needs to add a (do ... ) or something like that. what do you use for debugging?

9:51 raek: for stateful code? prints I guess... :)

9:51 tufflax: hehe

9:51 raek: for purely functional code, you can always test things in isolation in the repl

9:52 tufflax: yeah of course, functional is better :p

9:52 raek: I tend to build a purely functional layer first that does parsing and operations on domain data

9:52 kephale1: is there a pretty way to empty an input stream into an output stream?

9:52 copy into, i should say

9:52 tufflax: raek did you read my code? any tips on style?

9:53 raek: kephale1: yes, 'copy' :-) http://clojuredocs.org/clojure_core/clojure.java.io/copy

9:53 kephale1: raek: yay, ty again

9:54 raek: tufflax: I briefly looked though it. I'm not very familiar with how you program using the java.nio classes. my first idea was that this would probably be simpler using a thread/connection and streams

9:55 but I know that one thread per connection does not scale very well...

9:55 tufflax: Yeah thats why i didnt want that

9:58 raek: one advice is to try to limit the number of kinds of side-effects per function

9:59 for example read-from-client both reads data and changes the atom

10:00 if it would return the data instead, it would be easier to test it in isolation

10:00 tufflax: yeah that migth be a good idea

10:01 s/migth/might/

10:01 sexpbot: <tufflax> yeah that might be a good idea

10:01 Cozey: Which Mustache library would you recommend? clostache, stencil, mustache.clj ?

10:01 raek: in general, try moving state-changing stuff out from functions if possible

10:01 I think add-new-client is fine here, since it *only* does mutation

10:02 * tufflax nods

10:12 Cozey: what would you recomment for app configuration? property file? file with clojure code ?

10:13 abedra: Cozey, it depends on what you are configuring and if that configuration needs to change while the program is running

10:14 Cozey: i'd say it won't be update by the app, but maybe it would be nice to change the conf and notify an application - do You have something in mind?

10:14 this would actually not be easy to implement in a smart way

10:15 abedra: Cozey, having a clj file as configuration data makes it a little easier to reach in and modify configuration

10:15 Cozey: yes

10:15 true

10:16 it would be in lisp philosophy

10:16 chouser: but not if there are comments in the config file

10:16 abedra: I tend to use properties files for configuration data that I know won't change

10:16 :)

10:17 oelewapperke: if you know it won't change don't you want the compiler to optimize it out ?

10:18 abedra: oelewapperke, I mean won't change after it is configured

10:18 oelewapperke, I want it to be configurable by others though

10:19 that may not know how to edit a clj file

10:28 tufflax: Does bound-fn only install the bindings in the lexical scope?

10:30 stuartsierra: bound-fn is for dynamic, not lexical scope

10:31 raek: tufflax: if I understand it correclty, it should remember the values of the dynamically bound vars in the dynamic scope where bound-fn is called. when the resulting fn is called, the body is evaluated in a dynamic scope with those remembered bindings in place

10:33 (def *x* 1) (def f (binding [*x* 2] (bound-fn [] *x*))) (f) => 2

10:35 tufflax: Hm what are the dynamically bound vars? How come (future-call (bound-fn [] (println "arst"))) prints in my repl but not (future-call (bound-fn [] (fn-which-calls-println))), and not (future (println "asr"))

10:39 raek: tufflax: vars that are intended to be dynamically rebound are those named with *earmuffs* (there is no need for special naming of constants in clojure, since vars should not be metutaded for maintaining application state)

10:40 they are often used to as "implicit" arguments to functions

10:41 e.g. print prints to the stream in *out*. to print to another stream, one temporarily and dynamically rebinds the value: (binding [*out* ...] (print ...))

10:41 tufflax: what about earmuffs on global refs and atoms btw?

10:42 raek: sip them if you don't intend to rebind them with 'binding'

10:42 tufflax: ok

10:42 raek: in (def r (ref ..)), r is a constant (it always points to the same ref)

10:42 tufflax: i see

10:43 raek: tufflax: anyway, there should be no difference in writing (binding [*out* ...] (print ...)) and (binding [*out* ..] (function-that-calles-print ...))

10:43 tufflax: hmm, strange :p

10:44 raek: ...unless that function was made with bound-fn

10:45 (boudn-fn* f) can be seen as (fn [& args] (binding [...all the bound vars...] (apply f args)))

10:48 s/metutaded/mutated/ (in one of my previous lines)

10:49 tufflax: i made a new fn that prints, and it worked as you described, but not my fns in my pasted code hmm. (yes i evaluated them again)

10:49 Cozey: Hmm. I'd like to add a template name to a compojure route - so a wrapper function can render route's response with a proper temlate... I thought maybe about using metadata for this, but I'm not sure how to implement this. any ideas?

10:50 tufflax: maybe it has to do with where they were evaluated... or something :p

10:51 i mean, defined

10:52 raek: tufflax: yes, bound-fn remembers the bindings from the point where it is evaluated

10:53 tufflax: also, there are debuggers for clojure: http://georgejahad.com/clojure/cdt.html

10:54 tufflax: I mean defined as in where the defn of the fn that prints where evaluated, all bound-fns were evaluated in the same repl

11:01 So, to clarify: I write (ns some.ns) (defn test [] (println "dsrtd")) in a file and eval it. Then in the repl in ns some.ns i write (defn test2 [] (println "rst")). Then in the same repl (future-call (bound-fn [] (test))) does not print but (future-call (bound-fn [] (test2))) does

11:01 gotta go afk a bit...

11:08 raek: tufflax: what does #'test return in the repl? #'some.ns/test or #'clojure.core/yesy

11:08 *test

11:09 I think the file was somehow not loaded correctly and you're accidentally using clojure.core/test

11:23 tufflax: raek #'game.networking/test

11:25 raek: tufflax: so calling it directly work, but (future-call (bound-fn* test)) does not?

11:25 tufflax: yup

11:26 raek: and the body just contains (print "asdf")?

11:26 tufflax: or wait, that works

11:26 but not (bound-fn [] (test))

11:26 inside a future

11:26 raek: oh, of course...

11:27 tufflax: ? :)

11:27 raek: (future ((bound-fn [] (test)))) expands to (future-call (fn [] ((bound-fn [] (test)))))

11:27 the bound-fn ends up beining evaluated in the wwring thread

11:27 *wrong

11:28 (let [f (bound-fn [] (test))] (future (f))) should work though

11:29 maybe it would be nice to have something like (bound-future ...code...)

11:29 (defmacro [& body] `(future-call (bound-fn [] ~@body)))

11:30 tufflax: but wasnt that exactly what i did? dont u mean bound-fn*?

11:33 raek: tufflax: which example?

11:33 tufflax: the macro

11:34 raek: tufflax: you said that (bound-fn [] (test)) didn't work inside a future, so I assumed you were doing something like (future ((bound-fn [] (test))))

11:34 Cozey: Help! I cannot (require) clojure.contrib.condition - it can't find Condition__init method but it's there in the jar (clojure 1.3). How can I deal with that?

11:35 raek: Cozey: what toold do you use to start clojure?

11:35 Cozey: it's cake

11:35 but let me check with normal repl

11:36 tufflax: raek Sorry for the confusion, what I was doing was exactly what I said when i said "So, to clarify". Also i still have not understood the difference between test and test2

11:37 raek: hrm. there shoudn't be any difference between them...

11:37 tufflax: :p

11:37 raek: (future-call (bound-fn [] ...))) should do the right thing

11:37 tufflax: and you can call (test) and (test2) at the repl and both works?

11:38 tufflax: yes

11:38 raek: and it's not something basic, like that you forgot to save the file?

11:39 also, you said this behaves differently when you are are using bound-fn* instead of bound-fn?

11:39 tufflax: yes

11:40 well

11:40 hmm

11:40 raek: ,(macroexpand-1 '(bound-fn [] (test)))

11:40 clojurebot: (clojure.core/bound-fn* (clojure.core/fn [] (test)))

11:40 tufflax: it gets stranger

11:41 raek: tufflax: and you didn't miss the parentheses around (test)?

11:44 tufflax: raek hmm sometimes it works and sometimes not, maybe it's vims fault http://pastebin.com/qT3VXA4Y

11:45 raek: tufflax: another idea: try using println instead of print (and maybe even add a flush call). maybe this is a buffering issue.

11:46 tufflax: it is all printlns

11:48 raek: tufflax: does (defn test [] (println "arst") (flush)) make any difference?

11:49 tufflax: no, sometimes it still doesnt show up

11:50 im getting tierd of this problem :p

11:50 tired

11:52 Cozey: raek: some dependency pulled contrib 1.2 - that was the problem i think

11:54 Dantas: Hi all, reading a nice post about metaprogramming, im wondering what *ns* means (intern *ns* 'hello (fn [] println "Hello World"))

11:57 andrewclegg: dantas: that's your current namespace

11:57 raek: Dantas: it's a var that contains a reference to the current namespace of the repl

11:57 andrewclegg: user=> (in-ns 'clojure.core)

11:57 #<Namespace clojure.core>

11:57 clojure.core=> *ns*

11:57 #<Namespace clojure.core>

11:57 etc.

11:58 tufflax: So a final question about bound-fn; what gets bound in the new function? "bindings in effect" -- things bound with binding? But im not binding anything, and apparently *out* gets bound anyway. Does every regular var count as a binding in effect?

12:03 raek: tufflax: you didn't bind *out* yourself, but your repl runs inside a binding form that binds it

12:05 Dantas: raek: andrewclegg : the var symbol is *ns* ??

12:05 is the var symbol *ns* ?

12:05 raek: something like (binding [*in* ..., *out* ...] (loop [] (-> (read) (eval) (println)) (recur)))

12:06 Dantas: thanks

12:06 raek: Dantas: in the source code, *ns* is an ordinary symbol, just like intern and fn are

12:06 Dantas: yeah, thank u

12:07 raek: the symbol names the var #'clojure.core/*ns*

12:08 just like intern names the var #'clojure.core/intern

12:09 tufflax: i.e. your repl (but not the threads you start) runs in a dynamic scope where *out* is rebound

12:13 tufflax: raek ok, so not every regular var counts then

12:13 i guess that makes sense

12:14 raek ok now im gonna get on with my project. thank you very much for always helping me

12:29 timvisher: is clojure.contrib.logging deprecated in favor of tools.logging?

12:29 stuartsierra: yes

12:29 timvisher: awesome

12:30 stuartsierra: Basically, everything in the monolithic clojure-contrib is deprecated after 1.2

12:30 timvisher: what if i'm on 1.2?

12:30 stuartsierra: up to you then

12:30 timvisher: so tools.logging should work even on 1.2?

12:31 stuartsierra: It should, yes.

12:31 technomancy: timvisher: that's what we're doing

12:31 it's a lot more convenient than contrib.logging

12:37 mabes: technomancy: why do you find it more convenient? isn't it the same API as contrib.logging?

12:38 technomancy: mabes: no, it doesn't make you to call format everywhere

12:38 timvisher: is it easier to set logging levels in tools.logging?

12:38 technomancy: it takes var-args and makes a string for you

12:38 timvisher: no, that is implementation-dependent. there's no way to do it across all the loggers tools.logging supports.

12:39 mabes: technomancy: ah, that is nice

12:39 timvisher: gotcha

12:40 so is this information still relevent if i were to use tools.logging? http://www.paullegato.com/blog/setting-clojure-log-level/

12:41 technomancy: probably. I haven't used j.u.logging or apache logging.

12:42 timvisher: cool. thanks for the help

12:48 zitchie: list

12:48 ,(defn foo 'adsf')

12:48 clojurebot: Unmatched delimiter: )

12:52 wastrel: hi

14:46 pdk: ,(/ 1000 16.0)

14:46 clojurebot: 62.5

15:01 gfrlog: (fn [_] (do (foo) (bar))) is redundant, right?

15:03 wastrel: hi

15:04 ataggart: gfrlog: the do is redundant, yes

15:15 gfrlog: ataggart: thanks

15:15 wastrel: hi

15:18 wastrel: vampire day massacre

15:18 sorry connection lag

15:27 bartj: why can't this be done:

15:27 (fmap #(+ 1 %) (for [i (range 10)] i))

15:27 chouser: what's fmap?

15:28 hiredman: ,(doc fmap)

15:28 clojurebot: No entiendo

15:28 hiredman: clojurebot: jerk

15:28 clojurebot: No entiendo

15:29 hiredman: ,(require 'clojure.contrib.generic.functor)

15:29 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/generic/functor__init.class or clojure/contrib/generic/functor.clj on classpath:

15:29 hiredman: ,(require 'clojure.contrib.generic.functors)

15:29 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/generic/functors__init.class or clojure/contrib/generic/functors.clj on classpath:

15:29 hiredman: bleh

15:29 there is an fmap somewhere in contrib vaguely like that

15:29 bartj: hiredman, yes, I know

15:29 Applies function f to each item in the data structure s and returns

15:29 a structure of the same kind.

15:30 hiredman: bartj: I wasn't pointing it out to you

15:30 (for [i (range 10)] i) is redundant btw

15:31 bartj: I imagine it doesn't work because there is no fmap implemented in that library for seqs

15:32 bartj: hmm

15:33 seems strange though

15:34 hiredman: fmap is not used very often, so missing functionality is too be exepected

15:35 bartj: raek, help?

15:35 stuartsierra: You want ordinary `map`

15:39 bartj: stuartsierra, yes, I guess, fmap is supposed to be applied to maps, etc only

15:39 stuartsierra, but, I am puzzled and curious why it doesn't work in this guess

15:39 *case

15:39 stuartsierra: because the author didn't implement it.

15:40 `fmap` and the other c.c.generic stuff never went through a design review.

15:40 They're not part of the language.

15:41 hiredman: bartj: the only real advantage of fmap is it can map over values in maps, most people are likely to just roll their own

15:42 ,(let [a {:a 1}] (zipmap (keys a) (map inc (vals a))))

15:42 clojurebot: {:a 2}

15:42 hiredman: ,(into {} (for [[k v] {:a 1}] [k (inc v)]))

15:42 clojurebot: {:a 2}

15:42 hiredman: etc

15:43 bartj: stuartsierra, thanks!

15:43 hiredman, thank you for your time and help

15:45 zakwilson: I want a library for handling HTTP requests that lets me define handlers with typed arguments and define how the string parameters get converted in to the appropriate types. I don't know of such a thing and expect I'll have to write it myself, but I figured I'd ask first.

15:46 To give an example of the sort of code I want to write: (defhandler foo [id :int name :string img :file] ...)

15:49 hiredman: zakwilson: if defhandler is a macro you could just as easily use type hints instead of keywords, fwiw

15:51 and I would suggest just generating a function that takes a map of params or whatever and returns a map coerced to the correct types

15:51 zakwilson: hiredman: Would type hints work if I wanted to make the type conversions a multifn dispatching on the name of the desired type where the return value might be an arbitrary data structure (e.g. a map representing a database row)?

15:52 hiredman: zakwilson: oh, the macro would examine the tag metadata on the symbol and do the right thing, it would look like type hints to the user, but they would never make it to the compiler

15:53 zakwilson: I'm also considering an optional throw-on-null - e.g. (defhandler foo [id [:int :required]] ...)

15:53 hiredman: that sounds more like validation

15:54 (defvalidator foo ...) (defhandler bar ...) ((comp foo bar) some-request)

15:54 er, reverse those

15:54 (comp bar foo)

15:54 zakwilson: Yes. I'm not sure if I should conflate validation and ensuring that the handler doesn't have to worry about types in its body.

15:54 stuartsierra: When in doubt, separate.

15:56 zakwilson: Some languages treat null checks as part of the type system, and it seems like that might go well with this little island of static typing, but it does sound more flexable to have separate validators that can do anything.

16:04 The other question that comes to mind for me is whether and how to deal with session variables (sandbar stateful-session). My instinct is to not do it, but it could be kind of cool to have handlers take everything a web request might need to deal with as arguments.

16:06 hiredman: the functional way to do it would be with the state monad

16:07 but mentioning that tends to make people break out in hives

16:08 pjstadig: clojure is not a pure functional language, you're free to use vars, atoms, etc.

16:08 that's why they're there

16:09 gfrlog: there are still best practices about when to use them though

16:09 pjstadig: yeah but there is no reason to have to use monads

16:10 rich took the practical road with concurrently semantic reference types

16:10 but you're free to use monads too if you want

16:10 what do i care?

16:10 hiredman: pjstadig: monads and mutable reference types are orthogonal

16:11 pjstadig: how so?

16:11 you're talking about mutable state

16:11 robbe-: If I make-array an array, and share it amongst thread, the array is copied I presume? i.e. if I want to make changes that should be reflected in other threads, I could use e.g. an array of refs?

16:11 hiredman: gotta run, rides here

16:11 robbe-: threads*

16:12 pjstadig: an array shared amongst threads will need some kind of locking

16:13 robbe-: That means the array *is* shared amongst threads, and no thread-local copy is made when a thread starts

16:13 pjstadig: i guess you could use an array of refs, but why not a vector

16:13 robbe-: right?

16:13 pjstadig: right no copying unless you do it

16:13 robbe-: thanks

16:14 Considering alternatives at the moment. :-)

16:15 Ah, I the requirement (not set by me) is O(1) access time, and clojure documentation states: "Vectors support access to items by index in log32N hops."

16:15 Which is still plenty fast, but not constant time.

16:16 And I can't change the requirements because it's a school assignment. :P

16:16 gfrlog: robbe-: you could argue that it is constant, given bounds on the size of the computer and all that

16:17 although I suppose by that argument any halting algorithm is constant :-/

16:17 robbe-: Indeed, but I expect the assistant to be nitpicking about it. I'll just ask to be sure.

16:17 gfrlog: clojure is not a good tool for school assignments that are biased against clojure

16:18 raek: robbe-: I'd say: renegotiate the O(1) requirement to include the practically constant time of clojure's data structures

16:18 robbe-: Yeah, but you probably mean "not constant but incredibly low bound, which is in this case low enough to be considered constant." or something along those lines. :-)

16:19 Thanks for the advice. :-) Will mail him shortly.

16:19 raek: for a vector with 2^32 elements, the lookup requires 6 or 7 steps, IIRC

16:19 gfrlog: robbe-: Also make the case that arrays are not quite constant either due to caching and paging and such

16:19 raek: and for hash-maps you can't have more than 2^32 distinct hashes

16:20 gfrlog: raek: what's the collision algorithm?

16:20 robbe-: gfrlog: <devils advocate> but you can fix that with more ram

16:20 gfrlog: robbe-: the point is that in practice the distinction is quite murky

16:21 robbe-: I agree. Just trying to come up with anything he might have to counter the arguments. :-)

16:21 gfrlog: well I imagine it's his perogative to say "cuz I sed so"

16:22 robbe-: :D

16:22 Well, I have to go now, it's getting late over here, so I should mail and go to bed. Thanks everyone for the input.

16:23 gfrlog: enjoy your time zone

16:23 robbe-: Surely am, 20 past 10 pm and still light outside, I like that. Winter sucks though. :-)

16:24 gfrlog: enjoy your latitude as well then :)

16:25 raek: gfrlog: I think it has a special kind of node in the tree for hash collisions that linearly searches through an array of the objects with the same hash value

16:26 gfrlog: raek: that sounds like it would allow >(2^32) entries then, just with quickly decreasing performance?

16:26 raek: yeah, that's true

16:27 pjstadig: yes

16:28 so if you have a terrible hashing algorithm the data structure is actually log(n)

16:28 gfrlog: I'd think it'd be O(n)

16:29 if "terrible" means "worst case"

16:29 given raek said "linearly searches"

16:30 pjstadig: hehe

16:30 oops

16:30 i meant O(n)

16:30 raek: gfrlog: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java#L719

16:30 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentHashMap.java#L784

16:31 ordnungswidrig: ,(extend Object (ns-resolve *ns* (defprotocol Z)))

16:31 clojurebot: DENIED

16:31 ordnungswidrig: (extend Object (ns-resolve *ns* (defprotocol Z)));; this works

16:32 (extend Object (ns-resolve *ns* (defprotocol Z (x [this]))){:x (constantly 42)}) ;; -> #'user/Z is not a protocol

16:32 any clues

16:34 pjstadig: i believe defprotocol returns a symbol

16:34 not the protocol

16:35 oh

16:35 right but you're trying to resolve

16:35 ah but there is a #' there

16:37 yeah add an @ in front of the defprotocol

16:37 err

16:37 the ns-resolve

16:37 (extend Object @(ns-resolve *ns* (defprotocol Z (x [this]))){:x (constantly 42)})

16:37 ordnungswidrig: pjstadig: thanks, nice catch.

16:38 * ordnungswidrig avoids macro-writing at all costs)

16:56 TimMc: Well, I wrote a thing to do dynamically scoped "binding" in Java.

16:56 Now I'm passing it around for my coworkers to poke holes in. :-P

17:01 gfrlog: TimMc: wut

17:06 raek: TimMc: does it use ThreadLocal? http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

18:29 TimMc: raek: InheritableThreadLocal, yeah.

18:30 I'll see if I can get permission to post it -- I coded it on the clock, so by default it is company code.

18:30 My test rig for multi-threaded well-behavedness is amusing.

18:31 gfrlog: try { LocalConfig.push("key", "val"); /* stuff */ } finally { LocalConfig.pop("key") }

19:06 miwillhite: hey all…anyone got an app running on Heroku yet?

19:58 hey…I'm trying to run my clojure app with `lein run -m stammer.core` (relevant files: http://pastebin.com/wfQJ3C9c)…but I keep getting the exception in the pastebin…any ideas? (using lein 1.5.2)

19:58 * miwillhite is new to clojure…

20:00 sritchie: hey all -- what protocol would I extend to cover all sequences?

20:00 I had thought it would be aseq, but this misses vectors

20:01 hiredman: vectors are not seqs

20:02 sritchie: I think iterable is what I'm looking for

20:18 miwillhite: can I access environment variables in clojure? (like RACK_ENV in ruby for example)

20:18 technomancy: ,(System/getenv "HOME")

20:18 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.HOME)

20:19 miwillhite: awesome thanks!

20:21 technomancy: sure

20:23 __name__: ,(Runtime.getRuntime)

20:23 clojurebot: java.lang.ClassNotFoundException: Runtime.getRuntime

20:23 __name__: ,(Runtime/getRuntime)

20:23 clojurebot: #<Runtime java.lang.Runtime@12996d6>

20:24 __name__: ,((. Runtime/getRuntime availableProcessors))

20:24 clojurebot: java.lang.Exception: Unable to find static field: getRuntime in class java.lang.Runtime

20:24 __name__: ,((. Runtime getRuntime availableProcessors))

20:24 clojurebot: java.lang.Exception: Unable to resolve symbol: availableProcessors in this context

20:24 __name__: ,((.. Runtime getRuntime availableProcessors))

20:24 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

20:24 __name__: ,(.. Runtime getRuntime availableProcessors)

20:24 clojurebot: 1

20:25 __name__: Sorry.

20:42 TimMc: __name__: You can also privmsg clojurebot

20:43 __name__: TimMc: I know.

20:43 I always thought it would work and wanted to share the result.

20:43 #scala's bot still is cooler.

20:43 It gives you 42 :)

20:44 TimMc: weird

20:52 korny: hi folks - is there something like partition-by that splits a seq by a boolean fn into two seqs, rather than repeatedly splitting?

20:52 &(partition-by odd? [1 2 3 4 5 6])

20:52 sexpbot: ⟹ ((1) (2) (3) (4) (5) (6))

20:52 korny: whereas I'd like ((1,3,5)(2,4,6))

20:53 hiredman: ,(group-by odd? (range 10))

20:53 clojurebot: {false [0 2 4 6 8], true [1 3 5 7 9]}

20:53 korny: hiredman: thanks

20:59 pickles: I am about to tear my hair out over this: (def x [obj obj]), (.method (first x)) -> true, (map '.method x) -> [nil nil]

21:01 hiredman: do you understand what quoting a symbol does?

21:01 brehaut: ,(map #(.toString %) [(Object.) (Object.)])

21:01 clojurebot: ("java.lang.Object@1c0ae76" "java.lang.Object@fde7ba")

21:02 pickles: hiredman: i have an idea, but no, i do not

21:02 brehaut: ,(type 'foo)

21:02 clojurebot: clojure.lang.Symbol

21:02 TimMc: ,(type '.method)

21:02 clojurebot: clojure.lang.Symbol

21:02 TimMc: grah, I am slow

21:03 brehaut: pickles: symbols are ifn's, so it can be passed it

21:03 as an argument to map

21:03 ,(ifn? '.method)

21:03 clojurebot: true

21:03 brehaut: but its not a handle on a method

21:03 hiredman: pickles: http://www.apl.jhu.edu/~hall/lisp/Lisp-Quote-Hints.text is written for common lisp, but similar enough

21:04 brehaut: ,(map 'foo [{'foo 1} {'foo 2}])

21:04 clojurebot: (1 2)

21:04 pickles: when I do (map .terminates? x) i get an exception

21:04 hiredman: correct

21:05 TimMc: pickles: .method is a Java interop form

21:05 hiredman: because the name '.terminates?' is not bound locally or globally to anything

21:05 TimMc: It can't be passed around.

21:05 pickles: mmm

21:05 TimMc: pickles: However, #(.method %) can be. :-)

21:05 hiredman: (macroexpand '(.foo bar))

21:05 pickles: so i need to do a lambda

21:05 hiredman: ,(macroexpand '(.foo bar))

21:05 clojurebot: (. bar foo)

21:05 pickles: aha

21:05 i c

21:08 many thanks all

21:08 hopefully i'm through being a n00b for the day

21:16 rock on, it's working, thanks again!

21:22 * __name__ rocks on.

21:52 leif-p: Hi. Anyone know how to make clojure.pprint print metadata like (set! *print-meta* true) in the REPL does?

22:21 crowbar: Can someone please give me feedback on how I'm handling a point in 3d space? I'm currently trying to hold it as a map with {:x 1 :y 10 :z -4}. To simplify creation of a 3d point I have (defn point [a b c] {:x a :y b :z c}). Is this idiomatic?

22:26 chouser: crowbar: yep, it's fine. Also consider defrecord

22:30 crowbar: thanks chouser. exactly what I was after.

23:07 no_mind: I have some functions returning hash maps. I want to add the returned hash-maps to a sequence and return the sequence. How do I do this ? When I try to use concat or conj or cons, the returned sequence breaks hash-map elements into smaller sequqnces, something I do not want

23:08 hiredman: it means you are doing something that calls 'seq' on your maps

23:08 (seq {:a 1})

23:08 ,(seq {:a 1})

23:08 clojurebot: ([:a 1])

23:11 no_mind: hiredman: yes and I want to know how to avois this ?

23:12 hiredman: I want result like this ({:a 1, :b 2} {:c 3, :d4}) where {:a 1 :b 2} and {:c 3, :d 4} are returned from two different functions, lets say abc and xyz

23:22 bpr: no_mind: (conj existing-sequence (seq hash1 hash2 ...))

23:23 hiredman: bpr: nope

23:23 bpr: ?

23:23 then list rather than seq?

23:23 hiredman: bpr: what does seq do? how many args does it take?

23:24 bpr: yeah then list

23:26 lol, god i feel silly now

23:27 hiredman: thanks for pointing that out

23:48 bdesham: hi all

23:48 I'm trying to write a function like flatten, except that it works with sets instead of sequences

23:48 I came up with this: https://gist.github.com/1005837

23:49 hiredman: ,(flatten #{#{:a} #{:a}})

23:49 clojurebot: Duplicate key: #{:a}

23:49 hiredman: bleh

23:49 ,(flatten #{#{:a} #{#{:a}}})

23:49 clojurebot: ()

23:49 hiredman: huh

23:49 bdesham: it works fine, except that I'd like some way to make sure there are no duplicates in the input... for example, (flatten-sets [:a :b :a]) should generate some kind of output that lets me know there's a problem

23:49 hiredman: right ;-) I tried that

23:50 hiredman: ,(set (remove set? (tree-seq set? seq #{#{:a} #{#{:a}}})))

23:50 clojurebot: #{:a}

23:50 bdesham: ,(filter (complement set?) (rest (tree-seq set? seq (set [:a #{:b} #{:c #{:d #{:e :f} :g}} :h)))))

23:50 clojurebot: Unmatched delimiter: )

23:50 bdesham: damn

23:51 hiredman: ,(set (remove set? (tree-seq set? seq #{#{:a} #{#{:a}} #{:a :b :c {:d :e :f}}})))

23:51 clojurebot: 3

23:51 bdesham: ,(filter (complement set?) (rest (tree-seq set? seq (set [:a #{:b} #{:c #{:d #{:e :f} :g}} :h])))))

23:51 clojurebot: (:c :g :d :f :e :a :b :h)

23:51 bdesham: ,(set (remove set? (tree-seq set? seq #{#{:a} #{#{:a}} #{:a :b :c #{:d :e :f}}})))

23:51 clojurebot: #{:a :c :b :f :d :e}

23:51 hiredman: clojurebot: seriously?

23:51 clojurebot: I don't understand.

23:51 bdesham: lol

23:52 hiredman: that seems to do the same kind of thing

23:53 but I'd like something that would detect duplicates, no matter how deeply nested they are

23:54 hiredman: creating a set removes duplicates

23:56 bdesham: I guess I can check for duplicates at top level with (= v (vec (set v)))

23:56 but I could do that with distinct? just as easily

23:56 hmm...

23:58 hiredman: sets cannot contain duplicates

23:58 thats what a set is

23:59 ,(conj #{:a} :a)

23:59 clojurebot: #{:a}

23:59 bdesham: hiredman: right

23:59 hiredman: so you cannot possibly check for duplicates in a set, because there will never be any

Logging service provided by n01se.net