#clojure log - Dec 12 2011

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

0:00 fhd: amalloy: Reminds me of memory management in OS theory. Read-only pages are normally shared in a similar manner.

0:03 Scriptor: structural sharing is also helped out by clojure not changing the actual tree unless it has 32 elements it can add all at once

0:03 I think that's right

0:04 amalloy: eh?

0:04 Scriptor: er, not change the tree

0:04 amalloy: that sounds basically untrue

0:04 Scriptor: I meant creating a new tree

0:05 until 32 elements are added, it just does copy-on-write and creates new arrays

0:06 amalloy: i'd love to be proven wrong, but that doesn't sound like anything clojure does that i'm aware of. do you have a reference?

0:06 Scriptor: the above-mentioned link

0:07 amalloy: wait, not that link, this one http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

0:07 specifically in the 3rd code listing there

0:08 System.arraycopy(tail, 0, newTail, 0, tail.length);


0:08 Anniepoo: howdy - I'm returning to Clojure after an absence. My dev environment's on 1.2 I'm upgrading to 1.3

0:08 is there still a separate clojure-contrib jar?

0:10 Scriptor: amalloy: direct link to the current code https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java#L170

0:11 amalloy: ah, interesting. so it keeps a second direct pointer to the last chunk-of-32 elements of the vector, no matter where in the tree those are located

0:12 and can therefore avoid doing copying on the way back to the root until those are finished

0:12 Scriptor: amalloy: they're not actually in the tree in the first place, when you do something like (cons 1 []) it just makes an array

0:13 amalloy: right

0:13 Scriptor: and yep, this avoids copying the nodes going up to the root every time you cons

0:14 same with conj, it seems

0:14 amalloy: Scriptor: (conj x y) == x.cons(y)

0:15 pretty cool, thanks. it's been a long time since i read that article and i didn't get the significance at the time

0:15 Scriptor: amalloy: not with vectors though, righT?

0:15 regarding conj and cons

0:15 amalloy: Scriptor: the .cons method is just named badly - it's conj

0:16 &(.cons [1 2 3] 4)

0:16 lazybot: ⇒ [1 2 3 4]

0:16 Scriptor: ah

0:16 amalloy: well. "badly". it's named in a way that is only accurate historically

0:20 Scriptor: amalloy: heh, better to actually know clojure and be hazy on this than the reverse :)

0:26 devn: I know about fnparse and parsatron -- I seem to remember a few other parsers out there in clojure land. Anyone know what I'm forgetting?

0:26 parsley just came to mind

0:26 duck1123: does gloss count?

0:26 devn: got a link?

0:27 woops, parsley is not what i was looking for

0:27 Scriptor: this gloss? https://github.com/ztellman/gloss

0:27 devn: yeah gloss isn't really what i'm looking for

0:27 im looking for parsec clones/rewrites

0:27 i forgot clarsec, but it's a little difficult to read

0:27 duck1123: it's for parsing binary data, but wouldn't serve the purpose?

0:28 devn: duck1123: im looking for PEG stuff

0:29 parser combinators

0:30 http://brehaut.net/blog/2011/fnparse_introduction -- you know, when i read the tests i wasn't sure about fnparse, but it looks really nice

0:30 Raynes: devn: Also abandoned.

0:30 devn: If you plan to use it, might want to also plan to maintain it.

0:30 Scriptor: what's the currently maintained one, if any?

0:30 Raynes: Parsley.

0:31 ihodes: what about clj-peg? http://lithinos.com/clj-peg/

0:31 was recently updated, if memory serves

0:36 Raynes: org.apache.commons.compress.archivers.tar.TarArchiveInputStream

0:36 Jesus.

0:36 Anniepoo: anybody know where the clojure version is stored for slime/swank for windows?

0:39 duck1123: Raynes: seems perfectly reasonable

1:02 ben_m: I need to make a nicely organised list of libraries I discover from just idling here.

1:03 I bet sometimes in the future I'll think to myself "Mhh, I need to fiddle with some bits, but that's a pain in Clojure. Meh, seems like I'll use C." because I won't think about gloss.

1:12 tomoj: is there a workaround (e.g. lein feature?) for http://dev.clojure.org/jira/browse/CLJ-322

1:14 accel: if you do, you should make it into a big index

1:14 and call it clojure_yahoo

1:15 then, when you use eigenvectors to rank (based on which libraries use which other libraries), it cal be called clojure_google

1:15 tomoj: I mean, am I correct that: if project A and project B both depend on project C, A depends on B, C is not AOT'd, B is; then A may get B's version of C because B includes C's classfiles in the jar, barring manual cleanup of B's jar?

1:48 spoon16: what is the appropriate way to "forward" kw-args to another function?

1:48 ,(letfn [(a [& kw-args] (b kw-args)) (b [& kw-args] (apply hash-map kw-args))] (a))

1:49 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: null>

1:59 amalloy: spoon16: my personal opinion is: try not to do that. make your "real" functions take actual hashmaps, and add variadic keyword versions of them as sugar only

1:59 it's both inefficient and awkward to do this forwarding, as you've discovered

2:00 spoon16: yeah, that's the direction I ended up going… but I was wondering if there was some way to do it cleanly that I was missing

2:00 thanks

2:00 amalloy: well, if you changed a to (apply b kw-args) it would be fine

2:03 spoon16: amalloy: that only works in this example though, if you have any other arguments you end up having to build do something like (apply b (flatten [arg1 arg2 kw-args]))

2:03 which seems a bit gross

2:03 amalloy: uh. no, and also flatten is 100% wrong there

2:04 (apply b arg1 arg2 kw-args)

2:05 spoon16: sorry… I meant (filter (not nil)) not flatten

2:05 if kw-args is nil then apply will pass it through… which I guess is ok here… but if you want to destructure kw-args into a map it will fail

2:06 because (= kw-args '(nil)) instead of nil

2:07 (apply hash-map '(nil)) also fails

2:07 the right thing to do is do what you recommended earlier and make b just take kw-args as a first class arg instead of & kw-args

2:08 amalloy: it is not the case that kw-args is (nil)

2:13 spoon16: you are right… let me figure out what's going on in the larger piece of code I have and see if I can distill it down

2:16 amalloy: in my case I'm not using apply appropriately

2:17 so using apply does work pretty nicely

2:18 still, I think it's even cleaner to just have b explicitly take a kw-args parameter instead of making it optional

3:36 lnostdal: i read http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/ , then tried -- but i get different results: http://paste.lisp.org/display/126429#1

3:36 perhaps a clojure 1.2.x vs. 1.3.x thing? .. i'm testing with a 1.4 snapshot though

3:36 what do you guys get?

3:38 tscheibl: .

3:42 kral: when does 1.4.x will be released as stable?

3:47 Chousuke: lnostdal: that looks like the correct result to me, because of the set!

3:51 raek: lnostdal: I think work has been done to address the "Bindings do not migrate across thread boundaries." problem

3:52 iirc, bindings migrate to a new thread if you use 'future' (which pmap does internally)

3:52 ...since clojure 1.3

4:08 lnostdal: getting really tired of nullpointerexception, unknown location ..

4:08 raek, that's good news i guess

4:09 raek: lnostdal: unknown location? have you looked in the stack trace?

4:09 it should point to the exact point where it was thrown

4:09 lnostdal: i wonder if it migretes with regards to agents too

4:10 yeah, i guess it can't find location because the stacktrace ends up some other place (perhaps related to data for it not migrating across threads :P)

4:10 or some slime/swank try block doesn't get included in spawned threads or something

4:11 raek: you cannot catch an exception thrown by one thread in a catch block in another thread

4:11 since the control flows are unrelated

4:12 if you use a future, you will get the exception when/if you dereference it

4:13 lnostdal: yeah, but i guess slime or swank-clojure or something handles some cases; sets up the context needed to catch from some threads but not all

4:13 because it does catch e.g. (future (/ 42 0)) .. that ends up in the slime debugger

4:13 at least on clojure-1.4 here

4:13 raek: lnostdal: that's because the repl prints the future

4:13 which will dereference it

4:14 lnostdal: try this: (def x (future (/ 42 0)))

4:15 lnostdal: uh, a future doesn't execute before it is derefed? ..

4:16 in that case the docstring is wrong i think

4:16 raek: no, it does. but the exception is stored in the future.

4:16 lnostdal: ah, cool

4:16 raek: you get that exception when you try to look at the result of the future

4:17 lnostdal: i guess that makes sense in a world without restarts anyway

4:17 raek: futures are really made for asynchronous tasks where you want to start a bunch of processes in the background and then retrieve their values

4:18 if you want a long running background thread, you should include your own try/catch block at the top level of the future body

4:18 since in that case there is usually not another thread that "waits for the result"

4:19 lnostdal: yeah, loop+recur .. with a sleep at the outside in case something gets stuck in fail-over-and-over-again mode :P

4:19 (potentially flooding logs or *out* / *err*)

4:24 tscheibl: really funny are exceptions thrown when a lazy sequence gets realized ...

4:26 lnostdal: yeah, sometimes i wonder if what i really want is just green threads (spread over hardware threads; like done in e.g. haskell, would be nice) so i can do classic blocking i/o and exceptions and other things "make sense" again

4:26 no epoll .. no async .. just blocking calls with regards to http and socket i/o .. log i/o .. and db i/o .. simple

4:27 but i don't know .. i haven't thought about this much .. perhaps it won't solve any problems

4:28 tscheibl: don 't think so... real life is async, too... and we managed to handle it somehow for some thousend

4:28 years now :)

4:28 ..thousand

4:29 lnostdal: while i'm on a roll; "Unable to resolve symbol: blabla in this context" ..what context??? give me a file name at least! :>

4:29 tscheibl: .. and using clojure it becomes quite manageable

4:29 i do a (print-stack-trace e*)

4:29 in these cases

4:31 ..just do a (use 'clojure.stacktrace) beforehand

4:34 lnostdal: yeah, or sometimes evaling the core.clj buffer with the (ns ...) in it will yield a proper message with filename and even line numbers

5:05 AWizzArd: Moin moin.

9:53 TimMc: So... the EPL doesn't have a viral clause?

10:15 raek: TimMc: it explicitly says that a piece of code that merely uses the EPL'ed code as a library is not a derivative work of the EPL'ed code, so the library does not place any restrictions on the licence of code that uses the library

10:18 (this is in contrast to the GPL, which interprets "derivative work" differently)

10:19 so the EPL is not a viral license

10:42 TimMc: Ah, it's in the definition of derivative work, then. I see.

10:48 * TimMc creates the UPL (Unenforceable Public License) which requires that anything the Program links *to* be released under the UPL as well.

11:01 raek: TimMc: why would that be unenforcable? this is the case for all strong copyleft licenses, if I understand you correctly...

11:02 I don't think there i any difference between "X is bolted onto Y" and "Y is bolted onto X" in legal terms

11:03 it's more like "Z = the union of X and Y. Z is a derivative work of both X and Y."

11:05 TimMc: raek: Imagine a license that said that since your program links to libc (or whatever), libc has to be relicensed.

11:05 Ugh, still didn't express that well. Never mind, it's a stupid joke,

11:06 and I hate hitting comma instead of period at the end of a message, because it makes me feel like I have to type more.

11:06 * raek tries to image a law system where the UPL is in the position to make those demands...

11:07 raek: a crazy license indeed... :-)

11:42 sirn: What's the best way to check if item exists in a coll? e.g. in Python I could do "5 in [1, 2, 3, 4, 5] #=> True"

11:42 lucian: any idea if i could find videos for http://clojure-conj.org/schedule ?

11:42 gtrak`: ,(doc contains?)

11:42 clojurebot: "([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."

11:42 sirn: gtrak`: thanks!

11:42 gtrak`: keys though

11:43 ,(doc some)

11:43 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

11:43 sirn: ah

11:43 Wild_Cat: sirn: that won't work

11:43 contains? checks whether the *index* exists

11:43 sirn: yeah, just tried it

11:43 Wild_Cat: that is, (contains? n vector) just checks whether the nth item exists

11:44 gtrak`: ,(some #{:theKey} [1 2 3 4 5])

11:44 clojurebot: nil

11:44 gtrak`: ,(some #{:theKey} [1 2 3 :theKey 5])

11:44 clojurebot: :theKey

11:44 Wild_Cat: ,(some #(= %1 2) [2 3 4 5])

11:44 clojurebot: true

11:44 Wild_Cat: ,(some #(= %1 1) [2 3 4 5])

11:44 clojurebot: nil

11:45 sirn: that one works, thanks!

11:45 cmiles74: You could do a list comprehension...

11:46 TimMc: &(.contains [:a :b :c] :b) ; sirn

11:46 lazybot: ⇒ true

11:47 gtrak`: cmiles74, some does that for you: https://github.com/clojure/clojure/blob/f5f827ac9fbb87e770d25007472504403ed3d7a6/src/clj/clojure/core.clj#L2353

11:47 cmiles74: Gotcha'.

11:47 sirn: TimMc: nice! Is that .contains a Java stuff?

11:48 gtrak`: yes

11:48 TimMc: sirn: It uses the fact that all the Clojure collections implement the java.util.Collection (or whatever) interface.

11:49 sirn: TimMc: ah, I see.

11:49 TimMc: &(instance? java.util.Collection [])

11:49 lazybot: ⇒ true

11:49 blakesmith: TimMc: That's useful to know, thanks.

11:53 TimMc: I can't tell where it gets that interface from, though.

11:56 Oh, got it: ##(isa? (class []) java.util.List)

11:56 lazybot: ⇒ true

11:57 Wild_Cat: doesn't List specify .add, though?

11:57 I thought vectors were immutable?

11:58 TimMc: Yeah, but java.util.Collection specifies that some operations may be rejected.

11:58 cemerick: ,(.add [] "foo")

11:58 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException>

11:58 Wild_Cat: good point.

11:59 TimMc: Wild_Cat: cf. java.util.Collections#unmodifiableMap

12:00 &(.containsAll [1 2 3 4] [2 3])

12:00 lazybot: ⇒ true

12:00 Wild_Cat: &(.contains [2 3 4] 2])

12:00 lazybot: java.lang.RuntimeException: Unmatched delimiter: ]

12:00 Wild_Cat: &(.contains [2 3 4] 2)

12:00 lazybot: ⇒ true

12:00 Wild_Cat: &(.contains [2 3 4] 1)

12:00 lazybot: ⇒ false

12:00 TimMc: It's a sight nicer than using "some".

12:01 *abusing

12:01 Wild_Cat: aye.

13:03 micahmartin: ,*ns*

13:03 clojurebot: #<Namespace sandbox>

13:04 micahmartin: ,(binding [*ns* (the-ns 'clojure.core)] (do (println *ns*) (lazy-seq [*ns*])))

13:04 clojurebot: #<Namespace clojure.core>

13:04 mbac: what's the right way to terminate repeatedly?

13:04 clojurebot: (#<Namespace sandbox>)

13:05 micahmartin: Does anyone know why lazy-seq looses it *ns* binding (see above clojurebot)?

13:06 mbac: what do you mean "terminate repeatedly"?

13:06 gtrak`: ,(doc repeatedly

13:06 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>

13:06 gtrak`: ,(doc repeatedly)

13:06 clojurebot: "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"

13:06 Bronsa: micahmartin:

13:06 ,(with-redefs [*ns* (the-ns 'clojure.core)] (do (println *ns*) (lazy-seq [*ns*])))

13:06 clojurebot: #<Namespace sandbox>

13:07 (#<Namespace sandbox>)

13:07 Bronsa: no wait

13:07 this is worse

13:07 micahmartin: mbac: ahh. it's an infinite sequence. Try 'take or 'take-while.

13:08 Bronsa: interesting.. didn't know about with-redefs

13:12 Bronsa: Do you know the history of with-redefs? Why is binding not sufficient?

13:15 dnolen: micahmartin: lazy sequences and bindings do not work well together.

13:15 micahmartin: dnolan: incidentally? or Intentionally?

13:16 mbac: i see

13:18 dnolen: micahmartin: if you consider how lazy sequences work, how can they interact with dynamic binding?

13:18 micahmartin: binding and with-redefs seem like the same thing.

13:19 dnolen: micahmartin: they are not, with-redefs is about dealing with vars that are not dynamic.

13:20 micahmartin: dnolan: with-redefs allows rebinding of non-dynamic vars?

13:20 technomancy: temporary redefinition, not rebinding.

13:20 micahmartin: I see it just redefines them.

13:20 technomancy: it's mostly intended for test-time use; I would be deeply suspicious of any code that used it at runtime

13:21 micahmartin: dang, I wish I know knew about this a few weeks ago… it's helpful

13:22 technomancy: makes sense… but in the case where I need to rebind/redefine *ns*, should I be using something other than with-redefs?

13:22 eg. (with-redefs [*ns* (the-ns 'clojure.core)] (do (println *ns*) (lazy-seq [*ns*])))

13:23 technomancy: yeah, definitely something different; the seq will escape the scope of with-redefs. you need lexical scope if you want it to stay.

13:24 dnolen: micahmartin: you don't need with-redefs w/ *ns*, *ns* is dynamic

13:24 micahmartin: you might be able to solve your problem by forcing the lazy sequence inside binding

13:25 micahmartin: dnolen: I was just thinking the same thing

13:25 dnolen: micahmartin: I've found that technique useful when writing macros.

13:26 micahmartin: dnolen: yes, doall did the trick.

13:26 dnolen: micahmartin: cool

13:28 TimMc: If I ever write a regex lib, it's going to be called "two-problems".

13:29 dnolen: Seems like a kind of ugly surprise. So... bindings only applies inside the current stack-tail?

13:30 and seqs escape that?

13:30 technomancy: well yeah, that's why you shouldn't use bindings any more than you have to.

13:31 dynamic scope doesn't compose well

13:35 gtrak`: TimMc, bindings to vars follow a threadlocal stack discipline

13:36 dnolen: TimMc: its really is not surprising if you consider lazy sequences and dynamic binding. There was some discussion about special casing IO lazy seqs but nothing much has evolved on that front.

13:36 gtrak`: hmm, what if you do the binding in a map call?

13:37 like, (map fn2 (map fn1 coll)) where fn1 does a binding, would fn2 see the binding?

13:38 wait, that doesn't make sense

13:38 dnolen: gtrak`: was about to say that :)

13:38 gtrak`: you'd have to split the binding :-)

13:39 TimMc: Someone write a "Clojure pitfalls" thngy and put this on it.

13:42 gtrak`: something like (map pop-bindings (map your-fn (map push-bindings coll)))

13:46 technomancy: has anyone used clojure.java.jdbc with postgres hstore columns?

13:46 I'm too unfamiliar with postgres to tell the difference between unsupported features and pebkac.

14:00 looks like the two options for jdbc+hstore are either some jar file checked into an openstreetmap subproject's git repo or a couple pages of java code someone who claims to be bad at java has posted to a mailing list.

14:00 exciting.

14:08 cmiles74: I had never heard of this hstore thing before I read the HN article this morning.

14:09 technomancy: it's a pretty well-kept secret

14:09 there's a single page of reference docs with zero "getting started" material

14:12 rlb: I thought it was pretty new, too.

14:13 technomancy: I think it was distributed as a contrib pre 9.x

14:13 cmiles74: I see an article on the PG mailing list from 12/2009 with some prototype code, but it doesn't look like it's made it into the actual driver.

14:16 technomancy: yeah, I have no idea what to make of that. could you just compile it and start using it, or would you have to register it as a new type with the jdbc driver?

14:16 also: is there a reason it was never added to the driver itself?

14:21 cmiles74: My guess is that you can compile and then start using it. PG has a bunch of their own datatypes and I think it'd work in a similar way.

14:22 technomancy: it turns out the jar in osmosis's git repo is that very code: https://github.com/oschrenk/osmosis/commit/84a5fc574717b3c5bc41520f370b9fc8807798cd

14:22 cmiles74: ((org.postgresql.PGConnection)conn).addDataType("geometry",Class.forName("org.postgis.PGgeometry"));

14:22 technomancy: aha; thanks!

14:23 cmiles74: Section 5.2 of this document has more sample code: http://postgis.refractions.net/docs/ch05.html

14:23 It's not exactly the same thing, but at least it's something.

14:24 technomancy: what better way to reintroduce myself to postgres after four years of not using it?

14:24 cmiles74: :P

14:28 mrb_bk: hey everyone, i'm working on a redis rdb file parser in clojure, i'm a complete clojure noob

14:28 here's what i have going so far https://gist.github.com/6dcba245ab08354a0a8d

14:28 it doesn't do much :) just reads the magic number

14:29 if anyone has any comments, that would be great

14:31 technomancy_: cmiles74: for the record, it's as simple as this: (sql/insert-rows :mytable [(PGHStore. my-map)])

14:31 since PGHStore has a j.u.Map constructor

14:31 (this is with the jar from the osmosis project)

14:31 which is extremely sketchy, but whatever

14:32 cmiles74: Gotcha'. Thank you, I've been thinking about trying this out. :)

14:36 technomancy_: https://clojars.org/org.clojars.technomancy/osmosis-hstore for the record

14:46 TimMc: mrb_bk: Have you looked into using gloss?

14:47 mrb_bk: TimMc: I did, but I found it to be way too complex for me at this point

14:47 TimMc: for example I was having a difficult time even getting file --> lazy seq --> gloss

14:48 it looks like a good solution and in general i get it, but it's a lot of extra cognitive dissonance for me right now as I'm also trying to learn the language

14:50 amalloy: i just discovered git checkout has a -p option, mirroring the -p in add/reset. <3 git

14:50 mrb_bk: TimMc: does that make sense?

14:54 technomancy: is there a better way than (apply sql/do-commands (.split (slurp (io/resource "hstore.sql")) ";")) to run all the sql in a given file?

14:54 that feels a bit gross

14:55 TimMc: mrb_bk: Makes sense.

14:55 technomancy: I guess it's fine.

14:55 TimMc: technomancy: Not if you have ; in strings.

14:56 or comments

14:56 technomancy: TimMc: yeah, fine in this case I mean.

14:56 TimMc: Are you feeling lucky?

14:57 technomancy: seancorfield: is that something that should be added to the c.j.jdbc API?

15:02 duck1123: Has anyone had issues with delimiters and the newer versions of korma? It insists on either giving me a NPE or escaping the table names with double quotes

15:04 I love asking a question. It's a sure fire way to make sure it works on the very next test

15:21 powrtoc: I'm having some problems with clojure-mode and clojure-jack-in :-()

15:22 I get the following error: error in process filter: Search failed: "(run-hooks 'slime-load-hook) ; on port"

15:22 any ideas?

15:22 technomancy: powrtoc: try swank-clojure 1.3.3 or 1.3.4-SNAPSHOT

15:23 powrtoc: I'm on 1.3.3, but I'll try the 1.3.4-SNAPSHOT

15:24 I also tried 1.4.0-SNAPSHOT

15:25 technomancy: cheers... 1.3.4-SNAPSHOT works

15:25 :-)

15:26 technomancy: better get that released I guess

15:26 powrtoc: I knew I should've logged in here and asked, rather than spend 35 minutes faffing with it :-)

15:53 * amalloy just found himself writing (apply f [a b c]) instead of (f a b c)

15:53 ibdknox: lol

15:53 whoops :p

15:54 amalloy: ibdknox: (apply f (cons a (list* b [c]))) for good measure?

15:54 ibdknox: amalloy: that would be the safest.

15:54 ;)

15:59 ilyak: https://gist.github.com/1469066

15:59 Hi *

15:59 I have this slow function

15:59 profiler tells me clojure spends most of its time by converting long to int and vice versa

15:59 how should I write this code to it become efficient?

16:03 dnolen: ilyak: did you (set! *warn-on-reflection* true) ?

16:04 ilyak: dnolen: One sec

16:04 But I don't thing it would tell anything meaningful

16:05 dnolen: No lines in this fn trigger any warnings

16:08 dnolen: ilyak: can you add the defn for color to your gist?

16:09 ilyak: dnolen: https://gist.github.com/1469066

16:09 but it's basically instant

16:10 range seems to be a pretty inefficient function

16:11 But I don't really know what to replace it with

16:11 dnolen: ilyak: I see reflection warnings.

16:11 ilyak: explicit loop seems meh ugly

16:11 dnolen: in create-image?

16:12 dnolen: ilyak: in two places, you need to figure that out first - https://gist.github.com/1469123

16:12 ilyak: explicit loops for perf is fine, especially for something like this.

16:13 ilyak: using seqs for control when you're dealing with side-effects like this is a waste.

16:14 Wild_Cat: hrmm. Why is there no Leiningen 1.6.x Windows distribution at https://github.com/technomancy/leiningen/downloads ?

16:14 ilyak: dnolen: Color ctor and getRGB are both called exactly once

16:15 No reason to bother, except perhaps I should fix the white as (int )

16:16 dnolen: ilyak: ah you're right, but looking at the Javadocs setRGB is suspect

16:17 ilyak: explicit loop is much much faster

16:18 dnolen: ilyak: setRGB seems strange to me, you have boxed longs in range, but setRGB takes prim int

16:18 ilyak: No, it isn't

16:19 I'm so dumb

16:19 dnolen: ilyak: if explicit loop isn't faster then consider my last point.

16:21 ilyak: I suddently decided to stop caring about performance because it takes more human time than reduces computer time

16:21 TimMc: haha

16:23 dnolen: ilyak: what are you basing your setRGB call on? The javadocs say, int int int for the signature

16:38 technomancy: Wild_Cat: the windows maintainer is just behind schedule

16:38 Wild_Cat: OK, nothing to worry about then. Thanks.

16:45 cemerick: Odd: this emits a reflection warning for .equiv: (= (.charAt "f" 0) (.charAt "f" 0))

16:49 hiredman: there is equiv inline for characters

16:49 or wasn't last I looked

16:49 cemerick: right, and .charAt returns a char

16:50 hiredman: and Utils.equiv may take Object Object

16:50 weavejester: I've just updated clojure-mode and I can no longer connect to SLIME...

16:50 hiredman: updated to what, the lastest master?

16:51 weavejester: Just 1.11.4

16:51 djhworld:


16:51 > hello world

16:51 hsbot: Not in scope: `hello'Not in scope: `world'

16:51 djhworld: whoops

16:51 weavejester: Via marmalade, I believe.

16:51 Does: error in process filter: Search failed: "(run-hooks 'slime-load-hook)

16:51 seem familiar to anyone?

16:51 hiredman: latest according to git is 1.11.2

16:52 weavejester: package-list-packages claims 1.11.4...

16:53 And the latest commit on technomancy's repo is "Release 1.11.4.

16:53 So I think the release is correct :)

16:53 I wonder whether I need to update swank-clojure or something?

16:54 technomancy: crap, yeah I need to fix that

16:54 swank-clojure 1.3.4-SNAPSHOT should fix it

16:54 but it's dumb for it to require a snapshot.

16:55 weavejester: I'll try that :)

16:55 Might want to put a notice on it or something, or release a new version...

16:55 technomancy: wait... it should work with 1.3.3 actually

16:55 what are you on?

16:56 weavejester: 1.3.2

16:57 Or I was. I've just upgraded the plugin

16:57 Ah, it works now.

16:59 technomancy: just pushed a new clojure-mode; I think it should be more forgiving of earlier swank versions now

17:01 weavejester: Awesome :)

17:01 By the way, is there anything I need to do to enable SLIME completions?

17:01 I've never been able to get that to work.

17:02 technomancy: in the repl or in clojure-mode?

17:03 weavejester: In clojure-mode

17:03 technomancy: M-TAB works for me, but I don't remember if I did anything special to set it up

17:04 weavejester: M-Tab is my window switcher :) - I think by default it's M-\ ... or is that something else?

17:05 technomancy: there are a number of completion mechanisms; some of which can multiplex to others composably. M-TAB is a way to directly access the slime-specific one.

17:06 you can tie the slime completion mechanism into hippie-expand, for instance

17:06 weavejester: Emacs completions are a bit of a mystery to me. I was thinking of smart-tab, which I assume completes on tab

17:07 technomancy: hm. I am deeply suspicious of rebinding TAB to mean anything other than indent.

17:07 weavejester: I think it either indents or completes depending on the context.

17:07 technomancy: C-i is another way to invoke TAB without triggering your WM

17:08 so you can try C-M-i

17:08 amalloy: yeah, C-M-i is one way

17:08 weavejester: Oh yeah, that works.

17:08 I need to find a better key combo though. Maybe I'll try hippie

17:09 amalloy: i wind up doing something similar on occasion, using C-j to insert a newline. i configured RET to automatically reindent (arguably because i'm stupid), so when i don't want to i can use C-j

17:09 technomancy: IIRC hippie-expand is the one that can cycle through a number of different completion mechanisms

17:09 weavejester: Not sure I really need that, then

17:20 Aha, got it working.

17:28 bhenry: i need to add to the end of a list? how should i do this?

17:30 dnolen: bhenry: you should use a vector, otherwise concat might work for you.

17:30 bhenry: i have headers = [:a :b :c] and am cons-ing them to the beginning of the data formatted as a list of vectors like [1 2 3]. then i want to add the footers [6 5 4] at the end, so i can run a nice little tab-formatting function over the result.

17:30 ah i was thinking that. didn't know if it would be super frowned upon to turn them all into vectors.

17:42 TimMc: technomancy: Hey, lein 1.6.2 is defaulting to 1.3.0 in new projects -- did 1.6.2 just get released or something?

17:43 technomancy: TimMc: a few weeks ago

17:43 TimMc: nice

17:43 Turtl3boi: why is clojure used for web programming?

17:43 TimMc: Why not?

17:44 Turtl3boi: haha i dunno just wondering. i thought php/javascript and all that was rather entrenched

17:47 brehaut: Turtl3boi: nothing is 'entrenched' on the server side

17:49 (except for existing projects)

17:49 weavejester: Turtl3boi: Lots of languages are used for web development.

17:50 Turtl3boi: how can i start using clojure on a free web server?

17:50 or would i have to get a paid hosting and then set it up myself

17:50 weavejester: I believe Heroku has a free tier

17:50 * technomancy points discreetly to http://devcenter.heroku.com/articles/clojure-web-application

17:50 cemerick: As does GAE and Amazon Elastic Beanstalk.

17:50 Turtl3boi: emm what is techomancy

17:51 is that a bott

17:51 weavejester: Amazon only have it for the first year

17:51 cemerick: right

17:51 Turtl3boi: what's amazon elastic beanstalk?

17:51 weavejester: technomancy isn't a bot :)

17:51 technomancy: weavejester: is it because of your childhood that you say technomancy isn't a bot :)?

17:51 weavejester: Or if he is, he's a sentient AI and we're only years away from Skynet

17:51 Turtl3boi: i had never seen someone's name italicized b4

17:51 weavejester: Clearly of superior intelligence to us mere mortals :)

17:52 technomancy: not if I can't pass the reverse turing test.

17:52 weavejester: Elastic Beanstalk is Amazon's cloud-hosting platform.

17:52 Basically you can host Java servlets without having to worry about infrastructure, and Clojure web apps can be packaged as servlets.

17:53 technomancy: weavejester: congrats on the 1.0 release btw

17:53 weavejester: weavejester: Of Ring? Took us long enough to get there :)

17:53 But then I guess stability is a good thing for a project like that!

17:53 technomancy: yeah, definitely want that slow-moving stability at that layer of the stack

17:54 brehaut: weavejester: its not like the pre 1.0.0 releases were shonky though

17:54 weavejester: Compojure should be going 1.0.0 soon, too. I've just released an RC version. Not much change.

17:54 brehaut: True. That's why we figured we should go and release an official stable version :)

17:54 brehaut: hah fair enough :)

17:55 technomancy: is there still a plan to move it to a contrib, or was that just a rumor?

17:55 Turtl3boi: so what would clojure be used for in web design? the backend or the frontend

17:55 does it replace the PHP kinda

17:55 weavejester: technomancy: Weeeell... there was, and it still might happen, but not everyone who's contributed to Ring is on the Clojure's contributor agreement.

17:56 technomancy: yeah, I fail to see the upside for such a thing

17:56 weavejester: I don't really see much of an upside either, reallly...

17:56 I mean, it would be more official, but it would take a lot of work to get people to sign or replace code.

17:56 technomancy: it's not like it needs the Blessing of the Chosen for people to realize ring is where it's at.

17:56 weavejester: And it would impede future patches.

17:57 technomancy: and you'd have to use jira.

17:57 weavejester: Turtl3boi: It's more the back end, yeah

17:57 Turtl3boi: But Clojurescript compiles into Java, so potentially the front end too. That's still a little experimental though.

17:57 Er, Javascript I mean

17:57 Turtl3boi: ahh ok interesting

17:58 weavejester: technomancy: Oh yeah. I prefer Github really. Clojure's process seems a little too formal, which is good for a language, but maybe not for a library.

17:58 technomancy: good to know

17:59 weavejester: technomancy: By the way, I was thinking of creating a ragtime.leiningen subproject

17:59 which would add leiningen tasks like "lein migrate" and "lein rollback"

17:59 But I haven't quite figured out how people would hook their libraries into that.

18:01 technomancy: weavejester: I wonder if it wouldn't be better to run migrations via "lein run -m ragtime.migrate" or the like

18:01 weavejester: Or... maybe I could keep it simple, and just provide functions that people could use in their Leiningen plugins.

18:01 technomancy: then the function can still be invoked from an uberjar or war file when leiningen isn't present

18:01 at deploy time

18:01 weavejester: technomancy: Oh sure

18:01 cemerick: weavejester: Congrats, and thanks for everything :-D

18:01 weavejester: But having a small leiningen plugin to wrap around that might be nice...

18:02 cemerick: Thanks :)

18:02 I'm thinking that a library like Migratus could just pass a list of migration maps to Ragtime

18:02 And then Ragtime handles all the rest

18:02 Kinda like a Ring for migrations.

18:03 cemerick: weavejester: I'll have to bug you re: a lein-beanstalk release now.

18:04 weavejester: cemerick: Do you want to be added to the lein-beanstalk project? :)

18:04 cemerick: As a maintainer

18:04 cemerick: Risky move. ;-)

18:05 Fine by me.

18:05 I just don't want -SNAPSHOT versions floating around in the book.

18:05 weavejester: I'm probably not going to be personally invested in lein-beanstalk for a while, so if you are, then better to have someone who is using it

18:05 Or at least intested in its development.

18:06 cemerick: I use beanstalk quite a bit, and will be using lein more and more…so, sure. :-)

18:07 weavejester: cemerick: Perfect :)

18:07 cemerick: Your github account is "cemerick" too, right?

18:07 cemerick: Nope, that's my doppelganger that creates bugs all the time.

18:08 Might use a lein-beanstalk branch to figure out the new lein profiles / plugins / etc. action, actually.

18:08 (Yes, cemerick is me nearly everywhere.)

18:08 weavejester: Just making sure

18:09 cemerick: Sorry for the out-of-place not-really-humor. It's shaping up to be an odd week.

18:09 weavejester: Okay, you should be added.

18:09 np :)

18:09 Let me add you to clojars as well...

18:10 (I'm assuming you're cemerick on clojars, too :)

18:11 You're now added on Clojars too. Feel free to push out releases.

18:11 cemerick: yup

18:11 Great, thanks. I'll be sure to ping you on anything more than patch-level stuff.

18:12 gtrak`: Turtl3boi, take a look at noir for a full framework or ring and moustache for a minimal one

18:13 Turtl3boi: gtrak but that can't run on a free web host usually right?

18:13 gtrak`: though noir is pretty minimal too

18:13 Turtl3boi, yea, you can run all this stuff on heroku

18:13 Turtl3boi: so i can go setup a byethost free web server account and install heroku on it

18:13 gtrak`: Turtl3boi, no, get a heroku account: http://thecomputersarewinning.com/post/clojure-heroku-noir-mongo

18:14 doubtful you'll get a free web host that does jvm stuff

18:14 but heroku does it

18:15 * TimMc wonders if this will show up in italics in Turtl3boi's IRC client

18:15 gtrak`: is TimMc a bot?

18:16 Turtl3boi: yes Tim lol

18:16 i'm an IRC IDIOT so far

18:16 gtrak`: TimMc, how'd you do that?

18:16 Turtl3boi: i need to stop using chatzilla

18:16 TimMc: Turtl3boi: The first thing was me using /me to do an action.

18:17 gtrak`: That was /notice, which is the thing clojurebot uses to announce clojars news.

18:17 gtrak`: ah

18:17 TimMc: /notice #channel message

18:18 It's supposed to come in at a lower priority than privmsg.

18:18 ...although apparently some clients make it stand out *more* for no good reason.

18:19 amalloy: mine just treats it like a regular message with the string "(notice) " prepended to it. kinda silly but useable

18:20 * Turtl3boi what's up guys

18:20 Turtl3boi: holy crap that's so cool!

18:20 TimMc: haha

18:20 Turtl3boi: And if you need to start a message with a slash, use /say

18:21 Turtl3boi: Program Files/SexGame/hornyphoto.jpg

18:21 gtrak`: /

18:21 Turtl3boi: what did i do wrong

18:21 gtrak`: /say ...

18:21 Turtl3boi: /Program Files

18:22 oh right....... lol see how slow i am with computer syntax

18:22 why is that guys who generally work on Clojure and other cutting edge stuff are less smug than the guys in the #C and #C++ channels

18:23 Raynes: weavejester: Being able to accept contributions > being official.

18:23 lancepantz: Turtl3boi: i like to think it's because we have a higher quality of life, due to clojure :)

18:24 Raynes: lancepantz: I think you just canceled what he said out by being smug.

18:24 gtrak`: maybe it's just harder to notice the smug b/c of the lang

18:24 Raynes: The politically correct response is "Aw, shucks. I don't know!"

18:24 Turtl3boi: ROFL

18:25 btw gtrak i'm finally starting to understand fully that python code you gave me for that graphics course you took

18:25 lol see how slow i am

18:27 do you guys all use Linux for main OS?

18:30 gtrak`: Turtl3boi, i think it has some mistakes in it

18:30 Turtl3boi: haha possibly

18:30 it's ok i get the gist of it now

18:30 gtrak`: and it was like the first python i ever wrote

18:30 Turtl3boi: still haven't been called back for an interview for that graphics position i applied for

18:31 lol ya

18:31 i think i'm gonna give up on graphics

18:31 gtrak`: it's not a large market

18:32 Turtl3boi: yeah but Nvidia does pay well if you can get in

18:32 gtrak`: yea, i have a buddy there

18:32 Turtl3boi: but yeah it isn't a large market at all

18:33 gtrak`: enterprise and web will keep you fed while you're learning

18:33 Turtl3boi: what's enterprise?

18:33 like just making apps that run locally

18:33 gtrak`: enterprise is like pornography, you know it when you see it

18:34 Turtl3boi: haha

18:35 gtrak`: enterprise is a pretty big term, like something that isn't exactly just web

18:44 srid: is there a library like lamina for ruby (preferably using eventmachine)?

18:47 Turtl3boi: what's the easiest way of writing a web app

18:47 with HTML5 and Javascript?

18:48 technomancy: first you should take a working web application, read its source, and attempt to modify it.

18:48 you can start with the sample at http://devcenter.heroku.com/articles/clojure-web-application

18:49 Turtl3boi: where's the sample?

18:50 * Turtl3boi looks around

18:50 technomancy: it's linked to in the article

18:52 rickmode: I'm toying with the idea of deploying clojure via source file *outside* of jar files. I tried clojure.lang.Compiler.loadFile, however that doesn't work when using or requiring forms from other source files (refer does work).

18:52 So I know adding my source path to the app's classpath works. Is there another way that doesn't involve changing the hosting app's classpath?

18:53 technomancy: you can go in and mangle clojure.core/*loaded-libs* if you want to really go nuts

18:54 just don't tell anyone I told you that

18:54 cemerick: rickmode: are you trying to update a running app, or something else?

18:55 rickmode: cemerick: ya - I'd like to be able to edit the source, then reload it via a REPL.

18:55 cemerick: rickmode: if you make sure some directory is on the app's classpath, then you can dump source files in there to your heart's content, and load (or reload) them remotely from the REPL.

18:56 rickmode: Imagine code running on a customer site that you may want to tweak. So you extract the source from the jar, do some magic, and (perhaps after restarting the app), the app now uses the files rather than the version inside the jar

18:56 cemerick: Alternatively, you could just load all the code you want through the REPL.

18:56 technomancy: rickmode: just put a directory on the classpath ahead of the jar

18:56 then you can place the modified source there

18:56 cemerick: what technomancy said

18:57 technomancy: (assuming you're squeamish about editing the jar directly)

18:57 qbg: rickmode: load-file doesn't work foryou?

18:57 rickmode: cemerick / technomancy: ya that sounds like the best option. And the upside is there is no config change needed.

19:00 qbg: if I have code in two source files, then use and require fail, since those both *only* use the classpath. I *thought* using load-file dependencies first would work, but even though the dependence source loads fine (imagine it's a utils.clj thing), using require in my core.clj still searches the classpath rather than realize the namespace is already available. It makes sense actually. It's just a drag something like load-file w

19:00 It's just a drag something like load-file would _not_ work.

19:01 technomancy: it would work if everything downstream was also implemented in terms of load-file

19:02 rickmode: technomancy - ya - but that means using (refer ..) and such. The code won't look the same as the jar'd version.

19:02 technomancy: right, I mean, people use that stuff because it's much more convenient than thinking in terms of files all the time

19:02 rickmode: it's a subtle distinction - the load-file / script style vs. the classpath / use / require style

19:03 bloop: forgive me if this is a dumb question, but what is the difference between 1N and 1?

19:03 qbg: 1N is a bigint

19:03 seancorfield: ,(type 1N)

19:03 clojurebot: clojure.lang.BigInt

19:04 bloop: why does (/ 1/2 1/2) produce a bigint?

19:04 rickmode: technomancy / cemrick / qdb: Ok cool - I was just making sure I hadn't missed something.

19:04 alexbaranosky: any of you all use Marginalia? I'd be excited to hear more about what it does

19:05 Turtl3boi: alex what exactly do you do now for a living

19:05 qbg: bloop: Ratios are ratios of bigints, so it makes sense...

19:05 brehaut: it rejiggers your documentation and code to be equals

19:05 Turtl3boi: would you say it's hard to do what you do

19:06 bloop: qbg: ok then...

19:06 alexbaranosky: Turtl3boi, program on a piece of software called the Trade Idea Monitor, a kind of network for equity (mostly) brokers and buyers

19:06 in Java and Scala, we do pretty much XP, with some twists

19:06 Turtl3boi: omg you do programming for the finance industry

19:06 i heard that can be a nice industry

19:06 what's XP?

19:06 alexbaranosky: Turtl3boi, hard? I guess, but fun

19:07 qbg: XP = extreme programming

19:07 alexbaranosky: programming is hard if you do it right :) Because you are always optimizing out the easy bits

19:07 qbg: http://en.wikipedia.org/wiki/Extreme_programming

19:07 alexbaranosky: not sure if I really believe that last statement

19:08 bloop: qbg: but numerator and denominator don't always return bigints... eh, whatever

19:09 qbg: bloop: Might be a bug around here

19:09 bloop: programming should be hard like mathematics is hard; it should not be hard like lifting a box with your ears is hard

19:09 qbg: (inc bloop)

19:09 lazybot: ⇒ 1

19:11 Turtl3boi: haha thx alex

19:11 alex can you tell me what are some of the difficult questions you've been asked at an interview

19:13 well this is a long term question

19:13 no rush alex

19:13 rickmode: simple != easy. Programming the easy way leads to big messes. Programming the easy way in OO languages results to an object orgy (https://en.wikipedia.org/wiki/Object_orgy). I've yet to see a OO project of any age that isn't a mess of slightly wrong hierarchies and broken encapsulation.

19:13 Turtl3boi: i always thought OOP was kind of messy but i couldn't quite put my finger on it

19:14 i just really never understood other people's code very quickly

19:14 alexbaranosky: rickmode, I personally avoid inheritence until I'm physically forced to use it

19:14 mbac: what's the least horrible way to turn a byte array into integers

19:15 alexbaranosky: Turtl3boi, can you email me? Seems like a better forum for answering specific questions, and I also have to go eat now... don't want to forget

19:15 mbac: i'm decoding signed shorts

19:15 rickmode: Flat inheritence hierarchies help. Clojure-style OO is essentially flat.

19:16 Turtl3boi: later alex

19:20 rickmode: mbac: check out DataInput in Java : http://docs.oracle.com/javase/6/docs/api/java/io/DataInput.html

19:20 mbac: blah, i already have the data loaded sadly

19:21 rickmode: mbac: it's still usable via an input stream around your data

19:22 mbac: http://docs.oracle.com/javase/6/docs/api/java/io/DataInputStream.html

19:23 alexbaranosky: rickmode, I prefer to favor composition over inheritence almost always

19:23 rickmode: mbac: if you're brave you can also use bit shifting on the elements of the byte array

19:23 qbg: ByteBuffer?

19:23 mbac: bit shifting is a much more familiar beast to me than java libraries

19:24 qbg: http://docs.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html

19:24 Makes Java more like C land

19:25 rickmode: mbac: if you're data is a 4 byte array, then something like this works: (((unitbuf[0] & 0xFF) << 24) | ((unitbuf[1] & 0xFF) << 16) | ((unitbuf[2] & 0xFF) << 8) | (unitbuf[3] & 0xFF))

19:25 mbac: yeah, i was wondering if clojure had magic already to do that

19:25 no worries

19:26 qbg: Byte buffer lets you turn it into a ShortBuffer, and from there into a short array

19:26 rickmode: mbac: the bitwise operators are there... however Clojure is much happier creating longs than ints, so be careful

19:26 mbac: cool

19:26 thanks

19:35 Turtl3boi: what's the purpose of Heroku?

19:36 gtrak```: it's a cloud platform

19:36 they sell cpus and dbs for you to deploy on, the first one is free

19:36 Turtl3boi: interesting

19:40 did you write a web app and deploy it on heroku?

19:41 gtrak```: nah, not yet

19:41 i'm sure lots of guys here have though

19:42 brehaut: Turtl3boi: http://clojuresphere.herokuapp.com/ http://github.com/jkk/clojuresphere

19:44 replore_: and this is a good tutorial using clojure in heroku.. http://thecomputersarewinning.com/post/clojure-heroku-noir-mongo

19:48 alexbaranosky: reoku + noir is very smooth

19:48 correction: heroku

19:49 so none of you all are using Marginalia? I'm wondering if it might be useful somehow for Midje

19:50 brehaut: im pretty sure some of us are using marg

19:50 technomancy: it's useful for potential contributors. not so sure how useful it is for users.

19:50 alexbaranosky: technomancy, that's still a useful thing though

19:51 technomancy: absolutely.

19:52 Turtl3boi: what do u mean by "smooth" alex?

19:53 alexbaranosky: Turtl3boi, just that you can get a deployed webapp up in 5 minutes or something

19:53 and then you can redeploy with `git push heroku master`

19:53 also smooth on the noir side, you can easily refresh your runnign web server just with `:reload` to see changes you've made

19:54 all around just easy to work with

19:55 Turtl3boi: what does it mean to 'deploy' a webapp? like have it appear in a browser when you type in the URL?

19:55 alexbaranosky: Turtl3boi, yes. It has to run on a machine somewhere

19:56 mbac: are seqs memoized or does clojure re-synthesize them for each consumer?

19:57 technomancy: mbac: they're memoized

19:57 mbac: cool

19:58 Turtl3boi: do you write web apps alex? or mainly just ones that run on the local machine

19:58 alexbaranosky: the application I write at work is a webapp, so yeah

19:58 bloop: so, I've been redesigning my personal GUI library in Clojure and I'm considering the possibility of having a "single mutable root" and no other mutations in the rest of the scene graph (so using custom zippers instead of refs for things that 'change') I'm not very experienced with hardcore functional programming and was wondering what you guys think of this idea. Is it mostly a performance vs. capability concern?

19:59 Turtl3boi: umm do i have to be pretty decent with network programming (understanding TCP/IP) to be able to write web apps

19:59 mbac: not as a rule, no

20:00 brehaut: bloop: have you had a look at seesaw ?

20:00 bloop: brehaut: nope, I'll look into that

20:00 brehaut: Turtl3boi: web apps are about as airy fairy as you can get

20:01 bloop: its inspired by enlive and built on swing i believe

20:01 Turtl3boi: you mean easier to write than other apps

20:01 brehaut: Turtl3boi: no

20:01 Raynes: technomancy and I are trying to gauge how widespread the usage of nested vectors as :java-source-path in Leiningen is. Does anyone here use it or know of projects that use it?

20:01 brehaut: Turtl3boi: just that theres very few picky details

20:01 Raynes: Example: :java-source-path [["foo"] ["bar"]]

20:01 brehaut: Turtl3boi: you can get away without even knowing http when you start out

20:02 Turtl3boi: hahaha that would be me

20:02 amalloy: clojurebot: web apps |are| about as airy fairy as you can get

20:02 clojurebot: Ack. Ack.

20:02 bloop: brehaut: the cool thing about single-mutable-root is that any state of the whole GUI can be revisited just be holding on to the value... but I'm not sure if this is really a realistic goal... or useful. It seems like "how grainular should I make my side effects?" is a question I just don't have a good instinct for, because previously, avoiding side-effects was so tough that I just took what I could get.

20:02 brehaut: apropos of nothing: http://www.rimmell.com/bbc/news.htm

20:03 alexbaranosky: Raynes, technomancy I've not seen nested vectors used in my limited exposure

20:03 Turtl3boi: bbl

20:03 brehaut: Turtl3boi: have you looked at ring yet?

20:04 Turtl3boi: nope what's that

20:04 well yeah i saw something about ring on the heroku site

20:04 brehaut: Turtl3boi: its the web / http abstraction that basicly all clojure web stuff uses as the 'lowest level'

20:04 basicly its just an interface for functions that talk http

20:04 'just'

20:04 Turtl3boi: haha yeah that's what made me start worrying about knowing network programming

20:05 brehaut: Turtl3boi: you get given a map of (mostly) strings, and you return a map of (mostly) strings

20:05 Turtl3boi: wow that sounds easy maybe i should try writing a lil appsy

20:06 brehaut: Turtl3boi: its a little old now (its for clj 1.2 and pre 1.0.0 ring) but http://brehaut.net/blog/2011/ring_introduction

20:06 apologies for tooting my own trumpet

20:07 Turtl3boi: wow thanks i'll read up on it.... btw i hope you realize how newb i am. i was not a CS major and i shunned programming for quite a while

20:08 i was a geek who was into analog electronics

20:08 anyways i shall be back later

20:15 burngreg: Anybody have any experience in using SQL Korma with postgres schema's ?

20:19 TimMc: brehaut: That was pretty random.

20:19 brehaut: TimMc: ?

20:20 leo2007: is clojure slow? (http://shootout.alioth.debian.org/u32/compare.php?lang=clojure)

20:20 TimMc: brehaut: The article by Dr. Sloof. :-)

20:20 technomancy: leo2007: alioth benchmarks are well-known for being biased against languages that use JIT.

20:21 they're about as useful as the tiobe index

20:21 platforms that use jit, rather

20:22 leo2007: alright, thanks for the note.

20:22 TimMc: Also, the Clojure should probably be rewritten -- there is not way it takes more lines of code than Java.

20:23 amalloy: TimMc: if you can't use any HOFs because that means boxing and lazy-seq overhead, which is too slow for the shootout...

20:24 TimMc: hmm

20:27 cemerick: leo2007: The shootout allows (and therefore demands) the use of native libraries in e.g. python/ruby/java/clojure/scala/etc.

20:27 Makes it a total sham AFAIC.

20:28 Someone (besides me) should start a "No Bullshit Programming Language Benchmarks Game".

20:28 technomancy: cemerick: not sure "no bullshit" and "game" can go together in that context

20:28 hiredman: cemerick: isn't there a T at the end of AFAIC

20:29 cemerick: As Far As I'm Concerned.

20:29 hiredman: ah

20:30 cemerick: technomancy: it can be gamified while still providing some value.

20:32 technomancy: cemerick: it's just so subjective; people are always going to look at absolute speed rather than the maintainability/speed tradeoff that they actually care about because the former is quantifiable.

20:33 cemerick: technomancy: maybe sort by a Speed / AST nodes column? :-P

20:34 technomancy: the proportion of people who should be picking a language based on _ato-style squeezing-blood-from-a-stone (http://meshy.org/2009/12/13/widefinder-2-with-clojure.html) is tiny, but those kind of stats are always going to be where people look.

20:34 also: most people are going to come to the site looking for data to justify conclusions they've already made

20:34 cemerick: Most people just want to know they're within 20% of the fastest they can go, given platform limitations.

20:35 technomancy: I suspect you're looking for a technical solution to a social problem. =)

20:35 cemerick: I'm not looking at all, thank goodness.

20:35 technomancy: heh

20:35 cemerick: Annnyway…travisci is pretty slick.

20:35 technomancy: so good

20:35 cemerick: http://travis-ci.org/#!/cemerick/clutch/builds

20:36 It lives!

20:36 bloop: my biggest issue is that it treats optimization the wrong way: as something you do early in the project (by choosing a language)

20:36 cemerick: Uses a travis-provided couchdb instance for testing *everything* too.

20:36 I figured I'd have to go set up a clutch-specific account at cloudant or something.

20:56 alexbaranosky: is there any standard way to mark a Clojure function deprecated using metadata or something else?

20:56 TimMc: amalloy: It turns out the site doesn't compare SLOC, it compares gzipped size. :-P

20:58 technomancy: alexbaranosky: I came up with this: https://github.com/technomancy/leiningen/blob/1.x/src/leiningen/core.clj#L12

20:58 brehaut: alexbaranosky: use :deprecated as the key and "version number" as the string

20:59 technomancy: if you're deprecating it in favour of the same function in another ns, anyway

20:59 brehaut: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2010

20:59 technomancy: brehaut: :will-remove-in "2.0.0" if you want to really get them worried =)

20:59 brehaut: lol :)

21:00 alexbaranosky: thanks guys, will check those links

21:01 brehaut: technomancy: defdeprecated is a nice trick

21:04 cgray: i asked this the other day, but why is `last' not defined as #(nth % (dec (count %))) for types with O(1) count?

21:06 brehaut: if i were to guess, its because last is a sequence function, rather than a polymorphic function

21:07 and not all datatypes with O(1) count are random access? (although i guess it probably wouldnt matter)

21:07 cgray: true, for lists, nth is O(n), but so is last

21:08 brehaut: cgray: so really, you are asking why isnt vector special cased?

21:08 cgray: kind of :)

21:08 brehaut: (you could always use peek if you knew you had a vector)

21:09 cgray: aha, cool

21:10 hmm, it also looks like last is defined very early in core.clj, but i guess it could be redefined later

21:11 brehaut: cgray: only if the var was defined dynamically though right?

21:11 cgray: brehaut: oh good point

21:11 brehaut: although…

21:11 slowdown due to var lookup on a O(n) function might be a silly thing to optimize?

21:12 cgray: true

21:12 * brehaut stops speculating wildly

21:13 cgray: i always get confused because i assume that last is clever about different types like so many of the other seq functions

21:13 somehow i'll have to start remembering to use peek instead of last

21:23 arohner: is there a programmatic way to turn off swank?

21:34 tensorpudding: turn off swank?

21:36 you can do (slime-repl-quit) to kill a running swank process and remove the slime buffers

21:39 arohner: tensorpudding: that calls (System/exit 0), right?

21:39 I'd rather just stop the swank threads, and let the process figure out whether it's time to quit or not

21:39 the problem is, swank is keeping the process from dying

21:40 duck1123: try stopping the agents?

21:41 alexbaranosky: how does {:deprecated "x.y.z} get used in the attr-map? part of a defn ?

21:41 arohner: duck1123: yes, I've tried that. I'm quite certain it's only swank that's keeping the process from dying

21:42 duck1123: you're starting swank in your tests, right?

21:42 arohner: right

21:43 duck1123: looks like swank.commands.basic/get-thread-list might get you the threads. You could halt each one maybe

21:59 bobhope: where can I learn about clojure's agent scheduling algorithm?

21:59 on the heavyweight threads?

22:09 alexbaranosky: could anyone take a look at a gist of something I'm trying to do and explain why it is failing for me?: https://gist.github.com/1470342

22:11 mindbender: In my recent ritz update, I get these errors when I run the tests: https://gist.github.com/1470339

22:12 amalloy: alexbaranosky: well, "doesn't seem to work" is pretty dang vague. it looks to me like your alter-meta! should be quoting name: '~name

22:14 alexbaranosky: amalloy, hmmmm the alter-meta version applies the meta-data fine, the second version with the meta data done this way: ^{....} fails to apply the metadata to the unfinished defs

22:15 amalloy: alexbaranosky: you want to replace the former with the latter? but the latter works and the former doesn't? are you sure you don't have something backward?

22:15 alexbaranosky: ?

22:15 amalloy: you said the alter-meta version works fine, but your gist says it's the version that doesn't work

22:16 alexbaranosky: the key is I'd like to understand why it doesn't work, I guess

22:17 amalloy, sorry, I put them backwards

22:17 just fixed it

22:18 amalloy: in that case the problem is (probably) that ~name here resolves to the function itself, not the name. and the function has not been def'd yet in the ^ version

22:18 alexbaranosky: fixed the gist, not the code

22:19 hmm, even if I replace ~name, with '~name it still doesn't get the meta-data

22:19 but that does sound like it might be why it is behaving this way

22:19 makes sense at least

22:22 ammaloy: thanks for the suggestions I will just stick with the original

22:31 blakesmith: Hrm. I'm implementing a decompression algorithm that operates on (potentially) large files, and would like the file IO and decompression to only happen when that part of the file is asked for (lazily). Has anyone else encountered a problem like this before?

22:31 Seems like a job for a lazy-seq, or writing against the ISeq interface...

22:32 But I'm unsure.

22:34 brehaut: blakesmith: it sounds like you want a buffered reader or something from clojure.java.io over some java class ?

22:35 blakesmith: brehaut: Yes, but I'd like it to wrap decompression as well.

22:35 So, buffered reading and decompression wrapped together, for easier usage.

22:36 It'd be nice to be able to use idioms like 'take' on it as well..

22:36 Since this is for a clojure library.

22:38 brehaut: blakesmith: still seems like it probably should be a java reader class to do the decompression

22:39 blakesmith: brehaut: Would that then need to be wrapped in some way to support Clojure idioms like 'take'?

22:39 brehaut: blakesmith: well it'd be in the IO layer not the seq layer; i think the readers are lazy anyway

22:40 so you wouldnt worry about making it support a seq operations, just reader operations. then you can use the standard clojure java io stuff to go from the reader to other stuff

22:43 i might well be talking out my arse though

22:43 blakesmith: hehehe

22:43 Aight, I'll see if I can drum up some code, since that's easier to talk about.

22:43 Will report back. ;-)

22:45 alexbaranosky: does anyone know, how {:deprecated "x.y.z} gets used in the attr-map? part of a defn ?

22:46 amalloy: alexbaranosky: afaik it gets recorded and ignored

22:47 alexbaranosky: recorded by whom?

22:47 amalloy: it's in the var meta

22:47 &(meta #'struct-map)

22:47 lazybot: ⇒ {:ns #<Namespace clojure.core>, :name struct-map, :arglists ([s & inits]), :added "1.0", :static true, :doc "Returns a new structmap instance with the keys of the\n structure-basis. keyvals may contain all, some or none of the basis\n keys - where values are not ... https://gist.github.com/1470470

22:48 amalloy: &(meta #'agent-errors) ;; this one should actually have it

22:48 lazybot: ⇒ {:ns #<Namespace clojure.core>, :name agent-errors, :arglists ([a]), :deprecated "1.2", :added "1.0", :doc "DEPRECATED: Use 'agent-error' instead.\n Returns a sequence of the exceptions thrown during asynchronous\n actions of the agent.", :line 2003, :file "clojure/core.clj"}

22:48 alexbaranosky: tried to add it to a couple macros in Midje, and it doesn't seem to show up in the var meta

22:50 amalloy, dang, I'm on a roll of dumb tonight, oh well, it looks like I missed it and it is clearly in the var meta

22:50 take it easy time to relax my brain for the night with some tv :)

22:52 Turtl3boi: hi

22:53 tmciver: alexbaranosky: are we meeting at Sprout on Wednesday?

22:58 Turtl3boi: can i meet up too?

23:00 tmciver: Turtl3boi: Are you in the Boston area?

23:00 Turtl3boi: nope i live in california =(

23:00 i assumed most ppl here were from san francisco

23:01 tmciver: Nope, east coast

23:01 Clojurians better than west coast. ;)

23:05 Scriptor: yes east coast, that's why they have the east coast conferences at the most reachable placee :p

23:07 Turtl3boi: i wonder why that is

23:07 maybe i should relocate to boston

23:08 Scriptor: well, the confs are in north carolina of all places

23:09 tmciver: Yeah, but I didn't mind; I liked driving in NC better than Boston.

23:09 I've lived in Mass my whole life and I still can't find my way through Boston.

23:11 Turtl3boi: is boston a good place to meet girls

23:11 or is that more new york

23:12 tmciver: Not bad but probably not as good as NY or SF.

23:13 Turtl3boi: what's a better place to get a programming job? SF or boston

23:14 Scriptor: hmm, I wonder how fast I could whip up basic clojure->php

23:14 Turtl3boi: what's clojure -> php? you mean a translation program

23:15 Scriptor: something like that

23:15 tmciver: Not sure, but if you want to do Java web dev, you'd have no trouble getting a job in Boston.

23:15 Turtl3boi: can i watch you as you program it

23:15 can i view your desktop or something

23:15 java web dev? you mean like javascript web apps?

23:15 or JVM related web apps

23:15 Scriptor: sure, it's just going to have a lot of alt tabbing to irc, email, or reddit

23:16 jvm web apps

23:16 Turtl3boi: doesn't that mean just embedding an applet? ( i vaguely remember this from my old programming course)

23:17 tmciver: backend: Servlets, JBoss, Tomcat

23:18 Scriptor: yep, there's a huge market for server-side java

23:18 Turtl3boi: that sounds hard haha

23:27 amalloy: Scriptor: isn't that what pharen was/is?

23:27 clojure->php, that is

23:38 Scriptor: amalloy: a lot of it is inspired by clojure, but not completely

23:38 no sequences, no keywords, some syntax differences

23:38 mostly calling it clojure would set too many expectations :)

23:39 amalloy: heh

23:39 if you're serious about doing it, you should check in with ambrosebs - i imagine his cljs compiler/analyzer work would be relevant

23:40 Turtl3boi: what's the purpose of translating clojure into PHP

23:42 tmciver: you don't have to write PHP

23:42 amalloy: it's easy to think in clojure, and easy to run php in an enterprisey setting :P

23:43 Turtl3boi: so clojure is easier to think in?

23:43 it seems a pain in the butt for me

23:43 i thought it was just better in terms of multi threaded

23:44 amalloy: Turtl3boi: bro, if you want people to answer "no" to that question, you should hang out somewhere other than #clojure

23:44 Turtl3boi: LoL

23:44 sorry man i'm still a newb

23:45 tmciver: Turtl3boi: me too. It is hard at first if you don't have a functional programming background, as I didn't. But it's worth the mental strain.

23:46 amalloy: at my last job there were a few hard problems that i wrote first in clojure and translated to php, because it's easier to experiment in clojure, and you don't have to shout so loud to get the computer to understand what you mean

23:46 Turtl3boi: what's the best way to get started in functional programming?

23:47 amalloy: read code, write code. hang out in #clojure or #haskell

23:47 tmciver: Turtl3boi: and take a look at 4clojure.com

23:48 in fact, I have to get back there myself.

23:48 Turtl3boi: thanks

23:48 i meant to buy joy of clojure today but didn't get back to the store

23:49 tmciver: Turtl3boi: Halloway's Programming Clojure is a great starter book.

23:49 amalloy: Turtl3boi: the store!!!!? get it from manning.com, they have pdf and mobile download versions to go with your pBook

23:50 though to be fair i believe you get the pdf when you buy the book, even if you get a hard copy from some store

23:50 Turtl3boi: lol you serious

23:50 Scriptor: Turtl3boi: for me, the best way to get started with functional progamming was reading learn you a haskell and trying to implement functions it described before seeing the source

23:50 you could probably do the same with some clojure books

23:51 Turtl3boi: wow that's a good idea

23:51 Scriptor: lyah does a pretty good job of teaching functional basics, especially good recursion

23:52 Turtl3boi: amalloy are you saying it's free at manning.com?

23:52 or are you saying just don't go drive to the store to buy it

23:52 Scriptor: and lyah online is free

23:52 amalloy: Turtl3boi: the pdf is free if you get the book

23:52 Scriptor: amalloy: does cljs use a custom-built parser?

23:52 amalloy: Scriptor: no, it just uses clojure.core/read

23:53 Scriptor: oh right, I remember reading it a little

23:53 amalloy: Turtl3boi: also, i think someone recommended SICP to you already. it's an excellent book and enjoyable read, and free online, though IMO a bit heavy

23:53 Scriptor: I remember hearing of a good precursor to sicp

23:54 Turtl3boi: http://news.ycombinator.com/item?id=2115756

23:55 Turtl3boi: also, clojure and lisp in general is definitely easier to think in for many things

23:55 skeeterbug: is practical clojure any good?

23:55 Scriptor: macros are fun too

Logging service provided by n01se.net