#clojure log - Sep 08 2014

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

0:00 hipitihop: danielcompton, another limitation, this is being done in clojurescript so won't have access to all libs

0:00 arrdem: danielcompton: okay I found an old (2009) thread that sketched that exact same format. thanks.

0:00 justin_smith: I think the cljs equivalent would be switching to Object instead of map

0:01 hipitihop: danielcompton, looking

0:01 arrdem: danielcompton: sketching a spec of URIs for (artifacts, namespaces, vars, classes) all of which are versioned on a maven package so I thought I'd check for prior art in Maven URIs and make sure I superset it.

0:04 danielcompton: arrdem: is this for grimoire?:

0:04 arrdem: danielcompton: yeah but the hope is that it can be more general.

0:04 justin_smith: ,*clojure-version*

0:04 clojurebot: {:interim true, :major 1, :minor 7, :incremental 0, :qualifier "master"}

0:05 arrdem: $google clojure-grimoire var-link

0:05 lazybot: [clojure-grimoire/var-link.el · GitHub] https://github.com/clojure-grimoire/var-link.el

0:05 arrdem: well... that's a prototype emacs browser

0:05 links to the spec tho

0:06 danielcompton: hipitihop: could you use some XPATH to query the original XML document?

0:07 hipitihop: danielcompton, don't think so, I do need all elements parsed into final seq/vect I just need to detect the duplicates to warn user of the collisions .. a subsequent pass may drop the duplicates, or apply last in best dressed etc.

0:10 danielcompton: arrdem: hehe: http://oxlang.com

0:10 arrdem: danielcompton: oh well.

0:10 oxlang.org or oxlang.io would be hipper anyway :P

0:11 hipitihop: danielcompton, experiments so far suggest it's the creation of the transient/intermediate colls (that hold the composite keys) which is the high cost but have not been able to fully profile where the bottle neck is.. digging deeper.

0:11 danielcompton: arrdem: don't think anyone's heard of this oxford crowd anyway, I wouldn't worry about it.

0:11 hipitihop: could you construct the composite keys with xslt?

0:12 hipitihop: danielcompton, prior to giving it to our cljs app ? no

0:17 technomancy: arrdem: scopes are a strictly maven thing, profiles are a lein thing

0:20 arrdem: danielcompton: eh it's a non-priority. oxlang isn't actually a thing and odds are never will be just because I think breaking compat with Clojure is requisite to do anything interesting and will be devastating to utility or at least infrastructure.

0:21 technomancy: so... how does :scope "test" play with lein deps then? The Maven manual states that a test scoped dependency is _only_ loaded during the testing phase which Lein knows about.

0:21 technomancy: I may be misreading tho.. actual raw maven is new to me.

0:22 danielcompton: current draft https://github.com/clojure-grimoire/var-link

0:23 danielcompton: the idea is that documentation and source code level links can become kinda portable across different documentation systems including my own ofc.

0:23 technomancy: arrdem: any non-default :scope means it's ignored by downstream consumers

0:24 arrdem: I actually just answered this question on the lein mailing list. setting :scope in project.clj is only supported for legacy reasons, it should never be necessary

0:24 arrdem: technomancy: gotcha

0:24 danielcompton: damnit I thought I got that already. thanks :P

0:25 danielcompton: arrdem: I meant to clean it up when I pasted it but I'm on a kinesis and my editing is still a bit clumsy

0:25 arrdem: var-link is interesting, I like that the motivation is up front

0:26 what's the motivation behind having var and var+doc and var+src. Don't you just want var+doc and var+src?

0:26 arrdem: danielcompton: lazy users and tools like CrossCLJ which only give you one

0:27 danielcompton: having var seems to muddy the waters for me, I'm not sure where it would take me

0:29 arrdem: but I can see why it's there

0:30 arrdem: I guess my idea with the var:... class:... and ns:... types are that if you can just get to what you want you can find either source or docs. say I just want to find out something about clojure.tools.analyzer. I don't really give a damn whether you give me formatted documetation or source code as long as I can get there fast and start reading.

0:30 I suppose there's an argument in here for having an artifact: type

0:30 but that should probably just be mvn:

0:41 danielcompton: arrdem: just a thought, maven has source jars, could you do something related there?

0:42 arrdem: danielcompton: yep something like that is in the works.

0:43 danielcompton: the idea with var-link is that it's part of the same project. documentation/source artifacts that can link against each-other, so that engines like a refactored Grimoire can resolve the links to actual links.

0:44 but this is all out on the horizon somewhere

1:21 danielcompton: I heard that Clojure Cup winners get a lock of Rich Hickey's hair

1:23 tadni_: danielcompton: I saw the beginiing of a speech he gave, and was delighted to hear he made a reference to looking like the 4th Doctor.

1:23 http://en.wikipedia.org/wiki/Fourth_Doctor

1:24 danielcompton: tadni_: bahaha

1:24 tadni_: No one seemed to care or get it too, which I found a bit sad. It was something along the line of "I left my tardis running outside".

1:24 Or a similar motif.

1:25 * tadni_ really should be sleeping, but can't seem to get to bed.

2:02 iamanoob: Hello guys, is there a prettier way (or more common) way to write this: https://www.refheap.com/89978 (it just don't look right to me, i'm a complete beginner sorry)

2:11 BAMbanda: Can we pull in clojar packages to an independant lein repl?

2:11 outside a project directory

2:35 babygau: provided that f2 take 2 arguments (defn f2 [c d]...), how to write f1 that return value is f2 arguments??? => (f2 (f1 a b))

2:46 provided that f2 take 2 arguments (defn f2 [c d]...), how to write f1 that returned values are f2 arguments??? => (f2 (f1 a b))

2:49 gws: babygau: (apply f2 (f1 a b))

2:50 ,(apply + [1 2])

2:50 clojurebot: 3

2:51 babygau: @gws: tks mate, but is there any other way that I don't have to use `let` destructuring or `apply` function???

2:51 lazybot: babygau: Yes, 100% for sure.

2:52 * hipitihop for the benefit of others, I found the culprit to my problem and it wasn't caused by group-by or collating keys for duplicates but some of my own pathological code later in my implementation. Sorry for the noise.

2:53 Bronsa: babygau: not without changing the implementation of f2

2:53 there's no way to call f with 2 args using (f x)

2:54 babygau: @bronsa: so the best practice is f1 return [a b] and use `apply` on f2 which take f1 values, right?

2:55 Bronsa: babygau: yes, assuming you can't control the implementation of f2

2:56 otherwise you could turn f2 into (defn f2 [[x y]] ..) instead of (defn f2 [x y] ..)

2:56 or, even (defn f2 ([[x y]] (f2 x y)) ([x y] ..))

2:57 this way you can call (f2 [1 2]) or (f2 1 2)

2:58 babygau: @Bronsa: tks bro, the second one is great answer :D

2:59 Bronsa: babygau: np, btw there's no need to use @ to refer to someone in IRC

3:00 babygau: bronsa: oh, I don't know that, both #clojure & #irc are so new to me :)

3:02 Bronsa: babygau: also your client should auto-complete names with TAB

3:02 babygau: Bronsa, many thanks mate, i'm using #hexchat and `TAB` works indeed!!!!

3:03 Bronsa: you're welcome

3:03 babygau: Bronsa, about my question, I forgot that `defn` accept multiple arity, so I can manipulate `fn` argument just the way I want :)

3:04 Bronsa: indeed, it's quite handy when coupled with destructuring on the args vector

3:04 babygau: Bronsa, yours just hit right spot ;)

3:05 Bronsa: babygau: usually nobody writes functions that way though -- unrolling the args of lesser arities -- we just use apply

3:06 celwell: If I already have ring as a dependency do I need to also add clj-http as a dependency if I want to :require clj-http? I.e., if I'm already pulling in a library that depends on the library I need, do I still have to explicity depend on that latter library if I want to use it?

3:06 babygau: Bronsa, tks mate, I could see how `apply` is more favourable, It's just my curiosity when it comes to learn a new language :)

4:40 justin_smith: celwell: if you know it is a transative dep, you don't need to explicitly put it in your deps. If that fails, it will fail at build time, not in your deployed code, so it isn't a big risk.

8:42 Rhainur: oh man I'm so ignorant about clojure terminology that I don't even know what to google for

8:42 llasram: Rhainur: What are you trying to figure out?

8:43 Rhainur: how do I go from this vector [1 2 3] to 3 separate items. I have (def some-vector [1 2 3]) and I want to call a function with 3 arguments thusly: (some-fn 1 2 3)

8:43 clgv: Rhainur: you can change that - there are books and online introductions to clojure ;)

8:43 llasram: Rhainur: `apply`

8:43 ,(apply + [1 2 3])

8:43 clojurebot: 6

8:43 Rhainur: but apply gives me 1 item

8:44 I don't want to call some-fn on all the arguments

8:44 some-fn accepts 3 arguments

8:44 llasram: Right..

8:44 (apply f [x y z]) is the same as (f x y z)

8:44 daniel___: Rhainur: map would do that, apply is the closest to unpacking you might find in python et al

8:44 hyPiRion: ,(map (fn [x] (+ 1 x)) [1 2 3])

8:44 clojurebot: (2 3 4)

8:45 Rhainur: llasram: ahhhh

8:49 juliobarros: Datomic question: I have a bunch of entity types with several common attributes (name, active, etc.) does it make sense to make one common attribute that any entity "type" can have or to namespace each attribute for each entity x/name AND y/name, etc.

8:58 Rhainur: so this might be quite an unreasonable request, but I'm trying to figure out how to "think" in idiomatic Clojure and struggling a lot. For simple stuff it seems straightforward, but...

8:59 llasram: Rhainur: My experience is that you just work in the language long enough and it eventually clicks

8:59 bacon1989: ^

8:59 Rhainur: I have a a piece of code in imperative style that I'm trying to redo in clojure and am just blanking on doing it any way other than imperative

8:59 bacon1989: Rhainur: been running into the same problems

9:00 Rhainur: if you have the oreilly book on clojure programming, i'd recommend going through the parallelism/concurrency section a few times

9:00 llasram: It just takes time (again IME). I had a definite point where it flipped from feeling like I was struggling to write my code "backwards" to it feeling completely natural

9:00 Rhainur: how did you start though, just reading through books? or project euler or something?

9:00 bacon1989: the biggest hurdle I hit was figuring out how to have 'some' state

9:00 awwaiid: Rhainur: I kept trying to use atoms and refs and such, before realizing that I could just have a function that returns the new value, and then just conveniently forget that the old value was ever around (instead of overwriting it)

9:01 bacon1989: Rhainur: project euler is good as a start, but the solutions are mostly stateless

9:01 llasram: Rhainur: I went though project Euler problems, did a few tiny projects (Mandelbrot set renderer), and re-did a few work projects in Clojure (not for production at first -- just exercise)

9:02 J_Arcane: Clojure, thus far, is proving a very good sandbox for *forcing* me to get better at functional style. I have too much BASIC and Python in my blood still, so it's taking some amount of practice to get out of it.;)

9:03 dnolen_: juliobarros: more likely to get an answer in #datomic

9:04 juliobarros: dnolen_: Thanks. Did/do not see that channel ... Hmm.

9:07 Rhainur: J_Arcane: I went from PHP to Ruby and now I'm trying out Clojure

9:08 daniel___: Rhainur: 4clojure is good, a lot of those are hard to begin with

9:09 and after struggling a bit, you can search for solutions and see how others solved them

9:09 not3: I want to try clojure and racket

9:09 awwaiid: 4clojure?

9:09 clojurebot: 4clojure is the place to go for Clojure exercises

9:09 awwaiid: hm!

9:10 J_Arcane: I am working on the Clojurescript Koans myself. A few are a bit brain-bending, but it's a good way to quickly pick up the basics. I'll probably do 4clojure next.

9:12 awwaiid: a lot of my friends like exercism.io, but I haven't tried it

9:13 J_Arcane: awwaiid: I hadn't heard about that one. Looks pretty cool.

9:13 I'm finding I learn better through these sorts of interactive methods than with traditional books (though Practical Common Lisp was pretty good, just not sure I like CL).

9:14 necronian: Can someone explain to me what is happening here? (clojure.string/replace "$" #"\$" "\\\\$") => StringIndexOutOfBoundsException String index out of range: 3 java.lang.String.charAt (String.java:658)

9:15 clgv: ,"\\\\$"

9:16 clojurebot: "\\\\$"

9:16 clgv: ,#"\$"

9:16 clojurebot: #"\$"

9:16 necronian: This (clojure.string/replace "$" #"\$" "\\$") works

9:17 and this also evaluates (clojure.string/replace "$" "$" "\\\\$")

9:19 clgv: necronian: you have to consult the javadocs therefore Matcher/replaceAll

9:21 necronian: clgv: Yea that would probably be a smart idea

9:24 clgv: Thanks for the tip. I feel pretty stupid now. Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string.

9:27 dgaffney: Hey all, I'm relatively new at this and I'm trying to use the async module to make a series of calls to an API, then one final API call that uses the sum of the results from that series of API calls. What am I doing wrong here? https://gist.github.com/DGaffney/2b060bcc1a459334f65d

9:28 wait whooooops - I am in the clojure channel.

9:28 I'm learning both at the same time :|

9:28 * dgaffney joins node

10:10 jtackett: hey, I want to be able to write a file to the desktop from my heroku app

10:10 I know it is a read only file system, but I need a way for the user to save a text file they have created to their desktop

10:11 justin_smith: jtackett: what desktop?

10:11 jtackett: the user’s desktop

10:11 justin_smith: oh, then send it to them as a response with a content type that triggers a download

10:12 jtackett: how would you go about doing that in clojure?

10:12 justin_smith: technically they will decide where it goes

10:12 is this a webapp?

10:12 jtackett: yep

10:12 justin_smith: so, something on the client side has to send you a request, and you reply with the contents of the file

10:13 either they click a button "click here for your file" or you have some js magic going on

10:13 jtackett: so thinking from a view and handler set up

10:13 let’s say they click a button for it

10:13 justin_smith: right, and you would have the right data in the session to associate the user with their file

10:13 jtackett: how do you trigger a download?

10:13 justin_smith: by setting the content type such that a browser downloads rather than displaying

10:13 jtackett: sounds fancy

10:13 how does that work?

10:14 like what is the code for that

10:15 justin_smith: in your handler, you should return a map {"Content-Type" "some-content-type" :body (slurp (io/input-stream (io/file user-file)))}

10:16 wait, you probably want to leave off the slurp there

10:16 I am looking up docs for the content type setting

10:17 http://stackoverflow.com/questions/925854/forcing-a-file-to-download here we go

10:17 that's how you do it

10:18 oh, and the actual map is {:headers {"Content-Type" "application/octet-stream" "Content-Disposition" "attachment"} :body (io/input-stream (io/resource user-file))}

10:20 jtackett: alright perfect

10:20 d0ky: hello does anybody know how to remove diacritics ? i'm trying:

10:20 (java.text.Normalizer/normalize "áČš" java.text.Normalizer$Form/NFC) but it returns áČš instead aCs

10:20 jtackett: just need to figure out where that would go in the handler/view scheme

10:21 justin_smith: jtackett: that map is what you return from the handler

10:21 where usually you would return a string or whatever

10:22 mdrogalis: I think I'm close to understanding transducers. I get that they somehow don't use intermediate results and are more efficient in that sense, but why doesn't normal function composition suffice *to begin with*? See: https://gist.github.com/MichaelDrogalis/51fe0e76f61e6cebb987

10:22 jtackett: so usually I would return a view, but I should return that map?

10:22 can I also put a string as the body?

10:22 or does it need to be a file

10:22 justin_smith: sure

10:22 it can be a string, an input string - however you generate the thing to download

10:23 jtackett: so it could be: {:headers {"Content-Type" "application/octet-stream" "Content-Disposition" "attachment"} :body “Some string of text”}

10:23 justin_smith: if you return a map with :body key, the associated val is used the same way it would if it were the only thing you returned

10:23 right

10:23 jtackett: alright perfect

10:23 I’ll give it a shot after this meeting

10:23 thanks, I’ll be back on if I have any questions

10:24 justin_smith: so if it's more convenient it can also be a collection of strings, and ring will join them, for example

10:26 d0ky: hello is there any way how to replace accents letters with non-accents letters ? (java.text.Normalizer/normalize "ácš" java.text.Normalizer$Form/NFC) doesn't work :/

10:29 justin_smith: ,(java.text.Normalizer/normalize "ácš" java.text.Normalizer$Form/NFKD)

10:29 clojurebot: #<ExceptionInInitializerError java.lang.ExceptionInInitializerError>

10:29 justin_smith: err...

10:29 try that

10:29 it separates the diacritics from the chars

10:30 cbp: ,(java.text.Normalizer/normalize "ácš"

10:30 java.text.Normalizer$Form/NFD)

10:30 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

10:30 cbp: oops

10:31 d0ky: with (java.text.Normalizer/normalize "ťcš" java.text.Normalizer$Form/NFKD) or NFD i always get the same result ...

10:31 justin_smith: yeah, NFD and NFKD seem to give the same result

10:32 d0ky: but always with marks => ťcš

10:32 justin_smith: d0ky: it isn't meant to eliminate the diacritics, just make them separate characters, or a character plus a combining diacritic

10:33 (java.text.Normalizer/normalize "ácš" java.text.Normalizer$Form/NFD) => "ácš

10:33 that is exact what it should be doing

10:33 cbp: (-> "ťcš" (java.text.Normalizer/normalize java.text.Normalizer$Form/NFD) (.replaceAll "[^\\p{ASCII}]" ""))

10:33 d0ky: justin_smith: oh ... so can i get characters without marks ?

10:34 justin_smith: looks like cbp answered your question right before you asked it

10:34 d0ky: justin_smith: wooow that works great :)

10:34 thank you :)

10:35 cbp: sorry ... thank you :)

10:35 cbp: justin_smith: you both thanks :)

10:36 cbp: (:

10:36 justin_smith: d0ky: we have fake internet points we use in these situations

10:36 (inc cbp)

10:36 lazybot: ⇒ 8

10:37 d0ky: justin_smith: ok :)

11:25 dgrnbrg: Is (clojure.core.async/chan 0) the same as (clojure.core.async/chan)?

11:27 justin_smith: dgrnbrg: the docs seem to imply there is no buffer if no arg is supplied, so I guess that would be the same as explicitly supplying an n of 0?

11:28 dgrnbrg: that’s what I hope, but I don’t want to manually verify this—hoping someone else already knows

11:28 nick___: https://github.com/clojure/core.async/blob/53bf7866f195e6ba247ff7122b99784e66e9f1bb/src/main/clojure/clojure/core/async.clj#L66

11:29 justin_smith: dgrnbrg: https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj#L12 this seems to imply so too

11:30 dgrnbrg: the proper idiom appears to actually be to use nil instead of 0

11:30 hlprmnky: dgrnbrg: I just spun up a REPL and made a chan with ‘0’ and it certainly appears to behave just like a chan with no arg

11:31 dgrnbrg: it’s tricky to test the buffering behavior

11:31 because I want to be able to control whether or not there’s any buffering going on

11:36 ghadishayban: in the reducers intro post a couple years ago, there was a reference to multi-fold / multi-reducibles being a topic of active research. does anyone know of any research?

11:37 borkdude: in clojure mode, can you collapse functions?

11:39 justin_smith: borkdude: I use hs-minor-mode and outline-minor mode for that (they each have advantages, they each know how to collapse / expand a sexp)

11:39 ghadishayban: reducers for parallel reduction?

11:40 Johannes`: hi, is it possible to view REPL error messages in fireplace.vim?

11:40 i only get the Vim(python): Traceback: line

11:40 when code is invalid

11:41 borkdude: justin_smith thanks. I\m trying hs-minor-mode, but gosh, the default keybindings... :)

11:42 justin_smith: borkdude: yeah, it really needs custom keys

11:42 Johannes`: (pst) should show you the stack trace for the most recent error in any repl

11:42 Johannes`: in the odd case that clojure.repl is not in scope, it will be clojure.repl/pst

11:43 dgrnbrg: Johannes`: use “:lopen” in vim

11:43 this will open a vim stacktrace that will let you navigate the code easiyl

11:43 justin_smith: oh, fancy :)

11:46 Johannes`: dgrnbrg: it gives me "no location list"

11:46 dgrnbrg: Johannes`: you have fireplace installed? and you had an exception thrown?

11:46 Johannes`: yeah

11:46 dgrnbrg: weird

11:46 well, it’s supposed to work then

11:46 Johannes`: :S

11:46 technomancy: /

11:46 `.

11:47 derp

11:47 justin_smith: I thought it was maybe collaborative ascii art time

11:47 borkdude: maybe there is some mode that gives an overview in the left buffer, and you can select to set point to sexp in the right buffer?

11:48 justin_smith: borkdude: speedbar should be able to do that, if you have it configured for clojure (which I have not done, but I know is hypothetically possible)

11:48 borkdude: if you are talking about emacs that is

11:48 borkdude: justin_smith yes

11:48 danneu: I'm having trouble writing/applying a function `ignore-assets` that takes middleware that will only be applied to a request if it's no an asset request (css, js, etc) https://www.refheap.com/89984

11:49 having trouble thinking about it. has anyone written something similar?

11:49 justin_smith: ,(re-find #".js$|.css$|" "foo.css") ; danneu

11:49 clojurebot: ""

11:49 justin_smith: I think your regex is bad

11:50 danneu: the rest of it is bad too

11:51 justin_smith: you have trailing pipe

11:51 justin_smith: ,(re-find #"\.js|\.css$" "foo.css")

11:51 clojurebot: ".css"

11:51 justin_smith: ,(re-find #"\.js|\.css$" "foocss") ; I fixed this corner case

11:51 clojurebot: nil

11:51 danneu: haha thanks

11:51 TimMc: justin_smith: "...and you should feel bad."

11:52 Johannes`: justin_smith: thanks, using :map <F5> :Eval (pst)<CR>

11:53 justin_smith: danneu: with the fixed regex, it should be close to fixed if not fixed - your first regex actually matches anything with empty string (which is truthy)

11:53 ,(if (re-find #".js$|.css$|" "foo.bar") :MATCHED)

11:53 clojurebot: :MATCHED

11:53 justin_smith: ,(if (re-find #"\.js|\.css$" "foo.bar") :MATCHED :NO_MATCH)

11:53 clojurebot: :NO_MATCH

11:54 mr-foobar: a webapp using cookies + db is stateful right ?

11:55 ghadishayban: justin_smith: "joining" two reductions together

11:55 dm3: mr-foobar: no, it's stateful if it has a session or keeps something in memory

11:55 justin_smith: ghadishayban: ahh, so transducers

11:55 ghadishayban: in particular the transduce function

11:56 dm3: anyone experienced with core.logic here? having trouble thinking about a problem:

11:56 justin_smith: dm3: well, with a db you can proxy state via api calls

11:56 ghadishayban: justin_smith: only map can reduce over multiple logical collections

11:56 dnolen_: dm3: ask your question

11:56 Johannes`: why does [3] equal '(3)?

11:56 justin_smith: ghadishayban: I thought you meant composing reductions into one reducing action

11:56 dm3: basically need to reconcile two sets of records ('id 'number)

11:57 justin_smith: Johannes`: structural equality

11:57 dm3: where either 1. records are equal, 2. sum of records with the same id on one side == 1 record on the other side, 3. sums on one side == sums on the other side

11:58 mr-foobar: justin_smith: isn't it simpler to throw out rest and use a stateful server then ?

11:58 i think clojure might provide execellent primitives for a server.

11:59 danneu: mr-foobar: what are you trying to do?

11:59 justin_smith: mr-foobar: it is excellent for making servers. It is easy to make per-request bindings that are invisible to other requests.

11:59 mr-foobar: with persistent state via db or cookie session

11:59 mr-foobar: danneu: oh nothing. just got bored implementing yet another cookie seesion

12:00 justin_smith: mr-foobar: are you not using the standard ring middleware for that?

12:01 dm3: dnolen_: thought about fd, but cannot understand how to create a domain of sums which maps back to individual record ids

12:01 dnolen_: probably just thinking about the problem completely un-logically :)

12:01 jtackett: justin_smith: the download stuff works but it does not allow the user to name the file and decide where to save it

12:01 it only just downloads it

12:01 justin_smith: Johannes`: my response earlier was a bit glib. In clojure, since we focus on immutible values, we don't care so much about identity of objects, we do care if they have the same effective structure.

12:02 danneu: justin_smith: sad, i actually did have that trailing pipe in my code. the gist now works, thanks.

12:02 justin_smith: jtackett: I think another answer in that same SO thread had an answer for that

12:02 mr-foobar: justin_smith: i am but I feel if http is like an interface ( not ring which is a level of indirection ) I think you could embed an app directly into the server.

12:03 technomancy: Johannes`: it's because pervasive laziness would be a lot more awkward if it affected equality

12:03 justin_smith: mr-foobar: I like the indirection ring provides, it adds sanity and isolation

12:03 Johannes`: technomancy: true

12:04 technomancy: ,(= (map identity [1 2 3]) [1 2 3])

12:04 clojurebot: true

12:05 justin_smith: ,(= (map identity [1 2 3]) (lazy-seq [1 2 3]) (list 1 2 3) [1 2 3])

12:05 clojurebot: true

12:05 justin_smith: ,(= [1 2 3] (into-array [1 2 3])) ; but

12:05 clojurebot: false

12:06 technomancy: well yeah, mutability is gross

12:06 if only it were consistent about that though =(

12:07 justin_smith: yeah, just pointing out the gotcha :) it is of course there for good reason

12:08 actionshrimp: it was like 52/59ths the size or something

12:12 Johannes`: 18:03 <technomancy> Johannes`: it's because pervasive laziness would be a lot more awkward if it affected equality

12:12 out of context, this sounds like political debate

12:12 technomancy: poor people, amirite?

12:12 Johannes`: y

12:13 mdrogalis: Hah

12:13 lavokad: hi, why M-x clojure-mode doesn't provide the auto-indentation? Does anyone know what is problem with this?

12:14 rweir: as in "I hit enter but it didn't indent the cursor"?

12:14 technomancy: lavokad: that's what C-j does out of the box, but you can rebind to RET

12:14 danneu: for some reason after i updated my emacs packages, <enter> at the end of a line in a clj file always goes to col0 on the next line, but now i have to C-j to do that

12:15 justin_smith: lavokad: I think there is something like "electric-newline" you can set

12:15 danneu: <enter> used to behave like C-j

12:15 Johannes`: well check C-h k C-j and C-h k RET

12:15 lavokad: justin_smith: haha

12:15 technomancy: danneu: the old behaviour was a bug

12:15 lavokad: u know everyhing

12:15 that is crazy

12:16 danneu: Johannes`: thanks. RET is evil-ret and C-j is paredit-newline

12:16 justin_smith: lavokad: I've been using emacs for a long time

12:16 lavokad: electric-indent-mode. So this function in clojure-mode package?

12:16 rweir: no, it's independent of clojure-mode

12:16 justin_smith: it's an emacs thing

12:17 J_Arcane: I have apparently completed the Clojurescript Koans.

12:17 rweir: should we be koancerned?

12:17 J_Arcane: Hah!

12:18 justin_smith: J_Arcane: there is also 4clojure

12:18 if you are looking for more

12:18 lavokad: So why does one need clojure-mode?

12:18 rweir: lavokad, because emacs has no idea how to indent clojure code or colour it or ...

12:18 J_Arcane: justin_smith: Yes. also, the CLJS version is incomplete, if I want the rest I should consider at least doing the relevant parts of the clojure koans.

12:18 rweir: lavokad, electric-indent-mode asks the major mode to indent the thing

12:18 justin_smith: lavokad: for things like highlighting, for defining clojure specific versions of the generic emacs concepts (like what a sexp is, how things should indent)

12:20 it's like a janky brittle elisp version of protocols - there are the generic definitions of things, commands that act on them, and then each mode provides the concrete actions they are bound to

12:20 lavokad: ok. And what is best way to see clojure's function doc stuff in emacs?

12:20 while writing code..

12:21 justin_smith: I think there is a mode or setting for showing the arglist in the minibuffer - dunno about the docstring though

12:21 mwfogleman: lavokad: are you using CIDER?

12:21 adereth: C-c C-d

12:21 ?

12:21 justin_smith: but that would be part of the repl integration (swank / nrepl.el / cider) since it has to ask the clojure process for info

12:22 adereth: Assuming you are using CIDER

12:22 mwfogleman: if so, you'll want to set up eldoc (which justin_smith was talking about), and you can use M-. to see cource code and the C-c C-d (g / h) to see Grimoire stuff... I think there are others

12:23 danneu: Would anyone use a bolt-on forum system where you own trumpets.com and CNAME forum.trumpets.com to trumpets.forumservice.com?

12:24 rweir: isn't that what discourse does

12:24 dagda1: paredit or smartparens, is there a reason to favour one over the other?

12:24 danneu: rweir: isnt discourse self-hosted?

12:24 rweir: paredit had a better cheatsheet at least

12:24 technomancy: dagda1: smartparens is more work to configure, but it works on non-lisps

12:24 or so they say

12:25 J_Arcane: I think I technically use paredit, but to be honest I also mostly rely on electric-pairs insted.

12:25 dagda1: technomancy: it works with ruby also

12:25 danneu: rweir: and, at that point, discourse is even hard to self-host

12:26 justin_smith: lavokad: and given that my answers have been incomplete: http://media-cache-ec0.pinimg.com/236x/7a/19/bc/7a19bca2d9e429993ac39e4241d832e6.jpg

12:27 lavokad: ;D

12:28 I situate the cursor on defmacro word, then C-c C-d and waiting more in input..?

12:28 justin_smith: http://i.lvme.me/q2za7r5.jpg

12:28 J_Arcane: posting my clojure fizzbuzz golf apparently gained me new twitter followers in the form of four nearly identical "famous quotes" accounts and an SQL consultant.

12:29 justin_smith: hah

12:33 apod: lavokad: If you are using cider >= 0.7, the keybinding is C-c C-d d

12:34 lavokad: thanks!


12:34 rweir: hm, still no 24.4

12:36 mdrogalis: Repost from earlier:

12:36 I think I'm close to understanding transducers. I get that they somehow don't use intermediate results and are more efficient in that sense, but why doesn't normal function composition suffice *to begin with*? See: https://gist.github.com/MichaelDrogalis/51fe0e76f61e6cebb987

12:39 CookedGryphon: mdrogalis: the bottom one creates a lazy map which is fed into a lazy filter, the first one doesn't create an intermediate filter, in one shot it increments the number and looks at whether it's even

12:41 tbaldridge: mdrogalis: right, the second one creates lazyseqs between coll, map, filter, and dedupe

12:41 joegallo: CookedGryphon: making sure i'm tracking you, the difference is the amount of intermedia objects (that is, garbage) that are created?

12:41 CookedGryphon: yeah

12:41 joegallo: heh, intermedia --> intermediate ;)

12:42 would be very neat to see a comparison of the two in a profiler

12:42 CookedGryphon: say your coll is 50meg, and for simplicity's sake, each transformation you're doing on it the result also takes up 50 meg, with the first example you only end up with 50 meg in and 50 meg out, the second one, you end up with 50+ 50 for the result of the map + 50 for the result of the filter .... etc. which has to be GCd

12:43 joegallo: and gc is cheap, but it isn't *free*

12:44 technomancy: still, I get the feeling this isn't going to be a bottleneck in the large majority of applications

12:44 CookedGryphon: I think there's extra indirection too

12:45 in terms of the number of function calls

12:45 technomancy: similar to how multimethods are rarely a bottleneck, but it's good to have a faster alternative for those rare cases

12:45 joegallo: technomancy: maybe not on your debian-based system. but i'm running gentoo with the most incredible CFLAGS in the universe.

12:45 jk jk

12:45 * technomancy is in awe of joegallo's CFLAGS

12:47 justin_smith: another thing to consider is the number of heap lookups that are eliminated when transducers are composed - not that clojure is anything close to being a cache-line-coherent language, but every little bit helps

12:47 *cache-line-friendly I mean

12:47 coherency is another thing altogether

12:47 (provided by CPU, not language)

12:48 CookedGryphon: I personally am really excited about it. All my app does is pile up transformations on channels to respond to events

12:48 justin_smith: yeah, that seems like a perfect use-case

12:48 mdrogalis: CookedGryphon / tbaldridge: Sorry, got pulled away. Yep, I get that there's less garbage. But here's a more directed question: Why does core.async need to provide map/filter/etc mirrors in the first place?

12:48 Why couldnt it take an aribitrary function?

12:49 tbaldridge: mdrogalis: "arbitrary function" ?

12:49 CookedGryphon: ... what do you mean? It doesn't provide map/filter etc any more, it takes the transducers versions now

12:50 mdrogalis: CookedGryphon: Consider pre-transcuders commits. In core.async, there's map< filter<, mapcat< etc

12:50 Why couldnt there be one api that takes a function instead?

12:51 CookedGryphon: good point... and as I understand it, entirely the logic behind having transducers...

12:52 justin_smith: mdrogalis: that's what transducers are, right? it's the way one defines a function that can be bolted onto a channel. Or do you mean we should be allowed to put any function on there?

12:52 tbaldridge: mdrogalis: you'll be at STL right?, go to Rich's talk, all will be explained, I'm sure ;-)

12:52 CookedGryphon: I think you *can* put any function on there, which matches the signature of the transducers

12:52 mdrogalis: Just throw out transcuders for a second. I dont understand what prevented us from composing functions in the first place. D:

12:52 Im sure theres a reason, I just dont get it

12:52 tbaldridge: Yeahhh, I think Ill wait I guess.

12:53 dnolen_: mdrogalis: what is there to compose?

12:53 mdrogalis: map/filter/reduce too sequence like things

12:53 there are no real sequences in event streams

12:53 s/too/took

12:54 mdrogalis: dnolen_: Ahhhhh

12:54 There we go, it clicked.

12:54 dnolen_: Thanks. I was mentally throwing .. Something out. Im not sure what, but yeah. I see now.

12:56 ghadishayban: yeah the cache line sympathy is important too

12:58 justin_smith: ghadishayban: there we go, sympathy was the word I was searching for

12:58 ghadishayban: hiredman is on a crusade to get things to have reduce at the bottom rather than lazy-seq... the benefit is very nice

12:59 tbaldridge: +1, reduce all the things

12:59 ghadishayban: half of the knobs on c.j.jdbc/query call are to control realization of the sequence

12:59 rweir: reduce or transduce?

12:59 ghadishayban: think of them similarly

13:00 they can both abort through "reduced"

13:00 tbaldridge: I've noticed that half the time when I used lazy-seqs I was really only using them to compose pipelines, I very rarely wanted the lazy bits. Thus all that stuff can be converted to transducers

13:00 justin_smith: transduce is just a generalization of the reduce concept, no?

13:00 ghadishayban: now that into uses transduce, c.j.jdbc could do this: (into (take 5000) (queryr "select * from foo"))

13:01 rather (into [] (take 5000) (queryr "select * from foo"))

13:01 mdrogalis: Nice :)

13:01 justin_smith: ghadishayban: the laziness is helpful for having control of the db connection, and not needing to transmit more results if you discover you have what you need (though reduced could do the same I guess :))

13:01 jtackett: hey :justin_smith couldn’t find how to get the actual download window to come up

13:01 ghadishayban: that way you don't have to tell jdbc how much you want to stream

13:01 justin_smith: it's still "lazy"

13:02 technomancy: ITYM :org.freenode.clojure/justin_smith

13:02 ghadishayban: it's just not a concrete lazy-seq

13:03 jtackett: ghadishayban: wrap that in a doall

13:03 ghadishayban: ?

13:03 justin_smith: jtackett: the point here is we don't even want laziness in that context

13:03 jtackett: sorry came in the convo too late haha

13:04 oh i got ya

13:04 kind of loosing the point of clojure haha

13:04 justin_smith: jtackett: not sure, but maybe try taking out the content-disposition attachment part

13:04 jtackett: not at all! this is about transducers

13:05 jtackett: maybe it’s a different acontent type?

13:05 sorry I haven’t handled transducers at all

13:05 justin_smith: they are quite new

13:05 octet-stream should be the one for downloads in general

13:05 jtackett: nice, gotta love the new stuff coming out

13:05 justin_smith: the disposition should be the one that effects how it is handled

13:09 ghadishayban: transducers really are the shit

13:09 a high-performance, high-level abstraction that was hiding in plain sight

13:10 mikerod: transduce* all the things

13:11 ghadishayban: also plays nicely with java 8 streams api

13:12 justin_smith: oh really? that's awesome

13:12 dnolen_: ghadishayban: cool, I'm really looking forward to your Conj talk BTW :)

13:12 ghadishayban: for example java.util.regex.Pattern/splitAsStream

13:13 J_Arcane: Man, sometimes I love FreeBSD ports so much. Up-to-date packages for Clojure, CIDER, and clojure-mode, all in the repos already. :D Might be time to reboot in a minut.

13:13 ghadishayban: transduce over the stream, and you can get zero-allocation fun

13:13 tadni_: J_Arcane: Can't you just use package.el for the latter two?

13:14 J_Arcane: tadni_: Probably safer most times, yes.

13:15 technomancy: I wouldn't call it safer

13:15 package.el installs over unencrypted http

13:15 ghadishayban: wrote this as a demonstration of a reducer last year, works the same under transduce https://gist.github.com/ghadishayban/7002262 string regex split that is much faster than both string/split *and* Java's Pattern/split

13:15 J_Arcane: Well, I mean less from a security standpoint than from a current-ness one.

13:15 tadni_: FreeBSD has no Lighttable. The tradgedy.

13:16 technomancy: J_Arcane: "current" isn't always a good thing with cidec

13:16 J_Arcane: ie. you're possibly going to get a slightly newer package from MELPA or something for some packages.

13:16 technomancy: cider

13:18 arohner: can I use data literals to make datomic queries return joda time rather than j.u.Date?

13:18 ghadishayban: dnolen_: Conj talk will be low-level and dirty and you'll need a shower afterwards. nashorn really is an amazing piece of engineering

13:19 unfortunately the current state of invokedynamic isn't all rosy

13:20 nick___: Whats the prblem with invokedynamic?

13:20 Is there a good talk or blogpost?

13:20 ghadishayban: JVM current impl has some warmup issues, inferior to JRockit implementation

13:21 not fundamental problems with invokedynamic as a concept at all

13:22 nick___: if you want a reference http://mail.openjdk.java.net/pipermail/mlvm-dev/2014-August/005890.html John Rose wrote a brilliant summary of future direction for fast startup

13:22 on the JVM as a whole, a superset of indy issues

13:23 that whole thread is gold, especially Charlie Nutter, Marcus Lagergren

13:24 and Fredrik Ohrstrom, the originator of the JRockit impl which is able to crrrunch all the invokedynamic things and remove boxing

13:29 nick___: Thanks

13:29 So the problem is only with start up, or are there other fundamental problems?

13:31 ghadishayban: warmup that is the main issue for indy, and it's only so because of the JDK internal implementation (see LambdaForms)

13:31 and also indy doesn't run on android or GAE

13:32 atyz: I'm looking for a fn similar to interleave/zipmap but that would work with collections of different lengths. So when one collection is used it will start at the beginning and continue

13:32 ghadishayban: so it would definitely have to be a compilation mode

13:32 hiredman: atyz: cycle

13:32 atyz: thanks!

13:32 (inc hiredman)

13:32 lazybot: ⇒ 55

13:34 CookedGryphon: Does anyone here use expectations?

13:34 my tests do a lot of partial matches of big maps, and it's just infuriating using midje when it spews a whole screen of stuff out at you with no hint as to what's different between the two

13:35 and expectations looks better, but I can't seem to get expectations-mode to actually run my tests in emacs

13:35 or in the repl for that matter

13:35 technomancy: CookedGryphon: https://github.com/pjstadig/humane-test-output

13:35 danneu: i use expectations

13:36 technomancy: but I support getting off midje

13:36 atyz: I second technomancys' suggestion

13:36 tbaldrid_: CookedGryphon: use clojure.test ;-) the only true testing library

13:36 xeqi: poor unloved test.check

13:37 tbaldrid_: well yeah, use that when you can as well.

13:37 danneu: though 75% of my tests are a menagerie of `assert`s at the bottom on each file with `TODO: Extract into test framework` that never actually happens

13:38 CookedGryphon: is the general consensus to stick with clojure.test with humane-output then?

13:38 tbaldrid_: CookedGryphon: I just use plain clojure.test, and jump to the repl when I can't understand the test ouptut

13:38 CookedGryphon: if so, where are some good helpers for things like "this map contains at least these key/values and ignore the rest"

13:39 tbaldrid_: here's one, https://github.com/brentonashworth/lein-difftest and I like that it's not on by default.

13:39 atyz: tbaldrid_: you don't run your tests from the repl? Or are you running the entire suite at once?

13:39 via lein test

13:39 tbaldrid_: atyz: I do both, most of the time at the REPL

13:44 ckarlsen: after upgrading from 1.7 alpha1 to alpha2 i can no longer connect to datomic. 'NoSuchMethodError clojure.lang.SeqIterator.<init>(Lclojure/lang/ISeq;)V datomic.fulltext.Root (fulltext.clj:253)' -- after running `connect`. Only thing I did was replace alpha1 w/ alpha2 in project.clj and ran `lein clean`. Any tips?

13:50 amalloy: ckarlsen: alpha2 isn't binary-compatible with alpha1, and your version of datomic is apparently compiled against the other one

13:50 specifically, https://github.com/clojure/clojure/blob/43cc1854508d655e58e377f84836ba128971f90c/src/jvm/clojure/lang/SeqIterator.java changed a method from taking ISeq to taking Object

13:51 hiredman: (the pains of distributing an aot compiled library)

13:55 ckarlsen: ok thanks!

13:58 justin_smith: #closedsourceproblems

13:58 dm3: CookedGryphon: https://gist.github.com/dm3/a1dacafb11617a722a96 for the submap with humane-test

14:10 ghadishayban: justin_smith: hiredman: something like this in java.jdbc would be amenable to transduce/reduce https://gist.github.com/ghadishayban/d2f31961deba98ee4595

14:11 though java.jdbc i think is still compatible with clojure 1.2 and can't use 'reduced'

14:12 hiredman: ghadishayban: maybe link that gist on the jdbc story?

14:13 ghadishayban: k

14:15 llasram: Why do transducers have a special extra fast fast path for IReduce?

14:16 hiredman: do they?

14:16 llasram: Yeah -- look at the implementation of `transduce`

14:16 ghadishayban: transduce does

14:17 basically if you are in control, reify IReduce and not CollReduce

14:17 CollReduce on an IReduce just calls .reduce

14:17 it's a little surprising, only in that there are two functionally equivalent paths...

14:18 llasram: Blergh. I wish protocols could just their backing interface. Or something. So we could have the same JVM interface for an abstract protocol in both Clojure and Java code

14:18 s,could just,could just specify,

14:18 hiredman: hmmm, I can't say I like the idea of the recommended path being the java interface over the protocol

14:19 really what you want is the ability to retro fit a protocol to an existing interface instead of generating a new one

14:19 ghadishayban: yeah it strikes me as entirely pragmatic choice, and not motivated by idealistically dog-fooding protocols everywhere

14:19 hiredman: I think hugod did some work on something like that a while back

14:19 danneu: so i have a spare domain that i use for testing my subdomain-based forum system. every time i reset the database, this guy creates a thread http://community-1.fed.nu/forums/1/topics/5

14:20 it's like seed data

14:20 bacon1989: i'm still trying to wrap my head around transducers

14:29 llasram: bacon1989: They're like burritos

14:29 bacon1989: dirty and fast?

14:29 messy and fast to consume?

14:30 I have a small inklet on how they work, it's more about use-cases I guess

14:30 like, I look at defmulti, and i can see that it's a fancy generic dispatcher

14:31 TimMc: llasram: Oh, they are, aren't they?

14:32 ghadishayban: hiredman: something like that for jdbc?

14:32 bacon1989: I have a good question for you guys, say I wanted to write a website with a database

14:32 ghadishayban: my weekend yak-shave was making a fast csv parser that is reducible

14:32 hiredman: ghadishayban: binding a protocol to an already existing interface

14:32 bacon1989: where could I place the configuration optoins for my database, if it's going to be different based on deployment?

14:32 hiredman: I think it was hugod I may be mistaken

14:33 bacon1989: I can't place it in the .jar file, how would I refernece a custom config?

14:33 ghadishayban: i mean the basic interface for a query

14:33 (into [] xfn (query ...))

14:33 justin_smith: bacon1989: typically I have separate config files in the resource path, and use an environment variable to decide which one should be loaded

14:33 hiredman: so you could, for example, have IReduce available for java interop and just bind the CollReduce protocol to use that same interface instead of creating a new one

14:34 bacon1989: justin_smith: can you elaborate on that? what if I wanted to change the custom config?

14:34 justin_smith: bacon1989: with that setup, a client who wants none of the config in the jar, could add another to the classpath, and specify that one via env

14:34 bacon1989: ah

14:34 justin_smith: ie. if CONFIG=production it looks for production.edn in classpath

14:34 etc.

14:35 ghadishayban: hiredman: presumably the reduction time will overwhelm protocol/interface dispatch time

14:35 Bronsa: hiredman: I haven't read the backlog but there's a way to change the backing interface for a protocol

14:35 ghadishayban: hiredman: on-interface?

14:35 llasram: Bronsa: ooh?

14:35 Bronsa: llasram: what ghadishayban just said :)

14:35 danneu: bacon1989: i use `environ` library. https://github.com/danneu/bulletin/blob/master/src/bulletin/config.clj - for local dev, i have a .lein-env file (i dont commit) that has stuff like :database_url

14:35 llasram: oooh

14:36 ghadishayban: not dynamically, but at definition time...

14:36 Bronsa: I don't think it's documented though

14:36 ghadishayban: yeah was going to say, i've never used it

14:37 llasram: And it appears to generate a new interface with the provided name, which isn't what you'd need to solve this problem

14:38 bacon1989: danneu: justin_smith, I like both of your solutions

14:38 danneu's solution seems easier, but justin_smith's seems more flexible

14:39 justin_smith: bacon1989: getting a value from System/getenv and then using that as an arg to clojure.java.io/resource is a one liner

14:40 bacon1989: oh I know, but a system admin is more likely to blame you if they mess up a custom EDN config file, over messing with the environment variables

14:42 in fact, i'd probably employ both. Keep database config in env, and have a custom.edn outside of the scope of configuration

14:43 mbriggs: Hey guys, in ruby, if I did File.expand_path("~/foo.txt"), I would get "/Users/matt/foo.txt". Is there anything similar in clojure?

14:43 i.e. "turn this string into whatever bash would evaluate it to be"

14:43 hiredman: Bronsa: ah, well, there you go

14:44 so CollReduce should just be :on-interface on IReduce

14:44 Bronsa: yes

14:44 hiredman: someone tell rich

14:44 llasram: hiredman, Bronsa: except `defprotocol` still calls `gen-interface` for the provided :on-interface name

14:44 bacon1989: mbriggs: if you're not afraid to do some java interop, I think java.io.File has what you need

14:44 justin_smith: mbriggs: java.nio.file.PathMatcher

14:44 mbriggs: awesome, thanks

14:45 hiredman: llasram: :/

14:45 Bronsa: llasram: does it?

14:45 hiredman: llasram: gen-interface may short circuit if it already exists

14:45 (also not it on telling rich)

14:45 llasram: Bronsa: I don't see anything which would make it conditional

14:45 hiredman: hmmm...

14:46 rweir: mbriggs, does it really do what bash would do? or does it just expand ~?

14:47 hiredman: it doesn't look like it

14:47 llasram: hiredman: No, don't see anything conditional there either. In fact "normally" expects interface might already exist, in case of redef

14:47 mbriggs: rweir in this case just expand ~

14:47 Bronsa: oh well

14:47 hiredman: :/

14:48 Bronsa: inb4 classloader issues make the "shadowing" interface irrelevant

14:48 ... yeah it seems to work

14:49 hiredman: sure, but will it continue to work in aot project without a dynamic classloader

14:50 llasram: Bronsa: Er. Doesn't it actually make it not work, because then all the in-Java types implement one interface while the in-Clojure types implement another, where the interfaces just happen to have the same name?

14:50 Bronsa: http://sprunge.us/UAjJ

14:50 llasram: no that's the point

14:50 hiredman: will you end up with two IReduce.classes emitted, one from the java compiler with IFn and one from gen-interface with Object

14:50 Bronsa: the protocol actually uses the already existing interface rather than the one it just created

14:50 llasram: Oh!

14:50 whaaaa

14:50 How?

14:51 hiredman: :(

14:51 Bronsa: I have a vague understanding on why this happens

14:51 hiredman: and the behaviour will be different when compiling

14:51 Bronsa: yeah

14:51 llasram: `emit-protocol` has the most insane option-parsing code evar

14:52 Bronsa: I've seen some crazy stuff w/ clojure's classloader handling

14:52 llasram: OOOOOOH

14:52 I see now. The code unconditionally will define an interface for the name of the protocol, but will actually use a provided :on-interface instead

14:53 That's something special

14:53 TimMc: llasram: http://i.imgur.com/3OtgEyU.gif

14:53 llasram: TimMc: Yeah, that was pretty much me

14:54 hiredman: hilarious

14:54 so :on-interface then

14:54 llasram: Yep. Someone totes should tell Rich

14:55 hiredman: of course rich will never go for changing CollReduce to :on-interface IReduce

14:55 Bronsa: hiredman: uhm AOT compiling (defprotocol CollReduce :on-interface clojure.lang.IReduce (..)) might break things actually

14:55 hiredman: changing is verboten, only accrete

14:55 Bronsa: it's going to overwrite the clojure.lang.IReduce class file

14:55 hiredman: :(

14:56 llasram: Bronsa: Are you sure?

14:56 Bronsa: llasram: almost

14:56 llasram: Because I think the gen-interface'd interface is still named for the protocol

14:57 Bronsa: ah?

14:57 llasram: And even if it isn't, can always wrap the `defprotocol` in `(binding [*compile-files* false] ...)` :-D

14:58 Bronsa: nope that won't work

14:59 llasram: ah you're right about the interface name

15:01 llasram: Finally. I knew it had to happen at least once this week.

15:04 ghadishayban: i fail to see what the big deal is between CollReduce IReduce

15:05 justin_smith: mbriggs: one option (#(clojure.java.shell/sh "sh" "-c" (str "echo -n " %)) "~") - sadly that redundant sh invocation is truly needed

15:06 mbriggs: justin_smith yeah...

15:06 justin_smith: (#(:out (clojure.java.shell/sh "sh" "-c" (str "echo -n " %))) "~") actually

15:07 mbriggs: justin_smith i ended up just treating this as a special case, and made a wrapper fn around System/getProperty "user.home" to avoid java sillyness

15:07 justin_smith: that's fair

15:07 mbriggs: https://gist.github.com/4af1e2eb71927111842e

15:09 dbasch: mbriggs: you may want to make sure there’s a slash in between

15:10 (more properly a path separator)

15:10 justin_smith: bonus - "//" becomes "/" anyway, so there is little reason not to insert one

15:10 (slurp "/home/justin/////////////////////////////.bashrc") totally works

15:12 verma: what do you use to keep your processes up and running? like a process manager sorts, not really geared towards web/db servers, something more like a program I could give a process to and it keeps it up

15:12 llasram: verma: It my company we use runit

15:12 noonian: verma: something like runit or upstart maybe

15:12 verma: llasram, noonian hmm, k taking a look

15:14 llasram, noonian failed to mention that I should be able to kill processes as well, also runit is an init system?

15:15 noonian: yeah, so you could do something like sudo service my-app stop and sudo service my-app start and if it dies it will get automatically restarted

15:16 TimMc: justin_smith: cd //

15:16 verma: noonian, hmm interesting

15:16 noonian, so I am basically using the OS to manage processes :)

15:16 llasram: verma: Yeah -- unless I've misunderstood your reqs, what you want *is* an init system. We're on Debian squeeze&wheezy, so using runit > sysvinit for our services. Would probably just use upstart on Ubuntu, and will move to systemd along with rest of world

15:16 TimMc: and check your prompt

15:16 justin_smith: TimMc: cd ////// etc. all work on my box

15:17 but // is funny in my prompt, yeah

15:17 noonian: verma: yes, processes are really an os level concept

15:18 verma: noonian, yeah :)

15:19 TimMc: justin_smith: It's some weird special case, I think just in the shell itself.

15:19 Maybe not.

15:19 justin_smith: interesting

15:20 dbasch: “Multiple successive slashes are considered to be the same as one slash.” http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_266

15:20 justin_smith: yup

15:21 which is handy to know when constructing paths from freeform inputs

15:21 TimMc: dbasch: Except leading slashes. http://tiswww.case.edu/php/chet/bash/FAQ E10

15:21 "POSIX.2, in its description of `cd', says that *three* or more leading slashes may be replaced with a single slash when canonicalizing the current working directory."

15:22 justin_smith: TimMc: lesson: insert three slashes, not just one

15:22 TimMc: haha

15:23 DomKM: What is the largest open-source Clojure app with Compojure routing?

15:24 smizell: This might be a strange/crazy question, but is there any library that converts Clojure code to JSON? Like (def x 1) to ["def", "x", 1]?

15:25 tbaldrid_: smizell: "convert to JSON" for what use-case?

15:25 smizell: transit does this sort of thing...but it just uses JSON as a transport.

15:25 smizell: I'm basically curious if you could represent code with JSON

15:26 Interesting

15:26 justin_smith: smizell: this plus cheshire? https://github.com/technomancy/serializable-fn

15:27 smizell: tbaldrid: I've spent a lot of time developing JSON hypermedia formats. They are usually always considered data with code provided to parse them.

15:27 justin_smith: I guess the problem is that js has no [] / () distinction

15:28 llasram: smizell: All Clojure code may be represented as Clojure/EDN data, but the translation from Clojure/EDN data to JSON is lossy unless using a layered transport scheme like Transit

15:28 turbofail: hm. weird. i had a very clear case of reflection going on that *warn-on-reflection* didn't say anything about

15:28 at least when i loaded the namespace

15:28 justin_smith: turbofail: was it on a number?

15:28 turbofail: no

15:29 justin_smith: was it aot-compiled?

15:29 turbofail: well so it was an AOT-compiled namespace so that probably explains it

15:29 yeah

15:29 smizell: Yeah, you'd have to have some way to make some distinctions. You'd also have to limit what it can do.

15:29 Some experimenting: https://github.com/smizell/janeml

15:29 turbofail: that's the goto explanation for anything weird - AOT?

15:29 justin_smith: turbofail: yeah, the warnings happen at compile time, and its already compiled, so... there you go

15:30 in this case it's a simple deduction :)

15:30 turbofail: yeah i had forgotten that it was AOT compiled

15:31 justin_smith: not to say that I wouldn't check AOT for any weird ass behavior, after I eliminate the obvious

15:32 tbaldridge: smizell: LISP is basically an easy to read AST. ASTs can be represented as data, JSON is data...at least that's the way I think of it all

15:33 smizell: tbaldridge: Exactly.

15:34 TimMc: turbofail: This gets posted at work not too infrequently: http://i.qkme.me/3vb225.jpg

15:34 turbofail: heh

15:35 justin_smith: haha

15:38 smizell: tbadridge: I am just curious as to how much I could express in JSON. Since JSON is everywhere, there is some cool potential to process things all over the place in different languages.

15:39 tbaldridge: smizell: well sure, but it'd look like crap ( ;-) ) and writing a scheme parser isn't hard

15:39 smizell: tbaldridge: It would look horrible!

15:40 tbaldridge: smizell: but a scheme in any language is what...1-2 KLOC?

15:41 turbofail: depends on if you need to write your own GC or not

15:41 also depends on what you mean by "scheme"

15:42 smizell: tbaldridge: Surely something can be better than JSON Schema, though http://json-schema.org/

15:43 hiredman: turbofail: a mark and sweep gc could be as few as 20 lines

15:47 miber: I'm building a library to communicate with a certain HTTP API - it's basically just a wrapper around clj-http

15:47 right now it's only a bunch of functions, but now I'm facing two problems:

15:48 1) I don't know what's a good approach to have the URL of the server configurable (currently it's a global var, which doesn't feel right)

15:48 2) depending on how the server is configured, I might need to pass a {:basic-auth ["user" "pass"]} or even {:insecure? true} to the clj-http.client/post method

15:48 I'm quite new to Clojure and I'm looking for a idiomatic way to do this, any pointers?

15:48 justin_smith: miber: both can be handled by a config file you look for on the class path

15:49 unless you need to change those things in a single production run of the app

15:49 hiredman: best is to take them as arguments

15:49 miber: is there a standard way how to do it via the config file then?

15:50 hiredman: yeah, I was thinking to do it like so

15:50 owengalenjones: miber: I would look for io/resource examples

15:51 miber: would it be good if every function would then take a mandatory first argument which would be a map with the url and possibly other arguments to the post function?

15:52 hiredman: loading from a config file is not all that more flexiable than defing it in the code

15:52 miber: yeah, pass args

15:53 miber: ok, thanks

16:05 J_Arcane: OK, on second thought, maybe installing CIDER from ports (0.7.0) is a safer method than MELPA (0.8.0 and broken, apparently)

16:07 xemdetia: J_Arcane, I'm only seeing CIDER as being released at 0.7.0

16:08 J_Arcane: xemdetia: the MELPA release I just installed complains of a version mismatch between cider itself and cider-nrepl. One is 0.7, the other is 0.8.

16:08 xemdetia: https://github.com/clojure-emacs/cider/releases

16:08 I'm just going off this

16:09 llasram: J_Arcane: If you must MELPA, MELPA Stable

16:10 xemdetia: being bleeding edge can often be bloody

16:12 J_Arcane: Seems that way. Will probably just roll back the package and install from ports instead, usually stabler option.

16:14 Or just try nightcode or lighttable ...

16:15 justin_smith: or cursive

16:19 llasram: J_Arcane: The MELPA stable repository does all the magic of MELPA, but only for actual tags vs arbitrary commits

16:19 dgaffney: Hey - any reason why my jetty setup would return 404 when I clearly have a handler for the endpoint?

16:19 Rhainur: so I have a map of where the keys are all different but all the values = true, and I'd like to iterate over it, and change some of the values to false depending on the key

16:19 llasram: J_Arcane: That's probably what you *actually* want

16:19 Rhainur: how can I iterate over it and get a key/value pair

16:20 seq seems to break the map into 2 item vectors

16:20 justin_smith: Rhainur: (into {} (map (fn [[k v]] [(f k) (g v)]) {my data...}))

16:20 that is the most generic version

16:20 really you want the k part unmodified

16:21 amalloy: Rhainur: what do you imagine is the difference between a key/value pair and a two-item vector?

16:21 Rhainur: amalloy: if I change the value I want it to affect the original map

16:21 well

16:21 what I mean is

16:21 amalloy: well, like most things in clojure, maps are immutable

16:21 Rhainur: I want to create a new map

16:22 with (some) different values

16:22 amalloy: i mean, really you just do what justin_smith said

16:22 Rhainur: so I knew there'd be an (into) at some point

16:22 justin_smith: ,(into {} (map (fn [[k v]] [k (if (even? v) (inc v) v)]) {:a 0 :b 1 :c 2 :d 3}))

16:22 clojurebot: {:c 3, :b 1, :d 3, :a 1}

16:22 Rhainur: I just wasn't sure whether a seq was necessary

16:23 llasram: Rhainur: You could also use `reduce-kv` for MOAR SPEED, but the `map` via seq idiom is more flexible

16:24 justin_smith: ,(reduce-kv (fn [m k v] (assoc m k (if (even? v) (inc v) v))) {} {:a 0 :b 1 :c 2 :d 3})

16:24 clojurebot: {:a 1, :d 3, :b 1, :c 3}

16:27 justin_smith: ,(let [input {:a 0 :b 1 :c 2 :d 3}] (reduce-kv (fn [m k v] (if (even? v) (assoc m k (inc v)) m)) input input)) ; since you are only changing some keys

16:27 clojurebot: {:c 3, :b 1, :d 3, :a 1}

16:27 justin_smith: avoids needless assoc calls

16:32 ired_44: I'm learning Clojure and am writing my first macro, to print the docstrings of functions as they are run (eventually w/ interpolation of the arguments the function was called with, into the docstring). if anyone has a few minutes I'd appreciate comments/review of the code: https://gist.github.com/mhuebert/c03c131ca0f43f034f0c

16:36 SagiCZ1: is java.lang autoamtically imported to REPL?

16:36 J_Arcane: yeah, to hell with this I'm gonna reboot and try light table.

16:36 justin_smith: SagiCZ1: java.lang is always imported, period

16:36 SagiCZ1: ,(Math/signum 5)

16:36 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: signum>

16:36 SagiCZ1: where is the mistake?

16:36 justin_smith: ,(Math/signum 5.0)

16:36 clojurebot: 1.0

16:37 SagiCZ1: justin_smith: float.. ok

16:37 ty

16:37 turbofail: i hate that

16:37 justin_smith: 5.0 in clojure is a double literal

16:37 but float would work too yeah

16:37 ,(class 5.0)

16:37 clojurebot: java.lang.Double

16:37 turbofail: most of the java math functions are only defined for doubles or floats or whatever, which seems silly to me

16:38 SagiCZ1: turbofail: seems normal to me

16:38 turbofail: i don't think it's too outlandish to want an integer answer for doing (Math/pow 2 12)

16:38 technomancy: it's only normal if you have a simplistic type system

16:40 turbofail: signum and abs are probably the most annoying offenders

16:41 SagiCZ1: turbofail: well no one really forces you to use the lang.Math

16:41 turbofail: well i think abs does work for integer-ish things

16:41 dgaffney_: Hey guys - any reason I would suddenly be seeing 404's from a jetty server? It's totally weird. I moved from my desktop to my laptop and pulled the repo down, and only *some* of the endpoints are 404'ing, and I've cut it every way I can think, and I'm not seeing it...

16:41 justin_smith: ,(Math/abs -8)

16:41 clojurebot: 8

16:43 dgaffney_: They are using 7.6.1 for jetty, I just checked both boxes.... this is mindblowingly annoying.

16:43 amalloy: ired_44: what on earth are you using clojure.test/function? for? do you mean clojure.core/fn?

16:44 oh my gosh, c.t/function? resolves the var. that doesn't seem like a good thing to use in general

16:54 zanes: What’s the right way to reset! an atom, and only perform a side effect if the value changed?

16:55 tbaldridge: zanes: I wouldn't, I'd build it via compare-and-set!

16:55 zanes: That’s the answer I was looking for. Thanks!

16:55 tbaldridge: zanes: http://grimoire.arrdem.com/1.6.0/clojure.core/compare-and-set!/

16:55 dorkmafia: how do you make the up arrow run your previous command on the lein shell interface?

16:56 zanes: tbaldridge: In that case I need to first deref the old value, right?

16:57 tbaldridge: zanes: right, you deref, run code, and then run compare-and-set! if it returns true, you run your side-effects

16:57 zanes: tbaldridge: 👍

16:58 TEttinger: (inc tbaldridge)

16:58 lazybot: ⇒ 10

16:59 jtackett: I have a long running process that i need for the next web page view

16:59 how can I return the page and display the process output when it is finished?

17:00 justin_smith: jtackett: you could use a future, and block on the return value of the future

17:01 scratch that

17:01 you'd need a web socket (misread your question at first)

17:01 jtackett: a web socket?

17:01 how does that work?

17:02 justin_smith: it lets you send data to the browser after the request is complete - it leave a data socket open

17:02 jtackett: do you put that in the view?

17:02 justin_smith: so they get the page immediately, and the rest of the data as soon as it is ready

17:03 jtackett: can i use hiccup for that?

17:03 J_Arcane: Instarepl is cool.

17:03 justin_smith: jtackett: hiccup is orthogonal to this

17:03 jtackett: the issue here is that you need to return a page right now, and later you need to send more data

17:03 jtackett: so what code do I put where? haha

17:04 in a view / handler set up

17:04 justin_smith: jtackett: http://http-kit.org/server.html#websocket this is an example, not all ring backends support websockets

17:04 ired_44: amalloy: i think it's specifically to resolve the var

17:05 jtackett: perfect thank you

17:05 danielcompton: Server sent events might also be an option here

17:05 justin_smith: danielcompton: true

17:05 ired_44: amalloy: I tried using fn?, but it always evaluates to false

17:05 danielcompton: jtackett: you get a callback in the browser when new data comes from the server

17:05 justin_smith: danielcompton: if you look at that http-kit example, that is what you are actually doing

17:05 zanes: tbaldridge: I always want to do the set!, though. So I’d have to build retry logic manually?

17:06 I feel like I’m missing something still.

17:06 danielcompton: You wouldn't be doing a whole page reload but could get the same effect

17:06 justin_smith: danielcompton: on a semantics level, if not on the impl level

17:07 danielcompton: justin_smith: right. I think i'd prefer SSE for that scenario because it stays in HTTP land

17:09 justin_smith: unified async/websockets looks cool http://http-kit.org/server.html#channel

17:11 ired_44: amalloy: do you know if there's a better way to determine whether something is a function, within the body of a macro?

17:12 SagiCZ1: .

17:12 ,"."

17:12 clojurebot: "."

17:12 J_Arcane: #clojurescript

17:14 zanes: i.e. Is there a more succinct or idiomatic way to do this? https://gist.github.com/zane/d28a4b49935dd23d7612

17:15 hiredman: well, a. don't mix atoms and the stm

17:15 atoms are non-transactional, that dosync does nothing

17:16 zanes: Hmm. I should probably read up before asking this question.

17:16 hiredman: yep

17:19 amalloy: ired_44: well, what you're doing is just fundamentally both weird and difficult. there are a lot of edge cases you're going to miss with your current approach

17:21 like, consider (docprint (let [map {1 2, 3 4}] (count map)))

17:23 dorkmafia: is there a lein rc or anything?

17:24 technomancy: dorkmafia: no, but current master will probably become 2.4.4 as soon as we are confident in its stability

17:25 ired_44: amalloy: good point. hmm, do you think some kind of decorator macro would be a good idea? e.g.. choose the functions that I want to docprint and redefine them to a wrapped version... something like: (decorate! docprint-fn [fns...])

17:25 zanes: hiredman: https://gist.github.com/zane/d28a4b49935dd23d7612

17:25 amalloy: ired_44: that would be a much more viable approach. but you could probably just find some pre-built solution, like tools.trace or something, for that

17:26 technomancy: dorkmafia: would be great to get some folks using it and giving it a sanity check

17:26 amalloy: ired_44: the reason, by the way, that your macroexpand doesn't work is that macroexpand runs at runtime rather than compile time, and in the clojure.core namespace instead of in the namespace you compiled it from

17:27 although actually when i run all this in my repl it *does* work as you intend

17:28 ired_44: amalloy: yeah I was confused by that. also, I was able to define other functions that it would expand, but not elect-n, and it seemed arbitrary

17:33 dorkmafia: technomancy: ah i meant .leinrc like a bashrc lol not release canidate sorry about that :) I am trying to make the up arrow show my previous command and <c-r> be the reverse search

17:33 ired_44: amalloy: I was looking at this decorate code: https://github.com/weavejester/decorate/blob/master/src/decorate.clj

17:34 technomancy: dorkmafia: haha, oh. ok. yes, leiningen has several configuration files, but none of them should be needed to get the behaviour you're describing.

17:35 amalloy: ired_44: solution: stop looking at it. something weavejester hasn't touched in five years is not a great thing to model future programs on

17:36 danielcompton: technomancy: why is the Gilardi Scenario called that?

17:36 amalloy: danielcompton: gilardi thought of it first, or popularized it, i always imagined

17:37 technomancy: danielcompton: because we were debugging this problem for like two days, and then we hired Steve Gilardi, and basically the first thing he did after starting was explain exactly what was going on and how to fix it.

17:37 noonian: lol

17:42 xeqi: .. that was named after a person that is still alive?

17:43 I thought it was some historic / sci-fi reference I didn't get

17:43 technomancy: it's named after the guy who wrote clojure.core/require

17:43 hyPiRion: xeqi: hahah

17:44 * hyPiRion imagines xeqi meeting Gilardi at some conference in the future.

17:45 xeqi: I might already have, but didn't put it together

17:45 TEttinger: Gilardi Scenario?

17:45 amalloy: xeqi: it certainly sounds like sci-fi, but we have a real live gilardi

17:46 i avoid mentioning his first name because i forget if he likes steve, steven, or stephen

17:46 hyPiRion: I would probably guess the same thing if I didn't see commits by gilardi within lein

17:46 amalloy: scgilardi: you're a legend!

17:47 ~gilardi scenario

17:47 clojurebot: I don't understand.

17:47 xeqi: hyPiRion: whats really bad is I recognize scgilardi from emails on the clojure list, but never put the two together

17:47 amalloy: $google gilardi scenario

17:47 lazybot: [in which the perils of the gilardi scenario are overcome - Technomancy] http://technomancy.us/143

17:48 amalloy: clojurebot: gilardi scenario |is| http://technomancy.us/143

17:48 clojurebot: You don't have to tell me twice.

17:50 hoangelos: anyone have any experience using amazonica. Especially that are already using a truststore.

17:50 hyPiRion: It's sort of like my surprise when I read http://www.tutok.sk/fastgl/callback.html without actually looking at the author's name.

17:50 hoangelos: I'm getting an error whenever I set javax.net.ssl.trustStore with my trustStore for my SSL enabled app.

17:51 TEttinger: ~gilardi scenario

17:51 clojurebot: gilardi scenario is http://technomancy.us/143

17:51 TEttinger: yay

17:51 dorkmafia: technomancy: then how do i make the up arrow take me to the previous command and <c-r> preform reverse search? right now up arrow is preforming rev search

17:51 as well as <c-r>

17:52 scgilardi: I happened across the gilardi scenario again myself recently, working on "declare+" which allows declaring in other namespaces (to be used sparingly to work around otherwise circular deps). I kept wondering why code inside '(do' would work, and inside '(try' would fail. And then it dawned on me. https://gist.github.com/scgilardi/e040cd35c85cc96b9739

17:52 hyPiRion: There has to be some trust store policy change for java, because I've seen people complaining about trust store issues every day the last 3 days

17:53 dorkmafia: maybe it's due to inconsistencies between my inputrc and bashrc O.o

17:53 what's the default behavior for lein gen?

17:54 technomancy: dorkmafia: try moving .inputrc out of the way. the default behaviour is C-r to do a reverse search and C-p to step through history one by one

17:54 it looks like the arrows are unbound out of the box

17:54 hyPiRion: hoangelos: I have no idea how amazonica works, but if it's ubuntu/debian-based and you can install stuff, then `sudo apt-get install --reinstall ca-certificates-java` might help

17:55 apologies if it's entirely wrong, I have my suspicion that it may not help you

17:55 technomancy: how is it even possible to install a jdk without installing the jdk's certifdicates

17:56 dorkmafia: yup that was the issue sorry guys

17:56 =P

17:56 mearnsh: technomancy: idk but that happened to me as well.

17:57 hyPiRion: technomancy: I have no clue, but apparently reinstalling the java certificates solved the issue

17:57 hoangelos: hyPiRion: no not really

17:57 hyPiRion: but thanks anyway for saying something.

17:59 technomancy: mearnsh: what distribution/version?

18:00 hyPiRion: hoangelos: if it's any help, then the same issue would exist for Java and Scala as well. Perhaps googling with any of those would help

18:00 mearnsh: technomancy: i believe it was with openjdk 7

18:00 TEttinger: hoangelos, are you starting with the recommendations that datomic makes for their usage of truststore? -Djavax.net.ssl.trustStore=path-to-truststore -Djavax.net.ssl.trustStorePassword=**T***** -Djavax.net.ssl.keyStore=path-to-keystore -Djavax.net.ssl.keyStorePassword=**K***** my-transactor.properties

18:00 jtackett_: what would be the easiest way

18:01 mearnsh: mearnsh: might be a quirk of my system or package manager. but reinstall fixed it.

18:01 hyPiRion: technomancy: I recall someone using fedora

18:01 technomancy: hyPiRion: ah, gotcha

18:03 hoangelos: TEttinger: not sure what you mean by the datomic recommendations as it pertains to amazonica. HOwever, our app, which uses truststore and keystores for it's own server<->client HTTP already successfully used. But the trustStore one specifically makes amazonica fail.

18:04 TEttinger: I had never heard of amazonica before today, so I am not the one to ask. it does look like this is a challenge to search for

18:05 hoangelos: yeah. it's just a clojure library for amazon. one of the most complete.

18:05 just a wrapper for the amazon java library

18:07 jtackett_: just trying to figure out the websocket

18:13 dorkmafia: ater you do lein repl do you need to kill it and re run after you make changes?

18:15 TEttinger: dorkmafia: (require '[your.ns :reload])

18:16 I think I recall the syntax right :|

18:16 mearnsh: dorkmafia: which editor

18:16 dorkmafia: lein repl

18:16 TEttinger: what if i set the main to be my namespace

18:16 mearnsh: sorry, which text editor do you use

18:16 technomancy: dorkmafia: you can reload from lein repl, but it's a lot more convenient to do it from your editor.

18:16 dorkmafia: mearnsh: vim

18:16 mearnsh: dorkmafia: https://github.com/tpope/vim-fireplace

18:17 dorkmafia: ah yes all praise the pope

18:17 TEttinger: I wonder how I would do that in nightcode

18:17 mearnsh: indeed

18:17 should auto connect to your repl if you start it in your project dir

18:17 technomancy: protip: tpope is short for "The Pope"

18:18 mearnsh: otherwise just :Connect and then you can use the likes of "cpr" to reload your buffer in the repl

18:21 hyPiRion: ,(sequential? "foo")

18:21 clojurebot: false

18:24 dorkmafia: (:require [clojure.string :as string]) is this correct?

18:24 technomancy: dorkmafia: it's fine for putting in the ns macro

18:24 clojurebot: the ns macro?

18:24 clojurebot: the ns macro is more complicated than it needs to be, but this might help http://blog.8thlight.com/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html

18:24 technomancy: dorkmafia: ^ kind of required reading

18:25 the difference between require in the repl and in the ns macro confuses a lot of people

18:32 mdrogalis: Does anybody else break out the popcorn when aphyr is about to Jepsen something?

18:33 dorkmafia: (ns mybot.core (:require [xmpp-clj :as xmpp] [clojure.string :as string]))

18:33 technomancy: yah i had glanced over that I just wanted to make sure =B

18:33 jtackett_: hey looking for some more help with a long running process getting return to a web page

18:34 how do you return the web page and then update it with the result of the process when it’s finished

18:34 dorkmafia: cause the single quote is required on the shell

18:34 jtackett_: ?

18:35 tuft: jtackett_: you need some kind of asynchronous execution it sounds like

18:35 jtackett_: .. and a mechanism like polling or websockets on the client

18:36 lots of ways to do this

18:36 jtackett_: could i use something like sente?

18:36 what’s the easiest way to implement?

18:36 I have a project built with compojure and hiccup

18:36 in a view and handler set up

18:37 tuft: jtackett_: sente looks promising

18:37 nick___: What is the recomend way of reading in a clojure file (and get clojure data structures)?

18:37 jtackett_: (slurp “filepath”)

18:38 nick: (slurp “filepath”)

18:38 hiredman: no

18:38 slurp is the worst

18:38 L8D: (slurp "uri")

18:38 hiredman: slurp returns a string

18:38 L8D: (slurp "file://./foo.txt")

18:38 hiredman: so you have the entire string in memory, and the next thing people does is call read-string on it

18:38 terrible

18:38 L8D: (slurp "ftp://ftp.myserver.org")

18:38 hiredman: ,(doc read)

18:38 clojurebot: "([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?]); Reads the next object from stream, which must be an instance of java.io.PushbackReader or some derivee. stream defaults to the current value of *in*. Note that read can execute code (controlled by *read-eval*), and as such should be used only with trusted sources. For data structure interop use clojure.edn/read"

18:38 L8D: (slurp "http://www.google.com")

18:39 ,(+ 1 2)

18:39 clojurebot: 3

18:39 L8D: ,(slurp "http://jsonip.com")

18:39 clojurebot: #<SecurityException java.lang.SecurityException: denied>

18:39 jtackett_: slurp it and call it a day

18:40 L8D: Or just create a stream and call it a day

18:40 jtackett_: tuft: how would you go about setting up the websocket?

18:40 do you have a good example?

18:41 tuft: jtackett_: seems like sente has some good ones. i've not used it

18:41 L8D: So, as JavaScript developer with mild experience in ruby/python web servers and little-to-no experience in developing with Java and Emacs, where should I start?

18:41 jtackett_: what have you used?

18:41 this is my first time doing web sockets

18:42 tuft: jtackett_: never used them actually, only polling =)

18:42 jtackett_: L8D: start with java or clojure?

18:42 could I use polling instead?

18:42 L8D: To learn Clojure and how to setup a dev workflow with Clojure and ClojureScript

18:42 jtackett_: L8D: download light table and get on youtube

18:43 L8D: I mean...I know the semantics of LISP and all, I've just never worked with Java or Java-based languages/systems

18:44 jtackett_: tuft: looks like websockets are better, but I just want the easy solution for now

18:44 tuft: L8D: coming from ruby/python you might enjoy just using the lein repl and whatever text editor you're used to

18:44 jtackett_: "easy" will probably be whatever provides the best abstraction

18:44 whatever library that is

18:44 L8D: tuft: I've mostly worked with JavaScript/Node.js, and I have more experience with haskell than ruby.python

18:45 and I'm a hard-set Vim user

18:47 tuft: i think there's something called "campfire" for vim

18:47 aperiodic: L8D: fireplace.vim

18:47 benmoss: fireplace

18:47 L8D: tuft: There's a colorscheme called campfire

18:47 benmoss: haha

18:47 tuft: er, hah, fireplace

18:47 i'm using cursive with vi emulation

18:51 mearnsh: fireplace is pretty nifty

18:51 danielcompton: jtackett_: I woudl look at Server Sent Events

18:52 jtackett_: is there a good example project I could look at?

18:53 danielcompton: jtackett_: you could look at https://github.com/ninjudd/eventual

18:55 jtackett_: also https://github.com/ck/samples/tree/master/server-sent-events but it's using the Pedestal framework which you likely aren't

18:55 https://github.com/pedestal/samples

18:56 jtackett_: I’m using compojure and hiccup

18:56 noonian: jtackett_: if you want a nice simple abstraction on websockets you should checkout chord, it models websockets as a core async channel. If you want something more robust with fallback like socket.io i would recommend sente, but that might be overkill for just getting started

18:57 https://github.com/james-henderson/chord

18:57 jtackett_: there has to be an easier way to do this haha

18:57 this client server stuff sucks

18:59 tuft: doesn't get much easier than core async channels

18:59 once you get chord working, i guess =)

19:00 jtackett_: hahaha ya once I get chord working

19:01 I’m just confused how to set it up

19:01 handler or view?

19:02 tuft: looks like a handler from the docs

19:02 noonian: jtackett_: are you using clojurescript on the client? or vanilla js? on the server you will need to setup a handler, and make sure you are using a server that supports websockets like http-kit

19:03 jtackett_: I am using compojure

19:03 and I’m using hiccup on the client side

19:04 so just compojure and ring to do the routes, and then basically html to serve up the views/pages

19:04 Jaood: hiccup runs on cljs?

19:04 noonian: jtackett_: you should be able to use the handler example from the chord readme (under the 'Clojure' heading) and then hook it into your server using a compojure route

19:05 jtackett_: Jaood: yep

19:05 and noonian: just put that into the handler file?

19:05 noonian: to use websockets from your client code you will need to use javascript, either normal js using websockets or if you are using clojurescript you can use chord and treat it like an async channel from the client as well

19:06 jtackett_: ah shit so i need js or cljs on the client side

19:06 would love to avoid learning that for now

19:06 noonian: you'll need to put the requires into your namespace form, and define the handler in your handlers file, then hook up the handler to your routes; something like (defroutes ... (GET "/my-ws" req (your-chord-handler req) ...)

19:07 i think you could use chord on the server side and just use vanilla js websockets if you are using a browser that supports websockets

19:07 jtackett_: then what would call that get request in the client end?

19:07 noonian: you might want to read about JavaScript websockets

19:07 jtackett_: i def will

19:07 dbasch: jtackett_: or cljs, for example https://github.com/ptaoussanis/sente

19:08 noonian: var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");

19:08 however, the beauty of cljs is that if you already know core async then you don't have to know a thing about websockets heh

19:08 jtackett_: dbasch: that’s what my co-worker told me to use

19:09 ya i will probably go with sente

19:09 just need to figure it out

19:09 is there no other way to just fill in the text when the process finishes?

19:10 noonian: roughly: sente is to chord as socket.io was to websockets

19:14 amalloy: jtackett_: if you want to send an un-finished page to the client and then fill it in when the server's done with some other work, you have to have the client talk to the server somehow

19:14 noonian: jtackett_: you could poll the server until its finished using normal ajax requests

19:14 amalloy: if you're content to wait until the server-side process is done before sending anything, then of course it's easy

19:15 jtackett_: haha I’ll just make the jump and figure out sente

19:39 dbasch: jtackett: if you want to hack it as a proof-of-concept, you could have a frame that refreshes itself every X seconds

19:53 danneu: ,(str #inst "2014-09-08T23:00:27.485207000-00:00")

19:53 clojurebot: #<SecurityException java.lang.SecurityException: denied>

19:53 danneu: i like how str/.toString truncates data from the string that's in the literal

20:12 qq: can I use clojure "get" on "java.util.Map"

20:13 technomancy: if only there were a way to attempt to perform this action and record its results, which could confirm or deny a constructed hypothesis

20:15 err--I mean...

20:15 try it and see?

20:20 danneu: if i have a java.sql.Timestamp represented with the literal `#inst "2014-09-08T23:10:58.915549000-00:00"`, is there a trivial way to get the string that's in the literal?

20:25 dbasch: danneu: pr-str

20:26 amalloy: danneu: (subs (pr-str sql-nonsense) 5) or something

20:28 danneu: rofl

20:28 thanks

20:48 joobus: are there more clojure practice problems similar to clojure koans? I finished the koans.

20:52 amalloy: joobus: 4clojure.com is one

20:52 or you can do project euler in clojure (euler is back online again, right?)

20:56 llasram: ,(binding [*data-readers* {'inst identity}] (read-string "#inst \"2014-09-08T23:10:58.915549000-00:00\""))

20:56 clojurebot: "2014-09-08T23:10:58.915549000-00:00"

20:59 joobus: was just looking at 4clojure. it would be nice if the problems were doable offline, in a text editor and the repl. The web interface isn't ideal. thanks for the tip :)

21:00 bbloom: joobus: just do the problems locally and then copy paste to do final verification

21:13 amalloy: joobus: there are numerous tools people have devised to automate the process bbloom recommends, as well

21:13 a few lein plugins, an emacs mode or something...

21:43 joobus: i went with solving project euler problems, thanks amalloy :)

21:47 clj-newb: I see examples of private functions as (defn- and (defn ^:private defn- seems deprecated, but I can find no documentation to confirm this

22:08 technomancy: nah, it's not

22:30 ncthom91: hi all. I'm brand new to clojure, and actually mostly interested in clojurescript, but I can't figure out how to find all matches in a string with a given regex

22:31 bbloom: (doc re-seq)

22:31 clojurebot: "([re s]); Returns a lazy sequence of successive matches of pattern in string, using java.util.regex.Matcher.find(), each such match processed with re-groups."

22:32 ncthom91: bbloom perfect, thank you :)

Logging service provided by n01se.net