Fork me on GitHub
#clojure
<
2016-02-26
>
dmitrig0100:02:38

Me too, I call the namespace schema 😛

josh.freckleton06:02:58

I've read in some places there's a negative sentiment toward macros, what's your experience with using them?

seancorfield06:02:47

Well, we have about 30k lines of Clojure... over 2k functions... about 350 Vars... and only 10 macros.

seancorfield06:02:05

That's our production code base.

seancorfield06:02:32

Macros are good for syntactic sugar when the underlying function call looks a little weird.

seancorfield06:02:36

For example, we have a with-retry macro that let's us retry code that might throw occasional exceptions (mostly around 3rd party services) and automatically performs exponential backoff.

seancorfield07:02:42

so (with-retry :ms 500 :limit 6 (some-func with args)) will run the body up to 6 times, with an initial 500ms delay and an exponential backoff... under the hood, it would be (retry* 0 (fn [] (some-func with args)) :ms 500 :limit 6)

seancorfield07:02:33

@josh.freckleton: I'd say to always try to solve something with functions, and only add macros when you need to clean up the syntax.

josh.freckleton07:02:15

@seancorfield: good to know, this weekend I'm committing myself to learning them more thoroughly, but if they're mostly good for syntactic clean up... maybe not so important?

seancorfield07:02:30

It's good to really know macros but they're much more rare in production Clojure code than you might think...

seancorfield07:02:58

One of the real problems is that macros don't compose like functions.

dm307:02:54

it's important to understand macros and be able to write them when needed. A good macro can make a huge difference, e.g. the fnk family: https://github.com/plumatic/plumbing/blob/master/src/plumbing/core.cljx#L384

jarodzz08:02:10

hi, guys. quick question. when i choose between assoc and assoc!

jarodzz08:02:19

should i always prefer non-bang function?

jarodzz08:02:29

due to it is more functional?

rauh09:02:11

@jarodzz: assoc! is only for transients, which are special and for optimization. Don't use them unless you identified your function to be too slow. Usually you should use assoc and "standard" data structures.

jarodzz09:02:46

@rauh: got it. i was reading group-by in core lib, saw this. wandering why he choose assoc!

rauh09:02:33

@jarodzz: Many clojure.core functions use it to optimize performance. Also some libraries use it but by default application code doesn't usually use transients unless identified a bottleneck.

jarodzz09:02:02

@rauh, that makes sense. thx

bbss09:02:06

How can I make this more idiomatic:

(map (fn [one two] [one two])
     (take-while (fn [] true) (repeat :id))
     '(:one :two))
tried lein kibit but to no avail 😄

dm310:02:17

(map vector (repeat :id) [:one :two])

bbss10:02:43

Thanks, I knew something beautiful had to be possible 😄

jimmy10:02:40

hi guys I just forgot that there is a function in clojure that helps with this operation. For example : I have this vector [{:type :a :another "a"} {:type :a :another "a1"} {:type b :another "b"}] then after running that function, it returns something like this {:a [{:type :a :another "a"} {:type :a :another "a1"}] :b [{:type b :another "b"}]}. Any hint would be appreciated simple_smile

mostr10:02:22

@nxqd: (map (fn [e] {(:type e) e}) v) or you mean some ready to use func?

bbss10:02:12

partition-by

mostr10:02:04

aaaand I’ve just learned something new 😉

jimmy10:02:06

@mostr: sorry, I have fixed the post. It does some kind of partition

jimmy10:02:21

it's group-by

jimmy10:02:28

yes I've found it xD

bbss10:02:29

oh right. simple_smile

jimmy10:02:45

@bbss: I have the same thought at first, try partition but it's not quite right

jimmy10:02:51

thanks clojuredocs' recommendation 😄

mostr10:02:20

heh, love this way of learning new things 😉

jimmy11:02:09

hi guys is there any clojure java bridge lib for google maps api ?

cpmcdaniel15:02:14

hello #C03S1KBA2!

cpmcdaniel15:02:38

question about transducers and core.async… If I have a comp of map, filter, etc, and I pass that to a channel (chan 1 xform), it it weird if one of the map fns syncs some data to a database?

cpmcdaniel15:02:16

or should I pipe some channels together and keep my “pure” channels and “dirty” channels separate?

hugesandwich15:02:14

I would avoid side effects like that in a transducer

hugesandwich15:02:48

For one, a database can do all kinds of strange stuff that is beyond your control

hugesandwich15:02:19

I would think it would be better to control the flow explicitly into your database anyway rather than letting the transducer do it even though the transducer is less code

hugesandwich15:02:18

if you do elect to keep it as a transducer, at least pass the exception handler so you can deal with anything that blows up. Not sure in your case if you can leak resources like connections given your code, but just be aware.

cpmcdaniel15:02:12

I’m going to take a look at putting my “pure” transducers on my source channel, then mult that channel for a) syncing db-state and b) any further “pure” transducers

voxdolo16:02:13

I'm trying to make a leiningen plugin that accesses resources in the project running it, but from within that plugin refers to the resources dir of the plugin's jar rather than the including project. Is there a way that I can access the running project's context from this plugin?

voxdolo16:02:49

I see that can take a classloader, but I'm unsure how to get the classloader of the host application from the plugin.

voxdolo16:02:18

Conversely: if I'm overcomplicating things, I'd love to know other ways of turning a resource-relative path to a file in the host application into a resource/file/uri that the plugin can manipulate.

nkraft17:02:11

Anyone else using Emacs Cider on OS X? It used to work great but today cider-jack-in gives: "cider-project-type: Symbol's function definition is void: closure-project-dir". Any ideas for fixes?

echristopherson17:02:42

nkraft: closure with an s?

nkraft17:02:08

That's weird. Sharp eyes. simple_smile

nkraft17:02:38

Must be something in the latest Cider. I did some package upgrades yesterday.

stuartsierra17:02:07

'closure' implies something to do with ClojureScript compilation (& the Google Closure Compiler)

echristopherson17:02:26

there's also #C0617A8PQ

nkraft17:02:45

Thanks. I've moved the question over there. simple_smile

rnandan27317:02:16

Which is a better approach to develop in clojure luminus or immutant?

tolitius17:02:40

@rnandan273: luminus has immutant as its default server

voxdolo17:02:56

As an update to my above question, eval-in-project didn't actually make aware of the host project's classloader. I was, however, able to pull the project's root path from the leiningen project's :root key and just construct paths using .

rnandan27317:02:50

@tolitus Thanks

tolitius17:02:48

@rnandan273: sure, good luck simple_smile

vptheron18:02:10

hi, has anyone read the book “Clojure Applied” published by pragprog?

vptheron18:02:30

wondering if it’s good material

shaun-mahood18:02:06

@vptheron: Yes, it's really good (but not a beginner book)

jonahbenton18:02:07

@vptheron: utility depends on what you're looking for, but it's an exceptionally well-done book

jonahbenton18:02:25

lots of sample material on the website to evaluate

vptheron18:02:02

@shaun-mahood: @jonahbenton my understanding is that it’s very hands-on, compared to other books that are really focusing on the language itself, while this one is really about how to get things done

vptheron18:02:26

that’s something I miss a lot from the books I already looked at (Clojure in Action, and Clojure for the Brave and True)

vptheron18:02:40

they are awesome to understand the syntax and the tools, but not how to apply them effectively

shaun-mahood18:02:57

@vptheron: Oh yeah, if you've gone through those books already then Clojure Applied should be great for you.

rnandan27318:02:37

@tolitius: When i do this using luminus lein new luminus test-proj +immutant Unrecognized options: +immutant Supported options are: +sqlite, +site, +h2, +jetty, +cljs, +sassc, +swagger, +auth, +war, +http-kit, +cucumber, +aleph, +mongodb, +postgres, +mysql, +kibit

tolitius18:02:20

@rnandan273: immutant is a default server, so you don't need to specify it

tolitius18:02:44

"lein new luminus test-proj" will bring it in by default

tolitius18:02:37

i.e. check your project.clj, you should see the immutant dependency after lein new luminus test-proj

rnandan27318:02:33

@tolitius: So you suggest adding immutant-messaging under dependencies and using it

tolitius18:02:54

@rnandan273: probably best to take it to the #C077KDE3A channel

chrisn19:02:04

Hey, I would like to add a pom file as a dependency but it is not on maven although the jars it points to are. Specifically I am going for this: https://github.com/MysterionRise/mavenized-jcuda/. I want to either use that pom file or duplicate it into leiningen so I can build a cross-platform project with native dependencies on the various cuda sub-libraries.

chrisn19:02:17

I am a bit baffled by how to do this so far. I guess I would like to put that pom in my resources and then use it in my dependencies but it isn't clear how this would work.

chrisn19:02:49

nm, it looks like that won't actually work because those cuda binaries aren't in maven...

jonahbenton19:02:18

@chrisn are you building an application, or a library?

chrisn19:02:25

I am trying to build the jcuda set of jars along with jcudnn.

chrisn19:02:01

I switched to actually building them with cmake and mvn. This path is probably more robust as we have mac devs and such and this way they can build what they need.

shaun-mahood21:02:30

Is there a list anywhere of good open source projects to use as references for high-quality in-the-wild code? I know of a bunch of individual projects but was wondering if anyone is maintaining a list of them.

reefersleep21:02:08

I once saw a library on github that someone had written for parsing Clojure-code written without the parens - based solely on the indentation.

reefersleep21:02:20

Does anyone know where to find this? simple_smile

echristopherson21:02:38

@reefersleep: I don't know of that per se, but someone on this Slack is working on an editor that does that sorta

echristopherson21:02:54

it's set up to convert the editor's parenless code to the user's choice of clojure or js

echristopherson21:02:42

oh, I was wrong -- it also includes standalone parsers, not just the editor

reefersleep21:02:20

cheers @echristopherson simple_smile

reefersleep21:02:14

Can't tell whether it's the same as what I found, but it's interesting none the less!

hugesandwich22:02:20

Anyone have a good strategy for going to/from other formats/languages, for example when calling a Scala or Java api? I have a protocol which dispatches on type, and while it works, I'm not so happy with the calling conventions all over the place. In some key places, I did stick in things like in the case of serializers/deserializers which handles all this transparently from a single call, but that doesn't work well sometimes when more custom behavior is needed. I'm trying to avoid something like this in every single wrapper call I have to some other APIs: ->> x (encode) (foo) (bar "something") (decode)

hugesandwich22:02:17

actually better to write -> x (encode) (.foo) (.bar) (decode) since these aren't clojure functions

hugesandwich22:02:42

anyway, it all works, but feels wrong. I could wrap some functions with pre/post calls but like I said, it's not always just encode/decode, but might help somewhat I guess