#clojure log - Jan 09 2016

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

0:26 BRODUS: i'll try my question again since its quieted down, can derefing an atom ever throw an error? in the source the print method for atoms is same for other types that implement IDeref and they wrap the deref operation in a try/catch. I think this is only pertinent for Futures whose value isn't known yet, but I wondered if anyone else could confirm

0:26 heres the method: https://github.com/clojure/clojure/blob/bc186508ab98514780efbbddb002bf6fd2938aee/src/clj/clojure/core_print.clj#L387-L408

0:28 amalloy: deref on an atom can't throw an exception. it could theoretically throw an error like StackOverflowError if you happened to be at the end of your allocated stack already, but that's really just a problem in the calling code

0:29 *printing* an atom could throw a StackOverflowError, if the data in the atom is circular, or if the atom points to itself

0:29 ,(let [a (atom nil)] (reset! a a) (deref a) nil) ;; no error from dereffing

0:29 clojurebot: nil

0:30 amalloy: ,(let [a (atom nil)] (reset! a a) (deref a)) ;; but if you try to print that...

0:30 clojurebot: #object[clojure.lang.Atom 0x65e6d2ae {:status :ready, :val #object[clojure.lang.Atom 0x65e6d2ae {:status :ready, :val #object[clojure.lang.Atom 0x65e6d2ae {:status :ready, :val #object[clojure.lang.Atom 0x65e6d2ae {:status :ready, :val #object[clojure.lang.Atom 0x65e6d2ae {:status :ready, :val #object[clojure.lang.Atom 0x65e6d2ae {:status :ready, :val #object[clojure.lang.Atom 0x65e6d2ae {:status ...

0:30 BRODUS: ,(println (atom "1234"))

0:30 clojurebot: #object[clojure.lang.Atom 0x5478a746 {:status :ready, :val 1234}]\n

0:30 amalloy: well, okay, clojurebot is configured so that that doesn't error, but most programs aren't

0:30 BRODUS: its weird they include the status field for atoms

0:31 its not useful

0:31 it looks like it will always be 'ready'

0:32 justin_smith: BRODUS: I think it's for all things that can be dereffed (many of which have a non-ready state)

0:32 ,(promise)

0:32 clojurebot: #object[clojure.core$promise$reify__6999 0x38c25d61 {:status :pending, :val nil}]

0:32 BRODUS: right, but its still not unnecessary

0:33 i mean, its unnecessary

0:34 justin_smith: ,(Object.)

0:34 clojurebot: #object[java.lang.Object 0x53202231 "java.lang.Object@53202231"]

0:34 justin_smith: that hex number is not neccessary either

0:34 it's just part of the printed representation

0:36 BRODUS: hmm, the hex code coudl be necessary if you were trying to see if objects were the same instance

0:36 justin_smith: BRODUS: identical? will tell you that

0:36 just like realized? tells you if a derefable is ready

0:36 but it's in the printed form too

0:37 in both cases

0:38 BRODUS: yeah but if you were just looking at logs the hex code is needed for that differentiation

0:38 justin_smith: the info is useful, it's concise, it's cheap to provide it, so why not print it when printing the object?

0:38 BRODUS: sure, and when I print a dereffable, it's nice to know if it's realized

0:38 BRODUS: what makes you think knowing if a dereffable is realized is not useful?

0:39 BRODUS: i never said that, i just think its confusing for atoms

1:16 TristeFigure: Hi. I'm having a little problem. I'm reading a .clj file path using the *file* dyn var, but what I get is a string representing the path of the file relative to its "source-path". For instance *file*'s value is myproject/core.clj and what I want to is an absolute path or at least a relative path that encompasses the src folder, e.g. src/myproject/core.clj. So basically I need to get the current "source-path" value (i

1:16 not necessarily in src, it can be in /test or in any other custom-set directory). I'm not sure how I could achieve something like this. There is a *source-path* var in the standard library but it seems it only contains the current file name+extension. Any idea ?

1:34 neoncontrails: TristeFigure: sounds like what you want is a file server. Clojure doesn't make this particularly easy, but have a look at Compojure: https://github.com/weavejester/compojure

1:40 The idea is actually pretty simple though. You're basically just defining those strings that are the local path as the key, and returning the file as a value for those keys

1:40 elvis4526: Hello. I'm experiencing a OutOfMemoryError inside a relatively big clojure web app. Any tips on how to diagnose this ?

1:41 I know for the leak to happen, the app need to run for an extended period of time. Usually 2-3 weeks non-stop and more

1:43 neoncontrails: elvis4526: heh I'm working on a similar problem. Haven't solved it yet, but maybe we could help each other out

1:44 It's running server-side?

1:44 justin_smith: elvis4526: you can profile clojure apps with visualvm or yourkit

1:46 neoncontrails: I always forget Clojure has back-end capabilities. That might be a better solution than client-side cljs for my problem, hmm...

1:49 elvis4526: neoncontrails: Yep it is.

1:50 justin_smith: I tried the memory sampler in justin_smith, however i'm not quite sure what the results are supposed to mean

2:10 Storing Ring requests inside an Atom isn't really a good idea right ?

6:38 lokien: can someone explain a fn pattern to me? I'm staring at it for half an hour now and I still don't know how it works

6:39 BRODUS: lokien: what do you mean?

6:40 lokien: BRODUS: I'll lpaste it

6:43 http://lpaste.net/2716934979316613120

6:44 BRODUS: I mean that function it's used with reductions

6:44 BRODUS: you're confused about how 'move' works ?

6:45 lokien: yeah

6:46 particularly that anon function

6:50 m1dnight_: I keep getting this "when-let decleration should be a vector" error but it doesnt specify a proper file where it occurs

6:50 ive grepped all my when-let lines in my entire project and they all seem fine..

6:50 any tips on how to debug?

6:50 BRODUS: ,({go-right left go-left up go-up down go-down} \<)

6:50 clojurebot: #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>

6:51 BRODUS: ,(clojure.string/split "<<>>" #"")

6:51 clojurebot: ["" "<" "<" ">" ">"]

6:51 BRODUS: ,({right go-right left go-left up go-up down go-down} "<")

6:51 clojurebot: #error {\n :cause "Unable to resolve symbol: right in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: right in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: right in this...

6:52 lokien: BRODUS: I can clarify what it does

6:52 I just don't know how it does it

6:52 BRODUS: i'm just trying to work from the sexp with the hash map outwards

6:52 lokien: kay

6:53 BRODUS: oh ok

6:53 i didn't realize the keys would be evaluated in the hash map

6:54 after evaluation the hash map looks like {"<" go-left ">" go-right ...} and so on

6:54 each motion points to a function

6:55 lokien: uhm, ya

6:55 TMA: ({...} word) returns a function. that function is passed position which is a two-element vector

6:55 lokien: so.. we extract a function from a map and use it on position?

6:55 I think I understand now

6:55 BRODUS: yeah

6:56 lokien: welp, thanks

9:43 ely-se: Is there a function like load-file that takes a URL instead of a String?

9:45 domgetter: ely-se: (eval (slurp url)) ? (this may be a very bad thing to do)

9:46 BRODUS: ooh, i didn't know slurp took a url

9:47 ely-se: domgetter: it was an XY question, actually. I want to execute clj files that are resources. It seems load does that

9:52 thanks :)

10:44 justin_smith: you would need a read-string between slurp and eval

10:55 domgetter: Anyone know a good resource to learn what the term "middleware" means?

10:57 AimHere: Wouldn't wikipedia give you a rough overview?

10:59 domgetter: The description on wikipedia applies to any library I use. Are all libraries middleware?

11:05 Here is my question in context: https://github.com/dakrone/clj-http/blob/master/src/clj_http/client.clj

11:05 There are "middleware" functions in that file, but the wikipedia page talks about gluing programs together

11:05 so why is the word being used two completely different ways?

11:06 That's a bad rhetorical question. I guess what I should ask is, can the wikipedia page help me come to an understanding of the use of the term "middleware" in that client.clj file?

11:07 justin_smith: domgetter: a middleware is a function that takes a function as an argument and returns a new augmented function

11:08 domgetter: in a ring app, you have your handler which serves a request, and pass that to various middleware, like the one that takes a request, and returns a request which tracks a user session, for example

11:08 or one that takes a request, and returns a request where the request parameters are not mapped to keywords in a hash-map instead of being a raw string

11:08 etc.

11:08 s/not/now

11:08 domgetter: justin_smith: if I did that with channels, would the things which take stuff of off channels and process them be considered middleware?

11:09 justin_smith: no - but if you had a function that took a channel, and returned a new channel that did some special new thing for every event on the channel, that would be a middleware

11:09 domgetter: like a channel with a transducer on it?

11:10 justin_smith: exactly, the transducer there acts as a middleware

11:10 it wraps x, returns a new thing you can use as if it was x, but has a new feature

11:10 or a modified behavior

11:11 domgetter: in functional programming we often use composition of middleware in cases where OO programs would use inheritence

11:12 domgetter: and by composition here you mean functional composition?

11:12 or possibly a more general notion of combining?

11:13 justin_smith: functional composition (though here it is technically function application, middleware application acts like a composition of functions)

11:14 domgetter: the general shape is (fn middleware-f [f] (fn [x] (post-process (f (pre-process x)))) - you can optionally pre-process x before f sees it, then you optionally post-process the result before it is returned

11:14 and you take f and return a new function with that pre/post processing

11:14 domgetter: okay. That all makes sense. I'll ruminate on that for a while, thank you

11:31 favetelinguis: not sure how to ask since i have limited understanding but im reading about piplines in core async and would like to do somethings like this "ch-in -> stateful-pipeline -> out, that is having the pipline remember what has been processed before, now my questions is if this is possible using only channels and transducers or if i have to put a stateful go-loop into the pipleine dealing with the state?

11:33 then it would be like "ch-in -> ch-with-transducer1 -> go-loop with state -> some-more-transducer -> out-ch"

11:34 my thinking is that if i need state i might just as well use a transducer in the go-loop instead of putting then on pipeline channels...

11:35 BRODUS: well transducers can be stateful

11:36 domgetter: (take 4) returns a stateful transducer: https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L2738

11:37 Do you have to use volatile! to do stateful transducing?

11:48 favetelinguis: found some slide about using volatile! to store state in transducers, should fit my needs, thanks

14:03 lokien: How to get every second element of a vector?

14:05 Bronsa: lokien: take-nth

14:05 lokien: Bronsa: thanks

14:56 lvh: domgetter: no, but it makes a lot of sense because it's more performant than many of the alternatives

14:57 lokien: How to take n first letters from a string? Is there a prettier way than (str (take n string))?

14:57 lvh: domgetter: a stateful transducer can do whatever it wants, including store some state in java/JS

14:57 lokien: you could try some string methods

14:57 there's also subs

14:57 lokien: (subs s start end)

14:58 lokien: lvh: clojure.string? nothing useful (or I can't search properly)

14:58 lvh: lokien: subs is in core

14:58 lokien: lvh: subs is a thing I was looking for, thank you

15:02 tuddman: I have http://clojure.org/cheatsheet bookmarked. has str functions. plus, well, everything else.

15:03 MJB47: there also this version: http://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-no-cdocs-summary.html

15:03 which has better search imo

15:03 though ctrl-f is a thing

15:04 tdammers: ctrl-f is my bread and butter

15:04 or rather, /

15:04 unless a website chooses to break it

15:05 lokien: um, thanks

15:05 I'll bookmark it too

16:31 What can we do for large number readability? Something like 2_000_000

16:34 MJB47: if its only 0's

16:34 then 2e6 is an option

16:36 lokien: what if it's not only 0's?

16:49 gfredericks: 2e6 is bad since it gives you a float

16:50 I don't think there's anything basic for this

16:50 ,(type 2e6)

16:50 clojurebot: java.lang.Double

16:55 ridcully: make it a const and never look at it again?

17:15 lokien: How to check if an item appears twice in a row in a string (or a seq)?

17:15 "somestring" -> false ; "someestring" -> true

17:18 justin_smith: ,(some (partial apply =) ((comp (partial apply map list) (juxt identity rest)) "somestring"))

17:18 clojurebot: nil

17:18 justin_smith: ,(some (partial apply =) ((comp (partial apply map list) (juxt identity rest)) "someestring"))

17:18 clojurebot: true

17:18 justin_smith: that probably isn't the best way to do it, but it was fun

17:19 MJB47: i was gonna use loop/recur

17:19 idk whats simpler

17:19 lokien: uh, now I'll spend another 3 days trying to figure out how your function works, justin_smith

17:20 but thanks

17:20 gfredericks: ,(defn repchar? [s] (->> s (partition 2 1) (some #(apply = %))))

17:20 clojurebot: #'sandbox/repchar?

17:20 gfredericks: ,(repchar? "somestring")

17:20 clojurebot: nil

17:20 gfredericks: ,(repchar? "someestring")

17:20 clojurebot: true

17:20 lokien: :o

17:20 justin_smith depositioned

17:21 justin_smith: gfredericks: wrote the same function, he just gave you the readable version

17:21 gfredericks: ~justin_smith is the unreadable version of gfredericks

17:21 clojurebot: Ik begrijp

17:22 TMA: justin_smith: that's not certain. while yours is transparent, gfredericks' is somewhat opaque [at least or me]

17:22 MJB47: i find gfredericks much easier to read and understand

17:23 lokien: I find both of them confusing :^(

17:23 gfredericks: I find things in my pockets sometimes

17:23 lokien: lucky you

17:24 if they aren't snakes, of course

17:25 gfredericks: ugh pocket snakes are the worst

17:25 lokien: still better than NPEs, duh

17:26 gfredericks: NullPocketException

17:26 justin_smith: (try (frob x) (catch PocketSnake S ...))

17:29 lokien: I'm curious.. justin_smith, why do you only use one liners here? no defns, always anonymous functions

17:30 justin_smith: lokien: that is much simpler in irc

17:30 also, it's easier to put a one liner in a function, than it is to take one out of one

17:30 lokien: and also "one liner" - clojurebot only accepts a line at a time

17:30 lokien: justin_smith: much harder to put it into code

17:31 justin_smith: but you still could write them with defn

17:31 MJB47: i feel like that just adds uneeded bloat

17:31 justin_smith: exactly

17:31 MJB47: they are implicit when needed

17:32 justin_smith: why send two things to clojurebot when you can show what's needed with one

17:32 MJB47: everyone knows how defn works

17:32 so why not

17:32 lokien: maybe it's easier to fit if one has more complex functions, my are like 10 lines or less

17:32 MJB47: I think you're right

17:45 justin_smith: also, clojurebot erases all def and defns once every 15 minutes or so, so using def / defn isn't reliable

17:49 TEttinger: down to under 256 characters, btw, if you just use this to generate a single name of some elder god or great old one or whatever

17:50 ,(let[a #(apply str(flatten %))p partition R rand-nth n #(a(R(mapcat p[1 2 3]%&)))v #(n"aioeu""iaaiaa")](a[(n"STKNYPKLGVZ""GlThShNyFtCh""ZvrCthShrMycTch")(for[_" "][(v)(n"lpstnkgxzv"(concat[(R["h""gl""gr""nd"])(v)]"rnthggghtsltrkkhshng")"ghnlok")])]))

17:50 clojurebot: "Zerkiarn"

17:50 TEttinger: you were discussing illegibility?

17:52 ah, lokien left, but for strings I'd use (partial re-find #"(.)\1")

17:52 justin_smith: oh, good point

17:53 TEttinger: ,((partial re-find #"(.)\1") "somestring")

17:53 clojurebot: nil

17:53 TEttinger: ,((partial re-find #"(.)\1") "someestring")

17:53 clojurebot: ["ee" "e"]

17:53 MJB47: if its only a string then yer thats the best way

17:53 but he asked for seq as well iirc

17:53 TEttinger: surprised gfredericks, lord of the regex, didn't point that one out though

17:53 MJB47: oh i didnt read up

17:53 my bad

17:57 TEttinger: ,((partial reduce #(if (= %1 %2) (reduced true) %2)) "someestring")

17:57 clojurebot: true

17:57 TEttinger: ,((partial reduce #(if (= %1 %2) (reduced true) %2)) "somestring")

17:57 clojurebot: \g

17:58 TEttinger: hm, should be nil then

17:58 justin_smith: ,((comp true? (partial reduce #(if (= %1 %2) (reduced true) %2))) "somestring")

17:58 clojurebot: false

17:59 justin_smith: ,((comp true? (partial reduce #(if (= %1 %2) (reduced true) %2))) "someestring")

17:59 clojurebot: true

17:59 TEttinger: ,((comp not (partial reduce #(if (= %1 %2) (reduced nil) %2))) "someestring")

17:59 clojurebot: true

17:59 TEttinger: ,((comp not (partial reduce #(if (= %1 %2) (reduced nil) %2))) "somestring")

17:59 clojurebot: false

18:00 TEttinger: the only case this fails is with justin_smith

18:00 the only case this fails is with justin_smith's and a collection that contains true, or mine and a collection that contains nil

18:01 mine also fails if the collection contains false

18:01 justin_smith: ,((comp boolean #{::doubled} (partial reduce #(if (= %1 %2) (reduced ::doubled) %2))) "someestring")

18:01 clojurebot: true

18:02 justin_smith: instead of ::doubled you could use a gensym

18:06 ToBeReplaced: just a FYI to community; i haven't written clojure in about a year, i tried to add cider-nrepl 0.9.1 to my lein plugins, and there seems to be no way to start a REPL once i do that if i have :pedantic? :abort set

18:06 this gives me a sour taste and makes me less likely to want to pick it up again commercially

18:07 0.10.1 sorry

18:08 TEttinger: I don't use cider, lots of people in here do

18:09 justin_smith: there's a neat property here too. the collection can't contain itself as an element can it?

18:09 ,(map (fn [coll] (= coll (reduce #(if (= %1 %2) (reduced coll) %2) coll))) ["someestring" "somestring"])

18:09 clojurebot: (true false)

18:09 ToBeReplaced: yeah, maybe the tech has moved and i should be looking at different tooling; the issue is they ask for different versions of org.clojure/tools.nrepl (and no way to exclude what lein asks for)

18:10 TEttinger: they?

18:10 cider?

18:10 clojurebot: cider is Cider is unstable and broken right now, most things don't work. Use the last stable version of nrepl.el for now.

18:10 TEttinger: haha

18:10 thanks clojurebot

18:10 not sure if that's still true

18:10 ToBeReplaced: haha, "they" referred to lein vs. cider-nrepl

18:11 justin_smith: ,(def a (promise))

18:11 clojurebot: #'sandbox/a

18:11 justin_smith: ,(deliver a (delay [@a]))

18:11 clojurebot: #error {\n :cause "Unable to resolve symbol: a in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: a in this context"\n ...

18:12 justin_smith: ,(def a (promise))

18:12 clojurebot: #'sandbox/a

18:12 justin_smith: ,(deliver a (delay [@a]))

18:12 clojurebot: #object[clojure.core$promise$reify__6999 0x307cdb5b {:status :ready, :val #object[clojure.lang.Delay 0x6ae97dd4 {:status :pending, :val nil}]}]

18:12 TEttinger: what's this?

18:12 justin_smith: (= @a @(first @a))

18:12 ,(= @a @(first @a))

18:12 clojurebot: #error {\n :cause "Don't know how to create ISeq from: clojure.lang.Delay"\n :via\n [{:type java.lang.IllegalArgumentException\n :message "Don't know how to create ISeq from: clojure.lang.Delay"\n :at [clojure.lang.RT seqFrom "RT.java" 542]}]\n :trace\n [[clojure.lang.RT seqFrom "RT.java" 542]\n [clojure.lang.RT seq "RT.java" 523]\n [clojure.lang.RT first "RT.java" 668]\n [clojure.core$firs...

18:12 justin_smith: :P

18:12 ,(= @@a @@(first @@a))

18:12 clojurebot: #error {\n :cause "clojure.lang.PersistentVector cannot be cast to java.util.concurrent.Future"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentVector cannot be cast to java.util.concurrent.Future"\n :at [clojure.core$deref_future invokeStatic "core.clj" 2205]}]\n :trace\n [[clojure.core$deref_future invokeStatic "core.clj" 2205]\n [clojure.core$deref invokeSt...

18:12 justin_smith: ergh

18:13 there must be a way!@

18:13 TEttinger: @

19:11 tolstoy: ToBeReplaced: Did you resolve your issue? All I do is add tools.nrepl to the :dev profile and It Works.

19:51 ToBeReplaced: tolstoy: i did not resolve; is that true with :pedantic? :abort

19:52 tolstoy: Hm. I've never head of :pedantic?; Is that a lein thing?

19:52 I do run "lein deps :tree" all the time.

19:52 slester: not exactly clojure related, but just curious how you all come up with side projects to work on

19:53 I've just been fiddling with 4clojure and advent of code and I can't really think up a good project to test my chops

19:53 ToBeReplaced: yes, it's a feature to puke when dependency ranges are detected

19:54 tolstoy: ToBeReplaced: I just added it to my project, and "lein deps :tree" still works. What does that key prevent?

19:54 ToBeReplaced: I actually never put stuff in ~/.lein/profiles.clj. I just keep it all in the project file. Maybe that's it?

19:54 ToBeReplaced: tolstoy: can confirm that adding tools.nrepl to :dev profile instead of :user profile makes a difference

19:55 tolstoy: Ah, good!

19:55 ToBeReplaced: if i add to :dev in the project.clj, it accepts; fails if i add to :user in a profiles.clj

19:55 magic ;)

19:55 tolstoy: Is it possible to add a :dev profile to profiles.clj?

19:56 ianhedoesit: slester: I think a reasonable approach to start with is to just make things that already exist. thinking of truly unique and novel ideas isn't something that's easy (or something that everyone can do)

19:56 tolstoy: slester: For a long time, my side projects were side projects for work. Not sanctioned, just stuff it would be cool to use. In other words, that's where I found problems to solve.

19:57 slester: ianhedoesit, tolstoy, good advice!

19:57 ToBeReplaced: tolstoy: you can, yes... you're not meant to due to collisions

19:57 tolstoy: slester: Wouldn't it be cool to have drag/drop configuration for security scans? ;; That would get me into OM, etc.

19:58 ToBeReplaced: Ah. The reason I abandoned profiles.clj is that I wanted things to be explicit and for old projects to be self-consistent.

19:58 ToBeReplaced: it's a little weird because it *should* be in :user not :dev since it's meant to be for any project i work on... really i should just issue a PR to leiningen to update it's version of tools.nrepl

19:58 yeah; i totally get that... better for repeatability of the dev environment if your whole team uses the same environment as well

19:58 tolstoy: ToBeReplaced: When working with others, no one cared because they didn't use Emacs, or didn't use the plugins (like lein ancient, etc). In other words, no impact on anyone else.

19:59 ToBeReplaced: makes sense

20:00 tolstoy: I figured that if anyone cared, I could just maintain a local project.clj and never commit it, or something.

20:00 ANYWAY, I think Cider is really good these days.

20:00 I really like the C-c C-p to pop-up an evaluation of an expression into a read-only buffer.

20:03 And I set the toggle so that buffer is pretty-printed.

20:04 Very light-tableish. ;)

Logging service provided by n01se.net