#clojure log - Apr 18 2014

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

0:04 * kenrestivo backs away slowly at mention of cider

0:16 base698: Anyone know how to get this to work: (-> [old-position move] (partial apply interleave)) setting (def f (partial apply interleave)) works.

0:17 Frozenlock: ,(macroexpand-1 '(-> [old-position move] (partial apply interleave)))

0:18 clojurebot: (partial [old-position move] apply interleave)

0:18 base698: well that's helpful

0:18 Frozenlock: base698: I suppose that's not what you wanted :-p

0:18 base698: nope

0:19 Frozenlock: (macroexpand-1 '(->> [old-position move] (apply interleave)))

0:19 ,(macroexpand-1 '(->> [old-position move] (apply interleave)))

0:19 clojurebot: (apply interleave [old-position move])

0:20 base698: hmm.

0:22 success!

0:28 Frozenlock: thanks. first time I've used ->> in the wild.

0:29 Frozenlock: base698: No problem.

0:29 However I'm not sure this increase readability. I suppose there's some other stuff going in the ->> macro?

0:29 base698: yeah, it's super long

0:30 not sure if that pasted

0:31 there was a map and partition and some other stuff

1:24 serjeem: Sort of specific question, but: I'm trying to play with libgdx in a repl. I've got everything running just fine, but when I try to exit the window, it crashes the repl, complaining that the "subprocess failed".

1:25 Is there a way to keep the repl running even when the subprocess dies?

2:07 hiredman: serjeem: likely libgdx is kill the clojure/jvm process when the window closes, there should be an option in libgdx to disable that

2:08 serjeem: lein runs two jvms, one is actually running lein, the second is your projects, if that message is from lein it is because the project jvm (where your code is being run) is dying

2:42 danielszmulewicz: Are forward declarations broken with the latest clojurescript? Doesn't seem to work here.

3:16 martintrojer: ,(= false)

3:16 clojurebot: true

3:16 martintrojer: great

3:17 Frozenlock: (= nil false)

3:17 ,(= nil false)

3:17 clojurebot: false

3:17 martintrojer: ,(every? (constantly false) [])

3:17 clojurebot: true

3:17 martintrojer: perfect

3:25 dbasch: ,(= = - = =)

3:25 clojurebot: false

3:25 martintrojer: ,(every? (constantly false) [false])

3:25 clojurebot: false

3:26 dbasch: ,(every? (constantly false) [true])

3:26 clojurebot: false

3:27 martintrojer: ,(every? (constantly false) [])

3:27 clojurebot: true

3:27 dbasch: ,(every? every? [])

3:27 clojurebot: true

3:28 mpenet: ,(and)

3:28 clojurebot: true

3:37 Frozenlock: Is it an emacs function that 'prettify' the requires into equal length vectors?

3:45 owl-v-: how do i use mutable list?

3:46 dbasch: owl-v-: what do you mean mutable list? what do you want to do?

3:47 owl-v-: update list and use it as stack

3:47 dbasch: owl-v-: but why do you need to mutate it, as opposed to appending to an immutable one?

3:50 owl-v-: is there reason to use immutable list?

3:50 dbasch: owl-v-: normally you need a reason to use mutable structures

3:50 the default is immutability

3:51 ,(pop [1 2 3 4 5])

3:51 clojurebot: [1 2 3 4]

3:52 owl-v-: im using a list as an argument and iterate through and create new list then use this new list as argument of new function

3:52 yedi: what are the best clojure codebases to read for learning some of the better clojure development strategies

3:53 owl-v-: ,(pop [1 2 3 4 5])

3:53 clojurebot: [1 2 3 4]

3:53 owl-v-: ,(push 6 [1 2 3 4 5])

3:53 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: push in this context, compiling:(NO_SOURCE_PATH:0:0)>

3:53 owl-v-: ,(push [1 2 3 4 5] 6 )

3:53 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: push in this context, compiling:(NO_SOURCE_PATH:0:0)>

3:53 dbasch: ‘(conj (pop [1 2 3 4 5]) 6)

3:53 ,(conj (pop [1 2 3 4 5]) 6)

3:53 clojurebot: [1 2 3 4 6]

3:54 Jaood: ,(peek [3 5 7 9])

3:54 clojurebot: 9

3:54 owl-v-: ,(conj [list 1 2 3 4 5] 6 )

3:54 clojurebot: [#<clojure.lang.PersistentList$1@67c93d> 1 2 3 4 ...]

3:54 owl-v-: ,(conj [1 2 3 4 5] 6 )

3:54 clojurebot: [1 2 3 4 5 ...]

3:54 owl-v-: what's that '...'?

3:55 dbasch: ellipsis

3:55 owl-v-: ,(conj [1 2 3 ] 4 )

3:55 clojurebot: [1 2 3 4]

3:55 dbasch: clojurebot truncates results

3:55 owl-v-: and fifo?

3:57 ,(reverse (conj [1] 2))

3:57 clojurebot: (2 1)

3:57 owl-v-: why do i get list when reverse?

3:57 Jaood: (first (conj [] 9))

3:57 ,(first (conj [] 9))

3:57 clojurebot: 9

3:58 owl-v-: ,(reverse [1 2 3])

3:58 clojurebot: (3 2 1)

3:58 Jaood: ,(first (into [] [1 2 3]))

3:58 clojurebot: 1

3:58 owl-v-: ,(first (conj [1 2] 3))

3:58 clojurebot: 1

3:58 owl-v-: ,(ast (conj [1 2] 3))

3:58 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ast in this context, compiling:(NO_SOURCE_PATH:0:0)>

3:58 owl-v-: ,(last (conj [1 2] 3))

3:58 clojurebot: 3

3:59 dbasch: ,(type [])

3:59 clojurebot: clojure.lang.PersistentVector

3:59 dbasch: ,(type (reverse []))

3:59 clojurebot: clojure.lang.PersistentList$EmptyList

3:59 owl-v-: list out of vector?

3:59 ,(conj (1 2))

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

3:59 dbasch: ,(into [] (reverse [1 2 3])

4:00 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

4:00 owl-v-: ,(conj (1 2) 3)

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

4:00 owl-v-: ,(cons (1 2) 3)

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

4:00 owl-v-: ,(cons [1 2] 3)

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

4:00 owl-v-: ,(conj (reverse (conj [1 2] 3)) 4)

4:00 clojurebot: (4 3 2 1)

4:00 dbasch: ,(into [] (reverse [1 2 3]))

4:00 clojurebot: [3 2 1]

4:01 owl-v-: reverse of vector should return reversed vector :(

4:02 dbasch: no

4:02 “reverse: Returns a seq of the items in coll in reverse order. Not lazy.”

4:03 ,(rest [1 2 3 4])

4:03 clojurebot: (2 3 4)

4:03 dottedmag: owl-v-: You're mixing it up with Haskell :)

4:08 owl-v-: not logical... god da@# it!

4:11 dbasch: owl-v-: a vector is not a seq. reverse returns a seq

4:12 it’s good to know why and when to use a vector, and it’s not just because typing square brackets is convenient :)

4:20 owl-v-: so, i'm using two vectors in this function. and i have errors on line 12 and 4: https://www.refheap.com/77370

4:20 v and vv

4:27 dbasch: you’re calling your function with a vector of vectors, so you’re trying to decrement a vector

4:28 owl-v-: decrement a vector?

4:28 when v is [[]] , item is []

4:29 (first item) is first element of item which is just a number 99 in the first case.

4:29 dbasch: print n and m before line 12 and you’ll see

4:29 owl-v-: so n == 99

4:30 omg!!!!!!

4:32 why item is not iterated element of v?

4:32 when looped?

4:34 because it is not for loop?

4:34 dbasch: v is a vector of vectors

4:34 [[99 99]]

4:34 the first element of that is [99 99]

4:34 owl-v-: yes. that's what i want

4:34 dbasch: it’s also the last element, of course

4:34 sm0ke: can core.typed be used to enforce function argument/return types?

4:34 owl-v-: but item==[[99 99 ]]

4:35 sm0ke: so for e.g. what if i declare `inc` as [Num -> String], would core.typed throw exception?

4:35 dbasch: yes, item starts as v

4:36 owl-v-: i guess (loop [item v] ...) this simply initialize value item=v which is not what i want.

4:55 ambrosebs: sm0ke: not currently

4:56 owl-v-: ,(let [v []] (let [n 3] (conj v 3) )

4:56 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

4:56 owl-v-: ,(let [v []] (let [n 3] (conj v 3) ))

4:56 clojurebot: [3]

4:56 ambrosebs: sm0ke: working on generating casts from types

4:56 sm0ke: but there's always going to be a core of "trusted" annotations.

4:56 owl-v-: ,(let [v []] (let [n 3] ((conj v 2) (conj v 3)) ))

4:56 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Key must be integer>

4:57 owl-v-: illegal?

4:58 TEttinger: ,(let [v []] (let [n 3] (do (conj v 2) (conj v 3)) ))

4:58 clojurebot: [3]

4:59 owl-v-: -.-

5:00 what happened to (conj v 2)?

5:02 ,(let [v []] (let [n 3] (do (conj v 2) (conj v 3)) ))

5:02 clojurebot: [3]

5:02 owl-v-: ,(let [v []] (let [n 3] (do (conj v 2) (do (conj v 3))) ))

5:02 clojurebot: [3]

5:04 ucb: ,(doc conj)

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

5:04 ucb: owl-v-: conj returns a new collection

5:05 akazlou: interesting found that get/assoc/assoc-in work nice with nil map passed, is it by design?

5:06 katratxo: akazlou: "nil keys and values are ok" http://clojure.org/data_structures#Data%20Structures-Maps%20%28IPersistentMap%29

5:08 owl-v-: ucb; how do i update one at a time?

5:08 ucb: owl-v-: you don't? What are you trying to do?

5:12 owl-v-: add two vectors to a vector

5:12 [] -> [[1 2]] -> [[1 2] [1 3]]

5:14 Frozenlock: ,(conj [] [1 2] [1 3])

5:14 clojurebot: [[1 2] [1 3]]

5:14 akazlou: katraxo: thank you for the link, but what I meants, that (assoc nil {:lang "Clojure"}) or (get nil :lang) is ok, so map passing into assoc/get/assoc-in can be nil, and no NullPointerException,

5:14 for example in my sample ring app:

5:14 (-> (response-util/file-response file {:root "public"})

5:14 (response-util/content-type content-type))

5:14 if file doesn't exist file-response returns nil, but then content-type return {:headers {"Content-Type" content-type}} which is not right ring response

5:14 just found it interesting

5:22 kras: what's wrong with this function?

5:22 (defn flt [lis acc]

5:22 (if (not (seq? (first lis)))

5:22 (do (conj acc (first lis)) (recur (rest lis) acc))

5:22 (recur (first lis) acc)))

5:23 it just hangs when I eval (flt '(1 2 (3 4)) ())

5:24 ivan: kras: conj doesn't mutate acc

5:25 it returns a new value that you threw away

5:26 kras: oops !!!

5:27 lets say I throw away the result

5:28 it still doesn't explain why it should hang?

5:28 owl-v-: Frozenlock: thanks

5:28 kras: might be missing something else here

5:28 clgv: owl-v-: please do read some introductory material on clojure, you'll be learning much faster.

5:28 kras: here's the easier to read code https://www.refheap.com/77372

5:29 clgv: kras: good move. always post more than one-line code in a gist:)

5:29 kras: clgv: yeah realized it after seeing the code I posted

5:30 ivan: ,(seq? (first '(1 2)))

5:30 clojurebot: false

5:31 clgv: kras: you know that you always have to pass on the "modified" object. your (conj acc (first lis)) does not have any effect on future recursive invocations. and you are missing a base case where the recursion stops

5:31 kras: what exectly do you want to do?

5:33 kras: clgv: thanks for the hint

5:33 I think I undertsood the problem

5:33 I am basically trying to flatten a given nested list

5:33 let me try for some more time

5:33 beamso: ,(doc flatten)

5:33 clojurebot: "([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns an empty sequence."

5:34 clgv: beamso: I think it is a learning exercise ;)

5:34 beamso: oh

5:34 kras: yep

5:36 owl-v-: why is it harder to think in clojure/lisp than think in python?

5:36 or c or c++

5:36 llasram: Lack of experience

5:36 owl-v-: -.-

5:36 clgv: owl-v-: you are probably struggling with imperative programming vs functional programming

5:36 beamso: for me it's a) lazy evaluation and b) functions that return something vs functions that return nothing

5:37 clgv: owl-v-: that's why I suggested to you several times already to read introductory material on clojure - this will speed up your learning process

5:37 beamso: e.g. doall vs dorun

5:38 clgv: owl-v-: get one of the books and do the reading + experimenting cycle ^^

5:39 owl-v-: simple breath first tree search is not fun in clojure :(

5:39 llasram: And why do you say that?

5:40 clgv: owl-v-: why is that? you can directly translate the recursive function from c/c++/java to clojure. but naturally you might suffer a stackoverflow as you would in c/c++/java ;)

5:44 kras: this is what I came up with: https://www.refheap.com/77374

5:45 ofcourse since I am throwing away the conj result it returns an empty seq now

5:45 clgv: kras: still the same error with the "conj" I told you before

5:45 kras: do you know "cond"?

5:45 kras: like a case statement?

5:46 clgv: kras: it is a compact form to write those nested "if" statements (nested in the else case)

5:47 kras: okay, let me check that

5:49 owl-v-: ,(for [i (1 2)] (print i))

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

5:49 owl-v-: ,(for [i (1 2)] (println i))

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

5:50 clgv: ,(for [i '(1 2)] (println i))

5:50 clojurebot: (1\n2\nnil nil)

5:50 owl-v-: ,(for [i (1 2)] (prn i))

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

5:50 owl-v-: ?

5:50 clgv: read please^^

5:50 kras: owl-v-: please read the docs

5:50 beamso: (1 2) is calling the function 1 with an argument of 2. '(1 2) is the list of 1 and 2.

5:50 clgv: ,(1 2)

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

5:50 clgv: ^^

5:50 owl-v-: docs didn't help me at all

5:51 kras: (1 2) clojure expects 1 to be callable

5:51 or special form

5:51 owl-v-: ,(for [i [1 2]] (prn i))

5:51 clojurebot: (1\n2\nnil nil)

5:51 owl-v-: ,(for [i [1 2]] (println i))

5:51 clojurebot: (1\n2\nnil nil)

5:51 kras: if you want clojure to stop doing that then you have to quote it

5:51 ,(doc quote)

5:51 clojurebot: Huh?

5:51 clgv: $doc quote

5:52 &1

5:52 lazybot: ⇒ 1

5:52 clgv: &(doc quote)

5:52 lazybot: ⇒ "Special: quote; Yields the unevaluated form."

5:52 owl-v-: java runtime error :(

5:53 clgv: owl-v-: you'll have many more of those disappointing experiences if you dont try to learn clojure in a structured way, i.e. reading something that explains you the big picture and the mandatory basics

5:54 kras: owl-v-: clojure is a lisp, if that helps :-)

5:55 beamso: i recommend http://www.clojurebook.com/ . for me it was better than the pragprog books on clojure.

5:56 kras: one think which still confuses me a hell lot is recur

5:56 used to recursion with function names

5:56 clgv: kras: just imagine it is the function name of your current function^^

5:56 kras: any good article which explains why we need a special form recur instead of just using traditional recursion

5:56 clgv: kras: provided you have no loop surrounding it ;)

5:57 kras: because the JVM is not able to do Tail Call Optimization

5:57 daitya: owl-v-: section 1.1 of chapter 1 will help you get started thinking in lisp http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#%_toc_start

5:58 owl-v-: ,(let [v []] (for [item [1 2 3]] (conj v item)))

5:58 clojurebot: ([1] [2] [3])

5:59 clgv: kras: you tell the Clojure compiler to use tail call optimization by using recur. through the use of recur the compiler can also determine whether it really occurs in a tail call position

5:59 owl-v-: ...list

6:00 ,(let [v []] (for [item [1 2 3]] (conj v item)) v)

6:00 clojurebot: []

6:00 clgv: owl-v-: well you are wrong in interpreting that code as imparative code :P

6:00 kras: so if I implement a traditional recursion it will be translated to pure JVM recursion which doesn't support Tail resursion optimization?

6:01 clgv: kras: right. that does only matter if your recursion works on large data structures. so sometimes a traditional recursion is totally suitable if you know that the number of recursive calls is bounded by a small number

6:02 kras: ok makes sense now

6:02 owl-v-: ,(let [v []] (do (for [item [1 2 3]] (conj v item) v))

6:02 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

6:02 kras: clgv: thank you

6:03 Frozenlock: I've always found the lack of tail recursion optimization in Clojure... unfortunate.

6:03 owl-v-: ,(let [v []] (do (for [item [1 2 3]] (conj v item)) v))

6:03 clojurebot: []

6:03 clgv: Frozenlock: huh? you get tco by using recur explicitely.

6:03 Frozenlock: you'd want it implicitly if applicable?

6:04 Frozenlock: Yes

6:04 Wouldn't you?

6:04 clgv: wasnt there some discussion regarding that design choice?

6:04 owl-v-: ,(let [v []] (do (for [item [1 2 3]] (conj v item)) (println v) ))

6:04 clojurebot: []\n

6:04 clgv: well coming from C++/Java I never had TCO in the first place ;)

6:05 llasram: This may be the Stockholm syndrome talking, but given that general-case TCO isn't possible on the JVM, I'd rather have an explicit construct for it than have it just not TCO when it couldn't

6:05 clgv: llasram: yeah I also like the check telling me that I misplaced the recur^^

6:05 owl-v-: ,(let [v []] (for [item [1 2 3]] (conj v item) (print v) ))

6:05 clojurebot: #<CompilerException clojure.lang.ArityException: Wrong number of args (3) passed to: core/for, compiling:(NO_SOURCE_PATH:0:0)>

6:06 clgv: owl-v-: could you please use your own local repl?

6:06 llasram: Or just /query clojurebot

6:06 kras: or you can use http://tryclj.com/

6:06 please stop using this as a REPL

6:06 owl-v-: cool! thanks

6:06 llasram: Many options!

6:08 owl-v-: But FYI, that last bit of code you tried can't do what you want w/ immutable vectors

6:08 Not to mention `for` as generating a lazy sequence

6:11 owl-v-: :( but it works when (conj [] 1 2 3)

6:11 or (conj v 1) (conj v 2) (conj v 3)

6:12 i mean (conj (conj ( conj v 1) 2) 3)

6:12 llasram: owl-v-: Yes, but those are operating on the return value of conj in each case

6:13 You're doing the same thing as ##(for [i (range 1 4)] (conj [] i))

6:13 lazybot: ⇒ ([1] [2] [3])

6:13 llasram: Because `v` doesn't change -- it stays bound to `[]`

6:13 owl-v-: T.T

6:13 my python way of thinking...

6:14 i miss mutable list...

6:15 llasram: And my experience is that once I learned to use immutable data structures, I miss *those* in every language lacking them :-)

6:15 * clgv roflmao

6:15 llasram: You have complete access to mutable datastructures in Clojure

6:16 clgv: llasram: cant wait for the version of the above code using java.util.ArrayList ^^

6:16 llasram: ,(let [v (java.util.ArrayList.)] (doseq [i (range 3)] (.add v i)) v)

6:16 clojurebot: [0 1 2]

6:16 anna_: why clojure error reporting sucks ?

6:16 :(}

6:16 clgv: llasram: damn, you should have used `for` ;) :P

6:17 llasram: clgv: Let's not be crazy now :-p

6:17 One problem at a time

6:18 clgv: anna_: mostly due to the JVM since the only possibility for runtime errors are exceptions. but certainly there could be improvements trying to translate those exceptions into better user friendly error messages

6:18 daitya: owl-v-: if you want tutorial-style learning, many options to learn from: http://www.purelyfunctional.tv/ ... http://www.braveclojure.com/ ... http://aphyr.com/tags/Clojure-from-the-ground-up

6:19 clgv: the one from aphyr looks nice

6:19 daitya: and the best way is to try stuff in your local repl... it puts things in context (as opposed to clojurebot)

6:19 llasram: clgv: I don't think that's true... (re: errors) My reasons:

6:19 anna_: Because (a) rhickey isn't interested; (b) with some familiarity, most of the error messages do tell you what went wrong; and (c) because it's honestly difficult given the language design

6:20 clgv: llasram: well my answer would be in (c) I guess^^

6:21 owl-v-: i was doing http://projecteuler.net

6:21 daitya: llasram: i doubt if (a) is even within the answer space

6:21 clgv: owl-v-: better switch to 4clojure.com and start with the basic ones

6:21 llasram: daitya: Really? I think it's definitely a reason the Clojure error messages aren't better :-)

6:22 rhickey is completely fine with Clojure core macros (like defn) just throwing whatever exception bad input causes them to generate

6:22 clgv: llasram: provided those execptions carry enough information the error messages could be improved in the repl frontends

6:22 llasram: I'm skeptical

6:22 clgv: llasram: probably the compiler should throw ExceptionInfo objects with enough information

6:23 llasram: Maybe, but arbitrary code getting arbitrarily incorrect data -- there's only so much you can do

6:23 You'd really need every macro to carefully check what it expects vs what it recieves

6:25 clgv: right

6:25 but do you do that in your own code 100% of the time?

6:26 llasram: Of course not. And I'm not even saying that I think clojure.core should

6:26 I'm just saying I think it's what you need to do to get significantly better error messages, and that that kind of philosophical direction would need to come from the top

6:28 daitya: llasram: :) ... I feel there must be a good reason out there somewhere... it's completely counterintuitive that a carefully-designed language would deliberately not provide clean, useful feedback to its user

6:29 llasram: Well, I mean, it *does*, if you've got a certain mental model and level of familiarity. That's (b), and it's kind of a chicken-egg + self-selection thing

6:29 clgv: daitya: requiring a certain amount of effort would be one reason if the developers are not convinced the effort is worth it

6:30 llasram: If you stick around Clojure, you learn enough of the implementation to interpret the error messages. Once you've learned enough of the implementation, the error messages frequently tell you *exactly* what went wrong

6:30 ,(1)

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

6:30 durm: guys, help me please!

6:30 I want to do fs walk and store file to another place

6:30 llasram: Clojure expected an IFn (a function object) and found a Long

6:30 durm: i have a function

6:31 (defn walk [dirpath pattern]

6:31 (doall (filter #(re-matches pattern (.getName %))

6:31 (file-seq (file dirpath)))))

6:31 llasram: An error like "non-function used in call position" would be newbie friendly, but tell you *less* about exactly what went wrong

6:31 durm: which can walk over fs

6:31 and return file handlers

6:32 llasram: durm: In the future, please use a paste service like refheap.com for code longer than 1-liners

6:32 durm: oh sorry

6:32 ok

6:32 and in another expression i want to store the file

6:33 daitya: llasram: i'm fairly new to clojure, and that has been my experience... these days i get surprised that--more often than not--i barely glance at the error and know where I made a mistake... it took some effort, but now i have a certain level of comfort

6:33 durm: like (map #(println (__create media %)) (walk import-dir #".*"))

6:33 but it doesnt work

6:33 I think because of lazyness

6:34 owl-v-: why this is true? (= (list :a :b :c) (vec '(:a :b :c)))

6:34 Frozenlock: I remember coming to clojure without knowing any java at all. I wanted to throw my computer at the ground everytime I saw one of those horrible error messages.

6:34 daitya: owl-v-: hint... sequence abstraction

6:34 durm: how can I do it?

6:35 llasram: durm: Um, well `dorun` will force a lazy sequence and discard the results, if you just want to force it for side-effects

6:35 owl-v-: but this is java runtime error: (= (list a b c) (vector a b c))

6:35 llasram: durm: You might also consider using `doseq` instead of `map` if you just want to run some code for side-effects

6:36 daitya: owl-v-: what is the difference between 'a' and ':a'?

6:36 llasram: daitya: Oooh, the Socratic method. Fancy

6:36 owl-v-: just an element?

6:36 just elements?

6:36 durm: llasram: thanks, I will try it

6:37 owl-v-: http://www.4clojure.com/problem/6

6:38 daitya: owl-v-: do you have a running repl?

6:38 owl-v-: yes

6:38 with :a works but with 'a' does not

6:38 daitya: correct, but why?

6:39 llasram: oh don't tease ... any resemblance is purely coincidental

6:40 owl-v-: try this... first feed (def a "foo") to your repl, then feed 'a' to it

6:41 without the quotes

6:43 Guest27066: lol funny name daitya

6:43 owl-v-: daitya: "foo"

6:44 daitya: owl-v-: aha! now type in :a

6:44 Guest27066: http://vedabase.net/d/daitya ... a subtle pun on my real name

6:44 akazlou: :require vs :use in ns definition, which one is usually used?

6:44 owl-v-: daitya; :a

6:44 jonasen: akazlou: :require

6:44 Frozenlock: akazlou: :require

6:45 clgv: daitya: lol. you started a tutorial "clojure on hands and knees" just now ;)

6:45 Frozenlock: :use is evil

6:45 akazlou: or preference/difference between them?

6:45 why :use is evil?

6:45 Guest27066: :use is daitya

6:45 :D

6:46 clgv: akazlou: in (ns) only use ":require". in repl (use ...) is often pretty handy

6:46 daitya: owl-v-: before you bound a to something--that is, "foo"--it didn't exist

6:46 jonasen: I wouldn't say that :use is evil. It's just that :require can do everything (and more) that :use can do. So :use is not really needed

6:46 daitya: Guest27066: :D

6:46 clgv: akazlou: usually you use something like (:require [clojure.string :as str]) and then (str/join ", " (range 10))

6:46 Frozenlock: akazlou: Personally I hate it because it brings everything into the namespace. Want to know from which library a function is coming just by looking at the code? Good luck...

6:47 jonasen: Frozenlock: you can (:use ... :only ..)

6:47 Frozenlock: Sure, but do you really? :-p

6:47 kras: finally ended up with this: https://www.refheap.com/77391

6:47 jonasen: Frozenlock: no

6:48 owl-v-: daitya; a still shows "foo" but :a shows :a

6:48 clgv: jonasen: but why when (:require ... :refer ...) is equivallent?

6:48 jonasen: but I do use (:require [foo.bar :refer ..])

6:48 akazlou: ok, so with use you can't assign name to the import, but :as require will allow you to do it, or nice

6:48 daitya: owl-v-: and that is the correct behaviour

6:48 jonasen: clgv: exactly! :require can do al that :use can.. so :use is not needed

6:48 daitya: owl-v-: http://clojure.org/data_structures#toc8

6:49 akazlou: thanks

6:49 daitya: :a is a keyword... it evaluates to itself

6:50 whereas a is a symbol that means nothing till you bind it to something

6:50 clgv: ,'a

6:50 clojurebot: a

6:50 clgv: ,(class 'a)

6:50 clojurebot: clojure.lang.Symbol

6:51 daitya: ,(class :a)

6:51 clojurebot: clojure.lang.Keyword

6:51 clgv: ,(class (read-string "a"))

6:51 clojurebot: clojure.lang.Symbol

6:51 daitya: more correctly, a will not mean anything to _you_ unless you bind it to something

6:53 ,a

6:53 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)>

6:54 owl-v-: (def :a "boo") -> "java.lang.RuntimeException: First argument to def must be a Symbol" because :a is not a symbol

6:55 clgv: ,(def a 42)

6:55 clojurebot: #'sandbox/a

6:55 clgv: ,a

6:55 clojurebot: 42

6:56 daitya: owl-v-: yes, because :a already is--crudely speaking--permanently bound to a value... itself

6:57 owl-v-: but when do we use :keyword? in dictionary?

6:58 daitya: yes, that's the most common use case; keywords are used as keys in a map

6:58 ,{:a :a}

6:58 clojurebot: {:a :a}

6:58 daitya: but this is a perfectly valid map ^

6:59 clgv: ,({:a :a} {:a :a} {:a :a})

6:59 clojurebot: {:a :a}

7:00 daitya: clgv: ooh... why did that happen? let me go find out

7:00 (serious ^)

7:00 clgv: daitya: :D

7:00 ,({:a :a} {:b :b} {:c :c})

7:00 clojurebot: {:c :c}

7:03 owl-v-: returns last dic?

7:04 i think that's correct behavior :)

7:04 i tried on http://tryclj.com/

7:05 jonasen: ,({:a 1 :b 2} :a :not-found)

7:05 clojurebot: 1

7:05 jonasen: ,({:a 1 :b 2} :c :not-found)

7:05 clojurebot: :not-found

7:06 daitya: clgv: D'oh ... default value >_<

7:06 clgv: daitya: yeah you could just write a "get" in front to have it pretty obvious ;)

7:07 daitya: clgv: well, careless of me, because i knew about the optional default

7:08 thanks for the knock on the head :)

7:09 owl-v-: what does ( ) do on ({:a 1} :a :whatever) ?

7:10 daitya: try it in your repl

7:10 clgv: ,((#{{}} {}) {} {})

7:10 clojurebot: {}

7:11 Guest27066: how stupid is the idea to have a line-reader in clojure which collapses all the ending paranthesis? so intead of something like )]})]}))))) we can just write somthing like ...)

7:11 :P

7:12 clgv: ,((#{{}} {}) (#{{}} {}) (#{{}} {}))

7:12 clojurebot: {}

7:13 Guest27066: ignoring that it will just blow off all the existing tools and ides for clojure, its a nice idea

7:13 daitya: owl-v-: seriously, you will do well to read this: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html#%_sec_1.1

7:14 clgv: Guest27066: I guess it wont work in general, since there scenarios when you need to look ahead to be able to determine what closing paranthesis you need and especially which are closed later

7:15 Guest27066: hmm i am not sure if its entirly correct

7:15 every ...) will look ahead for the first unmatched (

7:15 thats it

7:16 clgv: no. you need to know all closing ones that are ahead..

7:16 Guest27066: yes

7:16 clgv: and I guess for that you'd need to read until the end of the document

7:16 Guest27066: beginnging you mean?

7:16 clgv: no

7:17 you need to know which paranthesis to insert instead of ...) you know the possible ones from the opening counter parts but some of them might be closed later on so you have to exclude those

7:18 and you cant tell if there is still a closing one before you readched the end of the file

7:18 -d

7:21 owl-v-: does (set (list)) make array-map?

7:21 clgv: no, it creates a set

7:22 ,(class (set (list)))

7:22 clojurebot: clojure.lang.PersistentHashSet

7:22 clgv: ,(class #{})

7:22 clojurebot: clojure.lang.PersistentHashSet

7:26 Guest27066: is there something like take-while but still extract the last failing element

7:27 clgv: Guest27066: you probably need something that would be called "take-until" then... refering to the looping constructs...

7:27 Guest27066: ,(take-while #(< % 10) (range 20))

7:27 clojurebot: (0 1 2 3 4 ...)

7:28 Guest27066: ,(take-while #(< % 5) (range 20))

7:28 clojurebot: (0 1 2 3 4)

7:28 clgv: Guest27066: with numbers it's easy to patch but you probably have something different

7:28 Guest27066: i can use 6 here, but thats not the point

7:28 clgv: right

7:28 clgv: ,(source take-while)

7:28 clojurebot: Source not found\n

7:28 clgv: $source take-while

7:29 lazybot: take-while is http://is.gd/6y8gU0

7:29 Guest27066: i can always write a reduce and reduced

7:29 clgv: Guest27066: write take-until base on take-while. you just have to move the "when"

7:29 Guest27066: but thats 1.5+

7:34 clgv: Guest27066: https://www.refheap.com/77393

7:35 Guest27066: nice

7:35 (inc clgv)

7:36 lazybot: ⇒ 16

7:37 Guest27066: hurmm

7:37 hey! take until?

7:37 oh ok

7:37 clgv: corresponding to the difference between while loop and repeat-until loop

7:39 oh humm concerning that the sematic is wrong. the predicate needs to be inverse for that naming^^

7:40 Guest27066: may be it should be named take-unless

7:41 take-unless-and-until

7:41 weird

7:42 owl-v-: why ({:a 10, :b 20, :c 30} :b) == (:b {:a 10, :b 20, :c 30}) ?

7:42 clgv: Guest27066: ok there are two variants in the gist now ;)

7:42 (take-until #{6} (range)) ; => (0 1 2 3 4 5 6)

7:43 (take-while+1 #(< % 6) (range)) ; => (0 1 2 3 4 5 6)

7:44 owl-v-: because keywords act as functions

7:44 owl-v-: you'd know that if you read anything about clojure at all.. :/

7:44 Guest27066: i will go with take-until

7:44 makes sense

7:46 daitya: clgv: +1 / owl-v- please do read the learning material available, otherwise you'll hit really unnecessary roadblocks, like you are doing now... for example, http://www.braveclojure.com/ and aphyr.com/tags/Clojure-from-the-ground-up

7:47 owl-v-: i read "Maps store key-value pairs. Both maps and keywords can be used as lookup functions." and couldn't understand

7:49 martinklepsch: anyone having used Schema here?

7:50 Is there a way to require a key to be i.e. a string?

7:50 agarman: @martinklepsch: yeah, both ole Scheme and Racket

7:50 martinklepsch: agarman, actually talking about prismatic/schema here :P

7:54 [(s/one s/Str "s") s/Str] — does it forme

8:06 Guest27066: anyone using fireplace facing problem of reloading record definitions?

8:06 re-definitions*

8:06 i guess it must be a clojure problem in general

8:14 martinklepsch: hey

8:24 gfredericks: Guest27066: yeah that can be tricky; I think every time you reload you get a new class on the jvm; old instances have the old method definitions

8:24 even weirder if you reload protocols that the records implement

8:25 Guest27066: yep, i end up killing the repl and restarting

8:26 martinklepsch: (zf/xml1-> xml-zipper :a :b zf/text) — how could I write this so that I can supply :a :b as list?

8:26 gfredericks: Guest27066: I can usually stay on top of things by making sure to reload protocols, then records, then restart stuff (e.g. w/ stuartsierra/component)

8:27 martinklepsch: seems like something where you'd use apply but I'm not sure how since there is another mandatory thing at the end

8:27 Guest27066: hurm i find it very constraining

8:34 gfredericks: martinklepsch: you could work something out with reduce for sure

8:34 Guest27066: what are you using records for?

8:35 Guest27066: gfredericks: just some abstraction which user can hold on to

8:35 gfredericks: Guest27066: when I use records I tend to minimize the amount of code inside the methods so it doesn't change as often

8:35 Guest27066: yep i noticed that

8:35 but i feels like a cheat

8:36 it*

8:36 agarman: , (#(apply + 1 (concat % [5])) [2 3 4])

8:36 clojurebot: 15

8:36 Guest27066: reloading function which records use works seamlessly nonethless

8:37 hurm may be i can follow that more strictly

8:37 gfredericks: Guest27066: yeah; I've found that even when changing the implementations, I don't need to restart if I'm thorough about what gets reloaded

8:38 and it's usually obvious if I've screwed it up somehow

8:38 Guest27066: yeah changes are easy to track and reload

8:38 just canhe function and reload is what i usually do

8:39 change*

8:39 martinklepsch: gfredericks, any more pointers? kinda lost I guess...

8:41 gfredericks: martinklepsch: I'm not familiar with the xml stuff in particular, but I'd imagine (zf/xml1-> xml-zipper (as-> <> (reduce #(zf/xml1-> %1 %2) <> [:a :b])) zf/text)

8:41 there might be a more succinct version based on what zf/xml1-> does exactly

8:44 ryanbraganza: newbie question - how do I print a big number without the trailing N? e.g. user=> (println 1234123946812893467981236478921697384671823649612934678126389461278364912763461265216385123478213749712893478912378947)

8:44 1234123946812893467981236478921697384671823649612934678126389461278364912763461265216385123478213749712893478912378947N

8:44 martinklepsch: https://github.com/clojure/data.zip/blob/b165e0c9d4ccd83280ac0462a36718b216b0ed20/src/main/clojure/clojure/data/zip/xml.clj#L56

8:45 llasram: ryanbraganza: You `str` it first

8:45 martinklepsch: gfredericks ^ — will look into your suggestion, thx!

8:46 ryanbraganza: llasram: thanks!

8:52 martinklepsch: gfredericks, turns out I can just (zf/text (xml1-> .... ))

9:38 akazlou: hi, guys, having difficulties understanding the behavior of apply fn:

9:38 (apply conj [1 2 3] 4) ;=> doesn't compile

9:38 (apply conj [1 2 3] [4]) ;=> [1 2 3 4]

9:38 although:

9:38 (conj [1 2 3] [4]) ;=> [1 2 3 [4]]

9:38 what is happening in the background when apply is called?

9:40 beamso: ,(conj [1 2 3] 4)

9:40 clojurebot: [1 2 3 4]

9:40 beamso: ,(apply conj [1 2 3] 4)

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

9:41 agarman: ,(apply conj [1 2 3] [4 5 6])

9:41 clojurebot: [1 2 3 4 5 ...]

9:41 agarman: ,(doc apply)

9:41 clojurebot: "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."

9:41 BobSchack: ,(apply conj [3] 3 1 3 4 4 [1 2 3])

9:41 clojurebot: [3 3 1 3 4 ...]

9:42 BobSchack: akazlou for apply it appears the last argument is expected to be a collection of arguements

9:42 agarman: ditto what BobSchack said

9:45 BobSchack: so you have (apply <your function> <arg1> <arg2> [<arg3> .. <argN>]) which is (<your function> <arg1> <arg2> <arg3> ... <argN>)

9:46 akazlou: what are the use cases when you need to use apply, instead of <your function> directly?

9:46 teslanick: Apply lets you hand a constructed list of arguments to a function, where you may not know what those arguments are ahead of time.

9:47 BobSchack: It's the same use case as *args in python

9:48 agarman: ,(apply + (range 3 11 7/9))

9:48 clojurebot: 682/9

9:48 agarman: ,(doc +)

9:48 clojurebot: "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'"

9:49 teslanick: One where you might not know the arguments or the number of arguments ahead of time:

9:49 ,(apply + (take (rand-int 20) (repeatedly #(rand-int 10))))

9:49 clojurebot: 6

9:49 agarman: for a fn like +, that's expecting a individual args, apply allows you to pass a sequence of args instead

9:50 teslanick: Sum a set of random integers between 0 and 10, between 0 and 20 members in size.

9:51 agarman: apply & reduce are similar

9:51 akazlou: ok, need to think about it, thank you guys

9:52 reduce is a little bit different as I may say: reduce is (f (f (f (args)))

9:52 when in apply f is called only once

9:53 but, yes, they are similar

10:00 in addition to apply question above:

10:00 ,(source apply)

10:00 clojurebot: Source not found\n

10:01 akazlou: (source apply)

10:01 (defn apply

10:01 "Applies fn f to the argument list formed by prepending intervening arguments to args."

10:01 {:added "1.0"

10:01 :static true}

10:01 ([^clojure.lang.IFn f args]

10:01 (. f (applyTo (seq args))))

10:01 ([^clojure.lang.IFn f x args]

10:01 (. f (applyTo (list* x args))))

10:01 ([^clojure.lang.IFn f x y args]

10:01 (. f (applyTo (list* x y args))))

10:01 ([^clojure.lang.IFn f x y z args]

10:01 (. f (applyTo (list* x y z args))))

10:01 ([^clojure.lang.IFn f a b c d & args]

10:02 so (apply conj [1 2 3] [4]) ;=> (apply conj (list* [1 2 3] 4))

10:02 ,(list* [1 2 3] 4)

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

10:02 akazlou: ,(list* [1 2 3] [4])

10:02 clojurebot: ([1 2 3] 4)

10:02 akazlou: and this result is then applied to conj

10:02 which conj expects

10:04 through conj.applyTo, (every fn is an instance of clojure.lang.IFn?)

10:04 dnolen_: akazlou: please don't paste into the channel, use a paste service

10:05 akazlou: sorry

10:06 teslanick: akazlou: Yes. Every function (and many "not functions") are IFns

10:06 (e.g. keywords are IFns too)

10:06 agarman: and maps

10:06 and sets

10:07 teslanick: I always forget about that. I find (:foo {:foo "bar"}) easier to think about than the inverse.

10:07 ({:foo "bar"} :foo)

10:08 ,({:foo "bar"} :foo)

10:08 clojurebot: "bar"

10:09 teslanick: But applyTo takes a list of arguments:

10:09 ,(. conj (applyTo '([1 2 3] 4)))

10:09 clojurebot: [1 2 3 4]

10:12 akazlou: yes, this is what list* produces I guess

10:13 teslanick: ,(doc list*)

10:13 clojurebot: "([args] [a args] [a b args] [a b c args] [a b c d & ...]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."

10:25 btcNeverSleeps: ouch, my Emacs / erc session crashed... If anyone did answer about my "lein test" hanging on an assert failing, it would be great if you could paste the answer again ^ ^

10:45 gfredericks: teslanick: I think keywords-as-fns is useful for record-like maps while maps-as-fns is useful for homogeneous hash-map-like maps

10:45 akazlou: on clojure.test/is is there any convention which value in = comes first expected or actual:

10:45 i.e. (is (= <expected> <actual>)) or (is (= <actual> <expected>)), I see the value having <expected> first

10:46 stuartsierra: (is (= <expected> <actual>)) is the norm but not enforced

10:46 teslanick: gfredericks: That's actually a really good point that I hadn't thought about. I rarely use maps as hash-map-like maps (to my own detriment; it's hard to shake my JS-provided worldview)

10:47 gfredericks: teslanick: I think it's the same use cases for using a hashmap *at all* in a statically typed language

10:47 in my experience it's usually in algorithmic contexts rather than data/logic contexts

10:48 akazlou: thanks stuartsierra

10:50 and if keywords and maps are both function, and in simple cases can be used interchangeably to get the value from the map, again which way is more common: (:keyword {<map>}) or ({<map>} :keyword)?

10:52 teslanick: As gfredericks pointed out, if you're using your map as a record of keyword->value, it's ocmmon to do (:keyword {map of kw->value})

10:53 But not all map keys need to be keywords. You could do { 'foo "at foo" }

10:54 In which case, you would use the other form:

10:54 ,({ 'foo "AT FOO" } 'foo)

10:54 clojurebot: "AT FOO"

10:54 gfredericks: if you're writing code that you want to work with arbitrary maps and keys, the safest route is clojure.core/get

11:10 akazlou: yes, clojure.core/get is even necessary when you do (->) and keys are not keywords

11:10 ,(-> {:headers {"Content-Type" "text/html"}} :headers (get "Content-Type"))

11:10 clojurebot: "text/html"

11:13 bbloom: akazlou: that's a good spot for a get-in

11:13 (get-in {:headers {"Content-Type" "text/html"}} [:headers "Content-Type"])

11:13 ,(get-in {:headers {"Content-Type" "text/html"}} [:headers "Content-Type"])

11:13 clojurebot: "text/html"

11:17 akazlou: cool :)

11:19 still trying to remember that you can any symbol in clojure fn name, like ? instead of is-, and even < and > :), which seems pretty common for Clojure

11:20 seangrove: ,(def : get)

11:20 clojurebot: #<RuntimeException java.lang.RuntimeException: Invalid token: :>

11:20 seangrove: Sadly, lots of symbols you can't use (or at least start with), otherwise writing perl in clojure would be a lot easier

11:20 martinklepsch: anyone a clever suggestion for something easily accessible like a map with multiple keys for the same value?

11:21 {15 [:subdoc-abstract :paragraph]

11:21 16 [:subdoc-abstract :paragraph]

11:21 40 [:abstract]

11:21 41 [:abstract]}

11:22 seangrove: martinklepsch: Probably a fn to construct that

11:23 (mk-hash-map [15 15] [:subdoc-abstract] [40 41] [:abstract] [[:nested :vector] 99] [:example])

11:24 martinklepsch: seangrove, yeah, probably just making a function that copies into the empty spots is simplest

11:27 mikerod: are there any good clj libs for working with Jar streams (input is my concern currently)? they are just annoying.

11:28 clojure.java.io doesn't quote do it all for me; maybe I just don't know how to use it good enough :P

11:30 stuartsierra: mikerod: https://github.com/clojure/java.classpath may help a little

11:41 felher: Hey folks. Say I have an impure function that returns something I need, like `create-random-card-deck`, whats the easiest way to get a sequence of n times invoking that function? (doall (map (fn [f] (f)) (repeat n create-random-card-deck))) doesn't strike me as being overly convenient.

11:41 llasram: &(doc repeatedly)

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

11:41 mikerod: stuartsierra: thanks! I'll take a look. after reading this project description, I think it is useful for other things I've been looking at to. win-win

11:41 felher: llasram: perfect! Thanks!

11:49 TimMc: seangrove: "sadly", yes...

11:56 martinklepsch: (fun :that :takes :a :lot :of :arguments) how could I rewrite that so that it takes a list which supplies some of those arguments? like (fun % :more :arguments)

12:01 seangrove: martinklepsch: apply?

12:01 (doc apply)

12:02 clojurebot: "([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."

12:03 seangrove: (map (partial apply +) [[1 1] [2 2] [3 3]])

12:03 ,(map (partial apply +) [[1 1] [2 2] [3 3]])

12:03 clojurebot: (2 4 6)

12:07 rasmusto: ,(apply vector 1 2 3 [4 5])

12:07 clojurebot: [1 2 3 4 5]

12:08 hfaafb: require_once("../../lib/WebServiceCore.class.php");

12:08 my bad!

12:09 how embarassing

12:09 <_<

12:09 rasmusto: ~php

12:09 clojurebot: php is http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/

12:09 nullptr`: hfaafb: yeah, here we say (require-once "../../lib/WebServiceCore.class.php") -- sheesh

12:09 hfaafb: :)

12:09 rasmusto: :)

12:13 jcromartie: ,((memfn .toUpperCase) "test")

12:13 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: .toUpperCase for class java.lang.String>

12:13 jcromartie: WHY?

12:14 nullptr`: ,((memfn toUpperCase) "test")

12:14 clojurebot: "TEST"

12:14 jcromartie: oh...

12:14 thanks

12:16 martinklepsch: seangrove, rasmusto, that works if I only want to append fn-arguments but not if I want to insert them in the middle

12:19 felher: Why does the following code stack overflow? (println (reduce #(map + %1 %2) (repeat 2000 [1])))

12:19 I guess there some lazy-magic going on there, since doing #(doall (map + %1 %2)) seems to fix the problem.

12:21 justin_smith: felher: for me that does not so, and returns quickly

12:21 ,(println (reduce #(map + %1 %2) (repeat 2000 [1])))

12:21 clojurebot: (#<StackOverflowError java.lang.StackOverflowError>

12:21 TEttinger: heh

12:21 justin_smith: odd

12:21 felher: :)

12:22 stuartsierra: felher: Lazy sequences nest. If you wrap too many of them, it overflows the stack when you try to consume it.

12:23 This shows up often if you use `concat` to build up a long sequence in a loop.

12:23 TEttinger: ,(reduce #(mapv + %1 %2) (repeat 2000 [1])) ; I wonder...

12:23 clojurebot: [2000]

12:24 TEttinger: mapv does avoid the laziness from repeat, interesting

12:24 felher: stuartsierra: oh, okay, thanks :)

12:25 justin_smith: TEttinger: I think the problem was the map laziness - it is reduce that eliminates the repeat laziness

12:25 TEttinger: ah

12:26 justin_smith: TEttinger: the reduce ends up building a long chain of map upon map, none forced until the print stage

12:26 TEttinger: ah! that makes sense

12:28 tudd: if you create a defrecord `RecordType` and define an instance with (def RecordType some-record) can you later pass that some-record into another fn and reference some-record.property

12:28 seems like a straightforward thing to do in OOP-land..

12:28 base698: is there a better repl so you can use emacs bindings to go back in history, jumper words etc?

12:29 jcromartie: base698: cider

12:29 justin_smith: tudd: that makes very little sense

12:29 jcromartie: base698: you can use it to connect to an nREPL in your leiningen projects

12:29 or anywhere, like on a production server :)

12:30 base698: that's an Emacs mode, BTW

12:30 TEttinger: (def RecordType some-record) can't be the right syntax

12:30 justin_smith: clojure version (def instance (RecordType. arg0 arg1 arg2 ... argN)) (:property instance)

12:30 or even (.property instance)

12:33 tudd: http://pastebin.com/htSdGhwY

12:33 justin_smith: ,(do (defrecord RecordType [property]) (def instance (RecordType. 42)) (-> instance .property))

12:33 clojurebot: 42

12:35 justin_smith: tudd: in that example, you can use (.ticker order) instead of order.ticker

12:35 or (:ticker order)

12:35 or (-> order .ticker)

12:35 but order.ticker is an error

12:36 and the right way to do it: {:params order :handler handler ...}

12:36 tudd: justin_smith: yep. error. but not in the repl

12:36 justin_smith: I am extremely skeptical that it would not be an error in the repl

12:36 just pass order as the params, clojure will use it as a map, it will just work

12:37 tudd: LT is cool with returning order.broker

12:37 justin_smith: also in this case you could just use a map instead of defining an Order record

12:37 then LT is broken

12:37 because that is not clojure code

12:38 lorefyr: Hi everyone

12:38 tudd: I didn't think so. But coming over from JS land, that does work, normally ;)

12:39 justin_smith: right, clojure is not js though

12:39 tudd: cljs

12:40 justin_smith: cljs is not js either

12:41 The google results for searching "clojure publish rss" are filled with useless results (pages that have the word "rss" somewhere, because that page has a feed) - any good libs out there for publishing rss with clojure?

12:41 seangrove: justin_smith: (js/console.log "x") is valid cljs

12:42 justin_smith: seangrove: oh, weird

12:42 seangrove: (js/Math.floor ...)

12:42 etc.

12:42 tudd: https://github.com/yogthos/clj-rss

12:42 justin_smith: never mind my above question, I found yogthos/clj-rss

12:42 hah, thanks :)

12:42 stuartsierra: Sometimes the ClojureScript compiler will let through things like `foo.bar`. I wouldn't rely on that, though.

12:43 justin_smith: stuartsierra: so that isn't an intentional feature?

12:43 seangrove: justin_smith: With cljs, it's always hard to tell :)

12:43 tudd: As it spits errors when called from within another fn, I won't

12:44 justin_smith: seangrove: the js murkiness sneaks in, I guess :(

12:45 seangrove: justin_smith: A bit. A lot of it is just unspecified behavior that'll be nailed down as practices are established

12:45 tudd: foo.bar is NOT idiomatic clojure(script), and even though you want it to ultimately become js, not gonna let you!

12:46 justin_smith: yeah, I never even thought to try foo.bar in cljs

12:47 tudd: don't bother. LT gets red-in-the-face mad at ya

12:47 mr-foobar: cljsc nodehello.cljs '{:optimizations : :target :nodejs}' > nodehello.js

12:47 * seangrove feels sorry for the poor dead horse and the beating it continues to take

12:47 justin_smith: which dead horse?

12:47 mr-foobar: is giving me "goog.addDependency("base.js", ['goog'], []); ..." in the compiled file

12:47 seangrove: foo.bar

12:48 justin_smith: it was new to me, sorry

12:48 seangrove: justin_smith: Oh, not at all ;)

12:48 Anyway, just added a css reset: * { position: absolute; top: 0px; left: 0px;}, let's see how this goes

12:50 tudd: justin_smith: thx again! collapsing LOC nicely after your suggestion

12:50 plus that, it now works! thing

12:50 justin_smith: tudd: cool

12:50 so you are just passing :params order now?

12:51 tudd: yep

12:51 justin_smith: a similar trick is (select-keys order [:keys :we :use :here])

12:51 or (assoc order :this "also" :and "this")

13:07 gozala: tbaldridge: Do you have time for a question regarding core.async/net ?

13:07 tbaldridge: sure

13:10 gozala: tbaldridge: so I was looking at the source

13:10 tbaldridge: and notice pattern similar to one I used

13:10 for buliding node.tcp module using core.async

13:11 tbaldridge: https://github.com/Gozala/node.core/blob/master/src/node/tcp.cljs

13:11 tbaldridge: only thing I noticed though

13:11 or rather did not quite got

13:11 tbaldridge: gozala: what do you mean by core.async/net btw? that doesn't quite exist?

13:12 gozala: tbaldridge: I was looking at

13:12 https://github.com/clojure/core.async/blob/net-channels/src/main/clojure/clojure/core/async/net.clj

13:12 tbaldridge: I’m aware it’s does not exists yet :)

13:13 tbaldridge: so I'll caution you as that has mostly been considered a bad idea and discontinued :-P

13:13 gozala: tbaldridge: Anyway what I was trying to understand was what’s a good way to deal with errors

13:13 tbaldridge: I see

13:14 tbaldridge: are there any ideas right now that are considered good ?

13:14 in terms of networking or any IO really ?

13:15 tbaldridge: gozala: errors are one thing, that we can discuss. Trying to create channel like semantics over a unreliable connection (like TCP or any net connection) creates a ton of problems.

13:16 gozala: tbaldridge: are those problems listed somewhere ? I would like to look at them

13:16 tbaldridge: I would also like to discuss errors

13:17 tbaldridge: so now I define connection in terms of a ISocket

13:17 that is record of input, output, and error channels

13:18 so data read from the connection is put onto input

13:18 data put onto output channel is written into underlying connection

13:19 if there is an error it’s put onto error channel

13:19 tbaldridge: ^

13:20 does that sounds reasonable so far ?

13:21 or did I ignored tons of problems already ?

13:24 tbaldridge: So my question regarding errors was mainly regarding how one would distinguish between write and read errors

13:24 or how had error would carry info regarding where did it happened

13:26 tbaldridge: I other words I am no longer sure that dedicated error channel for buth input / output errors was such a good idea

13:26 justin_smith: gozala: tcp connections introduce complications in error handling - like with a socket being held open, you don't get an error when you send the message that fails, you get an error later because tcp is retrying (you probably already know this I guess)

13:27 gozala: justin_smith: so that is more or less why I’m bringing it up

13:28 justin_smith: also I would kind of run into same issue if I would implement something like buffered FileWriter

13:28 tbaldridge: gozala: sorry, had to run for a sec, back now

13:29 gozala: where it’s not obvious how to associate error with chunk that was put

13:29 tbaldridge: gozala: justin_smith brings up some good points, and that's all part of the fun of working with tcp.

13:29 justin_smith: gozala: it forces everything to be async and nonlinear

13:30 tbaldridge: gozala: that's why I took a different approach with Hermod (kindof the successor to core.async/net): https://github.com/halgari/com.tbaldridge.hermod

13:30 justin_smith: so you should make your model so that it maps cleanly to tcp's weird time semantics

13:30 tbaldridge: gozala: if you push error handling off on to the app code things get a bit simpler for both the library and the app (imo).

13:31 gozala: tbaldridge: looking at that lib now

13:32 justin_smith: tbaldridge: gozala: yeah, that looks like the kind of approach I was suggesting actually

13:32 tbaldridge: yeah it's a lot like the actor model, except processes aren't tied to mailboxes.

13:33 gozala: justin_smith: tbaldridge I’m afraid it’s not clear to me yet what the approach looks like yet

13:34 tbaldridge: are there any examples anywhere outlining error handling ?

13:36 tbaldridge: or is idea is that if message send timed out that is an error ?

13:36 seangrove: bbloom: In your layout system, is slot meant to be absolutely positioned against the entire screen, and content relative to its parent?

13:38 bbloom: seangrove: i forget how i implemented it, but generally i prefer local coordinates wherever possible

13:38 tbaldridge: gozala: sending a message is always non-blocking, so sending always succeeds, but the message may not get to the other end

13:38 bbloom: game dev habits die hard

13:38 gozala: tbaldridge: so if I read correctly

13:38 tbaldridge: gozala: so the only way to ensure delivery is to send a message with a "respond-do" address and wait until you hear back from the receiver. If you don't get a reply, try resending the message, or give up.

13:38 "respond-to"

13:38 gozala: there are things like ::errro put on channel

13:39 tbaldridge: ok I see

13:40 tbaldridge: I guess what I am looking is something more abstract

13:40 tbaldridge: Can I give that FileWriter example I mentioned eariler

13:40 bbloom: for the record, i don't think CSP makes any sense in a distributed context

13:41 tbaldridge: and that's the problem. it really doesn't

13:41 channels are transactional, blocking and guaranteed delivery, that's pretty much the exact opposite of network connections.

13:42 justin_smith: bbloom: I think it can make sense, but only with the added abstraction allowing you to describe tentative and retroactively failed communications - not as a direct mapping (which is the naive and common first approach)

13:42 danielszmulewicz: dnolen_: ping

13:42 dnolen_: danielszmulewicz: pong

13:42 danielszmulewicz: Hi David, you helped me yesterday with bringing javascript objects to participate in pattern matching. I'm wondering now about Javascript arrays. According to the documentation, any Sequential type is eligible, but Javascript arrays are not sequential. Am I right that I could aim to reify array instances with the ISequential protocol? I can't find anything on that. Can you point me to the right direction?

13:42 gozala: tbaldridge: I think it’s not only about networking though

13:42 seangrove: tbaldridge: Is it used for distributed things in Go? I've not seen it at all, so not sure

13:43 bbloom: justin_smith: when failure is the norm, not the exception, i'd prefer a different model

13:43 tbaldridge: seangrove: sure, but go doesn't attempt to make a "distributed channel".

13:43 gozala: if you do any IO and you have a buffered channel to feed data into it

13:43 tbaldridge: you hit more or less same problem

13:43 bbloom: tbaldridge: justin_smith: CSP is slightly different than just sockets + queues... you can make stuff like zmq work nicely in a distributed context

13:44 seangrove: bbloom: Presumably the global offsets should be passed in as well. I'm thinking of draggable snap-to-guideline/grid/other-thing outside of the component itself

13:44 bbloom: but it's much more complex than shared memory networking

13:44 justin_smith: fair enough :) I'm just saying with the right abstraction failure can be integrated into the CSP model I think - as long as you don't expect the network to be a transperent medium

13:44 seangrove: tbaldridge: Ok, makes sense

13:44 bbloom: seangrove: ok, get ready... i'm going to send you another MSDN link lol

13:44 seangrove: http://msdn.microsoft.com/en-us/library/ms743737(v=vs.110).aspx

13:44 gozala: on one of the writes to disk writer may fail and there is no clear way to communicate that to a producer

13:44 or data provider

13:45 * seangrove just finished reading enough about behaviors

13:45 tbaldridge: bbloom: YAY! more XAML based stuff

13:45 seangrove: Adorners!

13:45 ffs

13:45 tbaldridge: (seriously, the only thing I hated about XAML was the XML part and the mutability, that stuff rocks)

13:45 bbloom: tbaldridge: no really, you're right. xaml is a good idea wrapped in a cloth of bad ideas

13:45 tbaldridge: fundamentally, the good idea is basically EDN :-)

13:46 general purpose, extensible data construction syntax

13:46 seangrove: Ah, but this does seem like a a good idea

13:46 * tbaldridge working on exactly that but with JavaFX

13:46 bbloom: tbaldridge: oh jeeze, i'm sorry

13:46 javafx was oracle getting WPF envy and fucking it up

13:46 tbaldridge: javafx2 isn't as bad

13:47 and don't knockit till you try it, edn syntax + clojure primitive and core.async makes it quite nice actually.

13:47 bbloom: heh ok, i can buy that

13:48 at least compared to HTML and/or swing, for sure

13:48 tbaldridge: yeah exactly

13:48 and now back to working with metadata and macros....to whomever wanted good line numbers inside a go macro....I hate you right now

13:48 lol

13:48 bbloom: seangrove: anyway, fns to map between local & global coordinates are context-dependent (of course) so you should use local coordinates wherever possible to avoid having to do lots of inverse transformations

13:49 seangrove: also, it's ok to put things at negative relative positions, you just need to deal with clipping policy

13:50 danielszmulewicz: dnolen_: Hi David, you helped me yesterday with bringing javascript objects to participate in pattern matching. I'm wondering now about Javascript arrays. According to the documentation, any Sequential type is eligible, but Javascript arrays are not sequential. Am I right that I could aim to reify array instances with the ISequential protocol? I can't find anything on that. Can you point me to the right direction?

13:52 dnolen_: danielszmulewicz: I think for now you need to do (matchv :clojure.core.match/objects [arr] ...)

13:53 danielszmulewicz: I recommend looking at the ClojureScript tests for examples - also feel free to update the wiki, I'm sure other people have similar questions.

13:53 danielszmulewicz: dnolen_: OK, I'll do that. Thanks.

13:54 dnolen_: By the way, converting my array with js->clj doesn't hurt neither. Does this seem acceptable to you?

13:55 seangrove: "The arrange pass begins with a call to the Arrange method. During the arrange pass, the parent Panel element generates a rectangle that represents the bounds of the child. This value is passed to the ArrangeCore method for processing."

13:55 bbloom: ^^ The rectangle representing the bounds of the child is the slot rectangle in your system, right?

13:55 dnolen_: danielszmulewicz: yes if expressivity outweights perf

13:55 outweighs

13:56 bbloom: seangrove: right b/c the child may be given a slot that's too big, so the child has margin & alignment settings to say how it gets positioned within that slot

13:56 danielszmulewicz: dnolen_: Yes, makes sense.

13:56 seangrove: bbloom: Alright, hope to have an Om render in an hour or so

13:58 bbloom: seangrove: just added you to a private repo of mine. plz don't commit to it ;-) it's got a layout.clj file that is more feature complete

13:59 seangrove: if you eval the render forms in core.clj you can play with the layout engine

14:08 Bronsa: bbloom: just noticed you have a typo in the github description for backtick

14:08 s/marco/macro

14:09 bbloom: Bronsa: fixed, thanks

14:13 mikerod: are there any libs out there that deal with attempting to fully-qualify all symbols in chunks of code and the context of their originating namespace? the goal being to store off the code as pure-data, that is sufficiently descriptive to be read back in and compiled at a later time.

14:14 *chunks of code with the context of their originating namespace*

14:14 technomancy: mikerod: sounds like the analyzer?

14:14 amalloy: mikerod: tools.analyzer?

14:17 mikerod: technomancy: amalloy this is what I thought

14:18 I'm not sure that it actually "qualifies" the symbols; but mabye I haven't dug enough

14:18 I know the idea is to make the AST data though

14:18 amalloy: it knows where they come from

14:18 mikerod: ok

14:18 I think I will continue to explore that then

14:18 amalloy: and then you can write a pass that consumes the AST and produces whatever you want. if you want, that can be a source-code form with qualified symbols, i imagine

14:19 mikerod: that makes sense

14:19 this sounds promising

14:19 I've only scratched the surface on tools.analyzer; and recently listened to the talk by umm

14:19 amalloy: by tbaldridge

14:19 (i guess, anyway)

14:20 mikerod: yes

14:20 that is it :)

14:20 "data all the ASTs"

14:20 tbaldridge: mikerod: you might checkout this : https://github.com/clojure/tools.analyzer/blob/master/src/main/clojure/clojure/tools/analyzer/ast/query.clj

14:20 it stores tools.analyzer asts in Datomic

14:21 haven't tried it, but it looks cool.

14:21 Bronsa: mikerod: there's an emit-form pass that compiles the AST back to clojure source. It doesn't return qualified symbols but I have a branch locally that enables that, I can finish that and push that if you need it.

14:21 mikerod: tbaldridge: awesome and Bronsa that certainly sounds valuable

14:21 Bronsa: tbaldridge: it doesn't really store asts in Datomic, it just uses Datomic's datalog

14:22 mikerod: I have done some "hand-rolling" of my own to qualify symbols

14:22 but not to the extent of the full-blown AST analysis

14:22 tbaldridge: Bronsa: yeah I just noticed that, lol

14:22 Bronsa: mikerod: beware that it will macroexpand the source though

14:24 mikerod: Bronsa: yeah, I am curious on this. I technically have some symbols in the source that do not "make sense" in the initial context. I'm wondering if this will cause the analysis to fail, or if I can "mock out" those symbols into the context to avoid failure.

14:24 This is DSL-stuff

14:24 Bronsa: mikerod: the analyzis will work only if the source can be eval'ed.

14:25 mikerod: however you can cheat and give the analyzer a patched-up env

14:25 mikerod: e.g. I have some code like: (+ a b im-a-undefined-symbol) ; where a and b are defined, the other is not; I will fill it in at a later time when reading back out the code and evaluating

14:25 Bronsa: I think the patched-up env was my hopes/thoughts

14:26 Bronsa: mikerod: to do that you need to know what locals/vars your code is going to use that are not already defined though

14:26 jcromartie: for some reason I'm stumped on this one: how to write a HOF which takes a function and returns a new function that ensures the original function is called once and only once

14:27 mikerod: Bronsa: I figured. I do wish I could "catch" failures to resolve symbols and provide a handler for it. I'm not thinking this is possible, but just a cool idea.

14:27 Bronsa: mikerod: if you can't know that, a really hackish way to make that work is to redefine this multimethod https://github.com/clojure/tools.analyzer.jvm/blob/master/src/main/clojure/clojure/tools/analyzer/passes/jvm/validate.clj#L19 not to throw

14:27 Averell: a closure with a flag is not good enough?

14:27 jcromartie: Averell: derp

14:28 well no

14:28 that's not good enough

14:28 what if it's called from two threads?

14:29 mikerod: Bronsa: interesting, thanks for the reference

14:29 jcromartie: oh, maybe a promise is what I'm looking for

14:29 eh… still, race condition

14:30 the function that I want to once-ify has side effects

14:31 hm, maybe laziness is the answer

14:31 amalloy: jcromartie: you close over a delay

14:31 assuming the args are known already?

14:31 jcromartie: args are not known

14:32 basically like memoize

14:32 but safe for side effects

14:32 amalloy: eh. so you use the same trick that's available to make memoize avoid side effects

14:33 (defn call-once [f] (let [value (atom nil)] (fn [& args] @(swap! value #(or % (delay (apply f args)))))))

14:33 er, avoid side-effect problems

14:34 justin_smith: jcromartie: maybe something like https://www.refheap.com/77421

14:34 jcromartie: amalloy: memoize is not safe

14:34 ,(let [f (memoize println)] (dorun (pmap f (repeatedly 10 #(rand-int 10)))))

14:34 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

14:34 amalloy: jcromartie: that's why i said, the trick that's available. you can make memoize safe by storing a delay

14:34 jcromartie: ok

14:35 ahhh

14:35 amalloy: instead of storing the actual value

14:35 i mean, i just typed out my call-once in irc, but i think it's the solution you want

14:37 holy smokes, justin_smith. if you use @ and reset!, you're like never thread-safe

14:38 justin_smith: good point

14:39 amalloy: jcromartie: my version returns the result of the first call, regardless of what args are passed to the second call. so that may not be what you want, i suppose

14:44 Bronsa: mikerod: just pushed the impl: http://sprunge.us/WLaL?clj

14:45 justin_smith: amalloy: jcromartie: edited https://www.refheap.com/77421

14:45 jcromartie: see, this is harder than everybody thinks it is :)

14:45 mikerod: Bronsa: awesome! thanks. I will definitely start experimenting with this then.

14:46 amalloy: that has the same problem memoize has, justin_smith. two threads can both be inside that swap! at the same time

14:46 justin_smith: oh, tricky

14:47 amalloy: that's, again, not a problem in my solution

14:48 koreth_: I want to parse a whitespace-delimited string into a vector of integers. (mapv #(Long. %) (clojure.string/split my-string #"\s")) does the trick but #(Long. %) seems unnecessarily ugly -- is there a more idiomatic "parse a number" function?

14:48 jcromartie: if it's a thunk it's not a problem

14:49 amalloy: jcromartie: huh?

14:49 justin_smith: amalloy: yours not intended for usage with functions that return nil, I assume?

14:49 amalloy: justin_smith: works for all functions

14:49 try it and see

14:50 Averell: why is it safe? i don't understand which part hides the locking

14:50 amalloy: Averell: it's dereffing the delay

14:50 there's a lock around that

14:50 justin_smith: amalloy: oh, of course, because it returns the delay, and derefs, so that delay will not be nil after the first call

14:50 smart

14:51 jcromartie: amalloy: I think yours is good BTW

14:51 I was saying that if you want to make a thunk callable once it's really easy

14:51 if you don't have to worry about args

14:52 amalloy: oh, for sure. that was my original suggestion: close over a delay

14:52 but it only works for thunks

14:52 nullptr`: koreth_: somewhat clunky, but you can use read-string instead of #(Long. %)

14:52 koreth_: Thanks

15:10 jcromartie: Is there a simpler version of: (not-any? nil? coll)

15:10 I think it's pretty clear, myself.

15:16 long-running futures are probably not a good way to handle periodic background tasks

15:16 like, (loop … (Thread/sleep 300000) (recur))

15:16 wrapped in a future

15:19 teslanick: You could use core.async to handle occasional background tasks.

15:21 seangrove: bbloom: https://www.refheap.com/fa7a23df23c6a97e7725391be => http://dl.dropbox.com/u/412963/Screenshots/du.png, slots working, content up next

15:22 bbloom: seangrove: cool

15:22 Rosnec: is it possible to use ztellman's gloss library to decode bytes from a file where you don't know the byte-count ahead of time?

15:22 bbloom: seangrove: happy with my approach? i don't remember how i felt about it ;-)

15:23 seangrove: Black space represent difference between slot-space and content-space. Some cheating in that the browser is still doing some layout intra-component.

15:23 bbloom: So far, mostly very happy. Few questions though

15:23 bbloom: seangrove: relying on browser for text layout etc is probably quite sensible

15:23 Rosnec: I can put byte-counts as prefix information, but I still need to be able to read from the file without knowing the size right away

15:24 bbloom: seangrove: definitely check out how that newer code i gave you access to handles margin & alignment

15:24 jcromartie: this is how I roll https://gist.github.com/jcromartie/11052252

15:25 * bbloom eyes bleed

15:25 Bronsa: jcromartie: jesus christ.

15:25 amalloy: jcromartie: (partial - 0)? that's just -

15:26 bbloom: jcromartie: #concatenative is that way ---->

15:26 amalloy: oh, no, i guess it's not, if you pass multiple args?

15:26 but in your case you're not

15:26 jcromartie: oh, good to know!

15:27 amalloy: and what is the deal with (comp f (comp g h) blah blah)?

15:27 (if you're going to post silly point-free code i have to assume you're willing to have it picked apart)

15:27 jcromartie: which line?

15:27 yes, please

15:27 amalloy: 10-12

15:28 jcromartie: ah yes

15:28 Averell: btw, vigenere is no longer considered safe by many people.

15:28 amalloy: (comp (partial map (comp f g)) (partial map h)) is (partial map (comp f g h))

15:28 mi6x3m: clojure, why is this working: (map (fn [a] { :a a }) "aaaa"), but this doesn't: (map #({ :a % }) "aaaa")

15:28 Bronsa: mi6x3m: #(f) is (fn [] (f)) not (fn [] f)

15:29 seangrove: bbloom: Should components be able to provide default layout guidance? e.g. I have a bootstrap panel, it conceptually has a header and a body. I probably want to think about layout for the body, but not necessarily the panel header (e.g. it should always be 15px heigh and 100% wide if that's what it suggests)

15:29 amalloy: ,'#({ :a % })

15:29 clojurebot: (fn* [p1__25#] ({:a p1__25#}))

15:30 bbloom: seangrove: the parent shouldn't have any insight in to what's inside the children other than to parameterize them

15:30 jcromartie: amalloy: excellent

15:30 amalloy: (partial list cycle [0]) is weird but i don't really get what it's doing

15:30 bbloom: seangrove: so from the parent's perspective, layout is about bounding rect only

15:30 mi6x3m: Bronsa: I see, so I have to use a function to create the map?

15:30 amalloy: (comp reverse (partial list ...)) seems like it ought to be (comp rseq (partial vector ...)) - gotta eke out all that performance!

15:31 mi6x3m: Bronsa: yeah, works with hash-map

15:31 tnx

15:32 derek_c: does anyone know how to specify a head value in a ring handler? it's returning something like {:status 200 :body "..."}, but I tried adding a :head key and it didn't work

15:32 the resulting HTML has an empty head element

15:32 hfaafb: :body doesn't mean the contents of <body>

15:33 it represents the body of the http response

15:33 derek_c: hfaafb: ah!

15:33 hfaafb: got it. thanks a lot

15:34 hfaafb: yw

15:34 jcromartie: amalloy: I had never heard of rseq before… good to know!

15:37 also, (comp vec (partial map f)) is (comp (partial mapv f))

15:37 soon this will be as concise as it would be with arguments!

15:38 justin_smith: jcromartie: you could also maybe reverse the order of the code and use ->> instead of comp

15:39 dunno if that defeats the point of what you are trying to do

15:40 hyPiRion: jcromartie: and `(comp (partial mapv f))` is just `(partial mapv f)`

15:40 amalloy: (comp reverse (partial list 26)) could also be written as (partial conj '(26))

15:40 jcromartie: well true but I have more in the comp

15:41 amalloy: yeah, just arrived at that oto

15:41 too

15:41 amalloy: that's a better solution than my earlier suggestion of comping rseq and vector

15:41 jcromartie: same for (partial conj (list [0] cycle)) for the args to (partial apply update-in)

15:41 now here's a question: is

15:41 is "let"

15:41 (excuse me, typing difficulties)

15:42 is "let" considered valid in point-free style?

15:42 amalloy: certainly not

15:42 jcromartie: ok

15:42 justin_smith: it's not really point free is it?

15:42 jcromartie: justin_smith: why not?

15:42 justin_smith: the bindings have names

15:42 amalloy: a "point" is a named variable

15:42 bbloom: jcromartie: post a before & after when you're done :-P

15:43 jcromartie: oh let, no

15:43 justin_smith: or am I missing what you are saying altogether

15:43 seangrove: bbloom: From the parent's perspective, layout (for the parent, or for any of its children) is about bounding rect only?

15:44 Whoops, meant to ask essentailly, whether the parent knows the layout of its childrent or is allowed to set the bounding rect of its children

15:45 bbloom: seangrove: only the runtime does any sort of hierarchical layout. any given layout mechanism should only handle a list of rectangles

15:45 jcromartie: justin_smith: I thought you were talking about the code as a whole, not just let bindings

15:45 but point-free programming is not just programming without names

15:45 it's programming without named arguments to functions

15:45 you still need to name things

15:46 I'd like to eliminate the redundant (int \A)

15:47 derek_c: can you write simple text-substitution macros in Clojure? Like for instance, I want a macro that represents two literal elements 1 and 2, so that I can create a vector with 3 elements like this: [(my-macro) 3]. Is that possible?

15:47 amalloy: that's what juxt is for, jcromartie. create two different functions that both want to receive (int \A) and juxt em together

15:48 derek_c: no

15:48 you can write `[~@(my-macro) 3]

15:48 justin_smith: derek_c: for that to work, it would need to be possible to return two things that are not joined by some structure, which just isn't a thing in clojure

15:49 derek_c: the thing is, I'm working with hiccup templates, and I just can't figure out how to properly compose views

15:49 you guys know how hiccup/html takes an arbitrary number of arguments right

15:50 jcromartie: I can just (def a-start (int \A))

15:50 derek_c: so say all my views start with two certain elements, like

15:50 amalloy: derek_c: you want the function named: list

15:50 (html (list a b) c) is the same as (html a b c)

15:50 derek_c: amalloy: oh really?

15:51 amalloy: but that's not a language-level thing right? it's just hiccup looks at the argument and say, ok it's a list, so we do this

15:51 justin_smith: ,(concat [1 2] [3]) in other contexts, there is concat

15:51 clojurebot: (1 2 3)

15:51 amalloy: indeed

15:51 bbloom: seangrove: does that make sense?

15:51 arav93: stuartsierra: Does the construct-calendar private function in clojure.instant take a string as input, I felt it's so by reading through the code, just need to confirm.\

15:53 stuartsierra: arav93: Honestly I don't remember anything about clojure.instant.

15:53 arav93: Yeah, I'm sorry to have disturbed you.

15:53 derek_c: is (list 1 2) the exact same thing as '(1 2)?

15:54 amalloy: thanks a lot!

15:54 amalloy: welllllll, there are a lot of ways to understand that question

15:55 derek_c: found this: http://stackoverflow.com/questions/3896542/in-lisp-clojure-emacs-lisp-what-is-the-difference-between-list-and-quote

15:55 amalloy: if they're evaluated, then yes they have the same value. but if they're passed to a macro that inspects them, it will see something different. or if you need something that's not a literal, rather than 1 and 2, then the two forms do different things...

15:55 justin_smith: ,(do (require 'clojure.instant 'clojure.repl) (clojure.repl/source clojure.instant/construct-calendar))

15:55 clojurebot: Source not found\n

15:55 stuartsierra: `clojure.instant/construct-calendar` just takes integer arguments for each component of the Calendar.

15:55 https://github.com/clojure/clojure/blob/201a0dd9701e1a0ee3998431241388eb4a854ebf/src/clj/clojure/instant.clj#L237

15:55 justin_smith: as is clear if you look at the source

16:00 jcromartie: (def papply (partial partial apply))

16:00 #ohgodwhy

16:01 amalloy: jcromartie: that's in useful, named ap

16:02 though i don't think i ever actually used it

16:04 justin_smith: (def pc (partial conj)) would also make it more succinct

16:04 I meant partial partial conj of course

16:04 Rosnec: does anybody know if the ztellman/gloss library has a means of reading encoded data from an input which possibly has extra bytes on the end?

16:05 jcromartie: oh god oh god oh god

16:05 how about (comp (partial apply mod) reverse (partial list 26))

16:05 oops

16:06 (def parpar (partial partial partial))

16:07 hyPiRion: now just throw in a juxt there and you're set

16:07 justin_smith: (def parpar (apply partial [(take 2 (repeatedly partial))])) ; easier to generalize

16:09 (def parpar (apply partial (take 2 (repeat partial)))) ; fixed

16:10 hyPiRion: justin_smith: (repeat 2 partial) is shorter

16:10 justin_smith: true!

16:10 jcromartie: nice

16:11 mi6x3m-alt: hey who here is using nightcode?

16:11 is seems to be a fun IDE

16:11 quick start and someone effective for small stuff

16:11 justin_smith: (defn parⁿ [n] (apply partial (take n (repeat partial))))

16:11 jcromartie: beat me to it, justin_smith

16:11 justin_smith: heh, I even put a nice superscript in the name

16:13 jcromartie: justin_smith: but you have a named arg!

16:22 oinksoft: what does &name mean in clojure?

16:23 like &form and &env in the source on http://clojuredocs.org/clojure_core/clojure.core/defn

16:23 Bronsa: oinksoft: &name has no special meaning in clojure, it's a regular symbol

16:23 justin_smith: ,((fn [& name] (concat name name)) 1 2 3 4)

16:23 clojurebot: (1 2 3 4 1 ...)

16:23 justin_smith: ,((fn [& name] (concat name name)) 1 2)

16:23 clojurebot: (1 2 1 2)

16:23 weavejester: oinksoft: They’re special macro symbols

16:23 oinksoft: Bronsa: how does defn bind to the name without using a macro?

16:24 weavejester: oinksoft: http://blog.jayfields.com/2011/02/clojure-and.html

16:24 Bronsa: oinksoft: &form and &env are implicit arguments on macros

16:24 oinksoft: thei are bound by the defmacro macro

16:24 oinksoft: but defn isn't defined as a macro?

16:24 or am i readin gthis wrong http://clojuredocs.org/clojure_core/clojure.core/defn

16:25 Bronsa: oinksoft: it is declared as a macro later in the source

16:25 oinksoft: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L318

16:26 weavejester: oinksoft: the clojure.core source code shouldn’t be considered idiomatic Clojure, because it’s bootstrapping the language

16:27 oinksoft: interesting, thanks Bronsa

16:27 weavejester: defmacro is defined after defn in the source, so defn is “manually” converted into a macro

16:27 rasmusto: defmacro is a fn?

16:28 oinksoft: nope it is bootstrapped the same way as a macro

16:28 weavejester: rasmusto: internally macros are functions that are tagged as being macros

16:28 oinksoft: and it calls (list '. (list 'var name) '(setMacro)), which is what is done manually for defn and defmacro

16:29 rasmusto: oh this thing? (. (var defmacro) (setMacro))

16:29 oinksoft: thanks Bronsa and weavejester :)

16:29 Bronsa: rasmusto: yeah. setMacro simply adds :macro true to the Var's meta

16:29 weavejester: Yeah. Needless to say, this isn’t what you should use in your own Clojure apps.

16:30 rasmusto: hah, okay. Thanks for the clarification

16:31 weavejester: Hm, should I go with “reploaded” or “reloaded.repl” for a library of repl functions based off the reloaded workflow

16:32 arrdem: the latter

16:32 weavejester: That was my inclination as well. It gives a nicer namespace

16:32 arrdem: punny names are awesome but hard to remember and search for :P

16:32 Frozenlock: reloaded.repl is indeed nicer

16:32 arrdem: $logs

16:33 right. I'm bot ignored.

16:33 weavejester: punny names do have the advantage of being unique, though.

16:34 Frozenlock: It's the wild west here, first one to grab a namespace gets it!

16:35 arrdem: plz no top level packages

16:35 plz

16:36 * Frozenlock wonders if he should grab as much names as possible, in case they become valuable like the .com domains

16:37 hrathod: https://github.com/john2x/repload

16:37 Frozenlock: Take a dictionary, loop through it and create a clojars project for each one of them... yes, I can see how my master plan would work.

16:37 *evil laugh*

16:37 weavejester: Frozenlock: I actually got burned by something like that. Had to name a project package “lein-gen” instead of “lein-generate” because in Clojars there’s a “lein-generate” that was written in 2010, and has since been abandoned (deleted repo, deleted github user, etc.)

16:38 rasmusto: org.clojure.core2

16:38 Frozenlock: perhaps a year prefix could be the best of both worlds :-/

16:40 weavejester: and contrary to domain names, this one is forever lost :'-(

16:41 weavejester: Frozenlock: Yeah. I toyed around with the idea of asking to see if it could be removed, since it was only downloaded 4 times, but that kinda sets a bad precedent.

16:42 I kinda think those people who use their domain names in their package names might have a point… :)

16:43 * stuartsierra hums quietly

16:44 arrdem: $seen gtrak

16:44 lazybot: gtrak was last seen quitting 1 hour and 49 minutes ago.

16:45 arrdem: weavejester: yeah. my stuff is all me.arrdem/*

16:46 technomancy: domain names are great for common nouns

16:46 arrdem: because I know _I_'m a singleton, so my stuff is safely unique :D

16:46 technomancy: but common nouns are boring

16:46 arrdem: good thing domain registrations are forever, right?

16:47 arrdem: technomancy: I mean.. my namecoins are registered into the next millennium so...

16:48 * arrdem wanders back off to urbit where his fellow "write only universe"rs lurk

16:48 weavejester: stuartsierra: Out of curiousity, is the reason for creating one’s own start/stop/reset functions in user.clj just a question of customisability?

16:48 stuartsierra: weavejester: yes

16:49 You need some way to hook in to application code to call a constructor.

16:49 I've been thinking about making a generic version using com.stuartsierra/component.

16:50 weavejester: stuartsierra: That’s what I was thinking of doing. Not only would it cut down on some boilerplate, but I think it would be better when namespaces fail to load

16:51 stuartsierra: weavejester: Yes. At least one other person has done this that I know of.

16:51 weavejester: stuartsierra: i.e. you could still have a “reset” even if your own code failed to load.

16:51 stuartsierra: Oh, do you recall who it was?

16:51 stuartsierra: weavejester: No, it's buried in the comments on my original blog post on thinkrelevance.com

16:51 weavejester: stuartsierra: I’ll take a look through it. Thanks for the pointer.

16:51 stuartsierra: you're welcome

16:53 weavejester: stuartsierra: Incidentally, have you found yourself needing to use “bridge” components at all? For example, I have a HTTP server component, and a component that handles websocket connections. To connect them I use a bridging component that just creates a handler with some static content, but doesn’t actually have state.

16:54 stuartsierra: weavejester: All the time. Sometimes I even just have an empty map with some dependency metadata.

16:54 weavejester: stuartsierra: Oh good. It’s not just me, then!

16:55 stuartsierra: I'm not sure yet if I like it, design-wise, but it doesn't cause any problems that I can see.

16:56 weavejester: It feels a little off, design-wise, for me too. But I haven’t been able to come up with anything better that doesn’t add unnecessary complication.

16:58 stuartsierra: I was toying around with the idea of a “::provides” metadata value though

16:58 For components that have a single useful value, like :handler

16:59 stuartsierra: I justify it (empty components) on the grounds that I am merely reifying a structure that was implicit in the code anyway.

16:59 weavejester: (component/using (component/bridge make-handler) [:app])

17:00 stuartsierra: I have also written components whose main job is to create and cache a value.

17:00 I usually provide access to that value through a function.

17:01 I hadn't thought about declaring that in the metadata.

17:01 weavejester: stuartsierra: It sounds like it might be possible to write some functions around common patterns, in the same way system-map exists

17:02 stuartsierra: Very likely.

17:02 weavejester: I’ll toy around with the concept and see if I can’t come up with something useful.

17:02 stuartsierra: I always want to try those things out in apps before codifying them in a shared library. That's how system-map came about.

17:03 weavejester: stuartsierra: Yeah, same here. My feeling is that you need to be pretty sure a function is going to be useful before including it in a library.

17:04 But I think in all the component-based stuff I’ve done, I wind up with an awful lot of components who are depended upon for a single value.

17:04 e.g. databases for their connections. apps for their handler functions. etc.

17:05 ^{::provides :handler} (new-hander-provider …), ^{{:provides :conn} (new-database …)

17:05 stuartsierra: Yes, I've seen both types as well: "connection" objects and pre-compiled functions.

17:05 weavejester: Maybe. I’m not sure :)

17:05 stuartsierra: What would you do with that metadata?

17:07 weavejester: stuartsierra: Use it when handling the dependencies, so instead of passing the whole component, we pass the value it wraps.

17:07 stuartsierra: Oh, I see.

17:07 Hmmm.

17:08 weavejester: {:server (using server [:app]), :app (provides app :handler)}

17:08 stuartsierra: Not sure about that. Feels like it's exposing internal details.

17:08 weavejester: stuartsierra: Yeah, I’m not sure either. I got halfway writing up an issue about it, then changed my mind.

17:09 stuartsierra: Try it out and see how it goes.

17:11 I'd much rather have experience reports than issues or patches.

17:14 weavejester: stuartsierra: We’re thinking along the same lines. I was going to try it out in my next project.

17:14 stuartsierra: weavejester: cool

17:18 shiranaihito: https://www.refheap.com/77439 -- how do inner maps get created there?

17:21 dnolen_: ,(assoc nil :foo 'bar)

17:21 clojurebot: {:foo bar}

17:21 dnolen_: shiranaihito: ^

17:21 bbloom: dnolen_: i was literally typing that

17:21 noonian: me too lol

17:21 bbloom: well, :x and 1

17:21 noonian: :foo and 17

17:22 bbloom: noonian: dnolen_ likes the classics

17:22 shiranaihito: oh :p

17:22 noonian: yeah, i like using symbols as values also; i think that's something that people new to clojure don't usually understand off the bat

17:22 shiranaihito: kinky

17:23 that seems like weird behaviour though

17:24 H4ns: hi. it's the simple things that make me struggle always: how do i get {1 2, 3 4} from [1 2 3 4]?

17:24 noonian: ,(apply hash-map [1 2 3 4])

17:24 clojurebot: {1 2, 3 4}

17:24 noonian: ,(doc hash-map)

17:24 clojurebot: "([] [& keyvals]); keyval => key val Returns a new hash map with supplied mappings. If any keys are equal, they are handled as if by repeated uses of assoc."

17:24 H4ns: noonian: ah, thanks!

17:25 noonian: np

17:27 shiranaihito: "(apply hash-map [1 2 3 4])" <-- damn, i actually wrote a helper method for that.. :p

17:28 dnolen_: ,(into {} [1 2 3 4])

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

17:29 dnolen_: oops

17:29 ,(into {} [[1 2] [3 4])

17:29 clojurebot: #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )>

17:29 dnolen_: ,(into {} [[1 2] [3 4]])

17:29 clojurebot: {1 2, 3 4}

17:29 dnolen_: erg, anyways, also ^ depending

17:32 rasmusto: ,(into {} (partition 2 [1 2 3 4]))

17:32 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry>

17:32 rasmusto: ,(into {} (map vec (partition 2 [1 2 3 4])))

17:32 clojurebot: {1 2, 3 4}

17:32 rasmusto: alternatively ##(into {} (mapv identity (partition 2 [1 2 3 4])))

17:32 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry

17:32 rasmusto: hah, nvm

17:38 TEttinger: I think the apply hash-map solution is cleanest?

17:39 tuft: i think apply hash-map fixes the concrete type, while into {} doesn't

17:39 TEttinger: I don't even know what a concrete type is in this context

17:39 noonian: with into you have to massage the input vector a bit

17:40 hash-map vs array-map or tree-map i guess

17:40 but i doubt the OP care's

17:41 itruslove: Can anyone tell me what the "dev-resources" resource path is intended for?

17:41 https://github.com/technomancy/leiningen/blob/7cc9d6163244fba1f0eedea43396b2a6a04528e9/leiningen-core/src/leiningen/core/project.clj#L424

17:41 It sounds like it's a default resources directory for dev, but it's defined in the :base profile.

17:46 vendethiel: Mhhm, isn't `(fn [& [a b]] ())` the same as `(fn [a b] ())` ?

17:46 Ooh; I guess the first form makes them optional

17:47 technomancy: itruslove: the purpsoe is the same

17:47 if it were in :dev, user-defined :dev profiles would override it

17:50 itruslove: technomancy: gotcha, thanks

17:51 holo: hi

17:53 I have a dilemma (revisited): to store or not to store generated.js and generated.css in git. the problem is, other collaborators may forget to run build after pull and not understand immediately their problem is they are running some outdated version of .js or .css

17:54 how are you guys/girls doing this?

17:55 dbasch: holo: explain the required steps in your README file

17:56 holo: dbasch, that's what I'm doing. my thinking was: humans are just unreliable

17:57 rasmusto: how about a makefile? :)

17:57 eh, probably just a blurb in a readme telling them to rerun everything is good

17:57 so long as they don't have to do anything manually

17:58 blake: Style/idiom question: Given data of keyed values {:k1 :v1 :k2 :v2} and a map of new names for keys {:k1 :l1 :k2 :l2} I want an output of {:l1 :v1 :l2 :v3}. I'm using:

17:58 (zipmap (map val a-map) (map data (map key a-map)))

17:58 nullptr`: echo 'alert("Hey! You need to run lein something-or-other!");' >> generated.js

17:58 lazybot: 'alert("Hey! You need to run lein something-or-other!");' >> generated.js

17:59 blake: ((I get the desired results.)

17:59 holo: rasmusto, that's the point, rerun already implies manual! or at least I think it does

18:00 rasmusto: holo: so they're just opening this stuff in a browser (without running any clojure tools)?

18:02 dbasch: blake: http://clojuredocs.org/clojure_core/1.2.0/clojure.set/rename-keys

18:03 holo: rasmusto, they (one person only actually) are using lein. yeah ok, maybe I can drop also a msg in :init

18:04 dbasch: ,(clojure.set/rename-keys {:k1 :v1 :k2 :v2} {:k1 :l1 :k2 :l2})

18:04 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

18:04 holo: rasmusto, actually :repl-options {:welcome "bla"}

18:04 rasmusto: holo: cool, that should work well imo

18:04 holo: we are running the app under lein repl :)

18:05 rasmusto, thanks for the chat hehe :)

18:08 blake: dbasch: Thanks!

18:11 dbasch: rename-keys ... cannot resolve symbol.... I need to include clojure.set?

18:12 dbasch: blake: yes

18:12 blake: dbasch, tx

18:22 justin_smith: vendethiel: also the first form allows providing extra ignored args

18:22 vendethiel: justin_smith: noted, thanks :)

18:24 perses: what is the wrong in this code, http://sprunge.us/bEjG , it doesn't work

18:27 justin_smith: perses: I get a stack overflow, try changing the self call in find-sqrt to recur

18:28 never mind, that just changes the overflow into a seemingly infinite loop

18:29 perses: justin_smith: can't i make a recursing in clojure?

18:29 justin_smith: it is not tail call optimized unless you use recur or trampoline

18:29 without the optimization, this code is running out of stack

18:29 because somewhere the guess is not getting improved where it should be

18:30 perses: i guess it should be a very basic for a fp to use recursing in this way

18:31 justin_smith: you guess wrong, or maybe clojure isn't fp

18:32 or maybe it is easy but we don't do it anyway

18:32 perses: maybe i'm wrong about clojure

18:32 justin_smith: recur don't terminate

18:32 justin_smith: right, like I said, I added a print statement, and your code keeps guessing 2.0 but not accepting that guess

18:32 Bronsa: perses: your good-enough? function is wrong

18:33 amalloy: perses: you may want an absolute-value in good-enough

18:33 oh, and it should read (* guess guess), not (* guess n)

18:33 maybe? i dunno. i'm bad at this. i resign

18:34 Bronsa: perses: http://sprunge.us/SMec?clj

18:40 justin_smith: (defn good-enough? [n guess] (<= (Math/abs (- n (square guess))) 0.1))

18:40 that def fixes the code

18:41 also, a good trick when something is recursing infinitely is add a println of the args and a (Thread/sleep 1000) to the top of the thing

18:41 that often helps expose the problem

18:49 technomancy: $seen brehaut

18:49 lazybot: brehaut was last seen quitting 2 weeks ago.

19:02 Frozenlock: Does lein select JRE by default?

19:03 justin_smith: it should use your default java

19:03 I don't think the question of whether it is jre / jdk would come into play normally

19:03 koreth_: Is there an equivalent of mapcat that returns a set rather than a list? Obviously (apply hash-set (map f coll)) works, but if there are a lot of duplicate values that'll waste memory building the intermediate list.

19:03 Frozenlock: justin_smith: Ah I see, so it's my fault :)

19:04 Yeah, but I want to use the jvisualvm

19:04 koreth_: Or maybe I should be using reduce rather than map.

19:04 justin_smith: Frozenlock: ahh, so you need the dt-socket to be open - but that should work across jvm versions anyway

19:05 Frozenlock: justin_smith: I don't know... when I ran jvisualvm it just said that I needed to run the JDK, not the JRE

19:05 justin_smith: koreth_: yeah, or use into #{} - that shouldn't hold onto the head

19:05 Frozenlock: oh, ok then

19:06 ,(into #{} (map inc (range 10)))

19:06 clojurebot: #{7 1 4 6 3 ...}

19:06 rasmusto: ##(into #{} (map inc (range 10)))

19:06 lazybot: ⇒ #{1 2 3 4 5 6 7 8 9 10}

19:06 rasmusto: just checking hashing order, don't mind me

19:06 justin_smith: versions!

19:07 amalloy: rasmusto: /msg the bots, if you don't have a reason for everyone to read what you're writing

19:07 justin_smith: ,*clojure-version* ##*clojure-version*

19:07 clojurebot: {:major 1, :minor 6, :incremental 0, :qualifier nil}

19:08 justin_smith: I guess lazybot has some anti-quine magic

19:09 hyPiRion: justin_smith: yeah, sorry about that

19:09 justin_smith: :)

19:09 amalloy: justin_smith: really it's a quirk of how ## parses - he reads the string that comes after ##, and if it's not a collection (usually a list, of course), he assumes you are talking about an irc channel like ##java or something

19:09 justin_smith: oh, OK

19:09 ,*clojure-version* ##(do *clojure-version*)

19:09 clojurebot: {:major 1, :minor 6, :incremental 0, :qualifier nil}

19:09 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

19:09 amalloy: lazybot giving an error message after every mention of ##java gets old fast

19:09 justin_smith: right

19:10 rasmusto: "##java gets old fast" -amalloy

19:10 :)

19:11 dbasch: koreth_: you could do (distinct (map …)), distinct is lazy

19:11 justin_smith: (inc dbasch)

19:11 lazybot: ⇒ 1

19:11 justin_smith: great idea

19:13 hyPiRion: rasmusto: keep in mind that the order is incidental

19:14 seangrove: bbloom: In :fixed vs :canvas (absolute), is the fixed positioning still relative to the parent or to the root view of the UI? I would expect the former. Luckily, CSS does the latter.

19:15 hyPiRion: ,(apply = (map (comp seq set) [(range -10 11) (range 10 -11 -1)]))

19:15 clojurebot: true

19:15 seangrove: s/luckily/irritatingly

19:15 rasmusto: hyPiRion: ah, I knew that. Was just curious of how the new hash algo ordered integers

19:15 hyPiRion: alright

19:16 bbloom: seangrove: i don't recall

19:16 justin_smith: ##(apply = (map (comp seq set) [(range -10 11) (range 10 -11 -1)]))

19:16 lazybot: ⇒ false

19:16 hyPiRion: Hrm, didn't know there were hashing changes from 1.4.0 to 1.5.0

19:16 justin_smith: not that any of us should be using 1.4 at this point

19:16 1.6.0

19:16 amalloy: hyPiRion: there were some in 1.6, not 1.5

19:17 afaik there weren't in 1.5, anyway

19:17 hyPiRion: amalloy: (apply = (mapv (comp seq set) [(range -10 11) (range 10 -11 -1)])) returns false on 1.5.1

19:17 amalloy: okay, and also in 1.4. so, both of those are different from 1.6, which supports my claim?

19:18 hyPiRion: oh, I mixed clojurebot and lazybot versions

19:24 Frozenlock: uh... what is this... I just changed my path, only to realize that the java in the /bin folder is a link to the JRE bin o_O

19:24 (trying to get the JDK)

19:25 justin_smith: you can just replace the symlink to the JRE with a symlink to the JDK, no?

19:25 hyPiRion: Frozenlock: which OS are you using?

19:25 Frozenlock: that's the thing, where I was expecting the JDK java, I found a link to the JRE binary

19:25 Ubuntu

19:25 justin_smith: on a debian based system you would use update-alternatives, and it would bea symlink to a symlink

19:25 Frozenlock: use update-alternatives

19:26 hyPiRion: Frozenlock: `sudo update-alternatives --config java`

19:26 justin_smith: https://help.ubuntu.com/community/Java

19:26 above link also covers manually installed java, so you can make sure it is visible to the alternatives system

19:26 amalloy: update-alternatives mystifies me. i don't know when i'm supposed to use it or how

19:26 Frozenlock: hyPiRion: That's what I used first, but I only saw JRE choices

19:27 hyPiRion: Frozenlock: did you install through apt-get/aptitude?

19:27 Frozenlock: I honestly don't remember. I might just reinstall everything

19:28 amalloy: Frozenlock: bathe your computer in acid to make sure the reinstall is complete

19:28 justin_smith: amalloy: picking defaults - it is done using a system of symlinks; you can manually replace the symlink with one pointing to a different target file, or use their weird semi-interactive CLI

19:28 Frozenlock: https://www.refheap.com/77448 <---- only JRE choices o_O

19:28 justin_smith: Frozenlock: you will know it was not installed via apt if it is not presented as an available alternative, my link above shows how to make it one

19:29 Frozenlock: OK, so use the instructions on my link above under "Oracle Java 7"

19:29 or just fuck it and replace /usr/bin/java with the symlink or binary of your choice

19:29 amalloy: Frozenlock: that's fine. my java bin lives in /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java

19:30 hyPiRion: Frozenlock: yeah, that's the JDK version. Try out `java -version` and see for yourself

19:30 Frozenlock: OpenJDK Runtime Environment (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.12.04.2)

19:30 OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)


19:30 arggg

19:31 * Frozenlock kills jvisualvm with a shotgun

19:31 rasmusto: kill -9gauge

19:31 justin_smith: Frozenlock: just tell the alternatives system that the jdk is the right default

19:31 hah

19:31 sometimes I miss xblast

19:32 seancorfield: (inc rasmusto)

19:32 lazybot: ⇒ 8

19:32 seancorfield: That made me laugh out loud!

19:32 rasmusto: glad I could help :)

19:33 technomancy: update-alternatives is like if you took rvm and made it not suck and work for anything

19:36 Frozenlock: does JDK use a different name than java? (like I said, 'java' in the JDK is a link to the JRE java)

19:38 amalloy: i'm pretty sure the thing in .../jdk/jre/bin/java is what you want to use

19:39 justin_smith: Frozenlock: wait, the one inside the jdk folder is a symlink to the jre one?

19:39 Frozenlock: amalloy: I always used it without any problems. But I want to try jvisualvm and it insists on telling me that I'm using the JRE instead of the JDK.

19:39 justin_smith: looks like it

19:40 * Frozenlock wonders if he did that monstrosity himself

19:40 amalloy: Frozenlock: no, that's just how the jdk is distributed

19:40 mine looks that way too

19:40 when you download a jdk, it comes with a jre

19:40 and that's the same java

19:40 it's not like it has a different java executable based on whether you want to pretend you're not using a jdk

19:43 justin_smith: Frozenlock: it could be the jvisualvm is reporting the wrong error, and you are calling a jvisualvm that is incompatible with the specific jvm?

19:44 Frozenlock: maybe

19:44 I'm looking for vjisualvm similar problems

19:44 justin_smith: there should be a version of visualvm inside the jdk file heirarchy - maybe that is not the same one you are invoking?

19:47 Frozenlock: eh, it works if I launch with --jdkhome <my-JDK-path>. GOOD ENOUGH

19:47 blake: If I want "(defn my-func [parm1 parm2 parm3=nil] ..." such that parm3 is either passed in by the user or is nil, do I have to do a multi-arity setup?

19:48 amalloy: blake: you want to support multiple arities (2 or 3), so...

19:49 justin_smith: it is doable with (fn [parm1 parm2 & [parm3]] ...) which is also multi-arity, but in a different way

19:49 blake: amalloy: Just checkin'. It's not like there's only way to do stuff.

19:49 justin_smith: Yeah, but doesn't that have other implications?

19:49 justin_smith: also means it will take and ignore any further arguments

19:50 blake: ...because the remainder of the arguments are passed in a vector and I'm only taking the first element of any vector?

19:50 justin_smith: but is more concise than the explicit (fn ([p1 p2] ... ) ([p1 p2 p3] ...)) version

19:50 blake: exactly

19:51 blake: justin_smith: That makes me nervous because I'm still getting parens wrong enough to where the arity check probably helps me from tearing my hair out (as if I had hair).

19:52 I guess it seems goofy to have a fn[parm1 parm2 parm3] followed by fn[parm1 parm2]=>(fn parm1 parm2 nil).

19:52 justin_smith: fair enough, then use the more verbose, more strict version

19:53 or add an explicit check (fn [a b c & [d :as rest]] (assert (< (count rest) 2))) but that seems a little silly

19:53 blake: Heh. Yeah.

19:53 amalloy: justin_smith: btw, you should really avoid doing comparisons on the result of count. you never know when infinite sequences will crop up

19:54 blake: ooh

19:54 amalloy: (< (count x) 2) => (not (next x))

19:54 justin_smith: amalloy: even in a rest arg ? I guess if someone called apply on something infinite?

19:54 amalloy: for sure

19:55 you can (apply f (range)), no problem

19:55 justin_smith: oh, of course

20:21 coventry: blake: If you're getting parens wrong a lot of the time, it's probably worth taking half and hour or so to learn paredit mode, or whatever the equivalent is in your browser.

20:21 amalloy: coventry: such a badass he turns paredit on in his browser

20:21 coventry: s/browser/editor/. :-) Thanks.

20:25 dbasch: coventry: I’d say it’s worth it regardless. Nobody should be spending cognitive power balancing expressions.

20:27 coventry: Anyway, kovasb's session has paredit https://github.com/kovasb/session#paredit

20:35 dsrx: coventry: holy cow that is really cool. stepped away from clj/cljs for a few weeks and this comes out O_O

20:42 bbloom: coventry: i enjoy the namespace name for his paredit functionality

20:42 it's in subpar/core.cljs :-)

20:45 coventry: Heh.

20:46 bbloom: $mail kovasb Hey man, you're paredit functionality is really *ahem* subpar.

20:46 lazybot: Message saved.

20:46 bbloom: d'oh i suck at spelling

20:47 amalloy: bbloom: you can $unmail kovasb, if you don't want him to know your a bad speller

20:47 bbloom: $unmail kovasb

20:47 lazybot: Deleted unread messages from bbloom to kovasb

20:47 bbloom: $mail kovasb Hey man, your paredit functionality is really *ahem* subpar.

20:47 lazybot: Message saved.

20:48 bbloom: amalloy: spared me having to write a bad follow up self-deprecating joke

20:48 amalloy: bbloom: i just wanted an excuse to use the wrong your in my response

20:48 bbloom: amalloy: haha i didn't even notice

20:49 amalloy: this is my biggest debugging weakness. i'm so used to reading/writing error-filled nonsense on the internet... my eyeballs have built in auto correct

21:11 eraserhd: Anyone want to converse to try and find an elegant solution to a monad-like kind of problem?

21:12 The problem is this: I want to find a way to thread functions that deal with two values. 1st is the "state", which should thread much like -> threads through composable functions.

21:13 But the second is a list of "effects", which I want to hide most of the time.

21:19 weavejester: eraserhd: A list of effects? Effects on the state, or something else?

21:20 eraserhd: Effects are tokens that represent side-effectful things to be performed.

21:21 Examples: [:beep], [:write-file "/tmp/foo.txt" "hello"], ...

21:21 The idea is to make a composable way to collect these.

21:22 weavejester: That’s an interesting problem, and as you point out, very close to the state monad.

21:26 eraserhd: I don’t have an immediate answer for you, unless you want to try one of the monad libraries

21:40 zspencer: is there something similar to apply but doesn't take a collection?

21:41 I've got a map of keywords to functions and I want to execute the returned function inside of a threading operator

21:41 (making an example)

21:42 eraserhd: zspencer: apply, but make the last argument []

21:43 Oh, you can't just ((:foo map)) in the threading operator?

21:44 zspencer: https://gist.github.com/zspencer/4d378e1d1d833041ccd5

21:44 yeah, the last argument right now is a vector :(

21:44 The larger context: https://github.com/zspencer/clj-warrior/blob/master/src/play.clj

21:44 also, hi jason :)

21:45 alew: you could define (defn invoke [f & args] (apply f args))


21:45 eraserhd: zspencer: We've been here for years. Glad you gave up ruby.

21:45 zspencer: alew: that's a reasonable thing; I just figured clojure would have something built in

21:46 i.e in javascript func.call(context, foo, bar) vs func.apply(context, [foo, bar])

21:46 eraserhd: The form you're looking for is really just (func foo bar) in clojure, it's the threading macro that's screwing you up.

21:47 IMHO

21:47 zspencer: Yea, I switched to the threading operator beacause it seemed clearer

21:48 but maybe I should consider composition for the steps

21:48 i.e. "take the players turn, then the ais turn"

21:48 All my code is bad and I feel bad

22:00 eraserhd: zspencer :/

22:08 hlprmnky: zspencer: the best piece of advice I’ve gotten so far about the threading operator is this, from a code review I was fortunate enough to have Hugo Duncan do of some bad code I’d written - he said, and I paraphrase: What I usually do is get everything working the way I want first, and then go through and look to add threading in a second pass, to make things concise

22:22 TravisD: Does anyone know of any libraries that allow you to manage your own random number generator, etc?

22:23 zspencer: hlprmnky: that's a reasonable thing.

22:37 bob2: TravisD, as in with a specific seed? http://docs.oracle.com/javase/7/docs/api/java/util/Random.html

22:38 TravisD: bob2: Ah, yeah, I keep forgetting that all of java is available

22:43 I was also hoping to have some choice of the method used

22:44 and for some snazzy clojure interface :)

22:44 zspencer: hlprmnky / eraserhd here's what I wound up with: https://github.com/zspencer/clj-warrior/blob/master/src/play.clj#L60

22:56 coventry: Is there any test.check code out there already for producing a lot of random deeply nested structures. Ideally with lots of structural sharing, but I can probably add that in myself.

23:25 owl-v-: how do i add v elements to vv one by one? (let [v [1 2 3]] (let [vv []] (map #(conj vv %) v)))

23:26 amalloy: owl-v-: you can't do that with map, because clojure data structures are immutable. instead, you would use reduce, something that builds up a single result from multiple input items

23:27 or in the specific case of conj, you can just use into: (into [] v) yields a vector containing all the items in v

23:30 bodie_: hi all, not sure if I'm doing something stupid or what -- do I need to be mindful of using hyphens in namespaces / in paths in my project tree with lein?

23:30 I keep getting a not found error

23:31 koreth_: What's the best way to do the equivalent of "rest" on a sorted set without losing the sortedness? (rest (sorted-set 0 1 2)) returns a plain old sequence.

23:31 ,(rest (sorted-set 0 1 2))

23:31 amalloy: yes. namespaces want -, and the path needs _ instead

23:31 clojurebot: (1 2)

23:31 koreth_: ,(sorted-set 1 2)

23:31 clojurebot: #{1 2}

23:31 amalloy: disj

23:32 koreth_: Thanks

23:32 bodie_: http://paste.ubuntu.com/7280810/

23:32 I see

23:32 so, use _ in the path?

23:49 amalloy: yes, bodie_

Logging service provided by n01se.net