#clojure log - Apr 17 2014

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

0:11 kenneth: hey all

0:12 so i'm not sure if this is a clojure thing; because i'm actually trying to code in wisp; but

0:12 i'm trying to make a macro that creates code which includes a hashmap

0:14 ambrosebs: kenneth: looks like wisp macros are similar to clojure

0:14 kenneth: let's pretend for the sake of simplicity that i want to (defmacro hello [x] (quote {(keyword x) x})), and i want this (hello foo) to be equivalent to {:foo foo}

0:15 when i try to include {} in my macro it errors

0:16 this is the code i'm playing with right now: https://gist.github.com/kballenegger/10952318

0:19 wisp doesn't seem to have (hash-map :one 2)

0:21 ambrosebs: kenneth: maybe (defmacro [x] `{~(keyword x) '~x})

0:22 what's expected input/output?

0:28 dissipate: macros are hard, just use functions

0:30 nightfly: functions are hard, just use expressions

0:35 dissipate: nightfly, core.logic? :D

0:54 Frozenlock: I'd like to have a blog with my compojure site. Is there anything plug'n'play for that?

1:03 kenneth: GOT IT

1:03 https://gist.github.com/kballenegger/10952318

1:03 woooo

1:14 sm0ke: hello i am trying to use piggieback for brepl, is it automatically launched with `lein repl`?

1:28 Frozenlock: Might be a better idea to just use a subdomain and octopress...

1:37 john_s: with vim-fireplace, if i'm connected to an nREPL, everything should be evaluated in a single context, right? i have a user.clj and it's working fine from the repl itself but seems to be unavailable from fireplace unless i explicitly require the namespace

1:48 irctc: i am getting the problem with propertis file how to use the seprate data base for testing

1:49 ambrosebs: john_s: do you get an error?

1:49 john_s: sometimes I need to :reload a namespace via lein to be able to use it in fireplace.

1:49 john_s: not sure why.

1:50 john_s: ah, interesting. yeah, i get "java.lang.RuntimeException: Unable to resolve symbol: reset in this context"

1:50 unless the current buffer is my user.clj or my project.clj

1:55 sm0ke: hmm how do i get sourcemaps working with a ring server?

2:01 john_s: ambrosebs: ah, it appears that (require '[some-ns :refer :all]) wasn't behaving like i expected it to

2:02 ambrosebs: when switching buffers, i lose the :refer :all (probably a logical way to prevent collisions)

2:02 ambrosebs: thanks for your help!

2:03 ambrosebs: john_s: ahk cheers

2:32 yedi: bbloom: would love a 'how this differs from CinC" section in the readme for https://github.com/brandonbloom/eclj

2:52 irctc: hello some body plz tell me how we write the config file for my data base

3:50 perses: hello

3:50 kenneth: what if i'd like to concatenate a symbol from two symbols in a macro

3:50 derek_c: can you use lein itself to connect to a nrepl?

3:50 kenneth: is that possible?

3:54 perses: i have a function which return structure like this (([1 2] [3 4]) ([5 5] [0 8])), when apply (apply concat result) i got ((1 2 3 4) (5 5 0 8)), but when try it at repl it's working

3:54 ,(apply concat '(([1 2] [3 4]) ([5 5] [0 8])))

3:54 clojurebot: ([1 2] [3 4] [5 5] [0 8])

3:54 perses: that's the right result, but when i do in the code i got it wrong

3:57 that's the actual code http://sprunge.us/ICcW

3:58 i guess the reason is in lasy-seq?

3:58 even i print final-edges i got another values

3:58 maybe the last values of the last line

3:59 how can i got the result for all lines?

4:03 isn't there anybody here for help?

4:05 katratxo: derek_c: `lein repl :connect [dest]` https://dpaste.de/5wyv/raw

4:07 samrat: perses: the (def ..) is redefining final-edges each time

4:08 perses: samrat: so how can i fix this?

4:09 derek_c: katratxo: thanks a lot!

4:50 perses: when i save the serialize data to a file and then load this data again as str then deserialize it i got error, i'm using methods there http://sprunge.us/fQca ?

4:50 can anybody help?

4:51 Anderkent: perses: what kind of error do you get? Is the byte array large enough?

4:52 perses: Anderkent: nope i got something string like 1221rer211 only

4:52 clgv: perses: you probably need to "flush" the stream

4:52 before you get the array

4:52 Anderkent: clgv: the OOS is closed before .toByteArray

4:52 that should work

4:53 clgv: ah right

4:54 Anderkent: perses: I assume the missing doublequotes around docstrings are just a paste error

4:54 clgv: perses: whats your exact input?

4:54 a quick test worker for me

4:55 Anderkent: yeah that too ;)

4:55 s/worker/works

4:56 ,(defn serialize Serializes value, returns a byte array [v] (let [buff (java.io.ByteArrayOutputStream. 1024)] (with-open [dos (java.io.ObjectOutputStream. buff)] (.writeObject dos v)) (.toByteArray buff)))

4:56 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Parameter declaration Serializes should be a vector>

4:56 clgv: ,(defn serialize [v] (let [buff (java.io.ByteArrayOutputStream. 1024)] (with-open [dos (java.io.ObjectOutputStream. buff)] (.writeObject dos v)) (.toByteArray buff)))

4:56 clojurebot: #<CompilerException java.lang.ExceptionInInitializerError, compiling:(NO_SOURCE_PATH:0:0)>

4:56 Anderkent: huh

4:57 clgv: ah well I got the following (-> {:a "bla"} serialize deserialize) ; => {:a "bla"}

4:57 perses: [B@bba4cd7 this is the result of serialize, i have saved it to a file, then i do (deserialize (slurp "/tmp/file")), i got java.lang.ClassCastException: java.lang.String cannot be cast to [B

4:57 clgv: perses: anyway you wont be happy with java serialization for clojure datatypes

4:58 Anderkent: perses: oh, you can't just print a byte array

4:58 neither can you slurp something and pass it to readObject

4:59 clgv: perses: you have to write it to a file via a fileoutputstream

4:59 perses: so you can skip the bytearrayoutputstream for the file scenario ;)

5:00 Anderkent: slurp works on text files, so it returns a string; what you want is (require '[clojure.java.io :refer [file output-stream input-stream]) (with-open [out (output-stream (file "path"))] (.write out (serialize "myobj")))

5:00 clgv: perses: but as I hinted before you'll store a lot of useless internal structure for clojure datatypes when you use serialization

5:00 Anderkent: (serialization is evil in general and you really shouldnt use it unless you absolutely have to)

5:01 clgv: Anderkent: nah. I would not go that far. you'd just define a serialization pattern for clojure datastructures. once you got that right it wont change anymore and your are safe ;)

5:01 ddellacosta: no way, serialization is awesome

5:02 clgv: it's almost equivalent to defining a binary reader/writer for clojure data

5:02 ddellacosta: says me and my database

5:02 Anderkent: unless say you put an Exception in your clojure data structures and then java changes the way exceptions are serialized in a patch version upgrade

5:02 clgv: delluminatus: :D

5:02 Anderkent: (totally not looking at https://github.com/elasticsearch/elasticsearch/issues/3145)

5:02 clgv: Anderkent: well dont do that ;)

5:02 Anderkent: .. don't use exceptions?

5:02 clgv: Anderkent: convert it to a clojure map ^^

5:03 Anderkent: or, you know, use a sane serialization library instead of builtin java

5:03 clgv: Anderkent: no dont serialize exceptions ;)

5:03 ddellacosta: yeah, I should qualify that, serialization with clojure data structures is a win

5:03 clgv: Anderkent: yeah. used kryo for that

5:22 perses: clgv: sorry i got DC

5:22 clgv: still there?

5:22 clgv: perses: yes

5:23 perses: clgv: you told i should use fileoutstream

5:23 clgv: perses: if you want to serialize to a file, yes

5:23 perses: yeah

5:23 perses: so what is the code should be?

5:24 clgv: replace yout bytearraystreams with the corresponding filestreams

5:24 *your

5:27 Anderkent: perses: https://www.refheap.com/76981

5:32 clgv: Anderkent: include the "file" expression in the functions and return the filename in "serialize" then you can roundtrip via -> ;)

5:35 Anderkent: maybe, but this way you can send to anything :P

5:38 perses: Anderkent: i got thread "main" java.lang.RuntimeException: java.lang.Exception: lib names inside prefix lists must not contain periods

5:39 Anderkent: https://www.refheap.com/76984

5:39 Anderkent: right, within a ns form its (:require [clojure.java.io :refer [file output-stream input-stream]])

5:40 (require ' ) is what you use just in a repl when you can't be bothered to use (ns)

5:43 Frozenlock: Ugh... my mouse is dying. I'll need a replacement. Anyone fell in love with a particular model?

5:44 Anderkent: depends what you do with it. for just programming / browsing internets i like the vertical ones

5:44 Frozenlock: It does look comfortable.

5:46 dsrx: pshaw, who needs a mouse

5:46 Frozenlock: I know, right...

5:46 Emacs is frowning on me

6:11 perses: Anderkent: ping

6:11 i got java.lang.RuntimeException: Unable to resolve symbol: output-stream in this context, compiling

6:12 Anderkent: perses: did you fix your require form?

6:12 output-stream is in clojure.java.io

6:13 perses: (require [clojure.java.io :refer [file output-stream input-stream]])

6:13 Anderkent: it should be :require at the beginning there

6:14 assuming it's in the ns macro

6:14 perses: yeah it

6:15 Anderkent: still get Unable to resolve symbol: output-stream in this context, compiling:

6:15 Anderkent: post your code somewhere?

6:18 perses: Anderkent: http://sprunge.us/JgCd

6:18 Anderkent: ugh that site eating the double quotes is really annoying

6:19 that code works for me, what version of clojure are you using?

6:19 (other than foobar not being a thing, obviously)

6:19 clgv: Anderkent: string quotes ;)

6:20 Anderkent: right

6:20 clgv: I am sold on [clojure.java.io :as io]

6:21 perses: Anderkent: how can i know?

6:23 Anderkent: it'll be in your project.clj

6:23 or the *clojure-version* var

6:23 clgv: perses: lol. you should specify it as dependency in project.clj

6:24 ,(clojure-version)

6:24 clojurebot: "1.6.0"

6:24 Anderkent: ,*clojure-version*

6:24 clojurebot: {:major 1, :minor 6, :incremental 0, :qualifier nil}

6:24 clgv: better use the function ;)

6:25 martinklepsch: Sente is pretty cool: https://github.com/ptaoussanis/sente :O

6:25 Anderkent: but function call blahblah overhead blah

6:26 clgv: yeah thats definitely an application hotspot here :P

6:26 Anderkent: it is if it's your entire application!

6:27 clgv: it is not if it is only run once ;)

6:27 perses: Anderkent: i have "1.3.0"

6:27 clgv: perses: time to upgrade^^

6:28 perses: clgv: lein upgrade?

6:29 clgv: no

6:29 perses: change your dependency declaration on clojure in your project.clj

6:29 ,(use 'clojure.java.io)

6:29 clojurebot: nil

6:29 clgv: ,(meta #'output-stream)

6:29 clojurebot: {:ns #<Namespace clojure.java.io>, :name output-stream, :added "1.2", :file "clojure/java/io.clj", :column 1, ...}

6:30 clgv: well wont change much. your code should work with 1.3 as well

6:32 Anderkent: yeah it should work on 1.3. Try cleaning the project, maybe? Dunno.

6:32 clgv: repl restart^^

6:56 irctc: hello how I am using a config file to store passwords / keys for DB and connection

6:58 clgv: irctc: you can use a clojure hashmap in the config file and load it via clojure.edn/read

7:30 oskarth: another option is to the store it in ENV keys

7:40 fizruk: ,(clojure.set/union [1 2 3] [1 3 5])

7:40 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set>

7:43 clgv: ,(require 'clojure.set)

7:43 clojurebot: nil

7:43 clgv: ,(clojure.set/union [1 2 3] [1 3 5])

7:43 clojurebot: [1 2 3 1 3 ...]

7:43 clgv: ,(clojure.set/union #{1 2 3} #{1 3 5})

7:43 clojurebot: #{1 3 2 5}

7:43 clgv: ^^

7:43 fizruk: thanks! and that is a sad result for seqs :(

7:44 clgv: yeah, you have to make sure to pass sets in there. if I remember correctly there was a discussion about checking for sets in the impl

7:45 ,(distinct (concat [1 2 3] [1 3 5]))

7:45 clojurebot: (1 2 3 5)

7:45 clgv: fizruk: the seq version ^^

7:45 fizruk: thanks!

7:46 clgv: is there a distinct-by function?

7:47 clgv: fizruk: no

7:47 hyPiRion: fizruk: no, which is somewhat bit puzzling.

7:47 clgv: fizruk: but you can implement it via a hashmap.

7:47 fizruk: or group-by + reduce-kv + distinct

7:49 ,(defn distinct-by [f coll] (->> coll (group-by f) vals (map distinct)))

7:49 clojurebot: #'sandbox/distinct-by

7:49 clgv: ,(distinct-by :a [{:a 1 :b 2} {:a 2 :b 3} {:a 1 :b 4}])

7:49 clojurebot: (({:b 2, :a 1} {:b 4, :a 1}) ({:b 3, :a 2}))

7:50 clgv: oops

7:51 owlHowl: hi

7:51 clgv: ah lol. forget that approach^^

7:51 ,(defn distinct-by [f coll] (->> coll (group-by f) vals (map first)))

7:51 clojurebot: #'sandbox/distinct-by

7:51 clgv: ,(distinct-by :a [{:a 1 :b 2} {:a 2 :b 3} {:a 1 :b 4}])

7:51 clojurebot: ({:b 2, :a 1} {:b 3, :a 2})

7:51 owlHowl: how do i insert an item in list and vector?

7:52 clgv: owlHowl: you cann only "grow" a list or vector but not insert something efficiently in the middle

7:52 hyPiRion: fizruk: https://www.refheap.com/76995

7:53 owlHowl: If you need to insert efficiently into a vector, consider using the RRB-tree.

7:53 clgv: hyPiRion: where has all the simplicity gone? :P ;)

7:54 hyPiRion: clgv: out the window, but at least it's lazy :)

7:54 owlHowl: yea, python is much simpler :P

7:54 fizruk: hyPiRion: clgv's version is not?

7:54 clgv: hyPiRion: hm yeah no lazy group-by built-in ;)

7:54 hyPiRion: fizruk: no, you cannot use clgv's version on infinite lists

7:54 fizruk: oh, I always forget map is not lazy

7:54 hyPiRion: fizruk: map is lazy, group-by is not

7:55 clgv: fizruk: map is lazy, group-by is not

7:55 lol :P

7:55 hyPiRion: clgv: oh wow

7:55 great minds and all that

7:55 owlHowl: if i have a list (list 0 2 3) and want to append elemenet 4?

7:55 clgv: ;)

7:55 fizruk: clgv: really, I though maps were not lazy!

7:55 clgv: hyPiRion: and laziness to type more than needed ;)

7:55 fizruk: that's wrong

7:56 fizruk: "mapv" is "eagerly" producing a vector^^

7:56 hyPiRion: owlHowl: Usually if I want to append to a list, I would do (concat my-list [4]). But if the lists are long, I'd consider replacing the list with a vector and do (conj [0 2 3] 4)

7:57 owl-v-: hyPiRion: so... vector > list ?

7:57 clgv: ,(mapv #(reduce conj % (range 10)) [() []])

7:57 clojurebot: [(9 8 7 6 5 ...) [0 1 2 3 4 ...]]

7:58 clgv: ,(mapv #(reduce conj % (range 5)) [(list) (vector)])

7:58 clojurebot: [(4 3 2 1 0) [0 1 2 3 4]]

7:58 hyPiRion: owl-v-: If you don't need laziness, then vectors are generally the best option, yes

7:59 fizruk: clgv: can you give an example of a lazy map?

8:01 owl-v-: hyPiRion: (def v (conj v 4)) ?

8:01 fizruk: clgv: I guess map's values can be evaluated lazily, but you have to know all indices in advance to built a map?

8:03 hyPiRion: owl-v-: yeah, that's possible. Just a small recommendation, if you don't already know it: It's generally a bad idea to redefine `def`fed values.

8:03 fizruk: Well, the problem lies mainly within checking for existence and associating new values onto the map

8:03 clgv: fizruk: (map inc (range)) is lazy

8:04 hyPiRion: To check for existence you have to realize the whole map, to assoc a value you have to realize it.

8:04 clgv: fizruk: you mean a hashmap?

8:04 fizruk: clgv: I meant Map as structure, yeah

8:04 clgv: oh well ...

8:04 fizruk: there is a library that supports lazy value calculation though...

8:05 fizruk: but that wouldnt help here ;)

8:05 fizruk: clgv: hyPiRion: now I see where I confused you :p

8:05 owl-v-: hyPiRion: (def v (conj v 4)) this generates list, not vector :(

8:06 hyPiRion: owl-v-: if you already have a list, then yes. If you want to append to a list, then I'd do (def v (concat v [4])). If you want a vector, do (def v (conj (vec v) 4))

8:06 clgv: is it a bad idea to have nested "bind"s in clojure.test.check?

8:08 fizruk: ,(#(vals (zipmap (map :x %) %)) [{:x 1 :y 1} {:x 1 :y 2} {:x 2 :y 3}])

8:08 clojurebot: ({:y 3, :x 2} {:y 2, :x 1})

8:08 hyPiRion: clgv: I do that indirectly through recursive definitions.

8:10 clgv: well maybe it is not the nested binds. it might be the vector of vectors that causes an endless loop

8:12 fizruk: ,(#(zipmap (map :x %) (map :y %)) [{:x 1 :y 1} {:x 1 :y 2} {:x 2 :y 3}])

8:12 clojurebot: {2 3, 1 2}

8:12 fizruk: is there a function for that? ^

8:12 clgv: hyPiRion: or my "such-that" predicate is too complicated to generate any samples at all

8:13 hyPiRion: clgv: yeah, I had an issue where "such-that" didn't generate any results, and henceforth I ended up in an infinite loop that wa

8:13 way*

8:14 clgv: well gotta split up the predicate on multiple values to multiple predicates on one value each

8:15 fizruk: unlikely

8:15 fizruk: ok

8:15 clgv: I'd go with reduce though. (reduce (fn [m, {:keys [x y]}] (assoc m x y)) {} coll)

8:23 hyPiRion: is there a generator to build a vector and have access to the element position?

8:23 owl-v-: hyPiRion: thanks. I just finished projecteuler.net/problem=1

8:23 clgv: I need to generate vectors where the generated values at the different positions are smaller than certain constants (per position)

8:23 hyPiRion: clgv: ...to the element position?

8:24 owl-v-: congrats :)

8:24 owl-v-: hyPiRion: is there way to sum += 1 ?

8:24 clgv: e.g. constants [2 5 -1] and I need vectors where the elements are smaller than those constants

8:24 owl-v-: hyPiRion: (def sum (+ sum 1)) ?

8:25 hyPiRion: owl-v-: There is no `+= 1` in clojure, but `a + 1` is usually written `(inc a)`. Though `(+ a 1)` is okay too.

8:26 clgv: sounds like a tuple bind

8:26 owl-v-: hyPiRion: (def sum (+ sum 3)) ?

8:27 clgv: hyPiRion: but the number of constants (= vector size) is varying...

8:28 owl-v-: hyPiRion: i guess it's only way for sum+=3

8:28 clgv: hyPiRion: (apply gen/tuple (map-indexed ...)) should work right?

8:28 fizruk: ,(let [x 2 x (+ x 3)] x)

8:28 clojurebot: 5

8:29 hyPiRion: clgv: yeah, something like (gen/fmap (apply gen/tuple (map (gen/choose lowest-value (dec %)) [2 5 -1])) vec)

8:29 fizruk: yeah

8:51 clgv: hyPiRion: ah great, I did not now gen/choose before

8:51 that library definitely needs more documentation with examples^^

8:51 hyPiRion: yeah, true that

8:53 clgv: hyPiRion: but the function in fmap is suppose to return values not generators, right? that's what the examples in intro.md suggest

8:55 zaiste: what's the best way to include a modified library e.g. compojure as a project dependency ?

8:55 hyPiRion: clgv: fmap takes a function and a generator, and the function converts the output of the generator

8:55 so yes

8:56 essentially (gen/fmap foo vec) converts the output from the foo generator by calling vec on it

9:11 owl-v-: how do I if (a==b && a!=c) ?

9:14 hfaafb: (if (and (= a b) (not= a c)) ... ...)

9:19 owl-v-: hfaafb: thanks

9:25 clgv: owl-v-: since you asked that question better read through one of the clojure books or one of the similar online material

9:41 `szx: zaiste: you mean something like leiningen checkouts? https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies

9:42 perses: is there a method called exit in clojure to make the program forcelly exits?

9:44 mdrogalis: perses: (System/exit 1)

9:45 perses: mdrogalis: what is the best way to handle command arguments?>

9:46 mdrogalis: perses: Command line arguments?

9:46 perses: mdrogalis: if i run it as script?

9:46 mdrogalis: There's libraries for that, google around, perses.

9:47 perses: is i want to pass as example input file to handle from inside the clojure project, what is the best way to do this?

9:47 owl-v-: when I (loop [i 1] (when (< i 10))) how do I break when i==7 ? I would like to keep (< i 10)

9:50 (loop [i 1] (when (< i 10) ("if i==7: break") (recur (inc i)) )) how do i break?

9:50 sgregory_: you don't break, you don't don't recur

9:51 (if (eq? i 7) 0 (recur (inc i)))

9:51 something like that

9:52 clgv: owl-v-: you definitely need one of those clojure books...

9:52 hyPiRion: replace (< i 10) with (and (< i 10) (not= i 7))

9:52 sgregory_: eq? is the wrong lisp ;)

9:52 sgregory_: yeah yeah yeah

9:52 owl-v-: sgregory_: o.o

9:52 perses: *command-line-args* don't work with lein run --file something ?

9:53 i tried to (println *command-line-args*) but i got nil

9:54 hyPiRion: perses: with `lein run`, it's the input commands

9:54 owl-v-: hyPiRion: and how do i then return 'i'?

9:54 hyPiRion: input arguments, rather. So like (defn -main [args] ...)

9:54 clgv: perses: use "--" before your args to notify leiningen that program aruments start after that

9:54 hyPiRion: owl-v-: if i == 7?

9:55 clgv: oh right, and what hyPiRion said ^^

9:55 perses: clgv: lein run -- hello, give me also nil

9:55 clgv: maybe i understood wrong

9:55 sgregory_: owl-v-: every expression has a value, so even a loop or if/else returns the last expression as a value

9:55 clgv: perses: (defn -main [& args] (println args)

9:56 hyPiRion: perses: *command-line-args* aren't set by `lein run`, they are given as args to the main function

9:56 clgv: owl-v-: you want code that constantly evaluates to 7?

9:56 hfaafb: (loop [i 0] (if (= i 7) i (recur (inc i))))

9:57 remember that `if` returns the second argument if the first argument evaluates to true, the third argument if the first argument evaluates to false

10:13 perses: ,(if true (println "true") (println "false"))

10:13 clojurebot: true\n

10:13 perses: how can i pass more lines if "if" passed?

10:14 println "true" and another thing

10:14 mdrogalis: perses: Surround many forms with (do ...)

10:14 ,(do (prn 1) (prn 2))

10:14 clojurebot: 1\n2\n

10:18 jballanc: perses: do works, but you might also consider refactoring your code so that you don't need more than one line in the if

10:18 could be as simple as extracting a method or using a letfn

10:25 reiddraper: hyPiRion: clgv: re: more documentation with examples. any idea where that would best live? more stuff in doc/? an examples/ dir?

10:26 clgv: reiddraper: I asked myself that question since I considered adding some of my generators as example...

10:27 reiddraper: but I dont know. other projects like midje use the wiki on github for structured docs

10:27 reiddraper: clgv: right now i'm steering away from the wiki because it's a separate git repo, and i like having everything versioned together. i could be convinced otherwise though

10:28 clgv: reiddraper: yeah being tied to github is a downside of the wiki

10:28 reiddraper: and github does a good job still rendering markdown that's just in a random file: https://github.com/clojure/test.check/blob/master/doc/intro.md

10:28 hyPiRion: reiddraper: I don't think there has to be a lot of examples, but example usage of common things could probably be in doc/examples.md. Preferably example use of all the generators and all the functions.

10:29 reiddraper: clgv: so would an 'advanced' generators page page in the docs/ be a good start?

10:29 hyPiRion: in particular, the choose function isn't mentioned in intro.md

10:29 (which was what we discussed)

10:29 reiddraper: right, good point

10:30 clgv: hyPiRion and fwiw, my goal is certainly to eventually have documentation that people love, so please don't hesitate to keep pointing out where things can be improved :)

10:30 clgv: reiddraper: probably. discussions of use of such-that would be great as well, I tried to generate a vector with certain properties which ran into an endless execution... (infinite loop maybe?)

10:30 reiddraper: clgv: yeah, and i suppose one issue with documentation is sometimes it gets spread out. I believe that is documented in the docstring, but probably not elsewhere

10:31 hyPiRion: clgv: I actually added an issue related to infinite loops revolving `such-that` because of that :p

10:32 reiddraper: hyPiRion: yeah just saw. i'm +1 for just changing gen/such-that to have a default limit. which I'd think should be pretty low, maybe after 10x or something

10:32 owl-v-: i want to do stuff like this python code:

10:32 clgv: currently struggling with finishing the test. I have a working generator (tested on repl) but the for-all code does not do anything it seems

10:32 owl-v-: def primefactor(a): # primefactor 3 and above

10:32 reiddraper: since you really should only be using it for things that are _very_ likely to pass

10:32 owl-v-: i = 3

10:32 while i < a/2:

10:32 if 0==(a % i):

10:32 return a/i

10:32 i+=2

10:32 hyPiRion: owl-v-: please use a pastebin next time (e.g. refheap.com)

10:32 clgv: owl-v-: very bad idea. use refheap.com please

10:32 owl-v-: ok

10:34 hyPiRion: reiddraper: yeah, I tend to fall into that trap myself. Instead of using bind and generating stuff bottom up, I tend to generate top-down and filter out the correct ones. Not surprisingly, that turns out to be inefficient

10:35 owl-v-: https://www.refheap.com/77008 to https://www.refheap.com/77009

10:37 hyPiRion: owl-v-: https://www.refheap.com/77010 is a literal translation

10:38 clgv: reiddraper: from a syntax point of view it would be awesome to have something let-like to build up generators using the generated values of previous generators

10:38 reiddraper: hyPiRion: cool, well having a pretty low retry-count will help encourage people away from that, i hope?

10:38 clgv: gfredericks has been working on something that sounds very similar: http://dev.clojure.org/jira/browse/TCHECK-15

10:39 hyPiRion: reiddraper: yeah, that should definitely encourage people to do it properly

10:40 reiddraper: hyPiRion: cool, i can either take a stab at that after work today, or if you wanted to make a patch. either works fine for me

10:40 hyPiRion: At least they realise that it's inefficient and the performance penalty they pay for it.

10:40 reiddraper: I haven't looked at it yet, so feel free to work on it. I have a master thesis to finish as well, so don't worry about me not having anything to do :)

10:41 reiddraper: hyPiRion: we can provide two arities, one with default times of 10 or so, and another that lets you pass in num-retries

10:41 hyPiRion: ha, excellent

10:41 hyPiRion: reiddraper: yeah, that's what I think is sane

10:41 reiddraper: cool

10:43 perses: what is the best book to learn clojure from?

10:44 hyPiRion: clgv: I think I attempted to do something like gfredericks as well https://github.com/hyPiRion/sc-sugar/blob/7f2c4c9d1385d00a382574aaa38e67ae8afabc92/src/com/hypirion/sc_sugar/sugar.clj#L50-L56 -- but the problem is that a good implementation needs to work like let, and that is really difficult due to capturing values, destructuring and all that

10:45 circ-user-QGnbp: Hello

10:46 hyPiRion: hi there

10:46 circ-user-QGnbp: Quick question if I have a vector of a map '({:a 1 :b 2} {:a 1 :b 3}). How do I apply a transformations to all b items?

10:46 I am getting a result from the db and would like to transform it to joda time

10:46 any idea?

10:46 btw I am a newbie in Clojure (but so far loving it)

10:47 bhauman: perses: http://pragprog.com/book/shcloj/programming-clojure

10:47 circ-user-QGnbp: thanks for the info

10:48 I am reading 2 books currently

10:48 hyPiRion: circ-user-QGnbp: do you have a function which converts a :b value to a datetime value?

10:48 circ-user-QGnbp: yes clj-time.coerce/from-date

10:49 clgv: hyPiRion: interesting

10:49 hyPiRion: circ-user-QGnbp: I'd probably do something like this

10:49 ,(defn from-date [val] (str "joda-date-" val))

10:50 clojurebot: #'sandbox/from-date

10:50 hyPiRion: ,(map #(update-in % [:b] from-date) '({:a 1 :b 2} {:a 1 :b 3}))

10:50 clojurebot: ({:a 1, :b "joda-date-2"} {:a 1, :b "joda-date-3"})

10:50 circ-user-QGnbp: I'll give it a try

10:50 thanks for your help

10:50 hyPiRion: you're welcome, hope you get it working

10:55 perses: circ-user-QGnbp: what are the books you currently reading?

10:59 circ-user-QGnbp: "clojure in action" "the joy of clojure"

10:59 "programming clojure"

10:59 perses

10:59 perses: thanks man

10:59 circ-user-QGnbp: they are good

10:59 but I need some hands on

11:00 perses: circ-user-QGnbp: which one you suggest to start with?

11:00 i'm new

11:00 circ-user-QGnbp: perses the joy of clojure is very good

11:00 I guess it depends on your background

11:00 but they are all good books

11:01 perses: circ-user-QGnbp: i'm come from ruby world

11:01 not java

11:02 what do you guys find Go programming relatinve to clojure, i'm they are different approach, but maybe they are same at any points

11:05 sgregory_: Go is interesting. I like it for the few cases I've used it, but I wouldn't use it for everything. My main use of it is a "Smarter" reverse proxy

11:06 And for shuffling network bytes around its very pragmattic

11:08 But writing business-logic in it could be tedious, the abstractions don't lend themselves to that type of thing very well (in my opinion)

11:09 But besides both having concurrency baked in, they're kind of at opposite ends of the spectrum.

11:09 perses_: sgregory_: sorry i got DC

11:10 sgregory_: Go has anonymous functions, but doesn't really use them well.

11:11 clgv: reiddraper: is there shuffling in test.check?

11:11 otherwise I'd just use clojure.core/shuffle

11:12 reiddraper: clgv: nope, but that would be a good addition, for sure

11:12 since you want to avoid using randomness that is not controlled by test.check

11:12 clgv: reiddraper: background: I have two sets of elements I want to mix together into one collection

11:13 reiddraper: yeah, that's why I asked

11:14 reiddraper: clgv: there are some subtleties with how shuffling should work w/r/t shrinking

11:14 clgv: reiddraper: yeah I guess you need some measure of sortedness for shrinking

11:15 I'll bridge the gap by generating an integer and use that to initialize a random generator used for shufflling for now

11:18 reiddraper: clgv: if you like, file an issue here http://dev.clojure.org/jira/browse/TCHECK for adding a shuffle generator

11:20 gfredericks: shrinking a shuffler sounds fascinating

11:21 should figure out how many random swaps it takes to get an even distribution and then use a bounded list of swaps

11:22 or...you could just generate a random permutation and then at each step you can take any of the swaps that get you closer to sorted

11:23 clgv: reiddraper: together with shuffle we woul get random permutations as well

11:23 reiddraper: shall I add that to the ticket as well?

11:23 reiddraper: clgv: add whatever you think is helpful

11:23 dnolen_: very cool Om application by one of the Ableton devs, undo/redo and visual history http://jackschaedler.github.io/goya/ (view in Chrome)

11:25 hyPiRion: gfredericks: I think the latter should work, it may be a big search space.

11:25 *but it may be

11:26 clgv: reiddraper: any minimum requirements for the content of the ticket?

11:26 hyPiRion: I mean, worst case n! runtime?

11:26 reiddraper: clgv: nope

11:32 clgv: thanks for filing that issue

11:37 clgv: reiddraper: no problem. we all benefit from that feature (hopefully) ;)

11:39 gfredericks: hyPiRion: did you have some criticism of my for macro earlier?

11:40 hyPiRion: gfredericks: No, I was just commenting on my own stuff, and just that it's hard to do it right. Haven't peeked into your impl yet

11:41 gfredericks: okay. mine is perfect and has no problems.

11:41 hyPiRion: nice

11:41 I expected nothing less of you

11:41 gfredericks: I fixed a problem last night, prior to which it had one problem.

11:44 I put it in test.chuck so I don't *need* it in test.check anymore I guess

11:45 reiddraper: i think its still destined for test.check, just may be a week or so until i have time to really understand it

11:48 gfredericks: reiddraper: no rush

11:52 it was fun to write; I guess it's sort of a rewriting macro

11:53 the vanilla case is pretty simple via bind/fmap, but supporting :let and :when was a big headache until I thought of the rewriting strategy

11:56 clgv: gfredericks: I wrote a iteration macro for a special-purpose datastructure supporting :let, :when and :while a few months ago. It was more a conditional code generation approach

11:59 the result of the code that the macro generates is tested with test.check for several non-trivial scenarios to make sure it works. :)

12:02 gfredericks: clgv: cool

12:14 clgv: do I have to use gen/resize when building a gen/sized generator recursivly?

12:14 seancorfield: Clojure style question: "The names of predicate methods (methods that return a boolean value) should end in a question mark. (i.e. even?)." -- do you think that means that a function ending in ? should return a strict boolean (true or false) or is it acceptable to return truthy / falsey?

12:15 (and I know it only implies "return boolean" -> "ends with ?", not the other way around)

12:16 llasram: seancorfield: I prefer strict boolean, just because their are many functions which treat `nil` different from `false`

12:16 s,their,there,

12:17 seancorfield: I had a quick look through the result of (apropos "?") and everything I checked seemed to return a strict boolean... which was partly why I asked... and partly because it came up as a question of style at work.

12:18 clgv: reiddraper: hyPiRion: how do I generate a vector recursively with test.check? the problem is a generated element will restrict the range for the following ones and so on

12:19 seancorfield: We have some functions at work that are (used as) predicates but they aren't strictly boolean return types (e.g., we have one that tests (#{"set" "of" "special" "values"} some-str) and that's obviously going to return nil or a string - but it's still a "predicate").

12:19 hyPiRion: clgv: https://github.com/clojure/test.check/blob/master/doc/intro.md#recursive-generators

12:20 clgv: hyPiRion: I read that. but how can I translate that to a vector/list? is there some generator for cons/conj/list* sematic?

12:22 martinklepsch: amalloy_, thanks for adding that comment here: http://stackoverflow.com/questions/21416917/multiple-regular-expressions-in-clojure :)

12:23 seancorfield: Any other opinions on that style question? Perhaps I should ask it on the mailing list...

12:23 reiddraper: clgv: here's any example: https://gist.github.com/abrooks/e1ed21f7d59f3bd09339

12:24 daitya: seancorfield: i'd like to hear opinions about that too... we have a couple of similar cases in our clj-webdriver code

12:27 clgv: reiddraper: thank you. so the trick is to use bind and conj

12:28 reiddraper: clgv: correct

12:37 clgv: reiddraper: I tried to translate it to a simpler exmple but something is still wrong, see https://www.refheap.com/77083

12:37 reiddraper: clgv: i'm afraid i can't look in any detail at the moment

12:38 seancorfield: daitya: I posted to the ML with more context / details

12:38 daitya: cool

12:38 will track that thread

12:39 clgv: reiddraper: ok no problem

12:41 coventry: clgv: When you call (permutation (dec n) ...), aren't you excluding n from the permutation, unless it was chosen on that iteration?

12:41 ... since you choose the next element with (gen/choose 1 n).

12:41 clgv: coventry: right changed that now^^

12:43 coventry: https://www.refheap.com/77083

12:43 somehow the case n=0 seems not to work as expected

12:45 mikerod: So I know there are issues out for this, such as http://dev.clojure.org/jira/browse/CLJ-1239; however, is there any good workaround to preserving metadata when doing something like a prewalk?

12:47 justin_smith: mikerod: if nothing else, you could manually register metadata while walking, and reapply the metadata to the output

12:49 coventry: clgv: I think you want (if (= 1 n)) rather than zero?, or (range 1 (inc n)). (range 1 n) has only n-1 elements, so your unused is empty at n=0.

12:50 clgv: coventry: for n=0 the empty vector is supposed to be returned

12:50 mikerod: justin_smith: hmm, what do you mean by "manual register" it?

12:51 coventry: clgv: Er, sorry, meant "unused is empty at n=1".

12:51 justin_smith: (if (should-transform o) (let [the-meta (meta o)] (with-meta the-meta (frob o))) o)

12:51 that is kinda psuedo-code but not far from being the meat of a postwalk function

12:52 clgv: mikerod: write a "walk" wrapper that uses clojure.walk/walk and adds metadata to the result. then rewrite all walk derivates you want to use using the walk wrapper

12:52 justin_smith: basically any object that isn't sent back out unchanged would need to be checked for metadata, and that metadata would need to be copied to the transformed version

12:52 clgv: coventry: damn off by one error.

12:52 coventry: thx

12:52 coventry: np

13:00 justin_smith: mikerod: my args to with-meta above were backward, but otherwise that method of "inheriting" metadata does work in my repl experiments

13:02 mikerod: https://www.refheap.com/77087

13:03 mikerod: clgv: justin_smith thanks for the ideas. I'll look into these.

13:04 I'd hope at some point clj chooses to fix up the walk implementation so we get this stuff built into the "core language". :)

13:05 justin_smith: mikerod: I am not sure the right behavior is always well defined - at least now you have the option of preserving the original metadata, or altering if you see fit that it be altered

13:05 clgv: mikerod: or someone writes an awesome walk library ^^

13:05 mikerod: justin_smith: Yeah, I figured the "tricky" cases are what has kept it in the state it is in

13:06 clgv: true, that'd be fine; now who..hmm...

13:06 clgv: so finally the test suite is completed and the implementation battle proof. :)

13:06 justin_smith: mikerod: random example: walking a structure transforming macros to functions invoking that macro, you wouldn't want the part of the var's metadata that declares it a macro

13:06 clgv: time to go home :D

13:07 mikerod: justin_smith: +1, that is a good example indeed

13:28 shafire: did someone make a performance check between jvm6 - jvm8?

13:30 jwm: is there a better way of doing this: (def mongodbs (into {} (map #(hash-map % mongo-config) [:bhn :ps :sq :la :spool])))

13:30 where mongo-config is a vector of values

13:30 I just want a non lazy map returned of key value pairs that are mongo-config

13:31 key: mongo-config

13:31 justin_smith: jwm: that does not look right, you need two element vectors for into {}

13:31 there is no such thing as a lazy map

13:31 jwm: it works

13:31 stompyj: (+ 1 1)

13:31 clojurebot: 2

13:31 justin_smith: at least not with a default {} map

13:31 jwm: I was just trying to clean it up

13:31 shafire: (+ 40 (+ 1 1))

13:31 stompyj: (clojure.data/diff {:a 1} { :b 2})

13:32 jwm: ok, non lazy sequency

13:32 justin_smith: ,"clojurebot evaluates random things, but comma makes him evaluate a specific thing"

13:32 clojurebot: "clojurebot evaluates random things, but comma makes him evaluate a specific thing"

13:33 justin_smith: her? it?

13:34 jwm: I am just creating a map of key value pairs where the value is the same across all pairs

13:34 justin_smith: jwm: ahh, hash-map makes a k / v, then that is coerced to a vec by into

13:34 ,(into {} [{:a 0} {:b 1}])

13:34 clojurebot: {:a 0, :b 1}

13:35 justin_smith: now I see how that works

13:36 jwm: yeah

13:36 I actually did that on my own.. new to clojure

13:36 just trying to come up with a shorthand way of doing it

13:36 or even shorter hehe

13:36 justin_smith: ,(do (def mongodbs (into {} (map vector [:bhn :ps :sq :la :spool] (repeat mongo-config)))) mongodbs)

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

13:36 justin_smith: oops

13:36 ,(do (def mongodbs (into {} (map vector [:bhn :ps :sq :la :spool] (repeat :mongo-config)))) mongodbs)

13:36 clojurebot: {:bhn :mongo-config, :ps :mongo-config, :sq :mongo-config, :la :mongo-config, :spool :mongo-config}

13:37 jwm: repeat might be good

13:37 justin_smith: slightly more concise, and to my eye definitely clearer what it is doing

13:44 amalloy: does anyone know what the deal is with irctc? he's sent me two PMs asking for help with clojure. actually he's sent them to my bouncer, since i'm offline at 4AM

13:45 llasram: Maybe they want help with Clojure?

13:45 amalloy: well presumably, yes

13:45 but PMing me, specifically, in the dead of night? seems like not the best plan

13:46 dbasch: ‘(zipmap [:bhn :ps :sq :la :spool] (repeat :mongo-config))

13:46 ,(zipmap [:bhn :ps :sq :la :spool] (repeat :mongo-config))

13:46 clojurebot: {:spool :mongo-config, :la :mongo-config, :sq :mongo-config, :ps :mongo-config, :bhn :mongo-config}

13:47 llasram: Yeah, fair enough. Failed attempts at humor aside, I have no additional information to offer

13:47 dbasch: justin_smith: that’s more concise to me

13:47 justin_smith: dbasch: yeah, that is much better

13:48 amalloy: well, i sent him a $mail. hopefully he'll just ask the channel at 4AM next time

13:48 justin_smith: amalloy: clearly your advice is the only advice he is interested in. Give him a quote for your consultation rates.

13:49 TravisD: amalloy: Did the PM wake you?

13:50 amalloy: no, certainly not. good lord. if i let IRC wake me. man

13:51 my sleep is so much more important than you guys in #clojure are. no offense

13:51 TravisD: hehe :) That would have been really unfortunate

13:51 hehe ouch! Cold as ice! ;)

13:51 Vfe: I am now sad ; ;

13:54 jwm: dbasch: definitely the best way.. I was trying to figure out how to repeat zipmap but didn't know about repeat!

13:54 thanks guys

13:54 dbasch: jwm: you’re welcome

14:00 justin_smith: I frequently forget zipmap because it is so rare I need a map where keys / vals come from two sequences that are generated independently

14:00 probably a coding style thing

14:00 hiredman: .win 15

14:00 jwm: yeah this is just temporary code anyway

14:01 wanted a concise way to map a default vector of config options to db keys in a map

14:01 -in a map

14:01 I can make my english more concise too hah

14:03 its amazing I spent an entire day on this

14:03 hehe

14:04 arrdem: amalloy: haha... good policy. 3am cat pics get old fast

14:06 yedi: i'm having trouble getting my webapp to run with `lein run` or from the compiled uberjar: https://github.com/yedi/reasoned-rhymer/blob/master/project.clj && https://github.com/yedi/reasoned-rhymer/blob/master/src/clj/reasoned_rhymer/handler.clj#L55

14:06 when i use `lein run` it seems to serve an empty webpage

14:07 when i use `java -jar target/reasoned-rhymer-0.1.0-SNAPSHOT-standalone.jar` i get this error: Exception in thread "main" java.lang.NoClassDefFoundError: reasoned_rhymer/handler Caused by: java.lang.ClassNotFoundException: reasoned_rhymer.handler

14:07 it works fine with `lein ring server` so i think i might be missing something

14:08 dbasch: yedi: put a (:gen-class) in your handler

14:14 yedi: dbasch: sweet, that fixed the java exception (and now i know a lil more about how java operates with clj)

14:14 but now it's behaving like `lein run` and serving an empty webpage

14:17 dbasch: yedi: client.html should be in resources

14:18 same path as your .js files

14:24 yedi: dbasch: if i did that, wouldn't i also have to change this line: https://github.com/yedi/reasoned-rhymer/blob/master/src/clj/reasoned_rhymer/handler.clj#L40

14:25 justin_smith: yedi: yeah, that path should be relative to the resources dir

14:25 or else the uberjar just won't work

14:33 jwm: hmm, I'm retarded, how do you run a function over each item in a vector

14:33 justin_smith: jwm: map or mapv

14:34 or for

14:34 ,(map inc (range 10))

14:34 clojurebot: (1 2 3 4 5 ...)

14:34 justin_smith: ,(map inc (vec (range 10)))

14:34 clojurebot: (1 2 3 4 5 ...)

14:36 stompyj: jwm: all I know is I just discovered the diff function yesterday

14:36 so I’m right behind you

14:36 jwm: hah

14:36 yeah I have just been copy pasting pretty much

14:36 until it works

14:36 :)

14:37 I've got mongodb connected to 5 dbs, smtp server going, web server going, websocket connection and repl inside lighttable going

14:37 amazing the power of this setup :)

14:37 justin_smith: jwm: the repl is great for that. clojure.repl/doc, clojure.repl/apropos, clojure.repl/source

14:37 jwm: transitioning from nodejs

14:37 yep I use them all

14:37 and google hah

14:37 justin_smith: http://clojure.org/cheatsheet also this

14:38 yedi: "The parser gets the root path from the classloader" --- how would i go about printing that root path?

14:38 jwm: yep I use that also

14:38 I was using doseq vs map

14:38 justin_smith: yedi: the classpath?

14:39 jwm: doseq is what I want to do (I want to run the function on each value of the vector)

14:39 justin_smith: lein classpath will show the classpath lein would create

14:39 you can also introspect on it from a repl...

14:39 jwm: but then I realized its not a vector its a map hehe

14:39 justin_smith: jwm: that works too

14:40 ,(map (fn [[k v]] [(str k k) (inc v)]) {:a 0 :b 1 :c 2})

14:40 clojurebot: ([":c:c" 3] [":b:b" 2] [":a:a" 1])

14:40 yedi: justin_smith: i think i mean just the file path? i'm basing this off of: https://github.com/yogthos/Selmer/issues/19#issuecomment-26844846

14:40 justin_smith: that uses destructuring, in that case it means "name the first and second items of the first arg k and v respectively"

14:41 yedi: in an uberjar, it is not a file path

14:41 since all of your stuff is inside the jar

14:41 a resource path is just a classpath at the jvm level

14:42 yedi: justin_smith: ahh i see

14:42 need to up my jvm-foo

14:42 `lein classpath` appears to be giving me multiple paths however

14:48 ahh i see, it tries to find the resource by looking at all of those paths

14:50 justin_smith: yes, that is the concept of a path - all the places it checks

14:50 well it is an overloaded term - either the specific path at which one thing is found, or the list of places that are checked when looking

14:59 lvh: Hi!

15:00 What's the thing I use to consume a REST API? clj-http?

15:00 yedi: success! thanks justin_smith

15:01 justin_smith: yedi: np

15:04 tudd: lvh: I'm using cljs-ajax

15:04 depends if you're consuming from the front or back.

15:05 justin_smith: tudd: I shudder at the human-centipede concepts that phrase evokes

15:05 tudd: ha

15:07 do you know much about Om and banging a REST response onto a channel ... and having it display properly?

15:08 want to continually grab external REST data, drop it in the om-state Atom, and have it re-render automagically

15:12 I tend to learn best by example; if there is any of this already done by someone who -actually- knows how to do it "properly"

15:15 also, do you know most idiomatic way to reach into a deeply nested Json doc? (:4th-lvl (:3rd-lvl (:2nd-lvl (:top-lvl response)))) Just doesn't feel like the right way.

15:16 AmandaC: tudd: (-> response :top-lvl :2nd-levl … )

15:16 justin_smith: tudd: turn it into clojure data nd use get-in maybe?

15:17 also with the "continuous updating" thing, sounds like a good usage of core.async with a sleep / grab data / operate on data loop

15:17 I am sure there is an example of doing that in om, though I don't have one immediately handy

15:18 tudd: AmandaC: yeah, thanks. was trying that way... some of the levels, have to get nested nth items of arrays... couldn't get something quite right..

15:19 justin_smith: tudd: unlike ->, get-in can take numeric indexes

15:19 ,(get-in {:a [0 1 44 3]} [:a 2])

15:19 clojurebot: 44

15:20 tudd: justin_smith: want to do exactly that: GET <some_json> -> bang it onto an async channel -> have that assoc into the Om Atom

15:20 re-render et voila

15:21 justin_smith: ,(-> {:a [0 2 42 3]} :a (get 2)) ; alternately

15:21 clojurebot: 42

15:21 tbaldridge: tudd: why not just have get-> swap into om atom?

15:23 tudd: pulling from different places. was toying around with corraling them into one async chan

15:25 tbaldridge: thanks though. yes, one step generally better than three.

15:27 justin_smith: thanks. get-in much more sensible

15:29 jwm: I love ->

15:33 justin_smith: tudd: the advantage of -> as opposed to get-in is you can do (nth n) to index a list or lazy-seq, and .accessor to get object slots

15:33 but with json you won't need those

15:38 lgs32a: is there something in om like IDidRender?

15:42 dnolen_: lgs32a: IDidUpdate is effectively the same thing

16:00 bodie_: what bot does the ,,(println "stuff") in here?

16:00 ,(println "inline eval, that is")

16:00 clojurebot: inline eval, that is\n

16:01 bodie_: PircBot

16:01 hmm

16:03 gfredericks: lazybot does ##(str "inline " "eval")

16:03 lazybot: ⇒ "inline eval"

16:04 justin_smith: ,"maybe this works?" 42

16:04 clojurebot: "maybe this works?"

16:04 justin_smith: n/m

16:05 coventry: Off topic: http://opensslrampage.org/

16:05 justin_smith: coventry: feel free to join us on #clojure-social

16:06 arrdem: ~offtopic |is| <reply> #clojure-social is that way sir

16:06 or the bots can still hate me..

16:07 grimoire: ~offtopic |is| <reply> #clojure-social is that way sir

16:07 clojurebot: Ack. Ack.

16:07 justin_smith: ~offtopic

16:07 clojurebot: Titim gan éirí ort.

16:07 justin_smith: ~offtopic

16:07 clojurebot: Cool story bro.

16:07 grimoire: clojurebot: offtopic |is| <reply> #clojure-social is that way sir

16:07 clojurebot: 'Sea, mhuise.

16:07 grimoire: ~offtopic

16:07 clojurebot: Huh?

16:07 grimoire: ~botsmack

16:07 clojurebot: clojurebot evades successfully!

16:08 bodie_: lol

16:08 justin_smith: ~botsmack

16:08 clojurebot: Owww!

16:08 grimoire: thanks justin :P

16:08 gtrak: ~botsnack

16:08 clojurebot: Thanks! Can I have chocolate next time

16:09 grimoire: clojurebot: offtopic is <REPLY> #clojure-social is that way sir

16:09 clojurebot: Ok.

16:09 grimoire: there we go

16:09 arrdem: ~offtopic

16:09 justin_smith: ~offtopic

16:09 clojurebot: #clojure-social is that way sir

16:09 arrdem: maybe I should just stay grimoire...

16:10 justin_smith: ~botcrack

16:10 clojurebot: Pardon?

16:10 justin_smith: ~botslack

16:13 arrdem: $mail hiredman y clojurebot blacklist me T_T

16:13 lazybot: Message saved.

16:14 cmiles74: Thank you for sticking it out with them, Melinda!

16:15 amalloy: i think hiredman /ignores lazybot, arrdem, so that's not going to work very well

16:15 arrdem: amalloy: T_T

16:15 I suppose I'm one of the lower signal inputs on this chan...

16:30 tudd: justin_smith: thanks! your suggestion ( get-in & -> ) has collapsed the LOC I - thought I - need

16:31 justin_smith: awesome

16:31 tudd: simple suggestion. big help.

16:31 readability jumped.

16:34 danielszmulewicz: dnolen_: ping

16:34 dnolen_: danielszmulewicz: pong

16:34 danielszmulewicz: hi David, I was wondering if I can extend js types in core.match like we can with java types.

16:36 dnolen_: I saw your 2011 talk, http://vimeo.com/27860102, getting my hands dirty with core.match. Thanks by the way.

16:36 dnolen_: danielszmulewicz: can you be more specific about what you mean?

16:36 danielszmulewicz: no problem.

16:38 danielszmulewicz: dnolen_: For Java types, we have an interface IMatchLookup, basically giving us the ability to use java types with core.match. I was wondering if I could extend a js array to do the same.

16:39 dnolen_: I hope I'm explaining myself.

16:41 dnolen_: OK, here is my code: https://www.refheap.com/77100

16:41 dnolen_: danielszmulewicz: IMatchLookup hack isn't needed in ClojureScript

16:41 that's because ILookup isn't a protocol in Clojure

16:41 just implement ILookup

16:41 in ClojureScript and you can do map pattern matching

16:43 danielszmulewicz: I wouldn't even bother with the conversion, just wrap in ILookup via reify or something like that

16:44 danielszmulewicz: dnolen_: Could you refer me to a snippet of code? That would be awesome.

16:44 dnolen_: danielszmulewicz: I don't have a snippet of code handy

16:45 danielszmulewicz: I found this http://gist.github.com/viebel/8461313

16:46 danielszmulewicz: but really you need to recursively apply via reify if you want it to work in the nested case

16:46 danielszmulewicz: dnolen_: Awesome. That should do it. Thanks a lot.

16:47 (inc dnolen_)

16:47 lazybot: ⇒ 2

17:11 mikerod: starting the cider REPL buffer via `cider` command has mysteriously just stopped defaulting to be in `cider-mode`

17:11 so I have to put it in cider-mode manually each time I start, then the hooks apply

17:11 I'm not sure I know how to diagnose where this has gone wrong

17:14 oh, there is this cider-repl-mode now

17:14 hmmm

17:15 oinksoft: hi, what's the equivalent in clojure of an erlang callback module?

17:15 i want to have some generic API

17:15 tbaldridge: oinksoft: protocols

17:16 oinksoft: tbaldridge: thanks

17:18 tbaldridge: what about using multimethods w/ defmethod in separate clojure (modules/files/whatever you call them)?

17:18 verma: if I am using async channels to trigger modals etc, am I going overboard?

17:18 tbaldridge: yeah, that works as well, and is much more flexible, at the expense of peformance,

17:18 but it's not bad

17:18 oinksoft: ok, thanks tbaldridge !

17:19 tbaldridge: oinksoft: protocols only dispatch off the type of the first argument. Multimethods can dispatch off anything

17:19 oinksoft: tbaldridge: you're right

17:19 tbaldridge: i'm new to clojure so this is very helpful. somebody i am working with suggested i use multimethods in this small project

17:20 tbaldridge: (as opposed to protocols)

17:20 tbaldridge: i think he figured that it would be easier to correct a poor design implemented w/ multimethods :)

17:20 tbaldridge: oinksoft: yeah, as a rule of thumb is probably best to stick with hashmaps and multimethods, switch to protocols when you need something faster

17:21 oinksoft: tbaldridge: that's a useful rule of thumb. is there a collection of such rules?

17:21 tbaldridge: sort of a companion to the style guide

17:22 tbaldridge: oinksoft: I'm not aware of any, sadly

17:22 oinksoft: thanks, OK, thanks again for the advice!

17:22 *that's OK

17:22 tbaldridge: one of the core ideas behind clojure however is that you should start with pure data, and use functions to manipulate that data

17:28 stuartsierra: oinksoft: For similar suggestions, check out some of Stuart Halloway's presentation videos.

17:40 verma: I am doing (in om): (om/button {:type "button" :class "blah" :dataToggle "modal" :dataTarget "#mymodal"} "Click Me!"), but the button appears without the :dataXXX fields in the dom

17:41 anyone seen this? inside my modal code I do see :dataDismiss correctly transforming into data-dismiss attributes

17:41 :className* it was 2 sentences above

17:46 coventry: verma: Do you mean dom/button? I think you need to prepend the map with #js in that case.

17:48 I've mostly used sablono, which lets you use straight maps, but dnolen uses #js in his tutes.

17:55 seangrove: verma: Yeah, it's not a map, it's supposed to be a js-obj

17:55 You can use a js literal via #js{:className "class" :style #js{:padding 10}}

17:55 Note that the style must also be a js object for React

18:01 danielszmulewicz: dnolen_: Actually for javascript arrays I

18:03 verma: sengrove, sorry I missed that part, I hand-typed it, it does have a #js before it :(, sorry about that

18:03 danielszmulewicz: dnolen_: sorry about that, I was saying that for javascript arrays it's not ILookup but ISequential that I would need to extend, am I right about that?

18:03 dnolen_: In order for them to participate in core.match?

18:04 verma: sengrove: something like this https://gist.github.com/verma/11013981

18:04 seangrove: ^

18:04 why my xchat has no auto name completion

18:05 seangrove: verma: Yeah, that looks good

18:06 verma: not sure what's going on :(

18:13 arrdem: suggestions for a Linux Java disassembler>

18:13 Bronsa: arrdem: javap -c :P

18:14 arrdem: Bronsa: facepalm. <3

18:14 justin_smith: arrdem: gdb does some disassembly

18:15 gtrak: arrdem: no-disassemble :-)

18:15 justin_smith: objdump?

18:16 gtrak: though that's more repl-oriented

18:16 justin_smith: I also see ndisasm (from nasm) recommended

18:16 amalloy: no-disassemble is more enjoyable to use than javap, because you don't have to aot-compile and then wade through a pile of classfiles

18:17 Bronsa: no-disassemble looks really neat

18:17 gtrak: a quick hack :-)

18:18 but seems to work well enough

18:18 tuft: i love the reference, too. those were my favorite movies when i was a kid. =)

18:18 Bronsa: if only I knew about it a few months ago :(

18:18 arrdem: gtrak: nice tool!

18:18 gtrak: thanks!

18:18 tuft: it's the macros of bytecodes

18:19 * tuft learned about it yesterday watching "Predictably Fast Clojure."

18:19 hiredman: no-disassemble requires using an agent, which isn't required, you can just grab the generated bytecode https://gist.github.com/hiredman/6214648

18:20 gtrak: hiredman: yea.. but then you have to be less lazy :-)

18:20 slightly..

18:21 maybe I should just steal that and add that to the project?

18:21 TimMc: ,(throw (ThreadDeath.)) ;; Curious about whether this is caught

18:21 clojurebot: #<ThreadDeath java.lang.ThreadDeath>

18:21 arrdem: gtrak: hardly steal...

18:22 gtrak: i see no problem having more than one way to skin the cat in there.

18:22 arrdem: 'tis the Lisp Way...

18:23 amalloy: hiredman: that paste doesn't work for me in clojure 1.6.0: Can't call public method of non-public class: public java.lang.Object clojure.lang.Compiler$DefExpr.eval()

18:23 AmandaC: I’m thinking of wrapping a REST Api, what would be the most idiomatic way to handle this, where it could have different endpoints?

18:23 amalloy: i guess you have to be in the clojure.lang package to make that work?

18:24 gtrak: AmandaC: seen the twitter wrapper? I thought that one was pretty nice to use.

18:24 AmandaC: gtrak: nope, got a link handy?

18:24 hiredman: amalloy: depends what it was changed to, a wallhack may just be the best idea

18:24 arrdem: $google clojure twitter API

18:24 lazybot: [adamwynne/twitter-api · GitHub] https://github.com/adamwynne/twitter-api

18:25 amalloy: it's just public class Compiler {static class DefExpr implements Expr{...}}

18:25 arrdem: AmandaC: ^^

18:25 hiredman: the code is maybe from around 1.4, so it may take some fiddling to work

18:25 gtrak: AmandaC: usage: https://github.com/gtrak/quewww/blob/master/src/quewww/twitter.clj#L36

18:25 and further down there's an async impl

18:26 AmandaC: https://github.com/adamwynne/twitter-api/blob/master/src/twitter/api/restful.clj

18:26 AmandaC: gtrak: ah, what I meant by “different endpoints” is things like different hosts which it’d be accessed on

18:27 * AmandaC is thinking of toying with the BitTorrent Sync API in Clojure

18:27 gtrak: still sounds like a similar sort of macro to me

18:27 pass in an endpoint as an argument

18:29 arrdem: (inc gtrak)

18:29 lazybot: ⇒ 8

18:29 AmandaC: that sounds like it’d lead to a lot of repetition

18:30 maybe I just don’t think functional enough

18:30 verma: seangrove, couldn't get that to work, so changed it to a :onClick handler which >! to a chan which will trigger the modal :P

18:30 gtrak: AmandaC: if a namespace isn't the right thing, you could return a bag of functions as a map or something.

18:31 close over the config. unfortunately, then it's a little harder to reason about, use tooling for..

18:32 essentially, that's why dynamic bindings exist, but we all know how terrible those are..

18:33 in this case it might not be so bad.

18:38 yedi_: justin_smith: what are you workin on

18:38 justin_smith: dunno, caribou stuff

18:39 yedi_: in all seriousness, a blog / friend authentication / commenting system for our caribou web framework

18:40 yedi_: it is also a proof of concept for my new plugin system extension for caribou

18:49 arrdem: hum... so why does emitted bytecode preserve var indirection even with ^:static?

18:50 yedi_: justin_smith: is instrument a clojure shop?

18:50 or primarily clj

18:50 justin_smith: yedi_: only partially clojure, I may even have to use other languages soon

18:51 yedi_: you guys are a remote shop

18:51 ?

18:52 justin_smith: not really, we have one guy in Colarado but he frequently flies back here, and he was local first

18:52 otherwise it is all local

18:52 gtrak: arrdem: static's a noop now I think

18:52 arrdem: gtrak: I'm gonna do a diff in a minute, but a cursory scan seems to indicate minor differences

18:53 gtrak: actually. using ^:static seems to enable use of invokedstatic....

18:53 gtrak: but that's all I've seen so far.

18:53 gtrak: oh, hm.

18:53 yedi: justin_smith: oh the map on http://weareinstrument.com/ gave me that impression

18:53 arrdem: Bronsa: ping ^^^

18:53 yedi: i guess it means where you guys are initially from

18:54 gtrak: arrdem: http://stackoverflow.com/questions/7552632/what-does-static-do-in-clojure

18:54 justin_smith: yedi: all those people came to PDX

18:54 yeah

18:55 Bronsa: arrdem: ^:static is a no-op right now

18:55 owl-v-: hi

18:56 gtrak: I trust whatever Bronsa says on this matter :-)

18:56 owl-v-: i'm trying to convert python code to clojore

18:56 justin_smith: owl-v-: a noble persuit

18:56 owl-v-: https://www.refheap.com/77046 to something like https://www.refheap.com/77109

18:56 gtrak: maybe clojure-in-clojure is really just a fuzz-tester

18:56 arrdem: Bronsa: hum..

18:57 justin_smith: owl-v-: that's not how while should be used, for starters

18:57 or def

18:57 Bronsa: arrdem: I have absolutely no idea what :static used to do btw. Are you maybe thinking of ^:const?

18:57 justin_smith: Bronsa: http://stackoverflow.com/questions/7552632/what-does-static-do-in-clojure

18:57 arrdem: Bronsa: neg. I'm doing research on the (disabled) ^:static system.

18:58 Bronsa: I'll check out ^:const tho.. not something I'm familiar with

18:58 hiredman: that is not correct

18:59 Bronsa: arrdem: you can avoid Var indirection by marking def[n]s ^:const

18:59 hiredman: Bronsa: I don't think that is correct either

19:00 arrdem: well... I've got a test case here, lets see what the compiler does :D

19:00 justin_smith: owl-v-: calling def inside the function means that as soon as you use it in two threads, everything breaks. The right way is to have multiple loop / recur bindings that are updated

19:00 hiredman: Bronsa: I have never used :const, but if I recall how it works correctly, it treats in the value of the def as a constant or "quoted constant"

19:00 Bronsa: hiredman: look at the decompiled code for (defn ^:const x [] 1) (defn y [] (x))

19:01 justin_smith: owl-v-: also, the while calls should probably be when calls

19:01 hiredman: Bronsa: if you say so

19:01 Bronsa: hiredman: http://sprunge.us/ViWC

19:01 justin_smith: hiredman: yeah, I saw it referenced as being an annotation to indicate something should be a primative value and not an object

19:02 hiredman: justin_smith: the top answer on that so post is wrong

19:02 verma: not sure what I am screwing up here: https://gist.github.com/verma/11016107 the om/get-state returns the right state as far as I can tell, but set-state is faulting, any ideas?

19:02 justin_smith: hiredman: OK, that's good to know

19:03 arrdem: Bronsa: confirmed here. good to know...

19:03 hiredman: justin_smith: static just removed the runtime var derefing, similar to what Bronsa is saying :const does

19:03 justin_smith: OK

19:03 hiredman: nothing to do with invokePrim

19:03 Bronsa: arrdem: hiredman unfortunately using ^:const on functions doesn't work for functions that close-over some locals

19:04 hiredman: Bronsa: putting a let binding around defs is super gross anyway

19:04 Bronsa: hiredman: nice rationalization :)

19:04 hiredman: Bronsa: how is it rationalizing?

19:05 arrdem: hiredman: just because it's nasty doesn't mean the compiler can't do something about it. Saying it's nasty is implicitly making an excuse for the compiler's inaction.

19:05 (or that's how I read it)

19:05 hiredman: the various metadata flags are buggy and inconsistent as all get out

19:06 :static is super weird, because everything in core is marked static, but as you know, it does nothing

19:07 Bronsa: hiredman: I agree that it looks gross but there are still cases where it's useful, it could *probably* be made to work if instead of using print-dup+read-string the fn object was retrieved by .getRawRoot on the var in the static init

19:07 owl-v-: justin_smith: how do i do >> x=1; x+=2; print x; on clojure?

19:07 Bronsa: hiredman: also what arrdem said

19:07 nDuff: arrdem, what are you looking for in that disassembler? If you wanted something with a nice IR, rather than a pure disassembler, that changes your choices. (If you want to be able to go back from the IR to bytecode, that changes them further).

19:08 justin_smith: owl-v-: (let [x (atom 1)] (swap! x + 2) (println @x))

19:08 owl-v-: but usually we find ways to do things without mutation - for example via a recursion with a new binding

19:08 hiredman: Bronsa: it could definitely be made to work, but then the question is, why have ^:const and ^:static, and why was :static disabled?

19:09 Bronsa: hiredman: arrdem, but anyway I don't even know if :const is supposed to work on fns or if it's just by accident so meh.

19:09 hiredman: right

19:09 arrdem: hiredman: I was talking to tbaldridge and it sounds like there were historical reasons for disabling ^:static not long after it was added.

19:10 hiredman: I think it is an accident, and most likely :const should just work on primitives

19:10 arrdem: hiredman: working through the patch that added ^:static, and it looks like most of it is still in place..

19:10 nDuff: arrdem, ...for pure analysis purposes, IBM's Wala is quite good (fast, clean, simple). If you want to round-trip from a SSA representation, you might have the misfortune to end up with the hairball of mutable state that is Soot.

19:11 arrdem: that's rather unfortunate.. ^:static should have a huge performance impact on function calls.

19:11 hiredman: if I recall correctly, when :static did do stuff it didn't pr-str the function object, althought it may have just called a no-arg constructor, so closing over may have not worked there either

19:11 Bronsa: hiredman: I'm looking at the code right now, looks like :static preserved the static types of args

19:12 arrdem: nDuff: that's probably overkill but I'll look into it. gtrak's hack is working really nicely.

19:12 Bronsa: hiredman: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L3454-L3460

19:13 owl-v-: how do i remove def in clojure “(def x 3) (if (< x i) (def x i))”?

19:13 in loop

19:13 justin_smith: owl-v-: use a loop binding, not a def

19:13 hiredman: Bronsa: I could be wrong, but isn't that the Expr class for static method interop?

19:14 justin_smith: owl-v-: def is only for globals

19:14 Bronsa: hiredman: no, that's StaticMethodExpr

19:14 StaticInvokeExpr is for :static

19:14 justin_smith: owl-v-: and ideally a def is not changed (with a few notable exceptions)

19:15 ,(loop [i 0 j 5] (if (> i j) [i j] (recur (inc i) (dec j)))) ; owl-v-

19:15 clojurebot: [3 2]

19:15 hiredman: Bronsa: so it tried to, but it relied on the static types at the call site, and wasn't connected to invokePrim anyway

19:16 justin_smith: owl-v-: notice that this way there are no "variables" - nothing changes other than bindings

19:16 Bronsa: hiredman: so if I'm not mistaken ^:static removed the var indirection + preserved the static types

19:17 gvickers: I have a vector of numbers [1 2 3 4 5], what is the most idiomatic way to return a new vector with the last element incremented?

19:17 arrdem: Bronsa: that seems to be the case..

19:18 owl-v-: justin_smith: (inc i) (dec j) yes... but (/ j 2)?

19:18 justin_smith: owl-v-: sure, whatever you need to do with the args

19:19 make each one a binding in the appropriate place

19:19 hiredman: Bronsa: sure, that must be why it was removed, in favor of invokePrim

19:19 owl-v-: ?

19:19 Bronsa: hiredman: probably, yeah

19:19 hiredman: the type stuff for it is way too fragile, depending the types at the callsite

19:20 justin_smith: owl-v-: often in clojure instead of mutable objects you have functions that create bindings based on arguments. instead of changing some variable, you bind an argument and recur

19:20 Bronsa: hiredman: no, it doesn't depend on the types at callsite. it uses the types on :arglists

19:20 hiredman: Oh

19:20 justin_smith: ,(loop [i 0 j 50] (if (> i j) [i j] (recur (inc i) (/ j 2)))) owl-v-

19:20 clojurebot: [4 25/8]

19:21 Bronsa: params is arglists, args is args at callsites

19:21 I mess that up everytime too

19:21 justin_smith: owl-v-: inc and dec are not special, it works the same way with any other function

19:21 arrdem: is it trying to offload the typecheck to the caller...?

19:21 hiredman: Bronsa: interesting, this is live on commented stuff, I wonder what it looked like when :static was live

19:22 justin_smith: gvickers: if it is always a vec and not some other sequential type:

19:22 ,(let [vec [0 1 2 3 4 5]] (conj (pop vec) (inc (peek vec))))

19:22 clojurebot: [0 1 2 3 4 ...]

19:22 justin_smith: err... :)

19:22 ,(let [vec [2 3 4 5]] (conj (pop vec) (inc (peek vec))))

19:22 clojurebot: [2 3 4 6]

19:23 justin_smith: silly aggressive truncation

19:23 Bronsa: arrdem: btw it looks like an approach like invokeStatic (assumed I understood this correctly) should be more robust for removing the var indirection rather than using ^:const

19:23 gvickers: justin_smith: thanks that is very clean!

19:23 verma: why would om/get-state work fine and return what's expected, but om/set-state! would blow up on the same owner?

19:23 arrdem: Bronsa: noted and added to the research list

19:23 Bronsa: arrdem: because it should work fine with fn with closed-overs too

19:23 justin_smith: gvickers: also peek / pop are constant time, unlike some other options

19:24 will not work on lists or lazyseqs or whatever though

19:24 verma: context: https://gist.github.com/verma/11016107

19:34 owl-v-: justin_smith: i couldn't remove def in second loop https://www.refheap.com/77114

19:35 justin_smith: OK - one more note - that first loop doesn't actually do anything, you have to bind the result somewhere (likely by pulling it into a let binding)

19:36 hiredman: Bronsa: well, :static generated static methods, so closed overs wouldn't work

19:37 justin_smith: owl-v-: also, the recur's args should not be in a vector - it should have two separate args

19:37 Bronsa: hiredman: oh right

19:38 arrdem: I derped. ^

19:38 hiredman: Bronsa: you could just get rid of manual :static flagging, do λ lifting and implement any function that doesn't close over anything and is never used as a value as a static method

19:38 (you know, for the clojure compiler you are working on)

19:39 justin_smith: owl-v-: also, the body of the function should be wrapped in let, so you can bind xx, a and x, and each block should create a new binding in the let form

19:39 arrdem: hiredman: even if it is used as a value you can still do static lifting..

19:39 justin_smith: ,(let [a 0 b 1] (+ a a a b b)) ; owl-v-

19:39 clojurebot: 2

19:39 arrdem: hiredman: you just have to have an instance class around that you can pass as a value.

19:39 justin_smith: ,(let [a 1 b 2] (+ a a a b b)) ; owl-v- - slightly less pointless this time

19:39 clojurebot: 7

19:45 coventry`: owl-v-: You'd probably get a lot out of chapters 3 & 4 of Clojure From the Ground Up: http://aphyr.com/posts/303-clojure-from-the-ground-up-functions

19:47 justin_smith: (inc coventry) good link

19:48 coventry`: verma: Have you verified it's failing on that line by deleting it?

20:15 verma: in om, how do I setup a component local state?

20:15 I have a go loop in IWillMount which sets a state variable which is used by a function inside IRenderState

20:16 doing a (om/set-state!) in my go loop inside IWillMount is blowing up

20:27 seancorfield: verma: you probably want to ask on the #clojurescript channel

20:28 verma: but put your code on refheap.com and post the link so we can take a look

20:28 verma: seancorfield, thanks, will do

20:28 I did put it here: https://gist.github.com/verma/11016107

20:29 at least the area I'm having trouble with

20:30 coventry`: verma: Oh, put the set-state! in did-mount instead.

20:31 owl-v-: I found this but I don't understand line 2 and 3. https://www.refheap.com/77117

20:31 coventry`: Probably the whole go block.

20:31 verma: https://www.refheap.com/77118

20:31 justin_smith: owl-v-: that defines multiple arities for the same function

20:31 verma: coventry` I did try that, let me do it again to make sure

20:32 justin_smith: owl-v-: it decides which one to call based on how many args it gets

20:33 verma: coventry`, I tried in did-mount but it fails the same way.

20:34 owl-v-: justin_smith: lol; is it like function overloading?

20:35 justin_smith: it is argument count overloading

20:35 if it gets one arg, the first one is used, if it gets 3 args, the second one is used

20:38 seancorfield: verma: exactly how is it failing? what JS errors are you getting in the console?

20:38 oh, taking it to #clojurescript

20:38 verma: :)

20:38 jwm: can you do a def inside a defmacro?

20:39 arrdem: jwm: you can have a macro that writes defs, but defs inside of defs are bad news.

20:41 jwm: yeah

20:41 I just wanted a nice shorthand way to define a bunch of similar globals

20:43 amalloy: jwm: you can do it by macroexpanding to (do (def ...) (def ...)), with something like `(do ~@(for [...] `(def ...)))

20:43 but if you need a bunch of similarly-named globals to be autogenerated, consider whether they should really all be separate globals at all. perhaps one global containing a map or a list would be better

20:45 jwm: yeah, I might do a map

20:45 I already did a map for my db collection :)

21:03 devn: Is there something already out there for doing a "fair interleave", where given [2 2], [4 4 4 4], [8 8 8 8 8 8 8 8], you get the least number of repetetive occurrences for each coll?

21:04 so, maybe an answer would be: [2 4 8 8 4 8 8 2 4 8 8 4 8 8]

21:05 or [1], [3 3 3], [5 5 5 5 5] => [1 3 5 5 3 5 5 3 5]

21:05 justin_smith: devn: that looks like something one would find in an algorithmic music composition toolkit (not that I can name it or point to an impl)

21:05 arrdem: devn: sort by length, partition, interleave?

21:06 devn: arrdem: let me give that a look -- my brains are fried today but i'd like to finish this last bit of work and call it a day

21:07 justin_smith: devn: that example with 1, 3, 5 is not the one that eliminates the most repetition, because the 1 could be between two 5s without adding any other repeat

21:07 devn: yeah, you're totally right

21:08 justin_smith: not that I know what the algorithm should be, just going off the constraint you describe

21:08 devn: no it's a good point, thanks

21:09 justin_smith: but then it's not much of an "interleave" - or it is a weird one - if 1 ends up in the middle somewhere like that

21:09 devn: the other case i havent written down yet is the case where there are a couple of even colls, [2 2] [3 3] [5 5 5 5 5] => [2 5 3 5 2 5 3 5 5]

21:10 justin_smith: I think what you describe could be interpreted as a few different kinds of interesting puzzle

21:10 devn: it's probably a well defined problem. network algorithms

21:11 this is really to cut down on hammering a particular host

21:11 justin_smith: ahh

21:11 devn: but the set of requests is a known value, and the range of hosts is a known value

21:12 so you might have like: {"host1.com" 33 "host2.com" 999 "host8.com" 2000}

21:12 justin_smith: what about an iterate that decs the count refered to by some key in a map, preferring to access each at a rate proportional to its count but also avoiding hitting the same one twice in a row

21:12 devn: it doesnt do a whole lot of good when the values are really far apart

21:12 but it's /something/

21:19 maybe this would work: https://github.com/overtone/overtone/blob/master/src/overtone/algo/chance.clj#L18

21:19 ,(let [data [1 3 3 3 5 5 5 5 5] freqs (frequencies data) total (count data) pcts (for [[v cnt] freqs] (double (/ v total)))] pcts)

21:19 clojurebot: (0.1111111111111111 0.3333333333333333 0.5555555555555556)

21:19 justin_smith: devn: weighted round robin? http://en.wikipedia.org/wiki/Weighted_round_robin

21:20 devn: justin_smith: nice find. thanks. i should have googled round robin.

21:20 justin_smith: a weighted choose seems like an impl detail for a weighted round robin actually :)

21:22 devn: the only issue with what you were saying above is that weighted round robin serves empty packets

21:22 i can pad and interleave with nils, but i am not going to be making empty requests

21:22 justin_smith: right

21:22 it's not a perfect mapping, but there are similarities

21:22 devn: justin_smith: yeah, i think the weighted choose is just fine

21:23 the spacing doesn't need to be perfect, just better than 500000 xs, and then 40000 ys

21:23 cddr: Does anyone have examples of really gnarly Java libraries that have been given a makeover with clojure?

21:24 justin_smith: cddr: you could compare ring to the java stuff it abstracts over, if that's what you mean

21:24 (ring being a lib for request handling in an http server, java stuff being tomcat or jetty etc.)

21:25 cddr: That sort of thing but I didn't think the servlet API is that bad (though admittedly I haven't used it in anger)

21:26 justin_smith: cddr: it is OK, it is not as nice as ring is

21:26 cddr: agreed

21:26 weavejester: Plus, Ring reimplements the parts of the servlet API that aren’t particularly well thought out.

21:27 justin_smith: or you could compare clojure.java.io to the various low level java stuff you would use otherwise - my only problems are the areas where c.j.io doesn't have coverage

21:27 and things like expecting a string to be a url instead of making it a byte stream

21:27 weavejester: Most of the time Clojure wrappers are around Java libraries that have reasonable APIs.

21:28 It’s very hard to deal with Java APIs that are “enterprisey”.

21:28 Usually it’s easier to rewrite those parts.

21:31 cddr: That's interesting. As a lisper, I was slow to look at clojure because where I worked at the time didn't have any Java code...

21:31 ...and I thought a big part of what was cool about it was that it worked well with one's existing Java codebase

21:32 justin_smith: I was slow to look at it because of a kneejerk reaction to [#{{}}]

21:32 weavejester: Funnily enough, the bracket syntax was one of the things that attracted me to the language.

21:32 justin_smith: somehow my reptile brain was like "thos symbols mean scary imperative madness"

21:33 llasram: cddr: Being able to use Java libraries is a huge advantage. Being able to use Java libraries with well-designed, simple interfaces directly is a huge advantage

21:34 cddr: But of course not every Java library has either a simple or well-designed interface

21:36 weavejester: Clojure tends to be less tolerant of complexity and bad design than Java. The more complex a Java library, the harder it is to build a simple interface to it, and therefore the harder it is to use with Clojure.

21:36 justin_smith: I may have to master the art of "java as if it were clojure, but I'm not allowed to use clojure" soon :(

21:37 I'm sure it can be done, but it will suck.

21:37 nDuff: justin_smith, ...well, there _are_ employers around that are looking for Clojure folks. :)

21:37 hiredman: justin_smith: write clojure code to generate the java source

21:38 justin_smith: heh, I like my workplace for now - I just may have to branch out into other languages to stay here

21:38 hiredman: yeah, I would be more than a little tempted :)

21:38 llasram: justin_smith: Would that be for a specific project?

21:39 nullptr`: whois llasram

21:39 llasram: hoho

21:39 SPIES

21:39 justin_smith: llasram: we are a web shop. As we move up in the industry (bigger clients, bigger budgets), we are more likely to have to cooperate with their IT demands

21:39 * nullptr` hides

21:39 arrdem: RED SPY IN THE BASE

21:40 * arrdem builds sentries everywhere

21:40 justin_smith: llasram: so it's more a question of MEGASHOECORP only allows java or node on the backend, MEGACOFFEECORP only allows php, etc.

21:40 llasram: Gotcha

21:40 justin_smith: whereas we used to say "your cheapest option is to let us build this thing with clojure" and they'd be like "cheap? OK"

21:40 llasram: nullptr`: http://blog.platypope.org/ :-)

21:41 * nullptr` nods hello

21:41 llasram: justin_smith: Yeah, probably a big harder to convince big companies of that TCO-wise

21:42 justin_smith: llasram: especially when they are leveraging their own ops team - one that "gets" java, but distrusts clojure

21:42 cddr: Yeah there's no getting round the "but nobody here knows clojure" objection

21:42 justin_smith: but is smart enough to know your clojure jar is not java (ie. tried to run a static analasys lib on it...)

21:42 llasram: Interesting

21:43 justin_smith: we had one very big client, big budget, where if we could point to a trustworthy third party static analysis tool that worked, we could have kept using clojure

21:44 coventry`: What did they want to use the tool for?

21:44 justin_smith: security analysis

21:44 java has so much predictable boilerplate, you can actually detect many common security flaws with regexes I guess

21:44 or something, I half suspect it is all voodoo

21:44 but nobody put a clojure label on their voodoo

21:45 llasram: Interesting. I would have expected that sort of tool to work mostly on bytecode, and thus work "fine" on AOTed Clojure

21:45 justin_smith: nope

21:45 arrdem: justin_smith: I mean... it depends... you can detect some really interesting things using static analysis..

21:45 justin_smith: no bytecode support

21:45 and we found no option with bytecode support

21:45 arrdem: bytecode analysis is really hard... you loose a lot of source PL semantics.

21:46 justin_smith: arrdem: in that case we should really have a provider offering that for clojure - at least one big company would have paid good money for it :)

21:46 arrdem: justin_smith: I mean.. if you wanna contract me to haxx on T.A and build such a thing I'll drop out now :D

21:46 coventry: I wonder how hard it is to retarget the clojurescript compiler to java.

21:46 arrdem: coventry: why would you?

21:47 justin_smith: so that existing java sa tools work

21:47 arrdem: mmmmm....

21:47 coventry: I didn't say it's a good idea, just one way to get through the hoop.

21:48 justin_smith: maybe the easiest way to get "good" coverage (meaning at least as much coverage as java gets)

21:48 arrdem: honestly... you could probably just write a t.a backend that writes Java source..

21:48 seangrove: coventry: You were clearly endorsing and recommending - nay, demanding - it be done

21:48 'I wonder' being the key words there

21:48 justin_smith: I wonder how hard it would be to launch florida into the sun

21:49 arrdem: justin_smith: how many boosters do you have?

21:49 justin_smith: =P

21:49 justin_smith: arrdem: let me start the kickstarter project and see how far we get

21:49 coventry: seangrove: Well, if anyone does it, I'll thank them I guess. :-)

21:51 justin_smith: anyway, yeah, if we had an sa tool for clojure, that would mean more paying clojure jobs, from what I have seen (both paid to make the tool, for usage of the tool, and clojure jobs that open up thanks to availability of the tool)

21:51 also, the easier it is for people to learn clojure... because one limiter is the fear of not being able to find another clojure dev in however many years if updates or fixes are needed

21:52 devn: man, it's been awhile since i've looked at incanter and contrib, but i just found myself in both of those places

21:52 justin_smith: contrib?

21:52 devn: so much buried treasure

21:52 clojurebot: Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

21:52 arrdem: hahahahah this SA suite claims to detect infinite loops... someone in Marketing needs to learn about the Halting Problem.

21:53 justin_smith: arrdem: that tells you how low the barrier is for that cash cow :P

21:53 arrdem: devn: not really.. I recently read a bunch of old contrib stuff. The valuable bits have all migrated already.

21:53 hiredman: justin_smith: some of that is just age, tools based on pattern recognition need patterns to be established and widespread

21:53 devn: arrdem: what about the monte-carlo lib?

21:53 justin_smith: I mean, as long as it doesn't claim to catch "all" infinite loops, they could be technically in the clear

21:54 hiredman: very good point

21:54 hiredman: and I think clojure allows for a lot of surface level variation in patterns (being so expressive)

21:54 which makes sa harder, maybe

21:54 coventry: So those java s.a. tools actually carry their weight?

21:54 devn: justin_smith: yeah, it's not /completely/ ridiculous to say "detects infinite loops"

21:55 yourkit "detects deadlock"

21:55 hiredman: the linting / sa space around clojure is trending upward, eastwood is great, typed clojure operates in a similar space

21:55 arrdem: and it is valuable to have taint analysis tools...

21:55 devn: forgive me, but just so im clear: SA => Software Analysis?

21:55 hiredman: (I haven't seen anything built on codeq yet though)

21:55 justin_smith: (not (re-matches #".*(while true .*)" source)) ;detects infinite loops

21:55 arrdem: devn: static analysis

21:56 devn: oh, thanks

21:57 justin_smith: fun talking, I need to head home

21:57 devn: so, story: years ago i had a conversation with chouser at strangeloop about how rich was really interested in datalog.

21:57 he brought up the idea of queryale programs and analysis

21:57 then rich builds datomic, then codeq

21:58 it seems like there has been some clear intent

21:59 coventry: devn: I meant security analysis.

22:00 devn: haha

22:00 hiredman: I really like the idea of codeq, and setup our ci server at work to import code in to it, but I have yet to come up with an interesting query to run on it

22:00 devn: that's been on my mind a lot lately too! :)

22:00 arrdem: hiredman: symbolic test coverage analysis!

22:00 hiredman: are you covering all slices of tested functions...

22:00 devn: hiredman: yeah, it's kind of a bummer that's the case. i think it needs to have its model expanded and be able to do sandboxed eval

22:01 arrdem: hiredman: all kinds of interesting things you can do there.

22:01 devn: i have been waiting for someone to add to the model with something like clojure.tools.analyze

22:01 so it's not just git

22:02 but then again, maybe that's not necessary

22:03 you could run some code at every commit where you basically generate metadata as symbols in a separate namespace

22:03 using tools like clojure.tools.analyze, etc. -- then you could query that

22:04 (def more-info-about-a-foobar-fn {...edn...})

22:05 what do you think?

22:07 i killed chat.

22:07 arrdem: I think you're complecting the evaluator and the source metadata.. if you're in an environment where you want it, just save the entire T.A tree into your Datomic store. Better yet, figure out some mapping of functions to uuids that's relatively static across program versions and devise a way to leverage Datomic's data change model to reflect changes in the analyzed program let alone the source code.

22:10 devn: arrdem: i think my general line of thinking is: expand codeq's model to allow for evaluation of particular aspects of the source on import.

22:12 does that still strike you as totally crazy? i think it'd be really cool if you could boot up codeq and say: "go spelunking in clojure.core" -- it uses tools.analyzer, eval with fuzzing of inputs to fns, etc. to add metadata to each commit

22:13 owl-v-: how do i loop through string?

22:13 arrdem: devn: nope... sounds like the kind of "real" next generation compiler I'd like to see T.A become and Clojure 2.0.0 feature.

22:14 devn: owl-v-: you mean like this?

22:14 ,(map clojure.string/upper-case "foo")

22:14 clojurebot: ("F" "O" "O")

22:14 devn: ,(apply str (map clojure.string/upper-case "foo"))

22:14 clojurebot: "FOO"

22:15 devn: ,(for [character "foo"] character)

22:15 clojurebot: (\f \o \o)

22:17 nullptr`: ,(let [[f o o] "foo"] (str o o f))

22:17 clojurebot: "oof"

22:18 owl-v-: thanks. this works. (defn test-palindromic [c] (for [a (str c)] a ))

22:18 devn: you can use loop/recur, owl-v- but the way you phrased your question made me think you might be trying to do something like "each"

22:19 ,(doseq [character "foo"] (println character))

22:19 clojurebot: f\no\no\n

22:19 devn: if you want "each"

22:29 elpizochoi: exit

22:34 owl-v-: how do i reverse string? "123" to "321"?

22:35 found it: (println (apply str (reverse (str 123))))

22:55 line 7 and 11 causing problem in this code: https://www.refheap.com/77125

23:02 Frozenlock: owl-v-: I've only rarely used recur, but shouldn't there be a `loop' somewhere?

23:03 owl-v-: Frozenlock: This one don't have loop and it works just fine: https://www.refheap.com/77117

23:03 alandipert: Frozenlock, the function is the recur point in this case

23:04 dbasch: Frozenlock: that’s how you do recursive functions

23:04 Frozenlock: well, tail-recursive functions

23:08 owl-v-: line 6 calls an array as a function

23:08 owl-v-: ops! syntax error!

23:08 dbasch: owl-v-: I assume that’s not what you intended

23:08 owl-v-: never mind, you’re doing multi-arity

23:08 ivan: are type annotation warnings supposed to prevent tools.namespace from actually refreshing?

23:08 owl-v-: ((- n1 1) * n2) to (* (- n1 1) n2)

23:08 :P

23:08 ivan: (also, no idea how to annotate something as an array of SomeJavaObj)

23:09 TEttinger: ivan: uh... it's complicated

23:09 ^[Lmy.namespace.SomeJavaObj

23:09 owl-v-: just syntax error which my editor didn't catch...

23:09 dbasch: owl-v-: also, your comparison is unnecessarily verbose

23:09 TEttinger: but better is ^"[Lmy.namespace.SomeJavaObj"

23:09 dbasch: ,(= (apply str (reverse "12321")) "12321")

23:09 clojurebot: true

23:09 ivan: TEttinger: thanks

23:10 TEttinger: actually uh I don't know if the quotes are a good idea

23:10 they might still need reflection if quotes are used, my use of type hints is rusty

23:11 (but you have a dangling bracket otherwise. stupid opcodes)

23:12 a 2d array of SomeJavaObj is ^[[Lmy.namespace.SomeJavaObj

23:12 ivan: ^"[Ljava.nio.file.LinkOption;" worked

23:12 owl-v-: dbasch: thanks. that works to with simplicity

23:12 noto: and I forgot ; right

23:18 arrdem: hack of the night... <arrdem> hiredman: symbolic test coverage analysis!

23:18 <arrdem> hiredman: are you covering all slices of tested functions... [20:53]

23:18 <devn> hiredman: yeah, it's kind of a bummer that's the case. i think it needs

23:18 to have its model expanded and be able to do sandboxed eval

23:18 <arrdem> hiredman: all kinds of interesting things you can do there.

23:18 <devn> i have been waiting for someone to add to the model with something like

23:19 clojure.tools.analyze

23:19 <devn> so it's not just git [20:54]

23:19 <devn> but then again, maybe that's not necessary

23:19 <devn> you could run some code at every commit where you basically generate

23:19 metadata as symbols in a separate namespace [20:55]

23:19 <devn> using tools like clojure.tools.analyze, etc. -- then you could query

23:19 gtrak: ~guards

23:19 clojurebot: SEIZE HIM!

23:20 Frozenlock: arrdem: you should probably paste it on refheap

23:20 arrdem: GAH

23:20 I'm sorry...

23:21 eh 12 lines coulda been worse

23:21 Frozenlock: well, the formatting is terrible :-p

23:22 arrdem: Frozenlock: it was an accident, new emacs keybindings and the capslock->ctrl remapping have me failing left and right today.

23:22 Frozenlock: I did about 75 lines of garbage in #clojure-social earlier today, now this T_T

23:23 Frozenlock: arrdem: Time to write some elisp to prevent you from pasting more than 2 lines of text in erc :-p

23:23 arrdem: Frozenlock: I already turned off flood protection...

23:23 I guess my proxy is providing it's own buffering or something.

23:32 Frozenlock: Any suggestions for this? https://www.refheap.com/77129

23:33 alandipert: Frozenlock, i'd put the maps into priority maps and binary search the now sorted-by-value thing

23:34 Frozenlock, https://github.com/clojure/data.priority-map or https://github.com/tailrecursion/cljs-priority-map in cljs

23:35 Frozenlock, actually - disregard. i think i completely misunderstood your question :-)

23:36 Frozenlock: alandipert: Yeah, I don't think I can do anything with that. But thanks anyway, I was unaware of priority-maps

23:39 dbasch: Frozenlock: how about something like (partition 2 (interleave (sort-by :a first-col) (sort-by :a second-col))) ?

23:42 Frozenlock: dbasch: That was my first approach, but there's a problem with that. Say the values are [1 2 3 4] [2 3 4 5], you 'll end up something with 1 and 2 paired together, instead of 2 and 2.

23:42 Eh, I might have forgot to say that I can drop value if needed. ;-)

23:49 dbasch: Frozenlock: so in that case you’d want to keep only 2-2, 3-3 and 4-4?

23:50 jcrossley3-away: cddr: immutant is chock full of "examples of really gnarly Java libraries that have been given a makeover with clojure", e.g. jms/hornetq, infinispan, quartz, etc

23:51 Frozenlock: dbasch: Yes. Or keep 1 matched with 200 or whatever (I can just filter it later). But 2-2 should be together, because they are a closest match.

23:53 Uh... is it me or Cider refuses to have more than a single function definition per entry?

Logging service provided by n01se.net