#clojure log - Apr 29 2014

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

0:00 cbp: I used it once to implement logging levels as an example

0:00 and that's the only time

0:00 Jaood: egghead: arrdem: I hear zippers follow the transients philosophy too

0:00 arrdem: Jaood: the issue with macros is that most of the time functions will do where people may traditionally reach for macros and as macros are meaningless at runtime (what is map of a macro? what is the value of a macro?) they aren't worth it.

0:00 egghead: zippers! lenses!

0:00 living life to the fullest

0:01 Jaood: most of the ideas are actually simple, they just have scary names

0:01 Jaood: arrdem: got it

0:02 cbp: lenses?

0:02 arrdem: Jaood: that's not to say I haven't written macros, it's just that macros are reserved for doing funky syntax extension tasks that a function _can't_ do.

0:07 amalloy: i used multimethod hierarchies twice at geni. one was on closed-source code that wasn't terribly interesting, and the other seems to have been replaced or removed, but i think it was part of cake or one of cake's supporting libraries (uncle maybe?)

0:10 Jaood: arrdem: you mean DSLs?

0:10 arrdem: Jaood: a lot of "dsl"s can be done with just datastructures and functions...

0:10 Jaood: macros are for when you need a syntax extension that genuinely writes defs or something else crazy

0:11 Jaood: so macros are not that favored as in the CL world

0:12 cbp: turns out having syntax for more than one datastructure removes most of the need of macros for DSLs :-P

0:12 arrdem: (inc cbp) ;; truth hurts

0:12 lazybot: ⇒ 4

0:12 arrdem: $karma `cbp

0:12 lazybot: `cbp has karma 3.

0:12 arrdem: cbp: tut tut

0:13 Jaood: cbp: are you referring the unified abtractions over the clojure collections?

0:13 *to

0:14 is the reference documentation on clojure.org normally up to date?

0:14 arrdem: Jaood: he's referring to the fact that we have reader syntax for more than just lists.

0:14 ,#inst

0:14 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

0:14 arrdem: ,#inst "now"

0:14 clojurebot: #<RuntimeException java.lang.RuntimeException: Unrecognized date/time syntax: now>

0:15 * arrdem gives clojurebot a look

0:15 arrdem: ,(type :foo)

0:15 clojurebot: clojure.lang.Keyword

0:15 arrdem: ,(type {:foo :bar :baz 9001})

0:15 clojurebot: clojure.lang.PersistentArrayMap

0:15 arrdem: ,(type [1 2 3 :foo {:baz :bar}])

0:15 clojurebot: clojure.lang.PersistentVector

0:15 arrdem: and of course

0:16 ,(type '(1 2 3 4 :foo bar cojure.core/cons))

0:16 clojurebot: clojure.lang.PersistentList

0:16 Jaood: you missed one

0:16 ,(type #{1 2 3 4})

0:16 clojurebot: clojure.lang.PersistentHashSet

0:16 Jaood: :P

0:16 cbp: documentation online is rarely up to date

0:17 arrdem: :P there's sets and there are some other reader lits too.. there's even a way to do user defined reader types

0:17 cbp: your best friends are clojure.repl/source, clojure.repl/doc and clojure.repl/apropos and some other function i forgot the name of

0:17 arrdem: cbp: juxt?

0:18 cbp: ns-publics i think

0:18 amalloy: arrdem: i found my use of defmulti hierarchies! it was in depot, which contained the pom-generating stuff that cake used: https://github.com/ninjudd/depot/blob/develop/src/depot/pom.clj

0:19 it's not super-compelling, since all it does is eliminate the repetition of treating ::dependencies as a list of ::dependency and ::repositories as a list of ::repository

0:20 but i had in mind that idea that the pom task would have to be extended to include more stuff

0:32 arrdem: thoughts on tweaking the meajure reader lit so that (= #meajure/unit [2 :feet] #meajure/unit [2 :feet 1])?

0:37 ,(let [θ₀ (/ Math/PI 2) θ₉ (/ Math/PI 4)] (- (* -1 (Math/cos θ₀)) (* -1 (Math/cos θ₉))))

0:37 clojurebot: 0.7071067811865475

0:42 myguidingstar: hi all, is it possible to run lein tasks inside current project-local nREPL?

0:43 arrdem: lein != nrepl

0:44 TerranceWarrior: do you people use slime or cider for emacs? what about vim, is fireplace.vim the end all of interactive repls or quasi thereof?

0:45 arrdem: fireplace is the be all end all, slime is depricated in favor of nrepl.el or cider.el

0:45 believe me, fireplace is better than what came before :P

0:47 TerranceWarrior: arrdem: i will take your word for it! :)

0:48 arrdem: TerranceWarrior: nrepl.el still totally works, it just isn't being actively developed anymore. be careful with cider and what emacs repository you install from, nightlies of cider are notoriously likely to be broken and suck hours of dev time to repair.

0:49 technomancy: clojurebot: melpa?

0:49 clojurebot: It's greek to me.

0:49 technomancy: clojurebot: melpa is not what you want.

0:49 clojurebot: Alles klar

0:49 Frozenlo`: I went back to nrepl after trying cider

0:50 arrdem: I've been using cider successfully, but I couldn't tell you what's different besides the name :P

0:55 myguidingstar: technomancy, is it possible to run lein tasks using *current* project-local nREPL session?

0:55 technomancy: myguidingstar: sure, try setting :eval-in :nrelp

0:55 *:nrepl

0:56 myguidingstar: what about running lein task inside REPL, something like (lein ...)

0:57 technomancy: myguidingstar: you can do that with grenchman

0:57 but you need a separate repl session for that

0:57 lein has to be isolated from your project to run

0:58 myguidingstar: technomancy, yeah, the msg "launch `lein repl :headless' from outside a

0:58 project directory" from grench confused me

0:59 technomancy: myguidingstar: what's confusing about it?

1:01 myguidingstar: technomancy, I thought I can't reuse curent project-local nREPL session for lein tasks (as my first question)

1:02 technomancy: oh right; that's correct

1:02 sorry

1:02 well

1:02 some tasks run project code

1:03 those tasks can run that project code inside the existing repl session

1:03 but the actual task itself can't run inside there

1:03 TerranceWarrior: arrdem: ok, so don't cross the streams. thanks arrdem.

1:04 myguidingstar: so some tasks will work, and some don't?

1:04 technomancy: myguidingstar: what specifically do you want run in the existing repl?

1:04 myguidingstar: do you understand the difference between things like `lein run` which run project code vs `lein clean` which don't?

1:05 you can never run a task itself inside a project repl, but you can tell a task to run *its* project code inside an existing repl rather than starting a new JVM

1:08 myguidingstar: technomancy, so what's `:eval-in :nrepl` for? Those like `lein run` or `lein clean`?

1:09 technomancy: myguidingstar: it's for `lein run` type tasks

1:10 myguidingstar: got it, thanks a lot technomancy

1:12 technomancy: np

1:14 TerranceWarrior: any of you working in play-clj?

1:20 amalloy: ~anyone

1:20 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:21 szymanowski: (clojurescript): what does this error means? WARNING: my-ns/my-fn no longer fn, references are stale

3:41 vijaykiran: well that was new - getting spam from id's here

4:01 kevinwebster: Is there a way to hack on a project source quickly with clojure and lein? Something analogous to Ruby bundler's :path option in the Gemspec (for any ruby people)?

4:02 vijaykiran: I'm not familiar with Ruby stuff - what kind of workflow are you looking for ?

4:03 TEttinger: "lein try" has been mentioned before, a plugin

4:05 kevinwebster: This may not be idiomatic in clojure, but in ruby if I wanted to "play around" with a dependency (gem) I would clone the source and then include the root directory of the source in a specific way. After that I could change things in the dependency's source and see the results in my project

4:07 would a solution be to add the source somewhere in the classpath and then remove it from the project.clj's dependencies?

4:08 ucb: kevinwebster: lein has checouts

4:08 checkouts*

4:08 kevinwebster: https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies

4:09 kevinwebster: ucb: I think that is exactly what I am looking for, thanks!!

4:09 ucb: np

4:25 brainproxy: hmm, when I make a mistake in a cider repl, no error is shown, like its going to another buffer or something but I can't find it

4:25 recently upgraded some emacs packages, haven't noticed this before

4:27 ucb: brainproxy: I recently upgraded to 0.7.0-alpha

4:27 brainproxy: and had the same thing. I reverted to 0.5.0 and all is well.

4:27 brainproxy: in sum: it didn't quite work for me; unfortunately I wasn't virtuous so I didn't investigate nor filed any bug reports.

4:28 but it is a thing

4:31 brainproxy: ucb: turned out I needed cider/cider-nrepl as a lein plugin

4:31 in profiles.clj

4:31 then bounced emacs altogether

4:31 and all is well

4:32 ucb: huh

4:32 brainproxy: java 1.8, clojure 1.6

4:32 ucb: interesting

4:32 I should try that then! :)

4:32 brainproxy: what was confusing me was the message i needed cider nrepl installed, but I thought that referred to an emacs pkg

4:32 when in fact it refers to a lein thing

4:32 i.e. the cider-nrepl plugin

4:33 the message was showing in Emacs messages buffer, amidst other stuff

4:33 ucb: I got that message too. Did look for an emacs package. Couldn't find it. Reverted to 0.5.0 :)

4:36 brainproxy: yep, something popped into my head to look in clojars

4:36 otw, I was about to do the same

5:49 luxbock: ,(case (type "a string") java.lang.String true false)

5:49 clojurebot: false

5:49 luxbock: why does this fail?

5:59 mpenet: ,(doc case)

5:59 clojurebot: "([e & clauses]); Takes an expression, and a set of clauses. Each clause can take the form of either: test-constant result-expr (test-constant1 ... test-constantN) result-expr The test-constants are not evaluated. They must be compile-time literals, and need not be quoted. If the expression is equal to a test-constant, the corresponding result-expr is returned. A single default expression can foll...

6:02 luxbock: I still don't understand. in my mind case expands to (cond e (= result clause-1) do-stuff (= result clause-2) something), but I guess I'm mistaken?

6:04 mpenet: Classes are not compile time constants for case, there are a few "improved" case versions out there with their own problems too

6:05 nippy has case-eval and cgrand did something a bit similar I think

6:05 pyrtsa: ,(clojure.walk/macroexpand-all '(case x 1 :one 2 :two))

6:05 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk>

6:06 pyrtsa: ,(macroexpand '(case x 1 :one 2 :two))

6:06 clojurebot: (let* [G__93 x] (case* G__93 0 0 (throw (java.lang.IllegalArgumentException. (clojure.core/str "No matching clause: " G__93))) ...))

6:07 luxbock: hmm ok

6:08 mpenet: ,(case (type "a string") #=java.lang.String true false)

6:08 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

6:08 mpenet: meh

6:23 TEttinger: ,(case (type "a string") (class "whee") true false)

6:23 clojurebot: false

6:23 TEttinger: ,(print (type "a string") " " (class "whee"))

6:23 clojurebot: java.lang.String java.lang.String

6:27 clgv: TEttinger: the values in a case expression need to be compile time constants

6:27 TEttinger: ah yeah

6:27 clgv: TEttinger: and lists are interpreted as different options

6:28 TEttinger: and before you got here we talked about how classes aren't compile time constants

6:28 I was trying to figure out how to get [03:04;09] <mpenet> ,(case (type "a string") #=java.lang.String true false) to work

6:29 clgv: TEttingeryou can write a wrapper macro around case which resolves symbols

6:29 TEttinger: sure, it wasn't my problem in the first place

6:29 nippy's case-eval was mentioned

6:40 sm0ke: is there a way to make a function really first class in clojure?

6:40 so every time i define a function it generates a class

6:41 which means it can not be passed around in the network

6:42 the-kenny: So you want to serialize functions?

6:42 sm0ke: feels like a cheat to say clojure has first class status

6:42 the-kenny: https://github.com/technomancy/serializable-fn

6:42 clgv: sm0ke: huh why? what's your definition of "first class function"?

6:43 sm0ke: should be same as values in terms of behaviour when comes to passing around

6:45 the-kenny: Define "passing around" then

6:46 ucb: anybody got experience with slingshot? I'm having a hard time throwing+ a record and then catching it

6:49 martinklepsch: sm0ke, couldn't you just pass it around as edn?

6:49 sm0ke: martinklepsch: not if the function you define is anonymous and not :aot'd beforehand

6:50 ucb: oh, ignore me, I'm just an arse

6:50 the-kenny: sm0ke: how would you handle a function's environment when passing it around in a network?

6:51 sm0ke: the-kenny: lets assume there are no closures

6:51 rurumate: I'm confused. When I define (ns foo-bar.baz) (defrecord Foo) in one project, I can (import [foo_bar.baz Foo]) in another, even without having aot'ed the lib project, right?

6:51 TEttinger: sm0ke: Wat and Kernel have first class everything. they're also dog slow

6:53 clgv: rurumate: you need to require the namespace otherwise you cant. if you see it working thats due to another namespace requiring that namespace or stale class files which might explode unpredictably in the future

6:54 sm0ke: so you mean according to metadata? or do you just want to inspect the function source expressions?

7:03 rurumate: clgv: I can't get to work reliably, I've even tried without lein

7:04 To demonstrate, I will push more horrible code in a minute here: https://github.com/methylene/class-not-found

7:08 done

7:10 clgv: rurumate: you need to (:require foo-bar.baz) and (:import foo_bar.baz.Foo) - I am not sure if the order makes any difference, you'd have to lookup that in the source. but you are on the safe side if you first require then import

7:11 rurumate: clgv: that's what I'm doing. have a look at https://github.com/methylene/class-not-found/blob/master/src/class_not_found/core.clj

7:12 clgv: rurumate: that should work. but you should use the keyword version in ns

7:12 rurumate: why?

7:12 clojurebot: why is Why

7:13 rurumate: oh why

7:13 clgv: because it is idiomatic to do so and better readable

7:13 where does record-holder.def come from?

7:14 rurumate: hmm, ok, I also noticed that using (gen-class :main true) instead of (:gen-class :main true) fails

7:14 clgv: it's from a lein project in lib

7:15 is it me, or is this on-the-fly compilation thing a bit brittle

7:16 clgv: rurumate: the proper version of your namespace should look like https://www.refheap.com/82895

7:22 rurumate: clgv: ok, will update it in a few secs

7:22 why no :main true in gen-class? is it default?

7:22 clgv: rurumate: the functions require, use and co are mostly for REPL usage

7:22 devurandom: Hello!

7:22 clgv: rurumate: yes

7:23 rurumate: all my namespaces with -main methods only have (:gen-class)

7:23 rurumate: it's pushed

7:23 devurandom: Can someone please point me to the docs for cond-> ? http://clojuredocs.org/search?q=cond-%3E does not give any results.

7:23 rurumate: clgv: can you start a repl?

7:24 clgv: devurandom: there is nothing on this site since cond is clojure 1.5+

7:24 devurandom: clgv: Is there a more up-to-date documentation?

7:24 clgv: $(doc cond->)

7:24 $doc cond->

7:25 hyPiRion: ,(doc cond->)

7:25 clojurebot: "([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression."

7:25 hyPiRion: eventually just

7:25 (doc cond->)

7:25 clojurebot: "([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression."

7:25 clgv: devurandom: do you have an explicite question?

7:25 devurandom: (Light Table has no docs on it, either)

7:25 clgv: hyPiRion: confused it with lazybots "source" ;)

7:26 devurandom: the builtin doc string is echoed by clojurebot above

7:26 hyPiRion: clgv: ah, yeah

7:26 devurandom: Ah, ok. So it is not a general Clojure command?

7:26 And still, Light Table seems to have less docs than clojurebot. :(

7:26 clgv: devurandom: it is. but clojuredocs.org is very much outdated ;)

7:27 devurandom: you get a printed docstring when you evaluate "(doc cond->)" on your repl that works for all functions/macros

7:27 devurandom: And (doc ...) would normally reference clojuredocs.org?

7:27 clgv: no

7:27 devurandom: Or what does "it" refer to in your sentence?

7:27 Sorry, I got confused...

7:28 clgv: devurandom: (doc ...) displays builtin docstrings

7:28 ,(doc map)

7:28 clojurebot: "([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & ...]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."

7:28 clgv: ,(doc cond->)

7:28 clojurebot: "([expr & clauses]); Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression."

7:28 clgv: you'll get the same result on your repl

7:29 devurandom: Weird. I tried to execute (doc cond->) in LightTable via Ctrl+Enter, and get an error message: "Cannot call method 'call' of undefined"

7:29 rurumate: clgv: added another update, is this even a lein problem?

7:29 devurandom: I thought LT would send stuff through the REPL when I press Ctrl+Enter

7:30 clgv: rurumate: what error do you get exactly?

7:30 devurandom: Maybe doc is not defined. Maybe because it is actually cljs and not clojure...?

7:31 ashish_: is there is any way to redifine the function temporary

7:31 is there is any way to redefine the function temporary

7:31 clgv: devurandom: ah maybe you need to (require 'clojure.repl) first. on "lein repl" that is done by the frontend

7:32 rurumate_: clgv: I get some 20 lines of stacktrace when I try a lein repl

7:32 ashish_: is there is any way to redefine the function temporary

7:33 rurumate_: can you start a repl?

7:33 devurandom: It seems cljs works very different from the standard Clojure you refer to. (require) is also not defined.

7:33 clgv: rurumate: no not with the clone repo

7:33 ashish_: is there is any way to redefine the function temporary

7:33 is there is any way to redefine the function temporary

7:33 is there is any way to redefine the function temporary

7:33 devurandom: But anyway, now I know how to get a clojure repl: "lein repl".

7:33 ashish_: please... stop it...

7:34 rurumate_: clgv: fI'll be afk now

7:34 sorry, good, I'll be afk for a while.

7:34 clgv: devurandom: clojure does not load the namespace clojure.repl atuomatically anymore. some dev environments do that automatically some dont

7:34 devurandom: clgv: And regarding your earlier question: No, I do not have an explicit question. I was just seeing this call in example code, and did not know what it does.

7:35 clgv: devurandom: conditional threading similar to ->

7:35 devurandom: Yep, thanks to clojurebot I understood it now :)

7:36 rurumate_: clgv: c u later; here's the actual error: http://pastebin.com/r4bin9Uw

7:36 clgv: devurandom: next time just (require 'clojure.repl) and you can use (doc cond->) on your repl

7:36 devurandom: (I am currently working through the Om tutorial, after I got recommended to use ClojureScript instead of JavaScript to display the data in my simulation.)

7:37 clgv: devurandom: oh so thats quite a headstart ;)

7:37 devurandom: clgv: It seems cljs has no (require) function. Seems the only possibility is to call it from the (ns) definition.

7:37 clgv: devurandom: I always recommend to read one of the books to learn fast

7:37 devurandom: I am currently very far away from any book, I fear. ;) I.e. no easy access to international bookshops.

7:38 clgv: devurandom: when developing cljs you should also have a clojure repl as far as I read (I did not use cljs yet)

7:38 devurandom: there are ebook versions of all recent books

7:39 devurandom: I think cljs implements a subset of clojure, so yes, I would assume I get most of clojure. Will figure it out. :)

7:39 clgv: devurandom: otherwise there are several websites (http://www.braveclojure.com/, http://aphyr.com/tags/Clojure-from-the-ground-up)

7:39 devurandom: clgv: Yes, a PDF might be nice. Any recommendation?

7:39 clgv: Thanks! :)

7:42 clgv: devurandom: "Clojure Programming" or "Programming Clojure (2nd Edition)"

7:43 * beamso seconds the 'clojure programming' recommendation

7:45 ashish_: is there is any way to redefine the function temporary

7:46 i wnt to use a new database for testing how it is possible

7:46 devurandom: clgv: Thanks!

7:47 ashish_: i wnt to use a new database for testing how it is possible so that it does not effects my original dta base

7:48 mpenet: ,(doc with-redefs)

7:48 clojurebot: "([bindings & body]); binding => var-symbol temp-value-expr Temporarily redefines Vars while executing the body. The temp-value-exprs will be evaluated and each resulting value will replace in parallel the root value of its Var. After the body is executed, the root values of all the Vars will be set back to their old values. These temporary changes will be visible in all threads. Useful for mockin...

7:48 the-kenny: ashish_: with-redefs. And you might want to take a look at https://github.com/stuartsierra/component

7:50 ashish_: there is a problem with-redefs i can not call from any function

7:51 <mpenet> <the-kenny> there is a problem with-redefs i can not call from any function

7:51 if i call then it store the value permanently

7:52 the-kenny: how are you calling it?

7:56 ashish_: <the-kenny> i put this in a function (with-redefs [db (fn [] testschema/db-spec)])(db)) and call from any other namespace if i do like this then this function give new value which i stored for temporay every times

7:56 grimmulfr: Ok, this seems to be a wee more active than #clojurescript: I cleaned a project, and now compilation won't make my out

7:56 folder with the required files. Any idea why? I don't get any error,

7:56 but only thing that gets compiled is the actual js file, and not the

7:56 helpers (goog, etc)

7:56 oops, sorry. copied :(

7:57 the-kenny: ashish_: that sounds strange

7:57 grimmulfr: what's :output-dir and :optimizations set to?

7:59 grimmulfr: :output-to "basic-site.js"

7:59 :output-dir "out"

7:59 thing is, it worked. after I cleaned, it won't recreate anymore

8:00 it creates the main js but not the helpers

8:00 well, not helpers, you kanow what I mean. goog :)

8:00 the-kenny: yes, I understand

8:00 grimmulfr: optimizations is none (tried whitespace too)

8:01 the-kenny: ashish_: I don't think `with-redefs' has such a fundamental but. Must be something in your code.

8:01 grimmulfr: never had that happen. No idea, sorry

8:02 grimmulfr: No problem

8:09 mskoud: Anyone know how to insert a background/watermark pdf file into a newly generated pdf using clj-pdf? This does not work: (pdf

8:09 [{}

8:09 [:graphics (PdfReader. (FileInputStream. "background.pdf"))]

8:09 [:phrase "some text"]]

8:09 "testresult.pdf")

8:19 clgv: mskoud: you could search for itext tutorials for that

8:27 mskoud: tried google got only java code, nothing about clj-pdf

9:29 Absolute positioning of text in pdf using clj-pdf?

9:36 pandeiro: is there anywhere the clojure/cljs core.async APIs are documented? the sequence functions analogs particularly

9:36 or does one just use the source?

9:37 voldyman: pandeiro: http://clojure.github.io/core.async/

9:42 pandeiro: is (async/map identity [my-chan]) the cleanest way to just copy a channel?

9:43 BobSchack: pandeiro try using into

9:43 oops I thought you meant seq onto a channel nevermind

9:44 pandeiro: BobSchack: np thanks; i thought i had seen an async/copy somewhere but i don't see it in the API now

9:44 BobSchack: are you looking to split a channel into multiple channels?

9:45 pandeiro: BobSchack: no i just want a copy of the channel so i can debug without consuming the actual original channel

9:46 maybe (tap (mult my-chan) (chan)) is what i am after

9:48 BobSchack: I think that still consumes the original channel it just allow you to split the original channel into multiple channels (ala fan out)

9:49 pandeiro: yeah, not what i wanted... i will just try map

9:51 hm, that also doesn't work

9:52 BobSchack: You want get the data on the channel for debugging and not have actual work happen in the meantime right?

9:53 pandeiro: BobSchack: exactly

9:56 BobSchack: okay I don't think you'll be able to do that directly. I have to head out for a meeting but if you ask your question later some of the core.async devs should be around.

9:56 pandeiro: BobSchack: yeah i am thinking it isn't possible; my bad

9:56 BobSchack: also the clojure mailing list is a good place to ask

10:07 arrdem: you're quite likely to get an answer there at any rate, it has a somewhat larger reach than this channel.

11:00 jcromartie: I'm trying to figure out the best way to version our Clojure application

11:01 we have regular sprints (2 weeks) and at the end of that sprint we deploy to an alpha environment, and then that build eventually gets promoted to a beta environment, and then eventually to production

11:02 but keeping track of things across project.clj, tags, the develop and master branches, etc. is getting hairy

11:03 TimMc: jcromartie: You might keep separate branches for alpha, beta, and master (production).

11:03 jcromartie: that's kind of what I was thinking

11:03 TimMc: and make sure that every merge to alpha updates a CHANGES.txt file as appropriate.

11:03 arrdem: $google git flow

11:03 lazybot: [A successful Git branching model » nvie.com] http://nvie.com/posts/a-successful-git-branching-model/

11:04 TimMc: The one thing about this that worries me is not easily knowing which changes have been merged to which branches.

11:04 arrdem: ^ the above is essentially that sort of branching model, using only one layer of dev builds.

11:05 jcromartie: what's the point of CHANGES.txt

11:05 TimMc: At work we often just develop against master, but then it's sometimes not clear what features and bugfixes are new since last release.

11:05 jcromartie: why not just git log master..alpha

11:05 TimMc: jcromartie: ^ see last statement

11:05 arrdem: an alternative, and what we did at Calxeda, is that each commit starts with the ticket number and only "full patch" commits make it into the alpha/beta/dev branches.

11:06 so it's easy to do `git log` and the first token on each line is the name of the ticket patched by that commit

11:06 jcromartie: yeah we do that

11:07 arrdem: but yeah maintaining a CHANGES.txt that tracks all the fixes since last "release" is a good idea, abet an overhead you can probably incur when snapshotting out a "final" alpha/beta/dev tag

11:07 rather than having all devs patch it all the time, which makes merges messy.

11:07 jcromartie: I don't see the point in a change file vs a good commit log

11:07 arrdem: jcromartie: it's just a summary that the person who does the release puts together for user convenience.

11:07 jcromartie: ok

11:08 you could also have lines in your git commits like "CHANGELOG …" that would help create that file automatically

11:08 well anyway

11:08 I like the idea of a change file for users

11:08 but if we have three major environments, having three branches makes sense

11:09 much easier than saying "uh, what's on what server now?"

11:09 and then "let me go check the hash on the release folder"

11:10 arrdem: pffft "what's the hash on the server", I "fixed" the build system so that we had the hash in our firmware builds -_- "what hash is running on the exhibiting hardware"

11:10 better bust out the FRU reader and find out...

11:11 jcromartie: :P

11:20 TimMc: Git log is not enough for a changelog.

11:20 For instance, lets say you need to revert some merged commits. They still show as merged, they're in the history -- but at least the changelog has been reverted.

11:21 It's also different in terms of what it says. A feature may be implemented in the course of three different merges; you might not list debugging commits in the log; doc changes don't need changelog entries...

11:22 And the merge conflicts for appending stuff to a log are pretty minimal. If you use a good mergetool like meld, it's a few extra seconds and that's it.

11:28 hyPiRion: TimMc: should be pretty minimal regardless of merge tools

11:38 jcromartie: what are my options for no-downtime deployments of a Ring app?

11:40 clgv: jcromartie: a wrapper in front of the real app to be able to exchange the implementation on the fly?

11:40 mpenet: nginx reverse proxy on 2 instances of the app

11:42 jcromartie: yeah

11:42 mpenet: via http://nginx.org/en/docs/http/ngx_http_upstream_module.html, I think there's an example in the clojars-web repo

11:42 jcromartie: so how do you handle the swap?

11:42 ah great

11:43 I'll read into this

11:43 mpenet: it's described here: https://github.com/ato/clojars-web/blob/46a6525ab9984e6bedb163c4ea14d2a6bac3c6b0/SYSADMIN.md

11:45 this goes into the details of the process http://p.hagelb.org/clojars-deploy

11:51 myguidingstar: hi all, what is `:provided` profile in leiningen for?

11:54 ispolin: jcromartie: Roomkey had a presentation at this year’s Clojure/West about their deployment strategy. Be wraned, it’s pretty involved: https://www.youtube.com/watch?v=vFX6T5oQC7Y#t=1250

11:54 jcromartie: maybe it's designed for dependencies that are already available locally to the project or something?

11:54 cool thanks

11:57 nz: myguidingstar: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

12:00 ispolin: jcromartie: TLDR: Roomkey spins up a new instance of their app, then cut over first the DB(as in old app is using new db instance), and then the traffic via DNS updates

12:00 myguidingstar: nz, thanks

12:01 jcromartie: yeah that seems pretty heavy duty

12:01 we'd like to do it on the same host

12:01 nginx might be the answer

12:09 are there any advantages to using "java -Dfoo=bar …" over an environment variable?

12:09 I am thinking no

12:10 especially considering how env vars work no matter how you run it (via lein or an uberjar or whatever)

12:11 technomancy: jcromartie: the only difference afaik is you can change system properties at runtime

12:12 can be nice during development

12:12 nullptr: i like that it's explicit, envs can be a bit wonky (shell env differs from system env, for example)

12:14 johnjelinek: hihi all

12:14 how's it goin'?

12:14 how do I put an anonymous function in a (->?

12:15 example: (-> (http/client {:port 443 :host base-uri :ssl true}) (http/post authorize-uri access-token-handler) (fn [x] (println x) x) (http/end (authorize-body code apikey redirect-uri apisecret)))

12:16 but (fn [x] (println x) x) is an error

12:16 I want to just analyze the output as it goes through there

12:17 gfredericks: you can do an anon fn with an extra pair of parens around the fn; but your specific use case is easier done with (doto (println))

12:17 clgv: johnjelinek: don't. if you really want to use two levels of parentheses ((fn [x] ...))

12:18 johnjelinek: the 2nd pair of parens will execute the anon fn?

12:18 clgv: yes

12:18 gfredericks: ,(macroexpand-1 '(-> x (fn [y] (z y)))

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

12:18 gfredericks: ,(macroexpand-1 '(-> x (fn [y] (z y))))

12:18 clojurebot: (fn x [y] (z y))

12:18 gfredericks: ,(macroexpand-1 '(-> x ((fn [y] (z y)))))

12:18 clojurebot: ((fn [y] (z y)) x)

12:18 gfredericks: johnjelinek: ^ compare those two

12:19 clgv: ,(require 'clojure.data)

12:19 clojurebot: nil

12:19 clgv: ,(clojure.data/diff (macroexpand-1 '(-> x (fn [y] (z y)))) (macroexpand-1 '(-> x ((fn [y] (z y))))))

12:19 clojurebot: [[fn nil [y] (z y)] [(fn [y] (z y))] [nil x]]

12:20 johnjelinek: I see the diff, it makes sense (I don't know how to read the data/diff though)

12:20 gfredericks: I don't think the data/diff is a helpful approach for understanding

12:20 clgv: I was just curious to see whether it helps. but it does not here ;)

12:21 johnjelinek: doto does work though :)

12:21 thanks!

12:22 gfredericks: np

12:22 clgv: ah lol you want print+return^^

12:22 johnjelinek: bingo

12:22 so I can keep on going down the (->

12:22 clgv: did miss the "x" due to line wrapp^^

12:23 johnjelinek: that might be interesting for you https://github.com/dgrnbrg/spyscope

12:25 johnjelinek: interesting

12:25 thanks

12:27 coventry: johnjelinek: Use clojure.tools.trace/trace

12:28 clgv: coventry: how'd that help in the threading macro?

12:41 coventry: clgv: With one argument, it does exactly what johnjelinek wanted: (require '[clojure.tools.trace :as ctt]) (-> 1 inc ctt/trace inc) prints out "TRACE: 2".

12:41 johnjelinek: cool

12:57 tcrawley: you around?

12:58 what format do I pass headers into http/get-now?

12:58 it's requesting a multi-map

12:58 erm, expecting*

12:58 can i not just pass in a vector of k/v pairs?

13:01 jcidaho: Hi. I've got a weird behavour with pr-str. Sometimes when I do (spit f (prn-str {:a "ho"})) f contains {:a ho} as oppose to {:a "ho"}

13:01 when I try to reproduce from the REPL the quoted version is put in the file, but at other times in the code it's the unquoted form

13:13 nevermind, some lazyiness * weirdness

13:18 coventry: Are you actually doing a map literal in the prn-str? I would do something like (def dbg (atom nil)) prior to the suspected code, then (reset! dbg printed-object) (read-string (prn-str printed-object)) to trigger an exception, and inspect @dbg in the repl.

13:30 justin_smith: coventry: another trick is (def dbg (atom {})) ... (defn problematic-function [args] (swap! dbg assoc (java.util.Date.) args)) ...

13:31 time indexed tracing to introspect from the repl

13:34 cbp: (inc justin_smith)

13:34 lazybot: ⇒ 38

13:35 justin_smith: a macro variation of let that returned {:val (what let returned) :bindings {:key-of-binding val ...} would be cool for debugging

13:36 maybe there is some internal that already gets this for a let?

13:43 amalloy: justin_smith: i don't quite understand what that would look like

13:46 johnjelinek: got a question about higher order functions

13:46 justin_smith: amalloy: I tried to type out what I had in mind but it looks clumsy

13:46 poorly thought out at the moment, sorry

13:46 amalloy: johnjelinek: you're in luck! HOFs are the answer to all questions!

13:46 johnjelinek: can I pass a function to a function and then return the result of that function in the parent function?

13:47 here, maybe a refheap will help

13:48 sm0ke: ,((fn [f] (let [r (f)] (inc r))) (partial inc 2))

13:48 clojurebot: 4

13:48 dbasch: johnjelinek: yes

13:48 johnjelinek: not-fully thought out example: https://www.refheap.com/82957

13:49 justin_smith: johnjelinek: yeah, we do stuff like that all the time

13:49 sm0ke: sure can be done, functions are first class values

13:49 johnjelinek: I either want to treat the hof like a callback or take the stuff that executes in the (fn [response ...) and return that at the end of the function

13:49 sm0ke: except when you pass then around wire

13:49 justin_smith: johnjelinek: passing in some function that may be conditionally used especially

13:50 sm0ke: to be fair, only the edn subset of clojure is first class

13:50 sm0ke: yes

13:50 johnjelinek: so, what do you recommend my my scenario?

13:50 justin_smith: sm0ke: java objects that are not edn don't pass over the wire either

13:50 sm0ke: functions are not serializable, so they are not first class imo

13:50 truly*

13:51 johnjelinek: maybe I could just inline the result instead of calling the hof, that way it would return the data at the end

13:51 I'm just not sure how to extract the data from the inner fn

13:51 justin_smith: sm0ke: as was mentioned above, the problem is closures, they are tricky things to serialize, and they are extremely important to deciding what a function actually means

13:51 johnjelinek: does my scenario make sense?

13:51 amalloy: johnjelinek: http/get is asynchronous, yes?

13:52 johnjelinek: amalloy: yes

13:52 llasram: sm0ke: Well, functions aren't *data*, but that doesn't mean they aren't first-class

13:52 johnjelinek: http/get has a handler fn as 3rd arity

13:52 amalloy: so this function, request-data, is actually returning long before the get is finished, so thus before your lambda is even called

13:52 johnjelinek: and so that gets executed upon completion

13:52 grimmulfr: Can't be this hard to use clojurescript :(. I'm going nuts here. It feels like everything's alpha

13:53 sm0ke: llasram: how did you solve the function passing for live development for parkour?

13:53 amalloy: you're sure you want to take this async function and force it to be synchronous? there's probably a better synchronous primitive if that's the behavior you want

13:53 grimmulfr: I seem to be doing everything ok, compuiles once, compiles the second time but ohly half the files, no error, yet nothign works

13:53 justin_smith: grimmulfr: much of clojurescript is very new

13:53 grimmulfr: but it worked :(

13:53 I have a project that works, and one that doesn't. same settings

13:53 johnjelinek: amalloy: I'm not entirely sure ... ultimately, what I'd like to do is pass in a token, a uri for data to fetch, and then pass it to a go-block

13:54 then whenever events in a channel are received broadcast to stuff

13:54 dbasch: grimmulfr: maybe you have stale js? have you done a clean?

13:54 sm0ke: cascalog has something weird, which i saw today, it serializes a function which is closure over locals!

13:54 johnjelinek: where the data being broadcast is the response from polling from request-data

13:54 sm0ke: pretty hip stuff

13:54 grimmulfr: done all sorts of clean. even started a new project and then manually added everything

13:54 johnjelinek: amalloy: make sense?

13:54 grimmulfr: compiles the js, but not the goog files which I got when I first did it

13:54 amalloy: johnjelinek: you don't actually care what this function returns at all, then. you just want it to have a (go ...) in the on-body

13:54 grimmulfr: now it compiled goog/base.js, but not deps.js

13:55 amalloy: add a channel parameter to the function request-data, and in on-body, write to it with >!

13:55 grimmulfr: No error either, which is even more anoying

13:55 justin_smith: sm0ke: what happens when a different vm tries to access the function, but the locals are from a library that the other vm does not have in the classpath?

13:55 grimmulfr: All the examples that I find use ring but I don't want a local server, I just want a html that loads my app.js :-<

13:55 amalloy: or pass it a function that contains a (go ... (>! ...)), whatever

13:55 justin_smith: sm0ke: or does it encapsulate every library closed over in the function?

13:55 johnjelinek: amalloy: yes, I want to have a go on the on-body, but I wanted to make request-data a little more generic

13:56 hrm ... maybe I don't need it to be more generic

13:56 justin_smith: sm0ke: that seems like it would be huge

13:56 sm0ke: justin_smith: lets just assume all libraries are present everywhere

13:56 johnjelinek: I was thinking about wrapping request-data in a go-block rather than having the go-block for on-body

13:56 dbasch: grimmulfr: not a problem, just navigate to the html page that ring would serve (or create one)

13:56 johnjelinek: but the on-body go-block prolly makes more sense

13:56 justin_smith: sm0ke: that's a really weird assumption

13:56 sm0ke: justin_smith: thats pretty normal for a distributed system

13:57 johnjelinek: amalloy: I'll try out some of your suggestions

13:57 thanks

13:59 justin_smith: sm0ke: given assurance that deserialization will happen in an environment that has identical bindings that are visible at the site of serialization, that is kind of cool. But if all code is visible at all hosts, why is the serialized function needed, couldn't you just send the ns and var name and let the other host resolve it?

13:59 bizniz98: Getting "Exception in thread "main" Wrong number of args (3) passed to: PersistentHashMap". There's something fundamental here I'm not getting...

13:59 amalloy: bizniz98: too many parens

13:59 llasram: justin_smith, sm0ke: Since it's specifically for cascalog, it can make the assumption the same libraries are available where the function will be serialized, because the job driver makes it so be

13:59 sm0ke: justin_smith: yes true, but what if i want to create function on the fly?

14:00 amalloy: you have ((x y) a b c) instead of something like (do (x y) a b c)

14:00 llasram: I'm still not a big fan of the approach as a general solution to delivering Clojure code to distributed systems though

14:00 justin_smith: llasram: ahh, OK. There is a larger defined system making those guarantees, that makes sense

14:01 sm0ke: https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/clj/cascalog/logic/fn.clj

14:02 bizniz98: amalloy: Thanks! That was it. I went the do route but still wound up with an extra set of parens!

14:02 sm0ke: though it requires you to use its own `fn` macro

14:04 Did anyone had some insights into how spark framework works, it seems to serialize anonymous functions with closures over local

14:04 i doubt if scala provides that oob

14:04 amalloy: huh. does the epl allow cascalog to borrow from technomancy/serializable-fn without attribution and not under epl?

14:04 sm0ke: :P

14:06 technomancy: amalloy: no attribution is fine, but you can't take someone else's code and change the license ever.

14:06 assuming it's above the copyright threshold

14:07 sm0ke: hmm then its a problem ? its Apache

14:08 amalloy: technomancy: i mean, https://github.com/technomancy/serializable-fn/blob/master/src/serializable/fn.clj and https://github.com/nathanmarz/cascalog/blob/develop/cascalog-core/src/clj/cascalog/logic/fn.clj#L6 clearly have a common ancestor, although they're far from identical

14:08 technomancy: haha; they kept the docstring

14:08 sm0ke: yes seems like nathanmarz/serializable-fn was pulled into cascalog

14:08 amalloy: i know, right?

14:09 sm0ke: which is fork of technomancy/serializable-fn

14:09 technomancy: yeah, that's not legal

14:09 sm0ke: i think technomancy is cool with it?

14:09 or is he? :D

14:09 technomancy: sm0ke: I would be happy to relicense it if they asked

14:10 amalloy: technomancy: when you make millions of dollars suing them, i'll take 25% for noticing the infringement, and 33% for contributing lots of the code

14:10 technomancy: sm0ke: I'm not cool with ignoring copyright law

14:10 sm0ke: yes just remeber me for bringing this

14:10 koalallama: technomancy: let me know if you need legal representation. I can find you a lawyer on google

14:10 technomancy: such a helpful bunch

14:11 sm0ke: lol

14:13 hyPiRion: technomancy: just file an issue

14:13 I guess you knew that already though

14:14 koalallama: hyPiRion: is that what Oracle told Google? Just file an issue?

14:14 cbp: with the copyright office amirite

14:15 mdrogali`: lol

14:16 sm0ke: tbh, i think its ok, doesnt a community thrives on adapting good code from each other?

14:17 although an attribution would have been good

14:17 technomancy: sm0ke: it's not about attribution, it's about following the law

14:18 justin_smith: sm0ke: and communities get screwed over by code getting relicensed or closed up (see gosmacs and the origins of the fsf / gnu project)

14:21 technomancy: https://github.com/nathanmarz/cascalog/issues/249

14:21 amalloy: technomancy: edit to include links to both files?

14:22 technomancy: good call

14:24 sm0ke: hurm wow

14:25 hiredman: ugh

14:25 johnjelinek: amalloy: I'm starting to think I'd like the data to return at the end of my request-data fn

14:25 sm0ke: i dont see how they will fix that without chaning license

14:25 johnjelinek: maybe I'm not thinking about it right

14:25 hiredman: the # thing in the code comments is due to print-length and print-level being bound

14:25 amalloy: sm0ke: well, asking technomancy nicely to offer them another license, as he said earlier he would happily do

14:25 hiredman: someone should open an issue with cascalog about that too

14:26 johnjelinek: maybe I'm thinking about it too synchronously

14:26 hiredman: maybe I will

14:28 grimmulfr: note to self, cljs compiles cljs files, not clj.

14:28 ffs

14:29 I had everything inside my source as a clj, trying to compile to cljs, and a bunch of other stuff mixed in

14:29 nullptr: grimmulfr: been there :)

14:29 hyPiRion: amalloy: or perhaps license that particular part of the project as EPL? I'm not sure if that's even possible though.

14:30 amalloy: perhaps. i can barely even spell lawyer, so i'm not going to speculate

14:30 llasram: hyPiRion: IANAL, but the Apache guidelines allow including EPL code as long as the code is in it's own file and notices etc clearly indicate that file is EPLed

14:31 I actually pulled+modified the Clojure EdnReader into Parkour recently and had to figure out what seemed to be the best approach

14:32 https://www.apache.org/legal/resolved.html#category-b

14:32 hyPiRion: llasram: I wish there were a website with examples on how to handle such things

14:32 were/was, I no English

14:32 l1x: technomancy: why is it a license violation?

14:33 because he does not display the source of the code?

14:33 amalloy: hyPiRion: you had it right: were

14:33 technomancy: l1x: because he took something he didn't write that was EPL-licensed and just proclaimed that it was apache-licensed

14:33 justin_smith: l1x: he is changing the license terms

14:33 l1x: oh i see

14:33 interesting

14:34 llasram: I hereby declare this bacon to be Vegetarian and Kosher!

14:34 hyPiRion: amalloy: thanks for confirming

14:34 technomancy: hyPiRion: most native english speakers don't follow the "correct" usage there anyway =)

14:34 l1x: technomancy: what would be the correct action in this case? license the software under EPL?

14:35 amalloy: well, i think it's simpler than that: EPL says that you can include EPL source into your own programs iff you license it as EPL and don't remove any copyright notices

14:35 technomancy: l1x: yes, or ask for the code to be dual-licensed

14:35 l1x: i see

14:35 thank you guys

14:36 amalloy: i bet in a decade or two, "was" will be acceptable over "were" there. english doesn't really have much of a subjunctive anyway

14:36 i mean, already it's "acceptable", i guess

14:36 llasram: amalloy, hyPiRion: I definitely wouldn't blink at either

14:36 technomancy: at this point it's like who/whom

14:36 amalloy: technomancy: you mean that snobby people use the wrong one so that they can sound educated?

14:37 technomancy: heh

14:37 amalloy: llasram: yeah, i wouldn't say anything unless asked to proofread

14:37 l1x: so what happens when I use an example code from a clojure project? like i use tools.cli https://github.com/clojure/tools.cli and I use the example displyed there

14:37 hyPiRion: If people already use it wrongly, then that would explain why I am confused

14:38 technomancy: l1x: there's something called the "threshold of copyright" meaning that trivial expressions can't be copyrighted

14:38 arrdem: technomancy: because that holds so strongly in the software domain...

14:38 * arrdem rolls his eyes

14:39 l1x: but if i want to be sure that nobody sues my ass i better license my code under EPL just because i used the example from tools.cli ?

14:39 technomancy: you need to display some modicum of creative effort to claim copyright

14:40 no, license your code under the EPL because it's a good license =)

14:40 justin_smith: also I think that things used as documentation as examples are assumed to provide permission to reuse and modify

14:40 joegallo: http://en.wikipedia.org/wiki/Subjunctive_mood#English study up, there'll be a test later

14:41 l1x: justin_smith: i hope so

14:41 technomancy: what is the difference between EPL vs APL v2

14:41 my understanding was that APLv2 is good because you have to give up your IPs

14:41 arrdem: ,(number? 2/3)

14:41 clojurebot: true

14:42 arrdem: ,(type 2/3)

14:42 clojurebot: clojure.lang.Ratio

14:42 technomancy: l1x: the main differences are that EPL is copyleft and APL makes you put a bunch of boilerplate junk in every file

14:42 l1x: "give up your IPs" doesn't really mean anything

14:42 unless you're talking about a DHCP lease

14:42 llasram: technomancy: I don't think the Apache license requires that. I think the Apache foundation just requires that

14:43 amalloy: dangit, technomancy beats me to the punch on an IPv4 joke

14:43 sm0ke: lol

14:43 technomancy: llasram: oh, gotcha

14:43 kenrestivo: i didn't really consider EPL copyleft

14:43 technomancy: kenrestivo: it's weak copyleft like the LGPL

14:44 arrdem: the EPL is so weakly copyleft that the FSF rips on it :P

14:44 amalloy: it's a less aggressive copyleft than GPL for sure

14:44 l1x: technomancy: right i was referring to copyleft

14:44 technomancy: except it doesn't have "GPL" in the name, so it doesn't freak out the suits

14:44 l1x: so afaik both EPL and APL are copylefty

14:44 technomancy: IIRC the main difference between the LGPL and the EPL is the latter has slightly stronger patent protection provisions

14:44 l1x: https://tldrlegal.com/license/apache-license-2.0-(apache-2.0) https://tldrlegal.com/license/eclipse-public-license-1.0-(epl-1.0)

14:44 technomancy: l1x: no, APL is more permissive

14:47 l1x: i see

14:47 devn: (defn third [coll] (nth coll 3)) (defn thirst [coll] (third (first coll))) (defn thirsty? [coll] (boolean (first coll)))

14:47 good times.

14:47 sm0ke: Welcome to #licensing! For more info visit http://licensing.com/

14:48 technomancy: maybe Licenser would have some advice

14:48 l1x: well, sorry but it is relevant to this channel :)

14:49 arrdem: sm0ke: well that's not what I expected...

14:49 sm0ke: you had a problem, and tried to use license, now you have two law suits

14:49 arrdem: (inc sm0ke)

14:49 lazybot: ⇒ 6

14:49 arrdem: bloody suits... c&ding me for my fan programming projects..

14:50 l1x: i have to think twice to opensource any code it seems

14:50 jcromartie: arrdem: which one would that be?

14:51 technomancy: l1x: it's a lot less complicated if everyone sticks with the same license

14:51 arrdem: jcromartie: one that's no longer public at the request of Privateer Press.

14:51 l1x: technomancy: yes but my company approved only APLv2

14:52 technomancy: oh, that's crappy =\

14:52 but as long as you don't copy/paste you should be ok

14:52 devn: what is the dyson bladeless fan of programming languages?

14:52 kenrestivo: arrdem: Elsevier?

14:53 arrdem: kenrestivo: huh? no...

14:54 dbasch: Prismatic’s fnhouse looks promising, but I can’t find a good sample app. It comes with an extremely basic one (guesthouse) that’s not very well documented.

15:02 Licenser: technomancy don't use GPL ;)

15:05 johnjelinek: question: at what point do you look at your functions and say, "I need to refactor this"

15:05 or "this is too gross to look at"?

15:06 justin_smith: johnjelinek: it is time to refactor when I look at the code and don't have any idea what I was trying to do

15:06 johnjelinek: justin_smith: lol, only then?

15:06 justin_smith: often I am forced to notice this when a bug is lost in the logic somewhere

15:07 johnjelinek: isn't it too late when you've come to that point?

15:07 justin_smith: johnjelinek: that's not the only time I refactor

15:07 johnjelinek: when is the earliest you refactor?

15:07 justin_smith: when a function is more than 7 lines long

15:08 (I just made that number up, it's a hunch I get as functions get longer)

15:09 johnjelinek: lol

15:09 real scientific, I see ;)

15:10 justin_smith: also if I see I am repeating myself

15:10 technomancy: I have an emacs mode that forces you to stop typing if your function is over 25 linees

15:11 TimMc: Oh, like Eclipse + PMD.

15:11 except it only tells you when you try to build

15:12 Actually, no, it's not at all the same.

15:15 kenrestivo: technomancy: link?

15:16 technomancy: https://github.com/technomancy/dotfiles/blob/master/.emacs.d/phil/programming.el#L30

15:18 cbp: that is horrible

15:18 johnjelinek: lololol

15:18 why?

15:18 clojurebot: why is the ram gone

15:18 justin_smith: cbp: no, horrible would be a timer where it lets the code sit there for 30 seconds and then comes back and deletes it

15:19 technomancy: calling it a mode may be a bit generous

15:19 pjstadig: just turn it into a oneliner...done!

15:20 cbp: I bet he has another where it stops you from going past 80 column lines so it fits into his terminal

15:20 pjstadig: hmm

15:20 good point

15:20 justin_smith: how about a cookiecutter function, cuts off anything to the right of 8 columns, and anything below 26 lines

15:20 if it can't fit on an old school terminal window, it shouldn't exist

15:20 *80

15:21 johnjelinek: technomancy: do lets go into your line count?

15:22 technomancy: johnjelinek: yeah, it's not picky

15:22 pjstadig: TBH, if you're counting lines in a lisp you're doing it wrong

15:23 dbasch: you could end up with abominations like this, to fit in 25 lines: https://gist.github.com/dbasch/6923514

15:27 grimmulfr: What would be an "official" way of getting json requests from within clojure/clojurescript? clj-http?

15:28 justin_smith: grimmulfr: in clojurescript, probably just use interop / AJAX

15:28 dbasch: grimmulfr: from cljs, cljs-ajax

15:28 grimmulfr: Cheers, will look into those.

15:29 justin_smith: slurp will work for get requests, clj-http if you need anything fancy

15:29 also there is http.async.client for async requests if you need that

15:32 grimmulfr: I just need a way to get JSON formatted data from my backends into my code so I can interpret, so anything will probably do I guess, as long as it;s not overkill to implement.

15:33 Just your average "send details" and interpret response. Forms and whatnot

15:33 kenrestivo: grimmulfr: i use (require '[cheshire.core :as json]) (-> "http://something.com/foo" slurp (json/decode true))

15:33 ain't no official tho, just expedient

15:35 justin_smith: kenrestivo: yeah, if you don't need to do the request async, or make a post request or query parameters, that's the right way as far as I am concerned

15:39 grimmulfr: Ok, will look into all of those. Cheers

16:08 technomancy: amalloy, hiredman: you two are ok with APL-ing serializable-fn, right?

16:10 mpenet: anyone knows if c.c.typed can annotate defmethod ?

16:10 hiredman: technomancy: sure

16:10 mpenet: defmulti yes, but I can't find an example for defmethod

16:25 technomancy: heh, cascalog claims to be EPL'd in some places and Apache'd in others

16:26 gfredericks: mpenet I think the idea might be that you only need to do the defmulti?

16:26 and all the defmethods have the same type

16:26 otherwise it would be difficult to determine the type of a call

16:29 blake__: Hey, if I have "(defmacro whatever [parm] code code code...)" immediately followed by "(defmacro whatever [parm] parm)" am I correct to assume that the second defmacro overwrites the first?

16:29 And that this might be done to deliberately stub out the first (potentially expensive or disruptive) call without breaking code?

16:29 justin_smith: blake__: I think it is done so that you can have proper recursion

16:30 or maybe not with macros actually...

16:30 blake__: justin_smith: How would that be even if they were functions? Since the second one does nothing but return the passed value?

16:31 justin_smith: blake__: it does it so that the recursion would be possible

16:31 even though clearly you did not use that facility

16:32 blake__: justin_smith: I don't get it.

16:34 justin_smith: blake__: it has to have its own symbol resolvable within its body

16:34 in case you wanted recursion

16:36 blake__: justin_smith: OK, but in this case, is it reasonable to assume the second macro exists to stub out the first? (It's not my code, and the first macro looks to be for profiling.)

16:37 technomancy: amalloy: ping

16:38 ToxicFrog: <violets> https://www.youtube.com/watch?v=qE9Pn0eBK https://www.youtube.com/watch?v=v3cZbQaqYN4 https://www.youtube.com/watch?v=qE9Pn0eBKRA

16:38 Er

16:38 justin_smith: blake__: I really don't know, the second macro, if both are in the same ns, totally replaces the first

16:38 ToxicFrog: Mischan, disregard.

16:39 justin_smith: I would take that as a smell indicating a poorly maintained codebase

16:39 blake__: justin_smith: OK, thanks.

16:45 amalloy: technomancy: i'm back! i was suffering from a linode outage

16:45 technomancy: amalloy: my condolances

16:45 amalloy: just thought I'd confirm you're OK with the dual-licensing of serializable-fn

16:45 amalloy: yeah, feel free

16:46 technomancy: cool

16:46 amalloy: i was wondering whether you needed my consent or not

16:47 technomancy: if it were just a matter of me giving the thumbs up then I'd feel kinda silly opening an issue with them

16:47 amalloy: eh, i dunno. it's still useful to remind them that copyright matters

16:47 technomancy: "there is a problem. please ask me to re-license some software in order to fix it." / "will you re-license it?" / "ok" / "well then"

16:48 I know, but it's good to do it in a way that doesn't make you sound like a pedant

16:48 even if you are one

16:48 closed https://github.com/nathanmarz/cascalog/issues/249

16:48 gtrak: technomancy: my attempt at structure, let's see what happens :-) https://github.com/clojure-emacs/cider/issues/546

16:48 justin_smith: technomancy: I see it more like "this is my request that you demonstrate that you know how to ask nicely"

16:49 which is reasonable, and doesn't need to involve pedantry

16:49 just respect

16:49 technomancy: justin_smith: it's easier to justify the request if it involves coordinating among multiple people, but yeah.

16:50 it becomes "would you like me to help you with your problem" instead of "I'm causing your problem" =)

16:50 amalloy: well, there goes my chance at patent-troll millions

16:50 technomancy: gtrak: cool; hope that goes well

16:52 justin_smith: gtrak: if that is accepted, I may even try cider. I check it out occassionally but I see scary visions of a hairy yak that threatens to steal days of my productivity. A stable release would help.

16:53 gtrak: justin_smith: yea, I hate the emacs way of doing things :-). cider needs that.

16:54 I learn things in emacs by accident.

16:54 technomancy: emacs is drawing you deeper into its gravity well

16:56 gtrak: Don't worry, I'm a pretty hateful person.

16:56 but maybe that's why it works.. sigh.

16:57 technomancy: http://its.a.trap.jpg.to

16:58 gtrak: just yesterday I accidently typed M-s o in a C-s search and was flabbergasted at the utility.

16:59 technomancy: 3>

16:59 gtrak: occur-mode

16:59 justin_smith: gtrak: cool, I use occur because it is very handy, but did not know about the m-s o binding

17:00 also m-x rgrep if you want something similar, but based on a subtree of your fs

17:00 gtrak: been using ack-and-a-half for that

17:00 justin_smith: gtrak: is that package thing?

17:00 gtrak: yea, it's a UI over ack, which is like a grep made for code.

17:01 technomancy: M-x rgrep is nice, but rgrep from eshell is nicer

17:01 justin_smith: ahh cool, so I assume it ends up with a clickable reference buffer like occur / rgrep do

17:01 gtrak: justin_smith: yes

17:01 justin_smith: awesome

17:01 gtrak: what's great about ack is it just looks nicer than grep with no effort on your part

17:01 use it the same way

17:01 justin_smith: technomancy: thanks for the hint

17:02 technomancy: justin_smith: but without the promptfest

17:02 nullptr: grep, ack, ag, and now pt -- https://github.com/monochromegane/the_platinum_searcher

17:02 and all four have emacs packages

17:02 justin_smith: technomancy: hmm, rgrep from eshell does not give me clickables

17:03 technomancy: justin_smith: weird!

17:03 gtrak: nullptr: I read that as 'all have four emacs packages', which is true for ack.

17:03 nullptr: heh

17:03 justin_smith: technomancy: probably a config or version thing

17:04 (that was a low information statement)

17:04 technomancy: justin_smith: oh yeah crap. I forget if I submitted this back upstream: https://github.com/technomancy/dotfiles/blob/master/.emacs.d/phil/my-eshell.el#L6

17:09 coventry: Is there a command-line rgrep for OS X?

17:09 justin_smith: the above ack / ag / pt are all osx I think

17:10 and of course grep -R

17:10 Raynes: <3 ack

17:11 justin_smith: with vanilla grep, -r does not follow symbolic links, -R does

17:11 though of course you probably want egrep not grep

17:11 dbasch: you can always combine find and grep to save time

17:11 justin_smith: grep is how it is for posix reasons

17:12 dbasch: is it faster because you can tell it which files to search for matches in?

17:12 dbasch: justin_smith: right

17:12 e.g. find . -name \*.clj -exec grep main {} \;

17:12 justin_smith: M-x rgrep does that (it prompts for a regex for the files to check for matches in)

17:30 mercwithamouth: so clojure experts and people generally smarter than me... for the last few days i've been looking over this article about using friend and liberator together and i'll admit it's still overwhelming. http://sritchie.github.io/2014/01/17/api-authentication-with-liberator-and-friend/

17:30 I'm wondering...is this approach absolutely necessary? do you have to tie the two libraries together in order to use both liberator and friend?

17:31 egghead: nope mercwithamouth

17:31 justin_smith: mercwithamouth: well, security only makes sense if you have a clean division of "inside" and "outside" - if anything liberator does crosses the inside/outside boundary, then they have to be integrated

17:32 egghead: you can just use friend over your route definitions

17:32 instead of deep integrating with liberator

17:32 justin_smith: ahh, good point egghead yeah

17:32 (that's still a kind of integration :P)

17:32 egghead: but the integration is w/ compojure instead of liberator :)

17:32 and liberator happens to integrate very nicely w/ compojure too :x

17:32 justin_smith: fair enough

17:33 egghead: I hit that same wall w/ friend + liberator

17:33 mercwithamouth: hmm

17:33 egghead: you wouldn't happen to have any public code would you?

17:33 egghead: sure mercwithamouth

17:34 justin_smith: https://github.com/hiredman/ideapad/blob/master/src/com/thelastcitadel/ideapad.clj this is a friend example that hiredman shared

17:34 egghead: mercwithamouth: https://github.com/eggsby/warden/blob/master/src/clj/warden/api.clj#L117-L152

17:34 nothing fancy

17:35 mercwithamouth: sweet! thanks

17:36 egghead: the simpler the better...i can build up from there once i get more comfortable

17:36 egghead: ya, that example is just basic http auth

17:37 and no roles, just either you are authed or not

17:37 the one justin_smith linked is a lot more in-depth

17:41 mercwithamouth: egghead: yeah yours is clear...i should be able to pick up on most of what i think i'll need from these two examples

17:42 lol it's clear that i have a long way to go with understanding lisp...

17:53 dnolen_: wow, 9 GSoC Clojure projects?

17:56 justin_smith: very impressive

18:11 d0ky: hello does enybody know how to post data with goog.net.Xhrio ? im trying to post vector of string or string .. depend on situatuions .. and i receive only something like params {:v nullo=null} how send all data like ["viktor" "one"] i tried (pr-str data) but it didn't work ..

18:13 hiredman: d0ky: https://github.com/hiredman/drawbridge-cljs/blob/master/src-cljs/drawbridge/client.cljs#L70-L94 the most relevant bit being the QueryData object

18:17 d0ky: hiredman: and is there any simplier way ? when i use read-from from enfocus it works ... but now i dont send data from any form

18:18 Frozenlock: d0ky: What are you trying to do? There might be libraries for that.

18:19 hiredman: d0ky: dunno, I am not familiar with enfocus

18:20 d0ky: Frozenlock: i want to send data from multiselect but before sending it i want to filter them with an atom to send the less the possible data to server

18:21 Frozenlock: I don't understand... why would you need an atom to filter?

18:22 d0ky: Frozenlock: i have stored some data

18:22 Frozenlock: in atom

18:23 so i have vector i want to send to server

18:25 Frozenlock: d0ky: ok... so the atom and filtering stuff really isn't revelant. :-p

18:25 You want to send a vector to the server. I've been using this recently and I like it https://github.com/JulianBirch/cljs-ajax

18:25 d0ky: Frozenlock: yes it isnt :)

18:27 Frozenlock: thanks .. i will try there a solution :)

18:29 Frozenlock: it works when i created a map like: {:in (pr-str dest-user)} and i can clearly read data on server

18:29 TravisD: Given some r, is there any non-stylistic difference between (dosync (ref-set r (f @r))) and (dosync (alter r f))?

18:30 hiredman: yes

18:30 the later is correct

18:31 TravisD: That's what i thought, but I'm confused about why the first one is wrong. Since both the reading and writing to r occur in a transaction, aren't they protected from other reads and writes?

18:39 hiredman: do you know the answer?

18:41 hiredman: TravisD: actually I may be wrong, it looks like derefing a ref is actually recording as a read in the transaction, so it may restart the transaction if a deref'ed ref's value changes

18:41 justin_smith: but the latter is still more clear

18:42 amalloy: there might be some weird corner cases where f is a non-pure function, which alters r and also some other ref?

18:42 but in most cases the former is just a grosser version of the latter

18:43 hiredman: amalloy: well, it would still be altering the other ref in a transaction

18:43 justin_smith: I wonder if the former would be more likely to trigger a retry of the transaction?

18:44 TravisD: Cool. I was mostly asking because I was worried that there were some sneaky situations in more complicated transactions that could cause problems

18:45 like, in a more complicated transaction I could see using @r in a let block which eventually set-refed r again

18:45 ref-set

18:46 hiredman: I have yet to see code outside of maybe the ants demo, where using refs and the stm was good, in general most places I have seen it would be just as correct, and simpler, using an atom

18:47 TravisD: Ah, I see

18:47 amalloy: yeah, that's my rule of thumb for concurrency: "if you think you need a ref, you're probably wrong"

18:47 coventry: TravisD: My understanding is that the ref-set version isn't going to trigger a retry if r has changed during the transaction, whereas alter will.

18:47 hiredman: so if you have large complicated usages of the stm, I take a good long look at it

18:47 amalloy: coventry: no, because reading r with @r causes it to be protected by the transaction

18:48 TravisD: hehe, cool. Anyways, I'm actually just rereading the chapter on concurrency

18:48 g2g!

19:47 zeroem: yogthos: considering using selmer for a non html templates. Is there an easy way to disable escape-html for the entire call to render?

19:48 whomp: i can't get vim mode to work in light table, any ideas?

19:49 yogthos: zeroem: don't think there is, another problem is that tags that are on lines by themselves will leave a blank line currently

19:50 whomp: nm got it

19:58 zeroem1: yogthos: thanks, may be a pull request in the future

20:00 yogthos: zeroem1: sure thing, it could easily be a flag

20:42 TravisD: amalloy, hiredman: Sorry about leaving so abruptly. I realized that I was already 10 minutes late for a meeting! Anyways, I wasn't using refs in any complicated way, but I have been reading about concurrency in clojure and I was just wondering :)

21:04 Does await always return nil?

21:06 ticking: TravisD: looks like it, await returns (. latch (await)), which in turn is a void method

21:06 TravisD: Ah, cool. I feel like it should be mentioned in the docstring, since it's pretty plausible that it would return the agent's value or something

21:07 the docstring for await-for also doesn't say that it returns true if the await didn't time out

21:07 ticking: use to code luke

21:07 *the

21:07 TravisD: :)

21:07 I looked at it quickly, but then decided to ask

21:07 ticking: but yeah you are right, it should be mentioned

21:12 arrdem: lazybot: reading the code is a poor excuse for worse documentation

21:12 TravisD: lazybot seems not to care

21:38 with a ref transcation, I can do multiple things like first read the value of the ref, and then update it. Is there a way to do the same with atoms? I have a lazy-seq of numbers and I want multiple threads to take turns reading them so that no two threads get the same numbers

21:39 gfredericks: yep

21:39 TravisD: https://github.com/Prismatic/plumbing/blob/master/src/plumbing/core.clj#L325-335

21:39 TravisD: oh cool

21:40 gfredericks: alternatively you could add a nil onto the front and then just make the first thing be assumed to have been read already

21:40 TravisD: I don't understand the second thing you said

21:41 gfredericks: ,(let [my-nums [10 20 30 40] a (atom (cons nil my-nums)) read-num #(first (swap! a rest))] [(read-num) (read-num)])

21:41 clojurebot: [10 20]

21:42 gfredericks: ,(defn make-iterator [nums] (comp first (partial swap! (atom (cons nil nums)) rest)))

21:42 clojurebot: #'sandbox/make-iterator

21:42 TravisD: aha.

21:42 gfredericks: ,(def my-nums (make-iterater (shuffle (range 20))))

21:42 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: make-iterater in this context, compiling:(NO_SOURCE_PATH:0:0)>

21:42 gfredericks: ,(def my-nums (make-iterator (shuffle (range 20))))

21:42 clojurebot: #'sandbox/my-nums

21:42 gfredericks: ,(read-num my-nums)

21:42 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: read-num in this context, compiling:(NO_SOURCE_PATH:0:0)>

21:42 gfredericks: ,(my-nums)

21:42 clojurebot: 19

21:42 gfredericks: ,(my-nums)

21:42 clojurebot: 3

21:42 gfredericks: ,(my-nums)

21:42 clojurebot: 16

21:43 TravisD: I came kind of close. I imagined doing (do (swap! a rest) (first @a))

21:44 gfredericks: oh yeah that's racey

21:44 TravisD: yeah :(

21:44 gfredericks: which is of course why swap! returns the new value

21:44 TravisD: yeah :D

21:44 it is exactly the reason

21:44 gfredericks: I've also done hairier things where you set some metadata on the return value and pull it out afterwards

21:44 ticking: arrdem: It depends I'd say, if you just want to know a property like a return type in weird border cases of a fn like in this case, the code is the right place to go. Having to read through all the code to learn a lib is a different thing though.

21:45 TravisD: ah, yeah, I never think of using metadata for anything

21:45 gfredericks: despite what bbloom says I think metadata usage is mysterious and impossible to summarize

21:45 bbloom: gfredericks: did i ever say it makes perfect sense? i'm constantly flip flopping on how i feel about it :-P

21:46 TravisD: hehe

21:46 arrdem: ticking: how is the _constant return value_ of a function a "weird border case"?

21:46 bbloom: most important thing: metadata does not influence equality

21:46 gfredericks: bbloom: yes this is the exact statement I'm complaining about

21:46 bbloom: both useful and terrible :-)

21:46 arrdem: ticking: that something is "(constantly nil) for side effects" should be docstring content.

21:46 gfredericks: bbloom: because that has nothing to do with the usage of metadata on fns and references

21:46 ticking: arrdem: seems like it was emergent behaviour, which the author did not really care about

21:47 TravisD: bbloom: One might mistakenly read that as "terribly useful"

21:47 bbloom: TravisD: that too

21:47 ticking: arrdem: (.await latch) could have returned something useful, or may do so in the future

21:47 arrdem: TravisD: zippers would argue that case...

21:47 gfredericks: bbloom: I could imagine arguing that metadata on values and metadata on other things are just two different features with the same name

21:48 TravisD: are zippers in clojure implemented using metadata??

21:48 lazybot: TravisD: What are you, crazy? Of course not!

21:48 TravisD: heh

21:48 arrdem: ticking: then the docs should _say so_. return types are bloody important!

21:48 bbloom: gfredericks: you mean metadata on value vs identity equality semantics?

21:48 yeah, metadata on identities seems a bit odd...

21:48 gfredericks: bbloom: but super useful though

21:48 bbloom: yeah

21:49 gfredericks: vars being the biggest example of course

21:49 ticking: arrdem: I'm not saying it should't do it, I said that it would be useful in this case, still it took me literally 3 seconds to look up the function and see what it does

21:49 gfredericks: but say you wanted to attach a history tracker to an identity; super easy with metadata & watchers

21:49 bbloom: gfredericks: for sure. i basically view metadata as a MASSIVE IMPROVEMENT on the proplists stuff in CL but still not quite "right" yet

21:49 ticking: arrdem: docs are important yes, but the computer does not execute documentation, and it's our job to read code...

21:50 gfredericks: ,(alter-var-root #'partial (fn [f] (comp #(vary-meta % assoc :type :partial-fn) f)))

21:50 clojurebot: #<core$comp$fn__4192 clojure.core$comp$fn__4192@9b9707>

21:51 gfredericks: ,(alter-var-root #'partial (fn [p] (fn [& args] (vary-meta (apply p args) assoc :type :partial-fn :args args))))

21:51 clojurebot: #<sandbox$eval242$fn__243$fn__244 sandbox$eval242$fn__243$fn__244@cb43a9>

21:51 gfredericks: ,(defmethod print-method :partial-fn [f pw] (print-method (list* 'partial (:args (meta f))) pw))

21:52 clojurebot: #<MultiFn clojure.lang.MultiFn@1643eda>

21:52 gfredericks: ,(partial + 1 2 3)

21:52 clojurebot: #<core$partial$fn__4232 clojure.core$partial$fn__4232@1923658>

21:52 arrdem: ticking: saying "oh well I can just grab source" is just waving aside the failure of the documentation in question. I can't claim that I'm innocent of this, but that we have the luxury of open source libraries is no excuse for lacking docs, especially when it comes to effective return type.

21:52 gfredericks: aw snap

21:52 ,(meta (partial + 1 2 3))

21:52 clojurebot: nil

21:52 gfredericks: ,(alter-var-root #'partial (fn [p] (fn [& args] (vary-meta (apply p args) assoc :type :partial-fn :args args))))

21:52 clojurebot: #<sandbox$eval99$fn__100$fn__101 sandbox$eval99$fn__100$fn__101@15316d4>

21:52 gfredericks: ,(meta (partial + 1 2 3))

21:52 clojurebot: {:args (#<core$_PLUS_ clojure.core$_PLUS_@11e8225> 1 2 3), :type :partial-fn}

21:52 gfredericks: ,(partial + 1 2 3)

21:52 clojurebot: (partial #<core$_PLUS_ clojure.core$_PLUS_@11e8225> 1 2 3)

21:52 TravisD: Alright. So what I really want is to have a convenient way for different threads to get their own random number generators. I also want to be able to reproduce results by using one seed to set up the entire system. Is this a reasonable approach? In each new thread you could invoke whatever random-wizardry you wanted, wrapped with a (with-new-rng...)

21:52 gfredericks: meh

21:52 TravisD: https://www.refheap.com/22d202e77c7d58b429d818c9b

21:53 arrdem: ticking: this isn't you, I'm on a docstrings tear today :P

21:53 gfredericks: TravisD: github.com/fredericksgary/four

21:53 ticking: arrdem: again, I said it should be changed

21:53 TravisD: gfredericks: Ah, cool. I saw it on the clojars search, but the name "four" threw me off

21:53 gfredericks: it's so obvious!

21:54 TravisD: gfredericks: Does the snippet of code I posted look sane anyways?

21:55 and what does four mean?

21:55 gfredericks: http://xkcd.com/221/

21:55 TravisD: Ah!

21:55 amazing

21:55 (inc gfredericks)

21:55 lazybot: ⇒ 53

21:55 ticking: arrdem: but lets face it, most code, even clojure code, sucks monkeyballs. the docs are even worse if they exist at all, so learning to read code (clojuredocs.org has a small code box for every fn) will only help you become more independent (and be a better programmer)

21:56 gfredericks: TravisD: yeah it looks fine; you could use this var instead if you wanted: https://github.com/fredericksgary/four/blob/master/src/four/stateful.clj#L4

21:56 ticking: arrdem: I feel though that there is quite a general dogma against reading code

21:57 gfredericks: unless that custom random class you have there is not a subclass of java.util.Random :/

21:57 TravisD: gfredericks: I don't think it is :( I read some terrifying posts about running into trouble doing experiments with crappy random number generators

21:57 so I was looking for a library with a few different prngs

21:57 apache.commons.math3 has the main ones, I think

21:58 gfredericks: is it weird that rand-int uses java.util.Random to generate longs that get turned into a double that gets coerced back into an int?

21:58 TravisD: pft, no, that's obviously the right way to do it

21:58 arrdem: ticking: speaking as a compiler author, code is not literature. Code is directives to your retarded best friend, the compiler, explaining to him how to tell his dumber moneky the processor how to munge integers into getting the right result. Code was never supposed to be written by humans for reading by humans. Humans read code because either something's wrong or because the human who wrote the code in the first place didn't make obvious what

21:59 TravisD: Knuth disagrees!

21:59 or, not really, actually

21:59 arrdem: TravisD: Knuth wants us to write books that _contain_ code.

21:59 gfredericks: ,(time (nth (repeatedly #(rand-int 100)) 1000000))

21:59 clojurebot: "Elapsed time: 272.405993 msecs"\n45

21:59 TravisD: yeah, I remembered that after blurting it out :(

22:00 * arrdem can't spell monkey

22:00 ticking: arrdem TravisD: hal abelson disagrees though Programs must be written for people to read, and only incidentally for machines to execute.

22:00 gfredericks: ,(let [r (java.util.Random. 42)] (time (nth (repeatedly #(mod (.nextLong r) 100)) 1000000)))

22:00 dbasch: (inc ticking)

22:00 clojurebot: "Elapsed time: 314.686804 msecs"\n44

22:00 lazybot: ⇒ 1

22:01 gfredericks: TravisD: looks like it's still pretty fast though :)

22:01 TravisD: gfredericks: :)

22:01 gfredericks: maybe it's the mod

22:01 ,(let [r (java.util.Random. 42)] (time (nth (repeatedly #(bit-and (.nextLong r) 127)) 1000000)))

22:01 clojurebot: "Elapsed time: 137.186877 msecs"\n92

22:02 TravisD: ticking: I don't actually feel strongly on the subject. It would be wonderful if all code could be read, but I also think that many things are complicated without explanation

22:02 gfredericks: yay now it's faster

22:02 TravisD: huh, wow. That's a surprisingly big difference between mod and bit-and

22:02 arrdem: ticking: Okay great, you can say that, but the reality is that code is written for machines to run it. We built computers because we wanted to tackle integer and matrix programming problems that were too complicated for humans to do by hand in a reasonable timeframe.

22:03 dbasch: arrdem: have you ever worked as part of a large software team?

22:03 arrdem: ticking: It wasn't until later that we developed languages above the machine directive layer

22:03 ticking: arrdem: Thought = Math = Code

22:04 and Speech = Thought

22:04 arrdem: ticking: you just made my argument for documentation in two lines.

22:05 ticking: arrdem: elaborate

22:07 arrdem: ticking: What's to say? We can't transmit or persist thoughts, so we persist writing and sometimes sound as the closest proxies thereto yet invented by man. These contain the math from which code is derived. Thus documentation is an isomorphism of the code in a human "native" format rather than a ^^ (somewhat less) retarded compiler native format.

22:08 ticking: arrdem: why do you asume that code is not a native human format, it was invented by humans, long before there were computers (e.g. lamba calc)

22:08 and to me it seems that Speech = Thought = Math = Code =|= an informal ad hoc description

22:08 arrdem: ticking: what was the last time you read FORTRAN code :P

22:09 ticking: what does fortran have to do with that?

22:09 fortran is still more readable albeit slower than assembly

22:10 also why do you say that speech and writings are only an aproximation of thought?

22:10 to me it seems that they are a serialization format which allows you to perfectly recreate thoughts

22:10 arrdem: because "true" thought storage would be networked BCIs and a hivemind.

22:11 ticking: how is telepathy transmitted by air any different than telepathy by magic/electricity

22:11 arrdem: text is, as you say, a serialization that allows us to recover thoughts often imperfectly with learning involved.

22:13 the three are functionally identical, and distinct from text in that there is no learning involved on the part of a reader. I have before me an algorithms textbook and homework. Simply by reading the textbook I am not armed with the tools required to solve the problems therein. I have to explore the ideas therein for myself and populate my own understanding neural graphs in a way that "shared" thought does not/would not demand.

22:14 ticking: sorry my bt keyboard gave up

22:14 arrdem: When I read code, I play compiler and interpreter. I have to understand, scan, parse, and explore the behavior of the code. When I read docs (good ones at least) I am given functions as black boxes that I can reason about easily with little to no loading.

22:14 * arrdem stops ranting and actually does his homework

22:15 ticking: yes but the same is true for regular thought

22:15 http://en.wikipedia.org/wiki/Subvocalization_(Learning_and_Memory)

22:15 dbasch: arrdem: I’m 44. I’ve been in the software industry for decades. I’ve seen things you wouldn’t believe. 5 1/4 floppies on fire off the shoulder of Orion

22:16 ticking: there is no regular thought without speech, when you hear you inner voice to reflect about the world, you activate your vocal cords involutarily, this is not surpressable and required

22:16 TravisD: dbasch: :) I can see the rain

22:16 dbasch: enjoy reading beautiful documentation while you can, one day you might get paid to… I won’t spoil it

22:17 arrdem: dbasch: I've already been paid to revers engineer an undocumented OS boot sequence so that I could inject bringup timing sensitive driver code. I'll fight for my documentation thank you.

22:17 dbasch: TravisD: c-beams glitter and all that :)

22:17 TravisD: hehehe

22:17 I will watch that movie tonight.

22:17 ticking: dbasch TravisD arrdem: I think the marginalia aproach is really good, code for the what and how, documentation for the why and wtf

22:18 dbasch: arrdem: I foresee endless battles against Directors/VPs who *need* everything to work yesterday

22:18 TravisD: ticking: Yeah, I was taking a look at that before. It makes really pretty documents

22:19 ticking: TravisD: could need a better index and search though, but that is first world complaining

22:19 TravisD: ticking: Also, in your last message I mentally replaced "wtf" with "what they're for" ;)

22:19 arrdem: dbasch: funny... if the hardware team had documented that MMIO segment worth a damn when the built it, my job would have taken 30 minutes rather than three weeks...

22:20 dbasch: arrdem: if I had a dollar for every time I heard something like that… wait, I do :)

22:20 ticking: arrdem: and if they had documented it wrongly it would have taken you three months ^^

22:20 no docs > wrong docs

22:20 dbasch: or docs that used to be right, probably the more common case

22:21 arrdem: well I had _those_ :C

22:21 TravisD: old docs might provide clues for the code detective

22:21 ticking: dbasch: yeah, people that write wrong docs on the first try are a special kind of species

22:22 TravisD: yeah, but unless you know that they are outdated, they will f*** you in the a**

22:22 TravisD: ticking: It's getting harder to avoid your profanity with clever substitutions ;)

22:22 Fling you in the air

22:22 ticking: nice

22:23 TravisD: one too many letters though :(

22:23 ticking: TravisD: I spend an entire day debugging cluster code that fails because of how the compiler precompiles lambdas and then serializes them

22:24 TravisD: so trust me, I'm holding back on the profanities ^^

22:27 TravisD: hehe :) I must live in some sort of heaven

22:28 dbell: fun to run if you want to get an idea of how clojure deals with order of hash-map entries as size increases: (keys (apply hash-map (interleave (range 1000) (range 1000 2000))))

22:36 gfredericks: is bound-fn terrible?

22:37 bbloom: gfredericks: http://okmij.org/ftp/Computation/dynamic-binding.html

22:37 gfredericks: bound-fn : call/cc :: something-better : shift/reset

22:38 gfredericks: bbloom: hell if I will ever understand continuations

22:39 bbloom: gfredericks: good news: i attempt to explain them in this audio: http://www.mixcloud.com/paperswelove/bbloom_3_17_2014_programming_with_alegebraic_effectshandlers/ :-)

22:39 gfredericks: ,(def ^:dynamic *x* 33)

22:39 clojurebot: #'sandbox/*x*

22:39 gfredericks: ,(def get-x (binding [*x* 44] (bound-fn [] *x*)))

22:39 clojurebot: #'sandbox/get-x

22:39 gfredericks: ,(get-x)

22:39 clojurebot: 44

22:40 gfredericks: ,(binding [*x* 55] (get-x))

22:40 clojurebot: 44

22:40 gfredericks: oh wait nevermind

22:40 but do mind this part

22:40 ,(def get-x (bound-fn [] *x*))

22:40 clojurebot: #'sandbox/get-x

22:40 gfredericks: ,(binding [*x* 99] (get-x))

22:40 clojurebot: 99

22:40 gfredericks: I know what's going on but it just makes me grumpy

22:41 amalloy: ,(first (binding [*x* 99] (lazy-seq [(get-x)])))

22:41 clojurebot: 33

22:41 amalloy: just for fun

22:41 bbloom: gfredericks: yeah, bound-fn is wonky

22:41 gfredericks: oleg's thing explains how it should really work

22:42 ticking: has anyone experience with proxy and serialisation? I'd prefer to avoid custom java classes, but I could imagine that serializing proxies might create a lot of classes.

22:54 gfredericks: well now I know about *print-readably* :/

22:55 ticking: dat unicode unsuport

22:57 amalloy: gfredericks: i know that it exists, but not what it does. it sounds almost like the opposite of print-dup, but it can't be that

23:00 gfredericks: amalloy: it turns of pr I think

23:00 ,(pr-str "foo")

23:00 clojurebot: "\"foo\""

23:00 gfredericks: ,(binding [*print-readably* false] (pr-str "foo"))

23:00 clojurebot: "foo"

23:00 gfredericks: no idea why that is a thing you would need to do in that manner

23:01 we should have another var that makes println act like print

23:05 for every function foo we should have a parallel dynamic var *foo-works* that defaults to true

23:09 MarlaBrown1: why does conj behave differently for lists and vectors?

23:10 dbasch: MarlaBrown1: because it inserts the element at the “cheapest” place for each structure

23:10 for a list, the cheapest place is the head

23:10 for a vector, the end

23:10 MarlaBrown1: cheapest meaning most efficient in the internal tree structure?

23:10 dbasch: yes

23:11 MarlaBrown1: gotcha, thanks

23:37 yedi: does anyone know the link that has cljs and the equivalent js stuff side by side

23:39 found it

23:41 TimMc: I'd like to use drawbridge to get a remote REPL, but I don't want to pass my password on the command line when doing `lein repl :connect http://...` -- is there a way I can store the HTTP authentication in profiles.clj or something?

23:48 gtrak: what would you guys recommend for pairing over the net for 2 emacs users?

23:48 I haven't used anything.

23:48 arrdem: floobits, if you can get it working...

23:48 technomancy: gtrak: definitely tmux, as long as you don't need to share a browser

23:49 floobits is neat, but it's only really interesting if you want to cross editor boundaries

23:49 gtrak: technomancy: that assumes like a shared server, yea?

23:49 I don't have any infra set up.

23:49 technomancy: gtrak: no need, https://syme.herokuapp.com

23:49 assuming you have an AWS account and like fifteen cents

23:50 gtrak: aha

23:50 that might be perfect.

23:50 oh god, floobits uses emacs packages

23:51 probably not going to work :-)

23:51 I'll do syme.

23:51 technomancy: I could never get the hang of floobits since you don't share the whole screen

23:51 so stuff like shells and repl sessions are hard to get right

23:51 gtrak: I need to just be able to give the guy a link.

23:51 technomancy: you can share them as long as only one person types, but it's really annoying

23:55 gtrak: technomancy: how do you setup stuff like emacs on syme?

23:56 technomancy: gtrak: just fork this repo and tweak to your liking https://github.com/technomancy/.symerc

23:57 gtrak: ah good. This is where my 'close to stock' config comes in handy :-).

Logging service provided by n01se.net