#clojure log - Oct 24 2014

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

1:08 domokato: hi guys

1:09 is there any way to preserve line numbers inside expanded macros (i.e. in stack traces)?

1:17 rritoch: domokato: What are you using to print your stack traces? All of my stack traces use clojure.repl/pst which always seems to report the line number of the macro (preserving line#)

1:18 domokato: rritoch: I mean during an exception. do i have control over how those print?

1:19 rritoch: domokato: Sure, just catch the exception (try ... (catch Throwable t (clojure.repl/pst t))

1:21 domokato: rritoch: thanks! i'll try that

1:23 rritoch: Does anyone know of a syntax using something like partial for the case where you want to append arguments? ex. instead of (map #(get % "id") mylistofmaps) something like (map (??? get "id") mylistofmaps)

1:28 domokato: rritoch: what about stack traces in compile errors? pst wouldn't work, would it?

1:31 TEttinger: ,(defn post-partial [f & args] (fn [& args2] (apply f (concat args2 args))))

1:31 clojurebot: #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>

1:32 rritoch: domokato: No, I don't know any way to catch compile errors other than manually compiling from repl (try ... (compile 'some.ns) ...

1:33 domokato: If your using leiningen maybe you could make a custom plugin, but I'm fairly sure that leiningen already uses something similar to pst to properly format clojure errors

1:34 domokato: rritoch: hm, ok. i have a macro that is like a let block, and any compile errors inside get compacted onto one line :(

1:35 rritoch: domokato: I see, that is the appropriate behavior, to debug your code you can use macroexpand and use the expansion in place of your code for debugging.

1:37 TEttinger: ,(((fn post-partial [f & args] (fn [& args2] (apply f (concat args2 args)))) get "id") {"id" 1})

1:37 clojurebot: 1

1:37 TEttinger: ok, it does work...

1:37 ,(defn post-partial [f & args] (fn [& args2] (apply f (concat args2 args))))

1:37 clojurebot: #'sandbox/post-partial

1:37 domokato: rritoch: clojure could in principle accurately report the line numbers where the body of the macro call used to be, couldn't it? that would be a good feature to add to the language

1:37 TEttinger: ,((post-partial get "id") {"id" 1})

1:37 clojurebot: 1

1:38 domokato: rritoch: that's a good idea

1:38 rritoch: TEttinger: Cool, that works for me, but I was hoping clojure already had it in its codebase

1:38 TEttinger: rritoch, how does that post-partial work for you?

1:38 oh ok

1:39 yeah, it's hard to think of every possible use case for mixing and matching fns and then to stick all of those in the std lib :)

1:39 domokato: rritoch: and how come clojure's core macros don't have this problem?

1:39 clojurebot: Excuse me?

1:44 rritoch: domokato: The best way I can answer that question is that clojure macros have gone through a lot of testing so any bugs with the macro's have been repaired already. When you see line#'s within clojure from macro expansions it will be to the function the macro called. I've never seen an inter-macro line# in a stack-trace.

1:46 domokato: rritoch: i meant when you use let and there is a compile error inside the body, you'll get a line number. but i guess let is a special form, so maybe that's why it works

1:47 rritoch: TEttinger: How could I go about getting registered with clojurebot?

1:50 TEttinger: I didn't know clojurebot needed registration

1:51 rritoch: OH, so what do I prefix with to use it?

1:51 TEttinger: comma

1:51 start a line with a ,

1:52 lazybot uses & or ## but ## will also work in the middle of messages. ##(str "like " "this")

1:52 lazybot: ⇒ "like this"

1:54 rritoch: ,(macroexpand ~(let [x 1] (println x)))

1:54 clojurebot: 1\n#<IllegalStateException java.lang.IllegalStateException: Attempting to call unbound fn: #'clojure.core/unquote>

1:54 rritoch: ,(macroexpand `(let [x 1] (println x)))

1:54 clojurebot: (let* [sandbox/x 1] (clojure.core/println sandbox/x))

1:54 rritoch: domokato: I can't find where the let* function is defined, but I believe it is a function which is why your getting line numbers

1:55 TEttinger: (doc let*)

1:55 clojurebot: Excuse me?

1:55 TEttinger: I guess it doesn't have docs

1:55 rritoch: ,(type let*)

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

1:56 rritoch: odd

1:57 domokato: apparently let has some "magical" functionality with it

1:57 domokato: let* can't be a function, otherwise it would evaluate its body immediately before any bindings could be made

1:57 TEttinger: it's probably private

1:57 justin_smith: rritoch: let* is a special form

1:58 rritoch: the special forms are defined in the java code

1:59 domokato: i've actually been avoiding writing macros that take bodies because it's hard to figure out where compile errors are...

2:33 borkdude: repost from #clojurescript: can someone take a look at this project why weasel isn't working in the browser? keep getting connection refused. start weasel by typing lein repl + (brepl). https://github.com/borkdude/todo-cljs

2:57 rritoch: Does anyone know what app clojuredocs.org uses to generate it's documentation? I'm currently using codox and lein-marginalia but neither compare to the quality @ clojuredocs.org

3:05 justin_smith: https://github.com/zk/clojuredocs

3:11 rritoch: justin_smith: Thanks, I didn't realize it was a web app but I should be able to use it for my own projects. It doesn't have a generator to produce static pages?

3:20 Geeky_Vin: anyone here used clojure to connect and create triples in allegrograph?

3:22 clgv: ~anyone

3:22 clojurebot: anyone is anybody

3:22 clgv: ~anybody

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

3:23 Geeky_Vin: okay, sorry for that.

3:24 does anybody here used clojure to connect and create triples in allegrograph?

3:24 clgv: no need to apologize. ;)

3:24 woah, the second message was the important one :P

3:25 Geeky_Vin: can you please pont me to a working code that would do that, cause the one I found in the franz site seems to be buggy and outdated.

3:25 clgv: you should ask your concrete problem - if anyone used allegrograph for that they can immediately answer ;)

3:25 Geeky_Vin: *point

3:31 has anybody used Allegrograph?

3:36 clgv: Geeky_Vin: maybe you have more luck later today when all the americans are here ;)

3:38 mskoud: Is there a library which provides cursors into atoms? I'm struggeling making updates in deep nested maps/vectors. I can find the location i want to update with filter functions, but that does not helt me when i want to update this location.

3:39 clgv: mskoud: "atom" as in clojure.core/atom or did you just mean values of nest maps/vectors?

3:40 mskoud: Lets say i have {:sublocation-id 2 :locations [{ :id 1 :name "A"} { :id 2 :name "B"}]} and the sublocation-id identifies i need to change element {:id 2 :name "B"} to fx :name "C"

3:40 clgv: mskoud: do you have a path to the update location or do you want to visit the structure and decide when you are at a location that you want to update that location?

3:41 mskoud: i do not have a path to it.

3:42 but i could build a path in a vector, that might be the best way.

3:42 clgv: in this case you have a path to the collection in which you dont know which element to change

3:42 TEttinger: you know about zippers, right mskoud? http://www.exampler.com/blog/2010/09/01/editing-trees-in-clojure-with-clojurezip/

3:42 clgv: as TEttinger says, zippers could be a solution

3:42 mskoud: ok! ill look into zippers. thanks.

3:43 clgv: but if you know the partial path and then just have to search the collection via a predicate you can build a function for that scenario

3:43 TEttinger: zippers are yet another handy tool in clojure's toolbox for dealing with data

3:43 rritoch: mskoud: You could always utilize a mutable data-type like java.util.HashMap (*duck*)

3:43 clgv: e.g. (modify-in data [my path] predicate update-fn arg1 arg2 ...)

3:44 rritoch: why should that be a good idea?

3:44 TEttinger: yeah, it doesn't solve much here

3:45 clgv: rritoch: depending on his context that might even cause severe problems (data in atom/ref)

3:45 rritoch: clgv: It's not really clojure(esque) but it's a lot easier to traverse HashMaps for deep updates

3:46 clgv: rritoch: but in his case it doesnt have real benefits but will forbid usage of that data within atoms or refs...

3:47 rritoch: clgv: forbid use within atoms?

3:49 ,(type (deref (atom (java.util.HashMap.))))

3:49 clojurebot: java.util.HashMap

3:49 mskoud: Think i'll be using swap! and update-in and define a helper function like (defn find-position-in-vector [vector-of-maps map-key map-val])

3:57 clgv: rritoch: yes they wont work correctly anymore. you'll loose the consistency guarantees

3:58 mskoud: just build something like (modify-vector v predicate modify-fn)

4:01 rritoch: ,(let [x (atom (java.util.HashMap.))] (swap! x #(do (.put %1 :k %2) %1) :v) (.get (deref x) :k))

4:01 clojurebot: :v

4:01 rritoch: Looks good to me

4:01 clgv: rritoch: single threaded yes.

4:01 rritoch: start firing multiple threads at it manipulating the atom

4:01 hyPiRion: no, not even single threaded

4:02 or well, eh – practically yes

4:02 but there's no guarantee the function passed to swap! won't be called multiple times

4:02 clgv: hyPiRion: why? If there are no retries, no consistency checks are needed ;)

4:02 rritoch: clgv: I'm under the understanding that any swap! ops are serialized so there shouldn't be a problem

4:03 justin_smith: rritoch: no

4:03 clgv: rritoch: there is. because of how the "atomicity" guarantee works. it is only guaranteed for clojure's persistent data structures

4:04 justin_smith: (doc swap!)

4:04 clojurebot: "([atom f] [atom f x] [atom f x y] [atom f x y & ...]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

4:04 justin_smith: if it was just serializaiton, there would be no retries

4:04 clgv: or well datastructures built to fulfill the same contracts as clojure's datastructures ;)

4:05 rritoch: in fact it uses compare and swap

4:05 justin_smith: rritoch: it does the ops optimistically, and then retries if it changed in the mean time

4:05 rritoch: with actual mutation, it won't be doing what you want at all

4:09 rritoch: justin_smith: Can you demonstrate an example where this fails? It has never failed for me?

4:14 This is a second example per clgv's comment about the compare and swap which again functions

4:14 ,(let [x (atom (java.util.HashMap.))] (swap! x #(do (.put %1 :k %2) %1) :v) (swap! x #(do (.put %1 :k2 %2) %1) :v2) (list (.get (deref x) :k) (.get (deref x) :k2)))

4:14 clojurebot: (:v :v2)

4:15 clgv: rritoch: you need concurrent modification of that hashmap, since this is the critical case where `atom` provides you consistency guarantees for clojure's persistent data structures

4:16 well, of the atom containing the hashmap to be exact

4:18 rritoch: clgv: If you need a thread-safe hashmap, see http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedMap%28java.util.Map%29

4:19 justin_smith: if you need a thread safe hashmap use {}, and use the fine tools that clojure supplies to modify it properly

4:21 rritoch: justin_smith: My point is simply that it is possible to reduce the complexity of accessing/modifying deep structures using HashMaps instead of clojure's Persistent versions.

4:22 clgv: rritoch: you are missing the whole point here... :(

4:23 alexherbo2: Hi

4:31 justin_smith: rritoch: https://www.refheap.com/92236

4:31 rritoch: checking...

4:31 justin_smith: if that were a proper clojure data structure in the atom, it would simply be shuffled

4:31 instead we lose data

4:34 borkdude: weasel problem solve

4:34 d

4:35 justin_smith: borkdude: what was the issue?

4:35 borkdude: justin_smith https://github.com/tomjakubowski/weasel/issues/33

4:36 (I wasted some hours on this, yuck :(

4:36 justin_smith: that's too bad

4:38 rritoch: justin_smith: Arrays aren't thread safe, the same should work with http://docs.oracle.com/javase/7/docs/api/index.html?java/util/concurrent/atomic/AtomicIntegerArray.html

4:38 err

4:38 clgv: unlikely ;)

4:38 rritoch: Well, it would, but I'm actually looking at AtomicReferenceArray which is more generic

4:39 clgv: rritoch: just plugin the AtomicIntegerArray into the code of justin_smith

4:40 rritoch: It isn't an array so the aset commands won't function

4:40 It works with .get and .set operations

4:40 clgv: rritoch: yeah you have to replace those with the read/write functions of that class...

4:40 but it will fail anyway

4:41 rritoch: additionally don't forget that your suggestion was to use hashmap within other clojure data

4:41 justin_smith: rritoch: yes, arrays are not thread safe. Earlier you suggested putting a hash map in an atom. Point is, atoms do nothing for you if you don't give them an immutible data type, if you are using a thread safe mutible, putting it in an atom is pointless

4:42 clgv: otherwise you'd switch completely to mutable java class, but then you come close having to ask the question "why again am I using Clojure in the first place?"

4:44 justin_smith: it'll even fail using the threadsafe class there. as long as he does not rewrite the code completely to use update (read+write combined) operations of that threadsafe class.

4:45 hyPiRion: rritoch: the point of persistent data structures in Clojure is mainly to make programming simpler by removing mutability. they decomplect identity and time compared to their mutable counterparts

4:46 justin_smith: clgv: right, but even if you use the threadsafe class properly - at best you are pointlessly using an atom to no benefit

4:46 hyPiRion: the fact that it makes concurrent programming easier is sort-of a side effect of them being simpler by nature

4:47 clgv: justin_smith: indeed

4:49 hyPiRion: the reason for the original question, is just that a lot convenience functions for "deep data manipulations" are missing. maybe a library is needed

4:50 justin_smith: clgv: I have never had too much issue with get-in, assoc-in, update-in, and the occasional clojure.walk/postwalk

4:51 clgv: justin_smith: well the previous data manipulation question is not too uncommon. I found myself in similar scenarios multiple times ;)

4:51 rritoch: clgv: As is, your right his code doesn't work

4:51 clgv: justin_smith: but it is probably not frequent enough for clojure.core

4:51 rritoch: algv: But I got it to work using (locking a)

4:52 clgv: rritoch: great, then you lost all benefits of atom ;)

4:52 justin_smith: rritoch: OK, then why is it in an atom?

4:52 rritoch: err... (locking a ...

4:52 justin_smith: it does work! it demonstrates that mutable types in atoms are pointless and broken

4:53 any fix involves a) something you could do easier without an atom b) using an immutible type inside the atom as intended

4:53 one of those

4:55 And, btw, one of those benefits of atoms being that unlike locking, it won't deadlock your code.

4:55 rritoch: justin_smith: well, locking on the mutable object resolves the issue, and the point of using an atom in this case is for mutability, so if you have long running apps that have an internal cache of the mutable object a reset process can load a new map into the atom without effecting running processes so processes started after the update would get the new map.

4:56 justin_smith: rritoch: you could do the same thing with a var

4:56 rritoch: Each new thread started would get the new mutable object, but existing threads would keep the old one

4:56 justin_smith: and with a var you wouldn't be pretending to get correctness that an atom is not giving you

4:56 that's not how atoms work

4:58 * clgv remembers hearing about at least two good Clojure books: "Clojure Programming" and "Programming Clojure (2nd Edition)"

4:58 rritoch: So how would you update the value of the var? It isn't exactly "good" programming practice to redefine vars.

4:58 Binding them is useful but won't update for all new threads

4:58 clgv: speaking of good Clojure programming practice ... ;)

4:58 justin_smith: rritoch: it isn't good practice to replace the contents of an atom, or to put mutible objects inside them

4:59 hyPiRion: justin_smith: replace the contents? Isn't that... what swap! and reset! do?

4:59 justin_smith: hyPiRion: with a bit more subtlety than what he is describing, sorry, I worded that poorly

5:02 icelesstea: Just exec some Scheme or some such in a separate thread, do the loop there and using set!, and then pipe its output back to Clojure - simple and cheerful !

5:02 justin_smith: hyPiRion: point being that the way he is describing using the atom provides no benefit he wouldn't get from reassigning a var, so I say better to dispose of the pretence and just use a var

5:02 rritoch: justin_smith: replacing a mutable object in an atom is an ideal way to handle "transational" state information for transactions which require multiple threads

5:02 justin_smith: rritoch: and what does this do that reassinging a var would not do?

5:03 rritoch: justin_smith: I honestly don't know, I never reassign vars, I always use atoms when I need mutable data.

5:04 justin_smith: rritoch: answer is nothing, using an atom to hold a mutable value is giving the illusion of correctness it cannot provide

5:04 clgv: rritoch: the take away is, just don't use mutable data in atoms or refs (not even transitively)

5:06 hyPiRion: I'm perhaps confused here, but I still don't grok why atoms + persistent data structures doesn't suffice here.

5:07 justin_smith: hyPiRion: they do suffice, rritoch was trying to tell someone their problem would be easier to deal with if they put a mutible hash map in their atom

5:07 hyPiRion: The combination is effectively thread-safe mutable data structures with snapshot capabilities.

5:07 alright

5:07 clgv: hyPiRion: they suffice for the original question of mskoud. just some tools functions are needed

5:08 hyPiRion: right. If you want a cache, you'd likely use some variant of cace from core.cache inside an atom

5:08 mskoud: they do indeed, a simple update-in with a helper function to obtain an index.

5:08 rritoch: clgv: I have 30 years programming experience, do you think I'm going th change my programming practices simply because you say so? The world doesn't work like that. I need to see actual proof that one way is better than another and I've already dealt with modifying deep structures with clojures persistent maps, its a nightmare, which is why I resort to using mutable maps for any deep structures.

5:08 clgv: mskoud: great :)

5:09 rritoch: clgv: Eventually someone will probably come up with some good functions for updating deep items of structured data in clojure, but until then data with a great deal of structure is easier to manage with mutable data.

5:09 clgv: rritoch: great argument - do as you like. I was just trying to help you to avoid painful consistency errors with atoms

5:10 justin_smith: rritoch: you are ignorant about clojure, stubborn about learning to use it properly, and trying to give novice clojure users advice on using the language. In my opinion at least one of these things should probably change.

5:10 Chousuke: what's the problem with update-in? is it too slow?

5:10 rritoch: justin, I'm not a "novice" I've been professionally programming in clojure for nearly 6 months

5:11 I've also read all of the official documentation (not counting the API refrence)

5:12 I've been programming with LISP since college, ~ 20 years experience there.

5:12 hyPiRion: rritoch: If I may ask, what exactly is the problem you have with updating deep items in structures?

5:13 the problem as in the difficult part of it

5:13 Chousuke: it's trivial

5:13 just use update-in

5:13 if it's too slow, then you might need another solution

5:13 rritoch: Merging back takes a ton of assoc statements which is fairly non trivial

5:13 justin_smith: rritoch: then you aren't using update-in

5:14 rritoch: Chousuke: that may be a solution, I've never used update-in

5:14 clgv: Chousuke: the actual question involved a predicate to find the elements that really need to change. so there could be useful helper function for that - but nothing critical

5:14 hyPiRion: Maybe you should try out update-in and assoc-in. They usually fit well

5:15 justin_smith: rritoch: I wasn't saying ignorant as an insult. update-in is one of the most important functions in the language, and addresses the problem of deep changes in immutible data structures in most cases.

5:15 hyPiRion: ,(update-in {:a [1 0 3]} [:a 1] + 40)

5:15 clojurebot: {:a [1 40 3]}

5:16 Chousuke: clgv: well, yeah, then you need to walk the entire datastructure anyway, which is less trivial. but isn't there a contrib library?

5:17 clgv: Chousuke: in fact a combination of update-in and walking the sequential collection suffices

5:17 justin_smith: Chousuke: there is clojure.walk/post-walk, or zippers, both were mentioned in this conversation

5:18 clgv: (modify-when coll pred f) would be a useful helper function.

5:18 but it's written quickly and then you can put it in tools lib you use ...

5:19 rritoch: Well, anyhow, thanks for the "update-in", it is my first time seeing that function, and yes, it does solve every problem I've ever had with deep structures.

5:19 hyPiRion: yay!

5:19 justin_smith: rritoch: http://clojure.org/cheatsheet

5:20 clgv: so let's get those mutable class from the table for non-performance optimization scenarios ;)

5:20 *classes

5:21 s/from/off ...

5:32 rritoch: Grumble, this assoc-in & get-in could have saved me at least 50 hours of headaches, someone should really add that to http://clojure.org/data_structures

5:34 Why isn't dissoc-in in clojure.core? That would also be helpful to complete the "set" of modification methods.

5:35 I've been abusing -> since I wasn't aware of get-in

5:36 hyPiRion: It's not evident how dissoc-in should act if the map turns empty

5:37 should (dissoc-in {:a {:b 3}} [:a :b]) return {:a {}} or {} (or nil)?

5:38 (But it's been discussed, see http://dev.clojure.org/jira/browse/CLJ-1063)

5:38 rritoch: hyPiRion: Well, I'd expect it to return {:a {}}

5:40 SagiCZ1: ,(= (:a {:a nil}) (:b {:a 5})

5:40 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

5:40 SagiCZ1: ,(= (:a {:a nil}) (:b {:a 5}))

5:40 clojurebot: true

5:40 SagiCZ1: isnt this weird?

5:40 rritoch: ,(dissoc {:a 1} :a)

5:40 clojurebot: {}

5:41 hyPiRion: me too. I usually define it à la (defn dissoc-in [m keys] (update-in m (butlast keys) dissoc (last keys)))

5:41 SagiCZ1: when the key is not in a map, it returns nil. If you pass it another parameter, that will be returned if the value is not found

5:42 ,[(:a {:a 1}) (:a {:a 1} :not-found) (:a {}) (:a {} :not-found)]

5:42 clojurebot: [1 1 nil :not-found]

5:42 hyPiRion: or (get {:a 1} :a :not-found)

5:43 SagiCZ1: yeah but not finding the key returns the same thing as when there IS a key with VALUE nil

5:43 rritoch: SagiCZ1: If you want to know if a key exists, check for the key instead of the value

5:44 hyPiRion: SagiCZ1: yes? That's why you can pass in a default value

5:44 If you want to check for existence and read its value in one function, use find

5:44 ,[(find {:a 1} :a) (find {} :a)]

5:44 clojurebot: [[:a 1] nil]

5:44 SagiCZ1: good ideas.. thanks

5:44 hyPiRion: ,(find {:a nil} :a)

5:44 clojurebot: [:a nil]

5:46 rritoch: hyPirion: is find faster than some?

5:47 `(some (partial = :k) (keys {:k nil}))

5:47 ,(some (partial = :k) (keys {:k nil}))

5:47 clojurebot: true

5:48 hyPiRion: rritoch: yes. But if you just want to check whether a key exists, you can use `contains?`.

5:48 ,(contains? {:k nil} :k)

5:48 clojurebot: true

5:50 rritoch: Ok, thanks. I've used contains before but I have an in? function in all of my apps which uses some so I usually just abuse that function

5:50 noncom: to people who used overtone: how do you go about sequencing your music ?

5:50 hyPiRion: np

6:01 SagiCZ1: how do you document a defmethod?

6:02 clgv: SagiCZ1: same as yesterday, document the defmulti

6:02 SagiCZ1: clgv: I am sorry I didnt catch the yesterday's response and forgot to check logs, thank you

6:16 Chaze: Hi. Is there any way to perform an eval with lexical bindings as bound variables?

6:16 My problem is, that I can do (let [x 1] (eval `(+ 1 x))

6:19 clgv: chaze: you have to inject those bindings

6:20 Chaze: clgv: can't google it. what do i do? :)

6:20 clgv: ,(let [y 1] (eval `(let [x# ~y](+ 1 x#))))

6:20 clojurebot: 2

6:21 clgv: the need for gensym arises from syntax-quote otherwise you'd need to use ~'x everywhere inside the list to eval

6:21 which you usually should not.

6:22 Chaze: why do you need `eval` anyway?

6:23 Chaze: clgv: I'm thinking of writing a constraint propagation DSL as an exercise, and want the user to be able to pass conditions along the lines of '(< x 3)

6:24 clgv: Chaze: you do not necessarily need eval for that. with macros you can construct functions for that shortcut predicates directly

6:24 s/that/these/

6:27 Chaze: how would a macro help me get around an eval here? at the time the predicate is defined by the user, none of its variables are bound to a value. then i need to evaluate them with different binding permutations

6:28 clgv: Chaze: the macro can expand to (fn [x] (< x 1)) which is then kept to use it later on

6:28 Chaze: the concrete solution depends much on how the DSL is structured

6:29 Chaze: clgv: ah. I could also expand to (fn [value-map] (< (value-map "x") 1)) or something along these lines?

6:30 clgv: Chare: though I'd prefer (fn [{:strs [x]}] (< x 1)) since you do not need to alter the specified form, which might get complicated

6:31 Chaze: that's map destructuring in case you want to look it up

6:32 Chaze: clgv: yeah, that's a nice solution. thx.

6:34 clgv: Chaze: another potential pitfall - if you can, let the user of the DSL decide how to name the bindings instead of doing that implicitely

7:57 CookedGryphon: Is there a good reason rseq doesn't work on strings? Or is it just unimplemented?

7:58 clgv: CookedGryphon: you want to cheat a palindrom exercise? :P

7:59 Bronsa: CookedGryphon: rseq is devined to operate in constant time

7:59 defined*

7:59 CookedGryphon: Bronsa: yeah.... and strings are indexed such that you can just make an iterator run over it backwards

7:59 Bronsa: hm, I guess it would be trivial to implement a RStringSeq though

7:59 yeah

8:00 CookedGryphon: dunno, no good reasons beside impl details then

9:28 Glenjamin: Hi everyone, i'm going to be running a cljs workshop at my local user group - I'm trying to decide between using Om and Reagent - anyone feel like weighing in with advice?

9:29 i'm planning to focus on building a declarative UI and keeping data & rendering neatly separated for figwheel-style reloading

9:29 verma: Glenjamin, what's the background of people? I did a presentation recently and decided to go with Reagent

9:30 CookedGryphon: unless the workshop is fairly advanced, I think om can be a bit confusing

9:30 verma: for my group, the background was javascropt

9:30 so Om would have been too much

9:30 Glenjamin: it's the FP group, i don't think anyone else knows clojure, but most know JS

9:30 CookedGryphon: and reagent shows off nice clojurey data structures/transformations

9:30 verma: yes, agree with CookedGryphon

9:43 CookedGryphon: You know what would be awesome, if the repl in emacs could drop clojure data structures in an expandable tree structure like the JS console in chrome does with js objects

9:43 so often even pprint comes out hard to read and full of irrelevant data

9:44 Glenjamin: cheers for the input, will have a go with reagent

9:50 puredanger: you might also look at Quiescent https://github.com/levand/quiescent

9:50 at the very least the readme has pretty good comparisons of om, reagent, and itself

9:51 CookedGryphon: you can use the clojure inspector for that

9:51 http://clojure.github.io/clojure/clojure.inspector-api.html#clojure.inspector/inspect

9:51 pops up a swing window on a clojure data structure

9:52 ssboisen: anyone familiar with the new ref-cursors in om?

9:55 CookedGryphon: puredanger: don't really like the idea of popping up a separate window, much less a swing one! but it might help

9:55 tried it and it doesn't work for lists of maps or anything nested

9:55 puredanger: hmm, I thought it did but admittedly I don't use it much

9:58 CookedGryphon: but yeah, it would be much nicer if there was something inline in the emacs buffer

9:58 that just used a tree-widget or something

9:59 lgrapenthin: CookedGryphon: I would use it

9:59 mmeix: Very basic question: when is it advisable to use "for"-constructs instead of map/reduce/filter/...? Readability? Style? Or are there cases, where only "for" is possible? (Didn't find such a case so far, admittedly being a newbie)

10:00 stuartsierra: I almost never use `for`

10:00 lgrapenthin: CookedGryphon: Have you tried cider-inspect?

10:00 CookedGryphon: ooh, no

10:00 what does that do?

10:00 puredanger: mmeix: readability - for is occasionally clearer (but I rarely use it either)

10:01 lgrapenthin: CookedGryphon: pretty much what you describe

10:01 mmeix: but there are not cases, where for is the only possible solution, right?

10:01 lgrapenthin: CookedGryphon: C-c M-i if you are on cideer 0.7.0+

10:01 mmeix: no' cases

10:01 CookedGryphon: mmeix: for is great for more complex list comprehensions, say (for [x (range 4), y (range 4), z (range 4) :when (not= x y z)] ...)

10:02 puredanger: CookedGryphon: yes, exactly - when there are multiple dimensions (x, y, z), I think it's useful

10:02 CookedGryphon: will evaluate the body for all combinations of x y and z where they aren't all equal in a list

10:02 mmeix: ah, I see ... in this case it's easier to reason about

10:03 and speed is no big difference, I guess

10:04 thanks!

10:05 CookedGryphon: it's also good that you can reuse bindings/destructure without quite so much fn boilerplate floating around

10:06 (for [[a b] map-of-things-that-map-to vectors, item b] ...)

10:07 didn't mean reuse bindings, I just meant use bindings as things to enumerate as part of the same for loop

10:08 mavbozo: #<CompilerException java.lang.OutOfMemoryError: PermGen space,

10:08 what does that mean? should I increase jvm max heap limit?

10:10 mmeix: CookedGryphon thanks: this makes sense for me ...

10:23 ssboisen: anyone familiar with the new ref-cursors in om?

10:37 CookedGryphon: that inspector is better, but still not what I wanted lgrapenthin

10:38 I want a tree expander, not to navigate down the tree

10:38 I might want to compare two items in a vector by some value nested in their maps

10:38 with a lot of extraneous information all around

10:50 the_danko: greetings friends! i think today will be a beautiful one.

10:51 anyone doing anything cool this weekend?

10:52 stuartsierra: mavbozo: The PermGen is where the JDK stores compiled code.

10:52 joobus: the_danko: trying to take over the world!

10:52 stuartsierra: mavbozo: It's separate from the regular heap.

10:53 the_danko: joobus: that's awesome! via software, drugs, charm, or what? do you expect us to know you have taken us over or will it be more subtle?

10:53 stuartsierra: mavbozo: There are command-line options to increase the size of the PermGen space; search.

10:53 joobus: the_danko: why are you pressing me for all these details?!

10:54 the_danko: I'm more of a high level guy

10:54 the_danko: joobus: haha i get that

10:55 i am feeling the joy of clojure

10:55 joobus: i'm here today to absorb some clojure brilliance because I'm still a relative noob

10:56 the_danko: the book joy of c?

10:56 the_danko: nice, me too! ok i lied. i haven't felt the joy fully yet but i know it is coming

10:56 yeah rocking the book and lispcast now

10:57 lithuania? don't they have beautiful women there?

10:57 joobus: i injured myself at the end of July, and for about 2 months had a cast and such on, and all I did during that time was program clojure, read clojure, watch rich hickey videos on youtube, etc.

10:58 now I'm in this limbo between OO programming at work, and thinking in clojure/immutable data types most of the time

10:58 the_danko: very interesting. you prefer the clojure style?

10:58 joobus: yes

10:58 CookedGryphon: I hate that, wondering why your java's complaining then realising you don't have a return statement

10:59 joobus: the complaint with OO-programming hiding state all the time resonated with me

10:59 basically, every OO program is a fairly implementation dependent thing. All the code at work does this and it's a mess.

10:59 the_danko: i was a trader until last week. wrote in java. now i am taking some time off to learn how i can help build the future.

11:00 joobus: not sure if clojure would fix that but that is where my mind has wandered

11:00 the_danko: yeah we ended up talking as much about software as we did about trading

11:00 joobus: trader as in stock/futures trader?

11:00 the_danko: well about java in particular

11:00 high frequency trading

11:00 so yeah

11:01 joobus: i was a trader for 6 years. had the series 7,55,63, but then the Fed started printing money and I wanted no part of the whole thing. no i program.

11:01 the_danko: nice

11:01 joobus: *now i program

11:04 the_danko: do you use cursive by chance?

11:04 joobus: no

11:04 i'm a vimmer

11:04 the_danko: got it

11:06 do any of y'all do mixed-source java and clojure projects in cursive/intellij?

11:07 joobus: i got lein droid to build the default project the other day; i thought that was cool. did some hot reloading via the repl to the android device, sweet. Now I'm wondering how/if it is possible to combine a clojure/clojurescript/android project as one project. I want the Web facing stuff to also be the UI for the android app, and written in cljs. Right now I'm just thinking on it for a while.

11:08 the_danko: interesting stuff, looking forward to hearing how it goes

11:09 Atlanis: you could use cljx to build it. Unfortunately, I don't have much more info than that

11:09 https://github.com/lynaghk/cljx

11:14 the_danko: how's your arm doing now joobus?

11:14 joobus: i screwed up my finger pretty good. now I get to live with it.

11:14 the_danko: joobus: that is rough.

11:18 joobus: anyone used bitcoij in clojure? just curious...

11:18 *bitcoinj

11:21 jonathanj: can i reload my project from `lein repl` without restarting the repl?

11:22 it's kind of time consuming to keep restarting the repl (and maybe losing some state) after each code change

11:22 arohner: jonathanj: https://github.com/pallet/alembic

11:23 doesn't work perfectly, but better than nothing

11:23 EvanR: jonathanj: did you try (:require 'myproject.core :reload-all) in the repl

11:24 jonathanj: no, i did not

11:24 the_danko: jonathanj: i use cursive. awesome video here. http://vimeo.com/103812557

11:25 jonathanj: well, that is part 2. probably want to watch part 1 first. you can reload easily using the repl tehre. i am a n00b though so if any others have better advice i would go for it.

11:26 arohner: ah, sorry, I assumed 'project' == 'project.clj'

11:26 yeah, if you want to reload your own source code, use your IDE

11:26 nrepl/cursive/vim fireplace, whatever

11:26 any decent clojure plugin will support it

11:26 EvanR: i had a hard time reloading a project in cursive intellij

11:27 justin_smith: arohner: I still do (require 'some.ns :reload) like a caveman

11:27 EvanR: i only do that if im testing the whole program

11:27 testing pure pieces in isolation is easier

11:28 jonathanj: is anyone here familiar with instaparse?

11:28 arohner: justin_smith: ouch :-(

11:28 jonathanj: i have a rule like: foo = letter { letter }

11:28 arohner: jonathanj: I used it for the first time yesterday so that must make me an expert

11:28 jonathanj: which produces output like [:foo 'F' 'O' 'O']

11:29 sorry, "F" "O" "O"

11:29 i would rather have [:foo "FOO"]

11:30 is there a way to get that by only modifying the grammar?

11:30 arohner: I had that same issue, didn't figure it out

11:30 I know that if you use regex literals, that goes away, but the parsing rules are different because regex are greedy, while 'normal' instaparse isn't

11:34 jonathanj: looks like the answer is to do something like insta/transform {:foo str} (parser-thing ...)

11:35 arohner: what about specifying an exact number of matches?

11:35 arohner: foo = bar bar bar

11:46 the_danko: ok so the joy of clojure says i need to put in (:require clojure.set) at the top of my file to use clojure.set

11:46 or at least that's what i thikn it says

11:46 however this works fine

11:46 (ns cljlearn.core)

11:46 (println (clojure.set/intersection #{1 2 3} #{ 1 2 6}))

11:47 Bronsa: the_danko: that's because clojure.repl or some other namespace that your repl loads requires clojure.set

11:47 the_danko: any idea why the :require doesn't seem to be necessary?

11:47 ahh

11:47 Bronsa: the_danko: don't count on that though, you should always require the namespaces you need

11:47 the_danko: Bronsa: awesome, thanks!

11:48 Bronsa: the_danko: also it's pretty rare to use (:require some.ns) alone

11:48 the_danko: you usually do (:require [some.ns :as alias]) or (:require [some.ns :refer [var]]) or even a combination of both

11:48 mearnsh: the_danko: https://github.com/technomancy/leiningen/blob/master/src/leiningen/repl.clj#L3

11:49 the_danko: ahh sweet!

11:51 Bronsa: thanks, reading up on the second form in the joy of right now. think i got it! it's awesome being able to hear the best practices, general usage patterns, etc. much appreciated.

11:53 Bronsa: the_danko: np

12:04 mtgrubb: hello all. I’m looking for some advice. I’m wanting to create a function that when passed a URI can return a record based on the scheme of the URI. These record “types” are an open set, so I can’t just build a static lookup table. I’d also like for the user of this library to only have to include the providers of these records in the dependencies list, but not have to explicitly require each one. So basically I want my function to be abl

12:04 search through the classpath for suitable providers, something similar to how Leiningen templates work. I looked through the leiningen code but couldn’t really see what I was looking for. Any advice?

12:08 Glenjamin: i think leiningen templates work on the premise of standard naming

12:14 cminus: mtgrubb: you could require a namespace based off of the scheme and come naming convention and then look up a well-known fn in that namespace and call it.

12:15 mtgrubb: cminus: thanks, I think i’ll try that.

12:17 puredanger: mtgrubb: there are also mechanisms in Java to declare new url connection providers based on scheme. it's probably way more than you want to deal with, but that is actually an open system built into Java. It does not handle the classloading/require aspects though.

12:18 there is also the ServiceLoader mechanism which requires declaring new service impls for an interface in the jar manifest. the jvm then helps you be able to answer a question like "what are all the registered implementations of this interface?" which otherwise is not answerable in Java without class path scanning

12:18 utilities exist for class path scanning as well of course

12:20 mtgrubb: puredanger: are you talking about pomegranate or aether?

12:20 puredanger: no

12:22 noncom: does anyone use overtone here ?

12:38 justin_smith: noncom: if this is regarding the sequencing thing, I think the idea of at-at was that it was for sequencing musical events in overtone originally

12:45 stompyj: what do people use overtone for?

12:45 what camp is it in?

12:45 tracker / reaktor / csound / max|msp ?

12:45 justin_smith: stompyj: it is a frontend for supercollider

12:46 supercollider is like max|msp but without the GUI

12:46 and instead, a UDP based messaging protocol for constructing the patches

12:46 stompyj: aha, so yeah, csound/kyma/max|msp

12:46 awesome

12:46 I gotta check that out sometime

12:46 justin_smith: stompyj: I have high hopes for pink

12:47 stompyj: what is that?

12:47 justin_smith: it is by steven yi, one of the core csound devs

12:47 and it is a synth engine in pure clojure

12:47 whereas overtone ships a separate c++ program that does all the synthesis

12:47 stompyj: whoa

12:47 very cool

12:47 justin_smith: it's very young still

12:47 but promising

12:48 stompyj: I used to be knee deep in that stuff in early 2000s, but I had to go hard analog with my music to ensure I wasn’t in front of a computer 24/7

12:48 haha

12:49 mtgrubb: puredanger: so it looks like I can use clojure.tools.namespace.find and clojure.java.classpath to search for namespace prefixes then load the namespaces that are named appropriately and call an init function.

12:49 justin_smith: stompyj: it's funny how the definition of "analog" has changed since ~1989 or so - I remember when it meant you had no DSP in your equipment

12:50 stompyj: well no dsp, and no microcontroller based sequencing / switching either

12:51 stompyj: now I often see it mean "not a laptop"

12:52 stompyj: justin_smith: hahaha, yeah, exactly

12:52 and good point

12:52 for me, I just mean, all my MIDI input is driven via keyboard, maschine, and then live inputs via bass/drums

12:52 justin_smith: I mean today it's hard to find electronic music equipment without digital logic, for the bypass functionality if nothing else

12:53 stompyj: and of course we both know that the keyboard is digital, and the maschine is a computer

12:56 donbonifacio: how could I use core.async to handle requests? for example, I'm at the request handler, and I need to fetch something from the DB, and after that provide some result. Is it a good match for this scenario?

12:58 justin_smith: donbonifacio: what is the functionality you would get from using core.async in your request handling?

12:58 noonian: donbonifacio: it's hard to use core async for that if you are using ring since it expects the response as the result of your handler function

12:59 donbonifacio: I was thinking about doing 2 parallel requests

12:59 justin_smith: noonian: you could be using websockets, and use core.async to put the result on that socket

12:59 noonian: justin_smith: yeah, that works fine

12:59 justin_smith: donbonifacio: as in from the same client?

13:00 donbonifacio: justin_smith: two independent webservices that I must call, for example

13:00 something like call them both in parallel and wait on them

13:00 don't know if core.async is good on this scenario, but I was trying to use it somewhere :)

13:01 justin_smith: noonian: another example - I have used core.async to manage the on-demand resizing of image assets (if I don't have a given resize cached already), where I pass a filename on the channel, put the same filename into the template, and then when the client asks for that file, that finds the result of the async (or waits until it is done as needed)

13:01 noonian: justin_smith: nice

13:01 justin_smith: noonian: since I shouldn't need to wait for the file to resize before sending the html

13:08 donbonifacio: yeah, if in order to handle a request, you need to pull in multiple remote resources, you can use core.async to ofload the requests so they can be done parallel

13:08 donbonifacio: but the IO should not be in go blocks

13:08 donbonifacio: which complicates things

13:08 bbloom: :-( "fns taking primitives support only 4 or fewer args"

13:09 my signature matches that of System.arraycopy

13:09 donbonifacio: kay justin_smith, I'll think on this a litter more. btw, just completed my first rest service and you helped me several times. thanks :)

13:09 puredanger: bbloom: that is one of my least favorite errors

13:09 bbloom: puredanger: you run in to it often?

13:10 puredanger: I did when working on the alioth programs :)

13:10 justin_smith: bbloom: I think it's because of the same problem you see with java library classes, where each use of primitive args must be defined separately (ie. a nearly identical method signature but taking an int or long)

13:10 donbonifacio: np

13:10 bbloom: puredanger: i'm not sure how to handle it, this is a perf sensitive function

13:11 puredanger: bbloom: it's one of my least favorite because there just isn't always a good way to handle it

13:11 bbloom: puredanger: although i have been considering iterator/range style objects for these types... seems like a major refactoring i don't want to deal w/ at this point in time

13:12 puredanger: bbloom: one option is to fold the function into the caller or use a macro to get that effect

13:12 or you can fold multiple prims together into an array

13:13 bbloom: yeah, was just considering the macro approach, but it's kinda ugly

13:13 puredanger: oh these are all worse than what you want to do, no question

13:14 bbloom: puredanger: i'm wondering how bad it would be if i just remove the type hints

13:14 i'm gonna do that to unblock myself for now

13:14 puredanger: you only need to remove one :)

13:14 I'd recommend casting it back into a long or whatever when you get into the fn

13:15 bbloom: puredanger: no, you need to remove one *argument*

13:15 not one hint

13:17 puredanger: oh right

13:20 bbloom: this is all limited by the number of generated interfaces at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IFn.java#L97 - 4 seemed like a good place to stop the explosion I guess

13:20 Bronsa: puredanger: I've often been wondering if generating prim interfaces on the fly would be problematic

13:20 bbloom: puredanger: yeah, i understand the motivation. this is the first time i hit this problem

13:25 it's weird b/c writing slow clojure and then making it fast has been very pleasant compared to writing java

13:25 but eaking out that last bit of perf has been challenging

13:25 it's forcing me to do more rewriting of code than i normal, but that's probably a good thing

13:26 seangrove: bbloom: You need a better JIT/Compiler/Language/Type|Effect System/datastore

13:27 I'd work on those first, and then build the thing you're working on

13:27 bbloom: seangrove: shhh, i can only solve all the problems in the world one at at ime

13:33 stompyj: justin_smith: haha, exactly re: keyboard / computer

13:33 andyf: To anyone at Cognitect: I've seen mentions of not being able to use Leiningen for most projects you work on. Out of curiosity, what do you use to fire up a repl with desired class path?

13:33 stompyj: when they exposed core cells in reaktor, I lost a year of my life

13:33 puredanger: I don't know about "not being able" - we certainly use leiningen all of the place

13:34 stuartsierra: We always start with Leiningen. Lots of projects have spawned their own one-off tools.

13:34 puredanger: there are some other projects that use shell scripts in tandem with maven to do stuff (basically using maven just for dep mgmt)

13:35 bbloom: andyf: i generally do use lein for that purpose, but I often miss the old big-co svn style of reproducible dependencies: ....

13:35 that is dump all your jars in a single directory manually

13:35 set the classpath to that

13:35 adereth`: donbonifacio: Have you seen Spiral? https://github.com/dgrnbrg/spiral

13:36 bbloom: i really wish union mount file systems caught on

13:36 puredanger: from working on Clojure itself, I actually end up using the ant version of the build there more than the Maven one. I have a branch where I have replaced the Ant stuff with just Maven though for Clojure. maybe some day I'll finish that off.

13:36 bbloom: rather than `lein deps :tree`, i really just want to type `ls lib`

13:37 technomancy: downstream packagers will really not like it if you introduce a circular dependency for packaging clojure/lein =)

13:37 andyf: I may have misinterpreted a statement of mr halloway's that led me to believe Leiningen was not usable for well over half of his projects. Can't find it quickly

13:38 technomancy: adereth`: hey, did you see this? https://github.com/technomancy/atreus/blob/master/atreus.rkt

13:38 stuartsierra: andyf: At the time, I think Stu Halloway's only project was Datomic. :)

13:38 tuft: is it common to use exceptions for error handling or something more like monads in clojure? i've been trying to use things like some-> but it's getting awkward

13:38 andrewhr: puredanger: +1 for maven only, just for the sake of having only one task/dep on single project

13:39 adereth`: technomancy: No! Nice! Reading now...

13:39 andrewhr: but is only my OCD talking louder :P

13:39 technomancy: tuft: option types aren't really tenable without built-in pattern matching, unfortunately

13:39 andyf: So if you have a Maven only project, is there an easy way to fire up a repl with correct class path, without needing an extra script?

13:39 puredanger: yeah

13:40 mvn clojure:repl or something like that

13:40 (I don't do this often)

13:40 tuft: technomancy: hmm indeed

13:40 technomancy: adereth`: output: http://p.hagelb.org/atreus-brd.svg

13:40 adereth`: well, the tracing is still done by hand

13:40 justin_smith: stompyj: I should make a wooden box with a set of knobs that are just sections of an oak branch (bark still on) that is just big enough to totally cover a laptop, the knobs all sending parameters via USB - a digital to analog interface converter

13:40 bbloom: can't you also just do `CLASSPATH=$(mvn classpath) java -jar $CLOJURE_HOME/clojure.jar

13:40 or something like that

13:40 technomancy: I mean the copper traces

13:41 stompyj: you’d sell out here in BK in minutes

13:41 organic redwood

13:41 technomancy: andrewhr: my first bug report to clojure was "hey, the instructions in the readme for mvn don't work; only ant works" =)

13:41 (november 2008)

13:42 puredanger: inside the clojure proejct itself, I usually just do "java -cp target/classes clojure.main"

13:43 justin_smith: stompyj: the trick is you need software to go with it that is as simple as a dedicated device is - ie. one button that totally resets state to a known place, no weird corners in state / UI that would require more than a few lamps and the positions of some knobs to understand

13:43 stompyj: yeah

13:44 justin_smith: stompyj: I have thought about making my beaglebone usable on stage, and the trick is making something simple enough, as simple as one of my stompboxes

13:44 stompyj: justin_smith: I used to know some guys from Berklee who were experimenting with those kinds of ideas

13:45 andrewhr: technomancy: nice. maybe maintaining one build system woulbe be a good thing™

13:45 justin_smith: stompyj: also, I have some plans to work with an open dsp box design, using some arm cortex chips, audio IO, and a couple knobs, plus arduino style connectors - a friend of mine has the boards made and the CPUs in place we just need to place the grosser externals

13:46 stompyj: the same chip as a modern smart phone, but bare metal, and a bus interface that we can supposedly attach desktop ram to(!)

13:46 * justin_smith is going to make a week long delay line

13:47 stompyj: haha, very cool

13:49 justin_smith: stompyj: it will be a big shift in brain gears to program for bare metal...

13:50 but it is exciting, he has a botique audio components business so this could lead to some actual products...

13:56 ohpauleez: andyf: I also use CMMA - https://github.com/ohpauleez/cmma

13:56 A Makefile that can sit on top of any deps tooling. It starts my REPL, launches CLJ targets, etc

13:58 noonian: spiral looks pretty sweet

13:59 andyf: bbloom: Closest I've found to that so far is 'mvn dependency:build-class path' but it's output includes too much to be usable in that way

14:00 ohpauleez: noonian: Please see the mailing list about the claims made in spiral: https://groups.google.com/d/msg/clojure/rKqT13Ofy4k/H9xvkZA9Yy4J

14:00 bbloom: andyf: sounds like maven :-/

14:01 stompyj: justin_smith: yeah, I think there is a ton of open space there. I think 2013 was the first year where people spent more money on music gear, then purchased music

14:02 andyf: puredanger: Yep 'mvn clojure:repl' does fire up a repl, and prep ending that cmd with rlwrap works as expected, except Ctrl-D does not exit, only ctrl-c

14:03 noonian: ohpauleez: thanks for the link

14:03 bbloom: puredanger: i forgot a bit of feedback on the survey: i want concrete inheritance. not b/c i like concrete inheritance, but b/c some poorly designed java APIs require it, and it's annoying to have to write java wrappers for that purpose

14:03 andyf: My goal in asking is to figure out how to make Eastwood easier to use from non-Leiningen repls

14:04 And Leiningen repls, too. Should not be difficult to do - I just need to know what to expect from the environment, which may be almost nothing

14:04 puredanger: bbloom: concrete inheritance is not something that will ever exist as a generic tool BUT Rich is considering something specifically for this use case w/Java

14:04 bbloom: puredanger: i know that ra and timsg ran in to the same problem w/ clojure-unity

14:05 puredanger: basically all unity stuff must subclass Component, so they just hacked clojure-clr's deftype

14:06 puredanger: there is a ticket for this. can't find it atm

14:06 borkdude: current status: watching cognitect webinar

14:06 technomancy: andyf: my recollection is that a while back relevance had a policy that mvn must be used "officially" for libs (back when lein couldn't deploy to central) but that people didn't use it during development much

14:07 but that was a long time ago and a fuzzy recollection

14:08 puredanger: we only use mvn for the contrib libs b/c that's all hooked into how the maven central deployment stuff works

14:08 most of the contrib projects also have lein projects and a lot of devs use lein as well

14:09 but only the maven pom is used in build/deploy

14:10 at the time all that was built (before I was involved) I don't think lein had enough support to handle everything that needed to be done. I suspect that would be a much smaller gap now.

14:10 technomancy: this was around the time of lein 1.5 iirc

14:10 puredanger: but it's hard to prioritize time to overhaul a ton of projects with working infrastructure now

14:11 technomancy: do you know off the top of your head of any obstacles to doing maven central signed deployment with lein?

14:12 technomancy: puredanger: I think the main obstacle is that cemerick is the only one who has done it, and he's never on IRC =)

14:12 puredanger: I've done it with Maven, but not ever tried with lein

14:12 technomancy: let me see if I can find the email about it

14:13 oh, he made a PR for it. what a champ!

14:13 https://github.com/technomancy/leiningen/blob/master/doc/DEPLOY.md#deploying-to-maven-central

14:13 mdeboard: lol

14:13 He's batman, basically.

14:14 puredanger: oh yeah, that's great

14:15 so that doesn't actually do the close and release/promote in nexus, would need that too. that's easier than it used to be to automate though.

14:15 andyf: technomancy: I happened across the discussion after this article including instructions by you on making things more easily available in repl - I will look into that: http://stuartsierra.com/2013/11/04/command-line-intransigence

14:17 puredanger: I have achieved about "85% Stuart" abilities in understanding and maintaining the contrib library infrastructure. thankfully he's still there to ask the other 15% of the time. it's no picnic.

14:18 stuartsierra: puredanger: :)

14:18 puredanger: (inc stuartsierra)

14:18 lazybot: ⇒ 12

14:18 puredanger: wat!?

14:18 stuartsierra: "85% Stuart, 99% rant-free"

14:18 puredanger: I rant in private :)

14:18 stuartsierra: puredanger: See, that's why people inc you.

14:19 (inc puredanger)

14:19 lazybot: ⇒ 18

14:21 bridgethillyer: those are both way too low. Was there a global reset recently?

14:21 puredanger: ok, I'm gonna go to lunch. no one break anything while I'm gone.

14:21 justin_smith: bridgethillyer: they answer the hard questions, which are fewer in number - you get more incs helping the newcomers, and anyone can do that

14:22 bridgethillyer: ahh

14:22 TimMc: or just spend way too much time on IRC

14:22 $karma TimMc

14:22 lazybot: TimMc has karma 73.

14:22 justin_smith: TimMc: that too

14:23 TimMc: and invent terrible things that people inc you for because the alternative is facing up to the thin barrier between production code and madness

14:23 bridgethillyer: ^

14:24 puredanger: I would say not just anyone can help newcomers and I hugely appreciate the people that do that here relentlessly

14:24 joshuafcole: TimMC: Where do you work? I'd love to have a thin barrier.

14:24 TimMc: joshuafcole: Brightcove

14:24 Anniepoo: .

14:24 puredanger: and with great humor and grace

14:25 bridgethillyer: hear hear

14:25 joshuafcole: :) Our shop has a live video broadcasting with serious social interaction system built on top of Drupal…. Drupal 6.

14:25 * TimMc waves to Anniepoo

14:25 joshuafcole: That we're slowly transitioning onto NodeJS / MongoDB from

14:25 I have stared into the abyss

14:25 TimMc: haha

14:26 To be clear, I haven't actually used swearjure at work. I do try to keep it separate.

14:26 joshuafcole: hah

14:26 justin_smith: joshuafcole: migrating to mongo?

14:27 joshuafcole: I'm not high enough up to make those architectural decisions, justin_smith

14:27 I just try to make the best of a bad situation

14:27 quile: joshuafcole: are you at least able to use clojurescript on node?

14:27 justin_smith: joshuafcole: not criticizing - the grammer was unclear to me

14:27 joshuafcole: :)

14:27 bbloom: justin_smith: i am criticizing: never migrate to mongo

14:27 lol

14:27 joshuafcole: quile: If only. At home I get to enjoy it though

14:27 justin_smith: "transitioning onto nod / mongo from"

14:28 mbac: what's the thing i want to do for fast 2d graphics

14:28 in clojure

14:28 joshuafcole: mbac: Not sure what level you're looking to draw at, but I've had decent success splatting into byte buffers and loading those into LibGDX pixmaps

14:29 mbac: i want to plot pixels mostly

14:29 joshuafcole: I'm procedurally generating my graphics though

14:29 stuartsierra: I've asked before, trying again: does anyone have a reference for the phrase "Getting SLIMEd" earlier than technomancy in 2010?

14:29 joshuafcole: That may be a good route for you then, though you'd need to make your own drawing routines or look for a lib to do it

14:29 mbac: i'm doing some kind of realtime sound visualization

14:29 k

14:29 sure

14:29 technomancy: stuartsierra: I got it from a co-worker, but I can't remember which one. maybe pjstadig or hiredman.

14:32 stuartsierra: technomancy: Thanks. Do you know if it existed in the Common Lisp world before then?

14:32 (this is for a talk)

14:32 technomancy: stuartsierra: hm; I don't think so

14:34 stuartsierra: OK, thanks.

14:35 justin_smith: mbac: I think the main thing is not going to be the overhead of putting the pixels on screen as much as the overhead of calculating the values. Things like cache-line friendly layout will make a really big difference if things need to be realtime.

14:54 TimMc: joshuafcole: Do you do your own video processing?

14:54 joshuafcole: TimMC: We do all our production and touching up in house, but I'm not actually familiar with the specifics

14:55 TimMc: *nod*

14:55 joshuafcole: creativelive.com

14:55 TimMc: I'm mildly curious if your company is a customer of my company. :-P

14:55 joshuafcole: After a year of labor you can hardly smell the drupal anymore!

14:55 TimMc: ha!

14:56 joshuafcole: I was actually curious about that too, but I don't think so (or at least, not directly). We manage our broadcasts via Ustream currently. We've wanted to move off them for more than a year, but we've had more… pressing concerns

14:56 stompyj: (inc joshuafcole)

14:56 lazybot: ⇒ 1

14:58 TimMc: I'm sure Ustream has built their own stack.

14:59 joshuafcole: Yeah, their reliability has been pretty awful though

14:59 and there's not much we can do but twiddle our thumbs and buffer when the streams go down

14:59 which isn't very good for what's supposed to be a live and interactive online experience

15:00 TimMc: Live is pretty hard.

15:00 joshuafcole: Yeah, in fairness, their awful is still 100x better than I could provide at half the scale. :)

15:01 gfredericks: does anybody know if java.jdbc lets me express "UPDATE foo SET bar = bar +1" without the general do-commands fallback?

15:06 justin_smith: gfredericks: I looked and did not find it

15:07 gfredericks: looks like do-commands returns what I want for an UPDATE anyhow, so that's not terrible

15:07 justin_smith: thanks

15:08 justin_smith: gfredericks: had to do something similar in a webapp, settled for do-commands

15:13 bbloom: hyPiRion: do you lean "decreasing" the constant factors? :-)

15:14 hyPiRion: bbloom: ?

15:14 bbloom: http://hypirion.com/musings/understanding-persistent-vector-pt-3 first paragraph

15:14 hyPiRion: Oh, hahah

15:14 clojurebot: Cool story bro.

15:15 bbloom: hyPiRion: great pictures, btw

15:15 hyPiRion: That sentence is technically correct though. Perhaps a bit ill-advised.

15:16 (inc bbloom) ; thanks

15:16 lazybot: ⇒ 47

15:16 bbloom: hyPiRion: (Thread/sleep 123)

15:16 constant factors: increased!

15:17 hyPiRion: Oh, it's on hacker news

15:17 joobus: (dec joobus)

15:17 lazybot: You can't adjust your own karma.

15:17 joobus: lulz

15:19 bbloom: the top comment being pedantic about "effectively" constant time is hilarious too

15:19 which reminds me of one of my favorite alan perlis quotes:

15:19 "for every polynomial-time algorithm you have, there is an exponential algorithm that I would rather run"

15:20 the comment that it's a "scam" that we claim "effectively" O(1) for our structures is funny. big-O is already a massive approximation

15:21 it's not really useful in practice other than to communicate "this is how much you should care about the magnitude of N"

15:21 answer for vectors: not at all

15:24 hyPiRion: ArrayList.add is O(n) and not O(log n). conj on a vector is O(log n).

15:24 tbaldridge: "we have constant time lookup on this array!"

15:25 hyPiRion: then again they both are O(n!). So much for that valuable property.

15:25 tbaldridge: "Not with a CPU cache that small you dont..."

15:25 bbloom: tbaldridge: ha, yeah, that's the other hilarious part

15:25 everything is basically always log(N), thanks to hierarchical caches

15:26 tbaldridge: btw, checked out pixie a bit ago. seems neat!

15:26 tbaldridge: bbloom: thanks, I'm pretty happy with it so far.

15:27 bbloom: tbaldridge: how close do you plan to stick to clojure?

15:28 tbaldridge: while working on eclj i realized that i wanted to veer further away than would really make sense to still call "clojure"

15:28 but you just tossed the clojure name from the get-go :-)

15:29 oh, i see your note about that in the readme now

15:29 nevermind!

15:30 athinggoingon: hi, I'm trying to install cider from melpa and am getting "failed to verify signiture queue". Is there another way to install an older version of cider from the pckage manager?

15:31 technomancy: athinggoingon: marmalade has a stable version

15:31 justin_smith: athinggoingon: queue is in melpa, but yeah, using stable is a good idea

15:31 technomancy: bonus points: it uses TLS so you're not installing

15:31 justin_smith: err... well queue is in one of the gnu emacs package sources

15:31 technomancy: *installing MITM-able packages

15:32 justin_smith: TLS: bonuses including not

15:32 TimMc: technomancy: You're no fun!

15:32 * TimMc hides his café wifi packet injection box

15:32 justin_smith: TimMc: oh, I thought that was a companion animal

15:41 bbloom: i'm curious: why bother with this if-check? https://github.com/clojure/clojure/blob/38d7572e4254afdd7f02b78095ccdb27065754d2/src/jvm/clojure/lang/ATransientSet.java#L28

15:42 does it serve a purpose really?

15:42 whodidthis_: how do i choose a thingie in undotree

15:43 hfaafb: click the thingie

15:44 whodidthis_: no mouse :(

15:44 capisce: bbloom: seems superfluous

15:44 whodidthis_: whats like a select type of command

15:44 bbloom: capisce: yeah, but it's such a small/clear function, it seems unlikely to be an oversight, but you never know w/ the clojure codebase

15:44 justin_smith: whodidthis_: usually hitting return in that kind of UI in emacs

15:44 bbloom: w/ rich, you might get "who cares" or "no, that seemingly simple thing is very very important"

15:45 tbaldridge: bbloom: transients sometimes create new collections, sometimes not.

15:45 whodidthis_: it says buffer is read only, maybe i did some bad command

15:45 amalloy: bbloom: assignments might bust some caches or inlining or something? which could make it worth the cost of checking, to avoid unnecessary setting

15:45 tbaldridge: bbloom: don't store the field if you don't have to.

15:45 bbloom: amalloy: tbaldridge: yeah that's what i was wondering...

15:46 both conj and disjoin both do it

15:46 amalloy: tbaldridge: i mean, the "obvious" way to do it is just "impl = impl.assoc(val, val)"

15:46 bbloom: but i wonder if rich benchmarked it or whatever

15:46 whodidthis_: http://www.emacswiki.org/emacs/UndoTree it looks really useful and i can move around but how do i select a point

15:47 bbloom: i mean, field writes always risk a write barrier or whatever in the GC, but this is a transient, presumably it lives in the nursery most of the time

15:47 whodidthis_: wait, or am i supposed to choose one, am i being stopid again

15:47 bbloom: i couldn't imagine that if check helping much

15:47 justin_smith: http://www.dr-qubit.org/undo-tree/undo-tree.el see the comments here at the top of the file

15:48 whodidthis_: oh dear, sorry about that just realized how it works

15:48 tbaldridge: bbloom: benchmark it and see ;-)

15:48 bbloom: tbaldridge: i have so much lower hanging benchmarking fruit ;-)

15:49 tbaldridge: seems like it would be slightly faster, I'm just surprised someone bothered.

15:49 bbloom: tbaldridge: i mean, faster is kinda the point of transients

15:49 but then there's the safety check for editability all the time

15:49 so *shrug*

15:49 tbaldridge: bbloom: well it seems cgrand wrote it back in 2009, so perhaps ask him ?

15:50 bbloom: oh heh

15:50 athinggoingon: justin_smith: thanks for your response. Since queue is in melpa, and I have added melpa to my list of package archives, shouldn't installing cider automatically install queue?

15:52 justin_smith: athinggoingon: sorry, not melpa, elpa - is elpa also one of your package sources?

15:53 elpa is the "official" one (melpa is for contrib stuff)

15:53 http://www.emacswiki.org/emacs/ELPA

15:53 mikefikes: I was curious: Is there a general sense of roughly how far off ClojureScript is from being deemed 1.0?

15:55 bbloom: mikefikes: ignore the version number, it's widely used in produciton & is very reliable

15:55 mikefikes: Yes. I'm using it in production.

15:56 More of a curiosity. Roadmap type stuff...

15:56 athinggoingon: justin_smith: is this it? (add-to-list 'package-archives

15:56 '("org" . "http://orgmode.org/elpa/&quot;))


15:56 mikefikes: Wondering if there are new features, or just bugfixes between now and 1.0

15:56 amalloy: mikefikes: i expect it will just depend on something whimsical. one day, rich will decide "sure, this seems like a 1.0"

15:56 justin_smith: athinggoingon: yeah, probably best to find where you are already settng up your package-archives and throw that one in there too

15:57 athinggoingon: also you can do M-: package-archives<return> to see the current value

15:58 technomancy: again with the non-tls package source. =(

15:58 justin_smith: technomancy: wait, what's the tls package source for queue.el?

15:59 melpa does not have it, it seems (which seems to be the source of this issue)

16:00 technomancy: justin_smith: I don't know. if there is none, the first thing to do would not be to install it insecurely but to report a bug.

16:01 M-x package-install-from-file with a manual download works

16:02 justin_smith: technomancy: cool, I did not know that was a thing

16:02 technomancy: el-get also supports installing straight from https it

16:02 git

16:02 bbloom: technomancy: how come i need to type my secret key 3 times to deploy to clojars?

16:03 technomancy: bbloom: sounds like your agent isn't caching your passphrase

16:03 bbloom: how do i make it do that?

16:03 technomancy: on a mac? ... I don't know =( it just works on debian

16:04 but `lein help gpg` might tell you

16:05 bbloom: technomancy: i'm afraid to fuck with it, since it took so long to get working in the first place!

16:05 athinggoingon: justin_smith: I'm running into failed to download gnu archive

16:05 http://stackoverflow.com/questions/26108655/error-updating-emacs-packages-failed-to-download-gnu-archive

16:05 technomancy: we don't have a lot of OS X users on the core lein team unfortunately

16:06 bbloom: technomancy: i uncommented the "use-agent" line in my config, will hope that works next time

16:06 technomancy: that sounds promising

16:06 bbloom: technomancy: remember i told you that so when it inevitably explodes, you can help me fix it :-)

16:07 justin_smith: athinggoingon: you should try one of the other options technomancy suggested above

16:07 athinggoingon: though if you don't have gpg installed, installing that and trying again couldn't hurt

16:08 bbloom: anyway, debugging hilarious complicated macros is now awesome thanks to Fipp 0.5.1's new code-dispatch pretty printing :-)

16:08 (inc maxkreminski) ; for his awesome work there

16:08 lazybot: ⇒ 1

16:08 technomancy: bbloom: have you seen racket's stepping macro debugger?

16:08 bbloom: technomancy:

16:08 yes

16:09 sadly

16:09 wow enter key failure

16:09 technomancy: yes, sadly we don't have nearly enough machinery in clojure for that to be possible

16:09 technomancy: I'm half in awe of how sophisticated it is and half terrified of ever writing anything that would need it.

16:10 stuartsierra: bbloom: These articles helped me http://coredump.io/blog/2013/04/29/gpg-for-people-that-dont-like-gpg/ http://sudoers.org/2013/11/05/gpg-agent.html

16:11 bbloom: stuartsierra: than you

16:11 technomancy: i'm not convinced racket's macro-heavy approach is a good idea though

16:11 technomancy: in fact, thanks to their incredibly strong research work, i'm convinced that it's not a good idea

16:12 technomancy: they have worked out all the little details and basically proven that macros are a hack

16:12 stuartsierra: (rejoining the discussion) bbloom: a hack for what?

16:12 technomancy: my gut says if anyone can get macro-heavy code right, it's racket; the question remains whether it's a good idea to begin with

16:13 bbloom: stuartsierra: partial/abstract evaluation and syntactic abstraction

16:13 technomancy: (obviously trivial macros for which the expansion is obvious at a glance are a win no matter what)

16:13 stuartsierra: ah

16:14 bbloom: despite it's many flaws, mathematica's approach works much nicer than macros for both partial evaluation and syntactic abstraction

16:14 although it lacks severely in the abstract evaluation department, which is a bummer

16:17 amalloy: heh. i just saw recap spelled as "re-cap": sounds like it literally means putting your hat back on

16:17 (dec amalloy) ; off-topic

16:17 lazybot: You can't adjust your own karma.

16:22 bbloom: ztellman: hey, i think i found a riddley bug: https://github.com/ztellman/riddley/blob/b1471263409d9aac5837606dc92d33e93906971b/src/riddley/walk.clj#L172-L175

16:23 ztellman: i'm trying to rewrite a particular symbol, but that if check prevents (.method obj) from rewriting 'obj -- i don't think there's any harm in just unconditionally doing the then branch of that else....

16:32 whodidthis: but if i use emacs where should i bind tmux prefix, whats a god unused ctrl+? button

16:32 technomancy: whodidthis: ctrl-z is good

16:32 whodidthis: thanks

16:32 technomancy: if you have tmux, you never need to background emacs =)

16:33 whodidthis: oh right it was that button

16:33 amalloy: yeah, C-z is where i hear folks putting tmux/screen stuff

16:33 stuartsierra: whodidthis: I use ctrl-t "t for tmux"

16:34 gfredericks: but ctrl-t is for transposition!

16:34 amalloy: stuartsierra: i think C-z, C-i, and C-m are the only letters i don't use regularly

16:35 technomancy: amalloy: huh, can tmux tell apart C-i and tab?

16:35 stuartsierra: gfredericks: Yes, so you would never type C-t twice in a row.

16:35 technomancy: in some contexts they are represented the same way, so I wouldn't recommend that

16:36 justin_smith: stuartsierra: repeated control-t pushes a letter forward in a word

16:36 mgaare: I bind tmux prefix to `

16:36 stuartsierra: justin_smith: huh, true. I never thought of using it that way

16:37 amalloy: technomancy: i dunno

16:38 gfredericks: stuartsierra: in any case, are you saying it only works for you as a tmux key when you press it twice?

16:38 amalloy: gfredericks: no, the other way around

16:38 the tmux key passes itself through to the application if you press it twice

16:38 whodidthis: yeah i was wondering why beginning of line was 2x ctrl-a

16:38 gfredericks: ooh, the point being that having to double up your usage isn't a burden

16:38 in contrast to C-b

16:39 technomancy: C-a and C-b are just abysmally bad defaults

16:39 amalloy: for what is C-b the default?

16:39 gfredericks: tmub

16:39 tmux

16:39 amalloy: those are indeed quite bad

16:39 i gotta learn tmux one of these days

16:39 technomancy: they're like ... "maybe when the machines burn civilisation to the ground, they'll actually be justified" bad

16:39 amalloy: i put a little effort into screen once, but it never really took hold over me. i'm one of those barbarians who just uses N OS shell windows

16:40 stuartsierra: gfredericks: I mean I don't have a reason to type C-t C-t in Emacs, so I can use C-t C-t as 'transpose' and one C-t for tmux.

16:40 mearnsh: tmux is pretty user friendly

16:40 whodidthis: mosh + tmux is great

16:40 * tuft just discovered mosh yesterday.

16:40 amalloy: mearnsh: what need has an emacs user for user-friendly software?

16:40 stuartsierra: I think ever Cognitect employee has a different preferred tmux prefix. ;)

16:41 *every

16:41 mearnsh: amalloy: haha. well it's sufficiently powerful too

16:45 gfredericks: amalloy: I use tmux less for the multiplexing and more for the remote persistence

16:45 95% of the work I do is in an emacs running on a server

16:46 sritchie: bmabey: hey man, saw your airbrake library -

16:46 TimMc: whodidthis: It doesn't do port forwarding and I've basically never wanted SSH access to a server without forwarding.

16:46 sritchie: bmabey: do you know of any cljs wrapper?

16:46 TimMc: so that makes me sad

16:47 whodidthis: :(

16:47 technomancy: TimMc: I basically use it for erc and nothing else =)

16:48 bmabey: sritchie: not that I know of.. we just use it on the jvm (BTW, we been using it lately to hit https://rollbar.com/)

16:48 sritchie: yeah, was looking at that

16:48 bmabey: thinking of going full client side with this redesign,

16:48 and trying to wrap my head around how to do authentication over sockets

16:48 with JWT

16:48 TimMc: technomancy: C-b is bad because of distance on a qwerty keyboard?

16:49 technomancy: TimMc: no, because readline uses it

16:50 bmabey: sritchie: I'd probably just wrap the rollbar JS lib

16:51 whodidthis: this emacs-live thingie is much better than whatever i came up with with vim

16:53 amalloy: TimMc: C-b is terrible because that's how you go back one character :P

16:54 justin_smith: ~emacs-live

16:54 clojurebot: I don't understand.

16:55 justin_smith: I thought we had a factoid for that

16:55 whodidthis: if you keep using emacs, you may want to switch from emacs-live to technomancy 's better-defaults setup

16:56 TimMc: amalloy: Oh! Yes, right.

16:56 thedanko: lispcast video three is starting to get heady

16:56 lots of maps eh

16:56 justin_smith: also, how much do I hate web forms that turn on bold text when I just wanted to back up a few chars

16:58 technomancy: justin_smith: O_O

16:58 justin_smith: technomancy: really it's my fault for muscle-memory typign C-b

16:58 technomancy: what wretched hives of scum and villainy are you visiting?

16:59 justin_smith: terrible places that allow commenting

16:59 technomancy: It's dangerous to go alone, take this. *hands justin_smith a noscript*

16:59 justin_smith: haha

17:00 mearnsh: i was confronted with this web form UI horror the other day: https://dl.dropboxusercontent.com/u/29566112/ss/form.png

17:00 technomancy: oh dear

17:01 mearnsh: re-entered several times before shaking my fist

17:01 justin_smith: mearnsh: what a weird place to change fonts

17:01 mearnsh: or whatever they are doing there

17:02 dbasch: mearnsh: this is worse: https://www.dropbox.com/s/0si5h8ocq96p5nk/verizon.png?dl=0

17:03 security reasons wat

17:03 ticking: additionally the star probably links to a billion password limitations leaving a password space of 2^8

17:04 EvanR: is {:a 1 :b 2} more or less idiomatic than {:a 1, :b 2}

17:04 upwardindex: How can I (def something) but specify the metadata (it seems the metadata gets overwritten by the def when I use (with-meta)

17:05 dbasch: EvanR: most people don’t seem to use , in literals but I’d say it’s a matter of taste

17:05 technomancy: upwardindex: use ^{:foo :bar} preceeding the var name

17:06 EvanR: I wouldn't put a comma in a small map like that, but it can be useful when you want to do a more complex one on a single line

17:06 mearnsh: EvanR: just use commas where they might enhance readability

17:06 ticking: upwardindex: you have to be carefull where you asign the metadata on. you want it on the war but it seems you currently place it on the object in it

17:06 'var

17:07 upwardindex: technomancy, ticking: Hmm, perhaps what I’m trying to do is very kosher, I’ll rework the code, thanks!

17:07 technomancy: upwardindex: no, it's fine

17:11 EvanR: i noticed its in the map pretty print

17:12 ticking: EvanR: they are just whitespace so you *could* put them everywhere

17:13 justin_smith: (defn, shatner-walk, [f, ...] (walk/post-walk, f, ...))

17:14 or wait that should be walken-walk

17:18 ticking: I think we should use them to highlight semantics.

17:18 (->

17:18 ,,,,,,,,,,,

17:18 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

17:18 ticking: , 1 ,

17:18 clojurebot: 1

17:18 ticking: ,,,,,,,,,,,

17:18 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

17:18 ticking: , inc ,

17:18 clojurebot: #<core$inc clojure.core$inc@493d4a>

17:18 ticking: ,,,,,,,,,,,

17:18 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

17:18 ticking: , print ,

17:18 clojurebot: #<core$print clojure.core$print@49cbde>

17:18 ticking: ,,,,,,,,,,,

17:18 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

17:18 ticking: )

17:18 sritchie: is anyne here working on a websocket app w/ sente or friends that uses authentication across the websocket channel?

17:19 ticking: poor clojurebot :(

17:19 seancorfield: sritchie: yes, we do it via sending credentials over the WS and getting a response back, as well as a periodic ping to verify session is alive

17:19 and the server tracks that an individual connection has authenticated

17:20 ztellman: bbloom: I think that seems right to me

17:20 sritchie: seancorfield: using sente? yeah, I guess I can use the :uid field that sente provides -

17:20 ztellman: bbloom: pull request welcome

17:20 bbloom: ztellman: already sent a PR

17:20 :-)

17:20 ztellman: oh, ha

17:20 sritchie: seancorfield: you can’t really “log in” over that channel, right

17:20 bbloom: ztellman: the PR simply calls f in the else branch

17:20 sritchie: seancorfield: if you’re trusting cookies to handle whether or not a user has authenticated

17:20 bbloom: ztellman: solved my problem

17:21 sritchie: seancorfield: like, if they start on my SPA unauthenticated, websocket connection established for page redirects, etc,

17:21 bbloom: ztellman: i was trying to find all mentions of a field name, but trying to call a method on a field name (.meth field) meant that the field wasn't found

17:21 seancorfield: sritchie: we require credentials to authenticate on the server, the server verifies each request is from an authenticated connection

17:21 sritchie: seancorfield: okay, so there’s no unauthenticated mode for you guys

17:21 seancorfield: so the app can operate in non-authenticated mode, but very limited

17:22 aaelony: has anyone used Clojure to create new UDFs for Hive/Hadoop? I have seen http://eigenjoy.com/2011/04/29/custom-hive-udfs-in-clojure/ and wondering if there has been an update?

17:22 sritchie: but can it switch to authenticated mode without re-establishing the websocket?

17:22 whodidthis: oh no, how do i shut down the repls started up via cider-jack-in

17:22 seancorfield: yes, because the server tracks the state as well as the client

17:23 dbasch: whodidthis: M-x cider-quit

17:23 sritchie: seancorfield: okay, so you’re not tracking authentication via a cookie, right

17:23 seancorfield: and the server won't allow / process various messages without it knowing the client has authenticated

17:23 correct

17:23 whodidthis: i tried cider-quit but them jvms still up, should i just kill them

17:23 sritchie: seancorfield: so the user has to log in every time they visit your site?

17:24 seancorfield: that's a separate concern and can be done via a cookie (we don't currently)

17:24 dbasch: whodidthis: sure, why not

17:24 whodidthis: was just wondering whether theres some other command i should know

17:24 sritchie: seancorfield: yeah, with a cookie, and then you’d have to reestablish the websocket connection

17:24 seancorfield: the client can request a unique token from the server (after authentication) that can be used once for login without supplying credentials

17:24 sritchie: seancorfield: so that it could be initiated with the cookie

17:25 seancorfield: and then store it in local storage or something, I guess?

17:25 seancorfield: I guess - we haven't gotten that far yet :)

17:25 sritchie: gotcha

17:25 okay, sounds like I need to poke around a little more :)

17:25 seancorfield: right now the app is internal only and we require authentication on each visit

17:25 sritchie: ah

17:25 reestablishing the websocket connection doesn’t seem too bad

17:26 ahahhh

17:26 https://github.com/ptaoussanis/sente/issues/63

17:26 whoops, too many “ahh”s

17:28 seancorfield: yeah, we have a timed session store in our app already so we'll connect that up at some point, then use the reconnect trick to deal with the cookie I expect

17:45 mikerod: Hmm. I thought that lazy evaluated values still captured the surrounding dynamic binding values at the time they were created

17:46 e.g. I thought dynamically bound var values would be "closed over" in when the lazy values were actually realized

17:46 uhh i.e.

17:47 I guess this is discussed @ http://dev.clojure.org/display/design/Improve+Binding

17:48 turbofail: hm. i'd imagine that sometimes you'd want that, and sometimes you wouldn't

17:48 i.e. it's probably something you'd want explicit control over

17:48 mikerod: Yes, I see some good arguments in both directions now that I look at it closer

17:49 in the more general case

17:49 I just had sometheing like a (binding [x 10] (for [v (some-list)] (+ v x))) and was confused that there was no bindings conveyance in the lazy seq realization

17:49 (it wasn't as obvious as this)

17:50 Just have to be careful with laziness in the scope of dynamic bindings I suppose :D

17:51 whodidthis: oh no my beautiful dreams, terminal+tmux+emacs dont seem too friendly

17:53 amalloy: whodidthis: there's not any conflicts between them that i'm aware of

17:53 aaelony: whodidthis: I use tmux and vim for that reason. Otherwise, I prefer emacs.

17:54 amalloy: mikerod: you do have explicit control! if you don't want conveyance, write the code you did write; if you do, you can capture the dynamic bindings via a lexical binding: (binding [*x* 10] (let [x *x*] (for ...)))

17:54 aaelony: amalloy, you're right. I think it's tmux and vim that shares ctrl-b

17:55 amalloy: aaelony: well, as we were saying earlier, you need to choose a good tmux key; c-b may be a good default for vim users, but it is abysmal for emacs

17:55 whodidthis: im not getting C-9 or C-0 through, probably something going on with tmux

17:56 aaelony: amalloy: true. screen is nice, but tmux is awesome.

17:56 mikerod: amalloy: yes indeed. the explicit control makes me all powerful!

17:56 amalloy: can anyone recommend a tmux tutorial for me? i have a minimal understanding of what tmux is supposed to do but no real experience with how to use it

17:57 mikerod: amalloy: I understand the issues involved and why it is explicit control now. It can just be a pretty sneaky thing in some contexts. Then again, I think dynamic bindings are a very sneaky thing in general.

17:58 aaelony: amalloy: this is a start: https://www.youtube.com/watch?v=wKEGA8oEWXw tmux tutorial

18:01 https://gist.github.com/MohamedAlaa/2961058 <-- tmux cheatsheet

18:22 whodidthis: its probably my lovely mosh-chrome/secureshell sending out some bad stuff with ctrl-numerals for whatever reason, dosent work without tmux either :(

18:23 is there some other interesting key i could use instead, like esc can be used instead of meta

18:23 raspasov: /msg NickServ identify iSch051065c

18:24 oops

18:24 #stupidShitOnIRC

18:25 justin_smith: raspasov: this is why I only identify from my #freenode window

18:25 raspasov: yea :)

18:25 ok changed lol

18:25 amalloy: man, i let znc identify for me. typing it manually would be sad

18:25 raspasov: there was a space at the front LOL

18:32 tuft: my favorite thing i got working in tmux is os x clipboard integration

18:32 EvanR: /msg nickserv id l01b167175

18:32 oops

18:38 TimMc: How did you manage that? Prefixing with /say?

18:40 amalloy: TimMc: that's how i usually do it

18:41 /msg TimMc if you don't know that you must be a noob

18:41 EvanR: /n00b

18:42 amalloy: EvanR: does that password mean something funny if you type it into a calculator and turn it upside down? it looks like it should

18:43 EvanR: its irc, dont you speak leet?

18:43 justin_smith: EvanR: clojure is so uncool, we can'

18:43 t even do nerd-cool

18:44 (stupid fat fingers)

18:44 ticking: I thought clojure is seen as a hipster language

18:44 EvanR: "clojure is considered a hipster language" hahaha

18:44 ticking: I mean. Most hipster things could also be advertised with clojures slogan.

18:45 Fixie Bike: Simple made easy.

18:45 justin_smith: ticking: walmart: simple made easy

18:45 amalloy: eugenics: simple made easy?

18:46 justin_smith: amalloy: I am really glad that one doesn't really work

18:46 amalloy: clojurebot: justin_smith is really glad eugenics doesn't really work

18:46 clojurebot: Roger.

18:46 ticking: doubt?! To the sharks with him!

18:49 justin_smith: ticking: I live in pdx, so I can say with some authority that hipsters still prefer ruby, with node coming a close second place

18:49 amalloy: do folks use tmux for their local machine? it seems like all the tutorials out there are like "you can manage windows locally but really tmux is all about persistent server sessions"

18:49 justin_smith: amalloy: locally I just use the tab feature on my terminal emulator

18:49 ticking: justin_smith: yeah, node IS a hipster language, but clojure still might be perceived as one ;)

18:50 amalloy: yes

18:51 Shayanjm: justin_smith: hipsters prefer ruby for no reason ;)

18:51 tuft: amalloy: i use it locally for the window management and for keyboard copy/paste

18:51 justin_smith: Shayanjm: hipster reasons are strange and neigh inscrutible in general

18:51 nextstep: hello, clojure newbie here. I would like to create an app that processes a large stream of data by applying several functions to it in a pipeline-like fashion, with dependencies and splits. What would you use, eep?

18:52 Shayanjm: true that

18:52 mearnsh: amalloy: yeah both local and on all my servers

18:52 mfikes: eschew complection, espouse immutability

18:52 amalloy: justin_smith: neigh? hipsters are horses?

18:53 justin_smith: nextstep: my first inclination would be to use thread pools and queues, perhaps via the core.async abstraction

18:53 amalloy: horpsters, either that or I am shit at spelling

18:53 ticking: if hipsters were horses, beggars would ride..... wait what?

18:53 justin_smith: nigh

18:53 mfikes: nextstep: If the problem is large enough, Storm

18:54 ticking: nextstep: depends, something between sequences, core.async, and bigdata, depending on the use case :)

18:55 EvanR: can i split on a string that is not a regex

18:55 ticking: EvanR: hurm?

18:55 amalloy: &(doc clojure.string/split)

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

18:55 EvanR: my string contains | and stuff that i dont want to escape

18:55 amalloy: EvanR: so, looks like no, but you can quote the regex

18:55 nextstep: mfikes, ticking: its not too big, i was actually looking for sth simple

18:56 EvanR: like (re-pattern '"foo") ?

18:56 ticking: nextstep: a simple sequence should work

18:56 nextstep: will run on the same machine

18:56 amalloy: ,(clojure.string/split "foo|?|bar|?|whatever" #"\Q|?|\E")

18:56 clojurebot: ["foo" "bar" "whatever"]

18:56 nextstep: ticking: but i need splits and i have a large number of functions to map

18:57 ticking: nextstep: splits?

18:57 amalloy: EvanR: \Q..\E is the regular expression quoting mechanism

18:57 nextstep: ticking: sorry, splits are bifurcations of the pipeline in the jargon of some libraries

18:58 i.e. applying a function only to the elements of a stream that satisfy this and that condition

18:58 after applying another function

19:01 ticking: nextstep: so you basically have to go full DAG processing?

19:02 mfikes: nextstep: I wonder if Prismatic Graph applies

19:03 nextstep: ticking: yes, a tree rather than a DAG would suffice for the moment

19:04 ticking: nextstep: well, even with sequences you can do conditional maps

19:04 if that is too simple, then you'll have to go up a notch with something like graph as mfikes mentioned, core async, or lamina

19:05 after that comes storm, or flambo

19:05 nextstep: ticking: ok, thanks. I'm fond of plain sequences but perhaps applying many conditional maps would be a bit clunky

19:06 and difficult to parallelize

19:07 dbasch: nextstep: why do you need conditional maps instead of one function composing all individual functions and conditions?

19:09 nextstep: dbasch: could you illustrate how to compose everything with a function?

19:09 mdeboard: justin_smith: I think last week you and i were talking about hide-show minor mode in Emacs. Just realized I bound it a long time ago https://gist.github.com/mattdeboard/119feedf99053e4c8610 I have a mouse with a ton fo buttons, so I set it up a long time ago to use one of the thumb ones to toggle show/hide. Go figger

19:09 dbasch: nextstep: you are processing a stream of individual inputs, right? the output for each input doesn’t depending on any other inputs

19:10 nextstep: if so, for each input you just need to apply a function e.g. if a do b and c, otherwise d and e, etc.

19:11 s/depending/depend

19:11 justin_smith: mdeboard: hah, nice

19:13 aaelony: mearnsh: tmux locally and on all your servers sounds like Inception, a dream within a dream, with a ...

19:13 within a ..

19:14 mearnsh: sessions should be nested with care, unset $TMUX to force

19:14 i don't go that far

19:15 aaelony: didn't know about unset $TMUX

19:15 nextstep: dbasch: yes, my inputs are independent

19:15 amalloy: i look forward to having N nested tmux sessions so that i need to hit C-z 2^n times to talk to the innermost one

19:15 nextstep: but some functions depend on other function applications

19:15 mdeboard: Now I need to fully exploit this mouse in emacs.

19:16 dbasch: nextstep: but they depend on the application of the function to an individual item, so you need to construct a function with all the conditions and then map that to the sequence

19:16 amalloy: mdeboard: if your hands leave the home row while you're using emacs, there's room to improve your workflow, by not doing that

19:16 mearnsh: well i don't nest sessions on the same machine, but yeah, if i want to talk to my servers' tmux it's C-z z, fortunately that's rare for me

19:16 mdeboard: naw never

19:16 amalloy: so what's the mouse for, then?

19:16 mdeboard: well

19:17 aaelony: paperweight

19:17 mdeboard: I do use the mouse to switch between workspaces on xmonad

19:17 with multiple monitors

19:17 amalloy: aaelony: hold down the Ctrl key by putting your mouse on it? i like that

19:17 aaelony: heheh

19:17 technomancy: amalloy: how do you think everyone was typing in all caps the other day?

19:17 mdeboard: and sometimes, if there's a casual, sensual lingering on my pointing device, well... I can't be blamed for what might happen next amalloy

19:18 dbasch: amalloy: you can always get a foot mouse

19:18 mdeboard: I'm only human, after all

19:18 amalloy: dbasch: i tried footpedals for my modifier keys

19:18 aaelony: replicant!

19:18 technomancy: it's adam and even not adam and minnie

19:18 *eve

19:18 mdeboard: amalloy: If your toes leave your homerow, you're doing somethign wrong.

19:18 * mdeboard vomits

19:19 amalloy: it was cool but coordinating between a foot and a finger is way harder than coordinating between fingers: i just couldn't get things as seamless

19:19 mdeboard: I'd like to see an experienced drummer do that kind of setup with emacs

19:19 I bet it would be ridiculous to see

19:19 noonian: amalloy: interesting, i was considering trying out that setup

19:19 dbasch: amalloy: I built a few foot click buttons years ago, didn’t use them for very long

19:19 mdeboard: since they come to the table with very good bilateral hand/foot coordination

19:20 amalloy: noonian: i'd still recommend it if the goal is to reduce finger fatigue, but not if you want to increase throughput

19:20 mdeboard: yeah, but fingers and hands aren't really the same

19:20 mdeboard: actually, one place my hands do leave the homerow but still stay on keybaord is flipping through buffers

19:20 C-x left/right arrow

19:20 noonian: amalloy: yeah i'm just trying to save my wrists/hands the strain

19:21 amalloy: mdeboard: put that on a better key then, silly

19:21 mdeboard: All my wrist strain went away after binding ctrl to caps

19:21 technomancy: http://p.hagelb.org/arrowed.jpg

19:21 amalloy: yeah, mine too, mdeboard

19:21 mdeboard: oh strongbag

19:21 bad.

19:21 technomancy: pff--ctrl on the thumbs is where it's at

19:21 mdeboard: technomancy: check your thumb privilege

19:22 amalloy: technomancy: i remember last time someone suggested that to me, i was like "but i use my thumbs for spacebar! i could never change that!"

19:22 mdeboard: damn i haven't seen homestar runner in so long but "arrowed" and "sworded" is still a common reference

19:22 Bronsa: amalloy: both thumbs?

19:22 technomancy: mdeboard: oh right I forgot some of us haven't evolved opposable thumbs yet my bad

19:22 amalloy: then after typing for a while i discovered i was actually using my right index finger for spacebar

19:22 technomancy: spoiler alert, etc

19:22 amalloy: like, when did i pick *that* habit up

19:22 mdeboard: technomancy: that's what my prehensile tail is for

19:22 noonian: massdrop is still manufacturing my ergodox

19:22 mdeboard: amalloy: wat

19:23 Bronsa: I have never pressed spacebar with my left thumb in my life

19:23 mdeboard: I bet that's not true

19:23 unless you don't have a left thumb

19:23 or a spacebar

19:23 or if you JUST popped into existence

19:23 Bronsa: my left thumb rests on the touchpad

19:23 mdeboard: Oh, I disable my touchpad asap

19:23 hate it

19:24 Bronsa: it's disabled while I type and for 0.3s after I stopped typing, and touch clicking is always disabled

19:25 technomancy: it is nice for scrolling

19:25 mdeboard: I use my Kinect for that

19:25 or voice commands

19:25 "Scroll down *flails*"

19:25 Bronsa: yeah scrolling while reading is 80% of what I use my touchpad for

19:26 technomancy: I got one of these for my birthday http://www.amazon.com/Griffin-Technology-NA16029-Multimedia-Controller/dp/B003VWU2WA/

19:26 pretty handy

19:26 Bronsa: nice

19:26 dbasch: the kinesis keyboard forces you to use your right thumb for space among other things

19:27 amalloy: technomancy: what for?

19:27 technomancy: amalloy: scrolling?

19:27 I don't have a trackpad

19:27 mdeboard: what on earth

19:28 amalloy: i don't really get what's wrong with the arrow keys or spacebar for scrolling

19:28 technomancy: also when I'm not at my desk my trackpoint is covered by my keyboard anyway

19:28 amalloy: i guess those mostly work for the browser

19:28 technomancy: amalloy: you can't press the arrow keys harder to make it scroll faster

19:28 (but if you could, it would be awesome and I would do that instead)

19:28 mdeboard: I just use my mouse'ss croll wheel

19:28 it has two modes

19:28 Bronsa: technomancy: well now you know what your next project will be :)

19:29 mdeboard: one is incremental scrolling (normal) and I can unlock it so it free scrolls. Pretty sweet.

19:29 technomancy: Bronsa: I have literally looked into pressure-sensitive analog switches to build this myself but haven't found anything suitable =)

19:29 amalloy: mdeboard: sure, i do too. but i can see how apple folks, or others without a mouse, want something similar to a scroll wheel

19:29 mdeboard: Oh yeah

19:29 Forgot about that

19:29 Can macs not use just regular mouse?

19:30 nextstep: dbasch: but how do i coordinate the order in which the mappings take place?

19:30 amalloy: they can, but those like...magic bluetooth touchpad things are popular

19:30 mdeboard: oh yeah

19:30 aaelony: can't stand the newish finger swiping mac os stuff

19:30 technomancy: if anyone knows of a suitable easily-mountable pressure-sensitive analog switch please let me know =)

19:30 dbasch: nextstep: what exactly do you mean by mapping? so far my interpretation is (map f s)

19:31 technomancy: hm... maybe a distance sensor

19:31 dbasch: amalloy: I have a bluetooth touchpad attached to the middle of my kinesis keyboard

19:32 amalloy: man, you and ninjudd/lancepantz would get along great

19:32 Raynes: Oh God.

19:32 We have one of them here too amalloy.

19:32 mdeboard: technomancy: http://en.wikipedia.org/wiki/Theremin

19:32 technomancy: do it.

19:32 technomancy: mdeboard: suuuuper tempted

19:33 mdeboard: That would be pretty amazing.

19:33 nextstep: dbasch: (map g s) depends on the result of (map f s0)

19:33 s should only contain some items in s0 that

19:34 satisfy certain condition

19:34 mdeboard: technomancy: http://www.moogmusic.com/products/Etherwave-Theremins

19:34 nextstep: i have this pattern many times, so a whole tree of processing

19:34 dbasch: nextstep: not really, you said g(x) depends on f(x)

19:35 nextstep: dbasch: sorry, its late here and my explanations kinda suck

19:35 dbasch: nextstep: at any point one of your functions can yield nil so the rest of the functions pass it through

19:35 and you can map (or keep, to ignore nils) your composed monster function

19:35 nextstep: i simply want to pass a stream through a tree of function mappings

19:35 {blake}: I do this weird thing...only in clojure, so I'm not sure why, exactly...but I'll be working my REPL and over the course of a few days, functions that I write will no longer be in the source file. Like, I've deleted them somehow.

19:36 nextstep: and run as much as possible in parallel

19:36 dbasch: nextstep: if you’re mapping a function, it’s a given that it can be parallelized

19:37 {blake}: It makes me wish "source" worked in the REPL.

19:37 nextstep: dbasch: ok, will try to see if i can come up with decent code

19:37 that's true

19:38 dbasch: amalloy: http://i.imgur.com/pPYmGrK.jpg <- my keyboard at the office

19:38 amalloy: dbasch: i don't need a picture; i've seen that exact setup every day for years

19:38 (from ninjudd and lancepantz)

19:38 dbasch: heh

19:38 * Raynes nods

19:38 amalloy: my keyboard is like a $5 piece of garbage

19:39 Raynes: My guy here doesn't use a trackpad.

19:39 I have a $180 das 4.

19:39 * technomancy feels like he should be peddling his wares

19:39 dbasch: age makes fingers less able to deal with crappy keyboards

19:39 Raynes: I'm definitely a keyboard crazy, but not an ERGO keyboard crazy.

19:39 amalloy: i don't need any stinkin keyboard pants, technomancy

19:40 Raynes: Where crappy keyboard is effectively any staggered keyboard?

19:40 dbasch: yes, the staggered format needs to die soon

19:40 technomancy: amalloy: dude, I've moved on

19:40 dbasch: these are not typewriters

19:40 technomancy: amalloy: wait, have you not seen http://atreus.technomancy.us?

19:41 Raynes: Perhaps one day I'll have hand issues that change my opinion.

19:43 amalloy: technomancy: it seems like if you're going to retrain your hands anyway to use that minimal number of keys, you might as well do something better than qwerty. as you say, these aren't typewriters

19:43 * technomancy nods

19:43 joshuafcole: technomancy: Whoah, you were behind the atreus?

19:44 technomancy: amalloy: I don't use qwerty on my own board, and the firmware ships with colemak and dvorak options

19:44 Raynes: In front of it a couple of times too, joshuafcole.

19:44 technomancy: joshuafcole: yup

19:44 joshuafcole: I'd read quite extensively about it when reviewing alternate keyboards

19:44 technomancy: oh nice

19:44 joshuafcole: Looks awesome

19:44 dbasch: I tried dvorak for a while but didn’t find it convincingly better

19:44 technomancy: I haven't actually put much effort into promoting it because I'm busy designing a circuit board to make the assembly process easier

19:45 dbasch: TBH if I were starting over I'd probably use colemak

19:45 zwer: joshhead did you test datahand keyboard?

19:45 oh I guess you were reading reviews, not writing them

19:46 ticking: technomancy: have you considered moving all the keys one row up? making the number row the new qwert and freeing up the bottom row as thumb modifiers.

19:46 zwer: anyway I'd give datahand keyboard a try if it was discountinued and sold for $1500 used

19:47 technomancy: ticking: the bottom row is already thumb modifiers

19:47 ticking: oh, you mean a layout for a conventional keyboard? not a bad idea, but I wouldn't use it myself.

19:47 ticking: technomancy: I mean't on a regular keyboard, like a laptop ;)

19:47 yeah

19:47 joshuafcole: Price has been a primary limiter in my search. I can easily justify $100, but $200 and up requires a lot of research

19:48 In order to ensure that I'm making the best call with that cash

19:48 ticking: technomancy: yeah, after a few years of using custom keyboards and layouts I found that carrying around keyboards is not work the hassle ;)

19:48 worth

19:49 technomancy: ticking: yeah... that's why I made one that's only 26cm wide and under 300g

19:49 mearnsh: been using colemak for over a year now, recommended

19:50 ticking: technomancy: yeah yours is the most portable I've seen, but it's still an extra device

19:50 technomancy: but thinking about it, I think it would be nice to combine it with an ipad, where one has to carry a keyboard around anyways

19:51 TimMc: zwer: https://github.com/dodohand/dodohand

19:56 ticking: technomancy: btw, is there a reason you lasercut instead of 3d print?, you could shave a lot of material of if the keyboard was just the outline of the keys ;)

19:57 technomancy: ticking: 3D printing is weak sauce

19:57 it's a lot more expensive, very flimsy, and much less precise

19:57 at least for designs that can be layered

19:57 arrdem: mainly the flimsy bit...

19:57 ticking: technomancy: it kinda depends on the process

19:58 the pla material most diy printers use is pretty rock hard

19:58 I'd say twice the strength of plywood

19:58 technomancy: well, the harder stuff is way slower to print

19:59 so it comes out being a lot more expensive

19:59 ticking: technomancy: sorry I don't follow you. It takes me about 4 hours to print something the size of your keyboard

19:59 TEttinger: leather keyboard from ponoko :D

20:00 ticking: while I'm asleep

20:00 technomancy: ticking: these cut in about 12m at a dollar a minute

20:00 ticking: so how does that increase price?

20:00 technomancy: yeah but where do you pay 3d printing at a minute rate?

20:00 TEttinger: that's laser cutting

20:00 technomancy: at the local hacker space

20:01 andyf: Any reason folks prefer tmux over vnc ? We share desktops between devs via vnc frequently at my work

20:01 ticking: every service that I know of is material usage * material cost

20:01 technomancy: anyway there's really no comparison in the feel vs wood that has been sanded and oiled with some wax mixed in

20:02 ticking: technomancy: and if you have a 3d printer yourself you pay only the filament which is dirty cheap

20:02 technomancy: andyf: latency mostly

20:03 I've done acrylic too which can be cool since it's transparent, but the texture of the wood is more appealing

20:03 ticking: technomancy: yeah, but I'd still prefer less border and less weight ;)

20:03 arrdem: andyf: for various projects & contests we prefer tmux/screen because we're doing sysadmin & server side work where vnc doesn't really apply nicely

20:04 technomancy: ticking: it's an OSS design. someone has made their own printed case, I just don't think it would sell very well.

20:04 andyf: Because no X libs/apps installed there?

20:04 TimMc: Does tmux do shared sessions more effectively than screen does?

20:04 arrdem: andyf: that's one reason

20:05 TimMc: they're equally bad

20:05 TimMc: You can also use ttyrec and ttyplay with the follow feature.

20:05 technomancy: TimMc: it's a lot nicer than screen, you just chmod a socket

20:05 instead of running screen as setguid root

20:05 TimMc: good

20:05 because that sucks and I don't do it

20:05 technomancy: also tmux sizes the screen according to the smallest client rather than the latest to join. >_<

20:05 TimMc: technomancy: Screen actually does some combo of that.

20:06 latest-smallest

20:06 technomancy: TimMc: hm; maybe it's improved since I used it. always drove me nuts.

20:06 TimMc: It's sticky is what it is.

20:08 technomancy: ticking: this guy is doing 3D printed cases, but I think it's specifically because it's not a design that lends itself to stacking flat layers https://www.crowdsupply.com/multiplxd/axios-keyboard

20:09 ticking: technomancy: yeah that looks a tad overengineerd :D

20:09 technomancy: it's been "right around the corner" since january; go figure

20:09 ticking: technomancy: I like the one hand two hand approach of only using a PCB as the entire structure

20:10 this seems to make assembly a lot easier and also uses minimal space/weight

20:10 technomancy: it's a cool hack, but I wonder how it would hold up to getting tossed in a bag

20:11 ticking: technomancy: I think this is where the 3d printing stuff really shines, one could easily create a case that is screwed on

20:12 to give structural integrity and protect the user from pointy leads

20:12 arrdem: interesting... anyone know how coveralls does code coverage analysis?

20:12 ticking: you don't need sub 0.1 mm precision then

20:13 technomancy: also if you want a version for your desktop you could print stell or ceramics

20:13 technomancy: ticking: yeah, and being able to iterate on designs that you intend on throwing away is appealing

20:13 ticking: http://www.shapeways.com/materials/steel

20:13 http://www.shapeways.com/materials/ceramics

20:14 technomancy: actually been thinking about hand-carved hardwood

20:14 TimMc: arrdem: You can't talk about code in here, this is the #clojure room!

20:14 ticking: technomancy: cnc milled hardwood?

20:14 arrdem: TimMc: sorry I thought this was #emacs for a while there

20:15 technomancy: ticking: or that, yeah

20:15 arrdem: I should do a kickstarter for a real TANAL/partial evaluator backed code coverage tool..

20:15 rather than execution tracing..

20:17 ticking: technomancy: so yeah PCB layout + pluggable backshells = win

20:20 whodidthis: maybe its easy to change paredit shortcuts into some C-alpha + ( etc combis or something, defaults seem impossibl to get to work

20:22 technomancy: whodidthis: recommended

20:26 mj_langford: 👍 arrdem

20:30 TimMc: Looks like the dodohand is in fact still in active development: http://geekhack.org/index.php?topic=41422.300

21:42 azeirah: Guys, is it possible to connect to the internet in a macro? Ex, when you're working with wikipedia pages, you could gather the data at compile-time

21:47 TEttinger: azeirah, yes it should be possible. I'm not a macro master, but you can try it out with just calling (slurp "http://google.com")

21:48 which will fetch the source of that HTML page as as string

21:48 azeirah: Interesting, thanks! I believe there lies great untapped power in macros

21:52 justin_smith: azeirah: and, as usual with great power, the ability to make a huge mess :)

21:53 azeirah: X] can imagine, yeah

21:57 gfredericks: azeirah: macros are mostly just for creating new syntax; I don't think I've ever seen a compelling use for side effects in a macro

21:58 mj_langford: That really looks like I'd consider having a build time script to do that sort of work

21:58 gfredericks: compile-time side effects just sound unnecessarily surprising

22:02 arrdem: Using macro time for side-effects is something I would call immensely suspect if not an outright code smell. Having a make or bringup subprogram that's explicitly run before or at bringup is much nicer.

22:05 azeirah: The example I mentioned was only to make it clear what I was talking about

22:06 I see a potential use-case for docstring gathering

22:13 dbasch: “sorry, you need network connectivity to compile this program” <- horror

22:13 justin_smith: azeirah: we have build time tools like marginalia for that sort of thing (depending on what you mean by "gathering"

22:20 oskarkv: I'm trying to use JavaFX, but apparently I can't import Label, but I can import some other things from JavaFX. Any ideas? https://www.refheap.com/1e9bd839e8b74222a12517527 http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Label.html

22:22 justin_smith: oskarkv: I have a hazy memory that there is something in javafx that needs to be explicitly initialized, and some classes break if you try to refer to them before that initializations occurs, this has something to do with how clojure handles side effecting code in class initializers iirc

22:23 oskarkv: hopefully someone else can tell you something more specific

22:23 oskarkv: justin_smith ok

22:23 Thanks

22:24 justin_smith So there is some method out there that I can call to fix it? :p

22:25 justin_smith: oskarkv: relevenat SO http://stackoverflow.com/questions/23365409/clojure-cant-import-javafx-classes-with-static-initializers

22:25 oskarkv: thanks

22:28 justin_smith: that post talks about using ButtonBuilder instead of Button - maybe you could figure out a way to use LabelBuilder? http://docs.oracle.com/javafx/2/api/javafx/scene/control/LabelBuilder.html

22:32 _gizmo385: Is it possible to make a type a subtype of another type?

22:32 For example, if I want to define a graph

22:32 But also define a graph with special properties that "extends" from my base graph definition?

22:32 justin_smith: _gizmo385: in clojure we do extension by encapsulation or interface implementation, not by inheritence

22:33 _gizmo385: though with defmulti you can use 'derive' to specify inputs that should be treated the same way a more general case would be

22:33 _gizmo385: So how does encapsulation work in Clojure?

22:34 Do you know of any good examples that I could delve into to get an idea of it?

22:34 justin_smith: _gizmo385: for example, if you use defrecord to define a record type, you can use assoc to attach new keys

22:34 _gizmo385: immutibility is the best encapsulation you can get

22:34 _gizmo385: stuartsierra has some good articles on this iirc, let me see if I can dig up a link

22:35 _gizmo385: Awesome, thansk :)

22:35 thanks*

22:36 TravisD: What is the recommended emacs package for editing clojure?

22:36 arrdem: clojure-mode is good...

22:37 TravisD: I also see something called cider, is it worth looking at?

22:37 arrdem: cider is sometimes unstable and opinions are mixed

22:37 danneu: TravisD: + paredit-mode

22:37 TravisD: Hi again guys, by the way :) It’s been a few months since I’ve been on

22:37 justin_smith: hello

22:37 arrdem: TravisD: cider is the successor to nrepl.el. Cider works like... 95% of the time in my experience, less in that of others.

22:37 TravisD: however nrepl.el still totally works

22:38 I think some people here are still using slime even...

22:38 justin_smith: TravisD: cider is a fast moving target, and the default way of installing will get you new versions before they are verified not-broken

22:38 TravisD: cool :) Is there a place to read about the alternative options?

22:38 danneu: i had to switch from cider back to nrepl.el.

22:38 justin_smith: TravisD: that said, if you install 0.7.0, it should just mostly work

22:38 * arrdem 0.8.0-SNAPSHOT and no issues recently

22:39 danneu: i was on that snapshot until it broke for me a month ago.

22:39 then i rage-revert my emacs.d

22:40 arrdem: yeah not gonna lie I've had days when cider just fucking broke

22:40 justin_smith: _gizmo385: this article from stuart sierra has a nice explanation of what we do in the clojure world instead of inheritance, and why we don't use it: http://www.ibm.com/developerworks/java/library/j-clojure-protocols/

22:40 arrdem: which is OK, because I'm only a student and I'm not reliant on cider to do work to get paid

22:40 but it's not exactly comforting either

22:40 however, #clojure-emacs is that way, and feel free to bitch at bbatsov when shit breaks :D

22:41 'cause I sure will

22:41 TravisD: lol

22:41 danneu: yeah. wake up early on a saturday. ready to kill a sideproject idea youve had for a while. nope, looks like it's gonna be an .emacs.d day

22:41 TravisD: maybe I’ll stick to clojure-mode for now

22:41 _gizmo385: Awesome, thanks justin_smith :)

22:41 arrdem: TravisD: I'm serious that I think the stability issues of cider are overstated for the most part

22:41 danneu: TravisD: i think there are just two things you need to figure out how to do to write clojure: 1) manage parens, and 2) eval stuff in your editor (nrepl.el)

22:42 TravisD: Is evaulating in the editor really necessary?

22:42 arrdem: no but it's hella nice

22:42 justin_smith: _gizmo385: the one extra thing that I would add to that article is that he focuses on protocols, and those are good for high performance, but multimethods are less brittle in interactive development (you can redefine them in your repl without things just breaking, unlike protocols)

22:42 TravisD: With other languages I often just keep a repl running and reload my files whenever I make changes to test

22:42 danneu: TravisD: well, my clojure workflow is to fake my way through a function while spamming "eval-buffer" til it works

22:43 TravisD: danneu: Lol

22:43 A sensible strategy

22:43 arrdem: danneu: yep. same strategy here.

22:43 danneu: if im fancy i'll throw a bunch of `assert`s at the bottom to test said function

22:43 until there are no errors

22:43 justin_smith: _gizmo385: and starting with a multimethod that dispatches on 'type', then upgrading to a protocol if performance is an issue is not difficult

22:43 arrdem: TravisD: it's nice to have a keybinding for "reload this shit" instead of having to do it manually at a prompt

22:43 TravisD: Yeah, that is a nice thing

22:44 but it’s also kind of annoying not to have readline :(

22:44 arrdem: readline?

22:44 you totally get a standalone repl buffer..

22:44 _gizmo385: Awesome :)

22:44 The multimethods might look like they solve my problem as well

22:44 justin_smith: TravisD: with other languages the startup time is such that it's no big deal to just kill it and restart with the new code :)

22:44 TravisD: But all my readline shortcuts don’t work :) Like ctrl + R to reverse search through my command history

22:45 danneu: isn't there a way to use rlwrap

22:45 TravisD: Ah, I’ve been using julia which actually has nontrivial startup time :(

22:45 arrdem: TravisD: oh. Yeah that is inconvenient.

22:45 TravisD: danneu: In the emacs repl buffer?

22:45 arrdem: danneu: yeah. `lein repl` uses rlwrap

22:45 IIRC

22:45 TravisD: arrdem: that sounds right

22:45 justin_smith: _gizmo385: the big picture idea is you could define a multimethod for each method you would have defined in your base class in the java design, then make records that each get the appropriate defmethod for each one they implement

22:46 arrdem: it's that java -jar clojure.jar doesn't that drives ppl nuts

22:46 justin_smith: arrdem: iirc at this point lein uses a java readline wrapper, but yeah, it gets the right behavior

22:46 danneu: TravisD: oh. in an emacs buffer i use stuff like line autocomplete.

22:47 TravisD: danneu: Yeah, there are probably good options in the buffer

22:47 arrdem: danneu: what do you use? nrepl? cider's autocomplete is sketch as hell for me.

22:47 TravisD: I’m just not used to it :(

22:47 _gizmo385: How would such a record work? How would I call a specific defmethod from inside a record?

22:47 Or would I just have to set up the dispatching correctly so that it works automatically

22:47 justin_smith: _gizmo385: it's different

22:47 _gizmo385: in java land, of course, methods belong to a class

22:47 in clojure land, functions and multimethods are first class

22:48 danneu: arrdem: id need to open it to jog my memory since it's all muscle mem by now. but one thing i use is C-x C-l from evil-mode to cycle through line completion candidates like in vim

22:48 justin_smith: they are not owned by some object or class (though they live in a namespace)

22:49 _gizmo385: So when I define a record and implement an interface, how are those function definitions being handled?

22:49 justin_smith: _gizmo385: so the idea is that you have a generic functionality you define (think along the lines of an interface in java), and then you use defmethod to extend that functionality to a specific datatype

22:49 you define the record, and then use defmethod to extend the multimethod onto that type

22:50 or you extend a protocol inside the record definition, as another option (as I mentioned, performs better, less flexible for interactive development)

22:50 _gizmo385: So instead of "extending types" you more so expand your function definitions to handle those new types?

22:50 justin_smith: right

22:51 and it's more general than that - a multimethod can dispatch on any function, not just type

22:51 but type of the first argument is the common case

22:52 _gizmo385: Awesome

22:52 justin_smith: _gizmo385: and I think that article I linked does a decent job of explaining why we do it that way, rather than via inheritance

22:53 _gizmo385: Fantastic. I've tinkered with functional programming before but I've never really dove into the paradigm so it's a bit strange to wrap my head around

22:53 justin_smith: _gizmo385: the other part of this, is that with a protocol or multimethod you can actually extend a built in type onto your method / protocol

22:54 _gizmo385: one of my favorite quotes on that subject is the one from Perlis: "It is better to have 100 functions operate on one data structure than 10 functions that operate on 10 data structures"

22:54 _gizmo385: Isn't that one on the Wiki as well haha?

22:54 justin_smith: _gizmo385: it's a popular quote

22:55 but that's part of the rationale for why we allow and encourage attaching a new multimethod / protocol to an existing datatype

22:56 and sicne we are not mutating anything, this has slim to none risk of breaking invariants in existing code

22:57 _gizmo385: The convention that I've been following in my code thus far is that whenever I have a function that operates on the structure of a data type, I always return a new instance of that type. Is that the correct thing to do?

22:58 justin_smith: _gizmo385: the built in data types do not mutate, any "modification" is really creating a new immutible instance

22:58 this includes any defrecord you create, and the default for deftype as well

22:58 unless you go out of your way to use underlying mutable classes via interop, you don't need to do defensive copying, it's built in

22:59 ,(def a [0])

22:59 clojurebot: #'sandbox/a

22:59 justin_smith: ,(def b (conj a 1))

22:59 clojurebot: #'sandbox/b

22:59 justin_smith: ,b

22:59 clojurebot: [0 1]

22:59 justin_smith: ,a

22:59 clojurebot: [0]

22:59 justin_smith: conj does not change the vector, but makes a new one (that is allowed to share structure, since we know it won't be mutated)

23:00 _gizmo385: Awesome, thanks :)

23:01 justin_smith: _gizmo385: I am sure if you have significant OO experience this all seems like bizarro world

23:01 but there are real benefits that you'll hopefully see pretty early on

23:03 _gizmo385: I'm starting to see the advantages. A lot of the functions that I'm writing are a lot easier to express and the type system makes things a lot more easy than it is in standard OO languages

23:04 justin_smith: if nothing else the fact that defensive copying is something you need to explicitly opt out of simplifies so much code...

23:04 or effectively defensively copying, at least

23:05 but the type thing - clojure is more likely to get a runtime type error than many languages, so that part is double edged

23:05 and we have various approaches for mitigating it (core.typed, prasmatic/schema)

23:08 TEttinger: or my favorite approach, writing all code yourself so no one can yell at you for breaking something

23:08 (but I've heard good things about core.typed)

23:09 justin_smith: TEttinger: how have you achieved this blessed status of not yelling at yourself when you break your own shit?

23:10 * justin_smith asks for TEttinger's guru's contact info.

23:12 TEttinger: justin_smith: you know that article, The Bipolar Lisp Programmer? when a bipolar person's various mental currents are all flowing the right way, we can get plenty done.

23:12 justin_smith: :)

23:13 danneu: i've ported haskell's type system into the comments of my clojure projects

23:13 just havent ported the type checker

23:13 TEttinger: and my 133 day streak agrees with me https://github.com/tommyettinger

23:13 justin_smith: oh, very nice

23:13 keep up the good work, hope you don't crash

23:13 TravisD: yowzah

23:13 * arrdem mad]

23:13 TEttinger: what have you been working on lately, justin_smith, other than your massive karma score here?

23:14 arrdem: growing his karma score :P

23:14 justin_smith: I am theoretically working on a client site right now in the window next to this one. Cleaning up an article link preprocessor, maintinance work.

23:15 I also do harsh noise, I've been doing more recording than usual lately

23:15 TravisD: harsh noise?

23:15 justin_smith: TravisD: like industrial music without the musical parts - most people hate it

23:15 TravisD: cool lol

23:16 have an example?

23:17 justin_smith: this is a guy I knew ages ago, I saw a concert of his recently https://www.youtube.com/watch?v=ba1oxuIIY1I start with the volume low and slowly ease it up

23:17 like I said, most people hate it, and I can't make any excuses, it's just a weird acquired taste

23:18 TravisD: Pretty interesting actually :) Do you use it as background noice while working or something?

23:19 TEttinger: non-harsh non-noise https://www.youtube.com/watch?v=hZcyu5bAi8w&feature=youtu.be&t=1s

23:19 justin_smith: TravisD: sometimes - or as a catharting thing to crank up and listen to. I enjoy making it.

23:19 TEttinger: heh

23:20 TravisD: justin_smith: Cool. How big is the community, roughly?

23:20 justin_smith: TEttinger: the roots of harsh noise are actually pretty strongly in prog / free jazz / 20th century "classical"

23:20 TEttinger: that's a surprisingly modern-sounding album that I'd never heard of from 1971.

23:21 justin_smith: TravisD: in a major metropolitan area, you can see an internationally renowned artist that gets positive reviews in pitchfork, that was well publicised, and expect less than 100 people to show up

23:22 TEttinger: justin_smith: in the not-too-distant future, music will all be dubstep drops all the time, and genres will be based on how much of pitbull's voice is sampled on top of it

23:22 justin_smith: TravisD: it was briefly more popular in the late '90s / early '00 years and you could see maybe twice the crowd

23:22 TEttinger: heh

23:24 TEttinger: anyway, back to the question - programming, answering questions on irc and SO, making noise, re-reading Samuel Beckett's three novels trilogy

23:24 TEttinger: so, what are some clojure libraries that people are finding useful for productivity in general? I'm unfortunately unable to use core.async on this next project because the code flow is handled by Java (libgdx's Application stuff makes porting easier to android though)

23:25 justin_smith: TEttinger: marginalia has helped me a lot, it's a nice way to browse my codebase

23:25 TEttinger: is prismatic still churning out nice libs?

23:26 justin_smith: as far as I know, I keep intending to try schema - maybe I'll pull it in right now actually it may just help...

Logging service provided by n01se.net