#clojure log - May 02 2013

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

0:00 pl6306: Yup

0:00 uvtc: SegFaultAX: right. metellus pointed that out a bit earlier. I meant, "in Clojure". But, yes, you're right.

0:00 SegFaultAX: thanks.

0:00 pl6306: Process and ProcessBuilder?

0:00 SegFaultAX: uvtc: How is that not "in clojure"

0:01 n_b: pl6306: There's also clojure.java.shell, not sure how much you need to do

0:02 uvtc: SegFaultAX: I was looking for something along the lines of `(index-of some-coll some-val)`. Though, just now I see that .indexOf is right there on the cheatsheet...

0:03 pl6306: Thanks I will give clojure.java.shell a try

0:05 akhudek: it's interesting that subs exists in clojure, despite .substring, but this is not the case for some other functions

0:09 uvtc: Anyhow, I'm glad to see (once again, in fact) that what I thought required a clunky solution actually had a built-in solution already that works nicely.

0:11 metellus: for the record, if you're backlogging: https://www.refheap.com/paste/14126

0:24 gdev: lazybot: whatis he talking about

0:24 lazybot: he is talkin bout my g-g-g-generation

2:32 amalloy: uvtc: anytime you work with indexes in clojure, your brain should be screaming "do we *really* need to use indexes?" remove-one-from is so much easier to write, and more efficient, without any indexes

2:35 he's gone, i guess, but for anyone following along at home, https://gist.github.com/amalloy/5500495

2:40 noidi: you could replace the let with destructuring to make it even simpler: (when-let [[x & xs] coll] ...)

2:49 amalloy: noidi: you could, but that's a bad habit to get into

2:50 because that will force realization of the first two elements in coll, not just the first one

2:50 (since destructuring & uses next, not rest)

2:55 noidi: aren't you realizing xs anyway in the body?

2:56 ah no, not in the else block

2:56 amalloy, I hadn't thought about that, good to know, thanks

2:57 amalloy: noidi: i don't realize xs in either side of the if

2:57 rest is lazy

2:57 noidi: ah, right

2:58 and with chunking that extra evaluation could be quite expensive

2:58 *realization

2:58 in case x is the last element of a chunk

2:59 amalloy: *shrug* even without chunking

2:59 you don't want to eagerly realize one too many elements of the ackermann sequence

2:59 noidi: hehe

3:00 amalloy: anyway, i wrote a lot of lazy-sequence functions with [x & xs], and it took me a long time to realize they were therefore all broken

3:00 noidi: why does it use next instead of rest?

3:00 amalloy: probably legacy reasons, from back when there was no lazy rest

3:01 so people wrote code like (let [[x & xs] coll] (if xs ...))

3:01 Apage43: it also will guarantee xs is nil if there is no more stuff left, if you're checking that

3:01 amalloy: Apage43: right, which IMO is a bad guarantee to make, except that it has to stay in because of legacy

5:05 clgv: is there a clojure bug with respect to type inference for primtives regarding the `cond` macro?

5:16 amalloy: that's not possible, clgv. cond is just a macro expanding to nested ifs, and any inferencing is performed on the expanded form

5:17 clgv: amalloy: ok then this is pretty strange. I get an autoboxing warning from recur when using `cond` but not when I write those nested `if` statements manually

5:43 no7hing: having a small problem with protocols: define a protocol in ns A, require it in ns B, compiler tells me it can't resolve it

6:02 antares_: no7hing: how do you require it? You should just require a namespace. Are you trying to extend it in another ns?

6:03 no7hing: i required the ns the protocol was defined in; with (:use [the.ns :only [TheProtocol]]) it works

6:04 that i have to require the ns either way too, was kind of ..surprising

6:08 djcoin: Hi folks, i'm not in clojure right now. But i had a question, it is really appealing to see such a language (flexbility but performance thx to the jvm, simplicity etc. compilation to javascript, etc.).

6:09 But isn't it too hard to code without any types ?

6:09 Given immutability/performance, I would be tempted by haskell too (yet laziness is a bit scary)

6:10 + Types and compilation makes code fast, I wonder if layers and layers of untyped clojure code can not alter performance

6:10 ANy hints ?

6:11 ucb: djcoin: you can provide type hints to speed things up a tad; but it might just be that you're preemtively worrying for no good reason :)

6:11 djcoin: in a word: speed is not /normally/ a problem, and when it is, I've not seen it be because of the lack of types (although reflection can be a bitch sometimes)

6:12 (lack of types is wrong; dynamic types more like it)

6:12 djcoin: yeah, that's what i meant

6:12 What about "programming in the large", librairies and stuff. Wouldn't types help to structure things up ?

6:13 (even if GC + immutability are already key points)

6:13 ucb: yes and no. If you have too many types then it gets a bit silly. If everything is a string, it also gets silly.

6:17 djcoin: ucb: sure, but I'm doing mostly javascript/nodejs those times (before python, i did too a bit of C/Java) but i'm beginning to be tired by types errors. + Finding a lib (especially in javascript I guess) can be cumbersome. When I see stuff like hoogle for haskell (google for types), I see this as really helping building abstraction too

6:18 antares_: no7hing: you don't need refer to the protocol unless you want to extend it. Simply use functions defined in it as if they were regular functions in the ns.

6:19 no7hing: if you need to extend a protocol from another ns, see https://github.com/clojurewerkz/money/blob/master/src/clojure/clojurewerkz/money/hiccup.clj for a small example

6:22 noidi: djcoin, there are efforts to add static typing to clojure https://github.com/clojure/core.typed

6:23 djcoin: noidi: yeah I saw that, inspired by typed racket, it looks nice. Wonder how far you can go with it

6:27 no7hing: @antares_: that's what i was trying to do, after i had issues using a record that was implementing the protocol; i moved the record definition to the ns where it's actually used and ran into the require/use issues; will take a deeper look into this in a calm hour today

6:28 arcatan:

6:28 naeg: How can I modify existing functions using macros? e.g. add another argument to that function, modify a function call inside that function

6:29 noidi: djcoin, by all means, check out haskell as well if it seems more appealing to you

6:29 personally I found clojure much less daunting

6:29 naeg: basically, I want to do this: https://www.refheap.com/paste/14113

6:29 noidi: and I really like the REPL-centric workflow that Clojure provides

6:29 no7hing: @antares_: is there a preferred way on wether to :use or :import protocols?

6:29 djcoin: noidi: I fear a bit haskell for its laziness (and space leaks)

6:30 antares_: no7hing: you simply need to require the namespace

6:30 noidi: djcoin, Clojure's laziness can trip you up as well, although only sequences are lazy by default

6:30 antares_: no7hing: when extending, refer to a protocol as if it was a function, using the ns prefix you used in require + /ProtocolName

6:31 imports are necessary for records

6:31 because records are compiled to Java classes

6:31 :use should be avoided if you use Cloure 1.4+, see http://clojure-doc.org/articles/language/namespaces.html

6:32 no7hing: @antares_: when mixing that up, it looks like it's time for a break; thanks for helping

6:33 @antares_: once you do it right, it just works

6:34 djcoin: noidi: I guess you chose clojure over haskell, what are the tradesoff if I may ?

6:36 antares_: djcoin: running on the JVM/.NET/JavaScript is by far the biggest trade-off (both a pro and a con). Learning curve in haskell is very steep, even for basic things like working with I/O and JSON, you have to have some understanding of monads and advanced control structures.

6:36 noidi: what antares_ said :)

6:37 djcoin: antares_: but if you do understand how to code the haskell way (monads and stuff), i mean, putting aside the learning curve

6:38 To be fair, the JVM ecosystem (java, xml etc.) is not very appealing to me, but i see how a super optimized jvm and using java to code the low level stuff can be great

6:38 + well, the types :s

6:39 antares_: djcoin: with deep understanding of either, what matters the most is library availability, operations tooling (that haskell lacks) and if your problem can be better expressed in a DSL vs type system

6:40 djcoin: unless your program is hundreds of thousands of lines or requires numerical computations efficiency, I don't think the static vs dynamic typing debate is very relevant

6:40 noidi: I work at a (mostly) Java shop, and I can imagine getting to work with Clojure in a year or two (we already have a couple of Clojure projects, sadly I'm not in one of them)

6:40 antares_: it's great to have static type checking and type inference. It's not a deal breaker for me.

6:40 noidi: on the other hand, there's a zero chance of the company moving to Haskell

6:41 antares_: noidi: in that case Scala is what you want

6:41 kinda the middle ground

6:41 and also a bag of compromises, but Java shops find it appealing most of the time

6:41 noidi: I don't :)

6:41 djcoin: antares_: Thanks for your answer, what do you mean by "operations tooling" ?

6:42 antares_: if you like Haskell, I think there's quite a bit you will like about Scala

6:42 djcoin: tools like visualvm, jstack, metrics libraries, JMX, JVM-specific profiling and monitoring

6:42 dtrace support

6:42 noidi: I'm really a Clojure guy at heart, and I've only looked at Haskell and Scala out of curiosity

6:43 antares_: haskell very much lacks all of this stuff

6:43 noidi: I do miss static typing from time to time, but for me that's not a big enough reason to give up all of Clojure's dynamic, malleable goodness

6:43 djcoin: Sure

6:45 antares_: isn't all those tools (the whole env) adding a lot to the learning curve ?

6:46 antares_: djcoin: you don't need them initially but it's scary to go into production without them

6:46 djcoin: (this is the same for all languages I guess - but does it integrate well with clojure ?)

6:46 antares_: and something like jstack or visualvm can be learned in an hour

6:46 visualvm and jstack work great with clojure

6:48 noidi: antares_, do you use Scala much? I think I remember seeing some Scala libraries by you, but I might be mistaken...

6:49 antares_: noidi: I used to, then switched to Clojure

6:49 Scala in 2007-2009 was a very different ecosystem. Binary compatibility and upgrades were total hell.

6:49 djcoin: Thanks antares_ , did you try haskell haskell, would you recommend it ? I guess not if you say operational tools are missing

6:50 antares_: djcoin: I like haskell but would highly recommend taking the learning curve and ops tools availability into account

6:52 djcoin: antares_: talking about ops tool, I guess Erlang must be a great fit

6:53 jjl`: presumably the ops tools are so great that someone wrote erjang to get worse ops tools for the jvm...

6:53 djcoin: :)

6:54 MAybe the "port" is not good itself

6:54 antares_: djcoin: Erlang has a good story there. But these tools are not nearly as well known.

6:55 jjl`: AFAIK erjang was developed as an experiment

6:56 jjl`: i think so. but i'm pretty sure the JVM's ops stuff was the reason for it

6:56 noidi: djcoin, here's something to watch while you're procrastinating on the language choice :) http://www.ted.com/talks/barry_schwartz_on_the_paradox_of_choice.html

6:56 jjl`: i mean erlang is *FAST*. they didn't need to move it to the jvm for performance

6:56 djcoin: noidi: yeah, i'm always weighting pros and cons

6:56 thanks :)

6:59 jjl`: oh I did not understand, I thought they coded some "erlang like" ops tools, in fact no, they port the whole vm oO a bit crazy

7:01 Do you need to deal with (is it better to have some (extensive) knowledge of) java and its environment, do go for Clojure ?

7:01 in "real world clojure"

7:02 noidi: yes, you pretty much need to know Java

7:03 jjl`: well, some of it

7:03 more about the stack as a whole than java the language

7:03 antares_: jjl`: no, erlang is not fast on computational workloads. Faster than Ruby and Python but that's nothing to be proud of :)

7:03 jjl`: antares_: i can compute in my head faster than ruby

7:04 antares_: jjl`: can't we all

7:04 djcoin: Yeah, well i know a bit of java, i know what the jvm is, but I don't know how deep the "java" stack goes and if you need to reach for it regularly

7:04 noidi: core parts of Clojure use things like Readers, so it certainly helps if you can read enough Java to understand documentation explaining them

7:05 antares_: djcoin: it's a well known fact that some of the most famous Clojure community members don't know much Java but did pick up some JDK bits and concepts :)

7:05 noidi: if you can more or less understand what's going on when reading a random snippet of Java, you'll probably do fine

7:06 djcoin: ok good :)

7:06 antares_: binary vs char streams is a great example

7:06 jjl`: most of it is the java libraries really. you'll use them a lot in clojure

7:06 djcoin: Yeah, i'm a bit afraid of using clojure as a combiner of java lib

7:06 (don't why I should though)

7:07 s/should/am

7:07 jjl`: clojure that uses java libs tends to be a bit ugly. java libraries are generally very much written for the imperative style

7:08 lucian: there are wrappers for most things you'd care about, though

7:09 my problem is the jvm itself, way too slow for development

7:09 jjl`: indeed. and a wrapper waiting to be written for the rest

7:09 lucian: i'm also much too comfortable with python

7:09 jjl`: luckily they're trivial to write compared to binding to C from Python/Ruby

7:09 jjl`: yes, quite

7:10 but i come from perl where there's never a need because someone else has done it already

7:10 lucian: there are certainly advantages, but whenever i start to do something in clojure i get too annoyed at the jvm being slow

7:10 jjl`: it would be as much of an issue with perl for custom things, though

7:11 djcoin: how slow ? you mean at startup ? because otherwise it should be fast no ?

7:11 jjl`: worse. have you ever written XS?!

7:12 arcatan: yeah, the startup time of JVM is pretty bad. you don't want to be restarting it just to reload code.

7:13 jjl`: have you tried using -Xint to make it run in interpreted mode?

7:14 not something you'd want to do for production, but for dev...

7:15 djcoin: lucian: so how slow for dev ?

7:16 lucian: djcoin: at least on my machine, it takes seconds to boot up

7:16 antares_: in Clojure, you will eventually use a long-running REPL from emacs/vim/IDE

7:16 and discover drip

7:16 lucian: whereas, say, python, is instant

7:16 antares_: even with drip, it still takes more than 1sec

7:17 antares_: note that Clojure code is compiled when it is loaded

7:17 lucian: even lein's help command takes 3-5sec :(

7:17 antares_: it's not a JVM problem. But that's also why Clojure doesn't suffer from the binary compatibility hell nearly as much as most compiled languages.

7:17 lucian: lein help is the worst case, it has to load *all* the plugins first

7:18 to display help for them

7:18 djcoin: yeah lein help is pretty daunting

7:18 dauting *

7:18 lucian: i'm pretty sure it's a jvm problem, i've had the same issue with plain java

7:18 djcoin: sry daunting*

7:18 lucian: i think its class loading is broken

7:19 naeg: how to get the name of a function with the namespace? e.g. #'f gives #'namespace/f, but I just want "f"

7:19 splitting at / seems cumbersome to me

7:19 lucian: djcoin: so if you can put up with that, it's probably fine

7:20 for me there aren't enough advantages over python to be motivated to put up with it :)

7:21 djcoin: lucian: parallel/concurrent programming, immutability, flexibility, functional style ?

7:21 and perf

7:21 :)

7:22 Apage43: naeg, the var will have :name in its metadata

7:22 lucian: djcoin: the first is less of an issue than one might think, second is meh, third is not the case, fourth i have enough of to be satisfied already

7:23 actually, i like immutability a bit more than 'meh'

7:23 Apage43: &(:name (meta #'map))

7:23 lazybot: ⇒ map

7:23 djcoin: I say simple and true flexibility, without weird lamba and metaclass

7:24 Apage43: if you have a var for some reason and want the name

7:26 lucian: djcoin: expression lambda and metaclasses are fine for me. i prefer traits/typeclasses/protocols to classes/meta, but i the benefit is not large enough

8:51 gdev: lazybot: fortune

8:51 lazybot: the impedance of mismatch is all your fault

8:52 gdev: =[

8:56 xumingmingv: lazybot: future

8:56 lazybot: fortune

8:56 lazybot: ,(println "PRIVMSG #hackerschool :herp")

8:56 clojurebot: PRIVMSG #hackerschool :herp\n

8:58 gdev: lazybot: whatis (+2_2)

8:58 lazybot: (+2_2) is 5 for extremely large values of 2

9:18 augustl: is it possible to implement a multimethod using a function that returns a new function? I.e. (defmulti foo :my-dispatch (call-function-that-returns-other-function))?

9:25 pjstadig: augustl: defmethod macro expands to this https://gist.github.com/pjstadig/5502123

9:26 so you can always manually call .addMethod on your multimethod

9:26 there's clojure.core/remove-method, but unfortunately not clojure.core/add-method, so you have to do it manually

9:29 jcromartie: so I rewrote my Clojure JSON API in Rails last night

9:30 I am already using at least two racist/mysogynist libraries

9:30 thank you, Clojure community, for not doing that

9:34 naeg: jcromartie: racist/mysogynist libraries? o.O

9:35 jcromartie: Feedzirra

9:35 mefesto: i only use libraries that treat me with respect

9:36 jcromartie: I think I had more earlier but I dropped some dependencies

9:36 naeg: what exactly I racist about feedzirra? can't really see it right now

9:37 duck1123: Think Godzilla

9:38 hfaafb: is godzilla racist?

9:39 naeg: either I still fail to see it, or we have a very different perception of "racist"

9:39 duck1123: combined with the R for L thing, it's a little insensitive, not quite racist

9:39 mefesto: hfaafb: instead of feedzilla it's feedzirra which seems like the intention was to sound the way asians can sometimes mispronounce the letter L

9:40 wink: depends how you define mispronounce

9:40 mefesto: i'm korean and find it kind of funny

9:40 ... well half korean.

9:40 naeg: oh, understand it now. but can't tell whether this was/is the intention of the developer

9:42 bengillies: how is it mysogynist then?

9:43 jcromartie: bengillies: it's not

9:43 but there are others

9:47 I am exaggerating a bit. I dont think they named their gems to hate on other people.

9:48 but it might be odd to explain the dependency on "feedzirra" to e.g. a gov't bureaucrat in charge of auditing an app or something like that, let alone gems like "clit", or "tit" or "daddys_girl"

9:49 or "trollop"

9:50 ball_gag, hash_dealer :)

9:50 mefesto: i think feedzirra wouldn't be an issue but yea those others are a bit much

9:54 Morgawr: hey guys :) a few days ago I finished a game in ClojureScript for the Ludum Dare competition, I wanted to thanks everyone who helped me with my random questions in here about Clojure. http://www.ludumdare.com/compo/ludum-dare-26/?action=preview&uid=8711 Here's the game if you're interested, it's a silly game but it's also on github in case anyone wanted to take a look a the code (it's not good code but at least it works)

9:55 I hope I can take this to the next level and develop an easy-to-use clojurescript engine for adventure games on the web, who knows

9:55 mefesto: i noticed that hiccup.form/form-to will convert any method that is not :get or :post into a :post but with a _method param. does compojure take this param into consideration with routes? [ex. (PUT "/my/uri" [] ...)]

9:56 weavejester: mefesto: It does

9:57 mefesto: weavejester: great. i figured it would but just wanted to check. thanks

9:58 jcromartie: Morgawr: awesome

9:59 Morgawr: :)

9:59 dnolen: Morgawr: neat

10:00 Morgawr: it's cool to see people do games with ClojureScript

10:01 Morgawr: dnolen: yeah, it was an interesting challenge. I had never developed anything "useful" with functional programming so I wanted to see how it would go

10:01 it's really powerful after all, some hiccups here and there because I had never developed on the web nor with javascript before but it was fun

10:02 especially in 48 hours haha

10:10 silasdavis: Morgawr, how much acid did you drop...

10:11 I'm in the castle

10:13 Morgawr: silasdavis: haha, way too much acid, just wait for the end

10:13 keep in mind it was very rushed because of 48hours limit

10:13 (around 3/4 of the time was spent on the actual engine, the rest on content creation)

10:14 silasdavis: no I'm impressed that's a fair bit of content and code for 48 hours

10:14 Morgawr: the wonders of very little sleep :)

10:16 hfaafb: Are there any examples of open source performant action games in clojurescript?

10:16 Morgawr: uh.. I remember viewing a few when trying to look for example code

10:16 https://github.com/mrmekon/tempest-cljs this one for example

10:17 https://github.com/thomcc/ld23 there's also this one, which was made for Ludum Dare 23 one year ago

10:18 http://lispgames.org/index.php/Clojurescript and there's this wiki with a few other

10:19 which reminds me I need to add my game to that list

10:19 yogthos: Morgawr: I made one too a while back :) https://github.com/yogthos/Clojure-Tetris

10:19 Morgawr: nice! :)

10:21 jcidaho: anyone benchmarked elastisch against clj-elasticsearch?

10:21 seems 10x slower, I'm prob missing something

10:34 gfredericks: is there anything mutable about an ##(Object.)?

10:34 lazybot: ⇒ #<Object java.lang.Object@1bede95>

10:45 TimMc: gfredericks: The mutex associated with it, I guess.

10:45 You might be able to carry 1 bit of state that way.

10:48 trptcolin: might be able to alter method accessibility w/ reflection?

10:48 [kind of a stretch]

10:49 TimMc: &(let [o (Object.)] (locking o (.wait o 1000)))

10:49 lazybot: ⇒ nil

10:50 TimMc: A good candidate for that would be Object#finalize()

10:51 ivan: remember to lock your Strings before mutating them

10:52 you don't want another thread to see a mutated string without the mutated hashCode

10:53 gfredericks: I still want mutable nils

10:54 trptcolin: i guess by definition, (Object.) is as immutable as anything can be, aside from primitives, in Java (and by extension Clojure)

10:54 ivan: how about some metadata on your nils

10:54 I want to know how long it took to generate this nil

10:56 gfredericks: ,(with-meta nil {1 2})

10:56 clojurebot: #<NullPointerException java.lang.NullPointerException>

11:00 tcrayford: clojurebot: for reals?

11:00 clojurebot: It's greek to me.

11:01 tcrayford: oh, nil is just java null, makes sense that there's no meatdata

11:05 trptcolin: meatdata. gross tcrayford

11:05 tcrayford: #notveganfriendly

11:31 rasmusto: I have a long-running loop with a Thread/sleep in it, and I get a stack overflow error if it runs for too long. I do a (swap! myatom (partial map somefunc)) on an atom within the loop and then check for some condition to break out of it.

11:32 I see lots of "LazySeq" and "map$fn" in my stack trace. Is using map (and laziness) a problem?

11:33 gdev: can you paste the code on refheap?

11:33 xeqi: it could build up a bunch of thunks, but I would expect something other then a stack overflow

11:38 rasmusto: gdev: I'll post what I can

11:45 dnolen: how many people only use ClojureScript with simple optimizations in production in some way?

11:46 or any optimization really that isn't advanced - I'd assume hardly anyone but curious

11:48 cmajor7: dnolen: I did, but just because it was quite hard to figure out the reason on why "advanced" did not work. we had too much code to figure it out easily, and the "not found $b.a c.." was not giving it away.

11:48 akhudek: I still do, but that's mostly because I can't manage to debug a problem.

11:48 cmajor7: the whole codebase was about a meg

11:49 akhudek: Yes, I have the same issue as cmajor7

11:49 cmajor7: advanced made it 150Kb, but would not run

11:49 trptcolin: same. we're doing that so far, but it's an internal app and i've only been looking at cljs for a couple weeks

11:49 mefesto: im using advanced opts for production

11:51 dnolen: for the people that use simple optimization for some reason, I don't suppose you're super concerned about performance then?

11:51 trptcolin: yep, for now

11:53 McqfrTheScott: Chousuke, vieläkö ajattelet musta?

11:53 rasmusto: gdev: I had to butcher some of the code, but the gist of it is still there: https://www.refheap.com/paste/d9371bde35befc47d6efa8aea

11:53 McqfrTheScott: Musta, hollantilaisesta joka puhuu suomea äidinkielena

11:54 rasmusto: xeqi: I am calling out to clojure.java.shell.sh, I'm not sure if that's relevent at all

11:54 dnolen: I'm asking because I'm looking at switching keywords to a real type away from JS strings.

11:55 under advanced compilation we can optimize constant literals easily of course

11:55 but not under any other optimization mode - so that it means non-advanced compiled code will take a small perf hit for keyword occurences, they have to constructed wherever they occur.

11:56 well "small"

11:59 xeqi: rasmusto: I would expect lazyness is biteing you there. For (some ...) to get the last element its going to have to step into each (partial map ..) which might contain another call of the same type due to lazyness. I could see this blowing the stack

11:59 also, you could loop/recur to avoid the atom/while/swap! if desired

12:01 rasmusto: xeqi: okay. I can probably modify the collection I'm using for my loop condition to something less sequential, or make two buckets instead

12:02 xeqi: rasmusto: you could add another doall to confirm before going to far

12:03 rasmusto: xeqi: doall in the swap?

12:04 xeqi: sure

12:06 alex_baranosky: do any of you have a good Emacs configuration that allows you to Meta-. into Java methods, so you can easily dive into clojure implementation details?

12:08 cmajor7: dnolen: I would love to use it, but it just did not work for me (compiled, but did not run). I wanted to do it more for a size reasons vs. performance, but in any case I agree with "keywords" as a real type vs. strings. Eventually people who run in "simple" would figure out the root cause of "why", and move to "advanced" anyway.

12:09 rasmusto: xeqi: Okay. I'll give that a shot and see if I can reproduce/fix this issue. Thanks for the suggestions :)

12:37 gdev: rasmusto:) sorry, I got called away from my desk right as you pasted the link

12:49 ynniv: is there a way to specify exclusions to plugin dependencies in lein?

12:51 xeqi: ynniv: [lein-plugin "..." :exclusions [some-dep]]

12:52 ynniv: hmm. what about implicit dependencies?

12:52 basically: [swank-clojure \"1.4.3\"] -> [clj-stacktrace \"0.2.4\"] is overrulling [ring \"1.2.0-beta2\"] -> [ring/ring-devel \"1.2.0-beta2\"] -> [clj-stacktrace \"0.2.5\"]

12:53 i tried adding swank clojure as an explicit dependency with an exclusion, but it isn't taking

12:53 technomancy: what are implicit dependencies?

12:53 xeqi: technomancy: dependencies added by a plugin by altering the project before e-i-p

12:54 technomancy: oh, yeah. =(

12:54 in retrospect I regret ever doing that or encouraging that

12:55 xeqi: ... I can't think of a way. Declaring a top level dep with the version of clj-stacktrace desired would work

12:55 * should work to get that version

12:55 ynniv: oh, that's simple enough

12:55 ddellacosta: ynniv, what is the plugin you are working with?

12:55 ynniv: [lein-swank "1.4.5"]

12:56 as well as [lein-ring "0.8.5"] and [lein-pedantic "0.0.5"], but they don't seem to be involved

12:57 gdev: technomancy:) I'll create a feature request to have leiningen display a message when it is asked to do something that you regret adding

12:57 ddellacosta: It's interesting 'cause it sounds similar to an issue I had with lein-ring

12:57 https://github.com/weavejester/lein-ring/pull/71

12:57 technomancy: gdev: with a patch please

12:57 ddellacosta: …so I'm wondering if it's the same kind of issue.

12:57 gdev: technomancy:) mkay, first I need a list of everything you regret

12:57 ynniv: ddellacosta: I had the same problem. I probably fixed it by specifying the library directly without realizing what I was doing

12:58 technomancy: also, thanks for making the greatest project management system I have used

12:58 dnolen: http://jsperf.com/fn-caching

12:58 interesting results

12:58 ieure: Man it's kind of a drag that (deftype) constructors can't have varargs.

12:58 ynniv: don't worry about regrets

12:58 technomancy: ynniv: thanks =D

12:58 xeqi: hmm, I need to remember to deprecate lein-pedantic once lein 2.2 is out

12:58 dnolen: we do this kind of caching for reify already, but this could make local fns cheaper

12:59 ToBeReplaced: ieure: the constructor can't, but your function to call the constructor can

12:59 ynniv: dnolen: wow, what's up with safari?

12:59 ieure: ToBeReplaced, Yeah, but it's pretty crap that I have to make an adjunct function to construct the thing instead of just saying (deftype Blah [& xs])

12:59 Now I need (make-blah [& xs] (Blah. xs))

13:00 ddellacosta: ynniv: probably this line is the culprit, I would guess: https://github.com/technomancy/swank-clojure/blob/master/lein-swank/src/leiningen/swank.clj#L62

13:01 ToBeReplaced: xeqi: i missed the start of the discussion -- deprecate because lein will start rejecting automatically?

13:01 ddellacosta: ynniv: ah, and you already tried added an explicit dependency, and that didn't take, huh...doh.

13:02 ynniv: sorry, it's 2 AM for me here so I have to hit the hay, but good luck solving this one.

13:03 xeqi: ToBeReplaced: deperecate because I put something similar into lein itself

13:03 ynniv: ddellacosta: thanks for looking into it. Now that I know it's a problem I'll just hack around until it works.

13:04 xeqi: it won't reject them, just warn on `lein deps :tree`. Thought I think we had a brief discussion on a flag to warn all the time, can't remember now

13:08 Okasu: dnolen: Is this caching are just boring memoization?

13:09 dnolen: Okasu: it avoids paying the cost of constructing the inner function on every call

13:11 ynniv: ok, I just hit c-c c-z and everything worked… are we not using clojure-jack-in anymore?

13:12 or perhaps more succinctly, how are people using clojure in emacs these days?

13:12 dnolen: Okasu: so we can cache all inner functions as functions on the namespace, and GClosure will optimize it.

13:13 Okasu: dnolen: Nice.

13:13 jstew: Greetings. I want to make a small web application to sharpen my clojure skills. What do most people use as a framework? Compjure? Ring? Noir? I'm not lookingfor full stack, just something I can play with.

13:14 ynniv: I prefer straight compojure

13:14 gdev: jstew:) http://pedestal.io/

13:14 ynniv: IIRC noir is no longer maintained

13:14 Okasu: jstew: https://github.com/Okasu/rss Compojure + Ember.js + Ember Data .

13:14 jstew: I looked at pedestal. I was sort of put off by the "sign and fax developer agreement" think.

13:14 s/think/thing

13:15 Okasu: nice! Thanks.

13:15 ynniv: Okasu: what's your experience with ember? I've been trying to build useful apps since Sproutcore 0.7, but the system always seems to trip over itself.

13:15 technomancy: another vote for straight compojure

13:15 gdev: you don't need a CA to use pedestal do you?

13:16 jstew: gdev: Nope. I could be wrong, but my perception is that the CA will hinder adoption and development.

13:16 ynniv: compojure, like sinatra, is probably never going away

13:17 tcrayford: I'd vote for compojure over pedal stool as well

13:17 Okasu: ynniv: It's nice and stable atm(not ember data), 1.0 is really near, we are currently using ember at work, and it's really great.

13:17 rkneufeld: jstew: Relevance guy here, you don't *have* to fax it, you could just digitally sign it.

13:17 rasmusto: gdev: no problem, I think another 'doall' might resolve my problem

13:17 rkneufeld: jstew: and then email it.

13:17 Okasu: s/at work/in production/

13:18 stuartsierra: gdev: No, you do not need a CA to *use* Pedestal. It's open source (EPL).

13:18 If you want to contribute code *to* Pedestal, then you need to sign & email the CA.

13:19 gdev: that's what I thought, I was just wondering why a CA would be a blocker for someone to use it, seemed odd

13:20 ieure: So protocols don't generate classnames you can use for hinting?

13:20 ynniv: the CA is too prominent on the website. it should probably be under the "open source" "tab", versus jumping out at people on a cursory glance over the page

13:20 also, the "tabs" are a poor design choice. they don't look like tabs, and they're difficult to use on mobile.

13:21 rkneufeld: ynniv: really, it's almost at the bottom of the page?

13:21 xeqi: you mean those are buttons you can click on?

13:22 ynniv: rkneufeld: yep, I can quickly swipe my fingers to get an overview of the page, and it stops with legalese in my face.

13:22 xeqi: yep

13:22 rkneufeld: ynniv: fair point. I'll echo that feedback to the people working on the website.

13:23 ynniv: rkneufeld: compare that to reading about languages. you scroll down, don't understand what the framework is about, glance at some grey icons, maybe realize they're clickable, then try to click them (which failed for me on mobile the first time around)

13:23 that would be excellent

13:24 I like the graphic design, tho

13:28 rkneufeld: Thanks

13:28 gfredericks: ieure: they do -- they generate a jvm interface by the same name I think

13:29 ieure: but you'd have to import it or use it fully qualified. Also I can't imagine that it would accurately describe all types that satisfy the protocol

13:29 ieure: gfredericks, Sure doesn't seem to work.

13:30 (defprotocol Component ...)

13:30 (.stop ^Component c)

13:30 Exception in thread "main" java.lang.IllegalArgumentException: Unable to resolve classname: Component

13:30 This is all in the same ns.

13:32 gfredericks: ieure: you may well still have to fully qualify it

13:32 hiredman: ieure:a protocol is not a class, you cannot use it for type hinting

13:32 gfredericks: I just tried it at the repl and it worked fully qualified. I don't think you'd want to try to make Component refer to both the protocol and the interface

13:33 ieure: hiredman, So basically I can't use protocols for performance-sensitive stuff?

13:33 Or it has to be the _type_?

13:33 gfredericks: hiredman: you can't?

13:33 hiredman: ieure: use the protocol functions

13:34 ieure: hiredman, Reference please.

13:34 gfredericks: oh right

13:34 but you can use the interface, if that suffices

13:34 hiredman: ieure: when you create a protocol, you create functions

13:34 tieTYT2: hiredman: thanks for your help earlier

13:34 ieure: Okay, wow, protocols are some bullshit.

13:34 tieTYT2: hiredman: thanks to you, I got some clojure code into our pure java, javaee application

13:35 technomancy: ieure: yesss... feel the hat flow through you

13:35 tieTYT2: I don't know what the opposite of pandoras box is, but you may have just opened it

13:35 technomancy: uh

13:35 hate

13:35 ieure: technomancy, I liked the first one.

13:35 technomancy: whatever floats yer boat

13:36 ieure: So what happens if I define two protocols with the same methods in the same ns?

13:36 hiredman: ieure: protocol functions get inline caches, so use them

13:36 ieure: you can't

13:36 they are collections of functions

13:36 ieure: lmfao

13:36 hiredman: they are not classes/interfaces/methods

13:36 gfredericks: ieure: you can use typehints in the example you gave though

13:36 hiredman: gfredericks: but you shouldn't

13:36 gfredericks: because it doesn't work for 3rd-party types?

13:37 linuxos: how do i get a negative rational number?

13:37 hiredman: gfredericks: because it is silly

13:37 gfredericks: linuxos: ##-3/4

13:37 &-3/4

13:37 lazybot: ⇒ -3/4

13:37 linuxos: don't know why my repl crashes when i do that

13:37 clojure 1.4

13:38 gfredericks: ignore the ## and the &, just type -3/4

13:38 hiredman: (.stop ^Component x), if stop is a protocol function, be the same performance wise (after jitting) as (stop x)

13:38 linuxos: i get Exception Ambiguous match for "-3/4" by #<Object[] [Ljava.lang.Object;@5223588b>

13:38 hiredman: should be

13:38 linuxos: ,3/4

13:38 clojurebot: 3/4

13:39 linuxos: ,-3/4

13:39 clojurebot: -3/4

13:39 gfredericks: linuxos: what sort of repl is this?

13:39 linuxos: lein repl

13:39 gfredericks: have you tried rebooting your modem?

13:39 hiredman: because the clojure compiler can see that stop is a protocol function, it will emit a protocol callsite for (stop x) which includes an inline cache

13:40 gfredericks: linuxos: does the stack trace point to anything interesting?

13:40 ieure: So is there some way to support multiple protocols in a type?

13:40 gfredericks: ieure: one type implementing multiple protocols? yes that's normal

13:40 hiredman: ieure: of course, you can name your functions differently, or put them in different namespaces

13:41 just like regular functions

13:41 "why can't I have two (def x y) in the same namespace?"

13:41 ieure: hiredman, Right, but this requires me to understand implementation details of (deftype).

13:42 hiredman: no, it requires you to know how clojure functions work

13:42 ieure: Which is the problem. It's not clear that it's happening or how it's implemented.

13:42 gfredericks: not really; just the fact that the protocol functions are resolvable as vars inside the namespace would suggest you can't overload them

13:42 which I assume is the recommended usage, as hiredman says

13:42 ieure: The fact that they ARE resolvable as vars inside the ns is not what's clear.

13:42 hiredman: obviously, if a protocol is just a collection of functions in a namespace, you cannot have multiple functions in a namespace with hte same name

13:43 which is why, at the beginning I said "protocols are not classes/interfaces/etc"

13:43 gfredericks: ieure: where are you learning about protocols from? clojure.org/protocols mentions this

13:43 ieure: deftype docs: "Dynamically generates compiled bytecode for class with the given name, in a package with the same name as the current namespace, the given fields, and, optionally, methods for protocols and/or interfaces."

13:43 Indicates that it makes a class. It works like a class.

13:44 gfredericks: deftype is different from defprotocol

13:44 ieure: Does not say "Generates functions in the ns corresponding to methods in the type."

13:44 hiredman: deftypes don't

13:44 gfredericks: the docs for defprotocol indicate in the examples that this is what happens

13:45 hiredman: deftypes are not protocols

13:45 ynniv: oh, swank-clojure is deprecated in favor of nrepl.el? always something new...

13:45 technomancy: swank still works

13:45 hiredman: deftypes can have protocols extended to them

13:46 if you extend the protocol Component (which has the function stop) to the type X, then you can call the function stop on X

13:46 linuxos: gfredericks: https://www.refheap.com/paste/14146

13:46 technomancy: linuxos: I think that's fixed in the latest leiningen

13:46 linuxos: ok

13:46 ieure: Yeah guys you're not convincing me that this stuff is any less shitty.

13:47 Only that you don't understand that to try to use these is peeling a shit onion.

13:47 hiredman: ieure: you've only convinced me you don't know what you are doing

13:47 read the docs

13:48 gfredericks: well. that was a fruitful interaction.

13:49 I wish I could understand that to try to use these is peeling a shit onion.

13:50 then I could help people better.

13:51 technomancy: I got a good hat-related laugh out of it.

13:51 in my book that's a win.

13:51 gfredericks: success criteria: either helping people learn the language or getting a good hat-related laugh

13:51 arrdem: Â/me starts reading scrollback, shocked to see a troll in #clojure

13:51 hiredman: "I wish you could understand that this tool sucks, because I don't know how to use it, and it made me feel bad"

13:52 daemian: i got "peeling a shit onion" out of it. +1

13:52 llasram: I would like to tactfully suggest that mocking people who are having a difficult time does not encourage others to join the community

13:52 ynniv: ,(inc shitonion)

13:52 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: shitonion in this context, compiling:(NO_SOURCE_PATH:0:0)>

13:52 gfredericks: I wonder if "shit" is an adjective-adjective like a brit might use, or a noun-adjective like anybody else

13:53 technomancy: llasram: in general I agree, but I know ieure and he's got very thick skin.

13:53 llasram: Fair enough then

13:53 gfredericks: I don't think we mock people just for having a difficult time

13:54 that doesn't make it constructive though

13:54 TimMc: arrdem: ieure was not being a troll.

13:54 ynniv: fwiw, I avoid the protocol stuff as well. the bits of clojure that get too involved with java have unexpected "functionalities"

13:55 TimMc: Mocking someone for not understanding a language feature is never going to help that language community.

13:55 arrdem: don't understand scrollback... need more coffee

13:55 gfredericks: it's difficult to handle people getting mad at you after you try to help them. a bit like parenting I guess :)

13:56 TimMc: Luckily, in this case you can just abandon the angry person.

13:56 No pesky legal ramifications!

13:56 ynniv: TimMc: just make sure you're abandoning the person and not the problem

13:56 hiredman: I am mocking him for have a ridiculous attitude about it and not being self aware enough to realize it

13:56 TimMc: ynniv: Very true.

13:58 gfredericks: probably best to be gracious about self-awareness-lackages; I've definitely been in that position before, and have no way to prove I amn't currently

13:58 ynniv: hiredman: I think that I showed up here a while ago with a similar protocol related aggravation, but hopefully was more self-aware of my behavior

13:59 technomancy: man, protocols.

13:59 gfredericks: that's technomancy's lesson

13:59 hiredman: *eyeroll*

13:59 arrdem: feh. they exploded in my face the first time..

13:59 ynniv: I have disavowed all knowledge of polymorphism other than defmulti

13:59 hiredman: technomancy just hates anything that generates lein bug reports

13:59 technomancy: gfredericks: life is simpler when you can just stop paying attention as soon as you hear certain words.

14:00 hiredman: basically

14:00 cygwin, protocols, war files.

14:00 sublime text

14:00 xeqi: aot ?

14:00 technomancy: that too!

14:00 gfredericks: why stop at cygwin? windows

14:00 hiredman: alex miller has a talk he gave where he metions protocols for spis, which is where they really shine

14:01 llasram: spis?

14:01 hiredman: sevice provider interface

14:01 gfredericks: spies?

14:01 nope

14:01 llasram: hehe

14:01 ynniv: xeqi: definitely aot. the extension of my knowledge of clojure's aot is :main ^:skip-aot

14:01 technomancy: gfredericks: well, that hate predates leiningen

14:01 hiredman: an api can be a lot of regular functions built on top of a protocol (an spi)

14:02 gfredericks: hiredman: in the dnolen style?

14:02 hiredman: so you can use the api to deal with anything you extend the spi to

14:02 gfredericks: sure

14:02 gfredericks: also similar to the functions that take seqs

14:02 hiredman: gfredericks: you ca drop the the 'the' and just say 'dnolen style' because it starts with a d

14:02 gfredericks: seq is a hand rolled protocol

14:02 gfredericks: hiredman: and now I will

14:03 yeah I used dnolen style for cljs arithmetic

14:03 it feels verbose. but I don't have any better suggestion

14:05 hiredman: our storage stuff at work is structured that way, we have a protocol that describes what operations we need from an object store, and then a bunch of functions on top for retries, md5sum checking, etc

14:06 so to use the storage functions with a new object store, you wire up the protocol at the bottom

14:06 gfredericks: right

14:06 ynniv: can I defer to a different route in compojure? kind of a server-side redirect

14:06 gfredericks: ynniv: you could extract all the functionality to a function that both routes call

14:07 which is to say "no I don't think so"

14:07 ynniv: there isn't enough code to bother with that, but I don't want them to fall out of sync

14:07 gfredericks: how would you even specify what route? construct another path?

14:08 ynniv: yeah

14:08 gfredericks: you could do that a bit manually, but that feels gross

14:08 (defroutes app (GET "foo" req (app {assoc req :uri "bar"})) (GET "bar" ...))

14:08 something like that

14:09 probably lots of reasons not to

14:09 xeqi: or make a mod-rewrite ype middleware

14:09 arrdem: gfredericks: will that work?

14:09 gfredericks: yeah that sounsd a lot cleaner

14:09 arrdem: probably not that exact code. Something similar I think should "work"

14:10 arrdem: gfredericks: I mean I get rewriting the request, I'm just not sure how compojure does routing.

14:10 gfredericks: app is a ring handler, so you can just call it with a request

14:10 arrdem: yeah that'd do it

14:11 gfredericks: does ring say anything about handlers returning nil?

14:12 amalloy: gfredericks: i don't know if it's explicit, but since nil doesn't contain any of the REQUIRED keys, they're not valid responses

14:17 gfredericks: I wonder what the adapters do...404 or 500?

14:17 xeqi: adapters?

14:17 gfredericks: e.g., the ring-jetty-adapter

14:17 xeqi: ah, right

14:17 gfredericks: the thing responsible for taking the clojure value returned and actually telling the client about it

14:18 or telling jetty about it I guess

14:24 amalloy: gfredericks: 500, i'm pretty sure

14:24 if you want a 404, you do it yourself

14:26 tieTYT2: is it inefficient to do this every time a method is called: RT.load("clojure/core"); //need to do this first to initalize the RT clojure.lang.Compiler.load(new InputStreamReader(resourceAsStream, "UTF8"));

14:26 technomancy: tieTYT2: yes, reloading all of core is costly

14:27 tieTYT2: ok maybe I could put this part ina static block

14:27 tylergillies: can "case" function take multiple values matches? like (case foo ("bar" or "baz") "quxx")

14:28 looks like yes

14:28 n/m

14:28 [raven]: Hi :)

14:30 hiredman: tieTYT2: https://github.com/sonian/Greenmail/blob/master/src/main/java/com/icegreen/greenmail/pop3/Pop3Server.java#L24-32

14:31 tieTYT2: hiredman: is that lock relevant?

14:31 hiredman: nope

14:31 tieTYT2: phew

14:31 any reason these first lines aren't final?

14:31 [raven]: I've a question, i'm trying to achieve this: http://paste.fedoraproject.org/10082/ but since I'm a noob, i'm not able to figure out how to make it happen. Someone can help me with some actual code? (I wroted a function that split the = string)

14:31 hiredman: if you reference the RT class, it should load clojure.core in a static init, so you don't need to

14:31 tieTYT2: nope

14:31 tieTYT2: ok I'll try this

14:32 kasterma: I am learning core.logic, using midje to do some testing. I wrote a function last, and corresponding facts. The facts don't behave the way I expect.

14:32 https://gist.github.com/kasterma/5504254

14:32 How to check the output of a function?

14:33 functiono

14:33 I meant.

14:33 tieTYT2: is that static block saying, (require 'greenmail.pop3) ?

14:33 kasterma: (lasto [1 2 3] 4) => u# fails.

14:33 hiredman: tieTYT2: yes

14:34 tieTYT2: ok thanks, sorry for all the questions

14:35 hiredman: kasterma: seems like a bad test, running logic goals out side of a run or run* is weird

14:35 (and who knows what kind of weird stuff midje is doing)

14:35 kasterma: Weird indeed, but at least I expect that to be the output.

14:35 (logic/run 3 [q] (lasto q 3)) => '((3) (_0 3) (_0 _1 3))

14:35 (logic/run* [q] (lasto [1 2 3 4 5] q)) => '(5)

14:35 These are as expected.

14:36 Is my expectation about the output incorrect?

14:36 hiredman: kasterma: sure, and those should be, but looking at the result of a goal outside of a run is looking an implementation detail

14:38 kasterma: hiredman: that is an interesting idea; I didn't think of it as such.

14:38 tylergillies: dafuq is up with this? https://gist.github.com/tjgillies/2652fe183ab19c2d9923

14:38 heh

14:38 kasterma: does seem to make sense though. Guess I'll refrain from testing like that. thx

14:39 tylergillies: throwing CompilerException java.lang.IllegalArgumentException: Duplicate case test constant: or, compiling:(NO_SOURCE_PATH:4:3)

14:40 oh derp

14:40 the default clause is a single clause

14:40 not a clause called default

14:41 doh that didn't seem to work either

14:42 justin_smith: tylergillies: case does not want a function to apply, it wants the literal value to check

14:42 it is turning (or "develop" "staging") into "develop" before the statement runs

14:42 not comparing to both

14:43 akells`: how does one get the length of a byte array? For example, I get a 'no matching field' found for (.length (.getBytes "abc"))

14:43 sorry, this is a borderline java question I guess

14:43 llasram: &(count (.getBytes "abc"))

14:43 lazybot: ⇒ 3

14:43 ToBeReplaced: tylergillies: justin_smith is right, consider cond, or transforming your value before the case

14:43 akells`: thanks llasram

14:44 tieTYT2: god I really hate that -/_ bs that clojure makes you do

14:44 xeqi: &(alength (.getBytes "abc"))

14:44 lazybot: ⇒ 3

14:44 tieTYT2: it would be simpler if they just forbade the - symbol

14:44 tylergillies: doh thanks

14:46 akells`: thanks xeqi

14:46 justin_smith: case is nice because it can do constant time dispatch unlike other stuff. one simple option: (case cluster-name "develop" "testing" "staging" "testing" "production" "production" "production)

14:46 akells`: alength vs. count -- is there a reason to pref one over another?

14:46 justin_smith: I missed a " above

14:47 TimMc: ,(class -)

14:47 clojurebot: clojure.core$_

14:48 ToBeReplaced: akells`: if it's a java array and you need speed, use alength... if it's a clojure collection, use count

14:48 akells`: much appreciated ToBeReplaced

14:48 xeqi: I believe alength gets translated into the jvm bytecode for array length, so should be faster

14:48 amalloy: justin_smith, tylergillies, ToBeReplaced: that's not really an accurate description of what case does, or how to fix his problem

14:48 akells`: thanks xeqi

14:48 dnolen: kasterma: did you solve your problem?

14:49 justin_smith: oh, test-constants- I see that now

14:49 !

14:49 amalloy: case takes literals, so it doesn't evaluate them at all. it's certainly not turning it into "develop" at compile-time; rather, it treats a list of things as an "implicit" 'or

14:49 justin_smith: cool, amalloy, thanks!

14:49 amalloy: so it's saying that it will fall into clause 1 if the value is any of: 'or, "develop", "stagin"; and clause 2 if the value is any of: 'or, "production"

14:50 kasterma: dnolen: well, solve is one word for it. :-) I learned that the results of goals are considered implementation dependent, and I should just test in the context of run.

14:50 amalloy: the fact that the symbol 'or falls into two clauses means it can't compile. if you just removed the or from both of those lists, everything would work fine

14:50 tylergillies: (inc amalloy)

14:50 lazybot: ⇒ 52

14:50 kasterma: This removes the problem, but I am still getting used to it.

14:50 dnolen: kasterma: this true, results of a goal is opaque anyhow, you'll just get a function

14:51 kasterma: dnolen: => s# worked though, only the => u# didn't.

14:51 I did see that in the repl different function no's were given.

14:51 amalloy: akells`: alength if the array is type-hinted

14:51 count if you don't know its type, or you care more about readability than performance

14:52 akells`: amalloy: much appreciated, thank you

14:52 kasterma: dnolen: anyway, thanks for checking up with me. I am really excited about learning core.logic. Just a year ago I switched from being a logician to being in IT. Now logic is back!

14:53 dnolen: kasterma: heh, cool.

14:53 hiredman: alength is silly

14:53 count can take arrays and has a special case for them and doesn't do anything silly like turning them in to seqs first

14:53 clojurebot: seqs and colls is http://www.brainonfire.net/files/seqs-and-colls/main.html

14:53 amalloy: hiredman: count does reflection for arrays

14:53 kasterma: dnolen: I am finding it strangely easier to proof the existence of weird stuff from AC, than to get into logic programming. Just started though.

14:54 dnolen: kasterma: AC?

14:55 kasterma: dnolen: axiom of choice.

14:55 [raven]: no help? http://paste.fedoraproject.org/10082/

14:55 dnolen: kasterma: the learning curve around logic programming is pretty steep I think, but then it gets very flat.

14:56 kasterma: dnolen: I am doing the prolog 99 problems now. Directly working on what I think it'll help with is a bit too steep.

14:57 dnolen: kasterma: cool! I haven't tried those myself - it may be that some of the more advanced example may require features of Prolog we don't have yet.

14:57 Okasu: ~/quit

14:57 clojurebot: No entiendo

14:57 dnolen: advanced problems I mean

14:58 ToBeReplaced: amalloy: that's wacky with case; i had no idea ->

14:58 kasterma: dnolen: if I have as much fun with learning as I expect, than I'll just keep going and help implement to get the features. :-)

14:58 ToBeReplaced: ,(case '(0) (0) 1 0)

14:58 clojurebot: 0

14:59 dnolen: kasterma: help always welcome

14:59 ToBeReplaced: that scares me... because that's not at all obvious

14:59 ,(case '(0) [0] 1 0)

14:59 clojurebot: 1

14:59 tieTYT2: why's there no disj for maps?

14:59 kasterma: dnolen: one other thing I read recently that I am very interested in in probabilistic prolog ideas; think Church.

14:59 are there implementations of that going?

15:00 dnolen: kasterma: we might do a Google Summer of Code on that

15:00 amalloy: yes, if you have never read the docstring for case, that is not obvious. but it includes a specific mention about not doing that

15:00 dnolen: kasterma: there is an existing Church-like project

15:00 kasterma: dnolen: link?

15:00 dnolen: https://github.com/clojure/core.logic/wiki/CLP%28Prob%29

15:02 kasterma: dnolen: thx, I'll take a careful look after I finish singletono and next2lasto.

15:03 trptcolin: [raven]: https://www.refheap.com/paste/14150

15:05 [raven]: trptcolin: Thanks a bunch!

15:07 gfredericks: ToBeReplaced: that's pretty weird; what's the difference there?

15:07 ,(case '(0) '(0) 1 0)

15:07 clojurebot: 1

15:13 ToBeReplaced: gredericks: if the test constant is a list, it checks whether the expression is in the list, not equal to the test constant

15:14 i didn't know that until a few minutes ago... amalloy points out that it's in the docstring... still took me by surprise

15:14 amalloy: ,(case 'quote '(0) 1 0)

15:14 clojurebot: 1

15:15 tieTYT2: ,(type vals {})

15:15 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$type>

15:15 tieTYT2: ,(type (vals {}))

15:15 clojurebot: nil

15:15 tieTYT2: doh

15:15 why does that return a clojure.lang.APersistentMap$ValSeq ?

15:15 I guess that's a type of sequence

15:16 i'm taking the result of a (vals m) call and trying to put it in an ArrayList

15:17 amalloy: tieTYT2: why would you put it into an ArrayList?

15:17 tieTYT2: but that's not working as expected. It's giving me a persistent list with APersistentMap$ValSeq in it, with the values in there that I want

15:18 I want to put the values into an arraylist

15:18 I'm calling it from java

15:19 and the java code wants to put it in an arraylist

15:19 i'm not sure if I answered your question or not

15:19 amalloy: tieTYT2: if the java code really wants an arraylist it's pretty bad java code

15:20 it should be happy to accept a Collection, or at least a List, which clojure sequences implement

15:20 tieTYT2: well the thing is this is going to be passed to JPA

15:20 and I'm concerned JPA will freak out if it's a clojure List

15:21 antares_: Titanium beta1 is released: http://blog.clojurewerkz.org/blog/2013/05/02/titanium-1-dot-0-0-beta1-is-released/

15:21 amalloy: well that's silly. unless it actually has a problem, or the javadoc explicitly says it must have an ArrayList, don't be concerned until you've tried the obvious, easy thing and it doesn't work

15:22 tieTYT2: ok fair enough

15:23 amalloy: glancing through the JPA javadoc, it seems to work with interfaces as generic as possible, so good on them

15:23 tieTYT2: but, vals is returning a List that returns a PersistentVector when I call "get" on it

15:23 so there must be some flaw in my clj code

15:31 oh the group-by result has a list wrapped around it for some reason

15:31 must be a problem with my input

15:40 oh i get it now. Group by returns a map where the values are wrapped in a vector. I forgot that vector part

15:42 justin_smith: code I literally just now wrote: (defn itemize-by [k m] (into {} (map (fn [[k [v]]] [k v]) (group-by k m))))


15:42 yes I use k twice, which is bad

15:46 tieTYT2: how can I make this code more idiomatic? https://www.refheap.com/paste/cc1d92f1176a5eaf454cadcc6

15:49 rbxbx``: tieTYT2: I believe (vals (apply dissoc (keyed-map db) (keys (keyed-map changes) could be replaced by using select-keys (http://clojuredocs.org/clojure_core/clojure.core/select-keys)

15:49 tieTYT2: how's this? https://www.refheap.com/paste/dce5a89c541657841a9645b82

15:49 rbxbx``: (I think that's what you're doing, yes?)

15:50 tieTYT2: yes I think so

15:50 ok thanks

15:50 rbxbx``: np

15:52 tieTYT2: actually I think select-keys is the opposite of what I want

15:52 i want to remove the keys

15:53 not keep them

15:53 oh but i think ic an do it this way

15:57 justin_smith: #(.getConsentKey %) == (memfn getConsentKey)

15:58 that is one way to make it more idiomatic, tieTYT2

15:58 llasram: Except that `memfn` is basically deprecated

15:58 justin_smith: it is?

15:58 why is that?

15:58 ppppaul: i want to do something like (update-in {:a "1"} [:a] Long/parseLong)

15:58 and suggestions?

15:58 any*?

15:59 tieTYT2: justin_smith: what I did or what rbxbx`` is suggesting?

15:59 gfredericks: ppppaul: #(Long/parseLong %)

16:00 ppppaul: thanks :)

16:00 gfredericks: not really possible to call a static method succinctlier than that

16:00 llasram: justin_smith: *shrug* All I know is that parts of the Internet believe rhickey so-considers it

16:00 ppppaul: i guess i could wrap it

16:01 llasram, what?

16:01 llasram: ppppaul: Re: memfn pseudo-deprecation

16:01 justin_smith: tieTYT2: well it applies to both, I personally think (memfn getConsentKey) is better than #(.getConsentKey %) but they are identical in what they do

16:01 gfredericks: memfn reduces the number of classes generated by compilation, no?

16:01 ,(class (memfn foobar))

16:02 clojurebot: sandbox$eval36$fn__38

16:02 gfredericks: ,(map class [(memfn foo) (memfn bar)])

16:02 clojurebot: (sandbox$eval75$fn__77 sandbox$eval75$fn__80)

16:02 llasram: gfredericks: memfn is a macro, so no

16:02 gfredericks: hmm

16:02 ah good point

16:02 it's partial that does that

16:02 ,(map class [(partial + 2) (partial + 4)])

16:02 clojurebot: (clojure.core$partial$fn__4214 clojure.core$partial$fn__4214)

16:02 gfredericks: phew

16:02 I'm right about _something_ at least

16:02 llasram: Heh :-)

16:03 I try not to let that go to my head when it happens to me

16:03 gfredericks: ask me anything about clojure and I'll find something different that I'm right about

16:04 amalloy: gfredericks: do you guarantee that it's a different something every time?

16:04 if so, i have uncountably-many questions for you whenever you've got the time

16:04 justin_smith: oh - one reason #(.foo %) beats (memfn foo) is that you can type hint the former

16:04 gfredericks: amalloy: sure, just send me a list of them

16:05 amalloy: gfredericks: (keep to-ascii-string (range))

16:05 gfredericks: I question your use of "uncountable"

16:05 amalloy: yeah, i know. that's countable, sadly

16:06 gfredericks: you can't waffle on the very thing I was counting on to prevent you from fulfilling my demands

16:06 amalloy: i couldn't quickly think of a way to generate an uncountably-infinite list in clojure

16:06 technomancy: there's no reason memfn couldn't take an optional type hint though

16:06 kind asilly

16:06 gfredericks: "uncountably infinite list" is oxymoronic

16:06 amalloy: is it?

16:06 gfredericks: "countable" == "listable"

16:07 justin_smith: technomancy: I agree, I like memfn better than anonymous function literals, just reporting what I find when looking for an explanation for the deprecation

16:08 tieTYT2: justin_smith: http://blog.jayfields.com/2011/08/clojure-memfn.html

16:08 according to that, "...it is almost always preferable to do this directly now..."

16:08 technomancy: is there a good reason why references to static methods can't be auto-memfnd?

16:08 err--not memfn but some static equivalent of memfn

16:09 seems like it could be easy to determine at compile time

16:09 gfredericks: such that you could (map Long/parseLong ["1" "2"])?

16:09 technomancy: why not?

16:09 gfredericks: I've wondered that too

16:09 same for instance methods, no?

16:09 technomancy: maybe arity ambiguity?

16:10 gfredericks: depends on whether a leading dot is legal anywhere elsee

16:10 ystael: gfredericks: i don't suppose you'd accept "map with well-ordered domain" as a proxy for "list"? :)

16:10 technomancy: I guess you could have :require [my.stupid.long :as Long]

16:10 amalloy: gfredericks: (for [n (range), set (power-set (range n))] (to-ascii set))? that should have cardinality larger than the integers, thus uncountable, right?

16:10 technomancy: capitalization isn't a reliable indicator in this case

16:11 ystael: amalloy: nope, that's a countable union of finite sets, still countable

16:12 gfredericks: any list of finite objects is countable

16:12 so if you've giving me a list of finite strings then it doesn't matter how you generated them

16:14 amalloy: i've changed my mind and now hate set theory forever

16:14 gfredericks: read about ordinals instead of cardinals

16:14 they're much trippier

16:15 technomancy: so the "ambiguity" is actually resolvable (duh) because the compiler knows the ns map

16:15 gfredericks: well; based on the amounts of either topic that are in my head

16:15 technomancy: how silly of me

16:15 gfredericks: ystael: your map with a well-ordered domain would have to accept infinite arguments I guess?

16:17 ystael: gfredericks: well, your well-ordered domain could be [0..1] given any well-ordering from Zermelo's theorem :)

16:17 gfredericks: but if you're in clojure you can't represent arbitrary irrational numbers

16:18 unless you want to argue that some mapping from infinite lazy sequences of something to irrational numbers suffices

16:18 ystael: the map still would not be representable in clojure, that's true

16:19 gfredericks: you brought up well-ordering as a weaker form of a "list"?

16:19 ystael: i was being silly :)

16:20 gfredericks: I cannot take set-theory but seriously

16:20 technomancy: set theorists, on the other hand

16:20 ystael: i figured, if you want to give an uncountable "list" of questions, maybe you could at least index them by the first uncountable ordinal or something

16:21 djwonk: do functions used in `reduce` have conventional param names? (e.g. [acc item] or something?)

16:21 gfredericks: ystael: it's a "generalized list" :)

16:22 technomancy: djwonk: I usually use `acc' unless I can come up with a better name (nodes, counts, etc)

16:22 djwonk: technomancy: thanks

16:22 technomancy: elem, item, or x for the second

16:22 djwonk: technomancy and hello from clojure/west

16:22 technomancy: hi hi

16:23 gfredericks: what? clojure/west is happening again?

16:23 this must be a dream

16:23 crap crap crap I must be missing my talk

16:23 djwonk: it probably will, but not today

16:24 gfredericks: I bet there's a class I failed to show up to all semester too while we're at it

16:24 * gfredericks misses his wedding altogether

16:24 djwonk: the swearjure talk was brilliantly executed, it set a new bar for seriously joking talks

16:24 gfredericks: haha, thanks

16:25 djwonk: oh, I said that without realizing it was you!

16:26 maybe my subconscious knew?

16:27 ystael: every time i hear the phrase "brilliantly executed" my mind's eye sees a very, very shiny axe

16:30 clojurenewb: hi, is there a way to handle an assertion error nicely, presenting a friendly message to the user without littering my function with exception handling ?

16:30 djwonk: ystael: as opposed to duly executed, like a legal document or rusty guillotine?

16:31 I guess it makes a difference: duly executed vs. dully executed

16:32 stuartsierra: clojurenewb: Exception-handling is usually messy.

16:33 djwonk: I'm thinking about a parsing problem. I've got a list of things and I'm building up a array (with nesting). I'm thinking about building it up with 'reduce' but it might not be the right way... since I need to keep track of the "next position" where an insert will happen

16:33 clojurenewb: stuartsierra: totally agree

16:33 it just makes my functions cluttered

16:34 technomancy: clojurenewb: there was a lib recently announced called "dire" that attempts to separate that kind of stuff out. haven't tried it, but it might address what you're asking.

16:36 mthvedt: djwonk: if you're using a parser lib, there is probably some way to rewrite parser rules to make it simpler

16:36 clojurenewb: technomancy: yes, I had a look at that, was hoping to avoid more dependencies etc, see if there was anything doable in core clojure

16:36 djwonk: mthvedt: I'm not currently using a parser lib, maybe I should consider doing so

16:36 gfredericks: clojure's built-in error handling is pretty raw

16:37 which is probably partly because libraries can make it arbitrarily nice via macros &etc

16:37 technomancy: I wouldn't worry about avoiding dependences, but avoiding new constructs that aren't built-in or particularly well-understood/well-documented is wise

16:37 mthvedt: djwonk: i'd like to plug my project, https://github.com/eightnotrump/clearley, to try to make "parsers that do things" easy to write

16:37 gfredericks: technomancy worries about dependencies so that you don't have to

16:37 technomancy: gfredericks: &etc is redundant

16:37 etc or &c

16:38 gfredericks: just because it's redundant doesn't mean I don't want to say it

16:38 technomancy: I see

16:39 gfredericks: redundancy is desirably in all sorts of situations, especially communication

16:39 * technomancy scribbles some observations on his clipboard and moves on

16:39 gfredericks: I'll go as far as I have to in order to keep from backtracking on anything I say

16:39 technomancy: "pin number"

16:40 trinary: "atm machine", "NIC card"

16:40 reeses: nic has been retronamed controller

16:40 since they're not usually on cards anymore

16:41 trinary: fair enough :)

16:41 callen: gfredericks: & is et which is "and"

16:41 gfredericks: et cetera => & cetera => &c

16:41 reeses: &c. is a great way to create an affected style

16:41 lazybot: java.lang.ClassNotFoundException: c.

16:42 wink: never seen &c

16:42 but I've also never seen "and yet" as in http://andyet.com/

16:42 technomancy: it's even better if you have fancy-pants typesetting on your ampersands

16:42 wink: you and your silly mothertongue!

16:42 djwonk: mthvedt: cool. do you think it would be a good fit for: https://gist.github.com/bluemont/5505213

16:43 reeses: technomancy: the two do seem to go hand-in-hand, don't they?

16:43 technomancy: reeses: one would hope

16:43 reeses: the sort of person who uses ffi ligatures

16:44 or the worst, the ct and st ligatures

16:44 TimMc: office

16:44 doesn't look too good in my terminal

16:44 djwonk: ligatures are a pain

16:44 technomancy: djwonk: that's how it shows you care

16:45 if it were easy everyone would do it

16:46 djwonk: oh? I mean converting ligatures from PDFs into searchable text is something I need to deal with

16:46 probably not too bad if I just did it and quit complaining about it

16:46 reeses: they're fine if implemented correctly, so the text layer has the non-ligature version for searching/indexing

16:46 mthvedt: djwonk: taking a look… that grammar's partially context-sensitive, i think

16:46 reeses: djwonk: you're dealing with the output of lazy typesetters, then

16:47 mthvedt: is any x.y intended to be a subheading of x?

16:47 djwonk: reeses: I think there are decent ligature conversion tools in Unicode

16:48 mthvedt: the actual text of the heading does not matter. I should have mentioned I have a `heading-level` function that returns the nesting level

16:48 reeses: yeah, you can play with the text layer to replace them

16:49 mthvedt: djwonk: is heading level a fn of the number of ='s

16:49 djwonk: mthvedt: just updated the gist, "==" is level 1, "===" is level 3, etc.

16:49 urg... "===

16:49 is level 2

16:50 FWIW, I'm parsing MediaWiki headings

16:51 mthvedt: I think if I pass along the current heading level in the reducer, I can parse manually pretty easily, not that I think about it

16:51 not->how

16:51 mthvedt: djwonk: that sounds best

16:52 it's a context-sensitive grammar, so no parser can do it automatically, the best is to split the chunks into tokens and do the thing you said

16:53 at least, no parser i know of for clojure

16:53 djwonk: mthvedt: thanks for taking a look

16:53 I'll share back when I've got it

16:54 mthvedt: djwonk: np

17:04 TimMc: djwonk: NFKC doesn't do what you need?

17:06 (Norm/normalize "\ufb03" NF/NFKD) ;;= "ffi"

17:06 djwonk: TimMc: haven't tried http://docs.oracle.com/javase/7/docs/api/java/text/Normalizer.Form.html#NFKC yet -- hopefully it will!

17:06 thanks

17:07 TimMc: NFKD might actually be what you want, I dunno.

17:08 djwonk: it sounds better than ignoring it and hoping they will fix themselves

17:12 mthvedt: side note: converting the output structure to all arrays (no hashes) makes it easier to incrementally build

17:14 tieTYT2: i like how pre/post throw errors even if -ea isn't set

17:14 akells`: does anyone have experience with java.nio.file.Files readAllBytes method? I'm about to tear my entire project apart under the assumption that it isn't reading all of a files bytes, but I wanted to ask around before I do. google doesn't seem to be helping me here. here's the code I'm using to create the byte array: http://pastebin.com/X9MhtxsC

17:15 djwonk: akells`: any chance you are closing the file too soon?

17:15 akells`: djwonk: I'm wondering if that might be the case, because all of my files are several kb short

17:15 djwonk: I've done that by mis-using `with-open`

17:16 akells`: djwonk: but the pastebin code is the only part that is actually dealing with the filesystem

17:16 I just don't see how I could be closing it too early, based on the nio.file.Files docs

17:17 djwonk: that was my only guess, it might not be the actual problem

17:17 akells`: djwonk: I appreciate the input

17:18 djwonk: akells`: can you share the code where you consume the bytes?

17:18 akells`: djwonk: as in, where I'm writing them out?

17:19 djwonk: sure

17:19 gfredericks: callen: now I know

17:22 akells`: djwonk: sorry it took a minute. http://pastebin.com/s9s2gw0f

17:22 the top function is just the snippet I'd pasted before

17:23 I'm able to properly get the length of the byte array -- at the point that its doing the concatenation, it knows the proper size of the image file

17:23 djwonk: akells`: black & white clojure code is hard to read (nudge)... where's the syntax highlighting... :)

17:23 akells`: oh sorry

17:23 http://pastebin.com/1e1FxBZR

17:25 djwonk: thanks :) I'm no expert, maybe someone else can help. I was just trying to figure out where the files were being opened and closed. it looks implicit -- if so, I'm not sure how you could be messing that up (not saying you are)

17:25 akells`: yeah. something must be going wrong at the concat part, I think. because I have a function that gets the length, and it uses the same .readAllBytes method to get the length

17:26 so that makes me think that if .readAllBytes is properly returning the length, it is probably also getting all the bytes properly. which would indicate that maybe the problem is somewhere else -- like the concat function or the actual outputting

17:27 mebaran151: easiest way to do an sha1sum?

17:27 djwonk: akells`: any chance you are reading the file twice and messing up the file pointer?

17:29 gdev: lazybot:) whatis he talking about?

17:29 akells`: djwonk: hm I'll look into that

17:38 mchampine: mebaran151: Perhaps https://github.com/franks42/clj.security.message-digest but are you sure you just want SHA1? What's it for?

17:40 Don't use SHA1 for password hashing. There are better alternatives.

17:41 aaelony: started playing around with Analemma which is really nice for drawing svg graphs served by ring. xy-plot (https://github.com/liebke/analemma/blob/master/src/analemma/charts.clj) works really well, but trying to figure out how to connect points into lines and also how to add an x label and a y label....

18:00 mebaran151: mchampine: not exactly for password hashing: I wanted an easy way for a partner app to demonstrate it generated a certain bit of JSON

18:09 SegFaultAX: mebaran151: bcrypt for passwords. Seriously.

18:12 arrdem: mebaran151: bcrypt yo you know you want to

18:26 mchampine: mebaran151: I put a snip w/ a simple SHA1 here: http://pastebin.com/3PfQfM7Q

18:27 trptcolin: mebaran151: if that bit of JSON is for the partner app to prove it knows a secret, you probably want a MAC [assuming security actually matters for your use case]. SHA1 is vulnerable to length extensions (https://blog.whitehatsec.com/hash-length-extension-attacks/#.UYLl_Ss4VV8)

18:29 _gdev: gdev: y u no remember to log out

18:30 mchampine: As long as you're just making sure 2 chunks of text match SHA1 is fine. If it's for anything you want to be secure, don't use it. trptcolin is right, use MAC (e.g. HMAC) to prove you know a secret - via challenge/response.

18:47 arohner: are there any libraries (or emacs modes) for properly indenting a chunk of clojure source?

18:47 with newlines

18:47 hiredman: clojure.pprint has a code mode

18:48 which is not perfect by any means, but is better than nothing

18:48 nDuff: emacs isn't that far off with clojure-mode IME

18:49 hiredman: actually, I should say it is pretty good, when I used it last the most annoying thing was docstrings

18:49 it would print a doc string like a string literal so "\n" instead of newlines, etc

18:50 arohner: I tried clojure.pprint, but it royally screwed some fns, like (foo \n bar \n baz \n 1 \n 2), etc

18:50 technomancy: yeah, I've had mixed luck with pprint

18:51 hiredman: arohner: using the code-dispatch?

18:51 arohner: hiredman: yes

18:51 hiredman: have you adjusted *print-right-margin* ?

18:52 there is https://github.com/brandonbloom/fipp

18:52 arohner: hiredman: ah, no. I'll play with that. thanks

18:52 hiredman: it doesn't have a code mode

18:57 callen: "The latest stable version of Clojure Core is 1.3.0." <-- remind me why we tolerate clojuredocs?

18:59 technomancy: because the alternative is incessant whining?

18:59 callen: technomancy: wasn't there an effort to make a similar site a year'ish ago?

19:00 technomancy: dunno

19:00 callen: it was around the time I was pondering something similar, and I was told not to bother because they had something in the works.

19:00 but nothing's changed, so I'm reconsidering.

19:00 technomancy: there's a new backend

19:00 callen: wut

19:00 technomancy: to clojuredocs.org?

19:00 technomancy: ayup

19:00 it's just blocked on someone volunteering to port the rails codes

19:01 callen: still looks to be rails to me.

19:01 if the current app is Rails, what was the old app?

19:01 technomancy: every time it comes up someone is like "oh I guess I should help out with that" and no one ever does

19:01 callen: my solution wasn't really to fix clojure-docs, it was to just make a clojure-backed wiki that was populated with documentation.

19:01 technomancy: the current frontend is from the old version

19:02 the current backend is a compojure REST API thingy

19:02 callen: isn't the documentation populated by a script? Why isn't that just re-run for 1.4 and 1.5?

19:02 I feel like I'm missing something here.

19:02 technomancy: I don't think there's a script

19:02 it was probably hand-imported

19:03 mysql was involved

19:04 arrdem: technomancy: incessant whining is easier than porting a rails app

19:04 for now

19:05 callen: so is the issue that the rails app needs to be ported to a clojure app/

19:06 I'm a little puzzled as to why the delineation of frontend rails app // backend compojure app exists.

19:06 technomancy: just a clojure HTML UI really

19:06 callen: I'm bumbling around on his github, looking for that backend.

19:06 technomancy: callen: IIRC the backend was added to make the repl clojuredocs-client more feasible

19:07 arrdem: I mean if it's just an issue of porting the frontend style to a compojure template we have tools to automate a good chunk of that

19:07 I and three other ppl have written html -> compojure templating engines

19:07 callen: technomancy: do you know who owns/runs the backend?

19:07 I can't find it on zkim's gh

19:07 technomancy: I know dakrone is involved

19:07 callen: arrdem: no.

19:07 technomancy: antares probably too given how much he goes off on docs

19:08 amalloy: technomancy: i don't think so. i think antares just started clojure-doc.org or whatever, to compete instead of fixing

19:08 technomancy: amalloy: there's no competition really

19:09 one is completely static long-form prose, one is per-var reference and comments

19:09 amalloy: sure, the value they provide is totally different. but they're fighting over domain name mindshare :P

19:09 callen: they're both nice to have.

19:10 I just wish the API docs were 1.5

19:10 technomancy: amalloy: long-term plan is to make the prose one a subdomain

19:10 I think there were hiccups around domain registration transfer or something

19:11 I just use docstrings

19:11 and ask on IRC when something is confusing

19:11 HTML docstrings are way overrated

19:13 Apage43: If I'm really feeling crazy I'll use markdown docstrings

19:15 arrdem: Apage43: long live lein-marg!

19:16 Apage43: yes :)

19:17 stian_: Want to do a "quantified self" app in Clojure - both to store data from my time tracker (start, end, category), but also be able to insert arbitrary time-based "facts" (time, ran 2km) (day, sleep quality: 4) etc... What would be a good storage layer? I was thinking about a key-value store, but needs to be embedded (this will not be a web app). And need good ability to query on range of time/date.

19:18 arrdem: stian_: first off github that 'cause that's something I've been thinking about for a while

19:18 callen: stian_: don't implement your own logical storage layer yourself

19:18 stian_: use a real database and store time in UTC

19:19 arrdem: stian_: callen beat me to it.

19:19 technomancy: stian_: there's a decent embedded BDB for Java IIRC

19:19 stian_: callen: Yeah, but if embedded, it's basically Sqlite3?

19:19 technomancy: don't use sqlite

19:19 on the JVM

19:19 callen: stian_: define embedded for me.

19:19 technomancy: the jdbc bindings are no good

19:19 stian_: callen: I'd like to be able to wrap an uberjar in a DMG, and have someone run it. Witout having to start a Redis server or something

19:19 callen: stian_: because I've known srs-face embedded engineers and people who just mean, "doesn't use a daemon"

19:19 arrdem: stian_: ibdknox's simpledb would probably cut it for a start,

19:20 stian_: then transition to a mongo instance

19:20 callen: cringe.

19:20 arrdem: callen: better plan?

19:20 brehaut: doesnt derby come with java these days

19:20 callen: stian_: the most well-tested solution to this "zero-daemon database" is sqlite3, despite the whining about it.

19:20 stian_: arrdem: Mongo instance for a "native" GUI app?

19:21 technomancy: sqlite3 is fantastic

19:21 callen: stian_: bdb is the other well tested solution, but you'll be hacking up your own indices and projections.

19:21 technomancy: if you are not on the JVM

19:21 callen: technomancy: what's the problem with sqlite3 on the JVM?

19:21 arrdem: is this a desktop application?

19:21 technomancy: callen: the jdbc bindings are a mess as soon as you need concurrency

19:21 stian_: H2?

19:21 arrdem: callen: evidently

19:21 hiredman: derby or h2 are both respectable choices

19:21 callen: technomancy: singleton db handler. :P

19:21 stian_: callen: Yes.

19:22 technomancy: use derby or h2 if you need SQL, BDB if you need just k/v

19:22 hiredman: I have a 3 gig h2 db here I've been using for crunching log stats

19:22 callen: stian_: is this a toy or scratch-my-itch thing?

19:22 hiredman makes a good point about derby and h2, assuming JVM is a given.

19:22 stian_: callen: Both :) Just playing around for now, but of course I'll put it on GH and if other people like it, maybe it could become sth more. Not talking about a lot of data though - performance is not a big issue.

19:23 callen: stian_: I'd say sqlite3 with a singleton database handler, h2, or derby.

19:23 stian_: callen: Thanks

19:23 callen: I'm not sure to what extent you're going to need concurrency here.

19:23 stian_: FleetDB?

19:24 callen: stian_: no.

19:28 stian_: OK, I think I'll try with H2.

19:56 pendlepants: anyone have a recommendation for a cassandra library?

20:11 djwonk: I want to apply a function n times. This is what I'm using. Is there a more idiomatic way? (nth (iterate peek my-vector) 2)

20:11 I'm grabbing the 'last' part of a nested vector

20:11 in the above case, (peek (peek my-vector))

20:11 amalloy: djwonk: no

20:12 you could (-> (iterate peek my-vector) (nth 2)) if you want; i don't like nth's argument order, personally

20:12 djwonk: amalloy: thanks! the parsing code I'm working on is pretty fun

20:35 tieTYT2: what if I'm using the threading operator to pass through dissoc and map? The former wants the seq as the first, the second wants it as the last

20:35 should I just not use threading in this case?

20:37 mthvedt: tietyt2: https://github.com/rplevy/swiss-arrows

20:37 tieTYT2: jesus that's intimidating

20:37 there's not an easier way?

20:38 I was hoping I could do this with the ->> operator: #(dissoc % nil)

20:38 mthvedt: tietyt2: i think that's allowed

20:38 also

20:38 Raynes: tieTYT2: You should just not use threading in that case.

20:39 Please don't try to hack around things just to use the threading operators.

20:39 They're made for specific situations.

20:39 tieTYT2: I did this: (->> (dissoc consents nil) vals (map count) (filter #(not= 1 %)) empty?)

20:40 that's not too hacky is it?

20:40 Raynes: No.

20:40 tieTYT2: ok good

20:40 i don't understand why my anonymous fn didn't work though

20:40 it said it couldn't convert something into an ISeq

20:40 mthvedt: i think you have to do

20:40 (#(blah blah))

20:41 tieTYT2: oh yeah

20:41 it looks better the way I wrote it so I'll leave it like that

20:46 mthvedt: if you have a long threading chain, it's often easier just to stick a (#()) in there

20:46 i don't think it's more obscure than lots of irritating superfluous parens

20:48 tieTYT2: seems practical, thanks

20:48 i lucked out that I didn't need to do that

20:48 mthvedt: yeah, your solution is fine, i was just trying to be passive-aggressive towards raynes

20:49 :P

20:49 tieTYT2: hah

20:49 xeqi: you wont win that battle

20:49 amalloy: haha

20:49 mthvedt: passive aggression isn't choosing battles… it's a lifestyle

20:50 tieTYT2: thanks, ttyl

20:51 Raynes: I've been called the king of passive aggressiveness before.

20:51 Be careful.

20:53 xeqi: or direct aggressiveness https://twitter.com/IORayne/status/247648094362157057

21:01 dobry-den: there is just no end to raynes' rage. i encountered this gh issue last week https://github.com/kingtim/nrepl.el/issues/83#issuecomment-8794778

21:02 Raynes: That was my very thoroughly filtered thoughts.

21:04 mthvedt: raynes? more like

21:04 raygenes

21:04 (one syllable)

21:08 djwonk: is `conj` efficient for vectors? If so, how would I know from the docs?

21:09 gfredericks: ,(doc conj)

21:09 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

21:09 gfredericks: it's _very_ mildly implied from the last sentence

21:11 djwonk: thanks gfredericks

21:11 gfredericks: the idea is that conj adds things in a way that's appropriate for the datatype

21:12 djwonk: it is mentioned on the cheatsheet at http://clojure.org/cheatsheet, but not at this summary of vector functions: http://clojure.org/data_structures#Data Structures-Vectors (IPersistentVector)-Related functions

21:12 so there is a slight disconnect in the docs as to the question of "is conj encouraged" for vectors

21:12 gfredericks: it definitely is

21:13 assoc works too but you have to know the index so that's dumb

21:13 djwonk: thanks

21:13 akhudek: conj is amortized log32n or something for vectors, so very fast

21:39 gfredericks: ,(let [v (vec (range 10000))] (time (dotimes [_ 10000] (conj v :foo))))

21:39 clojurebot: "Elapsed time: 5.003558 msecs"\n

21:39 gfredericks: ,(let [l (apply list (range 10000))] (time (dotimes [_ 10000] (conj l :foo))))

21:39 clojurebot: "Elapsed time: 1.476985 msecs"\n

21:40 xeqi: you know the bots sandbox and manipulate forms so their timing will be way off

21:40 gfredericks: ,(let [s (set (range 10000))] (time (dotimes [_ 10000] (conj s :foo))))

21:40 clojurebot: "Elapsed time: 12.914148 msecs"\n

21:40 gfredericks: this is the most scientific way to do it

21:40 xeqi: ah, then carry on

21:40 gfredericks: :)

21:40 that's a good point I hadn't thought of that

21:41 xeqi: also, don't trust clojure benchmarks that don't use criterium

21:41 https://github.com/hugoduncan/criterium

22:03 SegFaultAX: Github down again?

22:03 TimMc: Nope.

22:03 How the crud am I allegedly calling RT.readString here? Stack trace: https://gist.github.com/timmc/5506742 code: https://github.com/timmc/kpawebgen/blob/collapse-tagcat/clj/src/kpawebgen/spit.clj#L46

22:03 SegFaultAX: Weird, it isn't loading for me.

22:04 hiredman: I've been having weird issues connecting various hosts via the internet all day

22:04 SegFaultAX: hiredman: How else might you connect to them? ;)

22:05 hiredman: well hosts my lan are fine :P

22:05 on

22:05 SegFaultAX: :D

22:05 holo: hi

22:05 SegFaultAX: I can literally connect to any other site.

22:06 hiredman: the first thing I noticed was google search where taking a long time

22:07 and what I see now is I have a list of 6-7 hosts and run 5 pings against them, every time another one of the hosts has all 5 pings timeout

22:07 TimMc: preconditions and macros can both screw with line numbers

22:08 TimMc: It has to be a macro, right? The stack trace indicates a direct call from my code.

22:08 amalloy: TimMc: no, see the <clinit>?

22:09 TimMc: Ugh, yes. Class init?

22:09 amalloy: that's spit$ensure-db$fn being *compiled*, not being called

22:09 i've seen this a couple times in 1.5.x, and i don't really understand enough about classloading to know why clinit is happening at runtime

22:09 hiredman: that is the compiled code being loaded

22:10 amalloy: i've gotta run; i hope you guys leave an interesting explanation in the scrollback for me

22:10 TimMc: I think I'll sleep on it. :-/

22:10 (Maybe you'll figure it out before me!)

22:10 hiredman: clinit is what java static inits are compiled to

22:11 so the code is already compiled, so this is happening as the compiled classfile is loaded and the static init is called

22:11 which makes sense, because that is where any compiler emited calls to re-hydrate a pr'ed data structure would happen

22:11 which it would do using read-string

22:12 lfranchi: dumb clojure question... what's the most "clojure-ish" way to, given a seq of ints, generate a new seq with the nth element changed?

22:13 hiredman: don't use a seq

22:13 SegFaultAX: Weird, I can connect to github repos just fine but not github.com

22:13 lfranchi: it can be a vector, as well

22:13 hiredman: use a data structure with indexed access and indexed updates (vectors or maps)

22:14 vectors are associative of indices to elements

22:15 lfranchi: yeah, so if I want to get a new vector with a changed item at index n, what's the best way of doing that with a vector?

22:15 hiredman: can you think of another associative data structure?

22:15 lfranchi: ah, I can use assoc w/ a vector. interesting

22:16 thanks for the tips :)

22:19 holo: read-str disappeared from cljs-uuid.core since last version of cljs-uuid. I used to use it from the clojure side to read raw uuid like "7dc53df5-703e-49b3-8670-b1c468f47f1f". is there a more standard way of doing this now? I can just plug the deleted implementation in my project though

22:41 technomancy: holo: you can read #uuid"7dc53df5-703e-49b3-8670-b1c468f47f1f" with the reader these days

22:43 TimMc: hiredman: That all sounds very well and good, but I've been running with -Dclojure.read.eval=unknown for a while and this is the first time I've seen this. I don't see any fancy syntax here either.

22:45 holo: technomancy, I don't have a #uuid"7dc53df5-703e-49b3-8670-b1c468f47f1f", but instead a "7dc53df5-703e-49b3-8670-b1c468f47f1f"

22:47 hiredman: TimMc: *shrug* have you upgraded any libraries recently? have you run `lein clean` recently?

22:47 TimMc: No, yes.

22:48 I also tried to pare down the code to find the piece at fault, but I overshot. There's a lot of I/O here to work around. :-/

22:48 technomancy: holo: oh, you don't control the format; gotcha

22:49 hiredman: TimMc: if you had not run `lein clean` in while and had stale class files sitting around, running `lein clean` could have triggered the change

22:50 TimMc: Mmm, I see. Nothing's AOT'd, though.

22:50 hiredman: you could find the classfile it is blowing up on (assuming you aot) and run javap on it to take a look at the bytecode to find the printed form that is being read

22:57 brehaut: yeah

22:57 oops

22:59 TimMc: When I do (compile 'kpawebgen.spit) and then javap the relevant class file, I get https://gist.github.com/timmc/5506900

23:02 ...why does that have the namespace's docstring embedded in it?

23:04 Maybe that's just an inlined constant...?

23:04 hiredman: I wonder if slingshot is doing it for some reason

23:07 hah

23:08 it is from logging

23:08 taoensso.timbre

23:08 Recursive: ,(doc ->)

23:08 clojurebot: "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

23:09 TimMc: hiredman: ! How can you tell?

23:10 That was definitely it -- I upgraded timbre from 1.5.2 to 1.6.0. What the hell was it up to?

23:11 hiredman: somewhere it using the output of a pedicate in a macro, but the predicate doesn't return booleans

23:11 in the true case it returns a namespace object or something like it

23:12 https://github.com/ptaoussanis/timbre/blob/master/src/taoensso/timbre.clj#L304 is the predicate

23:12 dunno what macro it is

23:13 it is fixed in the current master of timbre

23:13 https://github.com/ptaoussanis/timbre/commit/0dc4951db73eca38951a29dd8c751e60d799b4e4

23:13 holo: technomancy, ,(java.util.UUID/fromString "7dc53df5-703e-49b3-8670-b1c468f47f1f")

23:13 Recursive: ,(java.util.UUID/fromString "7dc53df5-703e-49b3-8670-b1c468f47f1f")

23:13 clojurebot: #uuid "7dc53df5-703e-49b3-8670-b1c468f47f1f"

23:15 TimMc: hiredman: Man, how did you track that down?

23:15 And thank you.

23:15 holo: thank you Recursive

23:15 hiredman: it was the closest recognizable string to the readString call in the javap output

23:16 TimMc: Ah, I see -- https://gist.github.com/timmc/5506900#file-gistfile1-java-L699 "78:ldc#81; //String taoensso.timbre"

23:17 holo: (inc Recursive)

23:17 lazybot: ⇒ 1

23:17 hiredman: yep

23:17 holo: (inc technomancy)

23:17 lazybot: ⇒ 52

23:17 TimMc: Or I guess line 692, ns-filter-cache.

23:24 djwonk: to append one vector to another, I'm using `into`. Should I look at other options?

23:24 ,(doc into)

23:24 clojurebot: "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

23:25 technomancy: into is great

23:26 yacin: any idea what this error is? CompilerException java.lang.ClassFormatError: Invalid method Code length 236383 in class file pdns/lab$eval36980, compiling:(NO_SOURCE_PATH:1)

23:26 it may be a cascalog issue, but searching google didn't yield any good cascalog leads

23:26 thought i'd ask here too

23:30 danielglauser: djwonk: Looking at the code for into if the first collection is an IEditableCollection (I'm assuming most Clojure data structures are) then it has a fair amount of optimizations if that is your concern.

23:33 djwonk: danielglauser: not extremely worried about performance... just was rooting around looking for 'merge' or 'append' and didn't find those, so when I found 'into' I figured that was the way to go

23:33 technomancy: thanks

23:34 holo: yacin, I found this doing a little search on google. hope it helps: https://groups.google.com/forum/?fromgroups=#!topic/clojure/7mdnjn1vyYc

23:34 danielglauser: djwonk: Cool

23:42 yacin: holo: hmm, this definitely seems somewhat related. thanks

23:43 i'm dealing with large sets, but i'm def'ing them so they should have vars

23:43 which someone suggested would fix it

23:46 and i'm already reading the sets from a separate file. hmm

23:51 axle_512: hey guys, I'm writing a high performance scheduler in clojure (partly as a learning experience)

23:52 I have the code here: https://github.com/stephenjohnston/clj-sked

23:52 it uses promises to deliver the results of scheduled items, can handle hundreds of thousands of simultaneous jobs

23:52 would appreciate any positive critique

23:54 akhudek: how does it compare to Quartzite?

23:54 Raynes: amalloy and I did some cool scheduling stuff recently that you might like axle_512. First, we devised a library that he wrote called chronicle https://github.com/flatland/chronicle (very new and currently undocumented, but I'll fix that soon) that can be used to generate an infinite seq of Joda DateTime objects based on a simple cron-like spec. It doesn't have a scheduling piece included, but...

23:55 I wrote this naive little scheduler based on it: https://github.com/flatland/turntable/blob/master/src/flatland/turntable/timer.clj

23:55 axle_512: raynes: Sounds really interesting, I'll definitely take a look. I don't have cron support, but it was something I was thinking of adding.

23:55 Raynes: I want to tear that out into a library and making it better (i.e. use executers instead of timers, probably)

23:56 axle_512: I really like the idea of chronicle because it's so much more general than a scheduling specific library and can be used as the lower-level of such a scheduling library.

23:56 axle_512: akhudek: I believe quartzite is a wrapper around quartz. Quartz will have a lot more features, my little scheduler is only 100 lines of code.

23:56 akhudek: yes, but that's 100 lines of clojure :-)

23:57 axle_512: raynes: reading the source for flatland now

23:58 Raynes: axle_512: You pass 'schedule' a function to execute at the specific times and a chronicle spec (which is basically a Clojureized version of a cron spec) like {:minute [0 15 35 45]} to run every 15 minutes, for example.

23:58 It could be made much more robust, but it's really easy to implement these kinds of things in terms of chronicle.

23:59 I did timer.clj in like 10 minutes.

23:59 holo: yacin, glad it could help

23:59 Raynes: Anyways, enough tooting our horn. I just haven't told anyone about chronicle and it's kind of like finding religion, you want to tell everyone about it and make them do it too.

Logging service provided by n01se.net