#clojure log - Feb 17 2014

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

0:02 dsrx: hmmmm

0:02 ,(mapcat #(%))

0:02 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core/map>

0:02 dsrx: weird error message, that

0:03 amalloy: Wild_Cat: rich is too cool for specs

0:03 xensky: (defmulti foo [& args] (count args)), of course

0:08 xensky: amalloy: thanks, this fixes my problem

0:45 dsrx: is there any semantic difference between (reset! my-atom my-sym) and (swap! my-atom (constantly my-sym)) ?

0:46 pdk: you'd be creating a lambda with constantly

0:52 muhoo: is there some way to make the damn colors turn off in aviso pretty's nrepl middleware?

0:53 a stacktrace with a bunch of unreadable ^[[1;31 chars is not much improvement over java's stacktrace :-/

0:58 TEttinger: muhoo, yes

0:59 it's called ansicon, and it make the colors actual colors :D

0:59 https://github.com/adoxa/ansicon

1:23 sm0ke: how do i define typehint for void?

1:26 ambrosebs: sm0ke: why do you want that?

1:27 sm0ke: ambrosebs: i was using a macro which defines method signatures for gen-class by pulling typehints

1:28 so the problem is 'void' is valid inside gen-class :methods

1:28 but ^void is undefined as a type hint in itself

1:28 dsrx: is it?

1:28 sm0ke: ,(defn ^void foo [x] (prn x))

1:28 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: void in this context, compiling:(NO_SOURCE_PATH:0:0)>

1:29 ambrosebs: ,java.lang.Void

1:29 dsrx: hmmmmmm http://clojure.org/java_interop#toc30

1:29 clojurebot: java.lang.Void

1:29 ambrosebs: maybe that works?

1:29 sm0ke: ,(defn ^java.lang.Void foo [x] (prn x))

1:29 clojurebot: #'sandbox/foo

1:29 dsrx: http://i.imgur.com/VjJPkgd.png

1:29 sm0ke: ok thanks!

1:29 dsrx: what that? rick rolling?

1:30 dsrx: long story

1:30 ambrosebs: sm0ke: if not, perhaps java.lang.Void/TYPE

1:31 sm0ke: ,java.lang.Void/TYPE

1:31 clojurebot: void

1:31 dsrx: I guess that doc is just wrong then

1:32 ambrosebs: oh yea, that's weird

1:33 sm0ke: anyways i am will use Void for type hints and gen class signatures from now on

1:33 what

1:33 i will*

1:33 weird typo

2:03 TheBusby: anyone using lein from Makefiles? Having issues with not being able to 1. name the output of lein, 2. have lein give me the name of the file it will output...

2:07 dsrx: ,(identical? (str "foo" "bar") (str "foo" "bar"))

2:07 clojurebot: false

2:08 dsrx: on cljs/v8, that is true

2:08 apparently v8 interns all string values, not just literals

2:08 egghead: thats interesting

2:09 dsrx: oh hm, true in gecko as well

2:09 egghead: that's basically the javascript difference between new String("foobar") vs String("foobar")

2:10 since "foobar" === "foobar" but new String("foobar") !== new String("foobar")

2:10 dsrx: ya, it wouldn't make any sense at all to intern string objects

2:11 you know, I guess it's probably down to what identical? is in cljs

2:13 yeah identical? just compiles down to ===, hurf

2:18 logic_prog: multiple choice quiz: which of the following is true: (a) macroexpand-1 doesn't work in cljs (b) I'm an idiot (c) both of the above

2:18 ddellacosta: (str "a: " a ", b: " b) vs. (format "a: %s, b: %s" a b) ?

2:19 do folks prefer one over the other for any reason?

2:20 Ember-: depends

2:20 I prefer the latter way when doing logging and so forth, first one when building logical strings for the app itself

2:21 I'd guess the first one is more performant, but not sure

2:21 logic_prog: I prefer format always.

2:21 Ember-: haven't checked the clojure implementation for str

2:21 logic_prog: (str ... ) makes it hard to see the overall picture of what i'm constructing

2:21 (format ... ) is like "here's a template, and we'll fill in shit later"

2:21 Ember-: yeah, it depends like I said

2:21 (str "Value is:" foo) is kinda obvious

2:22 but (str "a" a "b" b "c" c "d" d) is not

2:22 logic_prog: (str ... ) is like sleep deprivation

2:22 at first you're like "it's a little, it won't hurt"

2:22 Ember-: str is ok for one dynamic parameter

2:22 logic_prog: alright, fine, I'll give you that

2:22 (inc Ember-)

2:22 lazybot: ⇒ 1

2:23 ddellacosta: thanks logic_prog and Ember-

2:23 Ember-: whee, I got my first karma \o/

2:23 ddellacosta: heh

2:25 ambrosebs: logic_prog: afaik cljs uses clj macros, so you don't have mexpand

2:25 logic_prog: yeah, but I need to _debug_ a macro

2:25 that works fine in clojure, and does something _slightly_ different in clojurescript

2:25 so I'm curious about "wtf does clojurescript see when this macro is expanded"

2:25 I apologize for not mentioning this in original question.

2:26 ambrosebs: logic_prog: call cljs.analyzer/macroexpand-1 iirc

2:26 logic_prog: http://grokbase.com/t/gg/clojure/12bn9rd175/macroexpand-1-for-clojurescript-macros seems to suggest I'm not the only one struggling with

2:26 ambrosebs: in clojure

2:27 something like (cljs.analyzer/macroexpand-1 (cljs.analyzer/empty-env) '(my-form 1 2 3))

2:28 logic_prog: hmm

2:28 ah

2:28 ambrosebs: that's my guess at least

2:28 logic_prog: I was wondering what to pass for the env

2:28 hmm, NullPointerException

2:28 let's see what else is wrong :-)

2:28 ah, got it working

2:33 dsrx: if I specify a lein dependency in :plugins, does it need to be specified in :dependencies as well?

2:33 logic_prog: (inc ambrosebs)

2:33 lazybot: ⇒ 5

2:34 logic_prog: ugly = (macroexpand-1 '(cljs.core.async.macros/go ... )) :-D

3:03 amalloy: dsrx: plugins and dependencies are very different

3:04 it goes in :plugins if you want it to be something that runs in your lein jvm, and :dependencies if it's something everyone who uses your project will need

3:04 (and if it's in :plugins, it will be accessible *only* in the lein jvm, not your project jvm)

3:05 so i can't really think of any instances of something you'd want in both. maybe nrepl?

3:08 glosoli: Is there anyway to catch several exceptions in one catch block ?

3:08 s/anyway/ any way

3:42 akl: (try <your code> (catch ExceptionClassA err1 (prn "got an A!")) (catch ExceptionClassB err2 (prn "got a B!")) (finally (prn "all done!")))

4:12 sm0ke: ,(class 1)

4:12 clojurebot: java.lang.Long

4:16 clgv: 18% to 20% speedup with Clojure 1.6-beta1 compared to 1.5.1 :D

4:17 probably due to the new hashing

4:35 sm0ke: nice but only where maps are involved right?

4:35 otherwise i heard it has gone slower

4:37 clgv: sm0ke: in this case overall on the whole program run

4:37 hyPiRion: sm0ke: The hashing itself is slower, but the collision loss may make up for it

4:38 clgv: sm0ke: I have at least one set of integers in there

4:38 that's sitting in a bottleneck

4:38 hyPiRion: Are you working with negative values too?

4:39 clgv: no.

4:39 hyPiRion: vectors? set of sets? If not, then the hashing may not be the culpris

4:39 culprit*

4:42 clgv: no. I would have blamed the set that contains a narrow range of longs, e.g. 100,101,...,199 where some of those are removed over time

4:42 hyPiRion: it is heavily optimized code.

4:46 katox: interesting, datomic doesn't work with upcoming clj 1.6 yet

4:46 back to stable for now, I guess

4:46 sm0ke: what is the type hint for ArrayList<String> ?

4:47 clgv: hyPiRion: there aren't that many performance related fixes in 1.6 that could be the reason right?

4:48 hyPiRion: does the ASM library update have performance consequences?

4:49 ambrosebs: sm0ke: just java.util.ArrayList should do it

4:49 clgv: sm0ke: yeah, there are no generics on JVM level

4:49 sm0ke: it's all compiler magic ;)

4:53 humm type hints for the result of a primitive function do not seem to work (primitive arguments but object return type)

4:54 manually specifying :tag metadata does not work either

5:49 muhoo: TEttinger2: windows? 0_0 um, no. i'm inside emacs nrepl.el, on linux. and escape codes are messing up the stacktraces

6:34 Gues_____: what;s up

6:35 what kind of channel is this ?

6:42 certainty: irc channel

7:11 clgv: certainty: are you a mathematician?

7:19 certainty: clgv: nope. why?

7:20 clgv: certainty: you need a certain amount of time, your answer was absolutely correct but it did not help the questioner at all ;) :P

7:20 scnr to quote that math joke ;)

7:21 certainty: clgv: heh! i vaguely remember that one. Wasn't there a manager involved somehow as well?

7:22 clgv: certainty: I think there are different versions of that joke

7:24 certainty: i see. a good one in any case

8:51 Fender: hi there

8:52 as always - I have a problem

8:52 I mean related to clojure

8:52 edbond: Fender, good start

8:52 Fender: so I map some 40 values by a function that takes approx 300 ms in avg

8:53 when I pmap the thing (I have 2+2 cores), time is reduced to 200ms

8:53 which is not ok

8:53 now I knwo the partition-stuff and it doesnt hepl at all

8:54 the function for mapping is pure btw

8:54 so I thought I try reducers

8:55 first of all, there is no real documentation on the functions

8:55 I mean, there is the source code but CLJ is my first lisp and I am not familiar with foldcat and the likes

8:56 still I managed to hack something together, a r/foldcat on r/map

8:56 while it is fast, I see that it is only using single core

8:56 although I have Java 7 and (Class/forName "java.util.concurrent.ForkJoinTask") succeeds

8:57 edbond: Fender, try more input values

8:57 Fender: mom, I'll try

8:58 its calculating...

8:59 do you guys know where I could get a decent doc on reducers?

8:59 loliveira: does somebody know a json library that is able to parse the following json? https://www.refheap.com/40625 Note that the keys don't have ' or ".

8:59 Fender: http://clojure.github.io/clojure/clojure.core.reducers-api.html -> 404

9:00 Ember-: loliveira: well, that is *not* JSON

9:00 and I'm not even talking about the var x = ... definition in the beginning

9:00 edbond: Fender, did you read blog posts? http://clojure.org/reducers

9:00 Ember-: json quite explicitly defines that keys *must* be strings

9:01 loliveira: Ember-: I know. I need to parse it from a js file.

9:01 Ember-: even jquery doesn't accept json without string keys (anymore, it used to)

9:02 loliveira: and you cannot add the string literals into that file?

9:02 Fender: edbond, I did but it just covers some functions

9:02 and specifically not the fork-join thing which I'dlike to use

9:02 loliveira: Ember-: I don't have write access to that file. =(

9:03 Ember-: how about you do some regexp magic before trying to parse it

9:03 find keys without quotes and add some

9:03 should be quite easy to do

9:03 loliveira: Ember-: i will try that way. thanks. =0

9:04 =)

9:04 Ember-: Some people, when confronted with a problem, think

9:04 “I know, I'll use regular expressions.” Now they have two problems.

9:04 ;P

9:05 but seriously, that should work in your case if it is not a wierd one

9:05 depends on the structure of that JSON

9:05 loliveira: other solution is to do the parsing yourself

9:05 json is really simple and not that hard to tokenize

9:06 Fender: (time (count (pmap get-field-data missing-fields))) ;; "Elapsed time: 7107.496882 msecs"

9:06 (time (count (map get-field-data missing-fields))) ;; "Elapsed time: 11904.429407 msecs"

9:06 each call to get-field-data returns a vector of 170k values

9:06 loliveira: Ember-: I'll try regexp first.

9:06 Fender: (count missing-fields) = 33 in this case

9:07 how could I get a decent speedup with r/reducers and fjreduce / fold?

9:08 Ember-: Fender: reducers help when your operations make a lot of garbage

9:09 when your long living operations do not create that much work for gc then not so much

9:09 Fender: these ones do for sure, but I already optimized that stuff

9:09 I know but why wouldnt pmap bring at least a twofold speedup?

9:10 for a 2+2 cpu...

9:10 usually it does

9:10 AimHere: Sometimes pmap makes things slower with the overhead of sorting everything out again after you've done all your calculations at once

9:11 Fender: hmm, I could try a thread pool instead

9:11 but still, sorting 33 values is not too much

9:13 maybe it's a memory allocation thing...

9:15 looks like some 700MB are allocated in the heap

9:15 with no in-between GC

9:18 hyPiRion: Fender: Don't use pmap, use ExecutorService instead. That should speed it up somewhat

9:19 Fender: I'll give it a try

9:21 can you recommend some lib where you basically submit your tasks and have some control e.g. to cancel the tasks?

9:22 hyPiRion: Fender: Whenever you submit a task to an executorservice, you get a future back which you can cancel

9:23 I'm not sure if there is any wrapper for executorservice though. Let me have a look

9:23 loliveira: Ember-: it seems that worked. =) (clojure.string/replace j #"(\w+)\s*?:" (fn [[_ m]] (str \" m "\": ")))

9:24 Fender: ah ok, I remember having tried that already earlier but I think I wrapped the future part inside my tiny lib and then I figured I coulndt cancel the stuff

9:24 ...which I disliked

9:24 don't look, I can look for myself, it just happens that sometimes someone has a nice recommendation

9:26 hyPiRion: yeah. Well, I've worked with ExecutorServices in Java, and they are very, very painless.

9:27 You have to specify how many threads, but apart from that, it should be rather straightforward.

9:28 Fender: ok, I'll check it out

9:28 thanks!

9:35 lvh: Hi! I'd like a code review on a function I wrote. I'm parsing some CSV with a header and a bunch of entry rows into maps of {:k "v"}; some "v"s need to be parsed

9:36 here's the code: https://gist.github.com/lvh/43d713e6812503f8fb5e

9:37 I wouldn't be surprised if this exists as a function already

9:46 AimHere: lvh, does that even run? I don't think those recurs look right

9:48 As in, normally I wouldn't recur a vector with the updated values, but rather just the values themselves

9:48 ,(loop [a 5 b 2] (if (zero? b) a (recur (dec a) (dec b))))

9:48 clojurebot: 3

9:49 AimHere: lvh, also, that probably looks a little neater written using reduce

9:52 lvh: AimHere: Oops, you're right :)

9:52 borkdude: is loop still a public macro? ;)

9:52 AimHere: ,(type loop)

9:52 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/loop, compiling:(NO_SOURCE_PATH:0:0)>

9:53 AimHere: Well it's still a macro. Don't know what you mean by public

9:53 llasram: ,(type @#'loop)

9:53 clojurebot: clojure.core$loop

9:54 lvh: how do you spell def-but-private

9:54 borkdude: ˆ:private true

9:54 llasram: lvh: (def ^:private whatever ...)

9:54 lvh: ah. Why isn't there a def-?

9:55 llasram: borkdude: Trying to confuse the new users? :-)

9:55 borkdude: (def ^:private hello 10)

9:55 llasram yes, sorry ;)

9:56 lvl because the clojure implementors are really lazy and don't generate every possible permutation of configuration up front for you ;)

9:56 lvh I mean

9:56 llasram: Or because a general mechanism (^:private metadata) is more powerful than giving every `def`-style macro an associated "but private" version

9:57 lvh: fair enough; it's just because I knew about defn- that def- seemed like an obvious guess

9:57 llasram: I think `defn-` only exists because the original Clojure metadata syntax was much less compact.

9:57 These days I pretty much only see defn- in code written by new users and rhickey

9:58 borkdude: here's how you can make a private macro though: https://gist.github.com/borkdude/9052017

9:58 lvh: llasram: that's two extremes right there :)

9:59 llasram: So I should replace defn- with ^:private?

9:59 borkdude: lvl (def ^:private some-var some-value)

9:59 why do I keep typing lvl instead of lvh

9:59 hyPiRion: llasram: :o You've never written code in Leiningen I see :p

10:01 benmoss_: do Clojurists agree that making fns private is a good thing?

10:01 borkdude: benmoss_ it depends

10:02 (pun intended)

10:02 llasram: hyPiRion: Haha. I did mean new code. Existing code bases from 1.2 days and before certainly use it, and better to be consistent

10:02 benmoss_: i guess for libraries and their APIs i still see the rationale

10:02 llasram: lvh: I don't think it matters as long as you're consistent. But using ^:private is more consistent since you can use the same mechanism for everything :-)

10:02 borkdude: benmoss_ it depends if you want your functions to be exposed or not

10:03 benmoss_: yeah, i guess I thought at least internally its often more of an OO thing

10:04 hiding access to state

10:04 shep-werk: you can hide state and only ever have public methods :-)

10:04 arcatan: (defmacro def- ...)

10:06 hyPiRion: llasram: :( I just pushed this https://github.com/hyPiRion/smallex/blob/dev/src/smallex/reductions.clj

10:07 Also I realised I commited the comment block, so now I'm finally reaching rhickey level

10:08 * hyPiRion force-pushes.

10:11 lvh: is there a safe parse-num in clojure?

10:11 I have a string; I want a number represented by that string

10:11 I don't want Integer/parseInt because it might be a big number.

10:12 (I also don't want parseInt because maybe it'll be a ratio)

10:12 I could do read-string, I suppose :)

10:13 hyPiRion: (Long/parseLong "12") or (BigInteger. "12")

10:14 lvh: hyPiRion: I guess that fixes most of them; I'll do ratios manually I suppose

10:15 borkdude: lvh yes, edn/read-string

10:15 lvh: hyPiRion: How do I get "BigInteger." as a function? (def i BigInteger.) doesn't work; I could write a lambda but that seems hacky

10:15 borkdude: oh man why didn't I think of that; wonderful

10:15 hyPiRion: #(BigInteger. %) ?

10:15 Not really hacky

10:16 lvh: (edn doesn't do ratios but whatever)

10:16 hyPiRion: okay, if that's fine that's fine :)

10:16 hyPiRion: lvh: I agree that it sort of looks hacky, but it's really the only way to make it into a function =)

10:17 borkdude: lvh: https://gist.github.com/borkdude/cf0073190b8d2ff91260

10:18 llasram: (doc biginteger)

10:19 clojurebot: "([x]); Coerce to BigInteger"

10:19 llasram: lvh: ^^

10:19 For specifically BigInteger

10:19 lvh: And I wrote https://github.com/llasram/method-fn

10:20 borkdude: function wrapping is idiomatic

10:20 llasram: lvh: Nobody else is using it yet, but now that Java 8 is going to have method and constructor references which produce automatic lambdas, I think it's time :_)

10:24 lvh: llasram: ooh!

10:25 is it bad form to have top-heavy let clauses?

10:25 It seems to me like I end up writing a big bunch of bindings that makes me a bunch of functions/values that do/are what I awant, and then a relatively small body of the let.

10:26 llasram: lvh: Not necessarily. If you're binding a lot of values you then refer to only once, you can probably make more frequent use of the threading macros (->, ->>, etc) instead

10:27 lvh: llasram: https://gist.github.com/lvh/43d713e6812503f8fb5e

10:27 I don't think that counts but I don't know ->(>)? well enough to judge

10:29 llasram: lvh: That looks completely reasonable structurally

10:29 borkdude: lvh I think your code is fine too

10:31 lvh: great; thanks :)

10:37 abaker: is Stuart Sierra's "system workflow" still the best game in town for managing application state? i.e. this: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

10:40 or I guess the area of dependency injection with config management is also blossoming: https://github.com/stuartsierra/component

10:47 stuartsierra: abaker: Yes, 'component' builds on the ideas in 'reloaded'

10:47 abaker: stuartsierra: cool, thanks

10:48 wei__: my API requests via clj-http are about 10x slower than the same requests in the browser. any ideas why?

10:57 lvh: I'm trying to parse dates with clj-time, but I want LocalDates, not DateTimes

10:59 and apparently you can't just use a custom formatter for format-local-time

11:00 wait, .local is a red herring; I want .format

11:02 ohcibi: can someone explaine to me why I get Long cannot be casted into Keyword here https://gist.github.com/ohcibi/9053150?

11:11 ceterumnet: howdy all

11:11 I have an interesting problem I can't figure out - I'm curious if anyone can shed any light on this: https://gist.github.com/ceterumnet/7b6bfc55874a26160941

11:12 I am wondering if this is a compiler bug or if I am just not understanding bindings (I suspect the latter)

11:17 fredyr: ceterumnet: what's the reason for using with-binding instead of binding?

11:17 ceterumnet: fredyr: no reason - I've tried both

11:18 fredyr: using binding, I don't think you have to do #'symbol

11:18 ceterumnet: fredyr: yea

11:18 fredyr: like the example here http://clojuredocs.org/clojure_core/clojure.core/binding

11:18 ceterumnet: still doesn't work

11:20 hyPiRion: ceterumnet: map is lazy, and is evaluated outside of the binding

11:20 try to replace map with mapv

11:20 fredyr: hyPiRion: nice catch

11:20 ceterumnet: hyPiRion: thanks!

11:20 hyPiRion: that was my error

11:22 ohcibi: this is crazy.. I only get this error when I return a set that contains two vectors with the same size? what is wrong with that?

11:22 https://gist.github.com/ohcibi/9053150?

11:24 hyPiRion: what error?

11:25 ohcibi: hyPiRion: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Keyword

11:25 lein midje :autotest even reports two failed checks although there is only one..

11:26 TEttinger: ohcibi, do you get a line number for the error?

11:26 ohcibi: TEttinger: no, there is a long stacktrace which eventually mentions the test-file but with the line that starts with (facts ...

11:27 when i return a set with vectors of different size I get a normal "expected value is not the same as the actual one" error message from midje..

11:29 oh

11:29 and when I return a set with vectors that contain both numbers its also working normally

11:34 hm seems to be a bug with midje

11:34 or lein-midje

11:42 sdegutis: Hi.

11:42 Does anyone in here deploy a Ring app to an EC2 server?

11:44 `cbp: ~anyone

11:44 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

11:45 Baraius: I did a little compojure app

11:45 Wasn't anything particularly special about EC2.

11:47 sdegutis: If so, what tools do you use for deployment? Do you use something like Chef, or something else? How do you handle automating EC2?

11:48 Baraius: I have done it both ways.

11:49 Vanilla AMI + Chef and configured AMI.

11:50 The latest one has been very configured AMI. That makes ASGs easier. I also have it setup to pull the latest version of the code from a named EC2 bucket on startup. "Pull" deploys if you will.

11:50 It has worked very well so far.

11:51 sdegutis: Oh hmm, we're not even using ASGs or AMIs.

12:24 danneu: I switched from Heroku to Linode for the beefy CPU.

12:24 It's just too good.

13:34 muhoo: insane idea: writing an alternative to freind that uses core.async go blocks instrad of all that mind-melting catching and throwing and redirecting

13:35 also, possiby, alternative to liberator in core.async

13:35 instead of callback hell

13:36 please tell me why the stupidest idea ever and it could never work

13:38 cemerick: ^

13:40 sritchie: dnolen_: seeing a bunch of "Cannot read property 'firstChild' of undefined" error messages coming out of om when I try to transact! within IWillMount

13:40 aphyr: muhoo: synchronization primitive on every transition between components imposes more overhead than fn calls.

13:41 (might be small for liberator, I dunno)

13:41 sritchie: dnolen_: pushing the code to github, after a little more investigation -

13:41 aphyr: but IIRC channels are require at least one CAS, so you might have to worry about unnecessary contention

13:42 sritchie: dnolen_: actually, I did have one more high level question about how to organize an app so I don't thrash the dom

13:42 cemerick: muhoo: you mean for characterizing the authentication of a request among multiple different workflows?

13:43 sritchie: dnolen_: I'm building a stopwatch, so one piece of the pieces of state tracks the current time; I have a go block that updates it every 10ms

13:44 at that same level of the atom, alongside :stopwatch-time, I have a :results key, with a vector of results; when the user hits a mark button, I add an entry to :results

13:44 muhoo: cemerick: i meant doing a wofkflow as a workflow, faux-linear inside a go

13:44 sritchie: is it correct that om WON'T re-render the whole list of results every time the stopwatch is updated?

13:44 (provided I'm careful about only passing that results cursor down into the "results" table component)

13:45 strangely, that go block runs three times for every "firstChild" error

13:45 cemerick: muhoo: "workflow as a workflow"?

13:46 muhoo: instead of all the callbacks, throwing, etc. the whole flow as a linear block, and let go hide the asychrony

13:47 cemerick: muhoo: workflows aren't asynchronous

13:47 aphyr: Agreed; HTTP state machine is definitely a decision tree.

13:48 muhoo: i'm not describing this right. i should mock something up and post it

13:49 i read sritchie's thing on friend + liberator and went, my god, there has to be a way to make this less confusing

13:49 cemerick: muhoo: are you talking about putting the interactions w/ e.g. openid/oauth/etc identity providers into a go block?

13:50 sritchie: cemerick: you could make it much less confusing by exposing the session management stuff, so that users could use that themselves deep in the routes

13:50 like, the interactive form stuff doesn't belong in a middleware

13:50 it belongs in a route

13:50 cemerick: that's one thing that's so confusing, I think… workflows that don't affect the session make sense as overarching middleware

13:51 workflows that DO populate the session belong down in individual routes, like /login, etc

13:52 yedi: "once again, 99% of all disagreements can be divided in to one of two fundamental categories: operating from different definitions or operating from different motivational principals"

13:52 bbloom, i like that

13:52 cemerick: sritchie: friend doesn't presuppose how you construct your ring app; it's a ring library, not a compojure/liberator/etc lib. Providing "routes" (or whatever the analogous construct for the library du jour) isn't really germane.

13:53 sritchie: cemerick: yet the interactive form DOES take a route

13:53 and matches on it inside the workflow, up in middleware

13:53 cemerick: which is confusing for users - "wait, I already have a login handler… so now I have to remember that MINE only gets called after friend, and friend might intercept it..."

13:54 cemerick: you seem really resistant to feedback that friend is confusing

13:54 muhoo: cemerick: i might start with that. it's more of just thrashing to find some way to hide the callbacks and throws. again, english is not the best language, i shoudl mock up what i want the code to look like, then beat it with macros until it actually works that way

13:54 cemerick: sritchie: it takes a URI path; "routes" mean different things in different libs

13:54 sritchie: sure, but it intercepts some URI about the typical routing layer

13:55 it tries to do "routing" on that single URi,

13:55 muhoo: might not actually need too many macros, maybe core.async already has all the tools i need

13:55 sritchie: with no notion of content type

13:55 if the user wants the interactive-form workflow, for example, they probably have a routing layer in place

13:55 (since you redirect to some other route after login)

13:55 muhoo: it's a hard problem. auth is just confusing. there's probably not much that can be done that hasn't already been done, and friend is definitely an improvment over everyone hand-rolling stuff instead

13:55 sritchie: so rather than having them try to intercept that one route in a workflow,

13:56 cemerick: muhoo: well, what I suggested as an interpretation is going to be tough; perhaps impossible given the way oauth/openid negotiation. But it'd be interesting to see if you can pull it off :-)

13:56 sritchie: muhoo: I think the liberator + friend direction is compelling; I'm just not convinced that oauth, interactive form, etc should be done as these throw catch deals in the middleware

13:57 muhoo: but the itch i feel is that i've been using friend since its first release, on several projects, have written and contributed to workflows, and still everytime i look at it i feel lost again.

13:57 ptcek: Any best practices for defining function with following calling patterns?: [par1] [par1 opts] [par1 par2] [par1 par2 opts] ?

13:58 muhoo: sritchie: thanks for that article, by the way. you explained it well.

13:58 sritchie: sure

13:59 cemerick: sritchie: the redirection is always just a URI, either one that you were bounced off of because you weren't auth'd yet or the default landing URI. URI paths != "routes". Subtle, but important since routes mean very specific things in different libraries.

13:59 sritchie: I'm not talking about the redirection

13:59 muhoo: hmm, and it's important to be routing-library-agnostic

13:59 sritchie: cemerick: I'm talking about the intercept of "/login"

14:00 and if you exposed the internal friend tools to manipulate the session.

14:01 muhoo: /login is hard because that's basically route

14:01 sritchie: I think it'd be much easier to get around some of the really confusing workflows like oauth

14:01 cemerick: I've never used liberator, but it seems like a lot of the friend/liberator friction comes out of the latter needing to own/be aware of the entire state transition graph. Without knowing more, it sounds like that would make the compose-handlers-to-build-apps pattern in ring somewhat incompatible in general.

14:01 bbloom: tpope: ok, after using the new cpp behavior for a while, i wanna go back to the old behavior

14:01 tpope: is there a quick vimrc override?

14:01 sritchie: cemerick: did you read that article I wrote?

14:01 cemerick: But I may be mistaken re: liberator.

14:01 sritchie: cemerick: maybe I just need to sit down and implement the stuff I keep talking about

14:01 :)

14:02 cemerick: sritchie: There are no "internal friend tools to manipulate the session". It's just ring sessions, full stop.

14:02 sritchie: you have a function in friend that, on succesful authentication, adds an identity into the session

14:02 correct?

14:02 muhoo: it stores state in the session. it also adds stuff to that session, i.e. identity

14:03 sritchie: cemerick: it's not "just ring sessions", it's a set of functions that manipulate the ring session

14:03 I get that you're not hitting a session store directly

14:03 I've read the entire friend codebase, and I get how it works

14:04 cemerick: here we go

14:04 https://github.com/cemerick/friend/blob/master/src/cemerick/friend.clj#L65

14:04 okay, so it is exposed

14:04 cemerick: sritchie: I think you're talking about make-auth? It's there, it's not even "private". What needs exposing?

14:05 muhoo: anyway, now i feel bad about starting this argument.

14:05 cemerick: muhoo: you didn't start anything :-)

14:05 sritchie: I guess it's not really worth going into - I know you're swamped with other stuff and not too open to changes on this stuff

14:05 muhoo: or restarting it

14:05 sritchie: which is totally fine

14:05 cemerick: sritchie: I'm open to any number of things, but concrete patches > irc hand-waving

14:06 sritchie: cemerick: yeah, sometimes discussion is useful before patches, as the author may have strong feelings for or against certain ideas

14:06 cemerick: I'm bummed that some people find friend confusing, but given the constraints of the space, it's my best effort.

14:06 pbostrom: ptcek: you can't do what you want, but you could either do [[par1 par2]] [[par1 par2] opts] -OR- [par1 opts] [par1 par2 opts]

14:06 muhoo: sritchie: it's confusing, and even when well explained, it's confusing. even when understanding the codebase, it's still confusing. the confusion exists elsewere, deeper, and i'd bet it's in the way state is dealt with and all they asynchrony, which is a point you made in yoru article.

14:06 gah spelling

14:06 cemerick: If someone else wants to totally destroy friend with a better library, I welcome that whole-heartedly. :-D

14:07 sritchie: cemerick: that's not the point :)

14:07 cemerick: I'm happy to do some work to try and make it less confusing, but only if you're interested in that

14:07 and you don't seem to agree that it's confusing

14:07 so, that's the point of the IRC stuff - if you don't think a change is worthwhile, I don't want to push on it

14:09 DomKM: Anyone have experience packaging a JRuby gem with a Clojure lib or know of an example that I could check out?

14:09 muhoo: sritchie: hell, i think it's confusing, and i'm willing to invest a non-zero number of hours on at least trying to come up with somethinc begter, either using or inspired by core.async. chas just said he's cool with that. the question is is it possible? i'm not sure.

14:09 sdegutis: cemerick: for what it's worth, I think Friend is just too specialized for a not-very-common use-case

14:09 cemerick: sritchie: I need to hear concretely what the problem is, and what the solution may be, at least in faint outlines.

14:09 sritchie: did you read the article I wrote?

14:09 sdegutis: cemerick: We went with an OpenID library since that's the only authentication we're going to be using for the foreseeable future.

14:10 muhoo: thinking now, i remember dealing with pam. auth is just a PITA, seems not to matter what domain or language.

14:10 cemerick: sdegutis: do what works for you :-)

14:10 sritchie: cemerick: does that thing I wrote not get across any confusion, even in faint outlines?

14:10 sdegutis: cemerick: Just trying to give helpful feedback.

14:11 cemerick: sritchie: IIRC, I did a heavy skim of it; it was heavy in liberator specifics, which I wasn't looking to sink into

14:11 sritchie: link, pls?

14:11 sritchie: I would say the bulk of it was a description of friend

14:11 cemerick: well, perhaps I did not RC :-P

14:11 sritchie: http://sritchie.github.io/2014/01/17/api-authentication-with-liberator-and-friend/

14:11 here's my "faint sketch" -

14:11 there's this concept of a workflow

14:12 adsisco: anybody managed to get jrebel working with clojure in intellij? it doesn't auto reload when i make changes to a class

14:12 sritchie: some workflows modify the session by intercepting some route, then don't come into play on future authed requests; some of them like the basic auth act on every request;

14:12 some, like oauth actually do their own handshakes and watch multiple routes

14:12 before redirecting back into the user's routing later

14:13 laher*

14:13 it's just very confusing to sort everything out, since it all has to happen in a middleware ABOVE the user's routing later

14:13 layer*

14:14 anyway, if you don't find writing workflows and trying to massage this stuff confusing, I guess we just operate on different planes :)

14:15 I think this could all be cleaned up by having workflows ONLY for stuff like basic auth

14:15 that requires middlewar

14:15 e

14:15 then, you could inject the "unauthenticated handler", etc into the ring request

14:16 and provide functions of request that logged a user in, logged out, redirected to the last URI, etc

14:16 by not trying to do so damned much in the workflow middleware and just providing components, the whole thing would be much less confusing, and you'd still be routing layer agnostic

14:16 (since everything you need is in each ring request)

14:18 cemerick: that count as a faint outline?

14:21 cemerick: sritchie: Perhaps. So you're suggesting that any one-time authentication should be just be a ring handler, and all decisions re: redirections, unauthorized access, etc all be made local to the rest of the app's handlers?

14:22 sritchie: yes, that's right

14:22 cemerick: that allows you to take advantage of you chosen library's constructs for content negotiation, etc

14:22 cemerick: like this, actually: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/signup_and_redirect.clj#L77

14:23 the signup post is a great example

14:25 sdegutis: Are there any Clojure testing libraries that are really obvious how they work internally?

14:27 Like, from the user's perspective, they're obviously just functions that use assertion macros and which get run through a test runner?

14:27 cemerick: sritchie: yeah, that probably would work. FWIW, the biggest motivator of the middleware approach was the (consistent) handling of authorization failures. Getting that without an overarching middleware may be tough.

14:29 sritchie: You should totally build it, but it'd be silly to characterize it as a patch to friend. The model is totally different, the result would be a different library with different "workflows" and a different user-facing API.

14:29 sritchie: you could still define default handlers in the middleware, and access them in the handler

14:29 cemerick: Friend is only ~500 LOC, so an alternative surely wouldn't be much more ;-)

14:29 sritchie: cemerick: :) good point

14:30 yeah, I'll see if I can whip it up soon, would love to run it by you

14:31 cemerick: sritchie: I don't know that it's a net win in terms of complexity; instead of throwing control, you're inverting that into fn calls to handlers hanging off of request maps. It'd basically be the same number of different things to keep track of, just accessed and used differently.

14:32 If you can manage to eliminate middleware entirely, and people are happy with the result, then I'll be behind it 100%.

14:35 jergason: how do i specify java maven dependencies in my project.clj? the leiningen tutorial mentions that a syntax exists but doesn't say what it is

14:36 amalloy: jergason: same as you specify clojure dependencies. they're not different

14:37 jergason: amalloy: it refers to a "Maven format"

14:37 TravisD: Is the main purpose of loop/recur to define recursive processes without needing to put it into a named function?

14:37 amalloy: jergason: have you successfully written a project.clj that contains a dependency? like :dependencies [[org.clojure/clojure "1.5.1"]]?

14:37 jergason: yes indeed

14:37 amalloy: TravisD: yes

14:38 jergason: that is the maven format

14:38 TravisD: amalloy: Cool, thanks

14:38 amalloy: tada!

14:38 jergason: amalloy: magical!

15:12 technomancy: sdegutis: I've heard "expectations" scores high on the "not too much magic" scale

15:13 sdegutis: The most magical part about it is that it places assertions at the top-level of a file.

15:13 I don't know why but that makes me somewhat nervous.

15:13 technomancy: haven't tried it myself

15:13 sdegutis: Otherwise I like its simple assertion syntax.

15:14 Maybe clojure.test is the simplest one. I kind of get how it works now, it just stores the test fn in :test metadata.

15:14 technomancy: there is a bit of unnecessary magic

15:15 but virtually everyone knows how it works

15:31 gfredericks: I wrote a macro to help write a function with 12 nested loops, and the compiled version involves 4108 class files.

15:31 I was expecting one.

15:32 Bronsa: you should look at how much bytecode a single doseq generates.

15:32 gfredericks: I'm not using doseq

15:32 SegFaultAX: gfredericks: Wut.

15:32 gfredericks: Can you share this magnificent beast?

15:33 gfredericks: sure one minute

15:34 SegFaultAX: gfredericks: Also, how slow is this thing?

15:35 hiredman: gfredericks: the compiler will turn some (all?) nested loop/recurs in to fns

15:35 basically bcause nested loop recurs in the jvm bytecode are a pain

15:35 gfredericks: https://www.refheap.com/40783

15:36 hiredman: that is interesting. still odd that I seem to get an exponential number of fns

15:36 compiling the last form in that paste takes some 30sec on my slow vm

15:36 SegFaultAX: gfredericks: Oh man, that's awesome. Thanks.

15:36 Haha, seriously?

15:36 gfredericks: yep

15:37 this is mostly just an experiment in how well I can optimize numeric clojure

15:37 I'm curious if this class blowup is a significant perf hit

15:37 SegFaultAX: Me too.

15:37 hiredman: gfredericks: it seems likely that the best way to omptize it is to generate the simplest bytecode possible for the jvm to jit

15:38 gfredericks: hiredman: I figured loops & arithmetic would do it, but apparently nested loops are bad?

15:38 hiredman: gfredericks: I would not recommend them

15:38 SegFaultAX: Oh Quarto is a game? Never played it before but reading the wiki on it.

15:39 gfredericks: SegFaultAX: I think? I just had another guy describe it to me for the sake of the stalemate-counting problem

15:40 hiredman: this will be fun to flatten :)

15:40 hiredman: gfredericks: my guess would be with the nested loops as fns you'll be allocating fns at such a rate it will dominate the runtime

15:42 SegFaultAX: gfredericks: Interview?

15:42 Because that'd be a pretty intense interview question.

15:42 gfredericks: SegFaultAX: no just having fun

15:42 I'm not good at interviewing

15:56 Bronsa: hiredman: what problems are you talking about re: nested-loops? In tools.emitter.jvm I do fine without wrapping all loops in a ^:once fn*

16:00 hiredman: Bronsa: right, I am saying the once fn is a way to avoid the pain of trying to generate correct bytecode for nested loops

16:00 it effectively unests the loops

16:00 clojurebot: excusez-moi

16:01 Bronsa: hiredman: ah, ok. I thought there was some problem I underlooked

16:02 hiredman: the jvm has restrictions on how you can use goto, something about the stack depth always having to be the same at each point if I recall

16:03 Bronsa: hiredman: honestly my understanding was that the :once fn* thing is needed only for locals-clearing purposes

16:05 hiredman: the ^:once is for that, but the fact that nested loops are hoisted out in to fns at all is because, and this is me guessing, rich discovered it was a pain in the ass / impossible to do the nested loops as nested loops

16:08 Bronsa: hm, I have yet to run into problems with nested loops but I'll do some more testing to see if I need to wrap loops in a fn too.

16:12 amalloy: SegFaultAX: quarto is a neat game. one of my early programming projects was to write a quarto ai

16:12 sadly the code is since lost to the mists of time

16:14 even with like a two-ply search whose heuristic was "make the board as complicated as possible so the human will get confused" beat me 90% of the time

16:20 TimMc: So, I've been writing a tracking and analysis program for my sourdough starter. (I'd like to know at any given time how much of each flour remains, for both reproducibility and allergen reasons.)

16:20 Here's the file format I've come up with so far, because I'm a horrible yak-shaver: https://gist.github.com/timmc/9059052

16:20 (Because obviously it is very important that the history file format be general-purpose...)

16:26 gfredericks: "...and all that remained was a smoldering pile of shaven yaks."

16:26 brehaut: TimMc: why not just use edn rahter than a mash up of columns and json?

16:29 TimMc: brehaut: Hmm, I should include an apologia.

16:29 brehaut: haha

16:29 maybe

16:30 TimMc: What it comes down to is that I kept wanting to use the key :type but it meant different things.

16:30 Type of entry, sub-type of entry, type of ingredient, type of measurement...

16:30 brehaut: TimMc: i was thinking you'd still have positional items

16:31 event change environment temperature {"scale": "C", "value": 25} would just become (event change environment temperature {"scale": "C", "value": 25})

16:31 (or a vector if you prefer)

16:31 TimMc: hmm

16:32 brehaut: easy to parse, and then you can destructure it in a multimethod easily too

16:32 TimMc: Or (to use JSON for a minute) {"type":["event", "change", "environment", "temperature"], "scale":"C", "value":25}

16:32 brehaut: sure

16:33 TimMc: where "type" is the only restricted top-level key

16:33 brehaut: btw, high five for scale: "C"

16:33 TimMc: :-)

16:34 I've been trying to use centigrade in everyday life.

16:35 brehaut: thats got to confuse people

16:35 TimMc: It does alarm people when I mention that the weather report predicts the high will be "negative two... celsius".

16:35 brehaut: haha

16:35 AlainODea: brehaut: except everywhere other than the US ;)

16:35 brehaut: AlainODea: i presume that americans mostly come into contact with other americans ;)

16:36 AlainODea: brehaut: a valid presumption as most Canadians do the same :)

16:36 amalloy: except on the internet, where we are constantly beset by strangers who are confused why we use dumb units instead of sensible ones

16:37 brehaut: i prefer to buy milk by the hogshead. dont you‽

16:37 AlainODea: amalloy: and we get caremad about it too :) Which reminds me, why not use Kelvin? ;)

16:37 * TimMc *really* would prefer Rankine

16:38 AlainODea: How many furlongs do you commute each day?

16:38 amalloy: i prefer to use Cromnians, which will be the standard unit a hundred years from now, just because it confuses people when i talk about degrees C

16:38 brehaut: haha

16:39 its 30 degrees by crom!

16:39 TimMc: (Rankine is an absolute scale, but has the same size "degree" as Fahrenheit.)

16:41 gfredericks: is this reminds me about that one thing

16:42 there's a kind of algebraic structure that is curious because you can subtract things but not add them

16:42 but I can't remember its name

16:43 classic example: points in space

16:44 brehaut: not a monoid then

16:44 gfredericks: right

16:44 this is not very googleable

16:45 TimMc: brehaut: So you think the one-distinguished-top-level-key approach is good?

16:45 brehaut: TimMc: if theres not an obvious name, i think positional is probably nicer?

16:46 TimMc: Positional is easier to process via non-JSON tools, such as eyeballs.

16:46 brehaut: yeah

16:46 TimMc: I wonder if there are any tools that can parse JSON from the end instead of the beginning.

16:46 brehaut: i think if your string of symbols is arbitrarly length id do [["foo" "bar" "baz"] {…}]

16:47 or perhaps [["foo" "bar" "baz"] {…} … {…}] if you want to have multiple args

16:47 (not that its necessary)

16:47 TimMc: Multiple args can get names in a map.

16:47 brehaut: yeah exactly

16:47 AlainODea: gfredericks: the folks on #haskell have a pretty good hit rate identifying data structures by their properties :)

16:48 brehaut: just depends on the functions you have: if you have existing functions that take args positionally it might be useful

16:48 TimMc: I could drop the outer layer then: ["foo", "bar", "baz", {"some":"data"}]

16:48 gfredericks: AlainODea: I don't think it would typically be considered a data structure

16:48 though maybe it still applies to haskellland

16:48 TimMc: No functions involved.

16:48 gfredericks: I'll go ask

16:48 amalloy: gfredericks: well, neither are monoids and categories

16:48 gfredericks: amalloy: right

16:49 brehaut: gfredericks: when has haskell land ever looked at an obtuse math concept and thought "you know, lets not turn this into code"

16:49 AlainODea: gfredericks: You are correct. I was fumbling for the right term :)

16:50 brehaut: touché. It has merits when you need it and don't want to build it yourself though

16:51 brehaut: AlainODea: im not saying its good or bad, just commenting on the nature of the community

16:51 gfredericks: AlainODea: haha they got it in like 8 seconds: "torsor"

16:51 AlainODea: brehaut: not at all. It's a valid observation.

16:52 gfredericks: score!

16:52 brehaut: i had one of those once, but it gradually ran out of wheels

16:52 gfredericks: this wikipedia article has very little in it that I understand

16:53 brehaut: what‽ who _doesnt_ understand principle homogeneous spaces!

16:54 gfredericks: clojurebot: who |_doesnt_| understand principle homogenous spaces!

16:54 clojurebot: Alles klar

16:54 gfredericks: clojurebot: who?

16:54 clojurebot: who _doesnt_ understand principle homogenous spaces!

16:54 gfredericks: someday I will have taught clojurebot half of all he knows

16:56 oh dates are another nice torsor example

16:56 brehaut: the fruit or the unit of time?

16:56 gfredericks: the romantic/social event

16:58 I guess if space is an example it makes sense that time would be too

16:59 TimMc: I don't buy this whole torsor thing.

17:01 Oh, wait, yes I do.

17:03 * gfredericks sells TimMc a torsor

17:03 TimMc: brehaut: OK, so this still has the property that you can't tell where the tag ends, but at least you can parse the entire line without having to understand it.

17:04 (In ["foo", "bar", "baz"], is "baz" the payload or the end of the tag?_

17:04 brehaut: yaeh and you dont have to mix parsers

17:04 TimMc: Thanks for the sanity check.

17:04 gfredericks: We've already got one!

17:05 brehaut: TimMc: np

17:07 TimMc: https://gist.github.com/timmc/9059052 updated, and makes more sense now.

17:10 amalloy: gfredericks: you're teaching clojurebot brehaut's bad spelling habits :P

17:10 (should be principal, not principle)

17:11 brehaut: sigh

17:12 gfredericks: ~spelling

17:12 clojurebot: I don't understand.

17:13 brehaut: me either clojurebot, me either

17:17 DomKM: How do I represent a non-standard dependency within the project.clj? Specifically the dependency has a "type" attribute. https://gist.github.com/daicoden/de146f45c565b5e3a3f4#file-pom-xml-L112

17:18 I've tried :type "gem" (like :exclusions ...) but it is ignored.

17:19 stuartsierra: DomKM: That's not a standard Maven dependency. It looks like your pom.xml has a special plugin to handle "gem" dependencies. That won't work in Leiningen.

17:21 DomKM: stuartsierra: is there any way to use :pom-addition to make it work? It appears that Leiningen does support plugins https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L381

17:22 stuartsierra: DomKM: As far as I know, :pom-addition is only going to add extra XML to the pom.xml file produced by `lein pom`. Then you would still have to run Maven to build your project. Leiningen itself cannot execute Maven plugins.

17:25 DomKM: stuartsierra: Ah, I didn't realize that. Thanks for your help. By any chance do you know how to package a clojure library that depends on a jruby gem? (I figure you might have run into this since Cognitect also does Ruby work.)

17:25 stuartsierra: Sorry, I don't know.

17:26 DomKM: okay, thanks anyway

17:51 scape_: what's a better way/more concise to do this?

17:51 ,(first(map #(% :op) (filter #(map? %) [2 {:op :value1} 3])))

17:51 clojurebot: :value1

17:51 whodidthis: how do i reduce an #inst by 1 hour

17:59 `szx: ,(->> [2 {:op :value1} 3] (filter map?) (map :op) first)

17:59 clojurebot: :value1

17:59 `szx: scape_: ^

17:59 scape_: `szx: thanks! that is better

18:00 pbostrom: whodidthis: clj-time is a nice library, but you might have to handle converting between java.util.Date and JodaTime dates

18:01 hyPiRion: ,(first (for [e [2 {:op :value1} 3] :when (map? e)] (:op e)))

18:01 clojurebot: :value1

18:01 scape_: interesting alternative

18:12 TimMc: &(->> [2 {:op :value1} 3] (filter map?) first :op)

18:12 lazybot: ⇒ :value1

18:13 TimMc: scape_: ^ the golfing continues

18:13 (No need to use map if you are only going to take the first element of the sequence.)

18:15 ticking: &(->> [2 {:op :value1} 3] (some map?) :op)

18:15 lazybot: ⇒ nil

18:15 ticking: damn ^^

18:16 TimMc: $findfn map? [2 {:op :value1} 3] {:op :value1}

18:16 lazybot: []

18:16 pbostrom: &(([2 {:op :value1} 3] 1) :op) ;probably not general enough

18:16 lazybot: ⇒ :value1

18:16 TimMc: haha

18:17 Or if you want the most concise answer...

18:17 hyPiRion: ,(some #(if (map? %) (:op %)) [2 {:op :value1} 3])

18:17 clojurebot: :value1

18:17 TimMc: &:value1

18:17 lazybot: ⇒ :value1

18:17 ticking: yes I

18:17 hyPiRion: TimMc: I was about to say ##((constantly :value1) [2 {:op :value1} 3])

18:17 lazybot: ⇒ :value1

18:17 ticking: yes I vote for hyPiRion

18:18 TimMc: Yeah, I yield -- that actually takes the form of a function. :-P

18:19 ticking: there should be a higher order function that takes a pred? and turns it into a function that returns identity or nil

18:22 `szx: https://www.refheap.com/40864 - clean up my mess please?

18:23 sdegutis: oh boy

18:23 `szx: what are the inputs/outputs

18:25 `szx: sdegutis: line-segments is a path in the form of line args suitable for quil's line function, i.e. [[x1 y1 x2 y2] [x2 y2 x3 y3] ...]

18:27 sdegutis: segments-lengths are the magnitudes of each vector, cumulative-lengths are the cumulative lengths of the path up to that segment

18:27 ticking: hyPiRion, TimMc: ha suck it.

18:27 ,(some :op [2 {:op :value1} 3])

18:27 clojurebot: :value1

18:28 TimMc: heh

18:28 hyPiRion: ticking: ##(some :op [2 #{:op} {:op :value1} 3])

18:28 lazybot: ⇒ :op

18:28 TimMc: or ##(some :op [2 {:op nil} 3])

18:28 lazybot: ⇒ nil

18:28 TimMc: or ##(some :op [2 {:op nil} 3 {:op 5}])

18:28 lazybot: ⇒ 5

18:29 ticking: hyPiRion, TimMc: yeah if fails fabulously ^^ oops

18:29 TimMc: what was the initial requirement?

18:30 TimMc: The original was (first(map #(% :op) (filter #(map? %) [2 {:op :value1} 3])))

18:30 hyPiRion: find the first value in a sequence which is a map, and return the value for the key :op

18:31 ticking: ah yeah then I just golfed into a sand pit ^^

18:31 TimMc: :-P

18:34 brehaut: btw, for your golfing needs #(or :c %&) is shorter constantly

18:35 ticking: brehaut: do characters count or the nodes in the code tree ^^?

18:35 brehaut: characters of course!

18:35 wasnt this game invented in perl?

18:36 ticking: brehaut: quite possibly, I just thought, nodes might be more lispy ^^

18:37 brehaut: secondary reason: characters makes golfed solutions more tweetable

18:37 ticking: brehaut: good point

18:42 damn having a new mac pro makes me really wish there was a up to date opencl lib ^^

18:45 seangrove: Is there a way to have a catch-all for a defmulti without the defmulti knowing what's implemented?

18:45 hyPiRion: seangrove: :default ?

18:46 (defmethod my-method :default [args] body)

18:46 seangrove: hyPiRion: Ah, that's exactly it. Thank you

18:46 hyPiRion: great :)

18:46 seangrove: I nearly had all the right words, but couldn't quite get google to answer me

18:51 TimMc: &(clojure.string/split "banana" #"an")

18:51 lazybot: ⇒ ["b" "" "a"]

18:51 TimMc: &(clojure.string/split "banana" #"na")

18:51 lazybot: ⇒ ["ba"]

18:52 TimMc: Why is the second not ["ba" "" ""]?

18:52 &(clojure.string/split "nanabanana" #"na")

18:52 lazybot: ⇒ ["" "" "ba"]

18:53 amalloy: brehaut: #(do %& :c)

18:53 brehaut: ah true

18:53 amalloy: not actually shorter, but a slight bit less awful

18:54 TimMc: and allows for falsey values

18:54 amalloy: TimMc: ##(clojure.string/split "banana" #"na" -1)

18:54 lazybot: ⇒ ["ba" "" ""]

18:54 TimMc: *sigh*

18:54 amalloy: split's default behavior is to discard trailing separators

18:55 so *obviously* a negative number means to not discard them. any fool can see that's the right API

18:55 TimMc: Thank you.

18:55 amalloy: java's string APIs are just bizarre

18:56 TimMc: Filing a useless JIRA to either note that clojure.string/split passes this behavior through... or to fix it.

18:57 ticking: imho this should be fixed otherwise it has to be ported to all the other languages, urgh

18:57 amalloy: TimMc: neither will happen. this behavior has been discussed dozens of times in this very irc channel

18:58 ticking: amalloy: really? so clojurescript just emulates it?

18:58 amalloy: huh?

18:59 i don't know how you discerned anything about cljs's behavior from my statement

19:00 however, i do see https://github.com/clojure/clojurescript/blob/master/src/cljs/clojure/string.cljs#L72-L79

19:02 and the impl does look like it's working hard to mimic java's behavior

19:03 seangrove: sritchie: How did you end up handling timer elements with React?

19:09 ticking: amalloy: yeah that seems to be the logical consequence, this seems really horrible though

19:09 amalloy: I would definitely expect such behavior in clojure.java.string, just not in clojure.string

19:10 amalloy: i mean, clojure is hosted. you either have to implement everything yourself, or live with the fact that there are differences based on where you're running

19:10 ticking: yeah but I think it should be clear what parts are hosted, and what parts are abstracted

19:18 shaungilchrist: I am curious if anyone is digging into the core.async GC issues in chrome (e.g. having channels stick around w/ their retaining tree pointing to state machine internals)

19:30 michaniskin1: i'm using the cljs compiler but not in lein-cljsbuild. i'm seeing ~3 sec incremental compile times when i used to see < 1 sec. are there some things i should look at to speed it up?

19:35 tpope: bbloom: I assume you could nmap <buffer> cpp cpab in after/ftplugin/clojure.vim

19:48 ticking: wow jocl (java opencl bindings) has highest good project to bad-readme ratio I've ever encountered http://cl.ly/image/3D05320q3Y2S

19:48 It's ascii art even has a rendering bug in my browser

20:21 holo: hi

20:23 I need to push a jar to clojars using scp. no one ever pushed this one, so I guess it will be created in a canonical group. this library isn't mine, so I guess it should be better to put it in my own group. how do I do it with scp?

20:24 bbloom: tpope: unfortunately not, :scriptnames suggests that gets loaded, but no effect. if I run that nmap command manually, it works though

20:27 tpope: presumably setup_eval is overriding that?

20:29 tpope: i just hacked the fireplace.vim file directly, but if you've got a better idea... i'm still terrible at vim script. thanks!

20:29 holo: oh I get it.. the group is in the pom!

20:39 bacon1989: so I was wondering, how many of you tried Om with clojurescript? I'm having a hard time figuring it out

20:39 should I try a few react tutorials first, and then try and get my head wrapped around Om?

20:41 Tolstoy: bacon1989: I think it's easier than you imagine, though dnolen's examples tend to be ... compressed.

20:43 bacon1989: Tolstoy: I guess i'll have to start looking into it again

20:43 Tolstoy: I think you can go a long way without using all that "component state" thing.

20:45 It's a bit confusing. There are "properties" and "state", and there's the values you pass in to the function. But "properties" are really the "app state" and "state" is really the component's local stat?

20:45 Oy.

20:46 I ended up just implementing all the interfaces and logging all the parameters, and then I could understand the docs. But I've since forgotten again. :) Ah, the memory of a hobbyist.

20:52 shriphani: anyone care to explain why this happens? https://www.refheap.com/40997

20:52 bruceadams: i'm struggling to write a Clojure function that takes a Java class as an argument and creates an instance of that Java class. The "new" special form seems to demand the actual class name. I haven't found a way to to use a var containing a reference to the class.

20:53 qbg: bruceadams: use reflection

20:53 bbloom: bruceadams: new will compile to an actual constructor call

20:54 bruceadams: yeah, what qbg said

20:54 shriphani: seqs can't be used as key value pairs

20:54 shriphani: they need to be vectors ?

20:55 bruceadams: i'm using reflection for some field stuff, not sure how to talk about constructors in reflection land (looking...)

20:55 shriphani: any particular reason ?

20:55 bbloom: shriphani: they need to implement java.util.Map$Entry

20:55 qbg: bruceadams: Do you have the class object?

20:55 bbloom: shriphani: what would (val (list "some" :long 'list)) be?

20:55 bruceadams: qbg: yes

20:56 qbg: http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getConstructor(java.lang.Class...)

20:56 or http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#newInstance()

20:56 If you want to invoke the ctor that takes no arguments

20:56 shriphani: ok nvm I see why

20:56 bbloom, thanks

20:58 qbg: bruceadams: Does that help?

20:59 bruceadams: qbg: pretty sure that'll work, yes. Thanks!

20:59 qbg: If you use .getConstructor, last time I checked clojure didn't handle varags nicely, so you have to pass it in as an array

21:02 bruceadams: qbg: seems kind of heavy, but will definitely work. i was trying to create a macro wrapped around Clojure's "new" special form, trying to get the class name in place. i got half-way there, then got stuck. (never wrote a macro before, which didn't help.)

21:02 qbg: Java is heavy :p

21:02 You're writing a macro?

21:02 bruceadams: yup. mostly much lighter with Clojure as the driver

21:03 qbg: Don't you have the class name available at compile time?

21:03 bruceadams: only as an attempt to get "new" to do what i wanted.

21:03 I do have the class names, about twenty of them, available at compile time.

21:04 I want a single Clojure function to be able to create instances of any of those twenty Java classes.

21:04 qbg: macros aren't that magic. Now if you used eval on the other hand :p

21:04 TimMc: amalloy: Neither will happen, but I feel the need to lodge protest, at least.

21:04 bruceadams: eval wants a top-level var, not a local (such as a function formal argument).

21:04 (which is where I got stuck)

21:05 qbg: You could create a function on the fly using eval, but reflection is the right way to go here

21:05 bruceadams: macros aren't magic! I'm sooo disappointed!

21:05 qbg: Connecting to your database at compile time and generating boilerplate code is just cool, not magic :p

21:07 bruceadams: qbg: thanks for the help. reflection had not crossed my mind (even though I'm already using it for other stuff).

21:12 akurilin: Quick question: I like threading functions, but I also like using destructuring of parameters to avoid having to care about parameter ordering

21:12 Can I have my cake and eat it too?

21:12 bbloom: akurilin: you mean like threading a map through a list of function calls? sure.... go for it

21:13 akurilin: As in, threading relies on placing the threaded piece of data at the beginning or end of the list of arguments, but I'm looking for more of an assoc instead.

21:14 bbloom: akurilin: you'll have to be clearer than that

21:14 akurilin: Or is the common pattern to always leave the fist/last param by itself and keep the rest of of the list of arguments as a destructured map?

21:14 when threading.

21:51 quizdr: i'm a little confused about the relationship between def and set!. shouldn't i be able to set! a var defined with def?

21:52 frozenlock: I'm having some trouble with logic.core. I want to make a function to get the intersection of two lists. Here's what I have: https://www.refheap.com/41077

21:53 bob2: quizdr, set! is for java interop, right?

21:53 noonian: quizdr: i thought that too from how scheme's set! works

21:54 bob2: frozenlock, the set module has an intersection method, but not sure how your question relates to core.logic

21:54 noonian: quizdr: you can only set! dynamic vars that have been bound with (binding [*dyn-var* true] ...)

21:54 frozenlock: Here's the problem. With ---> (run 5 [q] (intersectiono [:bob :input :test] [:input :test] q)), I get this result: ([] (:input) (:test) (:input :input) (:test :input))

21:55 I was expecting to get only (:test :input)

21:55 quizdr: noonian ah i see

21:56 frozenlock: bob2: thanks, I know that. I just want to practice my logic.core skills :-p

22:09 RMacy: quizdr did you get your question answered?

22:10 quizdr: RMacy yes, thanks

22:11 RMacy noonian answered it above

23:09 amalloy: frozenlock: it's core.logic, by the way

23:22 ddellacosta: ,(* 360 (/ 2 12))

23:22 clojurebot: 60N

23:30 RMacy: ,(inc tired)

23:30 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: tired in this context, compiling:(NO_SOURCE_PATH:0:0)>

23:30 RMacy: &(inc tired)

23:30 lazybot: java.lang.RuntimeException: Unable to resolve symbol: tired in this context

Logging service provided by n01se.net