#clojure log - Mar 15 2015

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

0:31 jimrthy: I may be looking at things the wrong way...has anyone used fnhouse with websockets?

4:05 eli-se: hi

4:15 dysfun: is there a builtin that is equivalent to (constantly nil) ?

4:15 TEttinger: #({}:P)

4:16 ,(#({}:P))

4:16 clojurebot: nil

4:16 TEttinger: actually it can be shorter

4:16 dysfun: that's just golfing it :)

4:16 TEttinger: ,(#({}1))

4:16 clojurebot: nil

4:16 opqdonut: here's one that's almost

4:16 ,(#())

4:16 clojurebot: ()

4:17 dysfun: that won't take an argument

4:17 opqdonut: oh right and neither of these work with an argument

4:17 dysfun: yeah

4:17 just realised :)

4:17 TEttinger: ,(#({}%&))

4:17 clojurebot: nil

4:17 TEttinger: there you go

4:17 ,(#({}%&) 1 2 3)

4:17 clojurebot: nil

4:18 dysfun: how does that work?

4:18 TEttinger: plus, no alphanumerics!

4:18 dysfun: %& is & rest, right?

4:18 TEttinger: it takes an empty map {} and tries to get an element from it, where that element has the key equal to all arguments passed to the fn

4:18 dysfun: oh right, i see

4:18 TEttinger: if it doesn't get that key, nil!

4:18 dysfun: nice

4:19 TEttinger: %& is fun

4:19 dysfun: i think 'always' and 'never' would be useful

4:19 (constantly true) and (constantly nil)

4:20 TEttinger: ,(#(str %1 ": " (clojure.string/join ", " %&)) "Scruffy" "The Janitor" [:id 1])

4:20 clojurebot: "Scruffy: The Janitor, [:id 1]"

4:21 TEttinger: specifically, %& is all args that don't already bind to a %1 or %2 etc.

4:28 eli-se: I'd just go with (constantly nil).

4:29 TEttinger: heh, eli-se with the injection of sanity

4:29 (inc eli-se)

4:29 lazybot: ⇒ 1

4:29 * eli-se wonders why it's not called 'const'

4:38 dysfun: because that's already got a meaning in other languages. everything in clojure is a const (loosely, anyway...)

4:41 amalloy: dysfun: that's not much of an argument. in haskell, const means the same thing as constantly in clojure

4:44 dysfun: true i suppose

4:44 but then haskell isn't exactly above changing the meanings of words also used in other languages

4:46 i'm trying to think of an example where we do that in clojure

7:00 justin_smith: dysfun: for

7:03 dysfun: ah yes

7:04 then again there's prior art for that usage, from CL

7:05 ah, protocols. in the real world they're the format of data. in clojure they're the format of behaviour

7:05 justin_smith: also, agents

7:05 dysfun: lots of definitions of agent to pick from already :p

7:06 justin_smith: in the real world they are things that do things (usually on behalf of a user), in clojure they are mutable containers that serialize changes

7:06 (on behalf of a user, or as part of a simulation with an AI flavored actor model)

7:08 dysfun: i saw a really cool agent based simulation the other day simulating an evacuation of an office building. the 'humans' exhibited surprising behaviour

7:10 https://www.youtube.com/watch?v=kHfHewzp5ls

7:11 it can apparently do loads of humans in realtime on fairly mediocre hardware

7:13 * justin_smith holds back the mom joke.

7:20 eli-se: hi

7:20 justin_smith: hello

8:21 thiagofm: hi, what does the @ means in clojure/clojurescript?

8:22 justin_smith: ,'@foo

8:22 clojurebot: (clojure.core/deref foo)

8:22 justin_smith: it means deref

8:24 bcm: Is there a lein template with cider nrepl baked in?

8:24 justin_smith: bcm: typically you don't want to embed cider in your project, only use it at dev time

8:24 it's better to add the dep to ~/.lein/profiles.clj

8:25 bcm: okay, but don't you need to do something like:

8:25 (nrepl/start-server :port 10101 :handler cider-nrepl-handler)

8:25 justin_smith: no, why would you need to do that?

8:26 bcm: That's how I've been starting my repl, just before i start my server

8:26 justin_smith: if you have the cider plugin in your profile, you can just use "lein repl" to start up your repl

8:26 and then start your server from the repl

8:27 if you really want to, you can start nrepl from inside your app, but the cider-nrepl plugin should take care of making sure the middleware is there

8:27 bcm: so lein repl + cider plugin in ~/.lein/profiles.clj => cider-nrepl-handler ?

8:27 justin_smith: bcm: yes

8:27 that's what the plugin does

8:27 bcm: oh i hope so

8:28 thanks justin_smith

8:29 justin_smith: np

8:29 bcm: i have a second question: is enlive still the best way to do scraping?

8:29 justin_smith: it works pretty well for me

8:29 bcm: yeah I can use it too. just making sure noone made something amazing

10:28 dysfun: is there a channel for midje-related things?

11:40 daniel`: anyone using vim-eastwood?

11:40 i get an error saying eastwood/lint__init not on classpath

11:54 thiagofm: thanks justin_smith

12:07 paulswilliamsesq: dysfun haven't seen one. I use midje a little bit but I probably won't be able to help.

12:09 dysfun: essentially i'm having difficulty matching nested data structures that contain records

12:10 i've written a function that recursively turns records into maps and that's making my tests pass, but it's silly

12:10 and when it prints out the expected and got they're character for character identical

12:11 paulswilliamsesq: but it fails?

12:12 dysfun: well, it did before i wrapped it with my utility

12:12 handily, thanks to the power of open source, i can show you

12:13 paulswilliamsesq: dysfun yeah, sure. I've done similar things. not with records.

12:13 gist?

12:13 clojurebot: http://gist.github.com/

12:13 dysfun: https://github.com/jjl/qarma/blob/service-loader/t/qarma/system/loader_test.clj#L78 if you comment out the clal to derecordify, it fails with messages that identical things aren't identical

12:14 of course they're not actually identical, because they're records

12:22 paulswilliamsesq: em.

12:22 so midje is establishing object equality which fails. I agree that wrapping the function on the left side isn't pleasent.

12:23 dysfun: yeah. i understand why it's doing that, but i can't find a different workaround

12:24 do you think it warrants a bug report?

12:26 paulswilliamsesq: dysfun not sure about a bug report. Do you know marick? He's answered a few similar questions on twitter previously.

12:26 oh, I've just found https://groups.google.com/forum/#!forum/midje

12:26 dysfun seems pretty responsive

12:33 dysfun: hrm, i'll ask in a bit, thanks

12:40 paulswilliamsesq: dysfun the only thing I can think off without looking into the midje source code is to apply an inverse of your derecordify to the right hand side which would be slightly better.

13:03 grui: Hi! I've got a newbie question about Cider and Emacs and Clojure. I have this clojure file, and I do M-x cider-jack-in. After that I go to every line and hit C-x C-e to load every funciton into the repl. Is there some way to load a whole buffer, or a whole project (same thing?) into a Cider repl in Emacs? I tried selecting everything and then hitting C-x C-e, but it doesnt seem like it's working. Don't know for sure though, since as

13:03 stated above I'm still very green with Lisp & Emacs... Thankful for any help!

13:04 pdurbin: grui: I highly recommend http://www.braveclojure.com/basic-emacs/

13:08 grui: pdurbin: so if I understand it right, I can do M-< C-Space M-> C-x C-e to load a whole buffer into cider? I don't understand the message returned, so I'll just assume it works...

13:15 dysfun: paulswilliamsesq: aesthetically, perhaps. i'm not keen :/

13:17 paulswilliamsesq: dysfun I did say slightly ;-)

13:17 dysfun I'll look forward to responses on groups if you do post. I've just joined. I like the stubbing concept of Midje, I think it will be my goto test framework.

13:21 pdurbin: grui: I don't know. Hopefully someone here who knows emacs can help. I'm more of a vi guy.

13:24 dysfun: paulswilliamsesq: i find it to be awfully convenient

13:25 there are a few cases i've found it to be pathological, but mostly it's great

13:25 tomjack: grui: no, try e.g. C-c C-k

13:25 if it's a normal clojure file defining a namespace

13:26 also, I'd be surprised (but not too surprised) if C-x C-e cares about the region

13:26 I think it just always evaluates the 'last' expression

13:27 actually I guess cider C-c C-k also works for just loading arbitrary code in a buffer

13:29 paulswilliamsesq: dysfun do you use the stubs long term, or just until you have working implementations to the stubbed functions? If that makes sense? Do you just use it for outside in dev, or long term isolation?

13:30 dysfun: actually i don't use all of that at present

13:30 i meant midje was useful, not stubbing

13:31 there's a lot more i'm sure it can do for me, but i have to balance my time between so many things already

13:33 paulswilliamsesq: dysfun tell me about it. I'm sitting between the FP and good OO camps and have been strongly recommended to learn Smalltalk to help our Java developers and I'm still spending a lot of time learning Clojure.

13:38 dysfun: the good oo camp? that's the one where they treat it as a functional language, right? ;)

13:39 bbloom: it's where you use just enough oo to bootstrap a functional abstraction :-P

13:41 gfredericks: ~FP is more gooder than OOP

13:41 clojurebot: A nod, you know, is as good as a wink to a blind horse.

13:43 dysfun: gfredericks: i know one thing: refs are better than locks

13:44 gfredericks: ~refs are more gooder than locks

13:44 clojurebot: No entiendo

13:44 gfredericks: ~refs |are| more gooder than locks

13:44 clojurebot: c'est bon!

13:46 gfredericks: (if you state a claim using improper english you get to disparage that claim without having to have any reasons/arguments)

13:47 (free internet points!)

13:48 tomjack: golf: (mapcat (fn [[k vs]] (for [v vs] [k v])))

13:48 (that is a golf request, not a golf attempt)

13:49 gfredericks: wrong number of args (1) passed to mapcat?

13:49 (mapcat 1) also accomplishes that

13:49 tomjack: uh, isn't mapcat a transducer thingy now?

13:49 where now = whenever 1.7 is released :)

13:49 gfredericks: probably I forgot about transducers

13:49 and just eval'd it in my head

13:50 yep looks like it'd work

13:50 tomjack: I'm on 1.6 at the moment so I did the same thing :)

13:51 I guess maybe that's the optimal number of points

13:54 or one more: (for [[k vs] m v vs] [k v])

14:17 I never noticed that :tag for a constant String def and :tag for a defn or a def fn which returns a String are the same

14:19 Bronsa: tomjack: yeah.. :tag for fns refers to the return type of the fn rather than to the fn value itself

14:19 tomjack: good thing you don't have to typehint fns

14:20 Bronsa: well.. this actually can be a problem sometimes, when your fns are more than just clojure.lang.AFns

14:21 e.g. if your function is actually an IPersistentCollection or something like that

14:21 $source char-name-string

14:21 lazybot: char-name-string is http://is.gd/JpGSXz

14:21 tomjack: haha

14:21 Bronsa: here for example you have a hashmap tagged as String

14:22 tomjack: static types were just poisoning my brain

14:23 Bronsa: I've never seen anybody actually complain about this issue though so I guess it doesn't really cause any problem in real code

14:23 (but it still bothers me)

14:24 bbloom: Bronsa: hm, that is pretty interesting

14:25 tomjack: I'd guess the intersection of where it matters (usually non-Clojure Java APIs?) and where it happens is small

14:25 and you can always use a local hint :)

14:25 bbloom: seems like objects that are both collections and functions are a theoretical problem more generally

14:26 like in scala, the fact that sets are invariant b/c they are both functions and collections

14:27 Bronsa: bbloom: I saw a note by Rich about this issue in some confluence page written years ago. I guess there's no interest/it's too late to change how type hints works now

14:27 bbloom: i wonder if you could side step the problem by interpreting callable objects in terms of an implicit conversion to a function object

14:27 tomjack: I was going to suggest that

14:28 bbloom: surely ambrosebs has some insight in to this whole situation :-P

14:28 tomjack: implicitly transport along an equivalence to a container, then take the second projection which is a function

14:49 paulswilliamsesq: dysfun ;-)

14:58 ambrosebs: sure it makes sense, I modeled type hint propagation as part of my latest paper

14:58 in the appendix though, will dig it out

15:01 bbloom: my opinion is that type hints are just hints and shouldn't be taken seriously. I'm perfectly fine with the current behaviour.

15:01 bbloom: heh. "shouldn't be taken seriously" is an interesting way to put it

15:02 ambrosebs: it's in the name

15:02 :)

15:10 here's my model of type hints

15:10 figure 6 http://frenchy64.github.io/doc/hint.pdf

15:10 TA-Local is the normal behaviour you'd expect

15:10 TA-AppLocal is the funky one

15:13 the question I'm interested in is "what do type hints tell you", which is why I concluded they shouldn't be taken seriously

15:13 and I specifically mean in terms of verification

15:13 they are seriously cool in their own right

15:14 people seem to think they make good documentation or tell you something about your program.

15:25 justin_smith: ambrosebs: removing runtime reflection is kind of nice though?

15:26 ambrosebs: justin_smith: of course!

15:26 that's why they're cool

15:26 not because they give you insight about what a particular function takes, for example

15:29 justin_smith: yeah, they do only one very small part of what people think of as "typing" in code

15:30 Bronsa: ambrosebs: they kind of enforce input types in some cases though

15:30 ambrosebs: Bronsa: exactly :)

15:30 justin_smith: Bronsa: with primitives?

15:31 ambrosebs: Bronsa: assume nothing :P

15:31 Bronsa: justin_smith: yeah

15:49 gfredericks: ambrosebs: does core.typed have anything for specifying the type of metadata?

15:50 ambrosebs: gfredericks: no

15:50 gfredericks: something I intentionally overlooked, could be added

15:50 gfredericks: if it did you could use that to get good old-fashioned nominal typing, right?

15:50 with :type metadata or something

15:50 ambrosebs: well it would be the same as a :type entry in a HMap

15:51 gfredericks: right

15:51 ambrosebs: which you can do lots of things with

15:51 gfredericks: kind of a dumb question I guess

15:52 ambrosebs: not sure what you mean by nominal typing since metadata is a structural type

15:52 gfredericks: meant the same thing as what you'd get with a normal :type key

15:52 ambrosebs: yes ok

15:52 correct

15:52 would be cool to have

16:16 paulswilliamsesq: Hi, is there a concise way of extracting a seq of titles from [{:title "the shining" :age "18} {:age "pg" :title "Jaws"}] - i.e. I want ("the shining" "Jaws") ?

16:17 voytech: Hi did You heard about postwalk ?

16:17 ambrosebs: paulswilliamsesq: (map :title yourseq)

16:18 mpenet: anyone knows how to run the cljs test in core.async ?

16:18 paulswilliamsesq: ambrosebs thank you - I was using map but writing my own anon function to extract the title within it!

16:18 ambrosebs: paulswilliamsesq: also valid

16:18 paulswilliamsesq: ambrosebs yeah, it works but was verbose

16:22 voytech: I had some problems with with-redefs . What I'm trying to achieve is to redefine some var from other namespace temporary, then call code which uses this var somewhere internally in multiple places, But my function is not being called in place of original one ? Is with-redef ony for binding in lexical scope ?

16:22 ambrosebs: ,(doc with-redefs)

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

16:23 ambrosebs: ,(source with-redefs)

16:23 clojurebot: Source not found\n

16:23 ambrosebs: voytech: looks like it's a big hammer and globally redefines vars.

16:23 voytech: is the code your calling returning a lazy sequence?

16:24 perhaps you need to realise it while the redefs are in effect

16:25 voytech: nope not lazy-seq

16:25 ambrosebs: code?

16:27 voytech: ambrosebs: https://gist.github.com/voytech/3bf374bcf81a023184b1

16:29 ambrosebs: what does deftask do?

16:29 looks like you're just returning a function

16:30 voytech: yes

16:30 ambrosebs: maybe you need an extra (fn [& body] (with-redefs [...] (apply (comp ...) body)

16:31 voytech: Ahh so when I'm returning function

16:31 when it will be called

16:31 it will be out of the scope of redef

16:31 ambrosebs: yes

16:31 voytech: ahhhh!

16:32 thank You for your quick eye then :)

16:33 ambrosebs: np

17:07 daniel`: anyone using vim-eastwood? i get an error could not locate eastwood/lint__init.class

17:07 have the dependency in my lein profile

17:11 nevermind, got it working

17:11 problem with my lein profiles data

17:12 night folks

17:23 Misatana: For those who've submitted Clojure issues to JIRA before, do the {code:none} … {code} blocks denoted at https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=advanced work for denoting code blocks in issues' descriptions?

17:28 bbloom: Misatana: you can edit descriptions after you submit tickets, so just give it a try

17:39 Misatana: bbloom: I actually haven't been able to edit any of my issues from the past so far, so I'm a little leery of trying formatting before making sure. https://confluence.atlassian.com/display/JIRA/Editing+an+Issue suggests that I should be seeing an Edit button, but it's not showing up for me; pressing the E key doesn't work either.

17:40 bbloom: Misatana: worst case scenario: you put an updated description in to a comment & ask somebody to fix the ticket for you

17:46 Misatana: bbloom: All right; thanks.

17:47 Bronsa: Misatana: {code} .. {code} blocks work fine, also you can preview the description before submitting a ticket

17:48 Misatana: Bronsa: Aha, I see. I hadn't realized that that little icon below was a preview button. Thanks a lot!

17:51 Guest70851: Hey there. I am looking to start learning Clojure and have been looking at some books. Judging by Amazon ratings, it seems that O'Reilly's "Clojure Programming" by Emerick, Carper and Grand is held in the highest regard. The book is two years old though, so my question is: is "Clojure Programming" still relevant in 2015? Or is it recommended in general? (I have been programming for a year, mostly in imperative languages but a lit

17:53 justin_smith: Guest70851: yeah, there are new features since then, but nothing it describes has changed iirc

17:53 ~books

17:53 clojurebot: books is http://clojurebook.com/ http://joyofclojure.com/

17:54 scottj: Guest70851: fyi irc has a message length limit

18:00 raspasov: Guest70851: I would say yes, without having read it all; I have the book though, and any time I've gone to consult it the information has been top notch

18:03 Guest70851: Thank's justin_smith and raspasov for your answers

18:04 justin_smith: Guest70851: that book, JoC, and this IRC channel are where I learned most of what I know about clojure

18:05 Guest70851: Sweet. I read that JoC is a bit harder to read for a Clojure beginner, so I guess I'll wait with that one.

19:22 wei_: is there a way to do a “for” form with an index?

19:24 havenwood: wei_: I don't know what you mean, but it makes me think of #each_with_index.

19:24 gfredericks: (for [[x i] (map vector coll (range))] ...)

19:24 havenwood: oh, sorry, wrong channel :(

19:24 gfredericks: (for [[i x] (map-indexed vector coll)] ...)

19:25 havenwood: hah!

19:25 that's the first time I've seen "wrong channel" when actually answering a question

19:26 wei_: thanks gfredericks. I guess map_indexed by itself would work, but it just has different semantics

19:26 havenwood: i thought i had posted in the wrong channel for a sec :)

19:26 havenwood: wei_: gfredericks: #crystal-lang is just too close to #clojure alphabetically.

19:27 gfredericks: wei_: different semantics or different syntax?

19:27 wei_: ah, just syntax. at first I thought “for” was eager

19:35 skeuomorf: justin_smith: Hmm, JoC website doesn't work without the www prefix, I tweeted Michael Fogus but I think it should be changed here meanwhile?

19:35 !ops

19:55 rs0: datomic uses Fressian internally, right?

19:56 in the storage layer?

20:00 gfredericks: I believe so

20:02 rs0: ok. i've been looking at Fressian a lot lately and it seems like there's been no work on it at all after its initial release

20:02 bbloom: rs0: i think that might be b/c it's *done*

20:03 rs0: bbloom: it's... not

20:03 bbloom: clojure collection types don't even round trip through data.fressian, with the exception of maps

20:03 bbloom: rs0: *done* ... for the purposes of datomic

20:03 although they surely have an internal fork

20:03 rs0: bbloom: that's what i'm thinking

20:04 bbloom: rs0: do you need binary storage? or are you looking for a transport data format better than json?

20:04 rs0: bbloom: https://github.com/rschmitt/dynamic-object

20:04 bbloom: b/c transit fits the latter role

20:05 rs0: bbloom: i'm aware of transit, but i want to add binary serialization to dynamic-object

20:05 bbloom: rs0: use transit w/ messagepack

20:06 (assuming they actually implemetned that, they said they were going to)

20:06 rs0: bbloom: i thought that Transit wasn't even stable yet

20:06 bbloom: they specifically said not to persist anything durably in Transit, in case it changes later

20:07 bbloom: rs0: ah,yes, i remember that. & see it in the readme at https://github.com/cognitect/transit-format#implementations

20:07 rs0: that's one reason i didn't look extremely closely at Transit; Fressian appears more mature

20:07 another reason is that Fressian actually has a really clean Java implementation. the Transit library looks really GoF to me

20:08 bbloom: you're more likely to get details about stability, compat promises, etc from the mailing lists

20:09 rs0: which ones should i look at?

20:10 bbloom: the main clojure users list is probably the place to start

20:10 rs0: k

21:00 sg2002: Hey guys. Have a question about debugging. Is there a solution that allows you to store function args every time it's called? I've been using spyscope, but printing data is not as useful in my case. I'd rather store them in some var instead. Seems kind of an obvious idea and an easy thing to implement myself, so there has to be a working implementation already.

22:05 gfredericks: sg2002: (defn store-args! [some-var] (alter-var-root some-var (fn [orig] (fn [& args] (alter-meta! some-var update-in [:calls] (fnil conj []) args) (apply orig args)))))

22:06 I'd probably pull in robert.hooke for a more slicker impl

22:20 this kind of makes me want to add to my repl utilities something that will instrument every function in a namespace with a hooke that stashes the args anytime an exception is thrown

22:21 which is a bit leaky now that I think about it

22:21 but probably worth it for just repl stuff

22:49 sg2002: gfredericks: Thanks. Using metadata for this is a great idea.

22:51 gfredericks: np

Logging service provided by n01se.net