#clojure log - Apr 16 2014

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

0:00 amalloy: &(doc promise)

0:00 lazybot: ⇒ "([]); Alpha - subject to change. Returns a promise object that can be read with deref/@, and set, once only, with deliver. Calls to deref/@ prior to delivery will block, unless the variant of deref with timeout is used. All subsequent derefs will return the same del... https://www.refheap.com/76684

0:01 amalloy: plus, i mean, you have all of java.util.concurrent at your fingertips if you want it

0:01 derek_c: ^

0:03 derek_c: amalloy: how does promise solve the problem?

0:04 amalloy: you give the thread a promise to block on, and deliver to it when you're "done"

0:05 derek_c: amalloy: hmm I don't think that's what I'm trying to do... I described my problem in more details here: http://stackoverflow.com/questions/23098575/how-do-you-block-a-thread-until-a-condition-becomes-true

0:05 I know I can just use java.concurrent, but there has to be a Clojure way

0:06 beamso: ,(doc deliver)

0:06 clojurebot: "([promise val]); Delivers the supplied value to the promise, releasing any pending derefs. A subsequent call to deliver on a promise will have no effect."

0:06 amalloy: rich encourages you to use j.u.c if it contains a solution to your problem. there aren't wrappers around that stuff because it's already good

0:07 derek_c: also, you said "condition", which is like a real thing in concurrent programming, distinct from "some condition is true"

0:09 derek_c: amalloy: ok... but maybe there is a way to do without condition variables. I'm really just trying to solve a simple concurrency probelm

0:09 here: http://upl.io/czj5ag

0:10 I'm modeling each sim as a thread, and the bathroom is the shared resource

0:11 and each sim starts in one of two initial states: either it wants to wash hands, or it wants to use the toilet

0:11 and it exits after it finishes what it wanted to do

0:14 guns: Interestingly, you could probably solve this problem with a channel with custom buffer implementation

0:15 hand washer = 1, toilet user = MAX_VALUE

0:17 derek_c: (a fixed buffer of course)

0:18 derek_c: guns: channel is not a Clojure primitive though?

0:19 amalloy: wait, isn't this just a reader/writer lock?

0:19 guns: derek_c: you would need a custom implementation that read an object's "size"

0:19 *buffer implementation

0:19 derek_c: guns: there are lots of ways to solve this problem if we model the bathroom as another separate thread that accepts requests from sims

0:19 amalloy: yes, it is

0:20 beamso: modelling it as a thread seems like overkill

0:20 amalloy: like, in clojure if you need a reader/writer lock, you use http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

0:20 guns: derek_c: I thought you wanted something "clojurey"

0:20 amalloy: why would you reinvent such a wheel, when really smart people already have it for you

0:21 derek_c: amalloy: I wouldn't if I was writing a real application... I was just wondering if this problem is solvable with the Clojure primitives, like vars, refs, atoms, and agents

0:21 so seems like it's at least not *easily* solvable

0:21 amalloy: well, none of those really like blocking

0:21 but that's what promises are for

0:22 derek_c: amalloy: I see

0:22 amalloy: i dunno, maybe i'm wrong about promises

0:22 derek_c: ok thanks guys

0:56 xsyn: Can I ask a stupid question about frequencies

0:56 I do a frequencies on a dataset I have and it returns pretty much what I expect

0:57 except when I do a (vals (frequencies data)) I get the response of a single val which is equivalent to all the frequencies added

0:58 and if I do a (keys (frequencies data)) I get (" ")

0:59 guns: xsyn: have some sample data?

1:00 xsyn: nevermind

1:00 I found it

1:00 it was a typo :/

2:35 gko_: What are *code-conversion-work*-xxxxx buffers? they pop up from time to time when I open a file...

2:35 wrong channel, sorry

2:47 yedi: man... learning simple devops stuff sucks

2:48 ivan: it might be because every devops tool is not good

3:01 sdegutis: Good morning.

3:01 Anyone awake?

3:11 dissipate: tools.logging vs. timbre

3:11 hmm

3:11 tools.logging looks pretty disappointing. i don't feel like slogging through log4j's documentation.

3:15 derek_c: does anyone know if the coroutines created by core.async.go get mapped into actual threads or not?

3:16 or do they just run in the same thread, like in Python and JS?

3:16 systemfault: You should watch the nice video on them

3:22 amalloy: derek_c: well, they run literally in javascript, in cljs. so definitely not multiple threads in that case

3:23 on the jvm, i'm not sure

3:52 Frozenlock: , (clojure.core/read-string (str {:a #"regexp"}))

3:52 clojurebot: {:a #"regexp"}

3:53 Frozenlock: , (clojure.edn/read-string (str {:a #"regexp"}))

3:53 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.edn>

3:53 Frozenlock: , (require 'clojure.edn)

3:53 clojurebot: #<SecurityException java.lang.SecurityException: denied>

3:53 Frozenlock: -_-

3:53 Anyhow, my point was, it doesn't work. Any idea why?

3:54 Seems I can't read a regexp with the edn/read-string

3:54 amalloy: Frozenlock: are regular expressions defined as part of the edn spec?

3:55 Frozenlock: Eh, doesn't look like it https://github.com/edn-format/edn

3:55 amalloy: so...

3:56 Frozenlock: So I'll have to use core/read-string

3:56 And hope not to be #'ed

3:56 :-p

3:56 maxthoursie: but you could define your own reader macros for edn, couldn't you?

3:57 Frozenlock: Last time I used core/read-string, the safest way was with *read-eval* to false. Is there any new practice?

3:58 maxthoursie: no, I confused that with tagged elements

4:00 Frozenlock: related https://github.com/edn-format/edn/issues/26

4:00 I guess the portability issue is the reason

4:00 Frozenlock: Yeah, regexes are weird beasts for clojure

4:01 maxthoursie: we'll, even outside clojure

4:01 that's the point, I guess, edn is made to be useful outside clojure

4:01 a regexp wouldn't

4:02 Frozenlock: Perhaps, but in clojure I can feel it often... you can't check them for equality either.

4:02 (And thus are unusable as key in a map)

4:03 trap_exit: are there builtin functions for arraybuffer -> string and string -> arraybuffer in clojurescript ?

4:03 maxthoursie: Didn't know that

4:03 Frozenlock: I've been spoiled by being able to use everything as a key :p

4:03 , (= #"." #".")

4:03 clojurebot: false

4:06 trap_exit: argh

4:06 clojurebot: No entiendo

4:06 trap_exit: bhow do I get arraybuffer/string translation ? :-)

4:06 maxthoursie: I think someone had a lib for that

4:57 so internet says turning of *read-eval* is not enough. What other things could cause side effects?

5:00 found a relevant link: http://grokbase.com/t/gg/clojure/132bt7kyzx/ann-never-use-clojure-core-read-or-read-string-for-reading-untrusted-data/132cdm08r4#132cdm08r4

5:02 Frozenlock: maxthoursie: As far as I understand, read-string with *read-eval* to false is 'safe-but-cant-guarantee-it-wont-bite-you-in-the-ass' :-/

5:02 At least since 1.5.0

5:02 maxthoursie: Frozenlock: that's what I gather too

5:03 but I'm failing to see the difference

5:03 clojure should use the edn reader

5:04 Frozenlock: But the edn reader can't read everything...

5:09 Another EDN case that's driving me crazy: keywords starting with a number. In clojure it's not a problem. However, because it's not in the EDN spec, cljs doesn't support it. :-(

5:10 ambrosebs: ,:1a

5:10 clojurebot: :1a

5:10 Frozenlock: ambrosebs: it works fine in Clojure

5:10 yotsov: Bronsa: hello, question regarding tools.emitter.jvm. I see it currently depends on ASM. Are there plans to remove this dependency (impression I got from one talk), or is ASM there to stay?

5:11 ambrosebs: Frozenlock: Clojure does almost no error checking. Unsurprising.

5:12 Frozenlock: Are you saying it shouldn't work?

5:12 ambrosebs: Frozenlock: I'm saying just because it compiles doesn't mean that much.

5:45 Frozenlock: xeqi: shouldn't `form-and-button' also accept a :button element? https://github.com/xeqi/kerodon/blob/master/src/kerodon/impl.clj#L47

5:46 (I might be wrong, but I usually use a :button with type :submit, rather than a :input)

6:19 petron: why is my Top K quickselect implementation error'ing out on some inputs? https://www.refheap.com/76711

6:22 irctc: Hello some body tell me how i am create the testing data base in clojure

6:26 Hello some body tell me how i am create the testing data base in clojure

6:29 clgv: ,(meta #'some-fn)

6:29 clojurebot: {:ns #<Namespace clojure.core>, :name some-fn, :added "1.3", :file "clojure/core.clj", :column 1, ...}

6:29 clgv: 1.3 for real?

6:30 Averell: petron: your partitioning only works for sorted coll

6:36 arav93: Hi, I need some help with clojure.instant

6:37 pyrtsa: Just ask the question.

6:40 arav93: Could someone tell me how parse-timestamp works in clojure.instant

6:43 llasram: In what sense?

6:46 pyrtsa: arav93: Did you read the source already? https://github.com/clojure/clojure/blob/master/src/clj/clojure/instant.clj#L48-L118

6:47 arav93: I read it but I'm unable to get it working.

6:50 pyrtsa: arav93: How about using one of https://github.com/clojure/clojure/blob/master/src/clj/clojure/instant.clj#L271-L288 ?

6:51 arav93: pyrtsa: I do not understand how

6:52 Frozenlock: ,(clojure.instant/read-instant-timestamp "1985-04-12T23:20:50.52Z")

6:52 clojurebot: #<SecurityException java.lang.SecurityException: denied>

6:52 Frozenlock: o_O

6:52 pyrtsa: (clojure.instant/read-instant-date "2014-04-16T12:34:56+01:00")

6:52 ,(clojure.instant/read-instant-date "2014-04-16T12:34:56+01:00")

6:52 clojurebot: #<SecurityException java.lang.SecurityException: denied>

6:53 Frozenlock: Dangerous dates are dangerous

6:53 pyrtsa: ,#inst "2014-04-16T12:34:56+01:00"

6:53 clojurebot: #<SecurityException java.lang.SecurityException: denied>

6:53 pyrtsa: arav93: If it's user input, pass in a string. If you've got a literal string in source code, just use `#inst "..."`.

6:54 (...and let the Clojure reader do the conversion for you.)

6:56 arav93: pyrtsa: Could you explain a lil better?

6:58 pyrtsa: For user input, something like (let [t (clojure.instant/read-instant-xxx s)] ...), for literals, (let [t #inst "2014-04-16T00:00:00.000+00:00"] ...)

6:59 ...where xxx depends on which type of result you want (java.util.Date / java.sql.Timestamp / java.util.GregorianCalendar).

6:59 And s was a string, of course.

7:15 * Frozenlock bangs his head on the keyboard

7:16 agarman: @Frozenlock - what's up?

7:16 Frozenlock: I -JUST- spoke about how regex can't be equal in Clojure. Yet, I wondered why one of my tests was failing.

7:16 Turns out there was a regex in the map

7:18 AimHere: When some people find an inappropriate regular expression in their code, they bang their head on the keyboard. Now they have *two* regular expressions in their code.

7:19 Frozenlock: ,(= {:a 1 :b #"surprise"} {:a 1 :b #"surprise"})

7:19 clojurebot: false

7:33 katox: Frozenlock: that's deliberate?

7:36 Frozenlock: katox: It was deemed somewhat irrelevant http://dev.clojure.org/jira/browse/CLJ-1182

7:38 katox: hm, yeah regarding this as two regexps are equal when they accept the same language is a bit complicated requirement ;)

7:39 s/when/iff

7:45 perses: if i want to write a function which take str and separator, and split it at separator, (defn gsplit [str separator] (clojure.string/split string #separator)) , is this right?

7:46 >(defn gsplit [str separator] (clojure.string/split str #separator)

7:46 > (defn gsplit [str separator] (clojure.string/split str #separator)

7:46 ,(defn gsplit [str separator] (clojure.string/split str #separator)

7:46 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

7:46 perses: ,(defn gsplit [str separator] (clojure.string/split str #separator))

7:46 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

7:47 agarman: , (fn gsplit [s sep] (clojure.string/split s sep))

7:47 clojurebot: #<sandbox$eval69$gsplit__70 sandbox$eval69$gsplit__70@1ebd60d>

7:47 vijaykiran: ,(clojure.string/split "test,5,-,stuff-more" #"-")

7:47 clojurebot: ["test,5," ",stuff" "more"]

7:47 agarman: , (gsplit "foo:bar" ":")

7:47 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: gsplit in this context, compiling:(NO_SOURCE_PATH:0:0)>

7:47 vijaykiran: ,(clojure.string/split "test,5,-,stuff-more" #",")

7:47 clojurebot: ["test" "5" "-" "stuff-more"]

7:48 agarman: , (doc clojure.string/split)

7:48 clojurebot: "([s re] [s re limit]); Splits string on a regular expression. Optional argument limit is the maximum number of splits. Not lazy. Returns vector of the splits."

7:48 arav93: Hi, I did (clojure.instant/read-instant-timestamp "1985-04-12T23:20:50.52Z") and I got #inst "1985-04-12T23:20:50.520000000-00:00" How do I pass this to parse-timestamp?

7:50 katox: , (class (clojure.instant/read-instant-timestamp "1985-04-12T23:20:50.52Z"))

7:50 clojurebot: #<SecurityException java.lang.SecurityException: denied>

7:51 katox: ;) nvm, should be java.sql.Timestamp, why another parse?

7:52 arav93: I'm trying to work clojure.instant ns.

7:57 katox: ,(source clojure.instant/read-instant-timestamp)

7:57 clojurebot: Source not found\n

7:58 katox: hmm, ok https://github.com/clojure/clojure/blob/5e9ad16e11aad1228ca3d1b0a9c3b52ccd602dbc/src/clj/clojure/instant.clj#L283

8:01 arav93: I did not understand much by reading through this , katox

8:03 katox: arav93: not sure what are you asking about but that snippet shows that a Timestamp object is constructed first in a function that is returned to parse a sequence

8:03 arav93: that fn can be called by a reader that you setup

8:10 perses: i have a very large file and i want to read line by line, and then process line then do the next line, what is the best way to do this?

8:11 Anderkent: perses: (with-open [rdr (clojure.java.io/reader "/my/file")] (for [line (line-seq rdr)] (do-stuff-to line)))

8:11 perses: Anderkent: is this the efficient way to do this?

8:11 Anderkent: oh, might have to wrap the for in doall

8:12 yes, line-seq is lazy

8:14 perses: Anderkent: so what should it be?

8:14 (with-open [rdr (clojure.java.io/reader "/my/file")] (doall (for [line (line-seq rdr)] (do-stuff-to line)))) ?

8:14 Anderkent: yeah

8:14 well. Depends if you need the results of do-stuff-to-line

8:14 or if you only care about side effects

8:15 doall if you need the results, dorun if you only need side effects

8:15 clgv: perses: you could also "slurp" the file and use clojure.string/split on it

8:15 Anderkent: clgv: see 'very large' above

8:15 clgv: Anderkent: ah ok. didnt see that

8:15 perses: thanks guys

8:15 Anderkent: I'm reading 'very large' as gigabytes though, perses if it's just a couple megs just slurp it :)

8:16 clgv: gigabytes? terrabytes! ;)

8:25 perses: ,(get (list 1 2 3) 0)

8:25 clojurebot: nil

8:25 perses: ,(get [1 2 3] 0)

8:25 clojurebot: 1

8:25 Anderkent: ,(nth (list 1 2 3) 0)

8:25 clojurebot: 1

8:25 perses: ,(0 (list 1 2 3))

8:25 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

8:26 perses: i guess if get is polymorphic function will be very good, but why isn't?

8:26 so get can work for list or vector or map

8:26 Anderkent: get is for getting a value from a structure that can be indexed

8:26 like a map or a vector

8:26 nth is for getting the nth value from a sequence

8:28 perses: so nth for list is more efficient than get for vector?

8:29 Anderkent: no, get for a vector is more efficient than nth; but you cant 'get' from a list, because you can not index a list

8:29 a list only lets you get the first element, or get all other elements

8:30 jcromartie: I see very little performance difference between get and nth for a vector

8:32 Anderkent: right, it might check if the collection is indexed or not, if it does then there's not much difference

8:32 if it doesn't and behaves like `last`, then it's o(n) rather than o(1)

8:33 jcromartie: ,(dotimes [_ 10] (let [n 1e6, v (vec (range n))] (time (dotimes [_ n] (get v (rand-int n))))))

8:33 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

8:33 jcromartie: oh fine be like that

8:33 Anderkent: hah

8:33 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L761

8:33 it does check

8:34 jcromartie: ,(let [n 1e6, v (vec (range n))] (dotimes [_ 10] (time (dotimes [_ n] (nth v (rand-int n))))))

8:34 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

8:34 jcromartie: ,(let [n 1e5, v (vec (range n))] (dotimes [_ 10] (time (dotimes [_ n] (nth v (rand-int n))))))

8:34 clojurebot: "Elapsed time: 57.234936 msecs"\n"Elapsed time: 22.612508 msecs"\n"Elapsed time: 22.719057 msecs"\n"Elapsed time: 20.353758 msecs"\n"Elapsed time: 20.465892 msecs"\n"Elapsed time: 19.734251 msecs"\n"Elapsed time: 24.6308 msecs"\n"Elapsed time: 21.561721 msecs"\n"Elapsed time: 20.138097 msecs"\n"Elapsed time: 19.321783 msecs"\n

8:34 jcromartie: ,(let [n 1e5, v (vec (range n))] (dotimes [_ 10] (time (dotimes [_ n] (get v (rand-int n))))))

8:34 clojurebot: "Elapsed time: 28.693759 msecs"\n"Elapsed time: 30.672505 msecs"\n"Elapsed time: 23.772632 msecs"\n"Elapsed time: 22.376006 msecs"\n"Elapsed time: 22.670438 msecs"\n"Elapsed time: 21.908001 msecs"\n"Elapsed time: 22.869125 msecs"\n"Elapsed time: 22.611847 msecs"\n"Elapsed time: 22.509958 msecs"\n"Elapsed time: 21.313093 msecs"\n

8:34 jcromartie: so nth is actually faster in that case

8:35 Anderkent: #reliablebenchmarks

8:38 jcromartie: Anderkent: you mean that benchmark is not good?

8:38 or is good?

8:38 my sarcasm detector is not working

8:41 te: ,`unquote

8:41 clojurebot: clojure.core/unquote

8:41 Anderkent: running something 10 times is not a good benchmark, no; at least not good enough to pick up on a 1msec difference :P

8:41 te: Someone talking about profiling?

8:43 Get an evaluation license for YourKit -- add this to your project.clj (assuming you're on OSX) :jvm-opts ["-agentpath:/Applications/YourKit_Java_Profiler_2013_build_13074.app/bin/mac/libyjpagent.jnilib"]

8:43 step 2: ...

8:43 step 3: profit.

8:44 Frozenlock: Assuming OSX is a thing now? The Apple invasion continues...

8:44 Anderkent: it's more of a 'hey I'll paste my path here fix it up if you're on linux/windows'

8:44 jcromartie: Anderkent: running it 1 million/100K times, 10 times...

8:44 * te has a mac because he's pragmatic and a thinkpad x120e because he still is growing a neck bear

8:44 te: beard*

8:44 Anderkent: also I'd guess like 40-70% people here are on macs

8:45 a neck bear would be a sight to behold

8:45 jcromartie: my job gives me a mac, I bought a thinkpad

8:45 xsyn: when life gives you lemons

8:45 * te shrugs

8:45 te: they'

8:45 they're both fine.

8:46 the tightness of apple's hardware + software is tough to beat

8:46 perses: ,(replace "please i prefer ruby", #"ruby" "clojure")

8:46 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/replace>

8:46 jcromartie: the $3K MacBook Pro has an amazing screen, and an amazing battery… but the $400 Craigslist thinkpad beats it in CPU performance

8:46 te: thinkpad, try as it might, still can't hold a candle to my battery life

8:46 jcromartie: nope

8:46 perses: ,(clojure.string/replace "please i prefer ruby", #"ruby" "clojure")

8:46 clojurebot: "please i prefer clojure"

8:47 te: fun little thing to try: implement all of clojure.string using no java

8:47 (direct interop i mean)

8:47 Anderkent: (defmacro dot [& body] (. ~@body)) - not direct interop anymore?

8:47 te: boo

8:48 Anderkent: :P

8:48 te: ./kickban Anderkent your macros are no good here

8:48 \o/

8:49 so, claypoole -- you guys ever use it?

8:49 or gals, or fish, etc.

8:50 perses: if i have ("Clojure" "is" "fun") how can i replace fun with another thing?

8:51 te: ,(replace {"fun" "radical"} '("clojure" "is" "fun"))

8:51 clojurebot: ("clojure" "is" "radical")

8:51 sohalt: hi, I just stumbled across reduce1 in merge-with and wondered how it differs from "normal" reduce, but couldn't find the source or documentation via (source reduce1) or (doc reduce1). Could anybody enlighten me on this one?

8:53 dnolen_: sohalt: it's private, just look at the source if you're curious

8:53 agarman: http://www.clodoc.org/doc/clojure.core/reduce1

8:53 te: sohalt: is this helpful? https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/protocols.clj

8:53 sohalt: thanks. I wonder why my quick google search didn't turn that up for me.

8:54 te: agarman: because google juice for clojuredocs is still riding high

8:54 im going to build a really great core.async LOIC to DoS it if it stays up much longer

8:54 agarman: lol

8:54 perses: ,(if nil "fasle" "true")

8:54 clojurebot: "true"

8:55 te: seriously, i don't know how you can have something as high in the rankings, as important as it turns out to be to newcomers as a result, and not ever bother to update it

8:55 hasn't there been some clojuredocs rewrite in the works for like 2 years now?

8:55 Anderkent: i think there was some drama involved

8:56 te: really?

8:56 i never saw anything about that.

8:56 Anderkent: don't really know, didn't follow it, just my impression from when i heard about it like a year ago

8:57 te: i take back what i was saying

8:57 looks like it saw a string of commits 3 months ago

8:57 clj-rewrite in progress apparently

8:57 happy to see that.

8:58 now, if people could just quit writing alternative documentation websites and find a way to share the same domain...

8:59 sohalt: Also while I'm at it: Why is the (when (some identity maps) … in merge-with required? Wouldn't a simple (when maps … do aswell?

8:59 gfredericks: my favorite documentation strategy is fingerhut's project

8:59 te: explaining to people: "nonono, you want to use clojure-DOC.org, not clojureDOCS.org.

8:59 such a bummer

8:59 gfredericks: I haven't seen anybody else care about it though

8:59 te: gfredericks: wait, what now?

9:00 gfredericks: te: it's a clojure project with alternative docs, and it adds them to the built-in vars at runtime so your repl docs are all customized

9:00 te: oh, yeah, i remember that -- have never used it personally

9:00 gfredericks: me neither; I just love the concept

9:01 te: I put http://getclojure.org out there -- would be nice to fix it up. there are a ton of cool examples in there, which, with some curation, could be used by andy's thingamajig

9:01 gfredericks: also it seems easier to generate a fancy website from docstrings than vice versa

9:01 te: <-devn

9:01 gfredericks: it could even be richer info than just docstrings

9:01 te: id like to add ratings to it, but i just haven't spent the time

9:01 gfredericks: e.g., separating brief refresher-style docs from full intros

9:02 te: gfredericks: yeah, i want to run clojure.tools.analyze across every single thing in getclojure.org

9:02 gfredericks: lists of related vars...

9:02 te: and capture a ton of meta

9:02 and yes, that. something like the clojure atlas ontology, mixed with examples

9:02 it would be a clear winner by default

9:04 gfredericks: andy said he has so far not gotten a single PR on that project

9:04 naturally I made a firm commitment to intend to work on it

9:05 te: andy has done so damn much for the community -- i know many people have, but sometimes i wish we had more of a community thing around recognizing people

9:05 throw them a balloon party or something

9:05 gfredericks: I did not realize until clojure/west that andy was not affiliated with cognitect

9:05 te: send them cookies. whatever it is. it'd be nice to show more appreciation all around for people

9:06 gfredericks: he's surely not the only one, if you look at the 1.6 contributors list

9:06 lots of people, lots of patches, lots of time, lots of effort

9:06 gfredericks: he's a lot more prominent than a lot of the people on that list though

9:06 te: but he's been doing it for a lot longer, and a lot harder than most

9:06 yeah, agreed

9:06 gfredericks: or at least one of the people on that list :)

9:07 te: gfredericks: want to throw $100 into a pot for an amazon gift card for andy?

9:07 ill match you

9:07 gfredericks: would gittip work for this?

9:07 te: not sure

9:08 heh, and then tbaldridge shows up and makes me feel guilty about just doing it for andy

9:08 sohalt: :D

9:08 te: we need to make a list and get a clojure tip going

9:08 once a month, someone gets recognized for their commitment

9:09 something like that

9:09 gfredericks: for some reason when tbaldridge "showed up" I imagined him swooping down from the rafters...? no idea what that thought was about

9:10 jcromartie: with a knife in his teeth

9:10 gfredericks: I guess "bird" is a sub-rearrangement of "baldridge"

9:10 te: i think it'd be nice to just highlight work people have been doing. there are a lot of people who aren't as public who have done a ton for the community for years

9:10 i want to get nakkaya to a US clojure conference, for example

9:11 we need to fund that guy. he has had a prolific clojure blog since 2009 i think

9:11 i think he's in turkey

9:13 gfredericks: gittip seems to only support regular donations? kind of weird...

9:19 te: *shrug*

9:20 what's the right way to set up a little fund for this kind of thing?

9:21 gfredericks: ^

9:22 gfredericks: te: no idea; that's what I was speculating about wrt gittip

9:22 te: im just going to set up a little site with stripe

9:22 and then people can trust me or not

9:22 Anderkent: fund as in how you could get money from other people, or how could you easily send the money?

9:22 drbobbeaty: gfredericks: You can do it in PayPal, if that doesn’t offend

9:23 Anderkent: isnt stripe us-only?

9:23 gfredericks: drbobbeaty: good point

9:24 Anderkent: i was thinking bitcoin, because paypal tends to dislike people sending donations

9:24 would suck to get your account locked :)

9:25 drbobbeaty: Anderkent: I think if you set it up with them as a Donation “destination”, then they get it. I’ve done this for charitable contributions for a Church Missions trip for my daughter. It’s really not all that hard, and they seem to be understanding of the nature of giving.

9:25 te: Anderkent: I was thinking anything except bitcoin, because bitcoin.

9:26 I feel like it has turned into a really long and elaborate troll.

9:26 drbobbeaty: te: but the motivation is pure, and honest.

9:27 te: there is a PR problem, not to mention there are a lot of people who were on the sidelines a couple years ago, and with all of the drama everyone is constantly hearing about it, they're still standing there watching

9:27 Anderkent: depends if you follow the drama or not; i feel like as long as you stay away from the obvious scams (exchanges, drug markets, blah blah), it's cool for everyday usage

9:27 te: so for donations it seems like a bad idea

9:28 because i bet less than 20% of the clojure community actually has bitcoins

9:28 gfredericks: I wouldn't know how to make use of bitcoin if somebody wanted to send me some

9:28 te: ^-case in point

9:29 gfredericks: that doesn't mean it's difficult; I just haven't looked into it; I wouldn't be surprised if it was difficult though

9:29 te: dogecoin is frankly more useful to me because if i were paid with it, i wouldnt feel obligated to figure out a way to actually redeem it, because it's mostly worthless

9:29 it's like getting a gold star

9:30 Anderkent: te: well, that depends on the amounts, doesn't it? 100$ in dogecoin is the same as 100$ in bitcoin

9:30 te: i like gold stars more than i like obligations

9:30 Anderkent: yeah sure, probably a bad example: i'll put it like this: I'd rather be sent food stamps than bitcoin.

9:31 Anderkent: gfredericks: running the risk of going too deeply offtopic, you get a mobile wallet app, scan a bar code at the shop, and press 'accept charge'

9:31 assuming you find a shop that supports bitcoin that has something you want, of course :) I tend to spend in a couple pubs in london

9:33 gfredericks: gotta find some good London pubs around Chicago

9:34 jcromartie: te: if you can exchange dogecoin for something, then it has value no?

9:35 te: meh, i didn't mean to make this a referendum on crypto currency

9:36 i dropped in a couple years ago and bought some BTC at 2$, watched it climb, crash, climb, crash, climb, sold and made my money back

9:36 i found the whole thing to be a PITA

9:36 i just dont see it being useful for regular people

9:37 it's like PGP.

9:37 jcromartie: anybody here using Cursive regularly?

9:38 guest234245: te: Pelle B. is writing a clojure wrapper https://github.com/pelle/bitcljoin

9:38 jcromartie: guest234245: bringing it back on topic beautifully :)

9:38 * te golf claps

9:39 guest234245: take that and make something useful ... for the regular folk

9:39 jcromartie: Clojure… regular folk… ?

9:39 gfredericks: making crypto useful for regular folk is apparently impossible?

9:39 guest234245: sometimes overlap

9:41 if anyone knows other crypto / clojure projects, please share

9:42 * crypto currency

9:42 te: gfredericks: i respect what keybase is trying to do

9:43 i know developers who don't know how to send a damned PGP email

9:43 jcromartie: I have a testing dilemma

9:44 te: jcromartie: do tell

9:44 jcromartie: I have a Clojure web app, but its whole job is to coordinate a bunch of external services.

9:44 Kayako, JIRA, Stash, Confluence, and more...

9:44 te: get your spinning animation ready :)

9:44 jcromartie: yeah really

9:45 te: what's your question?

9:45 also, i mentioned this earlier, but claypoole is really fantastic

9:45 it might not be a fit for you, but maybe it is...

9:45 jcromartie: well, so right now I have a bunch of integration tests written in Rspec that are totally black box

9:45 and run against real installations of these services

9:46 with a test setup script that goes out and prepares the whole testing environment

9:46 it's insane

9:46 it takes forever

9:46 te: yeesh

9:46 Anderkent: it does sound insane

9:46 jcromartie: and only one person can use it at a time

9:46 te: jcromartie: you want a stubbed service

9:46 record responses and test against those

9:47 keep your integration tests for the big "seriously, make sure it works before we deploy"

9:47 but stub the rest of those responses out

9:47 jcromartie: I guess I could stub the service responses before running the specs

9:48 te: then people can run it locally

9:49 jcromartie: I tried this https://github.com/fredericksgary/vcr-clj

9:49 but it blew up in my face

9:49 llasram: Oh geez. Will your insurance pay for the reconstructive surgery ?

9:49 jcromartie: but I think that was just the clj-http recording

9:49 if I mocked my API functions themselves… that should do it

9:50 Anderkent: jcromartie: what I did a while ago (but only mocking one web service) was mock my api wrapper for 90% of the code, then when testing the api wrapper mock clj-http

9:51 jcromartie: but one problem is the service state

9:51 like, testing the creation of things

9:51 Anderkent: i.e. (provided (clj-http/get "http://the-webservice/blah/foo") => {:status 500 :body "foobarzip"}))

9:51 well, yeah

9:51 jcromartie: testing that they don't exist before, then they are created, then it should exist

9:51 Anderkent: wiat, are you testing your wrapper

9:51 or the app that you're delegating to

9:52 jcromartie: testing the app that coordinates all of these services

9:52 Anderkent: right, so you want to test that it tells the other service to create something if it's told it doesn't exist, right? Not that it's actually created when told.

9:53 jcromartie: well part of the integration test is that the thing is actually created

9:54 gfredericks: jcromartie: let me know if there's a specific issue with vcr-clj

9:56 jcromartie: if the args/return are not serializable via pr/read I think that would cause it to not work

9:56 that fact should probably be better documented

9:59 jcromartie: gfredericks: so, for a given var and cassette, it doesn't handle the result of multiple calls to functions with side effects?

9:59 gfredericks: jcromartie: calling something multiple times should work

10:00 it will play back the return values in order

10:00 jcromartie: hm, ok

10:04 hlprmnky: nothing germane to add except “omg there’s a vcr-clj now hooray”

10:07 gfredericks: hlprmnky: I wrote it maybe two years ago

10:07 I'm just not a marketing person

10:08 jcromartie: hm, whatever version comes up with "lein try" doesn't seem to work when recording stateful vars

10:08 must be old or something

10:08 gfredericks: what's a stateful var?

10:08 I can't imagine an old version not supporting multiple calls to something

10:10 jcromartie: well, this didn't work: (with-cassette :foo [{:var #'foo}] (foo) (foo) (foo))

10:10 it didn't record any calls to (foo)

10:10 Morgawr: is there a function in clojure that groups vectors together? like (f [1 2 3] [4 5 6] [7 8 9]) -> [[1 4 7] [2 5 8] [3 6 9]] ?

10:10 jcromartie: but with 0.3.3 it works

10:10 gfredericks: jcromartie: this is the vcr-clj.core namespace?

10:10 Morgawr: vector would do that

10:11 clgv: Morgawr: (apply mapv vector ...)

10:11 ,(apply mapv vector [1 2 3] [4 5 6] [7 8 9])

10:11 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

10:11 clgv: ,(mapv vector [1 2 3] [4 5 6] [7 8 9])

10:11 clojurebot: [[1 4 7] [2 5 8] [3 6 9]]

10:11 jcromartie: gfredericks: yeah, vcr-clj.core/with-cassette

10:11 gfredericks: oh I didn't see the transposition

10:11 Morgawr: clgv: thanks!

10:12 also thanks gfredericks for replying anyway )

10:12 jcromartie: anyway I blame lein try :)

10:12 clgv: Morgawr: apply when you get a list instead of single vectors ^^

10:12 Morgawr: clgv: yeah, thanks

10:13 jcromartie: ah, I was using "lein try vcr-clj" and not "lein try com.gfredericks/vcr-clj"

10:13 gfredericks: yeah somebody else has a same-name project

10:14 and your example works for me on the alpha version (which only differs from 0.3.3 in the http namespace)

10:14 jcromartie: yeah

10:14 I think it's just someone pushed a really old version to clojars

10:14 open source problems :)

10:14 gfredericks: oh that might have been me by accident before namespacing the mvn artifact

10:15 damn leiningen's defaults

10:15 Anderkent: no, https://github.com/ifesdjeen/vcr-clj - looks like a different thing

10:15 and it defines the vcr-clj/vcr-clj artifact, which is what lein try vcr-clj would grab

10:15 (well, unless it was never deployed)

10:15 gfredericks: I'll crack open the vcr-clj/vcr-clj jar and see if it looks like my handwriting

10:16 Anderkent: gfredericks: https://clojars.org/vcr-clj it does

10:16 0.0.2

10:16 gfredericks: yeah that one is mine

10:17 just super old since I didn't keep deploying to that

10:17 if clojars had a way to mark things as bad I'd do that

10:17 Anderkent: hm, you don't like the default group name?

10:23 gfredericks: no

10:23 I just had a build break the other day because of people using default group names

10:24 jcromartie: but default group names are nice and sterile… when people use their own names then it adds an uncomfortable personal dynamic to the project dependencies

10:24 managers don't like that

10:24 Anderkent: gfredericks: can you elaborate on the build break?

10:24 jcromartie: "who the hell is this gfredericks guy? can I trust him?"

10:24 (I'm kidding)

10:25 (except not… we've had customers that were uncomfortable with open source attributions to individual authors)

10:27 Anderkent: i dunno I don't see how it makes any difference

10:28 gfredericks: Anderkent: I'll find the irc log

10:30 Anderkent: http://clojure-log.n01se.net/date/2014-04-14.html#15:37

10:30 it ended with technomancy claiming there's no need for internal libraries

10:31 Anderkent: right, okay, for anything non-public (mostly my forks of someones public lib tho) i'd still use my group name

10:31 gfredericks: yep I would've too

10:33 clgv: $latest seesaw

10:33 lazybot: [seesaw "1.4.4"] -- https://clojars.org/seesaw

10:33 clgv: awesome

10:33 Anderkent: well, it seems you use it for everything now, which kinda implies you would. But I still think it's really not needed 90% of the time

10:34 gfredericks: I don't want builds breaking 10% of the time :P

10:37 Anderkent: eh, guess I'm not being clear. Builds don't break if you only use default group name for public artifacts (unless clojars breaks, in which case your build breaks anyway). I agree private artifacts should be in a private namespace, but 90% of the time making your artifact public is fine. The builds should never break

10:38 gfredericks: it's also kind of pretentious to pick a low-entropy generic name and assume your library will be the most prominent one by that name for decades to come

10:38 which leiningen encourages you to do before you've even written any code

10:39 Frozenlock: I've always wondered why...

10:39 The clojars/lein tutorial clearly explain how to use a group name, but by default you have your nice, clean, short project name.

10:40 gfredericks: the alternative is to pick a default that won't work

10:40 more amusing perhaps would be a uuid group name

10:40 ,(symbol (str "fixme-" (rand-int 100000000)) "my-project")

10:40 clojurebot: fixme-85755338/my-project

10:41 Anderkent: well, you're trading the first lib with that name having it easier, or every lib with that name having the crappy experience

10:42 i don't see how the future libs with the same name are any better if my libs has a group name, unless they just swipe the default group name

10:42 gfredericks: this also assumes clojars is the only OSS repo

10:44 Frozenlock: UUID all the namespaces!

10:44 Anderkent: isn't clojars the only repo where the group-name = artifact-name thing is common?

10:44 gfredericks: hard to evaluate the tendencies of not-yet-existing repos

10:44 jcromartie: I think it's a Clojure thing in general

10:45 Frozenlock: I like it

10:45 gfredericks: "It's okay as long as nobody else does it."

10:45 Anderkent: it's not a problem until it's a problem and then we'll blame the people who broke it

10:46 jcromartie: org.8CDFB3A4-EE85-41BA-AB44-178B7CEB95E7.604141BA-4519-4FF3-AED7-AA795F73A709/D8CCABC0-EAB5-4549-BF8A-69189E1525BA

10:46 Frozenlock: jcromartie: magnificent

10:46 gfredericks: I think I've already put more effort into complaining about this than it deserves; it only cost me an hour

10:46 * gfredericks goes to do something else

10:47 gtrak: we should just use URIs for namespaces and forget projects.

10:48 changing maven can't be that hard..

10:50 or an rdf based build :-)

10:50 Anderkent: maybe we should just number projects

10:52 clgv: Anderkent: with characters like A, B, C, C++, D, ...? :P

10:52 Anderkent: I was thinking just a central service that would spit out an integer that will become your project name

10:52 gtrak: the problem is we have two namespaces, the classes and the maven one. We're a lisp-1.

10:53 clgv: single point of failure hooorray! :D

10:53 te: bahaha jcromartie

10:53 needs more sha512

10:53 clgv: Anderkent: you could just use the timestamp in milliseconds - how likely is it that someone else created a project in the same millisecond? ;)

10:58 technomancy: gfredericks: re: marking as bad on clojars: you can just deploy a new version with :description "don't use this" or something

10:59 we can do manual deletions, but we try to save that only for cases where sensitive data has been deployed

11:01 and for the record, I don't condone the use of everyday nouns like vcr as unqualified project names

11:02 AimHere: VCR is still an everyday noun? I thought that was some exotic rune that only old greybeards had heard of, like BetaMax and Geocities

11:04 jcromartie: yeah, there are programmers working today who have never handled a tape cassette

11:05 "why do Windows drive letters start with C:\"

11:05 gfredericks: technomancy: your approach is lesser known literary characters?

11:06 jcromartie: does that have something to do with tape cassettes?

11:06 Anderkent: org.clojars.jaceklach/'that one crow from norse mythology'

11:06 gfredericks: or did you just mean people forgot about A:\ and B:\?

11:07 jcromartie: gfredericks: what I'm trying to say is "kids these days!"

11:07 seangrove: jcromartie: Having used Windows XP for 5 minutes yesterday for something, I'd shorten that question down to "Why do windows?"

11:07 gtrak: ha, B:, when's the last time you used that one?

11:08 there's a window of about 10 years where people knew what a: and c: meant but might not have known b:

11:08 Anderkent: gtrak: not that long ago, because you can now map abitrary drives to b: :)

11:08 gfredericks: I don't think I personally ever used a B:\ but when I was <8yo I remember my grandfather having one

11:08 I don't recall ever seeing it used though

11:09 gtrak: Anderkent: my gut recoils at the thought, but my mind knows I don't give a crap because I've been using linux for 14 years.

11:09 and we have chroot

11:10 jcromartie: I used A: and B:

11:10 Anderkent: i had lots of 'fun' playing with the windows registry a couple years ago when I messed up a reinstall and it wasn't picking up the drives in the right order.

11:10 * jcromartie is old now

11:15 jcromartie: now raise your hand if you ever used an 8" floppy drive :)

11:16 Anderkent: I remember having an 8'' floppy drive but don't think I've personally used it

11:16 gfredericks: now you guys are trolling the kids by making things up

11:16 stop pretending computers were ever big. it's a silly fable.

11:16 hlship: My first experience with a disk drive was a large (12"?) removable hard disk platter for a Burroughs B800

11:17 Dad's accounting computer, circa 1978

11:17 I called it "HAL"

11:18 technomancy: http://p.hagelb.org/ibm-pc.png

11:19 locks: "After all, your son's still wearing that tie"

11:19 is he though

11:22 Anderkent: you could go some pretty dark places with that quote

11:24 instilled: hey! is there a way in clojure jdbc to apply a fn to column names for updates and inserts, e.g to transform a key from 'some-col' to 'some_col' (as e.g. sqlkorma does it) or do I have to do the mapping before hand?

11:25 joegallo: http://clojure.github.io/clojure/clojure.set-api.html#clojure.set/rename-keys is a useful thing

11:25 but that would be outside clojure.java.jdbc...

11:26 benmoss: that is a pretty hot fn

11:26 instilled: ok. that's perfectly fine… was just making sure i haven't overlooked something already available in clojure.jdbc...

11:26 thanks!

11:27 joegallo: actually, i think you can use the 'entities' functionality for that

11:27 if you want something inside clojure.java.jdbc. but i'm not positive, this is just from 2 minutes poking about.

11:28 instilled: i was hoping to find any example in the source (or test source) but failed to see how to properly use it...

11:28 joegallo: see more here: http://clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html#clojure-identifiers-and-sql-entities

11:28 (still not sure this is what you want, but it seems promising)

11:29 instilled: that's it. cheers. from the link above (j/query db-spec ["SELECT * FROM mixedTable"]

11:29 :identifiers #(.replace % \_ \-))

11:30 joegallo: yup, bingo

11:30 instilled: cheers a lot!

11:38 joegallo: instilled: you're entirely welcome

11:54 perses: how can i convert (((1 2) (3 4)) ((12 13) (0 1))), to ([1 2] [3 4] [12 13] [0 1]) ?

11:55 gtrak: apply concat map vec

11:55 perses: ,(->> (((1 2) (3 4)) ((12 13) (0 1))) (concat map vec))

11:55 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

11:55 gtrak: ,(apply concat (map vec '(((1 2) (3 4)) ((12 13) (0 1)))))

11:55 clojurebot: ((1 2) (3 4) (12 13) (0 1))

11:55 perses: ,(->> (((1 2) (3 4)) ((12 13) (0 1))) (concat map vec))

11:55 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

11:55 gtrak: err whoops, something like that :-)

11:56 coventry: vector, maybe

11:56 perses: ,(->> (((1 2) (3 4)) ((12 13) (0 1))) (concat map vector))

11:56 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

11:56 perses: ,(->> '(((1 2) (3 4)) ((12 13) (0 1))) (concat map vector))

11:56 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$map>

11:57 perses: ,(apply concat (map vec '(((1 2) (3 4)) ((12 13) (0 1)))))

11:57 clojurebot: ((1 2) (3 4) (12 13) (0 1))

11:57 perses: ,(apply concat (map vector '(((1 2) (3 4)) ((12 13) (0 1)))))

11:57 clojurebot: (((1 2) (3 4)) ((12 13) (0 1)))

11:57 perses: ,(apply concat (map vec '(((1 2) (3 4)) ((12 13) (0 1)))))

11:57 clojurebot: ((1 2) (3 4) (12 13) (0 1))

11:57 gtrak: ah, map vec apply concat :-)

11:58 ,(map vec (apply concat '(((1 2) (3 4)) ((12 13) (0 1)))))

11:58 clojurebot: ([1 2] [3 4] [12 13] [0 1])

11:58 gtrak: I was thinking in thread-macros

12:00 llasram: I prefer: ##(mapcat (partial map vec) '(((1 2) (3 4)) ((12 13) (0 1))))

12:00 lazybot: ⇒ ([1 2] [3 4] [12 13] [0 1])

12:00 llasram: Which I think came up yesterday? But maybe perses didn't like that answer

12:00 gtrak: (partial map .. ) always feels funny

12:00 justin_smith: #(map vec %)

12:01 llasram: gtrak: Then you aren't doing it enough :-)

12:01 gtrak: justin_smith: but that creates a new class!

12:01 justin_smith: At compile time. And it runs faster than partial.

12:01 gtrak: that's just the args-unpacking

12:02 slippery slope to bloatware!

12:08 llasram: just seems to me there ought to be a better way. weird wart, was looking at a nested versions of that yesterday with update-in.

12:09 llasram: gtrak: If you find the better way, please do let me know :-)

12:10 justin_smith: https://www.refheap.com/76754 <- surprising benchmark

12:10 gtrak's version is much faster

12:10 gtrak: I'd expect it to be

12:10 justin_smith: well, OK, surprising to me

12:10 gtrak: well, mine's totally lazy

12:11 hmm.. so is the mapcat one thoguh

12:11 justin_smith: I think it's the nested map elimination that does it

12:11 but that is still a very big difference

12:11 llasram: justin_smith: Now try it with reducers :-)

12:12 justin_smith: llasram: I have not used them, can you give me a reducers version?

12:12 llasram: Hmm, does criterium force evaluation of lazy results?

12:13 gtrak: wrap em in a doall

12:13 llasram: I think the way mapcat works will force evaluation of one step

12:13 justin_smith: llasram: yeah, definitely does

12:13 llasram: kk

12:14 justin_smith: (require '[clojure.core.reducers :as r]) then use r/map and r/mapcat. And I think can use r/foldcat instead of concat

12:14 justin_smith: llasram: wait - it may not force it, I will double check

12:14 llasram: cool, thanks

12:15 llasram: (actually `r/foldcat` <-> `apply contact`)

12:16 OR maybe not

12:16 BLOOP

12:16 So ignore the foldcat -- I never use it because `cat` requires input to be Counted for some reason

12:16 Oh, and need to force realization by (into [] ...) or such the result

12:17 So actually, lots of differences

12:17 justin_smith: llasram: oh, all the reducers stuff needs forced?

12:17 llasram: Yes. It otherwise just lazily accumulates a reducer chain

12:17 justin_smith: criterium is good, but it is the only thing that makes me feel like my cpu is way too weak

12:20 jebberjeb: ,(+ 1 2)

12:20 clojurebot: 3

12:20 jebberjeb: ,('foo 'bar 'baz)

12:20 clojurebot: baz

12:20 jebberjeb: wt!

12:20 justin_smith: ,(get 'bar 'foo) ; jebberjeb

12:20 clojurebot: nil

12:20 justin_smith: ,(get 'bar 'foo 'baz) ; jebberjeb

12:20 clojurebot: baz

12:21 justin_smith: a symbol in called position acts as get on its first arg

12:21 with second arg being the last arg to get, the default result

12:22 jebberjeb: justin_smith: many thanks

12:22 justin_smith: ,(doc get)

12:22 clojurebot: "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."

12:22 justin_smith: ,('foo '{foo 0 bar 1}) ; intended actual usage

12:22 clojurebot: 0

12:48 guest234245: yogthos: trying to use cljs-ajax and when I issue a POST its showing up on the other side as an OPTIONS request.

12:48 not sure what I'm missing..

12:49 blake__: Why does "iterate inc 5" give "5 6 7..." but "iterate + 5" give "5 5 5..."?

12:50 jcromartie: blake__: because (+ 5) returns 5

12:50 joegallo: (inc (inc (inc 5) --> 8

12:50 (+ (+ (+ 5))) -> 5...

12:51 blake__: jcromartie, joegallo: Thanks.

12:52 technomancy: clojurebot: dsls |are| intimidating and frightening https://secure.flickr.com/photos/technomancy/1884002248

12:52 clojurebot: Ok.

12:54 sdegutis: Has anyone experienced any issues using Clojure in dwm?

12:54 llasram: The X window manager?

12:54 sdegutis: Yeah.

12:55 llasram: Ok. What sorts of issues? (I mean, I'm not -- just having a hard time thinking of what sorts of issues could occur)

12:55 sdegutis: Never mind I forgot to try rebooting.

12:56 Sorry, I should have tried that first.

13:01 blake__: technomancy: "DSLs solve all the things!" -- Ruby

13:02 bbloom: blake__: more like OOP-EDSL all the things!

13:05 blake__: bbloom: 'deed.

13:08 sdegutis: Oh wait a minute, how is that upside-down now?

13:16 justin_smith: gtrak: llasram: https://www.refheap.com/76761 updated benchmarks, I was wrong, criterium was not forcing the laziness

13:16 that explains the surprising performance difference

13:18 llasram: justin_smith: That's good to know

13:39 michaniskin: which libraries are good for making SOAP clients in clojure?

13:39 Anderkent: well, there's clj-soap

13:39 i don't know of any other one

13:40 mdrogalis: necessary-evil

13:41 michaniskin: https://github.com/brehaut/necessary-evil

13:41 locks: love the name already

13:41 Anderkent: isn't that xml-rpc rather than soap?

13:41 michaniskin: haha the name is looking good

13:42 justin_smith: (inc brehaut) ; for that awesome name

13:42 lazybot: ⇒ 23

13:44 michaniskin: i think of SOAP and XML-RPC as "especially heinous", like in law and order svu

13:45 ok thanks!

13:53 seangrove: Structural sharing in edn? That sound like a thing?

13:54 bbloom: seangrove: not in a textual representation...

13:54 seangrove: Because large persistent data structures with a lot of shared structures (app state history) is nice nice in memory, but then serializing to send around is not nice

13:55 bbloom: I want to polish my history player to store the app state at every transition, but that's going to make sending reports to the server prohibitively large

13:55 justin_smith: seangrove: also it is bad for multithreading

13:56 bbloom: seangrove: maybe fressian covers this?

13:56 michaniskin: seangrove: gzip

13:56 seangrove: This is in the browser, I should have mentioned

13:57 bbloom: michaniskin: gzip is too late in the pipeline

13:57 michaniskin: you might have to generate and zip tons of stuff, only to get a tiny result at the end

13:57 michaniskin: bbloom: it's the pragmatic approach, not the fancy approach

13:58 bbloom: michaniskin: i mean, he can try it, but it's likely that he has too much sharing such that it will hang his UI at the frequency he wants to run it

13:58 michaniskin: i'd invent a new way to serialize only if standard compression doesn't work

14:00 bbloom: amusingly, XML has this feature, not that anybody ever uses it

14:02 seangrove: bbloom: I believe coventry said python's pickle format can do something similar

14:06 bbloom: seangrove: yeah, most object serialization libraries have no choice but to support object identity

14:12 seangrove: bbloom: For eclj, effects are programmable from the top-level, but are the automatically identifiable/taggable/queryable from the language itself?

14:12 For example, I'd like to slim my time-travelling debugger down, and just have it set a dynamic variable to mock any side-effects and play the message

14:13 bbloom: seangrove: i'm working on the design of that right now. example: https://github.com/brandonbloom/eclj/blob/master/src/eclj/interpret/meta.eclj#L145-L166

14:13 seangrove: Are you expecting to add some meta-data to a var/function/something so I can ask if it's side-effecting?

14:13 bbloom: seangrove: no. that's a *static* effect system, like "throws" in java

14:14 it would be hypothetically possible to abstract-interpret some code & see an approximation of what effects it may have

14:14 but i'm pretty far from that

14:14 likely to do type-checking via abstract-interpretation first

14:16 seangrove: Ok, I'm just realizing that the separation of state-transition and side-effecting as a pattern is really useful for us, specifically for things like deterministic reconstruction, but it's something that would fit better at the language level

14:16 bbloom: seangrove: you can approximate a real programmable effect system using OOP techniques

14:16 seangrove: Something like Eff/Elm/etc. representing effects as values

14:16 bbloom: seangrove: Om already does this

14:17 basically protocols + dynamic vars == crappy effect system

14:17 in the case of your app, you have that cast! effect, you can simply implement that as an operation on some dynamic var

14:18 seangrove: Intersting point

14:18 bbloom: (defn cast! [msg] (-cast! *eff* msg))

14:19 seangrove: I'll meditate on that

14:19 bbloom: seangrove: also ask dnolen_ how he intercepts state w/ the om protocols

14:20 seangrove: I definitely think time-travelling debuggers are a possibility in cljs now. Probably not even a ton of work, just more than it ideally would be

14:21 bbloom: seangrove: yeah, Elm has a JS monad essentially

14:21 which is somewhat akin to my "env" in eclj

14:21 being able to intercept all side effects is a fundamental feature of a next gen language -- hence my quest to add them to clj :-)

14:21 seangrove: bbloom: Makes me all kinds of excited :)

14:22 dnolen_: seangrove: doing a time traveling debugger specifically for Om would be pretty simple

14:22 amalloy: seangrove: the common-lisp printer does support structural sharing in printed representations, with stuff like (xs #1=(1 2 3 . #1#)), as the printed representation of (cons 'xs (cycle '(1 2 3)))

14:22 er, i guess (list 'xs (cycle '(1 2 3)))

14:22 bbloom: amalloy: yeah but edn doens't have such a facility :-(

14:23 amalloy: bbloom: yeah, i'm not saying you can do it in edn. but you said "not in a textual representation", which could have been misinterpreted

14:23 bbloom: amalloy: ah, you're right, sorry

14:23 amalloy: what CL does is basically read-time letrec :-P

14:24 amalloy: that's an interesting way of putting it. i guess you're right

14:31 TravisD: Does light table have a standard REPL in addition to the instarepl?

14:32 Also, are there any plugins for light table that emulate emacs key bindings?

14:32 amalloy: i think if you want light table to use a standard repl and emacs keybindings, you maybe just want to run emacs instead?

14:33 blake__: Sanity check, please: I'm trying to understand lazy-seq, but I came across a situation where my REPL gave me an error for one piece of code, then worked later for the same piece of code. The output is here:

14:33 https://www.refheap.com/76767

14:34 TravisD: amalloy: Hehe, that's a fair point. I've got a strange obsession with new editors. Always looking for something that I might like more than emacs

14:34 amalloy: it's a great way to waste time

14:34 seangrove: TravisD: I'm sure it has both, yes

14:34 Anderkent: blake__: well you get an error when you call it on ii rather than (ii 1) ?

14:34 seangrove: TravisD: ctrl+space repl

14:35 blake__: Anderkent: Thank you! I was =not= seeing that!

14:35 seangrove: And our very own ibdknox has seen fit to provide https://github.com/LightTable/Emacs

14:35 Jaood: amalloy: wouldn't customizing lighttable live via clojure a la emacs a good reason?

14:35 :)

14:35 xsyn: what's the difference between ~ and ~@

14:35 justin_smith: ,`(~@[1 2 3])

14:35 clojurebot: (1 2 3)

14:35 * Jaood doesn't know if that is even posible in LT

14:36 justin_smith: ,`(~[1 2 3])

14:36 clojurebot: ([1 2 3])

14:36 justin_smith: that's the difference

14:36 xsyn: thank you very much

14:36 justin_smith: np

14:36 TravisD: seangrove: Cool, thanks :) When I do ctrl + space repl, I only see instarepl

14:37 seangrove: Hrm...

14:37 One of my siblings uses emacs before they switch to emacs, that's the limit of my exposure so far

14:38 justin_smith: is your sibling in a time paradox?

14:38 TravisD: heh

14:39 Jaood: surely he meant LT somewhere there

14:39 seangrove: Erm, LT before using emacs

14:39 Jaood: :)

14:39 amalloy: (inc justin_smith)

14:39 lazybot: ⇒ 34

14:39 seangrove: TravisD: I think it's supposed to be the 'console', but it doesn't show up for me

14:40 * seangrove calls on technomancy

14:40 seangrove: it is a mystery

14:41 wow, this instarepl is definitely very cool though.

14:41 technomancy: http://p.hagelb.org/mystery.gif you mean?

14:42 seangrove: And thus, I have a gif-bot with no programming.

14:42 hyPiRion: ~mystery

14:42 clojurebot: mystery is http://p.hagelb.org/mystery.gif

14:42 seangrove: Ah, damn

14:42 Thought I was clever

14:42 TravisD: I don't understand the meaning of the gif

14:42 technomancy: =P

14:42 Anderkent: TravisD: are you saying it's a mystery?

14:42 seangrove: (inc Anderkent)

14:42 lazybot: ⇒ 11

14:43 TravisD: Anderkent: Haha :)

14:57 maxthoursie: I want autotest for clojure.test

14:57 is there something like that?

14:57 that is something that runs my test when code is changed

14:58 rlinehan: maxthoursie: I've been using lein test-refresh. it's worked pretty well so far. https://github.com/jakemcc/lein-test-refresh

15:00 gtrak: Raynes: I'd like to search lazybot log dumps, technically hard? Maybe lucene's too big, I'd be fine building something for myself that polls for new logs and dl's/indexes those.

15:01 maxthoursie: rlinehan: that was exactely what I was looking for, thanks!

15:02 gtrak: google was pretty ineffective at helping me find something earlier

15:02 maybe that could be made better, not sure.

15:02 justin_smith: gtrak: http://i.imgur.com/D2Hh0sn.png

15:02 gtrak: haha

15:11 Rosnec: is there a way to display the current recursion point?

15:12 I'm trying to recur, and it's telling me it's expecting 0 args when really there should be 1

15:12 the only thing I can think of is that lazy-seq is creating a recursion point

15:13 seangrove: bbloom: https://www.youtube.com/user/PapersWeLove

15:13 Are they holding the video hostage?

15:13 Rosnec: basically, the chain of functions is like (fn [x] (let ... (if-not ... (cons ... (lazy-seq (recur y))))))

15:13 maxthoursie: is there a literal for ints?

15:13 bbloom: seangrove: you'd have to ask zeeshanlakhani

15:14 Rosnec: lazy-seq does create a recur point

15:14 Rosnec: b/c the body of the lazy seq is a delayed function

15:14 seangrove: zeeshanlakhani: I'll send you some Korean snacks if you get it posted by this weekend

15:14 Rosnec: bloom: aha

15:15 if I use lazy-seq, is there really any need to use recur, then?

15:15 it won't consume the stack, right?

15:15 bbloom: Rosnec: you don't need recur here though, b/c by the time your deferred function runs, it will be on another stack

15:15 Rosnec: you got it

15:15 Rosnec: ok, got it

15:15 bbloom: Rosnec: just call the fn by name

15:15 Rosnec: yup

15:15 I was doing that before

15:15 when I thought "why don't I use recur instead?"

15:15 that's why

15:21 gfredericks: using recur with lazy-seq will not even work I don't think

15:21 at best it'll do something totally unexpected

15:25 bbloom: Bronsa: when is metadata evaluated normally on forms?

15:26 gfredericks: ,(meta #'int)

15:26 clojurebot: {:ns #<Namespace clojure.core>, :name int, :file "clojure/core.clj", :column 1, :line 841, ...}

15:26 gfredericks: ,(-> #'int meta :tag)

15:26 clojurebot: nil

15:26 gfredericks: ,(-> #'str meta :tag)

15:26 clojurebot: java.lang.String

15:26 gfredericks: ,(-> #'str meta :tag type)

15:26 clojurebot: java.lang.Class

15:27 gfredericks: sometimes apparently :)

15:27 bbloom: ,^{:x (prn 1)} [(prn 2)]

15:27 clojurebot: 2\n1\n[nil]

15:27 bbloom: ,(meta ^{:x (pr 1)} [(pr 2)])

15:27 clojurebot: 21{:x nil}

15:28 bbloom: i'm pretty sure that evaluation order isn't intentional

15:28 shouldn't matter in most cases, but that seems totally backwards to me

15:28 it's b/c it compiles to a with-meta call

15:28 (doc with-meta)

15:28 clojurebot: "([obj m]); Returns an object of the same type and value as obj, with map m as its metadata."

15:28 bbloom: note the arg order

15:30 gfredericks: does that apply to not-data-structures too?

15:30 ,^{:x (pr 1)} (pr 2)

15:30 bbloom: ,(binding [*print-meta* true] (prn '^{:x (pr 1)} [(pr 2)]))

15:30 clojurebot: 2

15:30 ^{:x (pr 1)} [(pr 2)]\n

15:31 gfredericks: ^ didn't eval the meta at all

15:31 bbloom: yeah, that's what i expected

15:31 hence why i asked Bronsa to know if he knew some other weird edge cases

15:31 at this point, he's the expert on weird evaluator edge cases

15:32 Rosnec: before I go and write this myself, is there a function like partition that can guarantee that the last partition has size < n? So if the size = n, it appends () to the seq?

15:32 bbloom: Rosnec: maybe you mean partition-all ?

15:32 Rosnec: doesn't that make sure the last partition has size n?

15:32 derek_c: can you define a var in a let form?

15:32 Bronsa: bbloom: sorry Icc was afk

15:32 derek_c: I mean, you can define an atom like (let [a (atom 3)])

15:32 how about var?

15:33 Bronsa: bbloom: it's evaluated before the expression when applied to non-quoted data literals

15:33 bbloom: Bronsa: really? example?

15:33 Rosnec: oh, wait a minute, partition cuts off the extra terms?

15:33 Bronsa: bbloom: sorry, I meant *after*

15:33 Rosnec: I've been using the wrong function this whole time!!

15:34 bbloom: Bronsa: haha ok yeah, makes more sense

15:34 Rosnec: I had the two confused

15:34 Bronsa: bbloom: not evalauted when the literal is not evaluated (quoted, arg to a macro)

15:34 Rosnec: but now I need something that's sort of the opposite of partition

15:34 partition-all keeps everything

15:34 bbloom: Bronsa: ok, i think that's what i understood from the experimenting above :-) thanks

15:34 Rosnec: partition cuts off the last seq if it's smaller than n

15:34 Bronsa: bbloom: the only gotcha I can think of is that read-time metadata on lists is not evaluated

15:35 ,^{:foo (println "foo")} (identity 1)

15:35 clojurebot: 1

15:35 bbloom: whoa.

15:35 Rosnec: I need something that adds an extra empty seq if the last seq is exactly of size n

15:35 bbloom: ok this is why i ask you these things lol

15:35 Bronsa: any idea why that is?

15:35 Bronsa: bbloom: no idea if that's a bug or if that's intended

15:35 bbloom: ,^{:foo (println "foo")} 1

15:35 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Metadata can only be applied to IMetas>

15:35 bbloom: ,^{:foo (println "foo")} (reify)

15:35 clojurebot: foo\n#<sandbox$eval285$reify__286 sandbox$eval285$reify__286@7108a1>

15:36 bbloom: Bronsa: i had punted on metadata in eclj's parser, but now i need it :-P

15:37 Bronsa: yeah, it's quite useful

15:37 bbloom: Bronsa: well i had it on vars, so it got me pretty far

15:40 dnolen_: Bronsa: so it easy to detect the presence of recur w/ tools.analyzer?

15:40 Bronsa: I did a horrible thing in core.match where I just flatten the search and search for a symbol because tools.analyzer didn't exist 3 (4?) years ago

15:40 "flatten the tree of forms"

15:41 would like to replace and fix with something more sane

15:41 Bronsa: dnolen_: quite easy, see https://github.com/clojure/tools.analyzer.jvm/blob/master/src/main/clojure/clojure/tools/analyzer/passes/jvm/annotate_loops.clj

15:45 gfredericks: dnolen_: Bronsa: do you guys think it's reasonable for advanced macros to depend on the analyzer? i.e., in the future will we have hundreds of calls to the analyzer via a handful of different libs when compiling our code?

15:46 (I don't know of a serious downside to this, just wanted to make sure it was okay to use it this way)

15:49 dnolen_: Bronsa: huh so -check-recur will do it

15:50 gfredericks: given how ad-hoc more advanced macros become I welcome our new tools.analyzer overlords

15:50 Bronsa: gfredericks: I believe cljs already does this, and when/if core.async moves to tools.analyzer that will be another one that does it. I think it's unlikely that it will be a wide-spread practice but definitely useful for the more powerful ones

15:51 BTW, check this

15:51 gfredericks: I was discussing a test.check macro with reiddraper that could be smarter w/ analyzer

15:51 Bronsa: ,(defmacro x [] (println "foo"))

15:51 clojurebot: #'sandbox/x

15:51 Bronsa: , (fn [] (loop [y 1] (x) (recur (Integer. 1))))

15:51 clojurebot: foo\nfoo\n#<sandbox$eval52$fn__53 sandbox$eval52$fn__53@15268b>

15:51 Bronsa: :/

15:51 gfredericks: It's time for another episode of "WTF Clojure with Bronsa"

15:52 bbloom: Bronsa: looking at compiler.java, it seems like the definite list is: map set vector fn reify ()

15:52 Bronsa: loop invalidation in Compiler.java potentially makes the code macroexpand more than once

15:53 bbloom: Bronsa: it's funny how rewriting clojure in clojure makes clojure's flaws so much more apparent

15:53 Bronsa: bbloom: oh yeah, forgot about ()

15:53 bbloom: smaller code == less place for bugs to hide

15:53 llasram: wow

15:54 Bronsa: bbloom: it's mostly really-edge-cases, it's not always that you find macros side-effecting at macroexpansion time

15:54 justin_smith: bbloom: how is your project related to CinC btw? https://github.com/cosmin/clojure-in-clojure

15:54 bbloom: Bronsa: the order of meta/value evaluation is totally edge-casey, but as i discovered evaluated vs not evaluated is a big difference ;-)

15:55 Bronsa: some code in core builds quote forms and evals them, like arglists :-/

15:55 justin_smith: it's totally unrelated

15:55 Bronsa: bbloom: arglists isn't really evaluated

15:55 the compiler just takes the second element

15:55 bbloom: Bronsa: but the metadata on def is, which means arglists gets evaluated as an item in a map

15:55 gvickers: Hey when defining mutlimethods, dispatch is decided based on the function on defmethod returning true correct?

15:56 Bronsa: bbloom: welllll

15:56 bbloom: Bronsa: if you don't eval metadata on def, then you get an arg list of the form '(quote ...)

15:56 from defn

15:56 justin_smith: Bronsa (et al?) are doing the "official"-ish clojure-in-clojure

15:56 Bronsa: bbloom: the compiler takes the arglists info before evaluating any of the metadata IIRC

15:56 bbloom: justin_smith: he's trying to make a production caliber clojure impl. i'm doing experimentation w/ something much crazier

15:56 Bronsa: not what i discovered :-P

15:57 Bronsa: let me check

15:57 justin_smith: bbloom: cool

15:57 bbloom: Bronsa: https://github.com/brandonbloom/eclj/blob/master/src/eclj/interpret/meta.eclj#L213-L225

15:57 justin_smith: my work wouldn't be possible w/ Bronsa's either

15:58 Bronsa: thanks for all your help, direct and indirect, btw :-)

15:58 Bronsa: bbloom: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L519

15:58 gtrak: the arglists created by the cljs analyzer also contain a spurious quote.

15:59 Bronsa: bbloom: so when the Var is interned, the Var has the unevaluated metadata + arglists with the 'quote removed

15:59 bbloom: when the Def gets evaluated, all the meta with the original arglists is evaluated

16:00 bbloom: Bronsa: *sigh* really?

16:00 that's just plain insane.

16:00 Bronsa: bbloom: you have no idea how much pain that caused me.

16:00 bbloom: Bronsa: where was the pain?

16:00 clojurebot: Gabh mo leithscéal?

16:01 derek_c: did 1.6 intro any breaking changes?

16:01 *introduce*

16:03 Bronsa: bbloom: weird things happen when you try to analzye ztellman libs and metadata evaluation varies slightly from how Compiler.java does.

16:03 bbloom: Bronsa: lol

16:03 Bronsa: ok, well, i'm going to write this down... and then forget about it

16:03 ztellman: Bronsa: example?

16:03 bbloom: b/c ztellman's libs are totally not target eclj code :-P

16:04 ztellman: it's not an intentional divergence, I'd guess

16:04 bbloom: i may update the goals in the eclj readme to say "makes ztellman's crazy projects obsolete, such that he must write newer even crazier things"

16:04 Bronsa: ztellman: https://github.com/ztellman/potemkin/pull/20 :P I

16:04 ztellman: aha

16:05 ok, merged

16:05 Bronsa: well that was fast

16:05 ztellman: well, I had meant to merge it days ago

16:05 I thought I already did

16:05 I need a daily email from Github of outstanding issues on my projects

16:05 bbloom: ztellman: i implemented the "alias" thing

16:06 ztellman: bbloom: cool, link?

16:06 bbloom: works a treat: https://github.com/brandonbloom/eclj/blob/master/src/eclj/env.clj#L35 and https://github.com/brandonbloom/eclj/blob/master/src/eclj/ns.clj#L10

16:06 ztellman: ha, that works

16:07 bbloom: ztellman: w00t first class environments!

16:07 ztellman: can I do fexprs in eclj?

16:07 bbloom: ztellman: there's no fexpr API, but there will be eventually

16:07 ztellman: ok, yeah, there will be some crazier things, then

16:08 martinklepsch: justin_smith, amalloy, thanks to your advice a few days ago I was able to parse this huge xml file w/o saving it in seperate files first — thanks a lot!

16:08 justin_smith: martinklepsch: awesome, glad it worked

16:08 what was the dtd fix?

16:08 bbloom: ztellman: i have a working metacircular interpreter modulo a few bugs. it's pretty slow, but partial evaluation & lifting the interpreter in to a compiler is planned :-)

16:09 ztellman: i look forward to what you wind up doing with "jit macros"

16:09 gtrak: bbloom: is eclj the thing that's going to make core.async introspection happen?

16:09 martinklepsch: justin_smith, the best workaround is actually to just change the path to the dtd before parsing, which will also change paths for other deps like mathml

16:09 ztellman: bbloom: ha, I'm more interested in having embeddable Clojure with first-class everything than performance

16:10 bbloom: ztellman: yeah, performance is a side effect of wanting to be able to write an embeddable clojure-in-clojure run on other platforms besides the jvm

16:10 ztellman: gotta write a compiler to get it to run elsewhere

16:11 gtrak: there would likely be like an eclj.async b/c eclj is capable of dynamic transforms, not just lexical ones

16:11 gtrak: so you'll (eventually) be able to do higher order operations within go blocks, for example

16:11 gtrak: ahhh

16:12 bbloom: gtrak: but that's a long way off

16:12 ztellman: the scope of the core.async transforms is pretty non-intuitive

16:12 it closed over a mutable deftype field and just held onto the value when the goroutine started, rather than throwing an error

16:12 took me *ages* to debug it

16:13 bbloom: ztellman: you should see some of the insanity i've encoutnered working on eclj

16:13 ztellman: you think clojure's stack traces suck?

16:13 ztellman: haha

16:13 bbloom: although being able to fipp.edn/pprint an env is pretty sweet

16:13 ztellman: yeah, I don't claim it's the craziest, just that the goroutine's boundaries unceremoniously at a function, and de-mutabilizing deftype fields, etc.

16:14 I was surprised how hard it was to reason about

16:15 bbloom: ztellman: the de-mutabilizing is probably a metadata bug

16:15 * bbloom continues to flip-flop on the metadata love/hate

16:15 ztellman: bbloom: oh, definitely

16:15 anyway, now I have a working compatibility shim, so I don't have to worry about core.async anymore: https://github.com/ztellman/manifold/blob/master/src/manifold/stream/async.clj

16:16 bbloom: ztellman: surely tbaldridge will have that fixed in a jiffy ;-)

16:16 gfredericks: there's not even a wikipedia article on f-expressions, how can they possibly exist?

16:16 bbloom: gtrak: https://en.wikipedia.org/wiki/Fexpr

16:16 gfredericks: gtrak: false alarm

16:16 bbloom: gfredericks: gtrak: yeah whoops sorry

16:17 tab completion failure

16:17 llasram: clojurebot: gtrak is a false alarm

16:17 clojurebot: Alles klar

16:17 gtrak: that's ok, I like reading these things :-)

16:17 ztellman: "Fexpr" sounds like some minor Norse deity

16:17 bbloom: ztellman: assuming your familiar with fexprs, are you also familiar with racket's "syntax objects"?

16:17 gtrak: Fexpr is a great band name.

16:17 ztellman: bbloom: only minimally familiar with fexprs, not at all with syntax objects

16:18 blake__: Fexpr and Conj stole Mjolnir!

16:18 bbloom: ztellman: in short, a syntax object is just a shallow AST node: it bundles a form with an env

16:18 justin_smith: blake__: lol

16:18 Vfe: Anyone ever use .setInterval js interlop with cljs and had it work? I’m trying the most simple example I can (ns example.main) (.setInterval js/window (js/alert “hi” 1000)) and it never alerts more than once. Pure JS works as expected.

16:18 bbloom: ztellman: in eclj, i don't do recursive analysis, i just do a shallow "parse" and map->Syntax on that...

16:19 ztellman: bbloom: presumably someone else can do recursive analysis, right?

16:19 martinklepsch: justin_smith, now it all takes 20sec instead of 5minutes, success!

16:19 bbloom: ztellman: the evaluator does the recursion

16:19 justin_smith: martinklepsch: nice

16:19 ztellman: bbloom: and that's pluggable?

16:19 bbloom: which means that you don't need feature expressions or any of that nonsense, if you don't go down a code path that uses some undefined value, it won't be an error...

16:19 it *will* be

16:20 ztellman: right now, it's a multimethod

16:20 ztellman: gotcha

16:20 bbloom: but it will let you intercept it

16:20 alew: an fexpr is like a macro except the return is also not evaled?

16:20 ztellman: intercept based on AST node type, environment, or both?

16:20 bbloom: alew: it's a first-class runtime macro that doesn't not explicitly evaluate, yes

16:21 ztellman: plan is that eval will be an open predicate dispatch function

16:22 anyway, the biggest issue w/ fexpr's a la Kernel is operand capture: if you had (defn call [f x] (f x)) and you pass that (call quote 1) you get out x, not 1

16:22 however, my plan is to parse children to syntax before running the fexpr, so you'd get (quote #Syntax{:form x :env {x 1 ...}})

16:23 meaning that operand capture could only happen if you explicitly extract the :form from the fexpr arg

16:23 otherwise, it works the same

16:23 * gfredericks blinks at eval as predicate dispatch

16:24 pbostrom: Vfe: shouldn't that be (.setInterval js/window #(js/alert “hi”) 1000)

16:26 Vfe: pbostrom: Thanks, that works. Never seen that in any of the web examples though O.o

16:27 justin_smith: Vfe: in your version, the return value of js/alert is the thing you are passing as the function to call

16:28 (as opposed to a function that will call js/alert)

16:29 Vfe: I gotcha, that makes sense.

16:31 edw: This is a very un-value-oriented programming question, but is there a simple way to serialize a Clojure map, maintaining the identity of shared structure?

16:31 And deserialize it, of course...

16:34 gfredericks: the wat

16:34 justin_smith: edw: so a map with mutable things in it?

16:36 edw: I guess you could hack something together with an ObjectOutputStream

16:37 gfredericks: edw: are you talking about serializing references to jvm objects? and then dereferencing them back to the original jvm objects after deserialization? or just about maintaining the redundancy in an object graph?

16:37 TimMc: edw: I believe Java serialization will maintain the object graph.

16:38 gtrak: wonder how many folks have tried to java-serialize edn.

16:38 justin_smith: I am sure it is possible, but it seems kind of pointless

16:39 gtrak: well, the cljs compiler analyzer data is way too big for print-dup, but fits in memory just fine due to structural-sharing.

16:40 justin_smith: ahh, a point!

16:40 www.pointerpointer.com

16:43 edw: TimMc: Ah, thanks for the tip. I just did some testing, and while duplicating equivalent objects will grow my memory use on deserialization, DISTINCT consideres this objects equivalent, so I may put "use Java serialization" in a TODO.

16:47 jpfuentes2: anyone here ever use clj-ssh and see auth errors?

16:53 amalloy: edw: clojure collections all implement Serializable, so you should be able to just use an ObjectOutputStream and be done

16:55 hugod: jpfuentes2: what short of auth errors?

16:55 jpfuentes2: USERAUTH fail

16:55 but all my args are right, and I know I can ssh into the host

16:55 michaniskin: i'm using clj-soap to make requests to a SOAP service. one of the API functions has optional arguments but i don't see a way of indicating which argument is which in the clj-soap client call. is this possible?

16:55 jpfuentes2: :ssh {:username "root"

16:55 :private-key-path "~/.ssh/id_rsa"

16:55 :strict-host-key-checking false

16:55 }

16:56 hugod: jpfuentes2: anything in the server logs?

16:56 justin_smith: jpfuentes2: are you sure that it interpolates "~" ? try expanding the path

16:56 hugod: yes, ~ is a shell thing

16:57 jpfuentes2: i tried that : (

16:57 when i'm running this with `lein test` a Java window pops up really quickly and disappears too

16:57 Apr 16 20:54:10 n1 sshd[1712]: Received disconnect from 172.20.20.1: 3: com.jcraft.jsch.JSchException: USERAUTH fail [preauth]

16:58 hugod: clj-ssh also logs the equivalent of ssh -vv on the client

16:59 edw: justin_smith: No, nothing mutable. Just a lot of shared structure. A lot of keys with the same compound value. The difference between deserializing with out preserved vs preserved structure could be 5:1 or greater.

16:59 amalloy: Thanks.

16:59 jpfuentes2: i need to hook that up, or is that in the exception message ?

17:02 hugod: jpfuentes2: via java logging

17:03 jpfuentes2: thanks

17:03 any idea on why a Java window pops up when I'm trying this?

17:04 hugod: it uses jna, and jna loads (but doesn't use) jwt

17:04 justin_smith: maybe it is trying to use the OS keychain?

17:04 hugod: it uses the system ssh-agent

17:05 justin_smith: which probably needs access to the Desktop system

17:05 which requires the silly window, I bet

17:05 hugod: it uses jna to get access to the socket

17:05 jpfuentes2: gotcha

17:06 hugod: you can run it with -Djava.awt.headless=true without any problems

17:06 I obviously meant awt, rather than jwt

17:07 justin_smith: hugod: ahh, yeah, that makes much more sense :)

17:07 hugod: if anyone knows how to use jna without it loading awt, then I'm all ears

17:08 jpfuentes2: interesting ...

17:09 it's as if it doesn't like RSA keys?

17:09 i just generated a test DSA pair and put it on server

17:09 looks like it worked

17:09 hugod: I use rsa keys all the time with it

17:10 does your rsa key have a passphrase?

17:11 if so it needs to be in the ssh-agent

17:12 jpfuentes2: no, it doesn't

17:13 hugod: is it particularly large? I think there was a 4096bit limitation from memory

17:14 jpfuentes2: 1.7K

17:14 hugod: that's the filesize I take it, rather than the number of bits in the key

17:14 jpfuentes2: yep

17:15 hugod: should be fine

17:15 jpfuentes2: well, i'll just go w/ this new pair for now

17:15 thank you for your help : )

17:16 hugod: np, let me know if you find the issue

17:36 arav93: I tried (clojure.instant/read-instant-date "2014-04-16T12:34:56+01:00")

17:36 and I got #inst "2014-04-16T12:34:56+01:00"

17:37 I'm not sure what is the data type of the output.

17:37 amalloy: arav93: (class x) will tell you, for any x, what type x is

17:38 arav93: stuartsierra: Could you explain how parse-timestamp works. i haven't been able to check it out.

17:38 amalloy: Thanks!

17:39 stuartsierra: arav93: It's a java.util.Date

17:39 arav93: I understood that part, stuartsierra

17:42 stuartsierra: arav93: Then I don't understand your question, I'm sorry.

17:42 gfredericks: data literals are super confusing for people who encounter them without an introduction

17:43 mostly the fact that they aren't tied to particular types; which is of course half of the point

17:43 technomancy: "wait you can have a space in between two things without a pair of delimiters wtf"

17:43 where "two things" actually means one thing?

17:43 gfredericks: man paredit is never going to figure that out

17:44 alandipert: also #{1 1} demonstrates that they add evaluation semantics

17:45 justin_smith: gfredericks: and emacs will never syntax highlight usages of #_ properly either

17:45 gfredericks: technomancy: let's start having formalized language feature factions within the community; the technomancy faction will hate records/protocols/data-readers and love multimethods

17:46 arav93: stuartsierra: Correct me if I'm wrong. To get the required result, I have to pass a 'java.util.Date' and I'd get the required result?

17:46 technomancy: gfredericks: can't me make it more general and just love reloading and interactive development?

17:47 martinklepsch: I'm bulk inserting things into Elasticsearch and would like to know how long this takes. When I wrap the call in a (time ) call it prints 350msec which isn't right — how would I go about doing something like this?

17:47 justin_smith: arav93: didn't we discuss parse-timestamp recently? wasn't your main interest how to annotate it for core.typed?

17:48 arav93: justin_smith: Yes. There were some unresolved issues.

17:48 justin_smith: martinklepsch: you could manually record the timestamps with ##(.getTime (java.util.Date.)) and manually calculate the ms

17:48 lazybot: ⇒ 1397684730098

17:49 stuartsierra: arav93: Sorry, I still don't understand what you're asking.

17:49 martinklepsch: justin_smith that sounds... elegant!

17:49 :D

17:50 justin_smith: martinklepsch: not that I have any idea why time would be returning a bad result

17:50 but .getTime from a Date should be reliable

17:53 martinklepsch: maybe some other thread is doing the work, and time is only checking the round trip time of spawning that thread and returning?

17:54 martinklepsch: justin_smith, I'm eval'ing in lighttable, will try repl

17:54 not using futures or anything though

17:54 justin_smith: my suspicion is the underlying lib may be using a thread

17:54 who knows though (could check the source of course)

17:56 martinklepsch: justin_smith, yeah, that would make sense indeed

17:56 systemfault: Hmm, macros are often said to be a selling point for any LISP… how often do you guys use macros in clojure?

17:57 justin_smith: use: constantly write: very very rarely

17:58 technomancy: they're very useful for selling lisp.

17:58 systemfault: Okay, I looked at a core.async video like 2 months ago… it’s written using macros, right?

17:58 justin_smith: right

17:58 pdk: what in clojure doesn't involve macros

17:58 justin_smith: so is "or", "and", "if", "defn"...

17:59 systemfault: What is a good case for writing a macro? Anything that cannot be done using normal functions? (I’m a beginner)

17:59 Bronsa: justin_smith: if is actually a special form

17:59 justin_smith: if you need to change the evaluation rules

17:59 fair enough

18:00 ,(filter (comp :macro meta second) (ns-publics 'clojure.core))

18:00 clojurebot: ([when-first #'clojure.core/when-first] [cond->> #'clojure.core/cond->>] [gen-class #'clojure.core/gen-class] [while #'clojure.core/while] [import #'clojure.core/import] ...)

18:00 justin_smith: in your own repl that will list all macros in clojure.core

18:01 76 out of 591 public definitions in my version

18:01 systemfault: Not that bad then

18:01 This is like 13%

18:02 Raynes: systemfault: What you want, almost always regardless of what it is, can be done with functions, just less pretty. That less pretty but functional sample should be the foundation upon which you build your macros to make things prettier.

18:03 justin_smith: Best practice is to always use a function, unless the thing you need can only be a macro. Do play with them to figure out what they do, just don't expect to actually need them in real code that often.

18:03 systemfault: So no need to become a macro god, I get it :)

18:03 technomancy: clojure.core is not intended to be representative of good style for user-level code

18:05 systemfault: Then… one last question. Any thought about core.typed? (types are attractive to me in most languages but do I want them in clojure?)

18:09 Jaood: Raynes: are you saying one should write the code first using functions and then (if you feel like or need it) rewrite it using macros to make it prettier?

18:14 TimMc: Jaood: Where "prettier" means "not unbearably redundant", yeah.

18:16 justin_smith: don't forget evaluation semantics - if you need short circuiting, rearranging before eval, or structural manipulation of your args, it's gotta be a macro

18:17 martinklepsch: whats the way to switch to a custom namespace in the repl?

18:17 justin_smith: martinklepsch: pre-existing or creating a new one?

18:17 martinklepsch: existing

18:18 justin_smith: (doc in-ns)

18:18 ,(doc in-ns)

18:18 clojurebot: "([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."

18:18 martinklepsch: thought in-ns should do it but nothing defined in there

18:18 clojurebot: "([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."

18:18 martinklepsch: hm

18:18 then I must be too stupid

18:19 justin_smith: ,(do (in-ns 'foo) ::bar)

18:19 clojurebot: :sandbox/bar

18:19 justin_smith: erm...

18:19 TimMc: heh, nice try

18:19 ::bar is expanded when that form is read

18:19 justin_smith: ,::bar

18:19 clojurebot: :sandbox/bar

18:19 justin_smith: ahh

18:20 TimMc: ,(do (in-ns 'foo) *ns*)

18:20 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: *ns* in this context, compiling:(NO_SOURCE_PATH:0:0)>

18:20 amalloy: martinklepsch: when you use ns (or in-ns) to go into a namespace, it is empty

18:20 justin_smith: ,(do (in-ns 'foo) clojure.core/*ns*)

18:20 clojurebot: #<Namespace foo>

18:20 amalloy: if you want to load a namespace from a source file, you need to use require

18:20 justin_smith: amalloy: he said it was pre-existing

18:21 TimMc: Oh yep.

18:21 amalloy: justin_smith: you and he didn't understand each other

18:21 justin_smith: oh, yeah, maybe not yet loaded

18:21 got it

18:21 to me "pre-existing" implied "required from a file already"

18:23 arrdem: Better names for a "math with units" library than arrdem/units? :P

18:26 justin_smith: don't name it clunitsjure

18:27 arrdem: I _think_ I have better taste than that. Should probably check.

18:28 justin_smith: if you want something less obvious: measures

18:28 Morgawr: mm.. I have a defrecord in a namespace and I require'd the namespace in another file and use (MyDefinedRecord. parameters) and it doesn't work

18:28 danneu: If I have a collection of points: [{:latitude 18, :longitude: -8, :score 42}, ...], does anyone know of the sort of algorithm that can "filter points with the highest score within 5km"?

18:28 justin_smith: maybe

18:28 Morgawr: records don't go out of their namespace?

18:28 gtrak: meajure

18:28 justin_smith: ouch

18:28 arrdem: my brain...

18:28 martinklepsch: amalloy, justin_smith, to me pre-existing meant that it's defined somwhere :D

18:28 justin_smith: in your clojure runtime or in the abstract wider universe?

18:28 arrdem: gtrak: that's so painful I may just use it..

18:29 Bronsa: +1 for meajure

18:29 arrdem: 3/3 Clojure hax0rz hate the name. Meajure it is.

18:29 gtrak: my 2 cents :-)

18:29 * arrdem exports LEIN_IRONIC_JURE

18:29 arrdem: technomancy: ^ you see this. you see it.

18:29 amalloy: Morgawr: records don't live in a namespace; they're java classes

18:29 you have to import them like any other java class

18:29 Morgawr: ah

18:29 I see

18:30 didn't know that, thanks

18:30 technomancy: arrdem: better be sufficiently hilarious

18:31 gtrak: or mehjure

18:31 arrdem: meajure is actually pretty good... most of this is gonna be math on financial units anyway rather than metric/imperial.

18:32 amalloy: arrdem: there are a number of unit-of-measure libs out there already. have you decided they're all no good?

18:33 arrdem: amalloy: I only found one, and it targets Clojure 1.2

18:33 amalloy: so... yes.

18:33 amalloy: https://github.com/martintrojer/frinj/blob/master/project.clj

18:33 * arrdem does more googling

18:33 amalloy: and there's nothing wrong with targeting 1.2, if it still works fine on 1.5 or whatever

18:34 arrdem: that lib used all sorts of stuff from Contrib that doesn't exist anymore.

18:34 amalloy: https://github.com/fogus/minderbinder/blob/master/project.clj

18:35 justin_smith: but these don't have a nice web2.0 friendly name like meajure

18:36 arrdem: justin_smith: shush you. I'll take a reasonable lib by someone I trust.

18:36 besides. that name is kinda evil..

18:36 (inc amalloy)

18:36 lazybot: ⇒ 99

18:36 arrdem: $karma technomancy

18:36 lazybot: technomancy has karma 105.

18:37 justin_smith: (reduce max (all-karma))

18:38 jaimef: can you guys stop spamming /r/lisp? k/thanks :P

18:38 arrdem: jaimef: but we have the better lisp...

18:38 * arrdem upboats all the Clojure posts

18:39 justin_smith: http://www.reddit.com/r/lisp I see very little clojure content there

18:39 is the problem that it shows up at all?

18:40 arrdem: justin_smith: yes. that subreddit insists that it's the CL subreddit, not the *lisp subreddit.

18:40 justin_smith: Clojure stuff gets downvoted agressively

18:40 complete with the usual Symbolics fetish..

18:44 amalloy: thanks for the links... looks like neither is a fit for my use case tho.

18:46 If I was doing math with fixed conversion rates, minderbinder is perfect. Unfortunately the nature of the task is floating conversion rates (currencies).

18:47 amalloy: i mean, if /r/lisp wants to be a common-lisp community, and their sidebar suggests they do, why would you post clojure stuff there? it's just rude. like, sure, they got a too-general name, but that's just too bad

18:47 justin_smith: arrdem: in that case, something like "standard" could be a good name

18:47 amalloy: arrdem: isn't that one of the use-cases frinj says it's great for?

18:47 justin_smith: fiat, specie...

18:49 arrdem: amalloy: reading..

18:49 ;; A big plastic bottle of really bad vodka?

18:49 things I never expected to see in source code..

18:50 justin_smith: arrdem: https://github.com/martintrojer/frinj/blob/master/src/frinj/feeds.clj

18:51 arrdem: justin_smith: oh damn.

18:51 still uses a global atom tho :P

18:51 amalloy: https://github.com/martintrojer/frinj/blob/master/src/frinj/feeds.clj#L23-L24 - augh just today i gave a class on why this is an evil race condition

18:51 justin_smith: arrdem: that's fair grounds for a fork with optional rename

18:52 arrdem: amalloy: yaaay dosync!

18:52 amalloy: arrdem: no, just a less-bad swap! function

18:52 (swap! feed-pool #(or % (...)))

18:52 arrdem: amalloy: right.

18:52 * arrdem starts making PR notes

18:52 justin_smith: then you can even leave out the when-not, yeah

18:53 amalloy: one of my slides was like "you think you need a ref and dosync, but really you just need to be more careful with your dang atoms"

18:53 justin_smith: amalloy: at a university? workshop?

18:53 amalloy: justin_smith: for other factual engineers

18:53 justin_smith: cool

18:53 arrdem: amalloy: is there a good rule of thumb for when to dosync? it's not a corner of the language I've trodden before, and I tend to just abuse swap! functions.

18:54 amalloy: arrdem: rule of thumb: don't

18:54 llasram: amalloy: Oh, are you at Factual now?

18:54 amalloy: like, refs are cool. but you never need them. i've used like five

18:54 arrdem: amalloy: I like that rule!

18:54 amalloy: once a year

18:54 llasram: I've still never used one

18:54 amalloy: llasram: yeah, for about two months now

18:54 llasram: I should study amalloy's uses of them :-)

18:54 amalloy: Cool!

18:54 arrdem: I only saw one last week... and promptly submitted a PR that got rid of it :P

18:54 llasram: haha

18:55 justin_smith: amalloy: so do you use an atom of a map instead of separate refs that need to stay syncronized?

18:55 amalloy: when possible, yeah

18:55 (and it usually is)

18:56 llasram: let me know if you find them. i don't know how to search for it

18:57 arrdem: hum... well I can't use frinj's feed structure directly due to API lags.. but I can just add-unit! myself.

18:57 llasram: amalloy: I'll just clone all your repos and grep for '(ref ' :-)

18:57 justin_smith: I saw a blog where a guy was talking about the poor MP performance of swap! with deep structures, and I imagined that synchronizing only on the set of refs you use would be less likely to lock things up than all the threads fighting over a big map they all want to modify

18:57 I'll see if I can dig it up

18:58 amalloy: justin_smith: for sure that's true, if you're doing something expensive to distinct subsets of a large structure

18:59 one amusing trick you can do is, instead of storing the actual value in the atom, store a delay of the value

18:59 justin_smith: oh nice, tricky

18:59 amalloy: then the work you do while swapping is very small, and then the deref does the work whenever

18:59 but that makes reading not-cheap, which rich frowns on

19:00 (because when N people deref a delay at once, N-1 of them block)

19:00 TimMc: I don't understand this trick you're talking about.

19:01 hiredman: amalloy: and is that way even once the value is realized

19:01 justin_smith: TimMc: the expensive calculation is not done while the swap! locks the object

19:01 TimMc: it makes me think of https://gist.github.com/samn/5843422

19:01 amalloy: hiredman: sure, although it's a pretty short locking window in that case

19:02 TimMc: justin_smith: Oh, swap in a delay that will perform the work at that node?

19:02 ...interesting.

19:02 justin_smith: TimMc: that's what I assumed amalloy meant, yeah

19:02 similar in spirit to using a lazy seq I guess

19:04 amalloy: i used that trick in https://github.com/amalloy/hermes/blob/master/src/flatland/hermes/queue.clj, to keep a buffer of "all the things that have happened in the last N minutes", where both reading and writing are expected to clean out stale events. i'm not sure anymore whether it was really a good thing to do, but it's an example

19:05 gtrak: maybe I should just join the http-kit party

19:05 anyone have anything bad to say about it?

19:06 just using jetty b/c lazy

19:06 justin_smith: it can break ring apps that assume the whole processing of the request happens in a single thread; IMHO that just means the ring app was broken though

19:06 http-kit is good

19:07 gtrak: ah yea, I wouldn't want to rely on that.

19:07 bhauman: loving websockets in http-kit

19:07 justin_smith: and the performance is great

19:07 and not needing a container on production

19:08 gtrak: the jetty ones seem to work.. but I noticed sente lets you define it as a ring-handler, whereas the jetty websocket server is further down.

19:11 arrdem: yaay my halfbaked units work. closeenough.jpg

19:12 amalloy: arrdem: the lisp motto

19:13 arrdem: amalloy: :D

19:16 petron: hmm, can't figure out why my Clojure implementation of the Top K quickselect algorithm is error'ing out for certain inputs: https://www.refheap.com/76711

19:17 amalloy: too many parens on line 11

19:17 arrdem: amalloy: 14 I think you mean..

19:17 amalloy: har har

19:18 he asked why it doesn't work, not why it's stylistically a little unpleasant

19:18 kenneth: hey all, macro question

19:18 arrdem: no... 11 doesn't close the cond block..

19:19 kenneth: say i have a macro like this: (defmacro def-react-class [ name & args ] `(def ~name (.createClass React ~@args)))

19:19 amalloy: arrdem: read line 11 more carefully. particularly the test (ie, leftmost part)

19:19 compare it to line 9

19:19 arrdem: amalloy: herp derp. gotcha.

19:19 amalloy: good eye.

19:20 Jaood: arrdem: don't you dare challenge amalloy !

19:20 kenneth: instead of just splicing in the args i'd like to transform them in a more complex way, how might i do that?

19:20 arrdem: Jaood: http://arrdem.com/i/really.gif

19:20 amalloy: (.createClass React ~@(whatever args))

19:21 kenneth: and whatever would just be a function that is called with the args

19:21 Jaood: arrdem: ;)

19:21 jarjar_prime: Hey there :-)

19:21 amalloy: but srsly, also really consider not writing a def* macro. just make the macro expand to (.createClass React whatever), and then someone can def it if they want

19:21 justin_smith: kenneth: write a function that takes a sequence representing the macro's input, and outputs the sequence that the macro should produce

19:21 kenneth: then call said function in the macro

19:21 Jaood: do you all have like emacs shortcuts for pasting gifs on irc? :)

19:21 jarjar_prime: is there a way to (or) a lazy-seq?

19:21 amalloy: &(doc any?)

19:21 jarjar_prime: so I can filter on them?

19:21 lazybot: java.lang.RuntimeException: Unable to resolve var: any? in this context

19:22 amalloy: er, i guess we just have ##(doc some)

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

19:22 arrdem: Jaood: tech is believed to have his own keybind tools... I just remember what images I have in my collection :P

19:22 jarjar_prime: (or (map #(namespace-prefix %) (string/split namespaces #","))) <-- that's kind of what i'm attempting

19:22 amalloy: jarjar_prime: what do you imagine that returning?

19:23 jarjar_prime: I want to feed that into a (filter), so I would like it to return true

19:23 justin_smith: arrdem: technomancy designs custom keyboards with dedicated gif-pasting keys, optimized for most pleasant possible keyfeel and click sound when sending the perfect gif

19:23 amalloy: jarjar_prime: i think you mean ##(doc some)

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

19:23 amalloy: (some namespace-prefix (s/split namespaces #","))

19:23 arrdem: justin_smith: you forgot that he's writing a forth implementation therefor so he can optimize the pasting in hardware..

19:24 Jaood: marcopolo`: marco

19:24 jarjar_prime: ah ok sweet, let me give that a try

19:28 amalloy: great (some) works :-)

19:28 (some #(.startsWith (name keywd) %)

19:28 (map #(namespace-prefix %) (string/split namespaces #",")))

19:29 justin_smith: jarjar_prime: you could eliminate the map call by putting the namespace-prefix call into the some predicate

19:29 Morgawr: what do you guys think is the best way of handling a tree data structure in clojure?

19:29 more specifically, an octree

19:30 justin_smith: jarjar_prime: or I guess you are doing that because you actually want to return the result of namespace-prefix

19:30 Morgawr: how much garbage are you OK with creating, and how fast does it need to be?

19:31 amalloy: by the way, justin_smith, you asked about where my class was. it's for factual, but it's not proprietary: the slides are at https://github.com/amalloy/clojure-concurrency-class, along with the code examples. original outline (which served a little bit like speaker notes)

19:31 akhudek: how do you pass closure compiler options with cljsbuild? Specifically, —debug

19:31 justin_smith: Morgawr: for doing some geometry stuff I found a quad-tree made of maps / vectors was fine, but in real time 3d rendering you may want to use something lower level

19:31 amalloy: cool, thanks for sharing

19:31 Morgawr: I'd need as fast as possible but it has to be pure Clojure (no java stuff)

19:31 I don't mind allocating extra memory/garbage

19:32 I was thinking of doing maps of maps

19:32 with vectors of children

19:32 justin_smith: so it's not like you will be creating a new octree for each frame at 60fps or something

19:32 Morgawr: like { :key val, :children [ { :key val :children [] } { :key val :children [] }] } or something like this

19:32 justin_smith: I don't have soft (or hard) realtime needs, if that's what you're asking

19:33 justin_smith: Morgawr: yeah, that sounds about right - and there are other options with similar semantics if that is too slow

19:33 Morgawr: I'll try with this, thanks

19:33 justin_smith: of course you will be using update-in / get-in extensively :)

19:34 Morgawr: yeah

19:34 justin_smith: you can promote from map to defrecord easily if you see perf issues without changing the rest of the code (besides the generation code)

19:35 Morgawr: yeah I think I will use a defrecord anyway

19:35 justin_smith: also if children is of a specific fixed maximum size, you could flatten it into the record for an extra boost

19:36 amalloy: justin_smith: that's not necessarily an improvement

19:36 Morgawr: chilren is of max size of 8

19:36 cause it's an octtree

19:36 what do you mean flatten it into the record?

19:37 justin_smith: amalloy: oh no? it removes a level of indirection and replaces a vector lookup with a record lookup, both should be wins, right?

19:37 Morgawr: you mean having something like { :keys val 0 child0 1 child1 2 child2 ... ... } ?

19:37 instead of { :keys val :children [] } ?

19:37 justin_smith: Morgawr: exactly

19:37 amalloy: justin_smith: (MyRec. new-value old-children) is a lot cheaper than (MyRec. new-value (:child1 old-rec) (:child2 old-rec) ...)

19:38 Morgawr: i recommend just using a map instead of a defrecord. but if you really want to use a defrecord, i definitely recommend not doing the thing justin_smith just suggested about flattening

19:38 justin_smith: ahh

19:38 Morgawr: yeah I don't like the flattening thing because of what you said about incremental upgrades

19:38 amalloy: not just because of performance but because it's disgusting

19:38 Morgawr: but why do you recommend using a normal map intead of a defrecod?

19:38 defrecord*

19:38 amalloy: because that's the default. you need a good reason to use a record instead

19:39 arrdem: can someone explain this? not something I've seen before. https://github.com/fogus/minderbinder/blob/master/src/data_readers.clj

19:39 justin_smith: amalloy: why not just use assoc to create the new record rather than using the constructor?

19:39 amalloy: justin_smith: doesn't matter, it has to do the same amount of work

19:39 justin_smith: ahh

19:39 Morgawr: amalloy: isn't the advantage of a record that it has a fixed structure and is implemented as a java class so it has better performance when not used in a generic setting?

19:40 amalloy: http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

19:40 Morgawr: in this case all my elements/subtrees are going to have the exact amount of elements

19:40 petron: amalloy, I don't see any paren-related syntax problems for my top-k fn.

19:40 justin_smith: petron: you are wrapping a number in parens

19:40 amalloy: Morgawr: the point is you haven't done it with a map yet. you don't know if you need the performance. don't give up the flexibility of maps until you know you need records

19:40 justin_smith: on line 11

19:41 amalloy: once you do know that, it's an easy change to use records instead

19:41 petron: ahhhhh

19:41 thx justin_smith

19:41 justin_smith: amalloy: it's a well known data structure, I doubt it will change as he works on it

19:41 petron: typo from an old do clause

19:41 thx for spotting that

19:41 Morgawr: amalloy: I'm looking for the best performance (I'm doing a case study on performance comparisons with some algorithms in java and clojure) and I already know I need an octree

19:42 and it's well-defined data structure

19:42 it's not something that I'll need to change and maintain

19:42 and afaik records behave exactly like maps, you can add new key/value pairs and they won't care

19:42 amalloy: well, they behave mostly like maps

19:42 justin_smith: Morgawr: that just creates a map under the hood

19:43 amalloy: you can't dissoc, you can't have missing keys

19:43 Morgawr: justin_smith: it's still a record as far as I know, just with added fields

19:43 amalloy: yeah

19:43 amalloy: you can't call them as functions

19:44 if your goal is to compare performance, it's reasonable to aim for high performance. but records aren't *that* much faster, really. try it out and decide for yourself

19:44 Morgawr: ah, I didn't know about them not being callable as functions

19:44 neat

20:06 justin_smith: maybe deftype would perform better than defrecord (easy enough to find out I guess)

20:08 petron: justin_smith, the syntax is good now, but I'm getting bad results :\

20:09 akhudek: hmm, source maps is trying to tell me that the problem I’m having with advanced compilation is in the closure string library

20:09 that doesn’t sound right

20:09 justin_smith: petron: maybe that calls for breaking it down into smaller functions and ensuring that each does what you expect?

20:10 arrdem: amalloy: having done a preliminary google, do you know of multimethod math in Clojure? seems like something obvious someone else's done before..

20:10 beamso: multimethod math?

20:11 amalloy: numeric-tower probably has it

20:11 which i think used to be generic-math

20:11 arrdem: yeah I found the old generic-math..

20:12 justin_smith: https://github.com/clojure/math.numeric-tower/blob/master/src/main/clojure/clojure/math/numeric_tower.clj#L103

20:12 it uses a protocol

20:12 arrdem: thanks justin_smith. I knew I'd seen something like this around before.

20:13 justin_smith: it's a smaller ns than I expected

20:14 arrdem: it's also kinda all it takes to put Clojure math on par with "normal" Lisp math :facepalm:

20:14 Pate_: thx, justin_smith I think my partition-by predicate is buggy

20:17 ToBeReplaced: arrdem: see algo.generic

20:17 arrdem: ToBeReplaced: THANK YOU

20:17 (inc ToBeReplaced)

20:17 lazybot: ⇒ 2

20:18 jergason: friends, i'm struggling with moving to a functional style.

20:18 ToBeReplaced: ha, i didn't know i had ever been inc'd in the first place

20:18 jergason: i find myself using let everywhere to make local variables, and it feels icky

20:18 arrdem: ToBeReplaced: :P I can remember most of the standard library... the contribs just clutter my head :(

20:18 jergason: are there some general strategies to avoid doing imperative programming via lets in clojure?

20:18 does this even make my sense?

20:18 *sense

20:18 justin_smith: jergason: but local bindings is the only reason to use let, and let is the main way to make local bindings

20:18 Pate_: justin_smith, fixed! partition-by doesn't work the way I thought it did.

20:19 jergason: yeah, i just feel like i'm abusing local bindings

20:19 justin_smith: well I guess it does sequencing too

20:19 arrdem: so why is that algo.generic when we have numeric-tower..

20:19 justin_smith: abusing them?

20:20 if you need to do multiple things in a specific order, and know all their return values, let is just fine for that

20:20 scottj: jergason: if you want more specific help, share a snippet of code and people can give feedback

20:20 justin_smith: and even if you ignore some return values (using _ on the lsh), that's still OK

20:20 *lhs

20:20 jergason: i shall do this

20:20 arrdem: (inc ToBeReplaced) ;; have some more karma. exactly what I was trying to remember.

20:20 lazybot: ⇒ 3

20:20 jergason: lemme make it work first

20:23 ToBeReplaced: arrdem: it looks like the protocol in numeric-tower is meant for internal implementation of just those methods that need to be dispatched over primitives

20:23 i certainly wouldn't extend them... i'd use algo-generic for algebraic props

20:24 scottj: jergason: btw, rich uses a lot of let bindings IMO, see for example codeq.

20:25 so you're in good company :)

20:25 arrdem: ToBeReplaced: yeah. I'm just gonna work off of algo

20:25 seriously tho... I knew that such a thing existed. I'm not insane! yay!

20:35 technomancy: is lein supposed to load "user.clj" before it does anything?

20:37 technomancy: arrdem: yeah, that's outside its control

20:37 clojure does that; no way to turn it off or anything even if we wanted to

20:37 arrdem: :sadpanda:

20:37 okay thanks. didn't know that.

20:40 Frozenlock: technomancy: might I ask more info about this? https://github.com/ato/clojars-web/pull/203#issuecomment-40665321

20:40 Where do you put this code?

20:40 technomancy: Frozenlock: that's just from the dotfiles for my browser

20:41 gotta head out for dinner; bbiab

20:41 arrdem: TIL tech is a konqueror user.

20:41 technomancy: dude

20:41 not konqueror

20:41 conkeror

20:42 TEttinger: the XULrunner based keyboard driven browser, conkeror

20:43 arrdem: man... I may just switch browsers for webjumps.

20:43 crud

20:58 akhudek: how I wish for this right now https://code.google.com/p/closure-compiler/wiki/FAQ#My_code_broke_when_using_advanced_optimizations!_How_do_I_figure

21:30 xeqi: Frozenlock: yep, I didn't use <button>s initially, and hadn't gotten back around to fixing it

21:31 Frozenlock: xeqi: Ok, so I'm not crazy :)

21:32 I sent you a pull request, for the tiny tiny change.

21:32 xeqi: I wouldn't go that far

21:42 arrdem: where would you guys suggest starting on wrapping this? https://github.com/pusher/pusher-java-client

21:43 I'm a little thrown by the anon class instantiation, and how to duplicate it.

21:56 dissipate: in order to use tools.logging do you have to have log4j or another java based logger installed?

22:07 llasram: dissipate: In your deps, yeah

22:27 amalloy: arrdem: you want reify

22:42 dissipate: amalloy, what is the most light weight logging utility to get up and running quickly?

22:45 amalloy: why are you asking me? if it's a general question and not a continuation of a conversation we've been having, ask the channel

22:46 dissipate: what is the most light weight 'batteries included' logging utility?

22:46 gfredericks: are those contradictory requirements?

22:49 dissipate: gfredericks, i don't want to mess with log4j or any of the other complicated ones

22:49 nightfly: rsyslog

22:50 dissipate: nightfly, any experience with this one? https://github.com/pjlegato/onelog

22:53 ddellacosta: dissipate: clojure.tools.logging works just fine

22:55 * gfredericks uses clojure.tools.logging

23:02 dissipate: ddellacosta, i guess i'll use that with just the default log4j config file

23:02 ddellacosta, but i don't understand why tools.logging is so heavy

23:02 ddellacosta: dissipate: what do you mean, heavy?

23:03 dissipate: ddellacosta, log4j is crazy. it has a 200 page manual that goes with it.

23:04 ddellacosta: dissipate: what does that have to do with tools.logging?

23:04 dissipate: ddellacosta, it uses log4j

23:04 ddellacosta: dissipate: use timbre if you want to pretend you are not using java

23:05 dissipate: it's significantly "heavier" though, in terms of Clojure codebase

23:06 dissipate: ddellacosta, onelog it is for me then. i just want to log to stdout

23:36 ToBeReplaced: dissipate: i don't know what was going on before... clojure.tools.logging is solid, and will use whatever logging backend is in your path... if you don't have one, it will use java.util.logging, which will go to stdout by default

23:39 dissipate: ToBeReplaced, ah, i did not realize that. thanks for the info.

23:41 ToBeReplaced, you wouldn't happen to know a good scheduling library other than the ones listed here? http://www.clojure-toolbox.com/ something lightweight

23:45 ToBeReplaced: unfortunately there are no good scheduling libraries anywhere ;)

23:46 dissipate: it depends what you are looking for... i don't think there are any viable alternatives to Quartz or Cronacle for the enterprise, but i haven't looked recently

23:47 nothing wrong with ScheduledThreadPoolExecutor if you're talking "do this once a minute" type of stuff

23:48 amalloy: ~java.util.concurrent

23:48 clojurebot: java.util.concurrent is "When I find myself in times of trouble / Prof. Doug Lea comes to me / Coding lines of wisdom / j.u.c."

23:48 dissipate: ToBeReplaced, i'm not really interested in scheduling something for the future or doing some cron-like schedule. my use case is scheduling something right away based on a message from a queue. i just want to be able to keep track of the running task, and start/stop/pause it

Logging service provided by n01se.net