#clojure log - Aug 25 2014

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

0:02 TEttinger: arrdem: " my two space indented block"

0:03 arrdem, markdown seems to have won in that arena

0:03 arrdem: TEttinger: sure point is that parsing text into indented blocks and paragraphs is dead easy but for stuff like Grimoire where I'm dealing with irregularly formatted but paragraphed text I want a way to bludgeon text into some form that I can machine edit

0:03 * arrdem doesn't want to copy edit all the clojure/core docs by hand

0:04 TEttinger: so adding {:op :indent :width 2 :children [:text] :text " ...} is less work than hand-editing it?

0:05 arrdem: I can build a parser to do that shit for me.

0:05 TEttinger: I'd use nesting to handle :children

0:05 rather than referencing :text twice

0:06 arrdem: what... something hiccup like?

0:06 that'd probably be nicer to hand type at any rate...

0:06 TEttinger: I dunno, my experience with text formatting mostly is limited to complex regexps processing TSVs

0:08 arrdem: hum... this is feeling more involved than a quick one off that belongs in my "random shit" lib...

0:12 TEttinger: this is the extent of my clojure text processing https://dl.dropboxusercontent.com/u/11914692/class-formatter.clj

0:17 rberdeen: what's the right way to check if (seq x) will succeed?

0:19 arrdem: rberdeen: will succeed or does succeed?

0:19 rberdeen: will is impossible without core.typed, does is just a precondition

0:20 unless I missunderstand the question

0:21 jk9357: is clojure a play on the word closure or am i wrong

0:22 TEttinger: jk9357, closure, jvm, clr, yes

0:22 rberdeen: arrdem: I think I was looking for this: https://github.com/clojure/core.incubator/blob/16aed877cdfa24371099b0d13877d2716908cc91/src/main/clojure/clojure/core/incubator.clj#L83

0:22 TEttinger: it was initially intended to target both and be functional (with closures)

0:28 rberdeen: is there anything in clojure.core that will return true for an empty lazy seq or java.util.ArrayList?

0:28 i guess I'm not sure exactly what the common property would be called

0:34 TEttinger: rberdeen: ##(identity true)

0:34 lazybot: ⇒ true

0:34 TEttinger: what do you want it to be false for?

0:35 rberdeen: i'm trying to validate that some input is list-ey

0:38 so arrays, java iterables, vectors, strings, etc would all result in true

0:39 sequable? from incubator looks close

0:39 i was hoping for something that worked in clojure and clojurescript

0:39 is this not a common problem?

0:43 sarcher: TEttinger: thanks for the help, I got what I needed, now just learning more :)

0:47 shekibobo: weirdest thing

0:47 sarcher: what's the best practice for building out a data structure in clojure?

0:47 shekibobo: I have a method that takes two arguments

0:47 sarcher: i'm parsing the xml, but now I need to store it in a 'friendly' structure.

0:48 shekibobo: I changed it to add a third one which is expected to be a vector

0:48 sarcher: like a map or something.

0:48 arrdem: sarcher: I think you'll find it's already in one..

0:48 shekibobo: and now I'm getting a nullpointerexception that I can't track down

0:49 sarcher: arrdem: i guess it is...so i should just pass / use the structure as-is?

0:49 arrdem: shekibobo: paste (refheap.com please) or we can't really help

0:49 sarcher: yarp

0:49 TEttinger: rberdeen: sequential?

0:50 (doc sequential?)

0:50 clojurebot: "([coll]); Returns true if coll implements Sequential"

0:50 TEttinger: ,(sequential? (java.util.ArrayList.))

0:50 clojurebot: false

0:51 TEttinger: ,(#(and (seq %) (empty? %)) (java.util.ArrayList.))

0:51 clojurebot: nil

0:52 TEttinger: ,(#(and (seq %) (empty? %)) [])

0:52 clojurebot: nil

0:52 TEttinger: ,(#(and (seq %) (empty? %)) [1])

0:52 clojurebot: false

0:52 TEttinger: hm

0:52 rberdeen: anything with (seq) in it won't work, because

0:52 * rberdeen ,(seq 1)

0:52 TEttinger: ,(seq (java.util.ArrayList.))

0:52 clojurebot: nil

0:53 TEttinger: ,(seq 1)

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

0:53 TEttinger: oh...

0:54 shekibobo: https://github.com/shekibobo/knapsacker/pull/1

0:55 that's the diff and the error print

0:55 TEttinger: ,(empty? 1)

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

0:56 rberdeen: all the clojure.core functions like seq? and map? seem to restrictive

0:56 ,(= {} (java.util.HashMap.))

0:56 clojurebot: true

0:56 rberdeen: ,(map? {})

0:56 clojurebot: true

0:56 rberdeen: (map? (java.util.HashMap.))

0:56 ,(map? (java.util.HashMap.))

0:56 clojurebot: false

0:59 grimoire: ~cols

0:59 clojurebot: Cool story bro.

0:59 grimoire: ~colls

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

0:59 TEttinger: hm, you can check the source here, rberdeen: http://clojuredocs.org/clojure_contrib/clojure.contrib.core/seqable_q

0:59 arrdem: rberdeen: Clojure's type predicates are famously trash

1:00 rberdeen: TEttinger: yeah, i guess I am just copying that function

1:01 shekibobo: updated the diff to be a little more conservative. stack trace from failure is in the comments: https://github.com/shekibobo/knapsacker/pull/1/files

1:01 TEttinger: it won't likely work on cljs, since it uses java classes I think

1:01 rberdeen: although it has since moved from clojure.contrib.core to core.incubator

1:02 thanks ClojureDocs from 2011

1:03 TEttinger: thanks for the help

1:03 TEttinger: no prob

1:03 I think arrdem may be better to ask :)

1:06 arrdem: TEttinger: heh clojurescript is not my forte

1:06 JVM clojure weirdness... maybe.

1:08 shekibobo: all I'm doing is passing the vector of items into the function and all instances where it is called. Before it was calling a hard-coded method to get the collection

1:09 lkjggg: Hey, where can I find good tutorials for clojure?

1:09 shekibobo: now I pass the items so that they can be retrieved in what I thought would be a safer way, and it should be working fine

1:09 but I get a NullPointerException on line 64 https://github.com/shekibobo/knapsacker/pull/1/files#diff-6262075c1285d0c0dd8d7a191717d811R64

1:10 but it doesn't seem to make much sense to me

1:10 lkjggg: http://www.braveclojure.com/ << this one was pretty cool

1:11 TEttinger: lkjggg: http://learn-clojure.com/ might be good to start too

1:13 shekibobo: motherF*****

1:14 so why doesn't (get things index) work if it's a list?

1:14 Isn't that part of the collections interface?

1:15 I have to explicitly use (get (vec things) index), otherwise I just get a null

1:15 arrdem: nth, don't vec it

1:15 shekibobo: nth

1:15 ok

1:15 arrdem: http://grimoire.arrdem.com/1.6.0/clojure.core/get/

1:15 http://grimoire.arrdem.com/1.6.0/clojure.core/nth/

1:17 shekibobo: arrdem: thank you, I've been tearing my hair out for the past two hours trying to figure this out

1:18 arrdem: shekibobo: :/

1:19 shekibobo: sorry about that... this is one of those abstraction weirdnesses of clojure. Vectors are indexed, because they are potentially lazy/infinite Sequence are not indexed in general. hence your issue.

1:19 shekibobo: yeah, I remembered reading something about them being different, but didn't remember seeing nth

1:19 arrdem: meh I need to roll the next version of Grimoire at some point

1:52 dawkirst: for a newcomer (coming from Ruby), do I read Programming Clojure or Clojure Programming (or both)?

1:52 seangone: You'll get different answers from different people.

1:53 Personally, I prefer the O'Reilly book but they're both good.

1:54 I suspect most Clojurians have multiple books :)

1:58 * beamso prefers the o'reilly book as well

2:04 Balveda: Evening

2:04 Anyone on?

2:06 seangone: yeah, some of us are Balveda :)

2:07 Balveda: cool, alright

2:07 I have something that's pretty dense to me

2:07 I've got this function I'm trying to make

2:07 (defn iterate-over [map fnc & args]

2:07 "Takes a map, a function, and arguments to apply to the function. Applies the function to the map, iterating over it."

2:07 (loop [m map

2:07 n nil]

2:07 (if (not= (count m) 0)

2:07 (recur (rest m) ((into n (apply fnc (first m) args)))))))

2:07 Of course it's a bit of a mess right now, but I was wondering if I could get any tips to make it work

2:09 seangone: Balveda so fnc takes a pair (key and value) and optionally other args?

2:10 Balveda: The idea is that you'd have a map you're feeding iterate-over with, and you're giving it a function and optional arguments to apply

2:10 fnc would take the first item of this map, and apply args

2:11 Then the next map you're giving it is the rest of the map

2:11 Without the first

2:12 huh

2:12 I think I fixed it

2:12 seangone: Balveda maps aren't ordered so it's not clear what you're trying to achieve here...

2:14 Your fnc only operates on each key/value pair (plus optional args)... are you trying to get a map back?

2:15 Balveda: Oh, should've specified

2:16 Usually what I'm working with is vecs of maps

2:16 seangone: so does iterate-over take a vec of maps, or a single map?

2:16 dawkirst: seangone, beamso thanks :)

2:16 Balveda: [{"dat1" 1 "dat2" 2 "dat3" 3} {"dat1" 4 "dat2" 5 "dat3" 6}] example

2:17 seangone: and you want what back? a vector?

2:17 Balveda: I want to apply a function to the individual maps, and store that

2:17 hence the into

2:17 seangone: store it? what do you mean?

2:17 beamso: store the calculated value back into the map?

2:19 seangone: why not just use mapv? (defn iterate-over [vec-of-maps fnc & args] (mapv (fn [m] (apply fnc m args)) vec-of-maps)

2:19 er... )

2:20 that will give you a vector back

2:20 Balveda: Store the value into a result map

2:20 mapv.. I'll check it out

2:20 TEttinger: it's like map but eagerly returns a vector instead of a lazyseq

2:20 Balveda: ah

2:20 seangone: hmm, if you want to process multiple values and accumulate the results into a single value, you probably want reduce

2:21 Balveda: Doesn't reduce apply a function to the res

2:21 seangone: that's why i asked if you wanted a vector back (vector of results) or a map

2:21 Balveda: duh, yeah

2:21 I'll see

2:21 so

2:22 let's see

2:23 seangone: good luck... i'm outta here for the night...

2:32 Balveda: That seems to have done it

2:32 clojurebot: Cool story bro.

2:32 Balveda: Thanks seangone

2:32 (inc seangone)

2:32 lazybot: ⇒ 1

2:32 Balveda: Stay out of it, clojurebot

2:49 arrdem: (inc sheangrov)

2:49 lazybot: ⇒ 1

2:49 * arrdem checks the logs for the right handle

2:50 arrdem: $karma sheangrove

2:50 lazybot: sheangrove has karma 0.

2:50 * arrdem confuse

2:50 arrdem: (deck seangrov) ;; clean up the mess..

2:50 (dec seangrov) ;; clean up the mess..

2:50 lazybot: ⇒ -1

2:50 arrdem: defuq

3:03 amalloy: arrdem: go home, you are drunk

3:04 arrdem: amalloy: actually haven't been drinking tonight... guess I can't late-night-#clojure on 0% BAC

3:04 * arrdem bed

3:11 kenrestivo: (inc dec)

3:11 lazybot: ⇒ 1

3:11 kenrestivo: (dec inc)

3:11 lazybot: ⇒ 8

3:12 SagiCZ1: (inc inc)

3:12 lazybot: ⇒ 9

3:12 kenrestivo: (inc inc dec dec inc dec inc dec dec)

3:12 lazybot: ⇒ 1

3:13 SagiCZ1: is clojure.core automatically refered?

3:13 kenrestivo: ,(doc ns)

3:13 clojurebot: "([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class .....

3:13 arrdem: SagiCZ1: yes

3:13 SagiCZ1: ,(ns 'xyz)

3:13 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol>

3:14 SagiCZ1: ,(ns xyz)

3:14 clojurebot: nil

3:14 SagiCZ1: ,refer

3:14 clojurebot: #<core$refer clojure.core$refer@1a7ffb3>

3:14 SagiCZ1: but if i use "in-ns" the core is not added right?

3:14 arrdem: correct.

3:14 SagiCZ1: i see

3:14 arrdem: you can also have (:refer-clojure :only []) to include none of core

3:15 SagiCZ1: what use is that?

3:16 arrdem: (ns foo (:refer-clojure :only [])) will also put you in a namespace that doesn't have core referred.

3:16 that's it

3:17 kenrestivo: if you wanted to shadow a bunch of core fn's, i guess

3:17 arrdem: the :only also lets you do selective referral if that's your thing

3:17 yeah

3:17 SagiCZ1: but why would i use "ns" over "in-ns"? if the only difference is that "in-ns" does not include the core?

3:17 arrdem: ns is just a macro providing syntactic sugar for the common case of wanting to include core and other deps

3:18 in-ns is a clojure special form that fucks with the *ns* var to actually change the "current" namespace

3:18 ns is built atop in-ns and some other stuff

3:27 Capt_Morgan: clojurebot: Hello!

3:27 clojurebot: excusez-moi

4:16 otfrom: morning

4:22 SagiCZ1: arrdem: Thank you.

4:24 arrdem: SagiCZ1: happy to help

4:27 Bronsa: arrdem: I can't understand how your with-kwargs macro should be used

4:43 arrdem: the idea was (with-kwargs :foo :bar :baz :quxx (my-shitty-kwargs-fn))

4:43 * arrdem 4am, bed

5:18 hellofunk: what an elegant way to use regex to determine if a string contains only digits? I'm a bit new with re-find and others...

5:21 clgv: ,(re-matches #"\d+" "028937397")

5:21 clojurebot: "028937397"

5:21 clgv: ,(re-matches #"\d+" "02893AA7397")

5:21 clojurebot: nil

5:21 hyPiRion: ^

5:21 clgv: hellofunk: ^^

5:21 hellofunk: thanks guys

5:21 clgv: hellofunk: + or * depends on whether the empty string is allowed as well

5:22 hellofunk: if I wanted to accept digits with a decimal, it would be #"\d+.\d+" ?

5:22 hyPiRion: you'd have to quote the dot

5:22 so #"\d+\.\d+"

5:23 hellofunk: ah

5:23 hyPiRion: but that assumes you always have the dot, and always have digits in front and after it

5:23 hellofunk: oh

5:23 how to make decimal; optional?

5:25 hyPiRion: #"\d+(\.\d+)?" – but now you get back a different type of result

5:25 ,(re-matches #"\d+(\.\d+)?" "028937397")

5:25 clojurebot: ["028937397" nil]

5:25 hyPiRion: ,(re-matches #"\d+(\.\d+)?" "028937397.0")

5:25 clojurebot: ["028937397.0" ".0"]

5:25 hyPiRion: ,(re-matches #"\d+(\.\d+)?" "fo")

5:25 clojurebot: nil

5:26 amalloy: ,(re-matches #"\d+(?:\.\d+)?" "028937397.0")

5:26 clojurebot: "028937397.0"

5:26 amalloy: to get the optional behavior with the original result type

5:26 hellofunk: nice!

5:27 hyPiRion: (inc amalloy)

5:27 lazybot: ⇒ 163

5:33 thesaskwatch: Hi .. I have a question - if core.contrib is now deprecated then where can I find deep-merge-with function?

5:35 Bronsa: thesaskwatch: https://github.com/flatland/useful/blob/48e517a1514ecfed769d17ea9f27041c6db6bdb3/src/flatland/useful/map.clj#L152 should be what you want

5:54 * lvh struggles to remember how syntax-quote works

5:54 lvh: I'm trying to write a macro that compiles down to two defmethods

5:54 llasram: That seems honorable

5:55 What's the struggle re: `

5:55 lvh: I don't think I want syntax-quote, because that means the parameter gets namespace-qualified

5:55 but I'm not sure :)

5:55 llasram: Well, you want to syntax-quote the bulk of most macros

5:55 Any unquoted symbols will generally be passed in as arguments to the maccro

5:56 Or under rare circumstances: ##`[example ~'example]

5:56 lazybot: ⇒ [clojure.core/example example]

5:56 lvh: llasram: Here's what I have: https://gist.github.com/lvh/af778be8644de39506f2

5:57 llasram: which does what I want, *except* that the "request" arguments in the defmethod calls I'm making are getting namespace-qualified.

5:57 (macroexpand '(defstep :a {} (a) (b))) ;; => (do (clojure.core/defmethod icecap.handlers.core/get-schema :a [icecap.handlers.core/request] {}) (clojure.core/defmethod icecap.handlers.core/execute :a [icecap.handlers.core/request] (a) (b)))

5:58 llasram: Right. So the hideous way you shouldn't do it is the trick above, where you unquote-quote the symbol w/in the syntax quote

5:58 The IMHO more idiomatic approach is you change your macro arguments slightly

5:58 And use a gensym

5:58 Here, just a sec

5:58 lvh: llasram: Thanks!

5:59 llasram: So, the thing that came to mind was the gross trick you mentioned

5:59 then I remembered that I *probably* don't actually want that :)

6:00 llasram: lvh: https://gist.github.com/llasram/63b9e84805d3aa9458a9

6:00 lvh: ~'request does indeed do what I asked for, although perhaps that is not what I *want* ;-)

6:00 clojurebot: Ack. Ack.

6:00 llasram: So you can use a gensym for the `get-schema` arg, since the user of the macro never sees it

6:00 Then let them provide their own symbol as a full fntail for the `execute` implementation

6:01 lvh: llasram: Huh. I don't understand how that works; is there a missing [request#] in the second ...

6:01 oooooooh.

6:01 yes yes yes, I see; you're making the parameter decl part of the macro call :)

6:01 llasram: Exactly

6:03 lvh: llasram: thanks a lot :)

6:03 llasram: np!

6:04 lvh: llasram: this will definitely work for now; at some point I would like to add the schema (that's a prismatic/schema) annotation to the parameter

6:04 (there's only one parameter that that thing can ever reasonably take, hence why I madei t part of the macro originally)

6:04 unfortunately I haven't quite figuredo ut how I'm going to extend schemas (https://github.com/Prismatic/schema/issues/140)

6:06 llasram: lvh: You just want to ensure the argument matches the schema?

6:06 lvh: llasram: Yes, but ideally ahead of time

6:07 llasram: The thing is that the schema describe steps, serialized to a database

6:07 llasram: the useful time to tell someone that the steps don't make sense is when I store them, not when someone tries to execute them

6:07 llasram: Sure. So, just evaluate them then?

6:08 prismatic/schema supports just checking that some data matches a schema

6:08 lvh: right, but ideally I would like to describe the behavior of "call this method in order to get the subschema" as a schema

6:08 llasram: I don't think it works that way :-)

6:08 lvh: the reason I want that is because these steps are themselves composed

6:09 https://github.com/lvh/icecap/blob/master/src/icecap/schema.clj#L24

6:10 (I appear to have worked myself into a pickle :))

6:11 llasram: So basically I would like to be able to validate a Plan, which consists of just schemas, vecs of plans, or sets of plans (so, eventually schemas, if you dig down deep enough)

6:12 llasram: Can't a custom checker predicate just recursively invoke the schema-checking machinery?

6:14 Oh, or is it that you need to check that some data is a valid schema?

6:15 lvh: llasram: Yep, that's what I'm doing :-) a checker predicate could do that, but then you have two problems: 1) you don't know if they're s/check'ing or s/validate'ing 2) IIUC predicates don't allow useful errors to be passed around

6:15 and useful validation errors is why I'm doing all of this schema business in the first place

6:24 What's the appropriate way to unit test stuff that uses core.async/timeout?

6:25 (ideally without actually having the tests wait n msec)

6:36 TimMc: $karma sheangrov

6:36 lazybot: sheangrov has karma 1.

6:36 TimMc: (dec sheangrov) ;; undo behavior indistinguishable from drunkenness

6:36 lazybot: ⇒ 0

6:37 lvh: (inc llasram)

6:37 lazybot: ⇒ 36

6:37 TimMc: (inc seangrov) ;; this one too

6:37 lazybot: ⇒ 0

6:37 TimMc: There we go. (Just in case anyone has those nicks.)

6:50 milos_co1agen: quit

6:51 oops, pardon

7:12 thesaskwatch: Bronsa: thanks :)

7:19 laurio: Is it possible to see which leiningen profile is in use when i run it? currently i get "'midje' is not a task. See 'lein help'." after running 'lein midje' although [lein-midje "3.1.3"] is added into plugins under :dev profile.

7:20 'lein pprint' also shows it to be defined under my :dev profile

7:21 ivank: why would someone use (reduce (fn [_ x] x) nil) someseq) to get the last element in someseq, rather than just using (last someseq)?

7:22 llasram: ivank: Because the former idiom would work on something which isn't a seq

7:23 And even if it were seqable, might avoid allocating seq wrappers for each element

7:23 (The former reason is fair; the latter is probably premature optimization)

7:23 hyPiRion: Now the question is: Why isn't last implemented this way?

7:23 ivank: ok. and I guess a set isn't a seq, since there's no order?

7:24 hyPiRion: a set is seqable

7:24 ivank: hmm

7:25 clgv: I hate that `last` is not optimized for vectors - instead you need to use `peek` there to get O(1) access ...

7:27 hyPiRion: clgv: huh, do you use `last` often?

7:28 clgv: hyPiRion: not lately, but access to the last element is in my code base several times

7:28 hyPiRion: you need a it when constructing a vector and the next element is chosen dependent on the last one

7:28 one example ;)

7:29 hyPiRion: That sounds like `iterate`

7:29 or `reductions`

7:29 I'm not disagreeing btw, I just found out that I rarely use last.

7:33 clgv: well, only `iterate` would be an option only if performance was unimportant

7:33 I am far from data analysis and such in that project ;)

7:40 mskoud: Trying to build a Korma query, and the query works, but the code is not looking sound. Can anyone give me a hint? http://pastebin.com/HCZtYMVq

7:47 TimMc: clgv: And it's weirder because nth is O(n) time for seqs but not for vectors.

7:50 clgv: TimMc: yeah. it's weird that this optimization concept does not hold for all core functions

7:51 TimMc: count is also O(1) for the types that support it

7:52 TimMc: At least it has a counted? predicate to help there.

7:53 (Not that count's docstring mentions it...)

8:02 hyPiRion: Oh, maybe I should file a JIRA issue for that and get it rejected

8:02 spradnyesh: is it possible to have something like "defvar" of common-lisp (http://stackoverflow.com/a/8928038) in clojure? better still, does something like that already exist?

8:03 hyPiRion: spradnyesh: defonce

8:03 spradnyesh: as far as i understand, def works like "defparameter" of common-lisp

8:03 hyPiRion: ohh, i'll check that. thanks

8:04 hyPiRion: ,(do (defone a 1) (defonce a 2) a)

8:04 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: defone in this context, compiling:(NO_SOURCE_PATH:0:0)>

8:04 hyPiRion: ,(do (defonce a 1) (defonce a 2) a)

8:04 clojurebot: 1

8:06 clgv: ,(do (alter-var-root #'a (constantly 42)) a)

8:06 clojurebot: 42

8:07 hyPiRion: clgv: or just (def a 42) – point is that defonce won't define a variable if it's already defined

8:07 clgv: ,(def a 23)

8:07 clojurebot: #'sandbox/a

8:07 clgv: ,a

8:07 clojurebot: 23

8:07 clgv: ah right there is no protection mechanism^^

8:08 $source defonce

8:08 lazybot: defonce is http://is.gd/WSqiPr

8:08 SagiCZ1: (doc defonce)

8:08 clojurebot: "([name expr]); defs name to have the root value of the expr iff the named var has no root value, else expr is unevaluated"

8:09 clgv: hyPiRion: ever tried to implement an (do-once expr) or (do-times 10 ...) for debugging purpose?

8:10 hyPiRion: afaik you need to define some variable in the surrounding namespace to get it to work

8:11 hyPiRion: clgv: not entirely sure on the do-once or do-times

8:11 clgv: the point of defonce is to not override contents after reloading changed source files

8:11 or, at least that's one important use case

8:12 clgv: hyPiRion: yeah I did not want to set it in relation with defonce, I just remembered that scenario from debugging ;)

8:12 hyPiRion: ah

8:13 no, I don't think so. I tend to use delays or memoization to evaluate expressions once though

8:14 SagiCZ1: does it maek any sense to call def inside a function?

8:15 (#(def x 3))

8:15 ,(#(def x 3))

8:15 clojurebot: #'sandbox/x

8:15 SagiCZ1: x

8:15 ,x

8:15 clojurebot: 3

8:16 SagiCZ1: so its a function with side-effect?

8:19 TimMc: And gone. Friggin' short-timers.

8:19 clgv: no, usually it does not make sense to use `def` within a function

8:19 TimMc: clgv: They already left the channel.

8:19 clgv: he'll probably come back after he shot himself in the foot ;)

8:20 TimMc: Might take a couple weeks or months for that to play out.

8:29 clgv: ~log

8:29 clojurebot: see logs

8:29 clgv: ~logs

8:29 clojurebot: logs is http://clojure-log.n01se.net/

8:29 clgv: $logs

8:30 $log

8:30 justin_smith: clojurebot: those are some old ass logs

8:30 clojurebot: Excuse me?

8:31 clgv: lazybot is secretive about his logs ;)

8:31 mskoud: (let [b 1 b (when true 2)] ...) whats the right way?

8:32 justin_smith: mskoud: what are you trying to do?

8:33 mskoud: pastebin.com/HCZtYMVq

8:33 clgv: ,(cond-> 5 odd? (* 2) even? dec)

8:33 clojurebot: 9

8:33 clgv: mskoud: the above is an option but not when you want to return a constant value

8:34 mskoud: yeah, acccording to your example you want cond-> or cond->>

8:34 mskoud: ok, ill try to check out cond->

8:35 clgv: though you do not necessarily seem to return the "same" entity - so it might not work

8:36 ,(cond-> {:a 1} (even? 2) (assoc :b 2) (odd? 5) (assoc :c 3))

8:36 clojurebot: {:c 3, :b 2, :a 1}

8:36 clgv: mskoud: a different example ^^

8:36 mskoud: thanks

8:48 TimMc: clgv: http://lazybot.org/logs/#clojure/2014-08-25

9:14 bajabongo: Hi,

9:15 I'm browsing an Om source (https://github.com/swannodette/om/) and I stumbled upon cursors,

9:15 apart from them, I see they implement a lot of protocols, like IFn, ICounted, etc.,

9:16 I was looking at the ClojureDocs for more info about them, but I couldn't find anything,

9:16 is there any documentation related to them?

9:16 gnandretta: bajabongo: have you seen the wiki page? https://github.com/swannodette/om/wiki/Cursors

9:17 justin_smith: reminds me of lenses kind of

9:17 bajabongo: gnadretta: yeah, I've looked at it but haven't digested it yet,

9:18 gnadretta: but apart from that, I'd like to get more info about "standard" Clojure protocols, like those above (IFn, ICollection, etc.),

9:18 but I failed to find anything,

9:18 justin_smith: I think IFn at least is a proper interface, rather than protocol

9:19 bajabongo: justin_smith: probably, but I wanted to play with a couple of them, just to try them out,

9:20 justin_smith: bajabongo: most of the core elements of clojure (functions, the basic datatypes) are defined in terms of these interfaces, which means that you can easily use your own custom classes with clojure, as long as you implement the relevant interfaces

9:20 the best thing is probably to read the java source where these interfaces are defined

9:20 bajabongo: justin_smith: or, rather, I *could*, if I knew these interfaces definitions,

9:21 justin_smith: most of them are right here https://github.com/clojure/clojure/tree/master/src/jvm/clojure/lang

9:21 bajabongo: which I can't find (I did not look up the source - but isn't there anything about them in terms of any docs?)

9:22 justin_smith: thx, I thought there are any docs about them; I was probably wrong :>

9:23 justin_smith: for each of the major interfaces - the name will start with I and the definition will be in that directory

9:23 bajabongo: I am looking, but not really finding anything - but the source is right there, and they are predictably named at least

9:27 bajabongo: justin_smith: thx; I was looking for it too before asking so no surprise you can't find anything; apart from that, no docs quite funnily corresponds to your statement above (about easiness of using one's own classes with Clojure),

9:27 ollivera: In the code below, I got {:key nil}, however "key" should not exist if the value is nil.

9:27 I have a document where the field should not be created if it is nil

9:27 {assoc test :key (if-let [a nil] a nil)}

9:27 bajabongo: i.e. it *could* be easy as long as I even knew what interfaces are available *at all* :)

9:27 gnandretta: bajabongo: IIRC “Clojure porgramming” by Chas Emerick mentions a couple of them (as implementation details) and presents collections from the abstractions they can participate in

9:28 bajabongo: but I don’t think that’s what you’re looking for :(

9:28 bajabongo: gnadretta: I did look into this book, I have a copy,

9:29 justin_smith: bajabongo: well, clojure does provide the means to see what interfaces and protocols an object implements via reflection in the repl. But agreed that some real docs of the core interfaces, what types implement them, and which ones you should implement for your type would be helpful

9:30 bajabongo: justing_smith: you're right; generally no pun intended, I was just nitpicking a bit :)

9:30 justin_smith: bajabongo: via the doc and source functions you can figure out which interfaces you need to implement in order to be a valid arg to a given function

9:30 ie. implement IFn to be the first arg of map, ISeq to be any of the others

9:31 ILookup for get / assoc / dissoc

9:31 bajabongo: justin_smith: I rather wanted to know the opposite - what interfaces do I have to implement, to be able to use which fun (feature),

9:32 justin_smith: ,(assoc [:a :b] 2 :c)

9:32 clojurebot: [:a :b :c]

9:32 justin_smith: bajabongo: how is that the opposite of what I said?

9:33 bajabongo: to use map, you need to implement IFn or ISeq, to use assoc you need to implement ILookup, to use deref you need to implement IDeref...

9:34 bajabongo: justin_smith: maybe not entirely opposite, but I *thought* there might be some kind of table (somewhere), where there are listed all interfaces and their methods, that's all,

9:34 justin_smith: bajabongo: don't call the interface methods, call standard clojure functions

9:34 and those are all made in terms of the appropriate interfaces

9:34 so call map, and you can use IFn and ISeq objects

9:35 bajabongo: ofc I know I can look up every function, and that would roughly have the same result, but it's just somewhat different than what I thought before

9:35 justin_smith: call assoc, and you can use IDeref

9:35 etc.

9:35 you don't have to look them all up (any different than you would in writing normal code)

9:36 you don't have to think about the interfaces much until you define new datatypes

9:37 and the clojure ecosystem is very rich with datatypes already, you shouldn't have to make new ones very often

9:37 bajabongo: as a last resort, I can always write code in a way it was *supposed* to work and just read the compiler error (about not implementing some protocol), anyway

9:37 justin_smith: yes, those errors will typically tell you exactly the interface or protocol you must implement

9:37 foo cannot be cast to IBar

9:38 bajabongo: justin_smith: you're right, but it all started as I was (and still) lookin at the Om source,

9:38 I just wanted to know what I'm reading

9:38 justin_smith: right

9:38 well, for that you don't want the clojure sources anyway, you would want the cljs sources

9:38 my bad on that one

9:39 bajabongo: no problem, as ClojureScript surely implements most of them, at least the basic ones,

9:40 justin_smith: iirc there are no protocols in cljs (though it does implement the basic interfaces)

9:40 bajabongo: I didn't add at the beginning, but I'm rather a Clojure(Script) noob, i.e. I can write sth in it but I want to know more

9:40 justin_smith: no protocols?

9:41 justin_smith: or just a (totally) different implementation?

9:41 justin_smith: not in cljs

9:41 only interfaces

9:41 that directory I linked previously - no protocols, it was only interfaces

9:42 the big difference being you can define protocols using normal clojure code, but for interfaces you must use interop

9:43 bajabongo: as far as I know, Clojure protocols are, actually, compiled to vanilla interfaces,

9:43 justin_smith: it's one of these things in clojure that would be simpler, except we want full access to the jvm level impl of things without a wrapper - so we have the non-wrapped version (interface) and the wrapped, clojure-friendly version (protocol)

9:43 bajabongo: sure, but protocols are only a subset of interfaces (the part you can sanely wrap from clj)

9:44 and iirc have some clojure specific stuff that aren't in interfaces too

9:44 bajabongo: justin_smith: but they are still interfaces, to be exact :)

9:44 justin_smith: scratch that, they definitely have clojure specific stuff (like putting protocol functions into a given namespace - the jvm knows nothing about our interfaces)

9:45 bajabongo: sure - it's because we want full and transperent usage of interfaces that we need the interface/protocol distinction

9:45 so we don't get trapped by our own wrapper

9:46 bajabongo: justin_smith: but there's one more thing that bothers me: you said there are no protocols in CLJS,

9:46 as far as I see, the docs says different: https://github.com/clojure/clojurescript/wiki/Differences-from-Clojure

9:46 justin_smith: bajabongo: d'oh - I had the protocol / interface thing for cljs backward -they have protocols but not interfaces

9:46 sorry

9:46 bajabongo: justin_smith: not a problem, I was just trying to clarify :)

9:48 justin_smith: so the basic interfaces in clj become protocols in cljs, and since they don't have interfaces in cljs (the underlying js platform has no such concept, unlike the jvm), there is no runtime object corresponding to the protocol

9:49 bajabongo: justin_smith: exactly as you say

9:51 justin_smith: apart from that, do you have an idea where I could find some more info about these "cursor" thing?

9:52 I mean, I know there is some info in the Om docs, but David doesn't mention how the actually work, and that's what interests me most

9:52 llasram: bajabongo: I think they're a base React thing

9:52 bajabongo: ofc I did look up the source, but with no success

9:52 justin_smith: I think the wiki link shared above was pretty clear, and the parts that are unclear may reveal which other parts of clojure you need to know to get it

9:52 bajabongo: llasram: they're not,

9:52 llasram: well nm

9:54 bajabongo: there is no such thing like "cursor" in the React ecosystem, and because of a fact that the Om's author has said a couple of times that the're "something like functional lenses", I'd like to get some more info,

9:54 but only info I found is about Haskell implementation, which does not help me much

9:56 oskarth: Getting a NullPointerException when I enter my username after being prompted by `lein deploy clojars`. Using lein 2.4.3 with java 1.8. Any ideas?

10:02 justin_smith: oskarth: does 2.4.2 behave better? try "lein upgrade 2.4.2" and see if it behaves any differently? (it should be obvious how to get back to 2.4.3 after that :))

10:04 oskarth: justin_smith: it worked with some lein-clojars plugin I found and keyfile, but it seems to be deprecated so will give 2.4.2 a shot

10:05 justin_smith: nope, same error

10:05 could it have something to do with drip? seems to be a bit non-deterministic (sometimes it gives me a nullpointerexception before prompting for username)

10:07 justin_smith: oskarth: does drip really speed things up so much? I thought the main source of latency with clojure startup was the loading of clojure.core, not the jvm startup

10:09 oskarth: justin_smith: when I installed it way back repl startup seemed to go a lot faster, but haven't done any serious benchmarking

10:11 clgv: justin_smith: drip probably keeps jvms with loaded clojure.core around ;)

10:13 oskarth: yeah, that's my understanding too

10:14 justin_smith: clgv: ahh, that's the extra sauce I didn't realize

10:15 but then you are commited to a specific clojure.core version

10:17 dnolen_: bajabongo: cursors just wrap collections and provide the collection API, the only difference is they track path information if you access a part of the collection. the implementation is almost entirely boilerplate.

10:19 clgv: justin_smith: yeah, tradeoffs ;)

10:19 gfredericks: reiddraper: I take it back -- my test.check mods aren't entirely obviated by calling functions with failing examples directly

10:20 reiddraper: I think the biggest missing feature is being able to resume long-running shrinks

10:20 bajabongo: dnolen_: o, nice to have a feedback from the author :), OK, but it's somehow still not quite clear how it all works,

10:20 dnolen_: bajabongo: for a list of protocols there's really not anything more definitive than the source https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L201

10:21 bajabongo: a cursor is just a data structure + path information, what else are you missing?

10:21 bajabongo: dnolen_: thanks, I'll look it up

10:22 dnolen_: well, yes, but how is then made this "two-way binding" thing?

10:22 jcrossley3: gfredericks: nice use of "obviate" :)

10:22 dnolen_: bajabongo: that's orthogonal - but it's also simple.

10:22 justin_smith: this gets me thinking, it would be really nice to have a definitive documentation of the core interfaces / protocols somewhere (even if they are just describing the implementation as of a certain specific version) -- unless that exists and we just aren't finding it

10:23 dnolen_: bajabongo: if you update a persistent data structure you will break equality checks along the path changed

10:23 bajabongo: that's all that's needed to drive React.shouldComponentUpdate

10:23 gfredericks: jcrossley3: I admit I googled it first to verify

10:24 jcrossley3: haha

10:24 gfredericks: but in my defense I didn't know of another way to continue the sentence

10:24 bajabongo: dnolen_: as you correctly noticed, the React's "shoudComponentUpdate" is what did bring me here with questions,

10:24 justin_smith: gfredericks: the availability of google obviates the self confidence and memory that having a large vocabulary once required

10:25 bajabongo: dnolen_: could I have a question about the overall process of rendering that you did in Om?

10:25 dnolen_: bajabongo: sure if it's not already answered by what I just said :)

10:26 bajabongo: I mean, I see you've added some Om-specific props like "__om_shared", etc, and - while I see the source - I (still) don't have a clear overall mental view of how it actually works,

10:27 dnolen_: but ofc I realize you may now want to answer it as it just "read f... the source" type of question,

10:27 but yet it's still not-that-clear for me :)

10:27 gfredericks: justin_smith: only in some situations

10:28 dnolen_: bajabongo: it sounds like you want to understand the implementation - what I just described above is how it works

10:28 bajabongo: I'm actually towards using ClojureScript with React, and was looking for some bindings, found yours, and was happy about using it until I did try to read the source - and as I'm rather a Clojure novice (I have an Erlang exp, though), I just don't get it, and I like to know what am I using

10:30 dnolen_: well, yes, the concept of a cursor seem to be clear, but I'd like to know how it works "in the big picture" (w.r.t Om),

10:30 dnolen_: or maybe I could just drop you an email about that?

10:30 dnolen_: bajabongo: it's just a convenience so that some component can update a piece of global application state w/o details of it's location.

10:31 bajabongo: no, just direct questions here or #clojurescript or ask on the ClojureScript Google Group

10:31 bajabongo: lots of people use Om and now quite a few people understand how it works internally

10:33 bajabongo: dnolen_: OK; so, if I understand correctly, when I change some path in the global app state, only that component connected with this path will update its view?

10:34 dnolen_: "change path" -> change some object at this path, I meant

10:41 tadni: So if I understand correctly, concurrency is not inherent to Clojure as you have to explicitly add it?

10:43 justin_smith: tadni: you have to explicitly use some construct that is concurrent

10:43 tadni: if that's what you mean

10:43 futures, agents, core.async are all popular ways to do clojure concurrency

10:44 scape_: feel free to correct me; concurrency is a central theme with the persistent data structs in clojure, meaning you can use them in a thread-safe manner but since immutability is central to clojure that means you get thread-safety in an automatic manner

10:44 justin_smith: what is inherent is the ubiquity of immutible data, which makes concurrency just work once you pull that in

10:44 tadni: justin_smith: Yeah, okay. I was just wondering why people were arguing this point not to learn Clj as an introductory lang.,

10:44 scape_: justin_smith, beat me to it hah

10:45 justin_smith: tadni: I would say that immutibility also makes things more clear to a learner

10:46 tadni: for example, when debugging, having certainty about the places you need to look in the code to know what happens with a given piece of data

10:46 tadni: justin_smith: Was it you, who was telling me if my choices were Emacs Lisp and Clj, to side with Clojure?

10:46 justin_smith: tadni: yeah

10:47 TimMc: I think pretty much anyone will tell you that.

10:47 justin_smith: (here at least)

10:47 TimMc: elisp has *mutable strings* for god's sake

10:47 justin_smith: tadni: emacs is a great example of "where the heck did that binding of that value come from" type hell

10:48 like - you can look up the key bindings / vars a given package offers, but you can't take a given var or binding and know which package last defined or altered it

10:48 or even in which scope these bindings hold

10:48 tadni: Now that Guilemacs seems like a viable option going onward, I see it more reasonable for me to go work with Clojure as a starter lang and move to Guile later and even later still, Emacs Lisp if I need to.

10:49 justin_smith: also, trying to do things the clojure way in emacs will lead to better code, trying to do things the elisp way in clojure will bring pain and confusion

10:50 bendlas`: justin_smith: But C-h k takes you to the current definition of a binding, which is kind of the same thing, isn't it?

10:51 * tadni wonders if it's worth peaking at Light table or if he should just stick to cider.

10:51 TimMc: If you're still learning Clojure, I recommend sticking with your favorite editor.

10:52 especially if it has paredit :-)

10:52 justin_smith: bendlas`: I think I overstated the degree of uncertainty in emacs / elisp

10:55 tadni: Now to remember the location and name of that fairly general/introductory level CLJ intro ...

10:55 justin_smith: ~intro

10:55 clojurebot: Cool story bro.

10:56 justin_smith: tadni: I like this one http://aphyr.com/posts/301-clojure-from-the-ground-up-welcome

10:56 tadni: justin_smith: Ah, I think that was it actually!

10:56 justin_smith: Yeah it was, ty.

10:57 justin_smith: this is not as good, but also popular http://www.braveclojure.com/

11:03 * tadni will brb.

11:15 sarcher: I'm coming from an object oriented background to clojure and have a question about how to represent 'objects' or datastructures in clojure. A map would work fine with properties, etc., but what is the best way to create that structure given that clojure's data types are immutable?

11:15 teslanick: What's wrong with a map or vec?

11:16 sarcher: I'm parsing an xml document with data.xml and I get a nice map of the XML structure, but I'd like to transform that map to a more simple form, then pass that form to a function to do something with it.

11:16 teslanick: nothing is wrong with maps and vectors.

11:16 I'm asking a really basic question. What's the best way to go from map of xml, to map of the structure that I choose.

11:16 justin_smith: instead of mutating the map, return a variation or derivative of it

11:17 sarcher: I'm probably overcomplicated this in my head.

11:17 teslanick: You can use reduce, a walker, or a zipper to transform a data structure into another data structure.

11:17 justin_smith: we have extensive facilities to make those derivations - update-in, assoc-in, clojure.walk/*

11:17 TimMc: sarcher: I predict a lot of clojure.core/for and clojure.core/into in your future.

11:17 sarcher: teslanick: thanks that's probably what i'm looking for.

11:19 in java I would have a Map<String, Element> and would iterate over the elements, creating a Map<String, Contact> objects.

11:19 justin_smith: sarcher: you probably know this already, but any mutation can trivially be expressed in an immutible form where instead of transforming the input, you create some variation on it

11:19 teslanick: What's the value in expressing an object as a Contact rather than a map of keys->values?

11:19 justin_smith: (into {} (for [[string element] iput] [string (f element)]))

11:20 f being a function from element to contact, of course

11:20 sarcher: teslanick: the xml structure could change, so to support different versions of the xml, i'd like to transform it into a form that will be consistent for my real application functions.

11:21 again there may be a better approach, or this may not really be necessary.

11:21 just trying to think through it as i've done simlar things in java.

11:21 teslanick: You could do the same thing with a clojure map. The XML changes, change your transformer to maintain consistency.

11:21 sarcher: teslanick: that's my plan to use a clojure map to represent a contact, i just need to transform the xml map to my clojure map.

11:22 was just asking for pointers on the best practice to do something like that.

11:22 teslanick: justin_smith has the right approach, I think

11:22 sarcher: thanks justin_smith, i'll give that a try.

11:24 teslanick: I assume you've found clojure.xml/parse and xml-seq/xml-zip ?

11:24 seangrove: dnolen_: Any chance of a retweet on the sfcljs tweet? I want to make sure we cover as much as possible while the designer is still fresh

11:25 We'll have him back in ~3 months or so to give an updated talk to see how things have progressed, but it'd be good to get as many questions as possible right now so people are aware of what a designer new to cljs/om thinks

11:27 sarcher: teslanick: i'm using clojure.data.xml and that piece is pretty awesome.

11:31 bacon1989: was wondering, if I have a folder ./foo, how can I create a lein project in it called 'foo'

11:32 it just seems to try and create the folder

11:33 schmee: what's the best way to go from ((0 1 2) (3 4 5) (6 7 8) (9 10 11)) to ((0 1 2 6 7 8) (3 4 5 9 10 11))?

11:33 so the odd-indexed lists get merged into one list and the even-indexed into another

11:36 llasram: schmee: where {even,odd}-indexed means by first element?

11:37 lvh: is there any guarantee which order source files will get executed in

11:37 (I know I am not supposed to care; I am just out of ideas, so I added some global mutable state)

11:37 actually, maybe I should just get rid of it and do it the Hard(TM) but probably okay way :)

11:38 justin_smith: lvh: one form at a time, top to bottom

11:38 lvh: justin_smith: Sorry, I mean order between different source files, not within a source file

11:39 justin_smith: top to bottom in the require block, depth first, right?

11:39 lvh: justin_smith: source file a.b.c modifies some global state in a.b.x at compile time, ...

11:39 oh

11:39 in that case it's actually easier without the global mutable state

11:39 schmee: llasram: no, I mean that the first list goes into the "even"-list, the second into the "odd"-list, and so on

11:40 so based on their index in the outer list

11:40 lvh: justin_smith: But if I do some defmethods in a clj file far, far away, I don't have to require the implementations to be able to use them, right

11:41 justin_smith: lvh: hmm - not sure about that detail, sorry

11:41 but my instinct would be to require the ns that has the defmethod, and namespace qualify the method invocation

11:41 dnolen_: seangrove: done

11:42 schmee: llasram: actually I just realized that `keep-indexed` might be what I'm looking for

11:42 cminus: schmee: (->> '((0 1 2) (3 4 5) (6 7 8) (9 10 11)) (group-by #(even? (first %))) vals (map flatten))

11:42 lvh: justin_smith: only one way to find out ; thanks!

11:42 seangrove: dnolen_: Thanks! Should be a nice first step. Also, I believe CircleCI should have a big Om-related announcement tonight as well

11:42 dnolen_: seangrove: interesting!

11:43 schmee: cminus: awesome, thanks!

11:43 (inc cminus)

11:43 lazybot: ⇒ 1

11:43 llasram: Noooo

11:43 (dec cminus)

11:43 lazybot: ⇒ 0

11:43 llasram: ~flatten

11:43 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

11:44 llasram: hash-map gives you no order

11:44 *and* it's doing even-odd by the first element

11:44 Maybe: ##(->> '((0 1 2) (3 4 5) (6 7 8) (9 10 11)) (map vector (cycle [0 1])) (reduce (fn [v [i x]] (update-in v [i] into x)) [[] []]))

11:44 lazybot: ⇒ [[0 1 2 6 7 8] [3 4 5 9 10 11]]

11:44 llasram: (inc cminus) ;; here, have it back

11:44 lazybot: You want me to leave karma the same? Fine, I will.

11:44 llasram: cminus: But just say no to `flatten` :-p

11:45 cminus: llasram: haha, ok. No flatten

11:45 tenchi: llasram: Haha...you just helped me with a 4clojure problem. Thanks!

11:46 TimMc: schmee: See the clojurebot factoid for flatten ^

11:47 justin_smith: lvh: https://www.refheap.com/89452

11:48 schmee: I like this solution: (flatten (keep-indexed #(if (even? %1) %2) '((0 1 2) (3 4 5) (6 7 8) (9 10 11))))

11:48 any way to get rid of `flatten`?

11:48 justin_smith: schmee: apply concat

11:48 schmee: or turn keep-indexed into mapcat

11:49 llasram: schmee: Huh. I thought you said you wanted even/add alternation, and not even/odd by first element

11:49 Oh, I see

11:49 indexed nm

11:51 justin_smith: ,(apply concat (keep-indexed #(if (even? %1) %2) '((0 1 2) (3 4 5) (6 7 8) (9 10 11))))

11:51 clojurebot: (0 1 2 6 7 ...)

11:52 tadni`: clojurebot's name drives me crazy for some reason. cljbot has that 3 and 3 to it.

11:53 schmee: justin_smith: I don't see how `apply concat` is any better than `flatten` if the result is exactly the same

11:53 justin_smith: schmee it's different when the elements are lists

11:54 ,(apply concat (keep-indexed #(if (even? %1) %2) '(([0 0 0] [1 1 1] 2) (3 4 5) (6 7 8) (9 10 11))))

11:54 clojurebot: ([0 0 0] [1 1 1] 2 6 7 ...)

11:54 justin_smith: ,(flatten (keep-indexed #(if (even? %1) %2) '(([0 0 0] [1 1 1] 2) (3 4 5) (6 7 8) (9 10 11))))

11:54 clojurebot: (0 0 0 1 1 ...)

11:54 justin_smith: *when the elements are sequential

11:55 tadni`: sadly clojureautomata is 7/8

11:55 not nearly as nice as 3/3

11:55 but clojureandroid would work

11:55 or clojuremachine

11:56 schmee: justin_smith: ahh, I see

11:56 lvh: if you have source files that are just about an interface (e.g. a protocol for a data store backend), would it typically be called "core"?

11:57 justin_smith: schmee: your code suddenly gets a big blindspot when you use flatten - sometimes that blind spot is worth it or even expected, but if you want to be general, apply concat or mapcat are much more reasonable in behavior

11:57 clgv: tadni`: OCD? ;)

11:59 tadni`: clgv: Not since "I was a kid", but yeah, little thinks like that sill irk me a bit. :^)

12:00 schmee: justin_smith: yeah, good to know! also, when you say "turn keep-indexed into mapcat", you mean write my own version of `keep-indexed` with the correct behavior?

12:01 or is there some magic that can be used

12:02 justin_smith: I mean something like ##(mapcat #(if (even? %1) %2) (range) '((0 1 2) (3 4 5) ( 7 8)))

12:02 lazybot: ⇒ (0 1 2 7 8)

12:02 justin_smith: oops, missed a 6 there, sorry

12:02 but I hope it is still clear

12:02 though probably best to use apply concat

12:03 lvh: yeah, so I have to require the module to see the implementation :(

12:04 schmee: justin_smith: aight, thanks for clearing that up!

12:04 (inc justin_smith)

12:04 lazybot: ⇒ 66

12:06 * gfredericks has a test.check shrink that's approaching a depth of 1000

12:07 lvh: gfredericks: eek

12:16 clgv: gfredericks: is there a verbose option to see that on the repl?

12:20 gfredericks: clgv: no, it's my fork

12:21 the verbosity is crucial for my use case because the shrinking can take so long that I want to be able to stop & resume & etc

12:21 right1: so uhh, how many people in here going to the DC clojure meetup tomorrow?

12:25 virmundi: Is anyone in here willing to have a quick glance at ArangoDB driver I'm writin, specifically the travesedo.core file? I'm new to Clojure (figured a driver is a good learning tool). I need to know if I'm on the right path for configuration ideas.

12:30 justin_smith: virmundi: got a link?

12:30 virmundi: Yep. Let me push really quick

12:32 here you

12:32 https://github.com/deusdat/travesedo/blob/master/src/travesedo/core.clj

12:33 I'm trying to make a fluent way to build up a configuration. That I've got so far should add a database connection to a larger, general-configuration.

12:34 clgv: virmundi: why not just use a clojure map that contains all configuration? it'll be much simpler and much easier to read

12:35 virmundi: I didn't want to expose all of the keys to the user. So I was thinking something like (tc/with-connection u (->> {} (tc/with-host "other") (tc/with-port 8332)))

12:35 clgv: virmundi: encapsulating `assoc` is strange as well. and your calls to add-config pass the wrong number of arguments because of the vector

12:36 virmundi: that way you'll have to write an essay to get a complete config

12:36 justin_smith: virmundi: why not a factory that takes the config the user would be interested in, and returns the full config object? With immutibility, much of the justification for information hiding disappears.

12:37 virmundi: or, even better, statically define a "default config" map, and let the user conj or assoc or merge as desired to get their working config

12:38 virmundi: justin_smith: I was going to have too assuming the default is for the localhost instance for the connection.

12:39 is it common to provide all of the keys and structure to clients?

12:39 For example, in ArangoDB if I want to run a query, I need the connection information (which is what my core file is trying to do), plus the query information, like which collection or an AQL statement.

12:40 justin_smith: virmundi: yeah, we don't do much information hiding - since our data structures are immutible, it suffices to document which parts are guaranteed and which parts may change in future verisons, and let a client make their own judgement on how painful they want upgrades to be

12:40 virmundi: which is of course very different from the best practices in the java world

12:43 virmundi: justin_smith: would Clojure folk do this: tc/insert-document (config clojure-map) where config is a map like {conns: [{con info 1} {con info 2}]}

12:44 justin_smith: virmundi: yeah, if you look at clojure.java.jdbc, the operations generally take a config map as their first arg

12:47 virmundi: justin_smith: should I put the possible keys in the ns doc section?

12:47 justin_smith: virmundi: I'd put the keys that define your "api" in the doc of the ns or of the most relevant function

12:47 (or def)

12:48 virmundi: and consider making a defrecord - where the official fields of the record are the public api, and other values can be associated ad-hoc but are known not to be "official", and only impl details

12:49 clgv: virmundi: use them incrementally in the examples that document the usage of your library, as well

12:49 justin_smith: I wouldnt recommend a defrecord until rcord features are really needed

12:51 virmundi: clvg: I hadn't gotten to defrecord yet :)

12:52 clgv: virmundi: just go for a plain clojure map until you are really sure that you need more

12:53 justin_smith: clgv: I just saw an advantage in defrecord since it describes a set of canonical keys, while also being usable as a regular map with other keys

12:53 virmundi: clvg: though would they work for making a closable lazy-seq? I need that for part of the driver API. Querying gets a cursor from the server. I thought a lazy-seq would be useful. But I need a way to tell the server that the cursor is no longer needed. This is easy enough if the whole sequence is read, but I could figure out how to do it if the client just took 4

12:54 justin_smith: virmundi: a common pattern is to define a block where any code inside the block can use the cursor, and once outside the scope of that block, the cursor will be closed

12:54 clgv: virmundi: lazy-seqs and closeable resource dont work well together

12:54 justin_smith: so they can lazily ask for as much or little as they like inside that block

12:55 clgv: virmundi: you could use explicit pagination and build something similar to chunked lazy-seqs where the resource is only used to realize a chunk

12:55 justin_smith: clgv: but I think that is exactly related to the feature he wants - you lazily access the elements the cursor can fetch, so as not to create more network traffic than needed

12:56 virmundi: justin_smith: how do I make that pattern? Is there a tutorial? I saw the with-close

12:57 clgv: justin_smith: the problem is that you must realize as much of the lazy-seq as you need in something like a "with-open" and thus outside that scope you dont really have a lazy-seq anymore

12:57 virmundi: clgv: database's response will chunck as well. It returns a list of matching items, along with a cursor field to get the next batch. Default batch size is 5 documents.

12:57 mikepence: hi group, I am keen to finally learn clojure, and hope to get to use it my day job (LivingSocial) at some point

12:58 wondering what the best path is to learning clojure, coming from a ruby and oop background

12:58 justin_smith: virmundi: typically this is done with a macro having a & body argument that is inserted into something like `(try (open connection) ~@body (finally (close connection)))

12:58 clgv: absolutely - but the semantics of laziness and those of the cursor match up nicely inside that block which has the connection open

12:59 clgv: justin_smith: if that's sufficient, then it certainly works...

13:00 tadie: ciao

13:00 !list

13:00 clgv: mikepence: getting one of the recent books and reading through it and toying with the examples meanwhile

13:01 virmundi: justin_smith: my Clojure knowledge is lacking on this point. If I have a try/finally like you said, won't the whole stream have to be evaluated?

13:01 clgv: virmundi: yes the lazy-seq must be evaluated in that try/finally block

13:01 virmundi: that's what I was talking about ;)

13:01 mikepence: @clgv - thanks

13:02 dnolen_: mikepence: Clojure Programming from O'Reilly is a pretty good introduction to the language if you're coming from a mainstream OO background

13:02 justin_smith: virmundi: any parts of the lazy-seq evaluated outside that block will throw an exception - which is exactly how clojure.java.jdbc operates

13:02 and I think it makes sense, personally

13:02 mikepence: thanks, that was the one that I was looking at

13:03 virmundi: justin_smith: I'll try looking at the code for clojure.java.jdbc more closely. Should be fun to learn.

13:03 clgv and justin_smith: thanks for the comments. I'll work on refactoring the api now. Not too sure what to do with core. Maybe put the query operations in it.

13:06 clgv: virmundi: there is no written law that you need a *.core namespace, so just delete it if you dont need it ;)

13:07 justin_smith: virmundi: also, there is a blogpost from our own puredanger (who is often here, just not right now) with some stuff relevant to the differences between clojure and java best-practices http://tech.puredanger.com/2010/02/25/questioning-oo/

13:07 (inc clgv)

13:07 lazybot: ⇒ 25

13:07 clgv: ah puredanger is alexmiller? didnt know that yet

13:07 justin_smith: it seems like my-project.core is there because it is generic enough to be auto-generated, but it doesn't always need to exist

13:08 sritchie: dnolen_: any chance I can get you to add om-bootstrap to the “reusable components” page?

13:08 section on the om page, rather

13:30 technomancy: justin_smith: it's been on my list for ages to get lein new to stop using .core if someone gives a multi-segmented project name

13:30 like my.project instead of my-project.core

13:30 (also would avoid stupid dash/underscore problems)

13:30 the whole .core thing is so dumb =(

13:32 mdrogalis: technomancy: lein new core

13:32 virmundi: But I learned it last week from lein ಠ_ಠ

13:32 technomancy: ~guards

13:32 clojurebot: SEIZE HIM!

13:32 justin_smith: technomancy: that sounds awesome

13:33 mdrogalis: lein new 0.1.0-SNAPSHOT

13:33 -boom-

13:33 justin_smith: rofl

13:33 virmundi: core is a placeholder that starts to act like a convention - but it isn't really needed at all

13:34 joshuafcole: See, that's the problem. Never name a placeholder something reasonable.

13:34 :)

13:34 technomancy: it's totally a case of the tail wagging the dog

13:34 justin_smith: we could always replace core with foo

13:34 people would be much less likely to leave foo

13:34 virmundi: and then foo would be the new core.

13:35 mdrogalis: That's an awesome expression.

13:35 technomancy: the rules for regular namespaces are made more complicated just so the rules for AOT'd namespaces are simpler =(

13:35 hiredman: fyi, if you give lein new a proper group-id like `lein new com.example/foo` you get src/com/example/foo.clj no core in site, it is great

13:36 dnolen_: sritchie: done

13:36 justin_smith: how about rename-this - bonus, it would also demonstrate how to munge ns file-names given that its file would be rename_this.clj

13:36 sritchie: dnolen_ nice, thanks man

13:37 justin_smith: (inc hiredman)

13:37 lazybot: ⇒ 53

13:37 justin_smith: that's awesome, I had no idea that worked

13:38 hiredman: sight

13:38 mdrogalis: justin_smith: Thats actually a super good idea.

13:40 technomancy: justin_smith: slightly annoying because you have two places to update; the filename and the ns name. I could see that being error-prone for people who are just getting started and have no idea how the tools work.

13:40 virmundi: justin_smith: entirely none lein related question. Why does (try (take 500000 (range)) (finally (println "finally"))) print finally and then the range?

13:40 justin_smith: lein rename-core core actual-name

13:41 virmundi: because it returns the result after runnign the finally clause

13:41 *running

13:41 virmundi: justin_smith: well that was a stupid question. Read that questioning-oo post and tossed out my JVM knowledge.

13:42 justin_smith: if you had a print in the body, and then one in the finally, they would print in the right order

13:42 hah

13:46 virmundi: another minutae of try/finally is that if you throw an exception in your body, the finally clause will be run before the caller sees the exception

13:48 ran into that recently, editing someone's code where they were calling the same cleanup code in their catch and finally blocks (was able to prove it was redundant)

13:50 virmundi: justin_smith: makes sense

13:50 justin_smith: oh, the detail I left out there was that they were throwing in their catch block

14:09 SagiCZ1: hi

14:09 so is anyone here who has the whole today's channel history? could you look up my last question and pm me the answer to it?

14:11 justin_smith: you could re-ask the question

14:11 gfredericks: SagiCZ1: the answer was "no"

14:11 justin_smith: I also think it got answered after you left though

14:11 amalloy: SagiCZ1: http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-08-25.txt

14:13 justin_smith: for reference, SagiCZ1 asked if (#(def x 3)) made sense

14:15 joshuafcole: Whether it makes sense depends on what you mean to do with the function, but the answer is almost certainly not. Also I think the example of the question may've been malformed since you didn't accept any parameters anyway.

14:15 def is a macro in clojure, which would execute on the forms prior to the function ever being called, rather than each time it was called

14:16 amalloy: joshuafcole: def isn't a macro

14:16 joshuafcole: Really? 0.o Oh man

14:16 amalloy: and it only half-executes when it's compiled: it creates the var immediately, but sets it every time you call SagiCZ1's function

14:16 it's a special form

14:17 joshuafcole: Ah

14:17 my bad

14:17 I hadn't realized the distinction. Thanks for clarifying.

14:22 stuartsierra: I wish `def` were a macro that expanded to code calling `intern`

14:22 but… declarations and recursive calls

14:26 SagiCZ1: thank you guys!

14:27 sorry i had to leave channel without saying goodbay

14:27 someone stole a major part of our city's network

14:27 i wonder what could a criminal do with 600 m of optical cable

14:27 Bronsa: stuartsierra: well, it could intern at compile time..

14:27 SagiCZ1: you cant scrap that

14:30 llasram: SagiCZ1: You mean.... physically stole the fiber?

14:32 SagiCZ1: llasram: yes

14:32 llasram: O_o

14:32 technomancy: llasram: happens all the time in some countries with copper

14:32 SagiCZ1: thats the thing.. they thought it was copper

14:32 technomancy: bahaha

14:32 llasram: Ah

14:32 That makes more sense

14:32 SagiCZ1: so they left it in a parking lot

14:33 but cut it in different places

14:33 anyway.. two towns of about 200 000 people with no internet connection :]

14:33 technomancy: SagiCZ1: wow. what city?=

14:33 SagiCZ1: https://en.wikipedia.org/wiki/Plze%C5%88

14:34 technomancy: my brother had that happen a few times when he lived in Manila

14:34 catern: that should be punishable with death

14:34 llasram: cool story, bro

14:34 SagiCZ1: credit cards terminals also ceased to work.. couldnt even shop to kill time

14:35 i think we depend on the internet way too much nowadays

14:36 catern: nah we just need more cables

14:36 SagiCZ1: yeah

14:40 csd_: Hello-- why is this code generating a null pointer exception? http://pastebin.com/vLsG36Z7

14:41 amalloy: csd_: a stacktrace is invaluable in debugging exceptions

14:41 that said, it happens that i can see what's going wrong: (rest args) never returns nil, so your loop continues going even past the end of the list; and (first ()) is nil, so you end up calling nil as a function

14:43 csd_: Thank you--

14:45 SagiCZ1: out of paredit.. do you use more than slurp, barf, raise, kill ?

14:47 amalloy: SagiCZ1: i use wrap-round and backwards-up fairly often

14:48 TimMc: SagiCZ1: convolute-sexp

14:50 SagiCZ1: TimMc: what convolute sexp does?

14:52 amalloy: oh, that too

14:52 TimMc: SagiCZ1: Check the docs. It's a little hard to explain, but it basically allows you to change the nesting order of sexps.

14:52 A day when I use paredit-convolute-sexp is a good day.

14:52 amalloy: SagiCZ1: you can use it to turn (fn [x] (let [y 1] (+ x y))) into (let [y 1] (fn [x] (+ x y)))

14:53 TimMc: it's truly a good day if you use C-2 M-x paredit-convolute-sexp

14:53 TimMc: *nod*

14:53 I think I got to use a 3-level convolute once.

14:53 amalloy: i never quite know what will happen when i do that

14:53 can anyone think of a clever way to find the first duplicate item in a seq, if any exists?

14:54 technomancy: sounds like an interview question

14:54 TimMc: The index of the first item that has already been seen?

14:54 bbloom: what is the opposite of `lein install` ?

14:54 stuartsierra: bbloom: rm -rf ~/.m2/repository

14:54 TimMc: hahaha

14:54 bbloom: stuartsierra: i hate computers.

14:54 amalloy: that sounds about right actually

14:54 (re stuartsierra's suggestion)

14:55 stuartsierra: More specifically, rm -rf the directory of the thing you installed.

14:55 Bronsa: , (reduce (fn [s x] (if (contains? s x) (reduced x) (conj s x))) #{} '(1 2 3 3 4))

14:55 clojurebot: 3

14:55 bbloom: stuartsierra: yeah, i gotcha

14:56 TimMc: Bronsa: And if you wanted the index, you could return the size of the set. :-)

14:56 amalloy: , (reduce (fn [s x] (if (contains? s x) (reduced x) (conj s x))) #{} '(1 2 3 4))

14:56 clojurebot: #{1 4 3 2}

14:56 amalloy: not very useful if it still returns truthy with no dupes :P

14:56 Bronsa: clojurebot: ?

14:56 clojurebot: Pardon?

14:56 justin_smith: tales of stupidity: once I was at a cafe and using their internet connection, and a bunch of deps were acting weird - so I hose my .m2 and try to get my deps from scratch, and still everything is misbehaving terribly

14:56 SagiCZ1: TimMc: thanks

14:57 TimMc: justin_smith: Captive portal?

14:57 justin_smith: turns out each artifact I downloaded was the html of a "agree to our terms and services" page

14:57 Bronsa: amalloy: derp

14:57 TimMc: Yeah...

14:57 amalloy: TimMc: why do you keep talking about the index? the original problem isn't interesting?

14:57 justin_smith: so I open a browser, agree to terms, and finally my deps work

14:57 TimMc: Offline (or near-offline) dev still sucks.

14:57 amalloy: Well, you didn't clarify which one you wanted.

14:57 (I asked.)

14:58 justin_smith: if only I had a picture of my face when I try to open the clojure.core jar file and see the contents of "click this box to agree to use our internet"

14:58 amalloy: TimMc: your asking looked like a (pretty bad) proposed solution: "easy, man, just look at the index of the first item that's already been seen"

14:58 TimMc: Ah, whoops.

14:58 justin_smith: It turns out that blowing away m2 is usually a bad idea.

14:59 justin_smith: heh

14:59 TimMc: The number of times I've ended up coding on the train and needed some dep that I needlessly blew away a week ago...

14:59 justin_smith: assuming that Internet != Web turns out to also be stupid, when not at home

15:00 Bronsa: amalloy: (try (reduce (fn [s x] (if (contains? s x) (throw (ex-info "" {:dup x})) (conj s x))) #{} '(1 2 3 3 4)) nil (catch clojure.lang.ExceptionInfo e (:dup (ex-data e))))

15:00 :P

15:00 amalloy: oh my gosh Bronsa what is wrong with you

15:01 TimMc: Bronsa: No longer clever, might as well use loop/recur. :-)

15:01 amalloy: i was about to eat lunch and i have now lost my appetite

15:01 SagiCZ1: seems pretty sleek to me

15:01 Bronsa: TimMc: yeah yeah, I was just being silly

15:01 amalloy: I mean, it works

15:04 stuartsierra: justin_smith, TimMc: I run a local Nexus server as a secondary cache for just this situation.

15:04 TimMc: Hey Midje users, do I need to have :aot listing every namespace with a :gen-class? Midje complains that it can't find namespaces that have :gen-class but are not listed for :aot in project.clj.

15:05 (The :uberjar profile specifies it but the main project does not.)

15:07 stuartsierra: TimMc: Sounds you're trying to reload an AOT-compiled namespace with stale .class files on disk.

15:08 TimMc: Nah, `lein do clean, midje` provokes this.

15:08 Latest midje.

15:08 stuartsierra: Then I have no idea.

15:21 SagiCZ1: ,(partition 2 (range 4))

15:21 clojurebot: ((0 1) (2 3))

15:22 SagiCZ1: is there some predefined combination of apply map?

15:22 map apply?

15:22 ro_st: i know that (apply concat (map f coll)) is mapcat

15:23 SagiCZ1: i would like the partition to return multiple collections here (map <foo> (parition 2 (range 4))

15:24 ro_st: sritchie: howdy, robstuttaford here

15:24 SegFaultAX: SagiCZ1: What do you mean?

15:24 borkdude: SagiCZ1 it does: (map count (partition 2 (range 4))) -> (2 2)

15:24 sritchie: ro_st: hey!

15:24 just saw your tweet

15:25 gfredericks: SagiCZ1: if you're asking about multiple return values, that's not a concept clojure has

15:25 SagiCZ1: gfredericks: no, not that

15:25 hard to explain

15:26 i know i can use apply if i can turn collection into multiple arguments

15:26 but i dont know how to combine it with map

15:26 TimMc: SagiCZ1: YOu should start by describing an example input/output.

15:26 AWizzArd: btw, apply is a “magic function” which you can’t implement yourself (without using apply).

15:26 justin_smith: SagiCZ1: (apply map f coll)

15:26 SegFaultAX: SagiCZ1: What do you mean you don't know how to combine it with map?

15:27 SagiCZ1: justin_smith: is that correct?

15:27 SegFaultAX: ,(= (map + [1 2] [3 4]) (apply map + [[1 2] [3 4]]))

15:27 clojurebot: true

15:27 justin_smith: ,(apply map + (partition 2 (range 10)))

15:27 clojurebot: (20 25)

15:28 SagiCZ1: but apply only takes one function and one collection right?

15:28 sdegutis: bbloom: what's the story behind the mongodb tweet? I was considering it as an alternative to datomic for a simple web-store app

15:28 justin_smith: SagiCZ1: nope

15:28 bbloom: sdegutis: a client of mine uses it. it's awful

15:28 justin_smith: SagiCZ1: it takes as many args as you like, the collection is "unwrapped" in place and becomes the rest of the args

15:29 by collection I mean the last arg, of course

15:29 sdegutis: bbloom: what in particular? the only annoyance I had with it is that you have to turn atomicity on manually

15:29 bbloom: sdegutis: just use postgres/sqlite/data-files

15:29 SagiCZ1: justin_smith: i see

15:29 TimMc: SagiCZ1: ##(apply + 1 2 3 [4 5])

15:29 lazybot: ⇒ 15

15:29 bbloom: sdegutis: it's not a database, it's an ORM for mmap

15:29 SagiCZ1: thats actualy more handy than i thought

15:29 TimMc: SagiCZ1: Which is the same as (+ 1 2 3 4 5)

15:29 SagiCZ1: thank you all

15:30 sdegutis: bbloom: Ah, I wondered why that sounded familiar:

15:30 bbloom: https://twitter.com/trptcolin/status/401586940786798592

15:30 justin_smith: clojurebot: mongodb |is| an ORM for mmap

15:30 clojurebot: c'est bon!

15:30 justin_smith: (inc bbloom)

15:30 lazybot: ⇒ 40

15:30 bbloom: sdegutis: haha that must have been me :-P

15:30 sdegutis: :)

15:31 justin_smith: ~mongodb

15:31 clojurebot: mongodb is an ORM for mmap

15:46 SagiCZ1: how do i kill whole expression before my cursor with paredit?

15:46 before: "(foo (foo2 (bar)))", after: ""

15:46 kill

15:46 sorry that was dumb.. its kill

15:47 SegFaultAX: SagiCZ1: Consider not being so violent, first of all. What did that sexp ever do to you?

15:48 SagiCZ1: he was completely out of line

15:48 barfed several times

16:32 technomancy: bbloom: protip: don't actually use sqlite from the jvm

16:32 the jdbc drivers are junk

16:32 bbloom: technomancy: noted.

16:32 technomancy: I mean I endorse the sentiment, but not the particulars

16:33 bbloom: thanks

16:54 martinklepsch: is there a subset? for maps where (clojure.set/subset? {:a 1} {:b 2 :a 1}) would be true?

16:57 gfredericks: not that I know of; I think I've written that before

16:58 annapawlicka: Anyone willing to help with a postwalk question? I need to remove all empty elements from a nested map. Code here: https://www.refheap.com/89463

16:59 lodin: Is there any way to use tools.analyzer(.jvm) to find undefined vars? I've managed to make a half-baked workaround by catching exceptions, adding forward declarations, and rerunning the analysis, but it won't work for vars in different namespaces. Any ideas?

17:00 hiredman: lodin: that is sort like proving a negative

17:00 all vars that aren't defined are undefined

17:00 arrdem_: lodin: how are you structuring your analyzer?

17:01 lodin: arrdem, currently I'm just feeding it a form like '(def x y) which will croak when it sees y, so I first analyze '(def y) and then analyze '(def x y) which makes it happy.

17:02 arrdem, I don't do any other setup than that.

17:02 arrdem: lodin: ... okay, and the goal here is what?

17:03 lodin: arrdem, realize that x depends on y, if I have e.g. (def x y).

17:04 arrdem: kinda like this? https://github.com/oxlang/oxcart/blob/master/src/main/clojure/oxcart/passes/tree_shake.clj#L71

17:07 lodin: arrdem, Thank you! :-)

17:08 arrdem: :P

17:10 sritchie: dnolen_: what version of clojurescript had that hashing bug for safari?

17:11 dnolen_: sritchie: http://dev.clojure.org/jira/browse/CLJS-839

17:13 sritchie: dnolen_: I’m getting an intermittent error with the code used for advanced compilation in http://om-bootstrap.herokuapp.com on safari;

17:13 dnolen_: sritchie: yes look at the ticket

17:13 sritchie: classes aren’t being applied in safari, and I’ve tracked it down to a Map[String, String] that won’t do lookups

17:13 yup

17:13 but with strings for me, not keywords

17:13 dnolen_: sritchie: I don't think it matter what the type is

17:13 sritchie: okay

17:14 dnolen_: sritchie: and I'm petty sure it only affects older hardware and only appears when optimizations kick in

17:14 higher JS optimizations tiers in JavaScriptCore

17:14 sritchie: well, I’m seeing it on safari 7.0.4

17:14 dnolen_: sritchie: the hardware matters

17:14 could not reproduce on my iPhone 5S

17:14 not once

17:15 sritchie: ah, yeah, this is a late 2012 macbook pro, I guess that’s “old” by now

17:15 dnolen_: yeah, it does seem to be related to JIT; I’m printing out lookups on this one map, and I get a string of the proper result, and then nils on the second time around

17:15 dnolen_: sritchie: someone with hardware to tests needs to submit the patch

17:16 sritchie: I don't have a suitable machine

17:16 sritchie: so (get {“nav”, “nav”} “nav”) => nil

17:16 dnolen_: sritchie: we don't need to go over the problem, I understand it :)

17:16 sritchie: my immediate thought is that this is parsing problem with advanced compiled code of some kind

17:17 so an acceptable patch in my mind would be something that appends a plain JS imul to all CLJS output that we can use

17:17 in advanced compilation case

17:18 sritchie: a simpler option is to just ^:export cljs.core.imul and allow people to fix this themselves

17:18 it's a pretty insane JS bug

17:19 sritchie: :)

17:19 seeing the comments in the ticket on the shim; I was on the version before that was added for safari

17:19 let’s see if an upgrade touches this

17:20 “All released versions of Safari 7 have a broken implementation of Math.imul”. love it.

17:27 martinklepsch: annapawlicka: https://gist.github.com/mklappstuhl/2dcf28d2eaef25a4034c

17:28 that was fun interesting

17:29 annapawlicka: martinklepsch: :-D thx! it still returns :roofs [{}]} (it shoudl not be there if it's empty) but it's way closer!

17:33 amalloy: annapawlicka, martinklepsch: just replace the two lines for dealing with maps with: (map? m) (not-empty (into {} (remove (comp nil? second) m)))

17:36 annapawlicka: amalloy: it still leaves :roofs [nil], while i want the whole :roofs key and its value to be removed if the value is empty

17:39 hiredman: [nil] is not empty though

17:39 it is a vector containing the element nil

17:40 annapawlicka: hiredman: it was empty though. the solution suggested by amalloy repalced {} with nil

17:47 mdrogalis: hiredman: I had a professor that explains that #{#{}} isn't empty because "it's taking an empty bag and putting it in an empty bag. The surrounding bag isnt empty anymore"

17:48 Sorta always stuck.

18:04 AeroNotix: mdrogalis: sounds like he was pretty high when he said that

18:05 lodin: arrdem, I don't see how I can use the oxcart function for incomplete forms, i.e. when a var can't be resolved.

18:07 mdrogalis: AeroNotix: He didn't start his sentence with "Yo dude" :P

18:09 justin_smith: have you ever walked the leaves of a red-black tree... on weed?

18:11 AeroNotix: this is your algorithm on drugs

18:15 TEttinger: AeroNotix: https://www.youtube.com/watch?v=jWyye9OneUM&feature=youtu.be&t=48m53s

18:16 AeroNotix: TEttinger: saw them in London

18:16 TEttinger: mindblowing

18:35 tuft_: TEttinger: do you know who that is speaking in the vocal sample there? hear him sampled in a lot of psychedelic music. sometimes too far out, but sometimes some solid philosophy =)

18:35 justin_smith: tuft: terrence mckenna

18:35 * tuft hasn't seen Shpongle but saw Infected Mushroom live in a small venue some years back.

18:35 tuft: cool thanks, justin_smith

18:36 justin_smith: he had an interesting biography

18:36 TEttinger: it's interesting to me how programming often works better for me based on the task and what music I am listening to

18:37 tuft: i pretty much totally depend on music to be productive

18:37 sometimes it takes a while to find the genre that fits my mood

18:37 justin_smith: sometimes it's a merzbow debugging day

18:39 tuft: i like the terrence mckenna quote that goes something like "Thinking can be beautiful, thinking can be sublime. Pure, essence of creativity. But we must ask ourselves: Do we have our thoughts, or do our thoughts have us?"

18:39 TEttinger: like when I was debugging complicated, extremely frustrating compatibility issues with Mono, it's angry angry metal for me. but for more of a simple thing like what I'm doing now that mixes art and code, shpongle is great. animals as leaders or other neoclassical metal (mixing classical music with guitar solos) is good when doing string stuff, since it has no lyrics

18:40 I also have my standby, the 12 hour chiptune mix

18:40 tuft: hah that sounds awesome

18:40 TEttinger: https://www.youtube.com/watch?v=GH7eUlri4yM

18:41 tuft: yay childhood

18:41 can i just eat cereal and play FF on the NES now? =)

18:42 justin_smith: someone needs to make a clojure lib called machine-elves

18:44 AeroNotix: tuft: This happens to me. I find that soma.fm's beatblender is generally good for me

18:44 tuft: err, I was scrolled back. Replied to something a while abck

18:44 back

18:44 tuft: AeroNotix: i got it =)

18:44 AeroNotix: i surf dublab.com's archives quite a bit too

18:44 there're like 1200+ eclectic mixes in there

18:46 AeroNotix: tuft: will check it out

18:47 TEttinger put me on a Shpongle run

19:01 technomancy: TEttinger: thanks for this link; sounds pretty good.

19:05 TEttinger: technomancy, heh no prob. I'm sad I haven't been using clojure much lately, it would be nice to get processing some data again but none of my projects use much of that right now

19:07 technomancy: same

19:38 danielcompton: Feeling like Leiningen surrounded by ants right now

19:39 catern: TEttinger: what are you using instead

19:41 TEttinger: catern, right now C#, I've also used Scala (and will likely revisit the project that uses it) but I'm not a fan of the type-obsessed academic fatalistic community

19:41 technomancy: "fatalistic" meaning "you can never know what's going to happen at runtime with a dynamic language; it will probably fail so why bother even trying"?

19:42 TEttinger: yes, they're basically that way

19:42 also they're convinced scala will fail, and are reluctant to use it

19:42 technomancy: huh

19:42 because it's not haskell?

19:42 TEttinger: that's the impression I keep getting

19:42 yes

19:43 it would be hilarious to see how they try to "improve" haskell

19:44 mdeboard: rewrite it in python

19:44 pure, unadulerated python

19:44 arrdem: TEttinger: who's doing the improving?

19:44 mdeboard: I'm actually pondering doing my oxlang prototype in python :P

19:45 mdeboard: go for it

19:45 TEttinger: arrdem, I just anticipate if everyone in Scala switches over to haskell the doomsday cult ethos will kick in in a few years and they'll all start trying to jump ship

19:47 arrdem: meh. scala has inheritance and traditional OO inheritance thoroughly hoses the only "sound" type systems which the research boys have invented to date. I think that there is merit in abandoning Scala as fundimentally type unsound... but just because it's unsound doesn't mean it isn't useful. It's arguably still better at some things than java .....

19:47 I mean, we don't even have a type system let alone a sound one and we still get stuff done so

19:48 technomancy: arrdem: I think the impossibility of HM in Scala is more due to the JVM interop than any design decisions within Scala itself

19:49 dbasch: arrdem: it depends on what you mean by “we.” I can’t imagine writing the 777 software in a dynamically typed language

19:49 technomancy: I mean... does it make any sense to design a type system on the JVM that doesn't support subtyping?

19:49 or do you just have two type systems, one for interop and one for good code?

19:50 arrdem: technomancy: the later is an idea I've been playing with seriously

19:50 technomancy: arrdem: well there are two separate questions: 0) is it a good idea? and 1) would there be any chance of such a thing taking off?

19:51 not that we can ever fully understand the factors making one language succeed where others fail, but a big part of clojure's success is the seamlessness of its interop

19:51 especially in the early days

19:53 arrdem: I think that the common case of proxy very much allows such a thing. Think, from little experience with hardcore JVM interop from Clojure.

19:53 hiredman: technomancy: hm isn't the be all to end all of type inference, haskell doesn't use it for example

19:54 technomancy: hiredman: yeah, that was more of arrdem's claim than mine

19:55 arrdem: dbasch: definitely true. maybe one day we'll get a truly general use language capable of spanning that entire range but I'm not holding my breath. I think that optional typing and checking systems are interesting because they let you potentially harden "dynamic" code until your entire system converges to a static design that is verifiable.

20:15 amalloy: i'm sad that my (is (successful? (clojure.test.check/quick-check 1000 ...))) produces the output "Ran 1 tests containing 1 assertions. 0 failures, 0 errors." would it be a crime to include something like (dotimes [_ 999] (is true))?

20:16 folks gotta know i really ran a thousand tests

20:23 gfredericks: amalloy: doesn't clojure.test.check.clojure-test/defspec do something like that?

20:24 hiredman: it prints stuff out

20:25 which is actually kind of annoying, since you don't really want a test suite to output stuff unless there are errors

20:25 gfredericks: oh I guess amalloy is referring to the summary output

20:27 this morning a wrote a "resume-shrink" function

20:59 justin_smith: (defn resume-shrink [resume job] "removes all unverifiable or irrelevant entries from a resume")

21:55 beamso: is there a particular pattern that i should be using if i'm attempting to use clojurescript + om for data input forms?

22:08 TimMc: amalloy_: In my johnny library, I make heavy use of nested loops to test various combinations of implementations. The result is something like "ran 18 tests containing 3267 assertions". It is *so damn satisfying*.

22:21 sritchie: beamso: yeah, I have one -

22:21 beamso: I pass down a channel into each input component,

22:21 and the passing component can map< that component to augment it will all path information you need to update your app state

22:21 then just have one core.async loop running to handle all those updates

22:24 beamso: i tried nested components but i saw weird things

22:24 the nested component wouldn't appear in the react dev tools in chrome

22:24 or i locked out any modification of the form

22:44 ben_vulpes: how do people running ring apps handle sessions across subdomains?

22:44 behavior i'm facing: log in to www.my-thing.com, visit my-thing.com, no valid session

22:45 beamso: do you have to adjust how you set the cookie on www.my-thing.com so that it's from my-thing.com?

22:45 *session cookie

22:49 ben_vulpes: don't quite know what you're getting at beamso

22:51 amalloy: ben_vulpes: the RFC is to use www.example.com, to avoid confusion about whether my-thing.com is a real thing or an example

22:52 munderwo: Hi all. Having a bit of a problem with using Om and Secretary. I've got this https://www.refheap.com/89469

22:54 ben_vulpes: amalloy: implying that my app should simply not respond at my-thing.com, but 302 those requests to www.my-thing.com?

22:54 (or that that should be handled in dns?)

22:54 munderwo: Im trying to transition to a new page in om, so want to detach what is currently on the root and transition to another "om/root" . I think detach is the right way to got about it. But the let binding of root seems to not work? Any time I try to reference it (ie even logging it) I get the same Cannot read property "call" of undefined.

22:55 amalloy: huh? no, i'm saying don't use my-thing.com as your "foo", but use example.com instead

22:57 ben_vulpes: ah

22:58 behavior that I'm facing: log into www.example.com, visit example.com, no valid session. amalloy - do you know anything about cross-subdomain ring cookie handling?

22:58 amalloy: i have no idea

22:58 i'm just trying to make your question more clear

22:58 ben_vulpes: thanks. i've reworded it per RFC.

23:01 beamso: in ring.middleware.session/wrap-session, have you tried setting/changing the :root option?

23:02 jakecraige: What's the syntax for requiring an ns and including it's macros?

23:04 munderwo: jakecraige: in the repl or in a file?

23:04 jakecraige: munderwo: file

23:04 munderwo: I've got [todos.rest :as r :include-macros true] right now, and i try to access the macro by it's name

23:04 and i get a symbol error that it can't find it

23:05 munderwo: hmm.. that seems about right. At least thats how you do it with om in clojurescript.

23:05 you can also :refer to a particular macro

23:05 by doing [todos.rest :as r :include-macros true :refer [my-macro]]

23:06 are you doing (:require [todos.rest :as r :include-macros true)

23:06 ie keyword require rather than function?

23:06 ben_vulpes: beamso: root defaults to "/", right? could i set it to the domain instead?

23:06 jakecraige: munderwo: yeah it's keyword require

23:07 munderwo: hmm… not sure then. looks like you're doing everything right? Maybe the macro isnt declared correctly?

23:07 jakecraige: munderwo: seems to work when I refer it, just not without it. thanks

23:08 munderwo: oh glad I could help :) first clojure question I could answer :)

23:08 beamso: ben_vulpes: at a guess, yes. but you'll need to test it.

23:14 ben_vulpes: my next curiosity is about how to specify multiple domains...

23:15 * ben_vulpes starts thinking about /etc/hosts

23:15 ben_vulpes: surely there's a better solution...

23:15 beamso: multiple domains for?

23:16 ben_vulpes: well i want sessions on example.com to be valid on www.example.com

23:17 wait i have misidentified the bug

23:17 problem exists in programmer

23:19 beamso: ouch

23:30 sarcher: Hi

23:31 what does (->> do?

23:31 the google does not like searches for (->>

23:31 haha

23:31 mdeboard: ,(doc thread-last)

23:31 clojurebot: excusez-moi

23:31 mdeboard: ,(doc ->>)

23:31 clojurebot: "([x & forms]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

23:32 sarcher: ah cool, didn't know you could do that in the repl. Thanks!

23:33 Methodical: sarcher: If you haven't found it already http://clojure.org/cheatsheet

23:33 sarcher: Methodical: thanks, I have not seen that yet.

23:34 I'm quite in over my head currently heh.

23:35 I'm still trying to figure out how to transform one structure into a different structure.

23:38 I'm parsing this XML with data.xml - https://gist.github.com/scarcher2/c582fe290f4295d98677 and trying to transform it from the XML structure into a more simple map [:id 1 :first-name "Joe" :last-name "Smith" :email-address "joe@example.com"]

23:39 would anyone be willing to help me learn how to do this? :-D

23:39 https://gist.github.com/scarcher2/aa761ba50424cb91e46b

23:39 so far I have the id in there, but now I need to iterate over the nested sequence and add content from them.

23:40 justin_smith: sarcher: why do you want [:key val :key2 val2] instead of {:key val :key2 val2} ?

23:40 sarcher: justin_smith: I honestly don't know the difference at this point :)

23:41 justin_smith: sarcher: [] is associative by numeric index, {} is associative by key lookup

23:41 sarcher: justin_smith: ok, so I definitely want {}

23:41 justin_smith: so the latter is usually the natural choice for key / value pairs

23:41 yeah

23:42 also use :as is a bit weird - require :as is idiomatic

23:42 and that can be part of your ns declaration

23:43 (ns sample.core (:require [clojure.data.xml :as data.xml] ...))

23:44 other than that, it looks like you are on the right track

23:44 sarcher: justin_smith: i made those two adjustments

23:44 amalloy: justin_smith: use :as isn't just weird, it's pretty bad - it creates the ns that require does, but also refers everything like a refer :all

23:45 sarcher: the problem i'm running into now is I don't know how to iterate over the sequence elements in contact and then set the value I get on my new map.

23:45 justin_smith: amalloy: OK - frankly I had no idea what it would do, just knew it was weird :)

23:45 sarcher: amalloy: so don't use :as?

23:45 justin_smith: sarcher: you are mapping over the :content tag - that should work

23:46 sarcher: don't use use

23:46 ~use

23:46 clojurebot: Only use :use with :only.

23:46 amalloy: sarcher: require/:as is fine; use/:as is no good

23:46 sarcher: amalloy: thanks, I saw it the other way in some sample code.

23:47 justin_smith: sarcher: so what do you get from contact-seq, and what do you expect it to be doing?

23:47 is it not transforming each contact?

23:50 sarcher: justin_smith: it is, but i'm trying to get the nested tag values out. It gives me a contact with attributes and a nested :content, but the nested :content is a sequence i believe, so I can't look it up like a map.

23:50 which makes sense, since it comes from xml. it would be a list of elements.

23:51 in java i would just have a nested for loop with access to add those values to my map.

23:51 but i'm not sure what the best or right way to do that in clojure is.

23:53 justin_smith: I get this from your code ([:id "1" :first-name nil :last-name nil :email-address nil] [:id "2" :first-name nil :last-name nil :email-address nil] [:id "3" :first-name nil :last-name nil :email-address nil])

23:53 sarcher: right, i get the id's fine because those are just a straight lookup from the contact

23:53 justin_smith: sarcher: it's a question of refining the functions that get the values out of the contact

23:53 you are getting some thing, like the :id

23:54 sarcher: the problem is the code is trying to access the last name, first name and email address like it's a map, but it's actualy a list of elements in the :content of the contact.

23:54 justin_smith: sarcher: so the first thing I did to figure this out was to add a new key to the value process-contact returns

23:55 :raw contact

23:55 so for each one I see the raw data we want to excavate

23:56 sarcher: justin_smith: cool, I just did the same thing and I see the data and how it is structured.

23:57 justin_smith: by the way thanks for taking the time to look at this with me.

23:57 justin_smith: then, in a repl, try using threading to narrow down how one accesses the nested structure

23:57 (-> (contact-seq (clojure.java.io/input-stream "/home/justin/big/Readings/data.xml")) first second :content)

23:58 next - (->> (contact-seq (clojure.java.io/input-stream "/home/justin/big/Readings/data.xml")) first second :content (filter #(= :first (:tag %))))

23:59 I hope you can see the method here

23:59 this probably isn't what you want the final code to look like at all, but helps get a much clearer view of how the whole thing is structured

Logging service provided by n01se.net