#clojure log - Jul 25 2013

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

0:30 aaelony: what's the best way to read a small edn format file entirely into memory?

0:33 brehaut: aaelony: (clojure.edn/read-string (slurp file-or-filename)) ?

0:34 aaelony: brehaut: thank-you, but that only yields the first line

0:34 brehaut: aaelony: the first line or first form?

0:34 aaelony: e.g. (count (clojure.edn/read-string (slurp data-file)) ) ;; gives 2

0:35 alandipert: (clojure.edn/read-string (str "(" (slurp f) ")")) is a quick fix

0:35 aaelony: brehaut: It's likely my fault, there is a edn structure on each line and I need all the lines

0:35 tomjack: you'd have to call read repeatedly

0:36 aaelony: alandipert: thank-you! that works :)

0:37 tomjack: https://www.refheap.com/7fac4581dac79e910dbbba793

0:37 the less quick fix..

0:38 https://www.refheap.com/67eedfdc3b75112b6cacc9a26 grrr

0:38 aaelony: tomjack: that's cool thanks. I googled a bunch of explanations, (such as http://stackoverflow.com/questions/15234880/how-to-use-clojure-edn-read-to-get-a-sequence-of-objects-in-a-file) but none of them fit exactly. thanks for everyones help

0:38 hiredman: I wish clojure would just throw an exception when it encounters def not at the top level

0:39 tomjack: eh

0:39 so one macro -> one def?

0:39 aaelony: errors

0:40 tomjack: or is the body of a top-level do also top-level?

0:40 hmm (partial not= foo), that's cool

0:40 I can't decide whether I like that or (complement #{foo}) better

0:41 hiredman: which ever, I am just tired of seen people try to use def like schemes define

0:41 alandipert: hiredman: but what about my defcoolthing macros :-(

0:42 brehaut: no cool things allowed. this is clojure. we only do serious computing

0:42 tomjack: inside let basically? or what?

0:42 aaelony: I'm still waiting for some macro named defleopard...

0:42 hiredman: (defn make-memo [fn] (def table ...) (fn [& args] do stuff with table))

0:42 alandipert: hiredman: in seriousness, i think i agree. i was investigating static compilation and a def in a closure makes compiling defns to java methods super trixty

0:42 brehaut: aaelony: thats only allowed in common lisp (and other languages from the 80s)

0:42 aaelony: haha

0:43 tomjack: ah right

0:44 * hiredman tries to get a message to this guy that he has a gist with incorrect def usage in it

0:45 hiredman: alandipert: I have a lisp -> go source compiler that ends up having to hoist lots of stuff like that in to the top level

0:45 alandipert: hiredman: do your generated methods take an env arg?

0:46 hiredman: yes

0:46 I end up generate the go equiv of what clojure does with IFn's

0:46 alandipert: cost of doing business w/ inner defs i suppose

0:46 hiredman: class and method(s) per function object

0:49 * alandipert dreams of a CinC generator that takes a platform capability spec and emits a suitable clj compiler

0:50 hiredman: we need an urclojure like, uh, whatever that is that shenanigans has

0:50 er

0:50 "shen"

0:50 klambda

0:50 but with more protocols and reify

0:51 futile: hey guys, remember when OOP was brilliant?

0:53 alandipert: hiredman: yes, into it. also the AIM 514 'lisp-based processor' thing

0:54 hiredman: look, the thing I said could actually happen :)

0:56 alandipert: hiredman: oh, you have explored the AIM 514 stuff? i'm tempted to learn VHDL on account of it

0:56 hiredman: I haven't, but it seems unlikely that lisp machines will make a come back

0:58 alandipert: they will, on my machine

1:17 aaelony: another silly question. I have a nice doseq that outputs lines to a file, but I want to label the line number of the line the data came from. I've tried (let [i 0] (doseq [row data] (let [i (inc i)] … but that doesn't seem to do it.

1:19 alandipert: aaelony: maybe (doseq [row data, i (range)] ...)

1:19 tomjack: that would be interesting

1:19 (doseq [[i row] (map vector (range) data)] ...) ?

1:20 aaelony: alandipert: I think that works!

1:20 alandipert: thanks :)

1:20 tomjack: &(for [row [1 2 3] i (range)] [row i])

1:20 lazybot: Execution Timed Out!

1:20 aaelony: cool

1:21 alandipert: or rather, (doseq [[i row] (map-indexed vector data)] ...)

1:21 tomjack: I think it's weird you can't use doseq-like bindings for zippy mode

1:22 aaelony: actually, that works then goes overboard… i'll need to bound the (range) ;)

1:22 zRecursive: ,(range)

1:22 clojurebot: (0 1 2 3 4 ...)

1:24 alandipert: ,(for [[i row] (map-indexed vector "stuff")] [i row])

1:24 clojurebot: ([0 \s] [1 \t] [2 \u] [3 \f] [4 \f])

1:26 tomjack: (for+ :zip [row data i (range)] ...) ?

1:28 alandipert: tomjack: fancy

1:30 aaelony: tomjack: what is for+ … having trouble researching that...

1:30 tomjack: it's hypothetical

1:30 aaelony: ah!

1:42 ok, I gave up and am using an agent instead...

1:43 tomjack: ..for the index?

1:46 ddellacosta: what's the idiomatic way to compare hash-maps for equality? I'm just doing = and that's not working how I want.

1:47 I guess I should be specific: I want to compare two clojure.lang.PersistenArrayMaps.

1:47 PersistentArrayMap

1:47 tomjack: what is an example of = not working how you want?

1:47 egghead: ,(= {:foo :bar} {:foo :bar})

1:47 clojurebot: true

1:47 aaelony: tomjack: yes

1:48 egghead: = is by value instead of ref

1:48 what is ref equality in clj

1:49 amalloy: egghead: identical?

1:49 egghead: ah nice, thanks amalloy

1:50 ddellacosta: thanks folks. I realized I'm being dumb and actually the maps I'm working with are not, in fact, equal, which is why it's telling me they are not equal. D'oh.

1:50 tomjack: clojure.data/diff

1:51 callen: ddellacosta: you really wanna use diff as a sanity check :)

1:52 ddellacosta: tomjack, callen: thanks! I didn't know about that one.

1:54 oh that is SO much nicer than how I was doing it

1:54 * ddellacosta feels much love for Clojure IRC

1:55 callen: ddellacosta: don't thrash around, ask. :)

1:56 ddellacosta: callen: totally…the problem is that it doesn't even occur to me to ask sometimes. I wouldn't have thought to have asked the appropriate question, which was, "how can I best find the diff between two hash-maps?"

1:56 hence the thrashing

2:29 what are people using to measure test coverage for their Clojure codebase?

3:05 tsdh: Hi. I have 2 deftypes A and B which have mutual (instance? A/B ...) checks in some protocol implementation methods. Is there a way to make that compile other than splitting the instance checks in functions A? and B? and adding forward declarations?

3:35 * ucb waves

3:35 ucb: many ohais

3:40 Uakh: ohaïs were had

3:40 hyPiRion: ohai

3:43 * ucb is pleased with the reception

4:07 tsdh: Uh, is it intended that different clojure.core.cache types require different usage patterns? I.e., SoftCaches update in-place with (miss ...) whereas the other's return a new cache one has to use in place of the old one.

4:11 hiredman: tsdh: I'd checkout core.memoize

4:12 (if you are looking at core.cache, because core.cache on it's own has never made sense to me)

4:13 tsdh: hiredman: I already use its SoftCaches in my project, so I thought I use its BasicCaches at another place, too. But now I simply use an (atom {}) which is as good for my use-case.

4:57 darkest_pod: Which concurrency primitive is best to share state between two working threads?

5:00 hiredman: http://wiki.gungfu.de/uploads/Main/clojure-conc.png

5:00 hyPiRion: (inc hiredman)

5:00 lazybot: ⇒ 21

5:01 echo-area: (def hiredman (atom 20))

5:01 Why does lazybot ignore me

5:03 hyPiRion: that's not legal lazybotian

5:03 ,(let [hiredman (atom 20)] (swap! hiredman inc))

5:03 clojurebot: 21

5:04 darkest_pod: hiredman: Thanks!

5:40 tsdh: Is there a nrepl.el command that lets me load the current buffer and reload all required namespaces, too?

5:40 ucb: tsdh: https://github.com/clojure/tools.namespace

5:40 that might come in handy

5:42 hyPiRion: tsdh: you may want to look into Stuart Sierra's setup, it's thought out by a smart man

5:42 tsdh: ucb: That looks great, and it's motivated by the same problem I have. Compile a ns with protocols, now you need to recompile all ns with types implementing these protocols.

5:43 ucb: also what hyPiRion said

5:43 hyPiRion: tsdh: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

5:45 tsdh: hyPiRion: Yes, very useful. Thanks.

6:04 noncom: what is the current fashion for cljs analog for clj-time?

6:04 i need a full-scale date manipulations with cljs

6:43 dnolen: noncom: probably worth taking a look at what's available via Google Closure

6:44 noncom: dnolen: yeah, looks like will have to. also found this http://stackoverflow.com/questions/17041115/clojurescript-date-time-library so not so out-of-the-box, but still not alone :)

6:44 g3ntleman: hey, everybody!

6:44 Did anyone successfully build clojurec on os x?

6:44 dnolen: noncom: I would personally avoid anything that cannot be Closure optimized

6:45 g3ntleman: I'm running into compile problems.

6:45 noncom: dnolen: ok, this makes sense, i will make the priority

6:47 dnolen: noncom: which means there's an opportunity for a nice wrapper about the Closure date stuff if someone is so inclined.

6:49 dark_element: dnolen noncom, maybe even name it cljs-time

6:50 noncom: yes..

6:50 dark_element: i'm still not in twitter, btw :D but gonna be soon, also gonna make audiovizs things and will share

6:50 dark_element: noncom hey. I am now looking at webgl video filters for visualisations

6:51 noncom: did you go about shadertoy?

6:51 dark_element: noncom i am soon going to push the project and you will most probably reuse the code and just write plugins for viz

6:51 noncom: wow!

6:53 dark_element: noncom plugins are nothing fancy. just new namespaces and you will have to provide basic functions for viz.

6:54 noncom shadertoy is fun place. i am looking into both shaders and applying filters on the output

7:08 noncom: dark_element: so r u using shadertoy or on your own?

7:12 doh, forging an entire time-date library for cljs is a big task..

7:15 dnolen: noncom: and unrealistic, which is why I suggested Closure + clj-time approach, just implement basics and over time (heh) people will likely submit enhancements

7:16 so does leiningen plugins and tasks use the JVM settings specified in project.clj?

7:17 hyPiRion: dnolen: almost

7:17 dnolen: hyPiRion: what do you mean?

7:18 hyPiRion: Give me a moment, I'll find the ticket related to this

7:18 Somelauw: Too bad that error messages don't include the lines in which my clojure code actually gives an error.

7:18 ClassCastException java.lang.Character cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:619)

7:19 That could be anywhere

7:19 hyPiRion: dnolen: technomancy/leiningen#1230 contains information about how :jvm-opts works, the patch will be in 2.3.0 which is right around the corner

7:19 lazybot: Set default :jvm-opts in :base profile to :displace -- https://github.com/technomancy/leiningen/issues/1230 is closed

7:21 dnolen: hyPiRion: yeah that's mostly about the project, I'm wondering about plugins and tasks

7:23 hyPiRion: dnolen: right. Those won't use the jvm settings specified within project.clj. You'd have to use the environment variable JVM_OPTS for extra opts

7:23 even then, I would've inspected what the leiningen shell script adds, because it is quite... configured

7:30 dnolen: hyPiRion: hrm, yeah the reason I'm looking at this is that CLJS compiler is nearly twice as slow for auto builds if you don't use server settings

7:33 instilled: What validation libraries is the most popular among clojurians? i'm looking for a general purpose validation library not tied to web, e.g. Sandbox. The other libraries (listed on clujure toolbox) all seem very similar and still actively developed. Any thoughts?

7:33 hyPiRion: yeah, we do some tweaks to speed JVM+Clojure loading up, at the cost of hotspot speed

7:34 dnolen: hyPiRion: is it possible to override?

7:34 https://github.com/technomancy/leiningen/blob/master/bin/lein#L120

7:37 hyPiRion: dnolen: hrm, not the way the arguments are ordered, unfortunately

7:37 dnolen: grr

7:40 hyPiRion: I'll put up an issue on it and see if we can find a way around it, may be that we can put something in for 2.3.0 if we figure out it's safe.

8:24 squidz: what options do I have when dealing with the datastructure differences between javascript and clojurescript? is there a good way to have our clojurescript sequences converted 'automagically'?

8:26 any libraries or anything that enable me to skip on using clj->js

8:27 dnolen: squidz: it's not possible

8:27 squidz: okay so it is just something that we have to pay attention to

8:28 dnolen: do you think that could be something that could be brought to clojurescript, or is there a fundamental limitation in the language that prevents it?

8:28 dnolen: squidz: ES 6 Proxy's could be used to work around this problem, but adoption seem unlikely

8:29 squidz: adoption of proxies?

8:29 in ES 6?

8:30 dnolen: squidz: yes

8:30 squidz: what library are you trying to interact with where marshaling is a big issue?

8:40 squidz: dnolen: I am using D3

8:43 g3ntleman: Did anyone successfully build clojurec on os x?

8:51 tbaldridge: squidz: there was a Clojure/West talk about doing this (I think even using D3), it guy went to a ton of trouble to make cljs/js interop better.

8:51 squidz: let me see if I can find his library

8:53 squidz: the lib https://github.com/dribnet/mrhyde

8:53 squidz: and a D3 wrapper using mrhyde https://github.com/dribnet/strokes

8:56 squidz: tbaldridge: okay. Do you know if the video is available to watch anywhere?

8:57 tbaldridge: squidz: the Clojure/West video schedule says it comes out on 7/29

8:57 squidz: and that'll be on InfoQ

9:01 Somelauw: Is there a _ in clojure.core? Or what could the _ refer to in ClassCastException clojure.core$_ cannot be cast to java.lang.Number clojure.lang.Numbers.multiply (Numbers.java:146)?

9:06 squidz: cool can't wait to see it

9:06 Bronsa: Somelauw: ##(class -)

9:06 lazybot: ⇒ clojure.core$_

9:06 Bronsa: ,(* -)

9:06 clojurebot: #<ClassCastException java.lang.ClassCastException: Cannot cast clojure.core$_ to java.lang.Number>

9:07 Bronsa: Somelauw: you probably missed a paren somewhere

9:10 Somelauw: Bronsa: Okay, but what does it mean? Is _ a minus sign?

9:11 I found the error I was doing (for [x [1 - 1]]) instead of (for [x [1 -1]])

9:11 Bronsa: Somelauw: class names get munged ##(munge '-)

9:11 lazybot: ⇒ _

9:12 Bronsa: Somelauw: java don't premit dashes and other symbols in class names

9:12 so clojure has to convert them to other things

9:12 - becomes _

9:22 Somelauw: Is there also a unmunge or something?

9:23 Bronsa: ,(clojure.repl/demunge "clojure.core$_")

9:23 clojurebot: "clojure.core/-"

9:24 hyPiRion: be wary though, munging and demunging is not one-to-one

9:24 ,(map munge ["-" "_"])

9:24 clojurebot: ("_" "_")

9:25 Somelauw: Bronsa: thanks

9:25 hyPiRion: ,(let [identity (comp clojure.repl/demunge munge)] (identity "_"))

9:25 clojurebot: "-"

9:26 Somelauw: hyPiRion: does that mean that I can't have both a function - and _ in a namespace?

9:26 because they both get munged the same

9:26 Bronsa: Somelauw: no, namespaces don't need to munge vars

9:27 it's only the class name that'll be the same

9:27 it's probably not going to work when AOT'ing though

9:29 yeah, if you AOT compile (defn a- []) and (defn a_ []) you overwrite a- with a_

9:32 Somelauw: But (def - 5) and (def _ 6) can conflict?

9:32 I'm not sure I completely understnad yet, but I'll avoid having both a_ and a- anyway.

9:32 Bronsa: no, defs don't break

9:33 it's fns that break when AOT

9:33 Somelauw: yeah, just avoid having the same name with - and _ and you'll be fine

9:33 Somelauw: oh, because functions are compiled to classes and classes can't have - in their name?

9:33 Bronsa: yes

9:34 so both a_b and a-b get compiled to the.ns%a_b.class

9:34 s/%/$

9:44 chrisrossi: I came across this: http://clojure.org/streams

9:44 just wanted to say +1

9:44 i'm coming from python and find python generators to be extremely useful.

9:49 noncom: did anyone ever read an mp4 with opencv and clojure?

9:50 i did that in java, but interested if someone had good experience with clojure oto

9:51 also there were many changes to opencv-java and javacv...

9:52 learner_: Hello All, a newbie question. What does "list comprehension" mean ?

9:55 squidz: hyPiRion: is it possilbe to use leiningen into an already existing non-clojure project?

9:57 learner_: list comprehensions are kind of like mathemetical set definitions

9:57 so something like the set of x where x is greateer than 10 and less then 20 {x | x > 10 : x < 20}

9:58 which is [11,12,13,14,15,16,17,18,19]

10:01 Somelauw: Is there something like a .leiningenrc or .clojurerc file, so I can always require pprint when starting a repl?

10:02 chrisrossi: python generators are a poor man's stream.

10:03 learner_: You can create them in clojure with the for macro.

10:07 ok, I found I can put stuff in user.clj

10:09 hyPiRion: dnolen: false alarm, you can in fact override the default settings. I am just not able to properly read bourne-again shell scripts.

10:10 dnolen: it's just LEIN_JVM_OPTS="your settings here"

10:10 nDuff: ...random aside, coming from #bash: LEIN_JVM_OPTS="foo" is probably the _worst_ way to pass a list of arguments around

10:11 ...as you can't include something like -f "filename with space" inside that argument list without forcing use of eval

10:11 ...and if you use eval, then arbitrary code inside that environment variable is necessarily executable

10:11 and a great deal of work (which most folks writing scripts don't know how to do) is necessary to sanitize arguments being passed in.

10:11 It's seriously bad news, and it's also completely endemic among shell scripts used to start Java processes for some reason.

10:12 hyPiRion: nDuff: We'd love improvements, fork Leiningen and send a pull request

10:17 futile: ,(doc ffirst)

10:17 clojurebot: "([x]); Same as (first (first x))"

10:17 futile: neat

10:18 ,(doc rrest)

10:18 clojurebot: It's greek to me.

10:18 futile: :D

10:19 hyPiRion: ,(doc nnext)

10:19 clojurebot: "([x]); Same as (next (next x))"

10:21 futile: ha

10:21 ,(doc fffirst)

10:21 clojurebot: Gabh mo leithscéal?

10:21 futile: ,(doc fnext)

10:21 clojurebot: "([x]); Same as (first (next x))"

10:21 futile: ha!

10:21 oh man, caddddr all over ahead

10:21 *agan

10:21 *again

10:23 Are there any Clojure libs that complement Datomic?

10:24 mmarczyk: futile: sure: https://github.com/rkneufeld/conformity https://github.com/halgari/fafnir

10:25 futile: Thanks mmarczyk :)

10:25 mmarczyk: :-)

10:25 chrisrossi: Somelauw: I'll withhold judgement but "poor man's" seems overly pejorative at first glance. i understand the dangers inherent in stateful iteration, but the allergy to it seems a little extreme to me. usually the scope a stateful iterator is used in is local, nonconcurrent, and entirely safe.

10:40 pyrhho: What's the clojure equivalent of MyClass.class ?

10:41 clgv: pyrhho: MyClass

10:41 ,String

10:41 clojurebot: java.lang.String

10:41 clgv: ,(type String)

10:41 clojurebot: java.lang.Class

10:41 pyrhho: ok. so I don't need to call anything to turn it into a class object..

10:41 clgv: ,(type java.util.List)

10:41 clojurebot: java.lang.Class

10:41 futile: ,(.new String)

10:41 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: new for class java.lang.Class>

10:41 futile: i dunno

10:42 pyrhho: ,(new String)

10:42 clojurebot: ""

10:42 futile: ,(String/new)

10:42 clojurebot: #<CompilerException java.lang.NoSuchFieldException: new, compiling:(NO_SOURCE_PATH:0:0)>

10:42 clgv: pyrhho: a class name is automatically resolve to a class symbol in the examples above

10:42 futile: ok fine

10:42 pyrhho: ah ok.

10:42 tolitius: ,(String.)

10:42 pyrhho: thanks

10:42 clojurebot: ""

10:42 futile: yeah that

10:42 clgv: pyrhho: delete the "symbol" ^^

10:42 futile: ,`~String

10:42 clojurebot: java.lang.String

10:43 futile: ,``~~String

10:43 clojurebot: java.lang.String

10:43 pyrhho: So, when I have a java method with the type signature methodName(Class<? extends C> arg1), I could just do (.method obj MyClass), then, right?

10:43 futile: OH NO

10:43 ,`````~~~~~String

10:43 clojurebot: java.lang.String

10:43 clgv: ,(type `~String)

10:43 clojurebot: java.lang.Class

10:43 clgv: ,(type `String)

10:43 clojurebot: clojure.lang.Symbol

10:43 clgv: ^^

10:43 futile: ,(= java.lang.String String)

10:43 clojurebot: true

10:43 clgv: pyrhho: yes

10:44 pyrhho: ok cool thanks

10:44 clgv: pyrhho: try out your current scenario on the REPL

10:48 silasdavis: Any convention/idiom for use of 'single' and "double" quoted strings?

10:49 Somelauw: chrisrossi: I'm not allergic to stateful iteration. It's more that streams can do more than generators. For example, when doing s = generator(), you can only iterate through s once in python, but if s were a stream, it can be iterated multiple times.

10:49 chrisrossi: ok, gotcha.

10:49 silasdavis: oh ignore that last comment

10:50 question rather - too long away from clojure, forget what everything does

10:50 chrisrossi: one thing i'm missing from the streams writeup is any example of what generator code might look like.

10:51 the python 'yield' makes writing those things really nice. anything similarly clever here?

10:51 Somelauw: chrisrossi: concat and keep?

10:52 and mapcat

10:53 futile: I bet Python generators could usually be done with plain old lazy sequences.

10:53 Somelauw: there is no direct equivalent to yield. But using concat, keep, mapcat and (for :when) you can get equivalent functioning code.

10:54 nDuff: chrisrossi: see http://clojuredocs.org/clojure_core/clojure.core/lazy-seq

10:55 chrisrossi: ...core.async actually results in code that looks very, very much like Python generators, but that's rather a different thing.

10:55 chrisrossi: nDuff: yeah i was looking at core.async yesterday. tickles some of the same brain cells, but still different.

10:56 i came to core.async looking for a gevent work alike, then realized it doesn't help with io.

10:57 nDuff: chrisrossi: eh? helps perfectly well with async IO.

10:57 chrisrossi: ...and Java has had async APIs ever since NIO was introduced, which was ages ago.

10:59 chrisrossi: hmm, maybe i still haven't grokked something essential, but it looks like the only time in core.async that you yield back to the go loop is when you push or pop from a channel. if there were io channels...

11:00 nDuff: chrisrossi: if you kick off an IO operation with a on-receive callback that feeds into a channel...

11:01 chrisrossi: ok, sure. that's doable. you still have to use callbacks to do that--something gevent or core.async is designed to allow you to avoid doing explicit callbacks and write synchronous style code.

11:02 tolitius: chrisrossi:

11:02 (go

11:02   (let [c (chan)]

11:02     (future (>!! c (blocking-io-read some-stream)))

11:02     (let [msg (!< c)

11:02       (do-something-with msg))))

11:04 chrisrossi: yep, that'd work, but it's still not the same. now you have a thread dedicated to one file/socket/etc...

11:09 pyrhho: So, I have a proxied Object, and I'm trying to call a method it got by extending an abstract class, but am seeing "IllegalArgumentException Can't call public method of non-public class"

11:11 Sorry, it's not a proxied object, actually..

11:12 I have a "public final class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel>", but am trying to call a method it gets from AbstractBootstrap.

11:12 Is it the generics, maybe?

11:14 I get the error when I do: "(doto (new ServerBootstrap) (.channel MyChannel))"

11:17 tolitius: chrisrossi: true, but hopefully a very sort lived thread

11:18 can be wrapped in a cached thread pool

11:19 alexgunnarson: hey everyone - i was wondering… what are some options for clojure iOS development?

11:19 i know of some instances where clojurescript has been used

11:20 but clojure… the jvm doesn't run on ios

11:20 chrisrossi: looks like clojure.java.shell doesn't support streaming to/from subprocs. some 3rd party libraries do. any favorites?

11:20 gfredericks: does anybody know what was meant here about reader metadata & IReference? https://groups.google.com/forum/#!topic/clojure-dev/mAHFtuaEXRk

11:21 tolitius: chrisrossi: what are streaming from shell?

11:21 (e.g. that can't be streamed from JVM)

11:22 *what are you

11:23 chrisrossi: i just want to call out to shell prog, get an output stream that can be used to write to the subproc's stdin and/or an input stream that can be used to read from a subproc's stdout.

11:24 just a pipe, basically.

11:26 nDuff: alexgunnarson: I've seen some folks working on an ObjC compilation target for that reason.

11:27 alexgunnarson: nDuff: any success with it?

11:27 nDuff: alexgunnarson: ...that's something closer to cljs than Clojure proper, though.

11:27 tolitius: chrisrossi: https://github.com/Raynes/conch might do what you want. check it out

11:27 nDuff: alexgunnarson: Don't know -- haven't tracked it closely.

11:28 alexgunnarson: nDuff: okay. thanks :)

11:28 chrisrossi: tolitius: i was actually looking at that one. thanks. have you used it?

11:29 tolitius: chrisrossi: e.g. (grep "ssh" {:in (ps "-e" {:seq true})})

11:29 no, did not have a need, but I am looking for an excuse to :)

11:30 chrisrossi: Raynes is solid though, so I would expect it to work as doced

11:33 chrisrossi: cool. i see the low-level api gives you :out as an input stream, just like i want. ;)

11:33 and the method of composing pipelines is pretty cool.

11:34 egghead: we're using conch for a little task runner, works well

11:34 tolitius: chrisrossi: yep, very clean

11:41 jvc: hi, I wrote this help mode for clojure https://github.com/judevc/clojure-here

11:46 mmarczyk: gfredericks: going by the code, objects implementing IReference would have their metadata reset to the leftmost metadata item specified in the source

11:46 gfredericks: ^:foo ^:bar ^:quux iref -> iref with {:foo true}, but not :bar or :quux

11:46 futile: jvc: can you put it in melpa?

11:48 mmarczyk: gfredericks: the relevant concrete classes are Namespace, Agent, Atom, Ref, Var -- not exactly read in very often -- so not a terribly big deal

11:48 jvc: futile: i put it in marmalade

11:48 I haven't put anything in melpa, let me have a try.

11:48 gfredericks: mmarczyk: how do you read them?

11:49 futile: jvc: melpa is awesome

11:50 gfredericks: mmarczyk: oh I see: (meta (read-string "^{:foo 12} ^{:bar 15} #=(atom nil)")) => {:foo 12}

11:52 mmarczyk: gfredericks: right

11:52 gfredericks: no way to read these in besides read-eval that I can think of off the top of my head

11:55 egghead: can I have a macro that behaves differently in cljs than clj somehow?

11:56 just want to reference 'go' by clojure.core.async/go and cljs.core.async.macros/go depending on the env its used for

11:57 dnolen: egghead: there's not really a simple way to do that

11:57 egghead: c'est la vie

11:57 bgilbert: egghead: maybe two separate macros under different namespaces, and shared functions in a common namespace

11:57 * nDuff tries to remember the name of the proposal for providing a clean, portable solution for that

11:57 egghead: currently i'm just not qualifying it and assuming that 'go' will be available at expand time

11:57 nDuff: (feature tags? something that made the language implementation queryable)

11:58 egghead: ya two namespaces is probably a better way to do it

11:58 thanks

11:58 mmarczyk: dnolen: egghead: haven't tried this, but checking whether there's a dynamic binding in place for *cljs-ns* (in cljs.analyzer) might be a way to do it

11:59 and incidentally I think it would be nice to have a supported way to do this

12:01 dnolen: mmarczyk: sounds like feature expressions to me :)

12:03 mmarczyk: dnolen: sure :-)

12:03 dnolen: I'd still like to have *clojure-version* bound to something sensible when compiling cljs

12:04 would be super funny if a compiler macro then used *clojure-version* to determine which Clojure-side facilities are available though

12:04 oh well.

12:06 oh wow, confluence uses some sort of rich text editor? no markup? :-(

12:07 dnolen: mmarczyk: I think it's possible to support Markdown, not sure Clojure Confluence does

12:08 futile: POCT = plain old Clojure tricks

12:08 POCT is great. libs should encourage POCT instead of reinventing them

12:10 mmarczyk: dnolen: oh great, help mentions some markup too, so that's encouraging... I'll find out soon enough if we've got it enabled

12:10 ChongLi: http://dev.clojure.org/display/design/Feature+Expressions

12:11 this is a nice article

12:11 dnolen: ChongLi: pretty sure it's on the table for Clojure 1.6 - we'll see

12:11 ChongLi: sweet

12:13 futile: dnolen: im probably way uninformed.. but would it make more sense to just define a stdlib-interface that each platform has to conform to?

12:13 then each program wouldnt care where its running, its just written one way.

12:13 learner_: squidz: Thanks for your answer about List comprehension. Really appreciate it

12:13 ChongLi: no

12:13 one of the core philosophies of clojure is platform power

12:14 by wrapping the platform in a standard interface, you lose that

12:14 futile: touche

12:14 yeah, it would require wrapping every single platform feature. thats not realistic

12:14 dnolen: futile: it only sound good in theory, platforms tend to differ in dramatic ways

12:15 llasram: Also, that kind of stuff is hard to get right. If you do it well, it saves users a ton of time. If you do it wrong, you get the Java process API

12:15 futile: ah right, exceptions/types/concurrency/etc

12:15 ChongLi: it pushes you into a "lowest common denominator" standard platform

12:15 feature expressions help you to detect and leverage your platform specifically

12:26 mmarczyk: design page re: recur to enclosing loop: http://dev.clojure.org/display/design/Named+loops+with+recur-to

12:26 (incl. links to clojure-dev discussion and cljs proof of concept)

12:58 callen: Dear #clojure, this is your daily reminder that https://github.com/uncomplicate/fluokitten exists.

13:02 futile: I thought I wanted comp, but that wasn't right. Then I thought it was iterate, that's not right either.

13:02 I guess I want (f1 (f2 (f3 f4))) or something.

13:03 It's kinda like iterate, but with different functions each time, from a list of functions.

13:03 How would you do this?

13:04 Maybe reduce...

13:05 ,(not (zero? (inc 3)))

13:05 clojurebot: true

13:05 justin_smith: ((apply comp fn-list) input)

13:05 futile: ,((apply comp [not zero? inc]) 3)

13:05 clojurebot: true

13:05 futile: Oh.

13:06 Thanks justin_smith :)

13:06 (inc justin_smith)

13:06 lazybot: ⇒ 3

13:07 futile: Yeah that makes a lot of sense suddenly.

13:09 justin_smith: another option: (defmacro ->vec [input fns] `(-> ~input ~@fns))

13:09 futile: Well even so, I think I'm doing it all wrong.

13:09 justin_smith: I don't think the bot will do macros, but that will work like -> but take the fns in a list/vector

13:09 futile: I'm trying to implement around-each fixtures.

13:10 (but it's all wrong)

13:10 Bronsa: ,(get (sorted-set 1) :foo) ;; this was surprising to me

13:10 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Keyword>

13:11 justin_smith: a fixture should be a function that takes the action it wraps as an argument, and it can decide whether to do it's action to the functions input or output or both

13:11 futile: justin_smith: can you show me in code (refheap)?

13:11 justin_smith: that way you can compose fixtures (similar to ring handlers for example)

13:11 futile: cuz im confused by what you mean

13:12 justin_smith: I have a meeting in four minutes, but remind me sometime later if I forget

13:12 futile: justin_smith: oh ok

13:13 for anyone else following along, this is my plan so far: https://www.refheap.com/16903

13:19 amalloy: mmarczyk: neat!

13:20 bbloom: mmarczyk: another current "solution": trampolines

13:21 amalloy: trampolines solve everything in real life; why not in clojure too?

13:22 * futile actually wants (#(fixture-3 #(fixture-2 #(fixture-1 test-fn))))

13:24 bbloom: hmmm… the letfn comment about loop layers is interesting

13:24 in theory, if you have mutually recursively defined functions, couldn't you recur from tail position to another function in the letfn block?

13:25 amalloy: bbloom: in scheme you could. in clojure it's not possible, and i don't think mmarczyk can change that

13:26 i mean, i guess he could conceivably code-walk the letfn and transform it to a single function, but it would be as much work as core.async's go macro

13:26 bbloom: yeah, i guess you'd need to inline all the mutually recursive functions into each other, in case you were to let such a fn escape

13:27 i *really* like the explictness of recur

13:27 super useful to have that checked for you at compile time

13:27 futile: Oh man, I think I have to use recursin.

13:32 callen: bbloom: https://github.com/bmillare/dj.compose

13:33 sigh, did he ignore me again?

13:33 can somebody copy-paste my message to him please?

13:33 that repo might help him.

13:34 Bronsa: 19:19:53 <callen> bbloom: https://github.com/bmillare/dj.compose

13:34 llasram: futile: (reduce #(partial %2 %1) test-fn [fixture-1 fixture-2 fixture-3])

13:34 futile: llasram: ah!

13:34 llasram: I'm not sure if that's *really* what you want, but produces what you mentioned

13:34 futile: why do you think its not?

13:35 callen: Bronsa: thank you.

13:35 bbloom: Bronsa: i heard him :-P

13:35 llasram: futile: Just seems odd, but thinking about it for a second, I see what you're going for

13:35 futile: llasram: yeah, each fixture receives a function it should call, which is either the test function, or another wrapped fixture.

13:36 llasram: this does that perfectly without forcing the users to wrap all fixture bodies in an anon func

13:36 bbloom: callen: this is interesting. thanks. in generally, i'm deeply interested in this sort of composition

13:36 i frequently lament about the fact that extend is useless b/c all the core abstractions are still interfaces :-/

13:38 callen: bbloom: glad it was useful. good luck.

13:38 bbloom: here's a puzzler, is there a way to generate java annotations with Clojure without using AOT/gen-class?

13:38 bbloom: ideally with proxy?

13:39 I saw the clojure.asm and AnnotationVisitor

13:39 doesn't seem like there's anything shake-n-bake.

13:39 llasram: callen: This came up a few days ago... I'm not sure it actually worked out for aphyr, but can invoke the internals of gen-class w/o AOT, and give the results to the same class-loader used by deftype

13:39 callen: composing proxy could be annoying.

13:39 llasram: he was in here last night and it still hadn't been resolved.

13:40 llasram: Oh, well, there we go

13:40 (checks some logs)

13:40 callen: I think realistically it's going to require rewriting/wrapping proxy and using the AnnotationWriter/AnnotationVisitor.java stuff in clojure.asm.

13:41 llasram: Hmmm, I wonder why the reach-into-internal stuff didn't work for him

13:42 stuartsierra: callen: deftype supports annotations.

13:42 https://github.com/clojure/clojure/blob/229bf8fe9a751e4f48bb2b7ea57e27ebc43d26ae/test/clojure/test_clojure/annotations/java_6.clj

13:44 callen: stuartsierra: I tihnk it's needed for proxying classes from Netty.

13:44 stuartsierra: I'm pretty sure aphyr already knows he can use annotations with deftype.

13:44 That's not the issue.

13:45 stuartsierra: Oh, sorry, I tuned in halfway through.

13:45 callen: stuartsierra: Netty uses/requires annotations and it's making his life difficult. Proxy needs to support annotations for better java interop.

13:46 stuartsierra: I recall using Netty in the past (version 3.x?), and I didn't need any annotations then.

13:46 callen: stuartsierra: aphyr is out on the hairy edge apparently.

13:47 stuartsierra: Often annotation-based APIs have an alternative, lower-level API that doesn't require annotations.

13:47 callen: stuartsierra: http://docs.jboss.org/netty/3.1/api/org/jboss/netty/channel/ChannelPipelineCoverage.html http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/class-use/ChannelHandler.Sharable.html

13:47 stuartsierra: I'm sure, given the signs of madness he was exhibiting, if such a thing were possible he would've done so.

13:47 proxy needs to support annotations.

13:48 stuartsierra: OK, I'm not disputing that.

13:49 When faced with an annotation-heavy Java API, I usually recommend writing wrapping Clojure functions in Java to do the annotation stuff.

13:49 s/writing//

13:50 callen: I'd rather fix proxy.

13:50 futile: What's that function that lets "defsomething" macros keep the metadata users gave it?

13:55 Saw it a lot in clojure.core functions, can't remember which ones though.

13:56 gfredericks: futile: if the macro passes the symbol through then it's normally not an issue I think

13:56 pbostrom`: futile: name-with-attributes?

13:57 futile: sounds right

13:57 except i thought whatever it was was in core

13:58 gfredericks: oh i think im just losing metadata because my macro uses with-meta instead of vary-meta

13:58 you're right. thanks.

14:07 miwa: I went to bed too late last night after having started to explore the world of clojure.. I dreamed of rainbow coloured parantheses o.O

14:07 seangrove: miwa: There's an emacs mode for that

14:08 miwa: well, I'm a vim user =P

14:08 callen: miwa: sorry to hear that.

14:08 seangrove: Well, heaven have mercy

14:08 Does your family know?

14:08 miwa: hah, I've even converted one or two emacs users actually ;)

14:08 seangrove: miwa: vim's good stuff, no worries :)

14:09 https://github.com/kien/rainbow_parentheses.vim

14:09 zilti: I once tried to use vim, I didn't even manage to set it up for clojure

14:09 miwa: well, setting it up is the hard part unfortunately zilti

14:10 zilti: Though I'd miss elisp too much.

14:10 futile: welp

14:10 ChongLi: vim is great for editing tasks

14:10 zilti: And orgmode

14:10 futile: writing good macros is hard

14:10 ChongLi: emacs is great for running processes like repls and stuff

14:10 miwa: well, I hear there's a vi mode in emacs for those who are so inclined :P

14:10 ChongLi: yeah evil

14:10 futile: ive been impressed by the architecture of Sublime Text

14:11 its like Emacs but for 2013 instead of 1982

14:11 miwa: yeah, Sublime Text seems pretty cool.. it's a bummer it isn't free though =/

14:11 ChongLi: yeah that's a dealbreaker

14:11 futile: thats what employers are for, to pay for it

14:11 zilti: But it's not using lisp... bah

14:11 futile: zilti: so?

14:11 ChongLi: it's not about the money

14:11 futile: ChongLi: oh, libre?

14:11 zilti: Sublime is free, isn't it? It's "just" not open

14:11 ChongLi: yes

14:12 futile: ChongLi: yeah, i dont care about that anymore. look what good libre did to emacs.

14:12 its stuck in 1983 thanks to libre

14:12 ChongLi: that does not follow

14:12 futile: and look at linux vs mac. libre isnt doing anything for me, the user.

14:12 * nDuff can't agree.

14:12 zilti: Well, I'd not want Emacs to change much

14:12 ChongLi: I'm sorry you feel that way

14:13 futile: ChongLi: i believe you

14:13 llasram: Yeah....... RMS's fears of non-free software polluting Emacs through runtime shared library loading aren't exactly a necessary property of libre software

14:13 futile: i used to care about libre on principle, but pragmatially, it gives me no real power as a user.

14:13 ChongLi: clojure is libre as well

14:13 nDuff: futile: speaking as an end-user, I feel hamstrung whenever I use a system I can't get into the guts of and modify.

14:13 futile: ...and, to be clear, I _do_ use that capability with some frequency.

14:13 llasram: (inc nDuff)

14:13 lazybot: ⇒ 4

14:13 ChongLi: if it weren't, most of us likely wouldn't be here

14:14 futile: i think that xkcd about scripting linux to keep the screen from going black sums up my argument against any supposed benefit of libre

14:14 fowlslegs: I am having a problem with the clojure.java.javadoc api

14:14 The javadoc function is rendering incromprehensibly

14:14 futile: "oh she got dressed and left only 30 minutes into me reading the manual on scripting the cursor"

14:15 or however it goes

14:15 fowlslegs: Is there a way to fix this or should I investigate alternative java documentation?

14:15 seangrove: fowlslegs: Sorry, haven't used the javadoc pieces at all

14:15 ChongLi: futile: you could repeat the same exercise with pretty much any proprietary software product

14:15 nDuff: futile: last month, I patched Ivy to add SSH agent support; to fix revision mapping support, and... eh, something else.

14:15 ChongLi: it does nothing to support your point

14:15 nDuff: futile: if the source had been closed, I would have had no recourse at all.

14:15 seangrove: I don't get the feeling that it's used all that much

14:15 futile: ChongLi: right. meaning libre or not makes no difference.

14:15 fowlslegs: seangrove: thanks!

14:16 ChongLi: futile: convenience is not the goal of free software

14:16 freedom is

14:16 futile: nDuff: not true. if the demand is high enough, a competitor comes out that gives you what you really want, and kills out the other guy

14:16 fowlslegs: anyone else know about the javadoc fxn?

14:16 nDuff: futile: that's in the long run. In the long run, as they say, we're all dead.

14:16 futile: ChongLi: freedom is a means to an end, not an end in itself

14:16 nDuff: futile: The short run matters.

14:16 futile: nDuff: no, in the short run too. datomic for example.

14:16 ChongLi: without freedom, you may lose everything

14:17 nDuff: futile: in the short run, I can't typically afford switching costs.

14:17 fowlslegs: Or does anyone know of a doc library that's good and contains java?

14:17 futile: ChongLi: thats an exaggeration

14:17 datomic isnt libre and its wonderful compared to postgres and mongo which are libre

14:17 nDuff: futile: ...and, by the way, the licensing on datomic hurts it a lot.

14:17 ChongLi: futile: tell that to the users of google reader

14:17 futile: nDuff: time will tell if it actually does hurt it or if thats just a false opinion

14:17 nDuff: futile: I haven't been able to use it in any of the places I've worked since it came out due to the licensing

14:17 futile: nDuff: even datomic free?

14:18 nDuff: futile: ...because we weren't willing to put down $$$ until we knew it was worth it, and we couldn't evaluate without risking lockin.

14:18 zilti: I don't mind using non-libre software sometimes, but as a future software developer I'll do everything I can to make my money with libre software

14:18 nDuff: futile: go with free, and you're betting transition costs on the product being worthwhile.

14:18 futile: that's a hard sell to management.

14:19 futile: nDuff: yeah, so some corporations lose out in the shortest-term due to that. but maybe thats actually a good thing. if you'd jumped in and found out it wasnt performant, youd have lost that valuable time. better for everyone to wait til it proves itself, not just people who dont wanna pay

14:19 ChongLi: i dont know any users of google reader

14:19 seangrove: nDuff: same concerns over lock-in with datomic as well

14:20 nDuff: futile: "better for everyone to wait" gets you things like the Python2->Python3 transition, where it's years after 3.0 is called preferred by the dev team but everybody is waiting for someone else to go port libraries over first.

14:21 futile: nDuff: thats a library concern, not analogous to datomic's issue. once datomic proves itself, everyone can jump in without hesitation. python3 isnt adopted because every lib author needs to wait for every other lib author.

14:22 nDuff: futile: how in the world is datomic going to prove itself is the strong majority of its userbase aren't willing to consider it because it's unproven and too risky to use the free version for a pilot that might need to scale?

14:22 futile: if people _do_ use it successfully, you have things like Viaweb's use of Common LISP

14:22 -- a competitive advantage they keep to themselves and don't publicize.

14:22 ...so others don't *know* that it's been used successfully until years after the fact.

14:23 futile: nDuff: thats only assuming every one of them needs that competitive advantage, which im sure they wont.

14:23 if we were to use datomic where i work, im sure we wouldnt mind publicizing that fact, we dont have many competitors.

14:23 our niche is something else, not how well we scale.

14:23 nDuff: futile: Right. Fact of the matter is that the Clojure community is limited in size. There are only so many potential adopters you can afford to drive off.

14:24 futile: nDuff: isnt datomic just java? tons more people can use it than just us.

14:24 nDuff: futile: Not everyone's projects are going to work out -- many to most will fail for reasons completely unrelated to the datastore.

14:24 futile: not to mention it uses rest lately, so even rails guys can use it

14:24 nDuff: futile: it's "just Java", but it's not nearly as usable from Java.

14:24 futile: nDuff: heh, nothing is :)

14:24 nDuff: ...is the impression I got last time I looked.

14:24 As in, hard enough to use from Java that nobody would want to.

14:24 zilti: futile: You still have to write the requests in EDN aka Clojure if you use it from Java

14:25 futile: zilti: edn isnt hard for java devs to learn for this small purpose

14:25 look, we're way off topic

14:25 nDuff: futile: anyhow, any shop using Java is a place prioritizing being able to replace their staff over making their staff productive

14:25 zilti: So in Clojure you can use data structures but in Java you have to put together Strings

14:25 nDuff: those aren't the places that are going to be using Datomic anyhow.

14:25 futile: my main point was that Sublime Text looks like its emacs-done-right. and thats pretty cool.

14:25 main thing holding me from switching altogether is that its paredit-mode is lacking some important keys

14:26 zilti: just like sql

14:26 which they've managed fine so far ;)

14:27 anyway, writing good macros is hard.

14:27 zilti: Damn, today is the first time I hate clojurescript for not having runtime macros...

14:27 futile: oh?

14:28 amalloy: does anyone happen to know what the jvm does when it receives a signal (sigterm, sigint, etc)? it seems to be doing basically what i want (giving InterruptedException to my running threads, then shutting down), but i wonder if that's actually what's going on, and whether that's promised behavior

14:29 hyPiRion: amalloy: Starts a new thread with max priority, and handles the Signal through a SignalHandler

14:29 zilti: I'm working on a project where it should be possible to just define forms for database editing with basically no logic to be inside, and have to somehow get that form out, modify it and listen to everything. Would have been way easier with some clojure.walk magic in a macro

14:31 hyPiRion: What happens with the specifics one, I'm not sure. Most of them are implemented natively, for whatever reason.

14:34 futile: ,(let [list [:foo :bar "baz" :quux :yay], [a [b & c]] (split-with (complement string?) list)] [a b c])

14:34 clojurebot: [(:foo :bar) "baz" (:quux :yay)]

14:34 futile: sweet

14:34 is that terrible code, or fine?

14:36 seangrove: futile: the code seems fine, but the intent seems terrible

14:36 futile: seangrove: whyzat?

14:36 seangrove: But I don't know what you're trying to do, so maybe it makes sense

14:36 futile: well, im writing a horrible macro.

14:36 Raynes: "That sounds like a terrible idea! I don't know what it is, but I bet it's horrible!"

14:36 futile: :D

14:36 im making this work (deftest "testing foo" ...body...)

14:37 except, since it uses a string instead of a symbol, you cant put metadata before that string, since it wont compile

14:37 so im going to just let people put a list of keywords there that will act like ^:kw

14:37 seangrove: Raynes: Far too many bangs

14:38 futile: ie (deftest :foo :bar "testing something" ...body...)

14:38 which i admit is "terrible, just terrible". but i dont have a better idea yet.

14:38 seangrove: futile: That's not so bad

14:38 It just wasn't clear why you'd be splitting/destructuring like that from the a b c example

14:39 futile: the inconsistency between ^:foo and :foo is bad

14:43 squidz: zilti: how would you do it with javascript?

14:44 zilti: squidz: Oh, I won't touch javascript, I'll stick to clojure :) Sure there's a way, but runtime macros would have made it simpler.

14:44 futile: is there a better way to do this? &(into {} (map vector [:a :b :c] (repeat true)))

14:44 oops i meant &&(into {} (map vector [:a :b :c] (repeat true)))

14:44 oh man whatever.

14:44 ,(into {} (map vector [:a :b :c] (repeat true)))

14:45 clojurebot: {:a true, :b true, :c true}

14:45 hyPiRion: ,(zipmap [:a :b :c] (repeat true))

14:45 clojurebot: {:c true, :b true, :a true}

14:45 SegFaultAX: arohner: Ping.

14:45 arohner: pong

14:45 SegFaultAX: arohner: Circle is awesome.

14:45 arohner: thanks :-)

14:45 SegFaultAX: Is github integration on the roadmap?

14:46 fowlslegs: (.printStackTrace *e) is giving me nil

14:46 arohner: WDYM, integration?

14:46 fowlslegs: but an exception was just thrown

14:46 SegFaultAX: I want to replace our CI with circle, but my team needs github commit status api.

14:46 arohner: we already do that

14:46 SegFaultAX: :O

14:46 Docs?

14:46 squidz: zilti: exactly

14:46 fowlslegs: any ideas on where the error is?

14:47 callen: SegFaultAX: what are they using right now?

14:47 SegFaultAX: arohner: Also, I really enjoyed your talk on infoq.

14:47 arohner: SegFaultAX: you shouldn't need to configure anything

14:47 SegFaultAX: arohner: Orly?

14:47 arohner: if we run the build, it updates commit status

14:48 SegFaultAX: arohner: Weird, the initial tests we did didn't seem to do that. But maybe we missed it since we're also testing codeship

14:48 arohner: thanks! you might also enjoy https://www.youtube.com/watch?v=9wgsDosgWhE . I was going to do that talk, then it interfered with my honeymoon

14:48 SegFaultAX: arohner: Are you in SF?

14:48 arohner: most of the time

14:48 SegFaultAX: arohner: You open to lunch sometime?

14:48 arohner: absolutely

14:51 ToxicFrog: How do I take the sqrt of an integer? The docs I can find all refer to 'clojure.contrib.math or 'clojure.math.numeric-tower, neither of which I seem to have (in 1.4)

14:51 futile: is remove-ns expensive?

14:51 ToxicFrog: Should I just make it a double and use java interop?

14:52 llasram: ToxicFrog: It should auto-coerce to a double when you call `Math/sqrt`

14:52 zilti: clojure.contrib is "dead" since 1.3

14:52 llasram: ToxicFrog: Or are you looking for an exact answer for when the square root is an integer?

14:53 ToxicFrog: llasram: nah, I don't need an exact answer

14:54 SegFaultAX: ,(Math/sqrt 16)

14:55 clojurebot: 4.0

14:55 futile: ,(gensym)

14:55 clojurebot: G__31

14:55 futile: ,(gensym "foo")

14:55 clojurebot: foo60

14:55 futile: neat.

15:01 stuartsierra: Huh. clojure.lang.Range isn't used anywhere.

15:02 bbloom: stuartsierra: `git rm` is my favorite command :-)

15:02 egghead: hmm, is there any utility around to split a command line string into an argument vector?

15:02 amalloy: stuartsierra: i always assumed it was an early prototype before lazy-seqs made (range) possible

15:03 stuartsierra: amalloy: That's my guess too. Probably left for backwards compatibility.

15:03 egghead: seems like a tricky problem, things like "foo -x 'bar 23' --foo bar"

15:03 amalloy: egghead: well, your shell will do the "hard" part there, of making "bar 23" a single arg

15:03 tools.cli isn't bad

15:04 egghead: amalloy: I'm taking in command strings as input, so I have to do it myself :(

15:04 bbloom: stuartsierra: but backwards compatibility inhibits my ability to git rm freely.....

15:04 egghead: unless I just forward it to sh -c or something

15:05 seangrove: stuartsierra: Isn't that something codeq could tell you?

15:06 stuartsierra: seangrove: I don't think codeq has a Java parser yet.

15:06 fowlslegs: Can someone help me understand a REPL error I am having?

15:07 seangrove: stuartsierra: Ah, good point

15:07 fowlslegs: It should be quite simple for most here I'm sure.

15:08 llasram: fowlslegs: Questions are welcome, so need for ceremony before asking :-)

15:08 s,so need,so no need,

15:08 fowlslegs: So I have this fxn: http://paste.ubuntu.com/5912118/.

15:09 llasram: Ok

15:10 fowlslegs: And when I try to use java.lang.Math methods I get this error "CompilerException java.lang.RuntimeException: Unable to find static field: hypot in class java.lang.Math, compiling:(NO_SOURCE_PATH:1:1)".

15:10 llasram: Oh, that's because JVM object static methods aren't Clojure functions

15:10 fowlslegs: For example, (f-values Math/hypot 5 5) gives me this.

15:10 llasram: Right. ##(class Math/hypot)

15:10 lazybot: java.lang.RuntimeException: Unable to find static field: hypot in class java.lang.Math

15:11 llasram: That's a method, which isn't a "thing" you can pass around

15:11 You need to wrap it in a function, which can be anonymous, like (f-values #(Math/hypot %) 5 5)

15:12 Because then: ##(class #(Math/hypot %))

15:12 lazybot: java.lang.IllegalArgumentException: No matching method: hypot

15:12 llasram: Hah

15:12 Because then: ##(class #(Math/sqrt %))

15:12 lazybot: ⇒ sandbox11278$eval15202$fn__15203

15:12 llasram: Anyway

15:12 You get the idea

15:15 fowlslegs: Hmmm maybe I need to read up on methods

15:15 I don't really understand how they differ from functions.

15:16 gfredericks: they're interop things

15:16 has anybody written an intro-to-the-jvm-for-clojure-programmers yet?

15:16 fowlslegs: (Math/hypot 1 1) works

15:16 gfredericks: I might volunteer if not

15:16 seangrove: gfredericks: That would be wonderful

15:17 gfredericks: okay that's on my todo list

15:17 maybe this weekend

15:18 fowlslegs: So why does it work in this single instance, but not when I use the for macro to use it generate the third value of each vector in my lazyseq

15:18 gfredericks: fowlslegs: are you still tripping on (f-values Math/hypot 5 5)?

15:18 zerokarmaleft: gfredericks: jvm = vm internals or core libraries often used via interop?

15:19 fowlslegs: yes

15:19 gfredericks: zerokarmaleft: not vm impl -- like the object model (what are methods? interfaces? etc?), the classpath, properties...

15:20 suggestions welcome

15:20 fowlslegs: try (f-values #(Math/hypot %1 %2) 5 5)

15:22 also should it be a blog post or something more communal?

15:22 llasram: gfredericks: Inner classes (because it's such a commonly asked question). Probably how `.method` and `Constructor.` are builtin pseudo-macros (or whatever the official name is)

15:22 zerokarmaleft: gfredericks: that sounds more like a communal effort

15:22 there's a lot of rabbit trails

15:22 gfredericks: should check that clojure-doc site

15:22 llasram: Maybe something on clojure-docs

15:22 clojure-doc even

15:23 Huh, which seems to be in a sadness-state right now

15:23 Oh, there already is one: http://clojure-doc.org/articles/language/interop.html

15:23 gfredericks: by which you mean it's missing its stylesheets?

15:24 llasram: And having encoding issues

15:24 gfredericks: I feel like an interop guide should be a separate thing

15:25 llasram: A separate thing from what?

15:25 gfredericks: an intro to the jvm

15:25 llasram: Ah

15:25 gfredericks: you can tell somebody "here's how you call a static method" and that's interop, but if they don't know what a static method is in the first place...

15:25 llasram: That does seem reasonable

15:25 zerokarmaleft: gfredericks: I remember handling those gaps by just shoehorning myself into java for awhile

15:25 gfredericks: I didn't have them since I had done java enough

15:26 zerokarmaleft: you wrote java code?

15:26 zerokarmaleft: only in an academic setting, years before I started clojure

15:26 which is to say, not really

15:26 fowlslegs: gfredricks: thanks very much. I just read up on the #() reader form.

15:28 gfredericks: zerokarmaleft: I was referring to your "shoehorning myself into java for awhile"

15:28 fowlslegs: np

15:29 fowlslegs: equivalent would be (fn [a b] (Math/hypot a b))

15:30 ltw: Can Clojure libraries be made interoperable with Java?

15:30 zerokarmaleft: gfredericks: oh yes, I did some stuff with hadoop in java even though I knew about cascalog

15:31 konr: haha, so amazing; I managed to get our scala programmer excited about clojure just by showing my test suite :)

15:33 fowlslegs: gfredericks: So I still don't understand *why.* Should I read up on Java?

15:33 gfredericks: So I still don't understand *why.* Should I read up on Java?

15:33 zerokarmaleft: gfredericks: it was more like revisiting an old language I was already familiar with and applying it to some useful albeit small scope

15:34 gfredericks: ltw: you're asking about java code calling clojure libs?

15:34 ltw: gfredericks: yeah, I want to write a library that will be called from Clojure and Java, but I want to write it in Clojure.

15:35 gfredericks: ltw: yeah you can go one of two ways depending on how easy you want to make it from the java side

15:35 anything you can do in clojure can be done clunkily from java via the RT class

15:35 so in that sense any clojure lib trivially qualifies

15:35 zerokarmaleft: fowlslegs: you can read up on Java a la carte as you run into jvm concepts that are unfamiliar

15:35 gfredericks: but you can also generate classes with methods, which makes it much cleaner from java

15:36 ltw: gfredericks: oh, like using gen-class?

15:36 gfredericks: that certainly works

15:37 I think I wrote a lib once for exporting a whole namespace as a java class with static methods

15:37 https://github.com/fredericksgary/lib-2367#export-ns

15:37 it uses gen-class

15:37 but is minimal effort

15:37 ltw: I think I'll go that way if it's reasonably non-trivial.

15:38 fowlslegs: thanks, will do

15:38 callen: Raynes: that's what you get for writing Haskell.

15:38 ToxicFrog: I'm running into something really weird with a recursively defined lazy infinite seq: http://hastebin.com/duforatapi.lisp

15:38 ltw: gfredericks: I think you've just solved the only problem I saw with the gen-class method approach.

15:38 it's a client library wrapping a service, so there was going to be many function definitions

15:38 gfredericks: my work here is done

15:39 Raynes: callen: I'm not writing Haskell. Just observing how horrible the support for it in Vim is. I mean, I can use Emacs for it, but Christ. After all these years I would have expected it to at least be able to indent Haskell half-assed.

15:39 ToxicFrog: I would expect that (0 1 2) are in the seq (because they are < 3), and then 3 and 4 should be also (because by the time it's calling (tasty? 3) it's realized the list head and discovered that is (= 0)

15:40 Instead it seems to be the case that (first tasty) is something other than 0 until it calls (tasty? 32) and then suddenly it is 0.

15:40 Is this a weird interaction with (declare)? Am I not understanding something fundmental about how lazy seqs work?

15:41 gfredericks: ToxicFrog: this is super weird

15:41 ToxicFrog: (this is 1.4.0, btw)

15:41 gfredericks: I get it in 1.5.1 too

15:42 ToxicFrog: Also I'm glad it's not just me who thinks it's weird

15:42 gfredericks: ToxicFrog: this has something to do with chunking

15:42 which you can tell by replacing (range) with (iterate inc 0)

15:43 ltw: is there an existing convention on how to name Clojure libraries that are interoperable with Java? (I have a Ruby library for this functionality already)

15:43 gfredericks: but I haven't figured out why that should be relevant though

15:43 Raynes: Not really, because nobody writes libraries that are interoperable with Java.

15:43 They value their sanity.

15:43 :p

15:43 stuartsierra: ToxicFrog, gfredericks: You're running into chunked lazy sequences there.

15:44 The 32 is a giveaway.

15:44 gfredericks: stuartsierra: oh definitely

15:44 stuartsierra: that's what I just said -- it's just not clear why it's relevant

15:44 as best I can tell, the act of computing a chunk of a chunked lazy seq is calling first on itself

15:45 which is not throwing an exception but is instead returning something weird

15:45 ltw: Raynes: ha, I'd rather write it once in Clojure and make it interop than have to write it in Java.

15:46 ToxicFrog: Adding a (println) says that it's nil until the first 32 elements have been evaluated, then 0

15:47 gfredericks: looks like (first my-chunked-seq) is nil during the computation of the first chunk

15:47 oh you just found out the same thing

15:47 ToxicFrog: Is there any documentation on chunked sequences? The docs for (range) don't mention that it chunks, nor that this optimization(?) may break things.

15:47 gfredericks: ToxicFrog: yeah I'd say a self-referential chunked lazy seq is a bad idea :)

15:47 ToxicFrog: in general a self-referential lazy seq probably shouldn't be necessary I don't think

15:48 ToxicFrog: gfredericks: necessary, no, but it's a convenient way to write some things

15:48 (I ran into this when making a simple prime generator as practice; when testing to see if the next number is prime it's useful to be able to refer to earlier primes)

15:49 (there are undoubtedly non-toy applications for this technique)

15:49 jcromartie: there needs to be a Jekyll for Clojure…

15:49 this is happening

15:49 gfredericks: jcromartie: somebody was working on that a week or so ago

15:50 ToxicFrog: gfredericks: in any case it should probably be mentioned in the docs for functions that generate chunked sequences that they do so and are thus not safe for recursion.

15:51 I would not normally expect replacing (range) with (iterate inc 0) to change the results of my code.

15:52 stuartsierra: Most of the core sequence functions used chunking when possible as an optimization.

15:52 s/used/use/

15:53 In general, Clojure's lazy sequences make no guarantees about *when* a particular part of the seq is realized.

15:53 ToxicFrog: I think the underlying surprise here is that I thought it was guaranteed that (first foo) would be realized before (rest foo)

15:54 When this is not actually the case.

15:54 futile: So,

15:54 the other night, I did "lein deploy", typed in my credentials, and it Just Worked™

15:54 today i try again, and it gives me a confusing msg

15:54 ToxicFrog: IT seems likely that this guarantee isn't actually stated anywhere, but it's still super surprising.

15:57 futile: Ah. I really did "lein deploy clojars" last time.

15:57 Works like a charm.

15:58 ToxicFrog: gfredericks, stuartsierra: to make it even more confusing, (chunked-seq? tasty) returns false in both versions

15:59 As does (chunked-seq? (take 5 tasty))

16:01 SegFaultAX: ToxicFrog: It just occured to me that I know you from #lua.

16:01 stuartsierra: chunked-seq? isn't documented, probably an internal function.

16:01 atyz: Hey all - I'm doing the following (with kormasql) https://www.refheap.com/16907 and getting an error saying I cannot use Can not issue data manipulation statements with executeQuery(). I've done some research and It would require me using executeUpdate() . Is there a way to get around this?

16:02 futile: ok

16:02 nevermore 0.0.1 released, its official :)

16:02 ToxicFrog: SegFaultAX: yep

16:03 stuartsierra: anyways - is there literature on sequence chunking, which functions I should beware of, etc?

16:04 stuartsierra: ToxicFrog: Not that I'm aware of. Assume any core function which generates a sequence may use chunking.

16:04 ToxicFrog: :(

16:05 llasram: ToxicFrog: What's the actual ultimate problem?

16:05 gfredericks: he wants to use haskell-style laziness-backed self-reference

16:05 ToxicFrog: ^ that

16:05 stuartsierra: Then use Haskell.

16:06 llasram: Oh. You can always explicitly unchunk your sequences

16:06 ToxicFrog: Sadly my underlying assumption that the n'th value in the seq won't be realized until after the (n-1)th value has been turns out to be false.

16:06 bbloom: ToxicFrog: decompile the problem into a lazy traversal and a state machine

16:06 s/decompile/decompose

16:06 ToxicFrog: llasram: how? (and how did you learn about chunking?)

16:07 bbloom: if you need linear execution, just loop over a sequence and conduct your side effects in the loop

16:07 ToxicFrog: bbloom: there are no side effects.

16:07 bbloom: ToxicFrog: evaluation is a side effect

16:07 ToxicFrog: I'm just trying to compute an infinite lazy sequence where the value of later values in the sequence is an expression of values earlier in the sequence.

16:07 SegFaultAX: IIRC chunked seqs are implemented in such a way that they should be transparent.

16:08 ToxicFrog: If evaluation is a noticeable side effect your abstraction is leaking, IMO.

16:08 bbloom: ToxicFrog: this is why people complain about understanding space complexity in haskell, b/c you can get UNBOUNDED lookahead w/ laziness

16:08 llasram: ToxicFrog: I read about it in /Joy of Clojure/ very early in my Clojure-programming. /JoC/ has this function: https://www.refheap.com/16909

16:08 SegFaultAX: Should being the operative term. They exist only as a performance optimization.

16:08 ToxicFrog: SegFaultAX: the genesis of this discussion is that they are actually not; I have code that returns different values when using a chunked seq vs. a non-chunked one.

16:08 bbloom: you can achieve what you want, but you must be explicit about your buffering

16:09 SegFaultAX: ToxicFrog: Bummer :/

16:09 ToxicFrog: bbloom: I would prefer unbounded lookahead (and thus terrible performance, OOMs, etc) to getting the wrong answers quickly.

16:09 llasram: It still depends on the implementation detail that `lazy-seq` recursion is evaluated one thunk at a time, but in practice it works

16:09 ToxicFrog: llasram: thank you.

16:10 bbloom: ToxicFrog: the answer is right, your assumption about the semantics are wrong :-P if you want to achieve haskell-like semantics, you need to implement either A) fully lazy evaluation or B) a particular data structure for your use case

16:10 this is why i'm suggesting: use a state transducer

16:11 SegFaultAX: Probably option b is easier.

16:11 llasram: ToxicFrog: Note that the docstring (which I wrote when I stole the function) isn't actually right -- it doesn't de-chunk the input seq, but returns a new seq which isn't chunked. So you wrap your input, not the seq your producing (if that wasn't obvious)

16:11 SegFaultAX: bbloom: Can you define that term?

16:11 bbloom: https://github.com/brandonbloom/transduce

16:12 llasram: oooh

16:12 ToxicFrog: bbloom: so, the objection I'm arriving at here is that chunking is an optimization that (a) does not seem to be documented outside JoC and (b) when applied can result in actual functional changes even in pure code

16:12 There is no indication which library functions produce chunked sequences, or even that chunked sequences are a thing, and if an optimization is meant to be that completely invisible it had better not change the results of code that triggers it!

16:13 SegFaultAX: bbloom: Ah, neat.

16:13 llasram: omg, bbloom, these are great

16:13 ToxicFrog: Alternately, a warning like "don't try to use self-referential lazy sequences, they will produce garbage due to internal optimizations used by clojure's lazy seq implementation" would be nice,.

16:13 bbloom: SegFaultAX: llasram: thanks!

16:14 zerokarmaleft: why is set! restricted against local vars?

16:14 bbloom: ToxicFrog: i just joined the conversation a tad late, so i need to look at your particular paste & understand the problem

16:14 llasram: ToxicFrog: The problem is that there really isn't a good way to tell when you're building a self-referential lazy-seq. If there were, I'd agree there should be a warning

16:14 SegFaultAX: bbloom: That's really useful. I'm sad to only just be learning about this library.

16:14 ToxicFrog: bbloom: http://hastebin.com/duforatapi.lisp

16:15 alandipert: zerokarmaleft: i take it you mean lexical bindings? it's because there isn't a mutable reference type (Var) behind them

16:15 ToxicFrog: bbloom: If you replace (range) with (iterate inc 0) it works.

16:15 SegFaultAX: ToxicFrog: The whole point of range chunking is that it's more efficient to generate groups of numbers rather than single values.

16:15 alandipert: zerokarmaleft: it can be achieved via macros though, see https://github.com/ztellman/proteus

16:16 SegFaultAX: If you're ok with the potential performance hit, though...

16:16 zerokarmaleft: alandipert: well, a bit more context, I'm simply trying to mutate a DOM element

16:16 bbloom: ToxicFrog: neither range nor iterate is bugged. your example is using declare to create mutual recursion but you're missing one level of indirection

16:16 ToxicFrog: SegFaultAX: which is fine. But it's a performance optimization that can change program behaviour and thus should be more visible than it is.

16:16 zerokarmaleft: e.g. (set! (.-innerHTML el) "foo")

16:16 ToxicFrog: bbloom: how/where?

16:16 alandipert: zerokarmaleft: oh, you probably want 'aset'

16:17 (aset el "innerHTML" "foo")

16:18 ToxicFrog: What should I have done instead to avoid this? What should I have read to know I was meant to do that?

16:18 zerokarmaleft: alandipert: perfect, thanks

16:18 odd that set! seemed to compile and run fine intermittently

16:18 bbloom: ToxicFrog: (first tasty) is going to be a constant

16:19 or should be

16:19 llasram: ToxicFrog: I don't think there was anything official you could have read. It's come up a few times on the mailing list, but AFAIK is basically tribal knowledge

16:19 ToxicFrog: bbloom: this is just a minimal test case; in practice (first tasty) might be some more complicated expression involving, say, (take limit tasty) where limit is some function of n.

16:20 bbloom: ToxicFrog: change (first tasty) to (doto (first tasty) prn) and you'll see what's happening

16:20 you're getting 32 nils

16:20 ToxicFrog: I already know that

16:20 bbloom: b/c (first UNDEFINED-VAR) is bad

16:21 gfredericks: bbloom: he knows what's happening he thinks it should not happen or be better documented

16:21 bbloom: if you want mutual recursion, you must define things simultaneously

16:21 i dunno what he want's documented

16:21 gfredericks: "don't use self-referential chunked seqs"

16:21 and also "chunked seqs exist"

16:21 ToxicFrog: ...how do I do that? Because last time I looked for "how do I do mutual recursion in clojure" the answer I got was "(define) one of the things first"

16:21 xpe: in choosing a JDK for Clojure, is there a significant difference between 7 and 8?

16:21 bbloom: no, it's don't use mutual recursion without a layer of indirection

16:21 ToxicFrog: bbloom: what gfredericks said.

16:21 xpe: or runtime?

16:21 bbloom: it's more than just chunked sequences

16:21 ToxicFrog: Ok, what layer of indirection? You keep saying I'm missing one and I'm asking what

16:22 bbloom: you're trying to evaluate tasty? while tasty is being defined

16:22 that's undefined behavior b/c it's mutually recursive

16:22 you need to add a delay or a fn call

16:23 and if you do that, you'll get a stack overflow, which is precisely what your function is trying to do :-P

16:23 gfredericks: now we need documentation saying "Don't be mutually recursive because it's undefined"

16:23 bbloom: it works perfectly well w/o chunking

16:23 bbloom: by luck

16:23 ToxicFrog: ...well, no, because by the time (tasty?) needs to evaluate part of tasty, the parts of tasty it's referring to are already realized non-recursively

16:23 bbloom: b/c of some internal order of execution

16:24 gfredericks: bbloom: if "some internal order of execution" means "evaluating lazy seqs in order one item at a time" then yeah

16:25 ToxicFrog: The first three values of tasty (0 1 2) are evaluated without any recursion; 3 onwards require evaluation only of (head tasty). It does not seem controversial that "the elements of a lazy seq are realized in order" is a reasonable assumption to make, and that the fact that this assumption is wrong should be documented.

16:25 gfredericks: for the record I don't think we should write code like this; but I think it's reasonable that he had different expectations and that this will happen to others

16:25 bbloom: i agree with that gfredericks

16:26 gfredericks: ToxicFrog: they _are_ realized in order, just some of them in parallel

16:26 ToxicFrog: Yeah, I would also be ok with the answer to "how do I do mutual recursion in clojure" being "don't", even if that is a really aggravating restriction in some cases

16:26 As long as that was actually documented somewhere.

16:26 bbloom: gfredericks: parallel == "observably simultaneously" ?

16:26 gfredericks: bbloom: I think so yes

16:26 bbloom: certainly I didn't mean wrt threads and such

16:27 supersym: is it me or do other ppl find defrecord a bit unwieldy as well

16:27 amalloy: ToxicFrog: that's not really true, though; the thing that's discouraged is self-recursive data structures

16:27 mutually-recursive functions are fine, although because we lack TCO you have to be careful

16:28 ToxicFrog: gfredericks: that doesn't really count as "in order" to me; "in order" implies that, at the moment the n'th element of the sequence is realized, all prior elements have already been realized.

16:29 gfredericks: ToxicFrog: okay; definitions I guess

16:30 ToxicFrog: gfredericks: basically the assumption of mine that was violated was that s[n] will always be realized after realization of s[n-1] is complete (and thus, by implication, that a definition of s[n] that depends on s[m] where m<n is safe).

16:32 bbloom: ToxicFrog: that assumption is valid, what assumption is invalid is that the evaluation of s[n] and s[n-1] will necessarily occur at alternating locations in the stack frame

16:33 in theory, chunking could maybe recognize and correct this

16:35 gfredericks: bbloom: but probably wouldn't if it makes it slower

16:36 bbloom: gfredericks: probably

16:36 all this discuss, incidentally, motivates my total lack of interest in the academic obsession with non-termination

16:37 the fact that evaluation TAKES TIME is a lie that haskell programmers wish would go away :-P

16:37 is IS NOT a lie & that

16:37 i failed to say that in any way that makes sense, but somebody will understand wtf i'm talking about

16:38 futile: is it a terrible idea to do (alter-meta!) on #'some-var which will be thrown away in a minute anyway?

16:40 gfredericks: you're throwing away vars?

16:41 futile: gfredericks: via (remove-ns)

16:41 ,(clojure.string/join "," [1 2 3])

16:41 clojurebot: "1,2,3"

16:42 futile: ,(do (remove-ns 'clojure.string) (clojure.string/join "," [1 2 3]))

16:42 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string>

16:42 futile: ,(clojure.string/join "," [1 2 3])

16:42 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string>

16:42 futile: oops

16:42 ,(require 'clojure.string)

16:42 clojurebot: nil

16:42 futile: ,(clojure.string/join "," [1 2 3])

16:42 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string>

16:42 futile: ,(require :reload 'clojure.string)

16:42 clojurebot: nil

16:42 futile: ,(clojure.string/join "," [1 2 3])

16:42 clojurebot: #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.string>

16:42 * futile panics

16:47 futile: dont worry ill figure this out

16:51 ok yeah i give up

16:51 i broke it. im sorry.

16:52 llasram: ,(do (require 'clojure.string) (clojure.string/join "," [1 2 3]))

16:52 clojurebot: "1,2,3"

16:52 futile: but.. but..

16:52 i tried that, didnt i?

16:52 ,(clojure.string/join "," [1 2 3])

16:52 clojurebot: "1,2,3"

16:53 PuercoPop: Oi, in order to use select from enlive do I have to transform the html string into an specific representaion?

16:54 squidz: is it possible to create and use source maps now wwith clojurescript?

16:54 ToxicFrog: bbloom: what?

16:55 bbloom: ToxicFrog: what about what?

16:55 ToxicFrog: If, during evaluation of s[n], the value of s[n-1] is nil, it is not the case that s[n-1] has been realized (even if the value has been computed internally and is being buffered somewhere invisible to my code)

16:56 And I'm not sure what you mean by "alternating locations in the stack frame"

16:56 gfredericks: I also don't know what he meant by that

16:57 futile: llasram: thanks for fixing it somehow :)

16:58 llasram: Computers just like me

16:58 bbloom: it's the difference between (do (realize! s n) (observe! s n) (realize! s m) (observe! s m)) vs (do (realize! s n) (realize! s m) (observe! s n) (observe! s m))

16:58 squidz: together with lein cljsbuild i mean

16:59 bbloom: actually, it's worse than that

16:59 ToxicFrog: bbloom: except in either case (realize! s m) is called after (realize! s n) completes, and thus (observe! s n) should succeed if (realize! s m) calls it.

17:00 When, in fact, it doesn't.

17:01 bbloom: let me clarify a few things: 1) i'm not saying clojure is PERFECT here. surely it may be possible to improve this behavior to meet your expectations w/o violating anybody else's 2) i think it's perfectly reasonable for this behavior to be undefined

17:02 now, with that said, the issue is more subtle than what i said, b/c it's really

17:02 ….

17:02 (realize-cps! s n callback)

17:02 or rather k for continuation

17:02 (realize-cps! s n k)

17:02 and when k gets called is important

17:03 i'm saying that it's currently undefined when it gets called, you're saying there is a reasonable definition

17:05 does that explain my comment?

17:06 ToxicFrog: Not really; I don't know realize-cps!. Documented?

17:06 bbloom: i just made it up

17:06 that's just realize with a callback

17:06 cps = continuation passing style

17:06 ToxicFrog: Aah

17:07 llasram: cps vs csp -- fight!

17:07 bbloom: llasram: both!

17:08 llasram: heh

17:08 bbloom: llasram: that's like saying "space vs time -- fight!"

17:08 :-)

17:09 ToxicFrog: make sense now?

17:10 ToxicFrog: also, i should add… if you can write a patch that doesn't hurt perf, break anything else, and fixes this, you should submit it!

17:10 ToxicFrog: I don't feel like my brain is entirely here right now, but AIUI you're basically just saying that it is undefined in what order the elements of a lazy seq are evaluated?

17:11 bbloom: i'm saying it's undefined how sequence realization and sequence observation will be intertwined

17:12 lazy sequences are little stateful machines that consumers take on the responsibility of executing, if unrealized

17:12 there is no rule that says the producer can't execute the machine a little bit before passing it along

17:13 ToxicFrog: Right.

17:13 Which is exactly what's happening here: it's evaluating the first 32 elements before making the results of any of those evaluations available.

17:14 bbloom: right, and this issue is only visible b/c you're at the top level

17:14 you would be UNABLE to write the program you write using let, b/c let doesn't allow mutual recursion, so you'd need to use letfn

17:14 or use mutation

17:15 letfn would require you call () to dereference the function name

17:15 which would create infinite recursion

17:15 which is one of two possible outcomes in your (broken) program: infinite recursion, or incorrect termination

17:15 you got incorrect termination

17:15 ToxicFrog: It seems that this should not create infinite recursion; it will eventually hit the base case (s[n] <= 3) and terminate correctly.

17:16 bbloom: ToxicFrog: there exists some set of operation semantics for which your program will not create infinite recursion

17:16 :-D

17:16 def's semantics are different than promises, are different than manual use of set! are different from function calls are different from deref calls

17:17 ToxicFrog: That said, when I get home I'll rewrite this using function calls (and it won't infinitely recur)

17:17 bbloom: yeah, do that

17:17 def is mutation

17:17 declare, def, def == 3 mutations

17:17 letfn will give you observably simultaneous mutations

17:17 ToxicFrog: wait wait wait, where's the third def?

17:18 bbloom: declare, defn, def

17:18 ToxicFrog: Aah.

17:18 I thought you meant three defs of tasty specifically.

17:18 bbloom: no

17:18 letfn will make it seem like all those mutations happen simultaneously

17:18 it acheives that by forcing an indirection on all definitions (that indirection is a function call)

17:18 ToxicFrog: Anyways, the main reason I wanted an infinite seq for this is that then it doesn't need to re-calculate earlier values repeatedly, which it will with fns.

17:19 I guess I could explicitly memoize.

17:19 bbloom: you want to write a corecursive function :-)

17:19 http://squirrel.pl/blog/2010/07/26/corecursion-in-clojure/

17:20 ToxicFrog: I do, and thanks

17:21 mmarczyk: ToxicFrog: (defn unchunk [xs] (lazy-seq (cons (first xs) (unchunk (rest xs)))))

17:21 bbloom: my pleasure, explaining that helped me understand it too :-)

17:21 ToxicFrog: Although based on what just happened it seems like that definition of fib should explode if chunking happens to occur, so either the example is bad or I still don't understand what's going on :(

17:21 mmarczyk: ToxicFrog: if you wrap (range) in unchunk, result will be as you expect

17:21 bbloom: that's why i hang out here. teaching is a great way to learn!

17:21 mmarczyk: not that it answers all the points raised

17:22 ToxicFrog: Anyways, tests run, CLs out for review, to the bus!

17:22 bbloom: mmarczyk: you're the rrb guy, right? awesomeness! just studied that a bit yesterday

17:22 mmarczyk: bbloom: wow, cool :-)

17:23 bbloom: mmarczyk: just so i understand correctly… this would enable vectors to have efficient push/pop on both sides?

17:23 mmarczyk: bbloom: right

17:23 bbloom: although I should say, regular conj (at end) will still be the "natural", fast, zero-cost option

17:23 bbloom: mmarczyk: right b/c you pay some extra cost on the left, but only if you use left push/pop, right?

17:24 mmarczyk: bbloom: whereas conj to front has a certain cost attached in that you'll end up with a less regular tree

17:24 bbloom: right

17:24 bbloom: so i read the abstract, but didn't really dig into the paper

17:24 basically reading/writing to the left (or middle, or splitting, whatever) will somehow manage to preserve amortized costs?

17:24 mmarczyk: bbloom: one of the things I've got on the roadmap is making it so the "new" ops

17:24 bbloom: ie i can't like perma-fuck-up my vectors?

17:24 mmarczyk: bbloom: do a little bit of extra work to try and return regular trees whenever possible

17:25 noncom|2: hi, i am writing a thin wrapper for a java lib and i find myself thin-wrapping lots of getters and setters. Id it okay that all setters names are with exclamation marks? An how do you usually go about naming getters?

17:25 mmarczyk: bbloom: basically there's a limit to how much "damage" there can be, yes

17:25 bbloom: mmarczyk: and even with that damage, the constant factors should beat 2-3 finger trees?

17:26 mmarczyk: bbloom: oh absolutely

17:26 bbloom: killer.

17:26 mmarczyk: bbloom: shouldn't be slower by more than a factor of 2

17:26 bbloom: paper indicates less

17:27 bbloom: actually there's a tradeoff here between concat speed and loss of lookup (etc.) speed

17:27 bbloom: mmarczyk: https://github.com/brandonbloom/fipp/issues/6

17:27 mmarczyk: bbloom: a regular vector is a tree whose shape is completely determined by the lookup algorithm, with the minor tweak of having a separate tail

17:28 bbloom: wow, great! thanks for the link

17:28 bbloom: mmarczyk: i only need left/right push/pop

17:28 mmarczyk: bbloom: I've been chatting with Jozef Wagner lately

17:28 bbloom: mmarczyk: don't need to thank me. thank you for creating cool stuff

17:29 lpetit: Hello, any adventurous Counterclockwise user, willing to give feedback on a new feature I've been developing recently?

17:30 bbloom: mmarczyk: i don't know Jozef Wagner

17:30 mmarczyk: bbloom: heh, I'm rather a fun of fipp and sort of wanted to write factjor myself, so glad to be reciprocally useful :-)

17:30 bbloom: he's been benchmarking cljs recently

17:30 bbloom: mmarczyk: oh cool

17:30 mmarczyk: bbloom: there's a thread on the mailing list

17:31 bbloom: also, there's a ticket of his in cljs jira re: arrayvectors

17:31 bbloom: mmarczyk: fipp and factjor are both part of my master plan… mwahaha

17:31 mmarczyk: bbloom: so he's done some benchmarking with 2-3 finger trees

17:31 bbloom: I imagine they would be :-)

17:31 bbloom: and apparently there's no contest

17:32 bbloom: in fact, funny thing, core.rrb-vector is faster for conj than PV in cljs (so I'll be fixing PV in near future :-P)

17:32 bbloom: mmarczyk: killer.

17:32 mmarczyk: bbloom: that's without any unbalanced trees, but the cost in that should be a small constant factor

17:32 bbloom: mmarczyk: if jonase doesn't take a try for rrb in fipp, i'll do it

17:32 mmarczyk: bbloom: fantastic! also very happy to cooperate on this

17:33 lpetit: mmarczyk: do you envision a point in time where rrb could replace PV in clojure proper?

17:33 bbloom: mmarczyk: after that, i need to port to cljs and explore reducers vs core.async on cljs side b/c i've got a core.async branch that makes fipp multithreaded :-)

17:33 mmarczyk: bbloom: I've noticed the c.async branch, very cool :-)

17:33 bbloom: but the ioc threads variant on jvm is much slower than the reducers variant

17:33 mmarczyk: lpetit: that's possible, but actually getting comparable perf in pure Clojure is a bit of a research project ATM

17:34 lpetit: part of the purpose of core.rrb-vector is to do that research, I think

17:34 lpetit: mmarczyk: okay. What's the gross constant difference for usual usages?

17:34 bbloom: mmarczyk: you mean compared to the java implementation of PV, right?

17:34 mmarczyk: bbloom: right

17:34 bbloom: mmarczyk: so gvec is slower than APersistentVector

17:34 mmarczyk: bbloom: it is

17:35 bbloom: lpetit: by about a factor of 2 IIRC

17:35 bbloom: mmarczyk: but if you can get gvec == APV, then you can get RBB == APV ?

17:35 mmarczyk: bbloom: lpetit: core.rrb-vector is on a par with gvec, with an important caveat

17:35 lpetit: mmarczyk: I must confess I don't know much about gvec

17:35 mmarczyk: bbloom: lpetit: the caveat is that that's only true as long as you only use rrb vectors of objects or rrb vectors of primitives, not mixed

17:36 bbloom: lpetit: I'm going to fix this one way or another... my understanding of what's going on is a bit of a conjecture at this point anyway

17:36 bbloom: and on cljs, there is no host-native-impl, only the cljs-impl, so rrb can definitely == pv, right?

17:36 mmarczyk: bbloom: lpetit: (but I'll take this opportunity to point out that jvm rrb vectors already support both objects and primitives at leaves and interoperate happily with both PV and gvec ;-))

17:36 bbloom: right

17:36 bbloom: glorious

17:36 mmarczyk: great work man

17:36 mmarczyk: bbloom: or at least with a very small extra overhead

17:36 bbloom: looking forward to developments. i'll let you know if/when i switch fipp over

17:37 mmarczyk: bbloom: well the idea and feasibility research is due to Bagwell & Rompf

17:37 bbloom: I totally think they've done a great job :-)

17:37 bbloom: of course. can't forget to thank the smarty pants dudes who write the papers

17:37 mmarczyk: :-)

17:37 bbloom: i'm always glad to see citations in readmes

17:37 i try to make it a habit

17:38 lpetit: mmarczyk: impressive

17:39 mmarczyk: bbloom: lpetit: it's important to note that in contrast to regular vectors, rrb trees' tree shape is not fully determined

17:39 bbloom: lpetit: so there's room for tweaking concat speed vs. lookup & Co. speed

17:39 bbloom: mmarczyk: which is also in contrast to 2-3 trees, too...

17:39 mmarczyk: bbloom: right

17:40 bbloom: lpetit: my plan is to do some extra work in slice/concat to preserve regular tree shape whenever possible (or very nearly so)

17:40 bbloom: if i only need left/right push/pop, can i do better than arbitrary splicing?

17:40 mmarczyk: bbloom: ah, so that's something which I'm planning to work on in near future

17:40 lpetit: mmarczyk, bbloom : you guys seem to know your stuff, I'm a bit lost. Anyway, that's what I like about this community, so much more to learn!

17:40 bbloom: lpetit: i didn't know SHIT about this < 1 year ago

17:41 mmarczyk: bbloom: direct impls of "prepend", "insert-at", "remove slice"

17:41 bbloom: lpetit: http://cstheory.stackexchange.com/questions/1539/whats-new-in-purely-functional-data-structures-since-okasaki

17:41 mmarczyk: bbloom: I'm totally in the market for good names for these functions, by the way

17:41 bbloom: start with Okasaki, then go to that thread :-)

17:41 callen: lpetit: yeah, Okasaki is the place to start.

17:41 mmarczyk: bbloom: hah! that's my favourite stack exchange thread ever :-)

17:41 callen: lpetit: you can derive the essentials yourself if you try to figure out how to make efficient immutable data structures without tons of copying.

17:41 arrdem: bbloom: that's an awesome thread

17:41 lpetit: bbloom: I had started once, but not knowing Standard ML was really slowing me down

17:41 bbloom: mmarczyk: i often write conjX functions for fnil things, like (def conjs (fnil conj #{}))

17:42 mmarczyk: but left/right/push/pop would be nice to have very clearly

17:42 mmarczyk: lpetit: "I'm lost", says the a guy who built complex systems in assembly :-)

17:42 bbloom: haha

17:42 mmarczyk: may i suggest left/right, prepend, and append?

17:42 mmarczyk: bbloom: yeah, I'd sort of like to have standardized names for these

17:43 bbloom: right == fast last

17:43 mmarczyk: bbloom: left/right access, prepend/append insertion?

17:43 bbloom: i guess left == first

17:43 yeah

17:43 but left/right as the protocol makes some sense

17:43 noncom|2: in clojure how do i know if a mapping is a (def) or (defn) ??

17:43 lazybot: noncom|2: What are you, crazy? Of course not!

17:43 mmarczyk: bbloom: yeah, sounds reasonable

17:43 bbloom: still good to brainstorm a bit

17:44 bbloom: also, I'd sort of like a standardized set of names

17:44 noonian: noncom|2: defn is just sugar for def

17:44 bbloom: well i guess there are THREE things you need

17:44 mmarczyk: bbloom: for example there's a cool confluently persistent deque

17:44 bbloom: peek/pop/push

17:44 peek/pop/push-left/right

17:44 blargh.

17:44 mmarczyk: bbloom: I think concat there is actually constant-time

17:44 bbloom: haha

17:44 mmarczyk: :-)

17:44 noonian: noncom|2: (defn my-fun [] ...) == (def my-fun (fn [] ...))

17:44 bbloom: ill brb in a bit

17:44 noncom|2: noonian: yes, but maybe there is some simple way... like what is it bound to? like (instance? clojure.lang.IFn)...?

17:45 mmarczyk: ok, see you around

17:45 amalloy: do I understand correctly that you like recur-to? :-)

17:45 bbloom: +1 recur-to

17:45 noonian: noncom|2: yeah, you could probably do (fn? my-fn) to test if its a function

17:45 bbloom: ok going.. really..!

17:45 noonian: ,(doc fn?)

17:45 clojurebot: "([x]); Returns true if x implements Fn, i.e. is an object created via fn."

17:46 justin_smith: ,(doc ifn?)

17:46 clojurebot: "([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn"

17:46 noonian: justin_smith: nice, I didn't know about that

17:46 noncom|2: noonian: gonna try it now..

17:46 ifn seems wider than fn

17:47 justin_smith: yes, I use it to see if something can have an arg applied to it, basically

17:47 noncom|2: yeah

17:47 well, fn works for my case

17:47 ToxicFrog: noncom|2: yeah, IFn is basically "can be called like a function", which includes many things which are not actually functions.

17:48 noncom|2: i think this is very beautiful that we have both fn? and ifn?

17:48 and why we have them

17:48 lpetit: bbloom: ok, I need one or two sabbatical years, just to read&digest okasaki + the marvelous stack exchange link with tons of undecipherable names :-)

17:50 mmarczyk: lpetit: bbloom: I'll add that IIRC slowdown with mixed object/primitive rrb vectors in single jvm image is ~3x compared to PV, ~1.5x compared to gvec; perhaps actually a bit less; that's with regular trees though, before concats

17:51 but this should be fixable

17:52 noncom|2: in clojure, is there a function to execute a function?

17:52 mmarczyk: if need be, I'll make it so different node types use different containing vector types -- actually I'll probably want to do the things required to make this less of a hassle for unrelated reasons

17:52 noncom|2: so that i can do like (-> f EXEC)

17:52 where f is fn

17:53 i mean defined with fn

17:53 mmarczyk: noncom|2: functions are callable, so you can say (.call f)

17:53 noncom|2: there's also apply, but that requires a seq of args

17:53 noncom|2: no "call" function, but you can write one: (defn call [f] (f))

17:53 noncom|2: so (-> f .call) does it!

17:53 i just checked

17:54 noonian: also (apply f [])

17:54 noncom|2: yeah, cool!

17:54 mmarczyk: you can also say (f) ;-)

17:54 noonian: lol

17:54 lpetit: First version of Counterclockwise with "fix indentation as you type" feature is available in the "auto shift" branch

17:54 Update Site : http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/

17:54 noncom|2: yeah, but my point was that i cant say (-> f ())

17:54 lpetit: Standalone apps: http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/products/

17:55 noncom|2: although i remember i was in wonder a few times in the past when realized that all i need is (f) without complications :D

17:55 mmarczyk: lpetit: awesome!

17:55 lpetit: mmarczyk: still very alpha. Feedback required !

17:56 mmarczyk: lpetit: pulling ahead of Emacs in Clojure support feels vaguely indecent ;-)

17:56 lpetit: (the standalone version can be downloaded and discarded easily ;-) )

17:56 noonian: mmarczyk: what is?

17:56 noncom|2: lpetit: hi! is the option to enable full-blown leiningen available in the new builds?

17:57 lpetit: noncom|2: no, I have split it into a branch, it was too unstable, and I needed more hammock time

17:57 noncom|2: okay! i'll be waiting :)

17:57 mmarczyk: noonian: ?

17:58 noonian: mmarczyk: what is ahead of emacs for clojure support?

17:58 mmarczyk: noonian: lpetit's Counterclockwise pulling ahead in this particular area

17:59 noonian: mmarczyk: ah, cool thanks

18:01 lpetit: The first person to download and find a bug in the "fix indentation as you type" feature will get …. many thanks from me! ;-)

18:02 Standalone version installs in a blink: http://updatesite.ccw-ide.org/branch/autoshift/autoshift-travis000104-git40b4075e5c7694be23892195c18e1c27e6371037/products/

18:04 mmarczyk: note, it's not just calling "reindent" on each line. It's shifting all children lines of the form being pushed to the right or the left while typing, plus all its right sibling forms, plus all the right sibling forms of the parent form if the parent form's tail has been shifted along the way, etc. until reaching a line which is not shifted

18:05 mmarczyk: so this preserves, as much as possible, manual indentation such as in 'cond

18:07 Next on the todo list: extend this behavior after paredit commands (so that e.g. "raise over" really works as expected), and also between copy/cut/pastes inside Eclipse (requires serializing the current "column" and not just the selected text)

18:08 mmarczyk: I *think* this is doable in emacs, I've seen some options to do that. But Counterclockwise's advantage is that it works with a real parse-tree: multiline strings are handled correctly, for instance

18:09 bbloom: lpetit: everybody should take a 1 to 2 year sabbatical every 10 to 15 years :-) at minimum! it's good for you

18:09 lpetit: bbloom: sure! Let's save some money then …. ;-)

18:09 bbloom: worked for me :-)

18:10 zerokarmaleft: does core.async have anything like golang's panic?

18:11 bbloom: zerokarmaleft: both JVM and JS have exceptions

18:11 zerokarmaleft: is there something particularly interesting about panic you're looking for?

18:11 zerokarmaleft: rather, does it facilitate looking at the state of the goroutines/blocks

18:12 bbloom: i believe the state is currently opaque, short of implementation details

18:12 tbaldridge is the man to summon :-)

18:12 zerokarmaleft: i.e. it's blocked waiting for a put! on such and such channel

18:14 bbloom: in general, you don't want to be able to query the state of channels or the little channel reading/writing machines

18:14 doing so can lead to race conditions

18:14 now, if i want it for debugging purposes, that's a different story

18:14 zerokarmaleft: that's precisely where I was heading mentally

18:15 e.g. in a long-running app, how can I know whether or not I have a bunch of go blocks spinning b/c I forgot to clean them up properly

18:15 bbloom: i'd like to see some sort of tracing/logging functionality, but i don't think it makes sense to expose much else for prying into the internals

18:16 zerokarmaleft: and to debug deadlocks

18:16 bbloom: maybe some aggregate values, like metrics

18:16 http://blog.golang.org/race-detector

18:16 zerokarmaleft: yea, something like that would be nice :D

18:16 bbloom: the core.async announcement post expressed some interest in that sort of thing

18:26 dfarmer: Hey all, I've got kind of silly practical question. Is there any way to turn off ANSI color in nrepl? I run 'lein repl' in an admittedly clunky term and every output line is preceded by "[14G[8G[15G, etc"

18:31 lpetit: Do you know a good resource to learn enough Standard ML to be able to read & understand the code examples in Okasaki?

18:32 and/or to be able to quickly mount a dev environment to really "run" the examples? (emacs not an option : one "hill" at a time ;-))

18:33 yogert: Hey, are there any Vim users here that could offer a beginner some help in getting situated with Clojure? : )

18:33 I've been finding a lot of conflicting instructions on the web regarding how to bet integrate the repls and such

18:34 best integrate

18:35 no Vim users eh?

18:35 futile: used to be one

18:35 but i got tired of having to hit so many keys just to move up a line

18:36 yogert: Heh, well im not looking to argue about the merits of your favorite editor, I'm just looking to try out clojure

18:36 futile: ah, misunderstood

18:37 guys, how would you benchmark two different types of databases without writing your whole application in both?

18:37 brehaut: yogert: im not a vim user, but i understand that integration is a bit in flux there

18:37 yogert: if you are just learning clojure, start with a lein repl and text editor seperately, rather than getting lost in an integration quagmire

18:38 futile: or just clojurebot

18:38 brehaut: ಠ_ಠ

18:38 futile: ,(dotimes 3 [i] (println i))

18:38 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: dotimes requires a vector for its binding in sandbox:>

18:38 futile: oh

18:38 brehaut: how about a web based repl or private messaging the bot

18:39 futile: but then how can we show him cool ways of doing the same thing?

18:39 yogert: ok, I've never used a lisp before, but I've been told that integration with repls etc is a very attractive feature

18:39 brehaut: yogert: certainy is nice

18:39 yogert: not crucial tho?

18:39 futile: ,(reduce + [1 2 3])

18:39 clojurebot: 6

18:39 brehaut: not when you are starting out

18:40 futile: yogert: in terms of running programs, you can use clojure just like you use ruby

18:40 brehaut: it makes you a lot more productive when you are already productive, but its just a side show to start with

18:40 futile: or whatever

18:40 yogert: ok

18:41 futile: ,(reduce + (take 3 (repeat 5)))

18:41 clojurebot: 15

18:41 brehaut: yogert: if you use a lein repl, you can easily (require 'my.namespace :reload) to relaod your code

18:41 futile: thats a shortcut for (* 3 5)

18:41 brehaut: :reload-all will also reload the dependancies too

18:41 futile: yogert: yeah just `lein repl` is fun too

18:42 ,(reduce + (take 3 (iterate 99 dec)))

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

18:42 futile: oops

18:42 ,(reduce - (take 3 (iterate dec 99)))

18:42 clojurebot: -96

18:42 futile: so confusing.

18:42 yogert: okay. I should watch some videos or something demonstrating the repl integration. I honestly don't have a clue what it is exactly, just that it is great. Is the repl itself any different than GHCI or Python's?

18:42 futile: yogert: same as python's

18:43 yogert: install leiningen (via homebrew or whatever) and type `lein repl` and then type (+ 1 2) in it

18:43 brehaut: Not via homebrew

18:43 yogert: just that its in your editor...

18:43 futile: brehaut: why not?

18:43 yogert: not via homebrew?

18:43 i already did


18:43 futile: yogert: i did too, no harm in it

18:43 yogert: osx package management sucks

18:43 brehaut: ideally you just grab the version from the lein website

18:44 futile: brehaut: thats what they all say.

18:44 brehaut: you dont need to package manage lein because it doesnt install globally

18:44 futile: (inc homebrew)

18:44 lazybot: ⇒ 1

18:44 brehaut: lein manages its own updates

18:44 futile: brehaut: homebrew isnt about globally or not.

18:44 brehaut: homebrew is about me not having to type boring crap in the terminal :)

18:44 justin_smith: homebrew stinks

18:44 futile: literally just `brew install leiningen` and im done.

18:44 (or is it lein?)

18:44 justin_smith: whats with the homebrew hate today?

18:45 brehaut: futile: stop talking out your arse; lein is simple to install without a package manager

18:45 futile: brehaut: yeah it is simple. you're right about that.

18:45 but its even simpler with homebrew.

18:45 justin_smith: it is literally one file, homebrew makes it MORE complicated

18:45 as usual for homebrew

18:45 futile: justin_smith: it may complicate HOW its done, but not WHAT i do to install it

18:46 brehaut: futile: ease vs simplicity

18:46 futile: brehaut: yep

18:46 brehaut: artificial ease now that sacrificies simplicity is asking for problems later

18:46 futile: and in this case i like easy better.

18:46 justin_smith: compare: create ~/bin/lein vs. install homebrew and brew install $(lein || leiningen whichever works)

18:47 futile: justin_smith: `brew install leiningen` and im done. to create ~/bin/lein i need to open Chrome and go find the dang file

18:47 then i need to download it. how? curl, wget, or just use my browser?

18:47 then i have to move it.

18:47 justin_smith: and then deal with brew when you want to update lein (vs. just letting lein autoupdate)

18:47 futile: man, just `brew install leiningen`

18:47 justin_smith: not true. itll update all the same

18:48 justin_smith: nope, it fucked up my coworker's install, in the middle of a workshop he was trying to run

18:48 futile: justin_smith: all `brew install leiningen` does is downloads the same trampoline file that you would normally download manually, and puts it somewhere on your path for you

18:48 justin_smith: brew is a mess, and you don't need it for something as simple as lein

18:48 futile: oh come on, you dont have to go making everyone leave irc just cuz you disagree with me

18:49 ;)

18:49 noonian: homebrew may be a mess, but not using it on a mac is even messier in my experience

18:49 futile: (inc noonian)

18:49 lazybot: ⇒ 1

18:50 justin_smith: noonian: my solution was to stop using my mac, and getting a system76 box

18:50 bbloom: justin_smith: all package managers are a mess, but brew is 100X more pleasant than any other mac package manager i have ever encountered

18:50 it's perfect for "eh, i just want to try it real quick"

18:50 futile: (inc bbloom)

18:50 lazybot: ⇒ 10

18:50 noonian: justin_smith: I'd just get a thinkpad but I need a mac for iOS stuff

18:50 futile: glad im not the only one who's perfectly ok with homebrew

18:51 justin_smith: noonian: I have a mac sitting on my desk, work gave it to me, I open the lid about once a week

18:51 futile: ok looks like i cant upgrade leiningen via homebrew.

18:51 that does suck.

18:51 bbloom: all the other package managers should take a lesson from homebrew on how to run a project tho

18:51 holy hell those guys rock

18:51 `brew edit foo` is trivial & pleasant

18:51 justin_smith: and a big part of that reason is there is no non-shit package manager under macos

18:51 bbloom: and they homebrew ppl are extremely responsive to tickets

18:51 `brew doctor` works magic

18:51 it's a damn well run project

18:52 they have all kinda of auto-build, CI github bot voodoo too

18:52 technomancy: homebrew's quality control leaves a lot to be desired

18:52 justin_smith: my biggest problem with brew is /usr/local is MINE and no system tool should fucking touch it, ever

18:52 pisses me off

18:52 clojurebot: Gabh mo leithscéal?

18:52 callen: technomancy: they don't have any

18:52 futile: justin_smith: ah, you're a linux user.

18:52 im not.

18:52 callen: they just axe bad formulae occasionally, that's it.

18:52 technomancy: that said, using a computer without a package manager is madness

18:52 futile: i mean in spirit of course

18:53 callen: futile: Macs have a /usr/local too.

18:53 futile: which is what homebrew runs on. Macintoshes.

18:53 futile: callen: thanks for the reminder

18:53 justin_smith: futile: switched back to linux, mainly because I missed package management

18:53 I have an unused osx machine sitting right here

18:53 technomancy: clojurebot: macports?

18:53 clojurebot: macports is not a package manager, it's a satire about package management.

18:53 arrdem: technomancy: TIL windows is sparta.

18:53 bbloom: lol.

18:53 technomancy: clojurebot: botsnack

18:53 callen: technomancy: aye.

18:53 clojurebot: Thanks! Can I have chocolate next time

18:54 futile: its probably not perfectly accurate, but people who get upset with mac stuff often closely resemble http://imgs.xkcd.com/comics/command_line_fu.png

18:55 brehaut: just what we need; more broad sweeping insults based on operating system choice. high five ◔_◔

18:55 bbloom: not to start an OS war, but i've never seen anyone succeed w/ linux+projector on the first try before

18:56 software sucks.

18:56 next topic!

18:56 brehaut: bbloom: operating systems are about as shit as text editors and command shells

18:56 arrdem: bbloom: .. this is a software channel

18:56 futile: yeah, i basically hate all software.

18:56 arrdem: bbloom: and yes I have succeeded with a projector on the first shot before

18:56 futile: but when i can repress it for a period, i dont mind most of it.

18:56 isaacbw: woo, koans complete

18:57 I don't feel enlightened, lol

18:57 bbloom: futile: knowing when and for how long to hold your nose is a key skill for programmers

18:57 futile: my colleague switched to linux for a year or so, and literally switched back to mac because of a projector problem during a talk at a user group or conference, i forget which.

18:57 bbloom: +1

18:57 jkj: just know your xrandr :P

18:58 arrdem: (inc jkj)

18:58 lazybot: ⇒ 1

18:58 isaacbw: ubuntu could probably use a projector plug n play

18:58 arrdem: isaacbw: you would think that, wouldn't you.

18:58 * technomancy loves being able to plug projectors directly into VGA and not hunt for adapters

18:59 arrdem: isaacbw: as with most things ubuntu it works 85% of the time right off, but when it doesn't you're in deep

18:59 technomancy: seriously though, the whole editing x.org config files stereotype is so 2007

18:59 isaacbw: I'm not an ubuntu user, but as far as linux goes it's the closest to a "just works" experience

19:00 arrdem: isaacbw: understood and agreed, I'm just making the point that there really is no such thing as "just works"

19:00 as far as the linux world goes at least.

19:01 noonian: I would prefer to use linux, but it always takes me a week at least to get a proper setup when I want to get a linux box working and configured to be productive with

19:01 technomancy: "just works" just comes down to "spend a bit of time researching before you buy"

19:02 brehaut: technomancy: yeah; i researched and came back with a mac and virtual box ;)

19:04 arrdem: hum.. anyone have a better DSL design than this? the general case of an ASM op is ["ADD" "EAX" "EDX"] or some such, but this gets funky when you want to use inline constants or chase pointers because you wind up with modifiers on the operands.

19:04 The current fix is that modifiers are macros, so you pre-expand the operand into its encoding

19:04 callen: as an XMonad user, things like projectors emphatically DO NOT just work.

19:05 technomancy: callen: I don't think xmonad has anything to do with that

19:05 jkj: my solution before mac was Arch Linux. just the eeepc i was running it on was quite horrid. never got used to the keyboard and it had just 1GB of mem.

19:05 technomancy: it's just a matter of knowing which brands of video card to avoid

19:06 jkj: and do think xmonad doesn't get on your way with projectors as long as you are willing to xrandr yourself

19:06 arrdem: but that means you loose data about your instruction sequence at read time, making any subsequent (prints) or other inspection less meaningfull/symbolic

19:06 technomancy: jkj: that hasn't been my experience; on debian and ubuntu you just plug it in and it rearranges everything

19:07 it's probably more complicated on arch; archies love to make things complicated

19:07 arrdem: technomancy: ah but at least our complicated has good wiki manuals and flat text file configs!

19:07 jkj: appreciating my mac now

19:08 but i actually liked arch. it was easy in the form of not having intrusive automation that just tries to work but ends up doing something stupid

19:09 noonian: thats how I felt after trying to get my Arch UI setup to work on Ubuntu

19:10 justin_smith: regarding linux and "just works", best to compare apples to apples (so to speak) - get a linux box, built to run linux with a distro pre-configured by the manufacturer

19:11 I mean imagine judging macos based on hackintosh

19:11 seangrove: nrepl really does seem nice

19:12 I was skeptical it would be better than swank/slime, but having multiple repls, one evaling in clojure, the other in the browser, and having them communicate and seamlessly update defs... very nice

19:12 Raynes: And being able to make use of it from vim with reasonable ease is useful as well

19:13 te: it has continued to get better

19:13 seangrove: Raynes: good point

19:13 te: i was skeptical too and dragged my feet for awhile

19:13 brehaut: seangrove: isnt the canonical spec for swank 'whatever the head of cvs currently does'? its not too surprising that nrepl is better than that ;)

19:13 technomancy: it's still missing a bunch of stuff; hopefully now that nrepl.el is maintained we can move forward with new features via nrepl-discover

19:14 (inspector, tracing, etc)

19:14 jkj: arrdem: have you tried just having ops be funs/macros themselves?

19:14 (asm/add :eax [:edx])

19:14 arrdem: which cpu or generic?

19:17 callen: technomancy: I can't even get YourKit or jvisualvm to work in Xmonad.

19:18 technomancy: attaching an external display upsets Xmonad sometimes, it's usually otherwise multi-display friendly.

19:18 futile: xmonad was the one thing i liked about linux

19:18 so i wrote a kind-of port for mac

19:18 i mean, i tried to hit the right balance between what xmonad is and what mac allows

19:19 anyone want a binary of it? im handing them out for free.

19:19 jkj: futile: sure!

19:19 futile: hold on, let me strip out the licensing code

19:24 sweet, it still builds

19:25 pcarrier: is there a pmap with custom parallelization factor?

19:28 futile: jkj: ok https://www.dropbox.com/s/8dzp2irtn8ssuvy/AppGrid.zip

19:28 jkj: if it doesnt load, let me know. code signing certificate crap sometimes pretends to work for me but not for others.

19:30 Derander: for anyone who remembers the moron trying to shuffle vast quantities of shit through clojure yesterday: it seems like java actually is fast enough for it

19:30 decided to implement in java in the name of stack homogeneity and it's shuffling along pretty close to as fast as gnu awk

19:30 (aka roughly 50x as fast as clojure)

19:30 this implies (to me) that I was probably doing something wrong.

19:31 jkj: futile: fuking splendid!

19:31 futile: jkj: thx

19:31 jkj: i have a custom build that lets me attach random keyboard shortcuts to shell commands and stuff, but it needs polishing up. interested?

19:31 btw, if anyone else wants to use this app, let me know and ill give you a link

19:32 jkj: futile: yes, very

19:32 futile: i think its jkj-approved

19:32 jkj: actually do you just want the fully scriptable one?

19:32 its scriptable via JS (or coffeescript)

19:33 i hate it cuz im getting tired of scripting everything.

19:33 i want my computer to just think for me.

19:33 jkj: futile: sure. don't mind testing either

19:34 futile: jkj: https://github.com/evanescence/zephyros

19:35 im thinking of ripping out all the scripting though. only like 5 people ever liked it.

19:35 not that it costs me anything to keep it, but, its just like, whats the point if only 5 people use it?

19:35 i dunno anymore.

19:43 brehaut: futile: are you taking credit for zephros?

19:43 futile: brehaut: yeah, i wrote it

19:43 brehaut: not matt gemmell?

19:43 futile: not him.

19:43 i think i caused too much confusion by asking him to house it for me

19:44 i think ill just ask for it back.

19:46 callen: futile: you hadn't mentioned you were a cocoa dev.

19:46 futile: callen: you told me not to talk about myself!

19:46 (over and over again)

19:47 callen: Usually it's blubbery self-deprecation or personal stuff. Talking about one's work is another matter.

19:48 futile: callen: noted

19:49 rebcabin: ,'(reduce 'or (list true false))

19:49 clojurebot: (reduce (quote or) (list true false))

19:50 rebcabin: ,(reduce 'or (list true false))

19:50 clojurebot: false

19:50 arrdem: jkj: right now it's for platform specific assemblers

19:51 the hope is to build a macro abstraction atop them that's portable

19:51 rebcabin: ,(reduce 'and (list true false))

19:51 clojurebot: false

19:51 amalloy: rebcabin: 'or and 'and are symbols, not functions

19:51 arrdem: jkj: as to making the notation fns or macros in itself I think that's the approach I settled on while driving home.

19:52 amalloy: symbols happen to also be callable as functions, but they don't do anything like what you're hoping

19:52 rebcabin: darn :)

19:53 i just saw someone in a video do this, and i didn't believe it then :)

19:53 video is by tmarble at linux australia

19:54 noonian: did it work in the video?

19:54 rebcabin: he does (reduce 'or (map even? '(1 2 3 4 5))) and purports that it works :)

19:54 noonian: ,(reduce and (list true false)))

19:54 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>

19:54 noonian: ,(reduce and (list true false))

19:54 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>

19:54 rebcabin: ,(reduce 'or (map even? '(1 2 3 4 5)))

19:54 clojurebot: false

19:55 noonian: ah

19:55 rebcabin: so dunno might have been some earlier version of Clojure or a jacked version

19:55 noonian: ,(ifn? 'foo)

19:55 arrdem: ,(type and)

19:55 clojurebot: true

19:55 #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:0:0)>

19:55 rebcabin: http://www.youtube.com/watch?v=ii-ajztxALM

19:55 noonian: ,(type or)

19:55 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(NO_SOURCE_PATH:0:0)>

19:55 rebcabin: around 36:36

19:56 clojurenewb: Raynes: hi do you have time for a laser question ?

19:57 rebcabin: he's using emacs org-mode in his video, and runs other things in the live repl -- but this one he just has a repo transcript

19:57 alexgunnarson: are we talking about las3r or laser?

19:57 jkj: futile: thank you for the software. you got me hooked. these are features mac os x is really missing

19:57 futile: jkj: appreciated

19:57 im getting some more apps out in a second

19:57 just cleaning it up

19:58 clojurenewb: alexgunnarson: laser as far as I know

19:58 alexgunnarson: clojurenewb: okay

19:58 futile: ok, anyone else want an xmonad-like app for Mac OS X? last chance.

19:58 clojurenewb: now I am intrigued by what las3r is

19:58 rebcabin: i like monads :)

19:59 jkj: futile: everybody needs it, but not many know they do i quess :)

19:59 callen: futile: sizeup is fine.

19:59 bbloom: i prefer monoids

19:59 futile: callen: if you say so

19:59 jkj: thats how i felt. i avoided sizeup/divvy/etc for a long time.

20:00 rebcabin: size up is great; "optimal layout" is pretty good too

20:00 futile: turns out, it wasnt the idea i was against, but their execution

20:00 alexgunnarson: clojurenewb: las3r is basically a clojure interface/wrapper for actionscript/flash

20:00 futile: i like AppGrid because its "composable".

20:00 you just remember a few key commands, and you can do a whole lot with them

20:00 alexgunnarson: clojurenewb: it's cool but even though i love flash functionality i just hate flash player…

20:00 rebcabin: i'll take a look at app grid -- can you tell us about monad, futile?

20:01 xmonad rather

20:01 noonian: futile: I'll probably checkout out zephyros when I have the time

20:01 clojurenewb: alexgunnarson: yeah I don't like proprietary plugins at all really

20:01 rebcabin: something is helping my spelling i want to turn it off!

20:01 alexgunnarson: clojurenewb: me neither

20:01 futile: AppGrid is just Zephyros with a hard-coded config, so you dont have to write one

20:02 i personally dont wanna write 100 lines of CoffeeScript (or JS) to configure a wm

20:02 and i know some people who feel the same

20:02 but i also know some people who love tinkering

20:02 rebcabin: xmonad is a dead-simple tiling window manager for linux.

20:02 noonian: futile: has anyone got zephyros working with clojurescript?

20:02 futile: noonian: i tried really hard for like 2 hours, couldnt figure it out

20:02 please be the first :)

20:03 noonian: futile: heh, I'll probably give it a shot but it took me a while getting it working in a simple clojure webapp so no promises :P

20:03 futile: oh nevermind then

20:03 its not a high priority

20:03 just would be really cool

20:03 noonian: yeah

20:03 futile: possibly not even that practical

20:03 rebcabin: anything that saves me a trip to the mouse is a win

20:04 futile: here's the source to AppGrid if you want: https://github.com/evanescence/grs

20:04 \cc jkj

20:06 alexgunnarson: hey everyone - so i'm considering developing a clojure app. obviously i'd like it to be write-once-deploy-everywhere but there's no "silver bullet" in terms of platform/VM/whatever for it to be deployed on. between Clojure+JVM+JavaFX, Clojure+Flex+AIR+Flash Player, and ClojureScript+Pedestal+HTML5+CSS, I'm not really sure where to go.

20:07 everyone thinks HTML5 is the future of everything but it's way behind flash and java libraries in terms of functionality

20:07 futile: alexgunnarson: i personally just use Clojure + HTML (via Hiccup lib) + CSS (via Garden lib) + JS (via ClojurScript) and dont care how it runs, just using lein-ring

20:07 alexgunnarson: and plus the HTML5 specs haven't even been hammered out yet

20:07 futile: alexgunnarson: yeah but there are other priorities besides just functionality. like searchability and runnability

20:07 jkj: AppGrid is probably better for most users as it makes a statement how things should work and is self documenting

20:08 noonian: I'm using Clojure for the backend and HTML5 + javascript on the frontend using handlebars for templating. Wasn't ready to commit to ClojureScript

20:08 alexgunnarson: well of course i would do a website with clojurescript + HTML5

20:08 futile: jkj: i agree. some people find it too limiting but i think its just what most people really want even if they dont know it yet

20:08 alexgunnarson: but an RIA? clojurescript is not quite what i want...

20:09 futile: lein-ring does what again? async?

20:09 jkj: futile: maybe zephyros could also preconfigure itself to resemble AppGrid and have some presets bundled?

20:09 futile: alexgunnarson: magically runs your ring app for you. ring is a web server type thing.

20:09 jkj: not it's bound to repel some people as it requires configuration (minimal though) out of the box

20:09 alexgunnarson: oh. okay that makes sense

20:09 futile: well, its a spec really, i think. lein-ring uses jetty by default.

20:10 jkj: i think even with a preconfiguration, its way too scary for most people.

20:10 jkj: futile: true

20:10 futile: jkj: even if it comes with its own zephyros.coffee file, itll still be like 80 lines

20:10 jkj: i have another idea.

20:10 alexgunnarson: what's the idea?

20:11 futile: jkj: i was thinking of a middle-ground between zephyros and appgrid, where you can configure it within the app, using a custom interface

20:11 jkj: it obviously wouldnt be as flexible as straight-up JS would be, but more flexible than appgrid.

20:11 jkj: then every type of user could use it.

20:11 i mean, there would be options for everyone.

20:11 alexgunnarson: well i'm not looking for an out-of-the-box thing necessarily… i'm willing to put up with coding hell

20:11 jkj: futile: true

20:11 bttf: i wrote a private function in my ring app that gets called by one of my handler functions ...the handler fn and private fn are in the same ns, but im getting errors at compile time

20:11 alexgunnarson: just as long as it gets easier

20:12 futile: alexgunnarson: sorry, this is off topic and its probably confusing you.

20:12 bttf: erros about so-and-so not a public function

20:12 futile: jkj: if you want to keep chatting about it feel free to come to #zephyros

20:12 bttf: wots the deal

20:12 alexgunnarson: futile: i'm not much of a server genius really

20:12 futile: alexgunnarson: sorry, those were two different conversations.

20:12 alexgunnarson: futile: ah okay

20:13 futile: alexgunnarson: ok about lein-ring. basically you just install lein-ring and it runs your Clojure web app for you.

20:13 alexgunnarson: you wont have to deal with how it does it, it just does it.

20:13 alexgunnarson: its really handy. https://github.com/weavejester/lein-ring

20:13 alexgunnarson: futile: that sounds awesome

20:14 futile: but i'm not really looking to run something in a browser… it'll be an app really

20:14 jkj: arrdem: do you have some intermedia presentation for the ops behind the notation?

20:14 alexgunnarson: futile: it might theoretically have some sort of limited functionality able to run in a browser, but that wouldn't be the focus

20:15 futile: alexgunnarson: it wouldnt run in the browser

20:15 alexgunnarson: are you familiar with Rails?

20:16 alexgunnarson: futile: so when you say web app you don't mean SaaS you mean like an app that uses the web like a social app or a weather app

20:16 futile: not too familiar, no

20:16 futile: alexgunnarson: what are you familiar with?

20:16 alexgunnarson: futile: not very much - pretty much java and scheme… i'm still making inroads into clojure

20:17 futile: alexgunnarson: have you ever written any kind of website, like php or anything else?

20:17 alexgunnarson: futile: yes but i did the frontend only

20:17 futile: i never set up any servers or really messed around with the back-end

20:17 futile: alexgunnarson: oh. i ee.

20:17 alexgunnarson: yeah im not sure what a good way to get started with doing that in Clojure would be.

20:17 alexgunnarson: i would almost recommend getting your feet wet with Ruby on Rails

20:18 alexgunnarson: futile: why is that?

20:18 futile: alexgunnarson: pretty much every lib ive seen for clojure assumes you know all about that kind of thing.

20:19 alexgunnarson: so html-generating libs assume you know all about html, etc

20:19 alexgunnarson: futile: well i know some HTML, CSS, etc. but i'm no expert yet

20:19 futile: alexgunnarson: if you arent super familiar with how http works, ring and compojure might seem a little confusing

20:19 alexgunnarson: futile: i'm really trying to determine the direction i want to go in so i can dive in to whatever solution is best

20:20 futile: alexgunnarson: ah. sorry, i got off topic again

20:20 alexgunnarson: sorry i've gotta go but keep me updated

20:20 futile: uhh

20:20 ok?

20:20 clojurebot: grok is a little hard to juxt but it's the best thing ever

20:20 alexgunnarson: bye :/

20:20 futile: bye

20:47 callen: alexkira: if you want to do a web app you might want to look at Luminus.

20:49 er

20:49 god dammit.

21:27 yedi: best way to use bcrypt from clojure?

21:28 nvm

21:33 can someone help me understand this line: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/signup_and_redirect.clj#L77 (specifically: `{{:keys [username password confirm] :as params} :params :as req`})

21:34 i know it sets those vars to the corresponding keys in (:params req), but how exactly does the :as work

21:38 `cbp: Does anyone have a link to that blogpost "understanding clojure's persistent vector implementation", I can't seem to find it anywhere nor can I remember the author :-P

21:42 yedi, it's destructuring a map that has a shape like {:params {:username "foo" :password "bar" :confirm "baz"}}

21:42 :as binds the whole map

21:43 ,(let [{{:keys [a b c] :as p} :p :as r} {:p {:a 1 :b 2 :c 3}}] [a b c r])

21:43 clojurebot: [1 2 3 {:p {:a 1, :c 3, :b 2}}]

21:45 `cbp: ,(let [{{:keys [a b c] :as p} :p :as r} {:p {:a 1 :b 2 :c 3}}] [a b c p r])

21:45 clojurebot: [1 2 3 {:a 1, :c 3, :b 2} {:p {:a 1, :c 3, :b 2}}]

22:54 futile: quiet night

22:56 brehaut: afternoon talios

22:56 talios: oh hai

22:56 brehaut: hows north of the hills

22:57 talios: grey, threatening rain

22:57 brehaut: likewise

23:01 yedi: why is the=is bcrypt fn returning different values after hashing the same thing? https://gist.github.com/yedi/9f219c53d6e5db95519c

23:01 futile: i think Clojure cant be appreciated fully until you first know C

23:02 yedi: im guessing its using an algorithm that adds some randomization

23:03 callen: yedi: that's what makes bcrypt useful dude

23:03 yedi: you can't store passwords with something that lets you precompute the value->hash relationship.

23:05 yedi: wait what? then how do you expect to do equivalence testing for passwords / auth when someone logs in? i though the whole point of a hashing function was quick deterministic 1 way hashing

23:06 callen: it's not that simple.

23:06 yedi: http://codahale.com/how-to-safely-store-a-password/

23:06 do NOT use generic hash algorithms for storing passwords.

23:06 Use scrypt, bcrypt, or PBKDF2

23:07 TimMc: Aw, I missed all the fun?

23:16 yedi: ok, so callen, how do you test that a password is equivalent to a bcrypt hash? im just confused about that part

23:20 bbloom: yedi: normally, i'm all for teaching stuff and letting people make mistakes while they learn.. but security, and cryptography in general, is a different story: let somebody who knows that they are doing do it. use a well tested library for this! and if you do want to learn, then there are LOTS of good articles about this topic, b/c it's something people get wrong A LOT

23:21 yedi: with that disclaimer out of the way...

23:21 there are different hash functions for different use cases

23:21 you don't want password hash functions to be super fast

23:22 if you are trying to hash a lot of files for bulk equality testing later, then yeah! go w/ the fastest hash that fits your other needs

23:22 but don't do that for passwords :-P

23:22 b/c the only person bulk-testing passwords, are hackers

23:22 if a user needs to wait an extra 1 to 100ms to login, that's no big deal b/c they do that so infrequently

23:23 yedi: ok yea i get it, but i just want to get bcrypt to work for my authenticate users function. I don't conceptually understand how to test for password = hash equality if bcrypt hashing isn't deterministic.

23:23 brb wiki

23:25 seangrove: Is bcrypt non-deterministic?

23:25 * seangrove goes back and checks

23:26 brehaut: its probably doing something like salting the phrase

23:26 but its consistently slow

23:26 seangrove: Ah, yes

23:26 yedi: https://gist.github.com/yedi/9f219c53d6e5db95519c -- yea i feel like i'm missing something really dumb

23:26 bbloom: i am NOT AN EXPERT, but iirc, it's intentionally non-deterministic

23:26 and you have to run a number of iterations

23:27 and statistically, you'll get a matching hash eventually

23:27 callen: yedi: don't use friend

23:27 bbloom: but the number of iterations determines how slow it is

23:27 callen: yedi: understand what you're using.

23:27 if bcrypt had predictable output for a given input, it wouldn't be useful.

23:27 futile: i just use openid and let google deal with it

23:28 bbloom: futile: i have fixed so many openid implementations, it's not even funny

23:28 seangrove: bbloom: Makes sense

23:28 bbloom: the 3 leg thing or whatever, people fuck up 2.5 legs of it :-P

23:28 futile: bbloom: yeah. im sure ive messed it up too.

23:28 we all do.

23:28 no such thing as security, amirite?

23:28 brehaut: yedi: im pretty sure you want to use bcrypt-verify to compare a password to a hashed password btw

23:29 oh, my bad. the docs explicitly say to use bcyrpt-credential-fn; bcrypt-verify is just an implementation detail

23:30 yedi: cryptography lesson one: read the docs on the library you are using ;)

23:31 bbloom: lesson 2: don't do it yourself :-P

23:31 it's at least NON_DETERMINISTIC -ly harder than concurrency :-P

23:31 brehaut: bbloom: maybe these lessons are out of order

23:32 yedi: bbloom: know of a good library for it?

23:32 and ok, thanks guys

23:32 bbloom: *shrug*

23:32 brehaut: yedi: well, friend for http authentication. the stuff you linked to is already wrapping up all the internals

23:33 zRecursive: ,(sqrt 10000000000)

23:33 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: sqrt in this context, compiling:(NO_SOURCE_PATH:0:0)>

23:33 callen: yedi: I generally advise people against Friend unless they know pretty far ahead what they need and want.

23:34 brehaut: yedi: btw, i think cemerick has a clojure-sec mailinglist somewhere in the depths of google groups

23:35 yedi: callen: is there something you'd suggest instead? for like a user management system in a webstore

23:35 callen: yedi: if it's a simple web app, just use bcrypt and a secure cookie store for sessions.

23:36 brehaut: or, if you arent planning to use https, just dont even both with passwords

23:36 callen: you'll spend more time fighting Friend than writing your web app if you're not building something big/elaborate with a lot of auth-flow corner-cases and don't know what you're doing all that well.

23:36 brehaut: s/both/bother/

23:36 callen: Clojure noobies trying to make a web app should almost never be using Friend unless they're participating in a large enterprise migration project.

23:37 how you poor bastards end up on Chas's doorstep I'll never know.

23:39 yedi: actually yeah I'd like to know, what made you try to use Friend?

23:44 TimMc: bbloom: What's this about bcrypt being non-deterministic?

23:44 That sounds entirely wrong.

23:50 callen: TimMc: deterministic with respect to hashing refers to the ability to arrive at the same hash from the same value.

Logging service provided by n01se.net